Annotation of q_a/samples/ddk/mono/mono.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1993  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     mono.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     A simple kernel-mode driver sample.
                     12: 
                     13: Environment:
                     14: 
                     15:     kernel mode only
                     16: 
                     17: Notes:
                     18: 
                     19:     See readme.txt
                     20: 
                     21: Revision History:
                     22: 
                     23:     03-22-93 : created
                     24:     06-02-93 : #ifdef's removed from IoCreateSymbolicLink, and
                     25:                bulk of pMonoReportResourceUsage commented out for
                     26:                ease of use with other drivers (see note below)
                     27: --*/
                     28: 
                     29: #include "ntddk.h"
                     30: #include "stdarg.h"
                     31: #include "stdio.h"
                     32: #include "monopub.h"
                     33: #include "monopriv.h"
                     34: 
                     35: 
                     36: 
                     37: //
                     38: // NOTE: Routines prefixed with "p" are private to this module
                     39: //
                     40: 
                     41: NTSTATUS
                     42: MonoDispatch(
                     43:     IN PDEVICE_OBJECT DeviceObject,
                     44:     IN PIRP Irp
                     45:     );
                     46: 
                     47: VOID
                     48: MonoUnload(
                     49:     IN PDRIVER_OBJECT DriverObject
                     50:     );
                     51: 
                     52: NTSTATUS
                     53: pMonoLocateDevice(
                     54:     void
                     55:     );
                     56: 
                     57: PVOID
                     58: pMonoGetMappedAddress(
                     59:     IN PHYSICAL_ADDRESS PhysicalAddress,
                     60:     IN ULONG            AddressSpace,
                     61:     IN ULONG            NumberOfBytes
                     62:     );
                     63: 
                     64: BOOLEAN
                     65: pMonoReportResourceUsage(
                     66:     IN PDRIVER_OBJECT   DriverObject,
                     67:     IN PMONO_RESOURCE   MonoResources,
                     68:     IN ULONG            NumberOfResources
                     69:     );
                     70: 
                     71: VOID
                     72: MonoDbgPrint(
                     73:     IN ULONG  DbgPrintLevel,
                     74:     IN PUCHAR DbgMessage,
                     75:     IN ...
                     76:     );
                     77: 
                     78: VOID
                     79: pMonoPrint(
                     80:     IN PMONO_DEVICE_EXTENSION DeviceExtension,
                     81:     IN PUCHAR                 TextString,
                     82:     IN ULONG                  BytesToMove
                     83:     );
                     84: 
                     85: VOID
                     86: pMonoClearScreen(
                     87:     IN PMONO_DEVICE_EXTENSION DeviceExtension
                     88:     );
                     89: 
                     90: 
                     91: 
                     92: NTSTATUS
                     93: DriverEntry(
                     94:     IN PDRIVER_OBJECT  DriverObject,
                     95:     IN PUNICODE_STRING RegistryPath
                     96:     )
                     97: /*++
                     98: 
                     99: Routine Description:
                    100: 
                    101:     Installable driver initialization entry point.
                    102:     This entry point is called directly by the I/O system.
                    103: 
                    104: Arguments:
                    105: 
                    106:     DriverObject - pointer to the driver object
                    107: 
                    108:     RegistryPath - pointer to a unicode string representing the path
                    109:                    to driver-specific key in the registry
                    110: 
                    111: Return Value:
                    112: 
                    113:     STATUS_SUCCESS if successful,
                    114:     STATUS_UNSUCCESSFUL otherwise
                    115: 
                    116: --*/
                    117: {
                    118: 
                    119:     PDEVICE_OBJECT         deviceObject        = NULL;
                    120:     NTSTATUS               ntStatus;
                    121:     WCHAR                  deviceNameBuffer[]  = L"\\Device\\Mono";
                    122:     UNICODE_STRING         deviceNameUnicodeString;
                    123:     PMONO_DEVICE_EXTENSION deviceExtension;
                    124:     BOOLEAN                symbolicLinkCreated = FALSE;
                    125:     WCHAR                  deviceLinkBuffer[]  = L"\\DosDevices\\MONO";
                    126:     UNICODE_STRING         deviceLinkUnicodeString;
                    127: 
                    128: 
                    129:     pMonoKdPrint (("MONO.SYS: entering DriverEntry\n"));
                    130: 
                    131: 
                    132: 
                    133:     //
                    134:     // Check to see if anybody else has claim the resources we want to
                    135:     // used. We don't want to be partying on someone else's hardware,
                    136:     // even when trying to locate our devicc.
                    137:     //
                    138: 
                    139:     if (!pMonoReportResourceUsage (DriverObject,
                    140:                                    MonoResources,
                    141:                                    MONO_NUMBER_RESOURCE_ENTRIES
                    142:                                    ))
                    143:     {
                    144:         //
                    145:         // There's a resource conflict
                    146:         //
                    147: 
                    148:         pMonoKdPrint (("MONO.SYS: pMonoReportResourceUsage failed\n"));
                    149: 
                    150:         return STATUS_UNSUCCESSFUL;
                    151:     }
                    152: 
                    153: 
                    154: 
                    155:     //
                    156:     // Try to locate a monochrome display adapter (MDA)
                    157:     //
                    158: 
                    159:     ntStatus = pMonoLocateDevice ();
                    160: 
                    161:     if (!NT_SUCCESS(ntStatus))
                    162:     {
                    163:         pMonoKdPrint (("MONO.SYS: pMonoLocateDevice failed\n"));
                    164: 
                    165:         ntStatus = STATUS_UNSUCCESSFUL;
                    166: 
                    167:         goto done_DriverEntry;
                    168:     }
                    169: 
                    170: 
                    171: 
                    172:     //
                    173:     // OK, we've claimed our resources & found our h/w, so create
                    174:     // a device and initialize stuff...
                    175:     //
                    176: 
                    177:     RtlInitUnicodeString (&deviceNameUnicodeString,
                    178:                           deviceNameBuffer
                    179:                           );
                    180: 
                    181: 
                    182: 
                    183:     //
                    184:     // Create an EXCLUSIVE device, i.e. only 1 thread at a time can send
                    185:     // i/o requests. If opened as non-exclusive, then we would need to
                    186:     // implement a more robust synchronization scheme than the event
                    187:     // mechanism we utilize below.
                    188:     //
                    189: 
                    190:     ntStatus = IoCreateDevice (DriverObject,
                    191:                                sizeof (MONO_DEVICE_EXTENSION),
                    192:                                &deviceNameUnicodeString,
                    193:                                FILE_DEVICE_MONO,
                    194:                                0,
                    195:                                TRUE,
                    196:                                &deviceObject
                    197:                                );
                    198: 
                    199:     if (NT_SUCCESS(ntStatus))
                    200:     {
                    201: 
                    202:         GlobalDeviceExtension =
                    203:         deviceExtension = (PMONO_DEVICE_EXTENSION) deviceObject->DeviceExtension;
                    204: 
                    205: 
                    206:         //
                    207:         // Initialize the dispatch event object. This allows us to
                    208:         // synchronize access to the h/w registers...
                    209:         //
                    210: 
                    211:         KeInitializeEvent (&deviceExtension->SyncEvent,
                    212:                            SynchronizationEvent,
                    213:                            TRUE
                    214:                            );
                    215: 
                    216: 
                    217: 
                    218:         deviceExtension->InterfaceType = Isa;
                    219:         deviceExtension->BusNumber     = 0;
                    220: 
                    221: 
                    222:         //
                    223:         // Map all the required resources, save the addresses
                    224:         //
                    225: 
                    226:         deviceExtension->VideoMemory =
                    227: 
                    228:             (PUSHORT) pMonoGetMappedAddress (MonoResources[MONO_VIDEO_BUFFER].PhysicalAddress,
                    229:                                              MonoResources[MONO_VIDEO_BUFFER].AddressSpace,
                    230:                                              MonoResources[MONO_VIDEO_BUFFER].Length
                    231:                                              );
                    232: 
                    233:         deviceExtension->CRTCRegisters =
                    234: 
                    235:             (PUCHAR) pMonoGetMappedAddress (MonoResources[MONO_CRTC_REG].PhysicalAddress,
                    236:                                             MonoResources[MONO_CRTC_REG].AddressSpace,
                    237:                                             MonoResources[MONO_CRTC_REG].Length
                    238:                                             );
                    239: 
                    240:         deviceExtension->ModeControlRegister =
                    241: 
                    242:             (PUCHAR) pMonoGetMappedAddress (MonoResources[MONO_MODE_CTL_REG].PhysicalAddress,
                    243:                                             MonoResources[MONO_MODE_CTL_REG].AddressSpace,
                    244:                                             MonoResources[MONO_MODE_CTL_REG].Length
                    245:                                             );
                    246: 
                    247:         if (!deviceExtension->VideoMemory         ||
                    248:             !deviceExtension->CRTCRegisters       ||
                    249:             !deviceExtension->ModeControlRegister
                    250:             )
                    251:         {
                    252: 
                    253:             pMonoKdPrint (("MONO.SYS: pMonoGetMappedAddress failed\n"));
                    254: 
                    255:             ntStatus = STATUS_UNSUCCESSFUL;
                    256: 
                    257:             goto done_DriverEntry;
                    258: 
                    259:         }
                    260: 
                    261:         deviceExtension->Xpos =
                    262:         deviceExtension->Ypos = 0;
                    263: 
                    264: 
                    265: 
                    266:         //
                    267:         // Create a symbolic link that Win32 apps can specify to gain access
                    268:         // to this driver/device
                    269:         //
                    270: 
                    271:         RtlInitUnicodeString (&deviceLinkUnicodeString,
                    272:                               deviceLinkBuffer
                    273:                               );
                    274: 
                    275:         ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,
                    276:                                          &deviceNameUnicodeString
                    277:                                          );
                    278: 
                    279: 
                    280:         if (!NT_SUCCESS(ntStatus))
                    281:         {
                    282:             pMonoKdPrint (("MONO.SYS: IoCreateSymbolicLink failed\n"));
                    283:         }
                    284:         else
                    285:         {
                    286:             symbolicLinkCreated = TRUE;
                    287:         }
                    288: 
                    289: 
                    290: 
                    291:         //
                    292:         // Create dispatch points for device control, create, close.
                    293:         //
                    294: 
                    295:         DriverObject->MajorFunction[IRP_MJ_CREATE]         =
                    296:         DriverObject->MajorFunction[IRP_MJ_CLOSE]          =
                    297:         DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MonoDispatch;
                    298:         DriverObject->DriverUnload                         = MonoUnload;
                    299: 
                    300: 
                    301: 
                    302:         //
                    303:         // Set the Start Address registers (indicate which part of
                    304:         // video buffer is displayed) to 0
                    305:         //
                    306: 
                    307:         WRITE_PORT_UCHAR (deviceExtension->CRTCRegisters,     0xc);
                    308:         WRITE_PORT_UCHAR (deviceExtension->CRTCRegisters + 1, 0);
                    309:         WRITE_PORT_UCHAR (deviceExtension->CRTCRegisters,     0xd);
                    310:         WRITE_PORT_UCHAR (deviceExtension->CRTCRegisters + 1, 0);
                    311: 
                    312: 
                    313: 
                    314:         //
                    315:         // Clear screen & alert world of our humble existence
                    316:         //
                    317: 
                    318:         pMonoClearScreen (deviceExtension);
                    319: 
                    320:         #define INIT_STRING "Mono driver initialized\n"
                    321: 
                    322:         pMonoPrint (deviceExtension,
                    323:                     INIT_STRING,
                    324:                     sizeof (INIT_STRING)
                    325:                     );
                    326:     }
                    327: 
                    328: 
                    329: done_DriverEntry:
                    330: 
                    331:     if (!NT_SUCCESS(ntStatus))
                    332:     {
                    333:         //
                    334:         // Something went wrong, so clean up
                    335:         //
                    336: 
                    337:         pMonoReportResourceUsage (DriverObject,
                    338:                                   NULL,
                    339:                                   0
                    340:                                   );
                    341: 
                    342:         if (symbolicLinkCreated)
                    343: 
                    344:             IoDeleteSymbolicLink (&deviceLinkUnicodeString);
                    345: 
                    346: 
                    347:         if (deviceObject)
                    348: 
                    349:             IoDeleteDevice (deviceObject);
                    350: 
                    351:         GlobalDeviceExtension = NULL;
                    352:     }
                    353: 
                    354:     return ntStatus;
                    355: }
                    356: 
                    357: 
                    358: 
                    359: NTSTATUS
                    360: MonoDispatch(
                    361:     IN PDEVICE_OBJECT DeviceObject,
                    362:     IN PIRP           Irp
                    363:     )
                    364: /*++
                    365: 
                    366: Routine Description:
                    367: 
                    368:     Process the IRPs sent to this device.
                    369: 
                    370: Arguments:
                    371: 
                    372:     DeviceObject - pointer to a device object
                    373: 
                    374:     Irp          - pointer to an I/O Request Packet
                    375: 
                    376: Return Value:
                    377: 
                    378: 
                    379: --*/
                    380: {
                    381: 
                    382:     PIO_STACK_LOCATION      irpStack;
                    383:     PMONO_DEVICE_EXTENSION  deviceExtension;
                    384:     PVOID                   ioBuffer;
                    385:     ULONG                   inputBufferLength;
                    386:     ULONG                   outputBufferLength;
                    387:     ULONG                   ioControlCode;
                    388:     NTSTATUS                ntStatus;
                    389: 
                    390: 
                    391: 
                    392:     Irp->IoStatus.Status      = STATUS_SUCCESS;
                    393:     Irp->IoStatus.Information = 0;
                    394: 
                    395: 
                    396:     //
                    397:     // Get a pointer to the current location in the Irp. This is where
                    398:     //     the function codes and parameters are located.
                    399:     //
                    400: 
                    401:     irpStack = IoGetCurrentIrpStackLocation (Irp);
                    402: 
                    403: 
                    404: 
                    405:     //
                    406:     // Get a pointer to the device extension
                    407:     //
                    408: 
                    409:     deviceExtension = DeviceObject->DeviceExtension;
                    410: 
                    411: 
                    412: 
                    413:     //
                    414:     // Get the pointer to the input/output buffer and it's length
                    415:     //
                    416: 
                    417:     ioBuffer           = Irp->AssociatedIrp.SystemBuffer;
                    418:     inputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;
                    419:     outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
                    420: 
                    421: 
                    422: 
                    423:     //
                    424:     // Synchronize execution of the dispatch routine by acquiring the device
                    425:     // event object. This ensures all request are serialized.
                    426:     //
                    427: 
                    428:     KeWaitForSingleObject (&deviceExtension->SyncEvent,
                    429:                            Executive,
                    430:                            KernelMode,
                    431:                            FALSE,
                    432:                            (PTIME) NULL
                    433:                            );
                    434: 
                    435: 
                    436: 
                    437:     switch (irpStack->MajorFunction)
                    438:     {
                    439:     case IRP_MJ_CREATE:
                    440: 
                    441:         pMonoKdPrint (("MONO.SYS: IRP_MJ_CREATE\n"));
                    442: 
                    443:         break;
                    444: 
                    445:     case IRP_MJ_CLOSE:
                    446: 
                    447:         pMonoKdPrint (("MONO.SYS: IRP_MJ_CLOSE\n"));
                    448: 
                    449:         break;
                    450: 
                    451:     case IRP_MJ_DEVICE_CONTROL:
                    452: 
                    453:         pMonoKdPrint (("MONO.SYS: IRP_MJ_DEVICE_CONTROL\n"));
                    454: 
                    455:         ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
                    456: 
                    457:         switch (ioControlCode)
                    458:         {
                    459: 
                    460:         case IOCTL_MONO_PRINT:
                    461:         {
                    462:             pMonoPrint (deviceExtension,
                    463:                         ioBuffer,
                    464:                         inputBufferLength
                    465:                         );
                    466: 
                    467:             break;
                    468:         }
                    469: 
                    470:         case IOCTL_MONO_CLEAR_SCREEN:
                    471:         {
                    472:             pMonoClearScreen (deviceExtension);
                    473: 
                    474:             break;
                    475:         }
                    476: 
                    477:         default:
                    478: 
                    479:             Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                    480: 
                    481:             pMonoKdPrint (("MONO.SYS: unknown IRP_MJ_DEVICE_CONTROL\n"));
                    482: 
                    483:             break;
                    484: 
                    485:         }
                    486: 
                    487:         break;
                    488:     }
                    489: 
                    490: 
                    491:     KeSetEvent (&deviceExtension->SyncEvent,
                    492:                 0,
                    493:                 FALSE
                    494:                 );
                    495: 
                    496:     //
                    497:     // DON'T get cute and try to use the status field of
                    498:     // the irp in the return status.  That IRP IS GONE as
                    499:     // soon as you call IoCompleteRequest.
                    500:     //
                    501: 
                    502:     ntStatus = Irp->IoStatus.Status;
                    503: 
                    504:     IoCompleteRequest (Irp,
                    505:                        IO_NO_INCREMENT
                    506:                        );
                    507: 
                    508: 
                    509:     //
                    510:     // We never have pending operation so always return the status code.
                    511:     //
                    512: 
                    513:     return ntStatus;
                    514: }
                    515: 
                    516: 
                    517: 
                    518: VOID
                    519: MonoUnload(
                    520:     IN PDRIVER_OBJECT DriverObject
                    521:     )
                    522: /*++
                    523: 
                    524: Routine Description:
                    525: 
                    526:     Free all the allocated resources, etc.
                    527: 
                    528: Arguments:
                    529: 
                    530:     DriverObject - pointer to a driver object
                    531: 
                    532: Return Value:
                    533: 
                    534: 
                    535: --*/
                    536: {
                    537:     WCHAR                  deviceLinkBuffer[]  = L"\\DosDevices\\MONO";
                    538:     UNICODE_STRING         deviceLinkUnicodeString;
                    539: 
                    540: 
                    541:     //
                    542:     // Unreport the resources
                    543:     //
                    544: 
                    545:     pMonoReportResourceUsage (DriverObject,
                    546:                               NULL,
                    547:                               0
                    548:                               );
                    549: 
                    550: 
                    551: 
                    552:     //
                    553:     // Delete the symbolic link
                    554:     //
                    555: 
                    556:     RtlInitUnicodeString (&deviceLinkUnicodeString,
                    557:                           deviceLinkBuffer
                    558:                           );
                    559: 
                    560:     IoDeleteSymbolicLink (&deviceLinkUnicodeString);
                    561: 
                    562: 
                    563: 
                    564: 
                    565:     //
                    566:     // Delete the device object
                    567:     //
                    568: 
                    569:     IoDeleteDevice (DriverObject->DeviceObject);
                    570: 
                    571:     pMonoKdPrint (("MONO.SYS: unloading\n"));
                    572: }
                    573: 
                    574: 
                    575: 
                    576: NTSTATUS
                    577: pMonoLocateDevice(
                    578:     )
                    579: /*++
                    580: 
                    581: Routine Description:
                    582: 
                    583:     Attempts to locate an MDA
                    584: 
                    585: Arguments:
                    586: 
                    587: 
                    588: Return Value:
                    589: 
                    590:     STATUS_SUCCESS if adapter found,
                    591:     STATUS_UNSUCCESSFUL otherwise
                    592: 
                    593: --*/
                    594: {
                    595: 
                    596:     NTSTATUS         ntStatus = STATUS_SUCCESS;
                    597:     PHYSICAL_ADDRESS physicalAddress;
                    598:     PUCHAR           crtcRegisters;
                    599: 
                    600:     //
                    601:     // Our FindAdapter logic:
                    602:     //
                    603:     //    - retrieve an address for the 6845's index register (0x3b4)
                    604:     //    - write a 0x0f to the index register (0x0f = index of Cursor
                    605:     //      Location Low register)
                    606:     //    - write a 0x55 to 0x3b5
                    607:     //    - read 0x3b5, and it should == 0x55
                    608:     //
                    609: 
                    610:     physicalAddress.LowPart  = 0x3b4;
                    611:     physicalAddress.HighPart = 0;
                    612: 
                    613: 
                    614:     if ((crtcRegisters = pMonoGetMappedAddress (physicalAddress,
                    615:                                                 1,
                    616:                                                 2
                    617:                                                 )))
                    618:     {
                    619:         WRITE_PORT_UCHAR (crtcRegisters,     0x0f);
                    620:         WRITE_PORT_UCHAR (crtcRegisters + 1, 0x55);
                    621: 
                    622:         if (READ_PORT_UCHAR (crtcRegisters + 1) != 0x55)
                    623:         {
                    624:             pMonoKdPrint (("MONO.SYS: could not find adapter\n"));
                    625: 
                    626:             ntStatus = STATUS_UNSUCCESSFUL;
                    627: 
                    628:             goto done_LocateDevice;
                    629:         }
                    630: 
                    631:         //
                    632:         //  Set current cursor location back to (0,0)
                    633:         //
                    634: 
                    635:         WRITE_PORT_UCHAR (crtcRegisters + 1, 0x00);
                    636:     }
                    637: 
                    638:     else
                    639:     {
                    640:         pMonoKdPrint (("MONO.SYS: HalTranslatedAddress(0x3b4) failed\n"));
                    641: 
                    642:         ntStatus = STATUS_UNSUCCESSFUL;
                    643:     }
                    644: 
                    645: done_LocateDevice:
                    646: 
                    647:     return ntStatus;
                    648: }
                    649: 
                    650: 
                    651: 
                    652: PVOID
                    653: pMonoGetMappedAddress(
                    654:     IN PHYSICAL_ADDRESS PhysicalAddress,
                    655:     IN ULONG            AddressSpace,
                    656:     IN ULONG            NumberOfBytes
                    657:     )
                    658: /*++
                    659: 
                    660: Routine Description:
                    661: 
                    662:     Given a physical address, retrieves a corresponding system address
                    663:     that can be used by a kernel mode driver.
                    664: 
                    665: Arguments:
                    666: 
                    667:     PhysicalAddress - physical address to map
                    668: 
                    669:     AddressSpace    - 0 if in memory space, 1 if in I/O space
                    670: 
                    671:     NumberOfBytes   - length of section to map
                    672: 
                    673: Return Value:
                    674: 
                    675:     A valid system address is successful,
                    676:     NULL otherwise.
                    677: 
                    678: --*/
                    679: {
                    680:     //
                    681:     // Assume we're on Isa bus # 0
                    682:     //
                    683: 
                    684:     IN INTERFACE_TYPE  interfaceType = Isa;
                    685:     IN ULONG           busNumber = 0;
                    686:     PHYSICAL_ADDRESS   translatedAddress;
                    687:     PVOID              deviceBase = NULL;
                    688: 
                    689:     if (HalTranslateBusAddress (interfaceType,
                    690:                                 busNumber,
                    691:                                 PhysicalAddress,
                    692:                                 &AddressSpace,
                    693:                                 &translatedAddress
                    694:                                 ))
                    695:     {
                    696:         if (!AddressSpace)
                    697:         {
                    698:             if (!(deviceBase = MmMapIoSpace (translatedAddress,
                    699:                                              NumberOfBytes,
                    700:                                              FALSE          // noncached memory
                    701:                                              )))
                    702:             {
                    703:                 pMonoKdPrint (("MONO.SYS: MmMapIoSpaceFailed\n"));
                    704:             }
                    705:         }
                    706:         else
                    707:         {
                    708:             deviceBase = (PVOID) translatedAddress.LowPart;
                    709:         }
                    710:     }
                    711: 
                    712:     else
                    713:     {
                    714:         pMonoKdPrint (("MONO.SYS: HalTranslateBusAddress failed\n"));
                    715:     }
                    716: 
                    717:     return deviceBase;
                    718: }
                    719: 
                    720: 
                    721: 
                    722: BOOLEAN
                    723: pMonoReportResourceUsage(
                    724:     IN PDRIVER_OBJECT DriverObject,
                    725:     IN PMONO_RESOURCE MonoResources,
                    726:     IN ULONG          NumberOfResources
                    727:     )
                    728: /*++
                    729: 
                    730: Routine Description:
                    731: 
                    732:     Reports the resources used by a device.
                    733: 
                    734: Arguments:
                    735: 
                    736:     DriverObject      - pointer to a driver object
                    737: 
                    738:     MonoResources     - pointer to an array of resource information, or
                    739:                         NULL is unreporting resources for this driver
                    740: 
                    741:     NumberOfResources - number of entries in the resource array, or
                    742:                         0 if unreporting resources for this driver
                    743: 
                    744: Return Value:
                    745: 
                    746:     TRUE if resources successfully report (and no conflicts),
                    747:     FALSE otherwise.
                    748: 
                    749: --*/
                    750: {
                    751: 
                    752: 
                    753: 
                    754: //
                    755: // NOTE: The following is commented out because some of the video miniport
                    756: //       drivers provided with the system (and in the NT DDK) regsister
                    757: //       their resources as exclusive;  if these resources overlap with
                    758: //       the resources used by the mono driver, then this driver will fail
                    759: //       to load.  This can be solved in one of two ways: by commenting
                    760: //       out the code below, and using the resources without reporting them
                    761: //       (not safe to do, but the easiest for this simple example); or, by
                    762: //       editing the source file(s) of the appropriate miniport driver
                    763: //       such that the VIDEO_ACCESS_RANGE.RangeSharable element is set to
                    764: //       TRUE, and rebuilding the driver.
                    765: //
                    766: //       A real driver should *always* report it's resources.
                    767: //
                    768: 
                    769: 
                    770: /*
                    771:     ULONG                           sizeOfResourceList = 0;
                    772:     PCM_RESOURCE_LIST               resourceList       = NULL;
                    773:     PCM_PARTIAL_RESOURCE_DESCRIPTOR partial;
                    774:     ULONG                           i;
                    775:     UNICODE_STRING                  className;
                    776:     BOOLEAN                         conflictDetected;
                    777: 
                    778: 
                    779:     if (NumberOfResources > 0)
                    780:     {
                    781:         //
                    782:         // Alloc enough memory to build a resource list & zero it out
                    783:         //
                    784: 
                    785:         sizeOfResourceList = sizeof(CM_RESOURCE_LIST) +
                    786:                              (sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)*
                    787:                              (NumberOfResources - 1)
                    788:                              );
                    789: 
                    790:         resourceList = ExAllocatePool (PagedPool,
                    791:                                        sizeOfResourceList
                    792:                                        );
                    793: 
                    794:         if (!resourceList)
                    795:         {
                    796:             pMonoKdPrint (("MONO.SYS: ExAllocPool failed\n"));
                    797: 
                    798:             return FALSE;
                    799:         }
                    800: 
                    801:         RtlZeroMemory (resourceList,
                    802:                        sizeOfResourceList
                    803:                        );
                    804: 
                    805: 
                    806:         //
                    807:         // Fill in the reosurce list
                    808:         //
                    809:         // NOTE: Assume Isa, bus # 0
                    810:         //
                    811: 
                    812:         resourceList->Count = 1;
                    813: 
                    814:         resourceList->List[0].InterfaceType = Isa;
                    815:         resourceList->List[0].BusNumber     = 0;
                    816: 
                    817:         resourceList->List[0].PartialResourceList.Count = NumberOfResources;
                    818: 
                    819:         partial = &resourceList->List[0].PartialResourceList.PartialDescriptors[0];
                    820: 
                    821:         //
                    822:         // Account for the space used by the controller.
                    823:         //
                    824: 
                    825:         for (i = 0; i < NumberOfResources; i++)
                    826:         {
                    827:             if (MonoResources[i].AddressSpace)
                    828:             {
                    829:                 partial->Type          = CmResourceTypePort;
                    830:                 partial->Flags         = CM_RESOURCE_PORT_IO;
                    831:                 partial->u.Port.Start  = MonoResources[i].PhysicalAddress;
                    832:                 partial->u.Port.Length = MonoResources[i].Length;
                    833:             }
                    834:             else
                    835:             {
                    836:                 partial->Type            = CmResourceTypeMemory;
                    837:                 partial->Flags           = CM_RESOURCE_MEMORY_READ_WRITE;
                    838:                 partial->u.Memory.Start  = MonoResources[i].PhysicalAddress;
                    839:                 partial->u.Memory.Length = MonoResources[i].Length;
                    840:             }
                    841: 
                    842:             if (MonoResources[i].RangeSharable)
                    843:             {
                    844:                 partial->ShareDisposition = CmResourceShareShared;
                    845:             }
                    846: 
                    847:             else
                    848:             {
                    849:                 partial->ShareDisposition = CmResourceShareDeviceExclusive;
                    850:             }
                    851: 
                    852:             partial++;
                    853:         }
                    854:     }
                    855: 
                    856:     RtlInitUnicodeString (&className,
                    857:                           L"LOADED MONO DRIVER RESOURCES"
                    858:                           );
                    859: 
                    860:     IoReportResourceUsage (&className,
                    861:                            DriverObject,
                    862:                            resourceList,
                    863:                            sizeOfResourceList,
                    864:                            NULL,
                    865:                            NULL,
                    866:                            0,
                    867:                            FALSE,
                    868:                            &conflictDetected
                    869:                            );
                    870: 
                    871:     if (resourceList)
                    872:     {
                    873:         ExFreePool (resourceList);
                    874: 
                    875: 
                    876:         if (conflictDetected)
                    877: 
                    878:             return FALSE;
                    879: 
                    880:         else
                    881: 
                    882:             return TRUE;
                    883:     }
                    884: */
                    885:     return TRUE;
                    886: }
                    887: 
                    888: 
                    889: 
                    890: VOID
                    891: MonoDbgPrint(
                    892:     IN ULONG  DbgPrintLevel,
                    893:     IN PUCHAR DbgMessage,
                    894:     IN ...
                    895:     )
                    896: /*++
                    897: 
                    898: Routine Description:
                    899: 
                    900:     Format the incoming debug message & calls pMonoPrint to write the
                    901:     message out to the attached MDA.
                    902: 
                    903: Arguments:
                    904: 
                    905:     DbgPrintLevel - level of message verboseness
                    906: 
                    907:     DbgMessage    - printf-style format string, followed by appropriate
                    908:                     list of arguments
                    909: 
                    910: Return Value:
                    911: 
                    912: 
                    913: --*/
                    914: {
                    915:     va_list ap;
                    916: 
                    917:     va_start(ap, DbgMessage);
                    918: 
                    919:     if (DbgPrintLevel <= MonoDbgLevel)
                    920:     {
                    921:         char buf[256];
                    922: 
                    923:         vsprintf (buf,
                    924:                   DbgMessage,
                    925:                   ap
                    926:                   );
                    927: 
                    928:         if (GlobalDeviceExtension)
                    929: 
                    930:             pMonoPrint (GlobalDeviceExtension,
                    931:                         buf,
                    932:                         strlen (buf)
                    933:                         );
                    934:     }
                    935: 
                    936:     va_end(ap);
                    937: }
                    938: 
                    939: 
                    940: 
                    941: VOID
                    942: pMonoPrint(
                    943:     IN PMONO_DEVICE_EXTENSION DeviceExtension,
                    944:     IN PUCHAR                 TextString,
                    945:     IN ULONG                  BytesToMove
                    946:     )
                    947: /*++
                    948: 
                    949: Routine Description:
                    950: 
                    951:     Writes a specified string to MDA memory
                    952: 
                    953: Arguments:
                    954: 
                    955:     DeviceExtension - pointer to a device extension
                    956: 
                    957:     TextString      - pointer to an ascii string
                    958: 
                    959:     BytesToMove     - number of characters to write
                    960: 
                    961: Return Value:
                    962: 
                    963: 
                    964: --*/
                    965: {
                    966: 
                    967:     PUSHORT VideoMemory;
                    968:     ULONG   x,y,i,j;
                    969:     UCHAR   Letter;
                    970: 
                    971:     VideoMemory = DeviceExtension->VideoMemory;
                    972:     x           = DeviceExtension->Xpos;
                    973:     y           = DeviceExtension->Ypos;
                    974: 
                    975: 
                    976:     for (i = 0; i < BytesToMove; i++)
                    977:     {
                    978:         Letter = (UCHAR) *(TextString + i);
                    979: 
                    980:         if (Letter == '\n')
                    981:         {
                    982:             //
                    983:             // Blank out the rest of the line
                    984:             //
                    985: 
                    986:             for (j = x; j < 80; j++)
                    987:             {
                    988:                 *(VideoMemory + j + (y * 80)) = 0;
                    989:             }
                    990:             x = 0;
                    991:             y = y + 1;
                    992:         }
                    993: 
                    994:         else
                    995:         {
                    996:             //
                    997:             // Write character & attribute out to video memory
                    998:             //
                    999:             // 0x0700 = No blink, black background, normal intensity,
                   1000:             //          white chracter
                   1001:             //
                   1002: 
                   1003:             *(VideoMemory + x + (y * 80)) = Letter | 0x0700;
                   1004: 
                   1005:             x++;
                   1006:         }
                   1007: 
                   1008:         if (x > 79)
                   1009:         {
                   1010:             //
                   1011:             // Wrap around to next line
                   1012:             //
                   1013: 
                   1014:             x = 0;
                   1015:             y++;
                   1016:         }
                   1017: 
                   1018:         if (y > 24)
                   1019:         {
                   1020:             //
                   1021:             // We've reached the bottom of the screen, scroll screen
                   1022:             // up by 1 row
                   1023:             //
                   1024: 
                   1025:             RtlMoveMemory (VideoMemory,
                   1026:                            VideoMemory+80,
                   1027:                            24 * 80 * 2
                   1028:                            );
                   1029:             y = 24;
                   1030: 
                   1031: 
                   1032:             //
                   1033:             // Zero out the bottom row
                   1034:             //
                   1035: 
                   1036:             for (j = 0; j < 80; j++)
                   1037:             {
                   1038:                 *(VideoMemory + j + (24 * 80)) = 0;
                   1039:             }
                   1040:         }
                   1041:     }
                   1042: 
                   1043:     DeviceExtension->Xpos = x;
                   1044:     DeviceExtension->Ypos = y;
                   1045: }
                   1046: 
                   1047: 
                   1048: 
                   1049: VOID
                   1050: pMonoClearScreen(
                   1051:     IN PMONO_DEVICE_EXTENSION DeviceExtension
                   1052:     )
                   1053: /*++
                   1054: 
                   1055: Routine Description:
                   1056: 
                   1057:     Clears the MDA
                   1058: 
                   1059: Arguments:
                   1060: 
                   1061: 
                   1062: Return Value:
                   1063: 
                   1064: 
                   1065: --*/
                   1066: {
                   1067: 
                   1068:     ULONG  i;
                   1069: 
                   1070:     //
                   1071:     // Zero out the MDA memory
                   1072:     //
                   1073: 
                   1074:     for (i = 0; i < 25 * 80; i++)
                   1075: 
                   1076:         *(DeviceExtension->VideoMemory + i) = 0;
                   1077: 
                   1078:     DeviceExtension->Xpos =
                   1079:     DeviceExtension->Ypos = 0;
                   1080: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.