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