This commit was manufactured by cvs2svn to create branch 'captive'.
[reactos.git] / drivers / dd / vidport / vidport.c
1 /* $Id$
2  *
3  * VideoPort driver
4  *   Written by Rex Jolliff
5  */
6
7 #include <ddk/ntddk.h>
8 #include <ddk/ntddvid.h>
9
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   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 }