Use free Windows DDK and compile with latest MinGW releases.
[reactos.git] / reactos / drivers / dd / vidport / vidport.c
1 /* $Id: vidport.c,v 1.24 2002/09/07 15:12:00 chorns Exp $
2 *
3 * VideoPort driver
4 * Written by Rex Jolliff
5 */
6
7 #define NTOS_KERNEL_MODE
8 #include <ntos.h>
9 #include <ntos/ntddvid.h>
10 #include "../../../ntoskrnl/include/internal/v86m.h"
11
12 #include "vidport.h"
13
14 #define NDEBUG
15 #include <debug.h>
16
17 //#define UNIMPLEMENTED do {DbgPrint("%s:%d: Function not implemented", __FILE__, __LINE__); for(;;);} while (0)
18
19 #define VERSION "0.0.0"
20
21 static VOID STDCALL VidStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
22 static NTSTATUS STDCALL VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
23 static NTSTATUS STDCALL VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
24
25 static BOOLEAN CsrssInitialized = FALSE;
26 static HANDLE CsrssHandle = 0;
27 static struct _EPROCESS* Csrss = NULL;
28
29 PBYTE ReturnCsrssAddress(void)
30 {
31 return (PBYTE)Csrss;
32 }
33
34 // ------------------------------------------------------- Public Interface
35
36 // DriverEntry
37 //
38 // DESCRIPTION:
39 // This function initializes the driver.
40 //
41 // RUN LEVEL:
42 // PASSIVE_LEVEL
43 //
44 // ARGUMENTS:
45 // IN PDRIVER_OBJECT DriverObject System allocated Driver Object
46 // for this driver
47 // IN PUNICODE_STRING RegistryPath Name of registry driver service
48 // key
49 //
50 // RETURNS:
51 // NTSTATUS
52
53 STDCALL NTSTATUS
54 DriverEntry(IN PDRIVER_OBJECT DriverObject,
55 IN PUNICODE_STRING RegistryPath)
56 {
57 return(STATUS_SUCCESS);
58 }
59
60 VOID
61 VideoPortDebugPrint(IN ULONG DebugPrintLevel,
62 IN PCHAR DebugMessage, ...)
63 {
64 char Buffer[256];
65 va_list ap;
66
67 /*
68 if (DebugPrintLevel > InternalDebugLevel)
69 return;
70 */
71 va_start (ap, DebugMessage);
72 vsprintf (Buffer, DebugMessage, ap);
73 va_end (ap);
74
75 DbgPrint (Buffer);
76 }
77
78 VP_STATUS
79 STDCALL
80 VideoPortDisableInterrupt(IN PVOID HwDeviceExtension)
81 {
82 UNIMPLEMENTED;
83 }
84
85 VP_STATUS
86 STDCALL
87 VideoPortEnableInterrupt(IN PVOID HwDeviceExtension)
88 {
89 UNIMPLEMENTED;
90 }
91
92 VOID
93 STDCALL
94 VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension,
95 IN PVOID MappedAddress)
96 {
97 UNIMPLEMENTED;
98 }
99
100 ULONG
101 STDCALL
102 VideoPortGetBusData(IN PVOID HwDeviceExtension,
103 IN BUS_DATA_TYPE BusDataType,
104 IN ULONG SlotNumber,
105 OUT PVOID Buffer,
106 IN ULONG Offset,
107 IN ULONG Length)
108 {
109 return HalGetBusDataByOffset(BusDataType,
110 0,
111 SlotNumber,
112 Buffer,
113 Offset,
114 Length);
115 }
116
117 UCHAR
118 STDCALL
119 VideoPortGetCurrentIrql(VOID)
120 {
121 return KeGetCurrentIrql();
122 }
123
124 PVOID
125 STDCALL
126 VideoPortGetDeviceBase(IN PVOID HwDeviceExtension,
127 IN PHYSICAL_ADDRESS IoAddress,
128 IN ULONG NumberOfUchars,
129 IN UCHAR InIoSpace)
130 {
131 if (InIoSpace)
132 {
133 return MmMapIoSpace(IoAddress, NumberOfUchars, FALSE);
134 }
135 else
136 {
137 UNIMPLEMENTED;
138 return NULL;
139 }
140 }
141
142 VP_STATUS
143 STDCALL
144 VideoPortGetDeviceData(IN PVOID HwDeviceExtension,
145 IN VIDEO_DEVICE_DATA_TYPE DeviceDataType,
146 IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine,
147 IN PVOID Context)
148 {
149 UNIMPLEMENTED;
150 }
151
152 VP_STATUS
153 STDCALL
154 VideoPortGetAccessRanges(IN PVOID HwDeviceExtension,
155 IN ULONG NumRequestedResources,
156 IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL,
157 IN ULONG NumAccessRanges,
158 IN PVIDEO_ACCESS_RANGE AccessRanges,
159 IN PVOID VendorId,
160 IN PVOID DeviceId,
161 IN PULONG Slot)
162 {
163 UNIMPLEMENTED;
164 }
165
166 VP_STATUS
167 STDCALL
168 VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension,
169 IN PWSTR ParameterName,
170 IN UCHAR IsParameterFileName,
171 IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine,
172 IN PVOID Context)
173 {
174 UNIMPLEMENTED;
175 }
176
177 ULONG STDCALL
178 VideoPortInitialize(IN PVOID Context1,
179 IN PVOID Context2,
180 IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData,
181 IN PVOID HwContext)
182 {
183 UCHAR Again;
184 WCHAR DeviceBuffer[20];
185 WCHAR SymlinkBuffer[20];
186 NTSTATUS Status;
187 PDRIVER_OBJECT MPDriverObject = (PDRIVER_OBJECT) Context1;
188 PDEVICE_OBJECT MPDeviceObject;
189 VIDEO_PORT_CONFIG_INFO ConfigInfo;
190 PVIDEOPORT_EXTENSION_DATA ExtensionData;
191 ULONG DeviceNumber = 0;
192 UNICODE_STRING DeviceName;
193 UNICODE_STRING SymlinkName;
194 CLIENT_ID Cid;
195
196 /* Build Dispatch table from passed data */
197 MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO;
198
199 /* Create a unicode device name */
200 Again = FALSE;
201 do
202 {
203 swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber);
204 RtlInitUnicodeString(&DeviceName, DeviceBuffer);
205
206 /* Create the device */
207 Status = IoCreateDevice(MPDriverObject,
208 HwInitializationData->HwDeviceExtensionSize +
209 sizeof(VIDEOPORT_EXTENSION_DATA),
210 &DeviceName,
211 FILE_DEVICE_VIDEO,
212 0,
213 TRUE,
214 &MPDeviceObject);
215 if (!NT_SUCCESS(Status))
216 {
217 DbgPrint("IoCreateDevice call failed\n",0);
218 return Status;
219 }
220
221 MPDriverObject->DeviceObject = MPDeviceObject;
222
223 /* initialize the miniport drivers dispatch table */
224 MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpenClose;
225 MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchOpenClose;
226 MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatchDeviceControl;
227
228 /* create symbolic link "\??\DISPLAYx" */
229 swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber+1);
230 RtlInitUnicodeString (&SymlinkName,
231 SymlinkBuffer);
232 IoCreateSymbolicLink (&SymlinkName,
233 &DeviceName);
234
235 ExtensionData =
236 (PVIDEOPORT_EXTENSION_DATA) MPDeviceObject->DeviceExtension;
237 ExtensionData->DeviceObject = MPDeviceObject;
238
239 /* Set the buffering strategy here... */
240 /* If you change this, remember to change VidDispatchDeviceControl too */
241 MPDeviceObject->Flags |= DO_BUFFERED_IO;
242
243 /* Call HwFindAdapter entry point */
244 /* FIXME: Need to figure out what string to pass as param 3 */
245 Status = HwInitializationData->HwFindAdapter(VPExtensionToMPExtension(ExtensionData),
246 Context2,
247 L"",
248 &ConfigInfo,
249 &Again);
250 if (!NT_SUCCESS(Status))
251 {
252 DbgPrint("HwFindAdapter call failed\n");
253 IoDeleteDevice(MPDeviceObject);
254
255 return Status;
256 }
257
258 /* FIXME: Allocate hardware resources for device */
259
260 /* Allocate interrupt for device */
261 if (HwInitializationData->HwInterrupt != NULL &&
262 !(ConfigInfo.BusInterruptLevel == 0 &&
263 ConfigInfo.BusInterruptVector == 0))
264 {
265 #if 0
266 ExtensionData->IRQL = ConfigInfo.BusInterruptLevel;
267 ExtensionData->InterruptLevel =
268 HalGetInterruptVector(ConfigInfo.AdapterInterfaceType,
269 ConfigInfo.SystemIoBusNumber,
270 ConfigInfo.BusInterruptLevel,
271 ConfigInfo.BusInterruptVector,
272 &ExtensionData->IRQL,
273 &ExtensionData->Affinity);
274 KeInitializeSpinLock(&ExtensionData->InterruptSpinLock);
275 Status = IoConnectInterrupt(&ExtensionData->InterruptObject,
276 (PKSERVICE_ROUTINE)
277 HwInitializationData->HwInterrupt,
278 VPExtensionToMPExtension(ExtensionData),
279 &ExtensionData->InterruptSpinLock,
280 ExtensionData->InterruptLevel,
281 ExtensionData->IRQL,
282 ExtensionData->IRQL,
283 ConfigInfo.InterruptMode,
284 FALSE,
285 ExtensionData->Affinity,
286 FALSE);
287 if (!NT_SUCCESS(Status))
288 {
289 DbgPrint("IoConnectInterrupt failed\n");
290 IoDeleteDevice(MPDeviceObject);
291
292 return Status;
293 }
294 #endif
295 }
296 DeviceNumber++;
297 }
298 while (Again);
299
300 /* FIXME: initialize timer routine for MP Driver */
301 if (HwInitializationData->HwTimer != NULL)
302 {
303 Status = IoInitializeTimer(MPDeviceObject,
304 (PIO_TIMER_ROUTINE)
305 HwInitializationData->HwTimer,
306 VPExtensionToMPExtension(ExtensionData));
307 if (!NT_SUCCESS(Status))
308 {
309 DbgPrint("IoInitializeTimer failed\n");
310
311 if (HwInitializationData->HwInterrupt != NULL)
312 {
313 IoDisconnectInterrupt(ExtensionData->InterruptObject);
314 }
315 IoDeleteDevice(MPDeviceObject);
316
317 return Status;
318 }
319 }
320
321 return STATUS_SUCCESS;
322 }
323
324 VP_STATUS STDCALL
325 VideoPortInt10(IN PVOID HwDeviceExtension,
326 IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
327 {
328 KV86M_REGISTERS Regs;
329 NTSTATUS Status;
330
331 KeAttachProcess(Csrss);
332
333 memset(&Regs, 0, sizeof(Regs));
334 Regs.Eax = BiosArguments->Eax;
335 Regs.Ebx = BiosArguments->Ebx;
336 Regs.Ecx = BiosArguments->Ecx;
337 Regs.Edx = BiosArguments->Edx;
338 Regs.Esi = BiosArguments->Esi;
339 Regs.Edi = BiosArguments->Edi;
340 Regs.Ebp = BiosArguments->Ebp;
341 Status = Ke386CallBios(0x10, &Regs);
342
343 KeDetachProcess();
344
345 return(Status);
346 }
347
348 VOID
349 STDCALL
350 VideoPortLogError(IN PVOID HwDeviceExtension,
351 IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL,
352 IN VP_STATUS ErrorCode,
353 IN ULONG UniqueId)
354 {
355 UNIMPLEMENTED;
356 }
357
358 VP_STATUS
359 STDCALL
360 VideoPortMapBankedMemory(IN PVOID HwDeviceExtension,
361 IN PHYSICAL_ADDRESS PhysicalAddress,
362 IN PULONG Length,
363 IN PULONG InIoSpace,
364 OUT PVOID *VirtualAddress,
365 IN ULONG BankLength,
366 IN UCHAR ReadWriteBank,
367 IN PBANKED_SECTION_ROUTINE BankRoutine,
368 IN PVOID Context)
369 {
370 UNIMPLEMENTED;
371 }
372
373 VP_STATUS
374 STDCALL
375 VideoPortMapMemory(IN PVOID HwDeviceExtension,
376 IN PHYSICAL_ADDRESS PhysicalAddress,
377 IN PULONG Length,
378 IN PULONG InIoSpace,
379 OUT PVOID *VirtualAddress)
380 {
381 if (*InIoSpace)
382 {
383 *VirtualAddress = MmMapIoSpace(PhysicalAddress, *Length, FALSE);
384
385 return *VirtualAddress != NULL ? STATUS_SUCCESS :
386 STATUS_INSUFFICIENT_RESOURCES;
387 }
388 else
389 {
390 UNIMPLEMENTED;
391 }
392
393 return STATUS_SUCCESS;
394 }
395
396 UCHAR
397 STDCALL
398 VideoPortReadPortUchar(IN PUCHAR Port)
399 {
400 return READ_PORT_UCHAR(Port);
401 }
402
403 USHORT
404 STDCALL
405 VideoPortReadPortUshort(IN PUSHORT Port)
406 {
407 return READ_PORT_USHORT(Port);
408 }
409
410 ULONG
411 STDCALL
412 VideoPortReadPortUlong(IN PULONG Port)
413 {
414 return READ_PORT_ULONG(Port);
415 }
416
417 VOID
418 STDCALL
419 VideoPortReadPortBufferUchar(IN PUCHAR Port,
420 OUT PUCHAR Buffer,
421 IN ULONG Count)
422 {
423 READ_PORT_BUFFER_UCHAR(Port, Buffer, Count);
424 }
425
426 VOID
427 STDCALL
428 VideoPortReadPortBufferUshort(IN PUSHORT Port,
429 OUT PUSHORT Buffer,
430 IN ULONG Count)
431 {
432 READ_PORT_BUFFER_USHORT(Port, Buffer, Count);
433 }
434
435 VOID
436 STDCALL
437 VideoPortReadPortBufferUlong(IN PULONG Port,
438 OUT PULONG Buffer,
439 IN ULONG Count)
440 {
441 READ_PORT_BUFFER_ULONG(Port, Buffer, Count);
442 }
443
444 UCHAR
445 STDCALL
446 VideoPortReadRegisterUchar(IN PUCHAR Register)
447 {
448 return READ_REGISTER_UCHAR(Register);
449 }
450
451 USHORT
452 STDCALL
453 VideoPortReadRegisterUshort(IN PUSHORT Register)
454 {
455 return READ_REGISTER_USHORT(Register);
456 }
457
458 ULONG
459 STDCALL
460 VideoPortReadRegisterUlong(IN PULONG Register)
461 {
462 return READ_REGISTER_ULONG(Register);
463 }
464
465 VOID
466 STDCALL
467 VideoPortReadRegisterBufferUchar(IN PUCHAR Register,
468 OUT PUCHAR Buffer,
469 IN ULONG Count)
470 {
471 READ_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
472 }
473
474 VOID
475 STDCALL
476 VideoPortReadRegisterBufferUshort(IN PUSHORT Register,
477 OUT PUSHORT Buffer,
478 IN ULONG Count)
479 {
480 READ_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
481 }
482
483 VOID
484 STDCALL
485 VideoPortReadRegisterBufferUlong(IN PULONG Register,
486 OUT PULONG Buffer,
487 IN ULONG Count)
488 {
489 READ_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
490 }
491
492 BOOLEAN
493 STDCALL
494 VideoPortScanRom(IN PVOID HwDeviceExtension,
495 IN PUCHAR RomBase,
496 IN ULONG RomLength,
497 IN PUCHAR String)
498 {
499 UNIMPLEMENTED;
500 }
501
502 ULONG
503 STDCALL
504 VideoPortSetBusData(IN PVOID HwDeviceExtension,
505 IN BUS_DATA_TYPE BusDataType,
506 IN ULONG SlotNumber,
507 IN PVOID Buffer,
508 IN ULONG Offset,
509 IN ULONG Length)
510 {
511 return HalSetBusDataByOffset(BusDataType,
512 0,
513 SlotNumber,
514 Buffer,
515 Offset,
516 Length);
517 }
518
519 VP_STATUS
520 STDCALL
521 VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension,
522 IN PWSTR ValueName,
523 IN PVOID ValueData,
524 IN ULONG ValueLength)
525 {
526 UNIMPLEMENTED;
527 }
528
529 VP_STATUS
530 STDCALL
531 VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension,
532 IN ULONG NumAccessRanges,
533 IN PVIDEO_ACCESS_RANGE AccessRange)
534 {
535 UNIMPLEMENTED;
536 }
537
538 VOID
539 STDCALL
540 VideoPortStartTimer(IN PVOID HwDeviceExtension)
541 {
542 PVIDEOPORT_EXTENSION_DATA ExtensionData =
543 MPExtensionToVPExtension(HwDeviceExtension);
544
545 IoStartTimer(ExtensionData->DeviceObject);
546 }
547
548 VOID
549 STDCALL
550 VideoPortStopTimer(IN PVOID HwDeviceExtension)
551 {
552 PVIDEOPORT_EXTENSION_DATA ExtensionData =
553 MPExtensionToVPExtension(HwDeviceExtension);
554
555 IoStopTimer(ExtensionData->DeviceObject);
556 }
557
558 BOOLEAN
559 STDCALL
560 VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension,
561 IN VIDEO_SYNCHRONIZE_PRIORITY Priority,
562 IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine,
563 OUT PVOID Context)
564 {
565 UNIMPLEMENTED;
566 }
567
568 VP_STATUS
569 STDCALL
570 VideoPortUnmapMemory(IN PVOID HwDeviceExtension,
571 IN PVOID VirtualAddress,
572 IN HANDLE ProcessHandle)
573 {
574 UNIMPLEMENTED;
575 }
576
577 VP_STATUS
578 STDCALL
579 VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension,
580 IN ULONG NumAccessRanges,
581 IN PVIDEO_ACCESS_RANGE AccessRanges)
582 {
583 UNIMPLEMENTED;
584 }
585
586 VOID
587 STDCALL
588 VideoPortWritePortUchar(IN PUCHAR Port,
589 IN UCHAR Value)
590 {
591 WRITE_PORT_UCHAR(Port, Value);
592 }
593
594 VOID
595 STDCALL
596 VideoPortWritePortUshort(IN PUSHORT Port,
597 IN USHORT Value)
598 {
599 WRITE_PORT_USHORT(Port, Value);
600 }
601
602 VOID
603 STDCALL
604 VideoPortWritePortUlong(IN PULONG Port,
605 IN ULONG Value)
606 {
607 WRITE_PORT_ULONG(Port, Value);
608 }
609
610 VOID
611 STDCALL
612 VideoPortWritePortBufferUchar(IN PUCHAR Port,
613 IN PUCHAR Buffer,
614 IN ULONG Count)
615 {
616 WRITE_PORT_BUFFER_UCHAR(Port, Buffer, Count);
617 }
618
619 VOID
620 STDCALL
621 VideoPortWritePortBufferUshort(IN PUSHORT Port,
622 IN PUSHORT Buffer,
623 IN ULONG Count)
624 {
625 WRITE_PORT_BUFFER_USHORT(Port, Buffer, Count);
626 }
627
628 VOID
629 STDCALL
630 VideoPortWritePortBufferUlong(IN PULONG Port,
631 IN PULONG Buffer,
632 IN ULONG Count)
633 {
634 WRITE_PORT_BUFFER_ULONG(Port, Buffer, Count);
635 }
636
637 VOID
638 STDCALL
639 VideoPortWriteRegisterUchar(IN PUCHAR Register,
640 IN UCHAR Value)
641 {
642 WRITE_REGISTER_UCHAR(Register, Value);
643 }
644
645 VOID
646 STDCALL
647 VideoPortWriteRegisterUshort(IN PUSHORT Register,
648 IN USHORT Value)
649 {
650 WRITE_REGISTER_USHORT(Register, Value);
651 }
652
653 VOID
654 STDCALL
655 VideoPortWriteRegisterUlong(IN PULONG Register,
656 IN ULONG Value)
657 {
658 WRITE_REGISTER_ULONG(Register, Value);
659 }
660
661 VOID
662 STDCALL
663 VideoPortWriteRegisterBufferUchar(IN PUCHAR Register,
664 IN PUCHAR Buffer,
665 IN ULONG Count)
666 {
667 WRITE_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
668 }
669
670 VOID STDCALL
671 VideoPortWriteRegisterBufferUshort(IN PUSHORT Register,
672 IN PUSHORT Buffer,
673 IN ULONG Count)
674 {
675 WRITE_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
676 }
677
678 VOID STDCALL
679 VideoPortWriteRegisterBufferUlong(IN PULONG Register,
680 IN PULONG Buffer,
681 IN ULONG Count)
682 {
683 WRITE_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
684 }
685
686 VOID STDCALL
687 VideoPortZeroDeviceMemory(OUT PVOID Destination,
688 IN ULONG Length)
689 {
690 UNIMPLEMENTED;
691 }
692
693
694 // ------------------------------------------- Nondiscardable statics
695
696 // VidDispatchOpenClose
697 //
698 // DESCRIPTION:
699 // Answer requests for Open/Close calls: a null operation
700 //
701 // RUN LEVEL:
702 // PASSIVE_LEVEL
703 //
704 // ARGUMENTS:
705 // Standard dispatch arguments
706 //
707 // RETURNS:
708 // NTSTATUS
709 //
710
711 static NTSTATUS STDCALL
712 VidDispatchOpenClose(IN PDEVICE_OBJECT pDO,
713 IN PIRP Irp)
714 {
715 PIO_STACK_LOCATION IrpStack;
716
717 DPRINT("VidDispatchOpenClose() called\n");
718
719 IrpStack = IoGetCurrentIrpStackLocation(Irp);
720
721 if (IrpStack->MajorFunction == IRP_MJ_CREATE &&
722 CsrssInitialized == FALSE)
723 {
724 DPRINT("Referencing CSRSS\n");
725 Csrss = PsGetCurrentProcess();
726 CsrssInitialized = TRUE;
727 DPRINT("Csrss %p\n", Csrss);
728 }
729
730 Irp->IoStatus.Status = STATUS_SUCCESS;
731 Irp->IoStatus.Information = FILE_OPENED;
732 IoCompleteRequest(Irp, IO_NO_INCREMENT);
733
734 return STATUS_SUCCESS;
735 }
736
737 // VidStartIo
738 //
739 // DESCRIPTION:
740 // Get the next requested I/O packet started
741 //
742 // RUN LEVEL:
743 // DISPATCH_LEVEL
744 //
745 // ARGUMENTS:
746 // Dispatch routine standard arguments
747 //
748 // RETURNS:
749 // NTSTATUS
750 //
751
752 static VOID STDCALL
753 VidStartIo(IN PDEVICE_OBJECT DeviceObject,
754 IN PIRP Irp)
755 {
756 UNIMPLEMENTED;
757 }
758
759 // VidDispatchDeviceControl
760 //
761 // DESCRIPTION:
762 // Answer requests for device control calls
763 //
764 // RUN LEVEL:
765 // PASSIVE_LEVEL
766 //
767 // ARGUMENTS:
768 // Standard dispatch arguments
769 //
770 // RETURNS:
771 // NTSTATUS
772 //
773
774 static NTSTATUS STDCALL
775 VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
776 IN PIRP Irp)
777 {
778 PIO_STACK_LOCATION IrpStack;
779 PVIDEO_REQUEST_PACKET vrp;
780
781 IrpStack = IoGetCurrentIrpStackLocation(Irp);
782
783 // Translate the IRP to a VRP
784 vrp = ExAllocatePool(PagedPool, sizeof(VIDEO_REQUEST_PACKET));
785 vrp->StatusBlock = ExAllocatePool(PagedPool, sizeof(STATUS_BLOCK));
786 vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
787
788 // We're assuming METHOD_BUFFERED
789 vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer;
790 vrp->InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
791 vrp->OutputBuffer = Irp->UserBuffer;
792 vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
793
794 // Call the Miniport Driver with the VRP
795 ((PDRIVER_STARTIO)DeviceObject->DriverObject->DriverStartIo)(DeviceObject->DeviceExtension, (PIRP)vrp);
796
797 // Translate the VRP back into the IRP for OutputBuffer
798 Irp->UserBuffer = vrp->OutputBuffer;
799 IrpStack->Parameters.DeviceIoControl.OutputBufferLength = vrp->OutputBufferLength;
800
801 // Free the VRP
802 ExFreePool(vrp->StatusBlock);
803 ExFreePool(vrp);
804
805 return STATUS_SUCCESS;
806 }