|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.