- Synchronize up to trunk's revision r57864.
[reactos.git] / win32ss / drivers / videoprt / dispatch.c
1 /*
2 * VideoPort driver
3 *
4 * Copyright (C) 2002, 2003, 2004 ReactOS Team
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21
22 #include "videoprt.h"
23
24 /* GLOBAL VARIABLES ***********************************************************/
25
26 PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
27
28 /* PRIVATE FUNCTIONS **********************************************************/
29
30 /*
31 * Reset display to blue screen
32 */
33
34 BOOLEAN NTAPI
35 IntVideoPortResetDisplayParameters(ULONG Columns, ULONG Rows)
36 {
37 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
38
39 if (ResetDisplayParametersDeviceExtension == NULL)
40 return FALSE;
41
42 DriverExtension = ResetDisplayParametersDeviceExtension->DriverExtension;
43
44 if (DriverExtension->InitializationData.HwResetHw != NULL)
45 {
46 if (DriverExtension->InitializationData.HwResetHw(
47 &ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension,
48 Columns, Rows))
49 {
50 ResetDisplayParametersDeviceExtension = NULL;
51 return TRUE;
52 }
53 }
54
55 ResetDisplayParametersDeviceExtension = NULL;
56 return FALSE;
57 }
58
59 NTSTATUS NTAPI
60 IntVideoPortAddDevice(
61 IN PDRIVER_OBJECT DriverObject,
62 IN PDEVICE_OBJECT PhysicalDeviceObject)
63 {
64 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
65 PDEVICE_OBJECT DeviceObject;
66 NTSTATUS Status;
67
68 /*
69 * Get the initialization data we saved in VideoPortInitialize.
70 */
71
72 DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
73
74 /*
75 * Create adapter device object.
76 */
77
78 Status = IntVideoPortCreateAdapterDeviceObject(
79 DriverObject,
80 DriverExtension,
81 PhysicalDeviceObject,
82 &DeviceObject);
83 if (NT_SUCCESS(Status))
84 VideoPortDeviceNumber++;
85
86 return Status;
87 }
88
89 /*
90 * IntVideoPortDispatchOpen
91 *
92 * Answer requests for Open calls.
93 *
94 * Run Level
95 * PASSIVE_LEVEL
96 */
97
98 NTSTATUS NTAPI
99 IntVideoPortDispatchOpen(
100 IN PDEVICE_OBJECT DeviceObject,
101 IN PIRP Irp)
102 {
103 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
104 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
105
106 TRACE_(VIDEOPRT, "IntVideoPortDispatchOpen\n");
107
108 if (CsrssInitialized == FALSE)
109 {
110 /*
111 * We know the first open call will be from the CSRSS process
112 * to let us know its handle.
113 */
114
115 INFO_(VIDEOPRT, "Referencing CSRSS\n");
116 Csrss = (PKPROCESS)PsGetCurrentProcess();
117 INFO_(VIDEOPRT, "Csrss %p\n", Csrss);
118
119 CsrssInitialized = TRUE;
120
121 Irp->IoStatus.Information = FILE_OPENED;
122 IoCompleteRequest(Irp, IO_NO_INCREMENT);
123
124 return STATUS_SUCCESS;
125 }
126
127 DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
128 DriverExtension = DeviceExtension->DriverExtension;
129
130 if (DriverExtension->InitializationData.HwInitialize(&DeviceExtension->MiniPortDeviceExtension))
131 {
132 Irp->IoStatus.Status = STATUS_SUCCESS;
133
134 InterlockedIncrement((PLONG)&DeviceExtension->DeviceOpened);
135 }
136 else
137 {
138 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
139 }
140
141 Irp->IoStatus.Information = FILE_OPENED;
142 IoCompleteRequest(Irp, IO_NO_INCREMENT);
143
144 return STATUS_SUCCESS;
145 }
146
147 /*
148 * IntVideoPortDispatchClose
149 *
150 * Answer requests for Close calls.
151 *
152 * Run Level
153 * PASSIVE_LEVEL
154 */
155
156 NTSTATUS NTAPI
157 IntVideoPortDispatchClose(
158 IN PDEVICE_OBJECT DeviceObject,
159 IN PIRP Irp)
160 {
161 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
162
163 TRACE_(VIDEOPRT, "IntVideoPortDispatchClose\n");
164
165 DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
166 if (DeviceExtension->DeviceOpened >= 1 &&
167 InterlockedDecrement((PLONG)&DeviceExtension->DeviceOpened) == 0)
168 {
169 ResetDisplayParametersDeviceExtension = NULL;
170 InbvNotifyDisplayOwnershipLost(NULL);
171 ResetDisplayParametersDeviceExtension = DeviceExtension;
172 IntVideoPortResetDisplayParameters(80, 50);
173 }
174
175 Irp->IoStatus.Status = STATUS_SUCCESS;
176 IoCompleteRequest(Irp, IO_NO_INCREMENT);
177
178 return STATUS_SUCCESS;
179 }
180
181 /*
182 * IntVideoPortDispatchDeviceControl
183 *
184 * Answer requests for device control calls.
185 *
186 * Run Level
187 * PASSIVE_LEVEL
188 */
189
190 NTSTATUS NTAPI
191 IntVideoPortDispatchDeviceControl(
192 IN PDEVICE_OBJECT DeviceObject,
193 IN PIRP Irp)
194 {
195 PIO_STACK_LOCATION IrpStack;
196 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
197 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
198 PVIDEO_REQUEST_PACKET vrp;
199 NTSTATUS Status;
200
201 TRACE_(VIDEOPRT, "IntVideoPortDispatchDeviceControl\n");
202
203 IrpStack = IoGetCurrentIrpStackLocation(Irp);
204 DeviceExtension = DeviceObject->DeviceExtension;
205 DriverExtension = DeviceExtension->DriverExtension;
206
207 /* Translate the IRP to a VRP */
208 vrp = ExAllocatePoolWithTag(NonPagedPool,
209 sizeof(VIDEO_REQUEST_PACKET),
210 TAG_REQUEST_PACKET);
211 if (NULL == vrp)
212 {
213 return STATUS_NO_MEMORY;
214 }
215
216 vrp->StatusBlock = (PSTATUS_BLOCK)&(Irp->IoStatus);
217 vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
218
219 INFO_(VIDEOPRT, "- IoControlCode: %x\n", vrp->IoControlCode);
220
221 /* We're assuming METHOD_BUFFERED */
222 vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer;
223 vrp->InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
224 vrp->OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
225 vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
226
227 /* Call the Miniport Driver with the VRP */
228 DriverExtension->InitializationData.HwStartIO(
229 &DeviceExtension->MiniPortDeviceExtension,
230 vrp);
231
232 /* Free the VRP */
233 ExFreePoolWithTag(vrp, TAG_REQUEST_PACKET);
234
235 INFO_(VIDEOPRT, "- Returned status: %x\n", Irp->IoStatus.Status);
236
237 if (Irp->IoStatus.Status != STATUS_SUCCESS)
238 {
239 /* Map from win32 error codes to NT status values. */
240 switch (Irp->IoStatus.Status)
241 {
242 case ERROR_NOT_ENOUGH_MEMORY: Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; break;
243 case ERROR_MORE_DATA: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; break;
244 case ERROR_INVALID_FUNCTION: Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; break;
245 case ERROR_INVALID_PARAMETER: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; break;
246 case ERROR_INSUFFICIENT_BUFFER: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; break;
247 case ERROR_DEV_NOT_EXIST: Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST; break;
248 case ERROR_IO_PENDING: Irp->IoStatus.Status = STATUS_PENDING; break;
249 }
250 }
251
252 Status = Irp->IoStatus.Status;
253 IoCompleteRequest(Irp, IO_NO_INCREMENT);
254
255 return Status;
256 }
257
258 /*
259 * IntVideoPortWrite
260 *
261 * This is a bit of a hack. We want to take ownership of the display as late
262 * as possible, just before the switch to graphics mode. Win32k knows when
263 * this happens, we don't. So we need Win32k to inform us. This could be done
264 * using an IOCTL, but there's no way of knowing which IOCTL codes are unused
265 * in the communication between GDI driver and miniport driver. So we use
266 * IRP_MJ_WRITE as the signal that win32k is ready to switch to graphics mode,
267 * since we know for certain that there is no read/write activity going on
268 * between GDI and miniport drivers.
269 * We don't actually need the data that is passed, we just trigger on the fact
270 * that an IRP_MJ_WRITE was sent.
271 *
272 * Run Level
273 * PASSIVE_LEVEL
274 */
275
276 NTSTATUS NTAPI
277 IntVideoPortDispatchWrite(
278 IN PDEVICE_OBJECT DeviceObject,
279 IN PIRP Irp)
280 {
281 PIO_STACK_LOCATION piosStack = IoGetCurrentIrpStackLocation(Irp);
282 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
283 NTSTATUS nErrCode;
284
285 DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
286
287 /*
288 * Storing the device extension pointer in a static variable is an
289 * ugly hack. Unfortunately, we need it in IntVideoPortResetDisplayParameters
290 * and InbvNotifyDisplayOwnershipLost doesn't allow us to pass a userdata
291 * parameter. On the bright side, the DISPLAY device is opened
292 * exclusively, so there can be only one device extension active at
293 * any point in time.
294 *
295 * FIXME: We should process all opened display devices in
296 * IntVideoPortResetDisplayParameters.
297 */
298
299 ResetDisplayParametersDeviceExtension = DeviceExtension;
300 InbvNotifyDisplayOwnershipLost(IntVideoPortResetDisplayParameters);
301
302 nErrCode = STATUS_SUCCESS;
303 Irp->IoStatus.Information = piosStack->Parameters.Write.Length;
304 Irp->IoStatus.Status = nErrCode;
305 IoCompleteRequest(Irp, IO_NO_INCREMENT);
306
307 return nErrCode;
308 }
309
310 NTSTATUS NTAPI
311 IntVideoPortPnPStartDevice(
312 IN PDEVICE_OBJECT DeviceObject,
313 IN PIRP Irp)
314 {
315 PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
316 PDRIVER_OBJECT DriverObject;
317 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
318 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
319 PCM_RESOURCE_LIST AllocatedResources;
320
321 /*
322 * Get the initialization data we saved in VideoPortInitialize.
323 */
324
325 DriverObject = DeviceObject->DriverObject;
326 DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
327 DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
328
329 /*
330 * Store some resources in the DeviceExtension.
331 */
332
333 AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources;
334 if (AllocatedResources != NULL)
335 {
336 CM_FULL_RESOURCE_DESCRIPTOR *FullList;
337 CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
338 ULONG ResourceCount;
339 ULONG ResourceListSize;
340
341 /* Save the resource list */
342 ResourceCount = AllocatedResources->List[0].PartialResourceList.Count;
343 ResourceListSize =
344 FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
345 PartialDescriptors[ResourceCount]);
346 DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize);
347 if (DeviceExtension->AllocatedResources == NULL)
348 {
349 return STATUS_INSUFFICIENT_RESOURCES;
350 }
351
352 RtlCopyMemory(DeviceExtension->AllocatedResources,
353 AllocatedResources,
354 ResourceListSize);
355
356 /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
357 for (FullList = AllocatedResources->List;
358 FullList < AllocatedResources->List + AllocatedResources->Count;
359 FullList++)
360 {
361 INFO_(VIDEOPRT, "InterfaceType %u BusNumber List %u Device BusNumber %u Version %u Revision %u\n",
362 FullList->InterfaceType, FullList->BusNumber, DeviceExtension->SystemIoBusNumber, FullList->PartialResourceList.Version, FullList->PartialResourceList.Revision);
363
364 /* FIXME: Is this ASSERT ok for resources from the PNP manager? */
365 ASSERT(FullList->InterfaceType == PCIBus);
366 ASSERT(FullList->BusNumber == DeviceExtension->SystemIoBusNumber);
367 ASSERT(1 == FullList->PartialResourceList.Version);
368 ASSERT(1 == FullList->PartialResourceList.Revision);
369 for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
370 Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
371 Descriptor++)
372 {
373 if (Descriptor->Type == CmResourceTypeInterrupt)
374 {
375 DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
376 DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
377 if (Descriptor->ShareDisposition == CmResourceShareShared)
378 DeviceExtension->InterruptShared = TRUE;
379 else
380 DeviceExtension->InterruptShared = FALSE;
381 }
382 }
383 }
384 }
385 INFO_(VIDEOPRT, "Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
386 DeviceExtension->InterruptLevel,
387 DeviceExtension->InterruptVector);
388
389 /*
390 * Create adapter device object.
391 */
392
393 return IntVideoPortFindAdapter(
394 DriverObject,
395 DriverExtension,
396 DeviceObject);
397 }
398
399
400 NTSTATUS
401 NTAPI
402 IntVideoPortForwardIrpAndWaitCompletionRoutine(
403 PDEVICE_OBJECT Fdo,
404 PIRP Irp,
405 PVOID Context)
406 {
407 PKEVENT Event = Context;
408
409 if (Irp->PendingReturned)
410 KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
411
412 return STATUS_MORE_PROCESSING_REQUIRED;
413 }
414
415 NTSTATUS
416 NTAPI
417 IntVideoPortQueryBusRelations(PDEVICE_OBJECT DeviceObject, PIRP Irp)
418 {
419 PDEVICE_RELATIONS DeviceRelations;
420 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
421 PVIDEO_PORT_CHILD_EXTENSION ChildExtension;
422 ULONG i;
423 PLIST_ENTRY CurrentEntry;
424
425 /* Count the children */
426 i = 0;
427 CurrentEntry = DeviceExtension->ChildDeviceList.Flink;
428 while (CurrentEntry != &DeviceExtension->ChildDeviceList)
429 {
430 i++;
431 CurrentEntry = CurrentEntry->Flink;
432 }
433
434 if (i == 0)
435 return Irp->IoStatus.Status;
436
437 DeviceRelations = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS) + ((i - 1) * sizeof(PVOID)));
438 if (!DeviceRelations) return STATUS_NO_MEMORY;
439
440 DeviceRelations->Count = i;
441
442 /* Add the children */
443 i = 0;
444 CurrentEntry = DeviceExtension->ChildDeviceList.Flink;
445 while (CurrentEntry != &DeviceExtension->ChildDeviceList)
446 {
447 ChildExtension = CONTAINING_RECORD(CurrentEntry, VIDEO_PORT_CHILD_EXTENSION, ListEntry);
448
449 ObReferenceObject(ChildExtension->PhysicalDeviceObject);
450 DeviceRelations->Objects[i] = ChildExtension->PhysicalDeviceObject;
451
452 i++;
453 CurrentEntry = CurrentEntry->Flink;
454 }
455
456 INFO_(VIDEOPRT, "Reported %d PDOs\n", i);
457 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
458
459 return STATUS_SUCCESS;
460 }
461
462 NTSTATUS
463 NTAPI
464 IntVideoPortForwardIrpAndWait(PDEVICE_OBJECT DeviceObject, PIRP Irp)
465 {
466 KEVENT Event;
467 NTSTATUS Status;
468 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension =
469 (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
470
471 KeInitializeEvent(&Event, NotificationEvent, FALSE);
472 IoCopyCurrentIrpStackLocationToNext(Irp);
473 IoSetCompletionRoutine(Irp, IntVideoPortForwardIrpAndWaitCompletionRoutine,
474 &Event, TRUE, TRUE, TRUE);
475 Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
476 if (Status == STATUS_PENDING)
477 {
478 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
479 Status = Irp->IoStatus.Status;
480 }
481 return Status;
482 }
483
484 NTSTATUS NTAPI
485 IntVideoPortDispatchFdoPnp(
486 IN PDEVICE_OBJECT DeviceObject,
487 IN PIRP Irp)
488 {
489 PIO_STACK_LOCATION IrpSp;
490 NTSTATUS Status;
491 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
492
493 IrpSp = IoGetCurrentIrpStackLocation(Irp);
494
495 switch (IrpSp->MinorFunction)
496 {
497 case IRP_MN_START_DEVICE:
498 Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
499 if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
500 Status = IntVideoPortPnPStartDevice(DeviceObject, Irp);
501 Irp->IoStatus.Status = Status;
502 Irp->IoStatus.Information = 0;
503 IoCompleteRequest(Irp, IO_NO_INCREMENT);
504 break;
505
506 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
507 Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
508 if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
509 Status = IntVideoPortFilterResourceRequirements(DeviceObject, Irp);
510 Irp->IoStatus.Status = Status;
511 Irp->IoStatus.Information = 0;
512 IoCompleteRequest(Irp, IO_NO_INCREMENT);
513 break;
514
515 case IRP_MN_QUERY_DEVICE_RELATIONS:
516 if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
517 {
518 IoSkipCurrentIrpStackLocation(Irp);
519 Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
520 }
521 else
522 {
523 Status = IntVideoPortQueryBusRelations(DeviceObject, Irp);
524 Irp->IoStatus.Status = Status;
525 IoCompleteRequest(Irp, IO_NO_INCREMENT);
526 }
527 break;
528
529 case IRP_MN_REMOVE_DEVICE:
530 case IRP_MN_QUERY_REMOVE_DEVICE:
531 case IRP_MN_CANCEL_REMOVE_DEVICE:
532 case IRP_MN_SURPRISE_REMOVAL:
533
534 case IRP_MN_STOP_DEVICE:
535 Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
536 if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
537 Status = STATUS_SUCCESS;
538 Irp->IoStatus.Status = Status;
539 Irp->IoStatus.Information = 0;
540 IoCompleteRequest(Irp, IO_NO_INCREMENT);
541 break;
542
543 case IRP_MN_QUERY_STOP_DEVICE:
544 case IRP_MN_CANCEL_STOP_DEVICE:
545 Status = STATUS_SUCCESS;
546 Irp->IoStatus.Status = STATUS_SUCCESS;
547 Irp->IoStatus.Information = 0;
548 IoCompleteRequest(Irp, IO_NO_INCREMENT);
549 break;
550
551 default:
552 Status = Irp->IoStatus.Status;
553 IoCompleteRequest(Irp, IO_NO_INCREMENT);
554 break;
555 }
556
557 return Status;
558 }
559
560 NTSTATUS NTAPI
561 IntVideoPortDispatchPnp(
562 IN PDEVICE_OBJECT DeviceObject,
563 IN PIRP Irp)
564 {
565 PVIDEO_PORT_COMMON_EXTENSION CommonExtension = DeviceObject->DeviceExtension;
566
567 if (CommonExtension->Fdo)
568 return IntVideoPortDispatchFdoPnp(DeviceObject, Irp);
569 else
570 return IntVideoPortDispatchPdoPnp(DeviceObject, Irp);
571 }
572
573 NTSTATUS NTAPI
574 IntVideoPortDispatchCleanup(
575 IN PDEVICE_OBJECT DeviceObject,
576 IN PIRP Irp)
577 {
578 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
579
580 DeviceExtension = DeviceObject->DeviceExtension;
581 RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
582
583 Irp->IoStatus.Status = STATUS_SUCCESS;
584 Irp->IoStatus.Information = 0;
585 IoCompleteRequest(Irp, IO_NO_INCREMENT);
586
587 return STATUS_SUCCESS;
588 }
589
590 NTSTATUS NTAPI
591 IntVideoPortDispatchPower(
592 IN PDEVICE_OBJECT DeviceObject,
593 IN PIRP Irp)
594 {
595 return STATUS_NOT_IMPLEMENTED;
596 }
597
598 NTSTATUS NTAPI
599 IntVideoPortDispatchSystemControl(
600 IN PDEVICE_OBJECT DeviceObject,
601 IN PIRP Irp)
602 {
603 return STATUS_NOT_IMPLEMENTED;
604 }
605
606 VOID NTAPI
607 IntVideoPortUnload(PDRIVER_OBJECT DriverObject)
608 {
609 }