|
|
1.1 ! root 1: #if defined(i386) ! 2: ! 3: /*++ ! 4: ! 5: Copyright (c) 1989, 1990, 1991, 1992, 1993 Microsoft Corporation ! 6: ! 7: Module Name: ! 8: ! 9: inpdep.c ! 10: ! 11: Abstract: ! 12: ! 13: The initialization and hardware-dependent portions of ! 14: the Microsoft InPort mouse port driver. Modifications to ! 15: support new mice similar to the InPort mouse should be ! 16: localized to this file. ! 17: ! 18: Environment: ! 19: ! 20: Kernel mode only. ! 21: ! 22: Notes: ! 23: ! 24: NOTES: (Future/outstanding issues) ! 25: ! 26: - Powerfail not implemented. ! 27: ! 28: - Consolidate duplicate code, where possible and appropriate. ! 29: ! 30: Revision History: ! 31: ! 32: --*/ ! 33: ! 34: #include "stdarg.h" ! 35: #include "stdio.h" ! 36: #include "string.h" ! 37: #include "ntddk.h" ! 38: #include "inport.h" ! 39: #include "inplog.h" ! 40: ! 41: // ! 42: // Use the alloc_text pragma to specify the driver initialization routines ! 43: // (they can be paged out). ! 44: // ! 45: ! 46: #ifdef ALLOC_PRAGMA ! 47: #pragma alloc_text(init,DriverEntry) ! 48: #pragma alloc_text(init,InpConfiguration) ! 49: #pragma alloc_text(init,InpPeripheralCallout) ! 50: #pragma alloc_text(init,InpServiceParameters) ! 51: #pragma alloc_text(init,InpInitializeHardware) ! 52: #pragma alloc_text(init,InpBuildResourceList) ! 53: #endif ! 54: ! 55: ! 56: NTSTATUS ! 57: DriverEntry( ! 58: IN PDRIVER_OBJECT DriverObject, ! 59: IN PUNICODE_STRING RegistryPath ! 60: ) ! 61: ! 62: /*++ ! 63: ! 64: Routine Description: ! 65: ! 66: This routine initializes the Inport mouse port driver. ! 67: ! 68: Arguments: ! 69: ! 70: DriverObject - Pointer to driver object created by system. ! 71: ! 72: RegistryPath - Pointer to the Unicode name of the registry path ! 73: for this driver. ! 74: ! 75: Return Value: ! 76: ! 77: The function value is the final status from the initialization operation. ! 78: ! 79: --*/ ! 80: ! 81: { ! 82: PDEVICE_OBJECT portDeviceObject = NULL; ! 83: PDEVICE_EXTENSION deviceExtension = NULL; ! 84: DEVICE_EXTENSION tmpDeviceExtension; ! 85: NTSTATUS status = STATUS_SUCCESS; ! 86: KIRQL coordinatorIrql = 0; ! 87: ULONG interruptVector; ! 88: KIRQL interruptLevel; ! 89: PIO_ERROR_LOG_PACKET errorLogEntry; ! 90: ULONG uniqueErrorValue; ! 91: ULONG dumpCount; ! 92: NTSTATUS errorCode = STATUS_SUCCESS; ! 93: PCM_RESOURCE_LIST resources = NULL; ! 94: ULONG resourceListSize = 0; ! 95: BOOLEAN conflictDetected; ! 96: KAFFINITY affinity; ! 97: ULONG addressSpace; ! 98: PHYSICAL_ADDRESS cardAddress; ! 99: ULONG i; ! 100: UNICODE_STRING fullDeviceName; ! 101: UNICODE_STRING baseDeviceName; ! 102: UNICODE_STRING deviceNameSuffix; ! 103: UNICODE_STRING registryPath; ! 104: ! 105: #define NAME_MAX 256 ! 106: WCHAR nameBuffer[NAME_MAX]; ! 107: ! 108: #define DUMP_COUNT 4 ! 109: ULONG dumpData[DUMP_COUNT]; ! 110: ! 111: ! 112: InpPrint((1,"\n\nINPORT-InportInitialize: enter\n")); ! 113: ! 114: // ! 115: // Zero-initialize various structures. ! 116: // ! 117: ! 118: RtlZeroMemory(&tmpDeviceExtension, sizeof(tmpDeviceExtension)); ! 119: for (i = 0; i < DUMP_COUNT; i++) ! 120: dumpData[i] = 0; ! 121: ! 122: fullDeviceName.MaximumLength = 0; ! 123: deviceNameSuffix.MaximumLength = 0; ! 124: registryPath.MaximumLength = 0; ! 125: ! 126: RtlZeroMemory(nameBuffer, NAME_MAX * sizeof(WCHAR)); ! 127: baseDeviceName.Buffer = nameBuffer; ! 128: baseDeviceName.Length = 0; ! 129: baseDeviceName.MaximumLength = NAME_MAX * sizeof(WCHAR); ! 130: ! 131: // ! 132: // Need to ensure that the registry path is null-terminated. ! 133: // Allocate pool to hold a null-terminated copy of the path. ! 134: // ! 135: ! 136: registryPath.Buffer = ExAllocatePool( ! 137: PagedPool, ! 138: RegistryPath->Length + sizeof(UNICODE_NULL) ! 139: ); ! 140: ! 141: if (!registryPath.Buffer) { ! 142: InpPrint(( ! 143: 1, ! 144: "INPORT-InportInitialize: Couldn't allocate pool for registry path\n" ! 145: )); ! 146: ! 147: status = STATUS_UNSUCCESSFUL; ! 148: errorCode = INPORT_INSUFFICIENT_RESOURCES; ! 149: uniqueErrorValue = INPORT_ERROR_VALUE_BASE + 2; ! 150: dumpData[0] = (ULONG) RegistryPath->Length + sizeof(UNICODE_NULL); ! 151: dumpCount = 1; ! 152: goto InportInitializeExit; ! 153: ! 154: } else { ! 155: ! 156: registryPath.Length = RegistryPath->Length + sizeof(UNICODE_NULL); ! 157: registryPath.MaximumLength = registryPath.Length; ! 158: ! 159: RtlZeroMemory( ! 160: registryPath.Buffer, ! 161: registryPath.Length ! 162: ); ! 163: ! 164: RtlMoveMemory( ! 165: registryPath.Buffer, ! 166: RegistryPath->Buffer, ! 167: RegistryPath->Length ! 168: ); ! 169: ! 170: } ! 171: ! 172: // ! 173: // Get the configuration information for this driver. ! 174: // ! 175: ! 176: InpConfiguration(&tmpDeviceExtension, ®istryPath, &baseDeviceName); ! 177: ! 178: if (tmpDeviceExtension.HardwarePresent == FALSE) { ! 179: ! 180: // ! 181: // There is no Inport mouse attached. Return unsuccessful status. ! 182: // ! 183: ! 184: InpPrint((1,"INPORT-InportInitialize: No mouse attached.\n")); ! 185: status = STATUS_NO_SUCH_DEVICE; ! 186: errorCode = INPORT_NO_SUCH_DEVICE; ! 187: uniqueErrorValue = INPORT_ERROR_VALUE_BASE + 4; ! 188: dumpCount = 0; ! 189: goto InportInitializeExit; ! 190: ! 191: } ! 192: ! 193: // ! 194: // Set up space for the port's device object suffix. Note that ! 195: // we overallocate space for the suffix string because it is much ! 196: // easier than figuring out exactly how much space is required. ! 197: // The storage gets freed at the end of driver initialization, so ! 198: // who cares... ! 199: // ! 200: ! 201: RtlInitUnicodeString( ! 202: &deviceNameSuffix, ! 203: NULL ! 204: ); ! 205: ! 206: deviceNameSuffix.MaximumLength = POINTER_PORTS_MAXIMUM * sizeof(WCHAR); ! 207: deviceNameSuffix.MaximumLength += sizeof(UNICODE_NULL); ! 208: ! 209: deviceNameSuffix.Buffer = ExAllocatePool( ! 210: PagedPool, ! 211: deviceNameSuffix.MaximumLength ! 212: ); ! 213: ! 214: if (!deviceNameSuffix.Buffer) { ! 215: ! 216: InpPrint(( ! 217: 1, ! 218: "INPORT-InportInitialize: Couldn't allocate string for device object suffix\n" ! 219: )); ! 220: ! 221: status = STATUS_UNSUCCESSFUL; ! 222: errorCode = INPORT_INSUFFICIENT_RESOURCES; ! 223: uniqueErrorValue = INPORT_ERROR_VALUE_BASE + 6; ! 224: dumpData[0] = (ULONG) deviceNameSuffix.MaximumLength; ! 225: dumpCount = 1; ! 226: goto InportInitializeExit; ! 227: ! 228: } ! 229: ! 230: RtlZeroMemory( ! 231: deviceNameSuffix.Buffer, ! 232: deviceNameSuffix.MaximumLength ! 233: ); ! 234: ! 235: // ! 236: // Set up space for the port's full device object name. ! 237: // ! 238: ! 239: RtlInitUnicodeString( ! 240: &fullDeviceName, ! 241: NULL ! 242: ); ! 243: ! 244: fullDeviceName.MaximumLength = sizeof(L"\\Device\\") + ! 245: baseDeviceName.Length + ! 246: deviceNameSuffix.MaximumLength; ! 247: ! 248: ! 249: fullDeviceName.Buffer = ExAllocatePool( ! 250: PagedPool, ! 251: fullDeviceName.MaximumLength ! 252: ); ! 253: ! 254: if (!fullDeviceName.Buffer) { ! 255: ! 256: InpPrint(( ! 257: 1, ! 258: "INPORT-InportInitialize: Couldn't allocate string for device object name\n" ! 259: )); ! 260: ! 261: status = STATUS_UNSUCCESSFUL; ! 262: errorCode = INPORT_INSUFFICIENT_RESOURCES; ! 263: uniqueErrorValue = INPORT_ERROR_VALUE_BASE + 8; ! 264: dumpData[0] = (ULONG) fullDeviceName.MaximumLength; ! 265: dumpCount = 1; ! 266: goto InportInitializeExit; ! 267: ! 268: } ! 269: ! 270: RtlZeroMemory( ! 271: fullDeviceName.Buffer, ! 272: fullDeviceName.MaximumLength ! 273: ); ! 274: RtlAppendUnicodeToString( ! 275: &fullDeviceName, ! 276: L"\\Device\\" ! 277: ); ! 278: RtlAppendUnicodeToString( ! 279: &fullDeviceName, ! 280: baseDeviceName.Buffer ! 281: ); ! 282: ! 283: for (i = 0; i < POINTER_PORTS_MAXIMUM; i++) { ! 284: ! 285: // ! 286: // Append the suffix to the device object name string. E.g., turn ! 287: // \Device\PointerPort into \Device\PointerPort0. Then we attempt ! 288: // to create the device object. If the device object already ! 289: // exists (because it was already created by another port driver), ! 290: // increment the suffix and try again. ! 291: // ! 292: ! 293: status = RtlIntegerToUnicodeString( ! 294: i, ! 295: 10, ! 296: &deviceNameSuffix ! 297: ); ! 298: ! 299: if (!NT_SUCCESS(status)) { ! 300: break; ! 301: } ! 302: ! 303: RtlAppendUnicodeStringToString( ! 304: &fullDeviceName, ! 305: &deviceNameSuffix ! 306: ); ! 307: ! 308: InpPrint(( ! 309: 1, ! 310: "INPORT-InportInitialize: Creating device object named %ws\n", ! 311: fullDeviceName.Buffer ! 312: )); ! 313: ! 314: // ! 315: // Create a non-exclusive device object for the Inport mouse ! 316: // port device. ! 317: // ! 318: ! 319: status = IoCreateDevice( ! 320: DriverObject, ! 321: sizeof(DEVICE_EXTENSION), ! 322: &fullDeviceName, ! 323: FILE_DEVICE_INPORT_PORT, ! 324: 0, ! 325: FALSE, ! 326: &portDeviceObject ! 327: ); ! 328: ! 329: if (NT_SUCCESS(status)) { ! 330: ! 331: // ! 332: // We've successfully created a device object. ! 333: // ! 334: ! 335: break; ! 336: } else { ! 337: ! 338: // ! 339: // We'll increment the suffix and try again. Note that we reset ! 340: // the length of the string here to get back to the beginning ! 341: // of the suffix portion of the name. Do not bother to ! 342: // zero the suffix, though, because the string for the ! 343: // incremented suffix will be at least as long as the previous ! 344: // one. ! 345: // ! 346: ! 347: fullDeviceName.Length -= deviceNameSuffix.Length; ! 348: } ! 349: } ! 350: ! 351: if (!NT_SUCCESS(status)) { ! 352: InpPrint(( ! 353: 1, ! 354: "INPORT-InportInitialize: Could not create port device object = %ws\n", ! 355: fullDeviceName.Buffer ! 356: )); ! 357: errorCode = INPORT_INSUFFICIENT_RESOURCES; ! 358: uniqueErrorValue = INPORT_ERROR_VALUE_BASE + 10; ! 359: dumpData[0] = (ULONG) i; ! 360: dumpCount = 1; ! 361: goto InportInitializeExit; ! 362: } ! 363: ! 364: // ! 365: // Do buffered I/O. I.e., the I/O system will copy to/from user data ! 366: // from/to a system buffer. ! 367: // ! 368: ! 369: portDeviceObject->Flags |= DO_BUFFERED_IO; ! 370: ! 371: // ! 372: // Set up the device extension. ! 373: // ! 374: ! 375: deviceExtension = ! 376: (PDEVICE_EXTENSION) portDeviceObject->DeviceExtension; ! 377: *deviceExtension = tmpDeviceExtension; ! 378: deviceExtension->DeviceObject = portDeviceObject; ! 379: ! 380: // ! 381: // Set up the device resource list prior to reporting resource usage. ! 382: // ! 383: ! 384: InpBuildResourceList(deviceExtension, &resources, &resourceListSize); ! 385: ! 386: // ! 387: // Report resource usage for the registry. ! 388: // ! 389: ! 390: IoReportResourceUsage( ! 391: &baseDeviceName, ! 392: DriverObject, ! 393: NULL, ! 394: 0, ! 395: portDeviceObject, ! 396: resources, ! 397: resourceListSize, ! 398: FALSE, ! 399: &conflictDetected ! 400: ); ! 401: ! 402: if (conflictDetected) { ! 403: ! 404: // ! 405: // Some other device already owns the ports or interrupts. ! 406: // Fatal error. ! 407: // ! 408: ! 409: InpPrint(( ! 410: 1, ! 411: "INPORT-InportInitialize: Resource usage conflict\n" ! 412: )); ! 413: ! 414: // ! 415: // Log an error. ! 416: // ! 417: ! 418: errorCode = INPORT_RESOURCE_CONFLICT; ! 419: uniqueErrorValue = INPORT_ERROR_VALUE_BASE + 15; ! 420: dumpData[0] = (ULONG) ! 421: resources->List[0].PartialResourceList.PartialDescriptors[0].u.Interrupt.Level; ! 422: dumpData[1] = (ULONG) ! 423: resources->List[0].PartialResourceList.PartialDescriptors[0].u.Interrupt.Vector; ! 424: dumpData[2] = (ULONG) ! 425: resources->List[0].PartialResourceList.PartialDescriptors[1].u.Interrupt.Level; ! 426: dumpData[3] = (ULONG) ! 427: resources->List[0].PartialResourceList.PartialDescriptors[1].u.Interrupt.Vector; ! 428: dumpCount = 4; ! 429: ! 430: goto InportInitializeExit; ! 431: ! 432: } ! 433: ! 434: // ! 435: // Map the Inport controller registers. ! 436: // ! 437: ! 438: addressSpace = (deviceExtension->Configuration.PortList[0].Flags ! 439: & CM_RESOURCE_PORT_IO) == CM_RESOURCE_PORT_IO? 1:0; ! 440: HalTranslateBusAddress( ! 441: deviceExtension->Configuration.InterfaceType, ! 442: deviceExtension->Configuration.BusNumber, ! 443: deviceExtension->Configuration.PortList[0].u.Port.Start, ! 444: &addressSpace, ! 445: &cardAddress ! 446: ); ! 447: ! 448: if (!addressSpace) { ! 449: ! 450: deviceExtension->Configuration.UnmapRegistersRequired = TRUE; ! 451: deviceExtension->Configuration.DeviceRegisters[0] = ! 452: MmMapIoSpace( ! 453: cardAddress, ! 454: deviceExtension->Configuration.PortList[0].u.Port.Length, ! 455: FALSE ! 456: ); ! 457: ! 458: } else { ! 459: ! 460: deviceExtension->Configuration.UnmapRegistersRequired = FALSE; ! 461: deviceExtension->Configuration.DeviceRegisters[0] = ! 462: (PVOID)cardAddress.LowPart; ! 463: ! 464: } ! 465: ! 466: if (!deviceExtension->Configuration.DeviceRegisters[0]) { ! 467: ! 468: InpPrint(( ! 469: 1, ! 470: "INPORT-InportInitialize: Couldn't map the device registers.\n" ! 471: )); ! 472: deviceExtension->Configuration.UnmapRegistersRequired = FALSE; ! 473: status = STATUS_NONE_MAPPED; ! 474: ! 475: // ! 476: // Log an error. ! 477: // ! 478: ! 479: errorCode = INPORT_REGISTERS_NOT_MAPPED; ! 480: uniqueErrorValue = INPORT_ERROR_VALUE_BASE + 20; ! 481: dumpData[0] = cardAddress.LowPart; ! 482: dumpCount = 1; ! 483: ! 484: goto InportInitializeExit; ! 485: ! 486: } ! 487: ! 488: // ! 489: // Initialize the Inport hardware to default values for the mouse. Note ! 490: // that interrupts remain disabled until the class driver ! 491: // requests a MOUSE_CONNECT internal device control. ! 492: // ! 493: ! 494: status = InpInitializeHardware(portDeviceObject); ! 495: ! 496: if (!NT_SUCCESS(status)) { ! 497: InpPrint(( ! 498: 1, ! 499: "INPORT-InportInitialize: Could not initialize hardware\n" ! 500: )); ! 501: goto InportInitializeExit; ! 502: } ! 503: ! 504: ! 505: // ! 506: // Allocate the ring buffer for the mouse input data. ! 507: // ! 508: ! 509: deviceExtension->InputData = ! 510: ExAllocatePool( ! 511: NonPagedPool, ! 512: deviceExtension->Configuration.MouseAttributes.InputDataQueueLength ! 513: ); ! 514: ! 515: if (!deviceExtension->InputData) { ! 516: ! 517: // ! 518: // Could not allocate memory for the mouse data queue. ! 519: // ! 520: ! 521: InpPrint(( ! 522: 1, ! 523: "INPORT-InportInitialize: Could not allocate mouse input data queue\n" ! 524: )); ! 525: ! 526: status = STATUS_INSUFFICIENT_RESOURCES; ! 527: ! 528: // ! 529: // Log an error. ! 530: // ! 531: ! 532: errorCode = INPORT_NO_BUFFER_ALLOCATED; ! 533: uniqueErrorValue = INPORT_ERROR_VALUE_BASE + 30; ! 534: dumpData[0] = ! 535: deviceExtension->Configuration.MouseAttributes.InputDataQueueLength; ! 536: dumpCount = 1; ! 537: ! 538: goto InportInitializeExit; ! 539: } ! 540: ! 541: deviceExtension->DataEnd = ! 542: (PMOUSE_INPUT_DATA) ((PCHAR) (deviceExtension->InputData) ! 543: + deviceExtension->Configuration.MouseAttributes.InputDataQueueLength); ! 544: ! 545: // ! 546: // Zero the mouse input data ring buffer. ! 547: // ! 548: ! 549: RtlZeroMemory( ! 550: deviceExtension->InputData, ! 551: deviceExtension->Configuration.MouseAttributes.InputDataQueueLength ! 552: ); ! 553: ! 554: // ! 555: // Initialize the connection data. ! 556: // ! 557: ! 558: deviceExtension->ConnectData.ClassDeviceObject = NULL; ! 559: deviceExtension->ConnectData.ClassService = NULL; ! 560: ! 561: // ! 562: // Initialize the input data queue. ! 563: // ! 564: ! 565: InpInitializeDataQueue((PVOID) deviceExtension); ! 566: ! 567: // ! 568: // Initialize the port ISR DPC. The ISR DPC is responsible for ! 569: // calling the connected class driver's callback routine to process ! 570: // the input data queue. ! 571: // ! 572: ! 573: deviceExtension->DpcInterlockVariable = -1; ! 574: ! 575: KeInitializeSpinLock(&deviceExtension->SpinLock); ! 576: ! 577: KeInitializeDpc( ! 578: &deviceExtension->IsrDpc, ! 579: (PKDEFERRED_ROUTINE) InportIsrDpc, ! 580: portDeviceObject ! 581: ); ! 582: ! 583: KeInitializeDpc( ! 584: &deviceExtension->IsrDpcRetry, ! 585: (PKDEFERRED_ROUTINE) InportIsrDpc, ! 586: portDeviceObject ! 587: ); ! 588: ! 589: // ! 590: // Initialize the mouse data consumption timer. ! 591: // ! 592: ! 593: KeInitializeTimer(&deviceExtension->DataConsumptionTimer); ! 594: ! 595: // ! 596: // Initialize the port DPC queue to log overrun and internal ! 597: // driver errors. ! 598: // ! 599: ! 600: KeInitializeDpc( ! 601: &deviceExtension->ErrorLogDpc, ! 602: (PKDEFERRED_ROUTINE) InportErrorLogDpc, ! 603: portDeviceObject ! 604: ); ! 605: ! 606: // ! 607: // From the Hal, get the interrupt vector and level. ! 608: // ! 609: ! 610: interruptVector = HalGetInterruptVector( ! 611: deviceExtension->Configuration.InterfaceType, ! 612: deviceExtension->Configuration.BusNumber, ! 613: deviceExtension->Configuration.MouseInterrupt.u.Interrupt.Level, ! 614: deviceExtension->Configuration.MouseInterrupt.u.Interrupt.Vector, ! 615: &interruptLevel, ! 616: &affinity ! 617: ); ! 618: ! 619: // ! 620: // Initialize and connect the interrupt object for the mouse. ! 621: // ! 622: ! 623: status = IoConnectInterrupt( ! 624: &(deviceExtension->InterruptObject), ! 625: (PKSERVICE_ROUTINE) InportInterruptService, ! 626: (PVOID) portDeviceObject, ! 627: (PKSPIN_LOCK)NULL, ! 628: interruptVector, ! 629: interruptLevel, ! 630: interruptLevel, ! 631: deviceExtension->Configuration.MouseInterrupt.Flags ! 632: == CM_RESOURCE_INTERRUPT_LATCHED ? Latched:LevelSensitive, ! 633: deviceExtension->Configuration.MouseInterrupt.ShareDisposition, ! 634: affinity, ! 635: deviceExtension->Configuration.FloatingSave ! 636: ); ! 637: ! 638: if (!NT_SUCCESS(status)) { ! 639: ! 640: // ! 641: // Failed to install. Free up resources before exiting. ! 642: // ! 643: ! 644: InpPrint(( ! 645: 1, ! 646: "INPORT-InportInitialize: Could not connect mouse interrupt\n" ! 647: )); ! 648: ! 649: // ! 650: // Log an error. ! 651: // ! 652: ! 653: errorCode = INPORT_NO_INTERRUPT_CONNECTED; ! 654: uniqueErrorValue = INPORT_ERROR_VALUE_BASE + 40; ! 655: dumpData[0] = interruptLevel; ! 656: dumpCount = 1; ! 657: ! 658: goto InportInitializeExit; ! 659: ! 660: } ! 661: ! 662: // ! 663: // Once initialization is finished, load the device map information ! 664: // into the registry so that setup can determine which pointer port ! 665: // is active. ! 666: // ! 667: ! 668: status = RtlWriteRegistryValue( ! 669: RTL_REGISTRY_DEVICEMAP, ! 670: baseDeviceName.Buffer, ! 671: fullDeviceName.Buffer, ! 672: REG_SZ, ! 673: registryPath.Buffer, ! 674: registryPath.Length ! 675: ); ! 676: ! 677: if (!NT_SUCCESS(status)) { ! 678: ! 679: InpPrint(( ! 680: 1, ! 681: "INPORT-InportInitialize: Could not store name in DeviceMap\n" ! 682: )); ! 683: ! 684: errorCode = INPORT_NO_DEVICEMAP_CREATED; ! 685: uniqueErrorValue = INPORT_ERROR_VALUE_BASE + 50; ! 686: dumpCount = 0; ! 687: ! 688: goto InportInitializeExit; ! 689: ! 690: } else { ! 691: ! 692: InpPrint(( ! 693: 1, ! 694: "INPORT-InportInitialize: Stored name in DeviceMap\n" ! 695: )); ! 696: } ! 697: ! 698: ASSERT(status == STATUS_SUCCESS); ! 699: ! 700: // ! 701: // Set up the device driver entry points. ! 702: // ! 703: ! 704: DriverObject->DriverStartIo = InportStartIo; ! 705: DriverObject->MajorFunction[IRP_MJ_CREATE] = InportOpenClose; ! 706: DriverObject->MajorFunction[IRP_MJ_CLOSE] = InportOpenClose; ! 707: DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = ! 708: InportFlush; ! 709: DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = ! 710: InportInternalDeviceControl; ! 711: ! 712: // ! 713: // NOTE: Don't allow this driver to unload. Otherwise, we would set ! 714: // DriverObject->DriverUnload = InportUnload. ! 715: // ! 716: ! 717: InportInitializeExit: ! 718: ! 719: // ! 720: // Log an error, if necessary. ! 721: // ! 722: ! 723: if (errorCode != STATUS_SUCCESS) { ! 724: errorLogEntry = (PIO_ERROR_LOG_PACKET) ! 725: IoAllocateErrorLogEntry( ! 726: (portDeviceObject == NULL) ? ! 727: (PVOID) DriverObject : (PVOID) portDeviceObject, ! 728: (UCHAR)(sizeof(IO_ERROR_LOG_PACKET) + (dumpCount * sizeof(ULONG))) ! 729: ); ! 730: ! 731: if (errorLogEntry != NULL) { ! 732: ! 733: errorLogEntry->ErrorCode = errorCode; ! 734: errorLogEntry->DumpDataSize = dumpCount * sizeof(ULONG); ! 735: errorLogEntry->SequenceNumber = 0; ! 736: errorLogEntry->MajorFunctionCode = 0; ! 737: errorLogEntry->IoControlCode = 0; ! 738: errorLogEntry->RetryCount = 0; ! 739: errorLogEntry->UniqueErrorValue = uniqueErrorValue; ! 740: errorLogEntry->FinalStatus = status; ! 741: for (i = 0; i < dumpCount; i++) ! 742: errorLogEntry->DumpData[i] = dumpData[i]; ! 743: ! 744: IoWriteErrorLogEntry(errorLogEntry); ! 745: } ! 746: } ! 747: ! 748: if (!NT_SUCCESS(status)) { ! 749: ! 750: // ! 751: // The initialization failed. Cleanup resources before exiting. ! 752: // ! 753: // Note: No need/way to undo the KeInitializeDpc or ! 754: // KeInitializeTimer calls. ! 755: // ! 756: ! 757: if (resources) { ! 758: ! 759: // ! 760: // Call IoReportResourceUsage to remove the resources from ! 761: // the map. ! 762: // ! 763: ! 764: resources->Count = 0; ! 765: ! 766: IoReportResourceUsage( ! 767: &baseDeviceName, ! 768: DriverObject, ! 769: NULL, ! 770: 0, ! 771: portDeviceObject, ! 772: resources, ! 773: resourceListSize, ! 774: FALSE, ! 775: &conflictDetected ! 776: ); ! 777: ! 778: } ! 779: ! 780: if (deviceExtension) { ! 781: if (deviceExtension->InterruptObject != NULL) ! 782: IoDisconnectInterrupt(deviceExtension->InterruptObject); ! 783: if (deviceExtension->Configuration.UnmapRegistersRequired) { ! 784: ! 785: MmUnmapIoSpace( ! 786: deviceExtension->Configuration.DeviceRegisters[0], ! 787: deviceExtension->Configuration.PortList[0].u.Port.Length ! 788: ); ! 789: } ! 790: if (deviceExtension->InputData) ! 791: ExFreePool(deviceExtension->InputData); ! 792: } ! 793: if (portDeviceObject) ! 794: IoDeleteDevice(portDeviceObject); ! 795: } ! 796: ! 797: // ! 798: // Free the resource list. ! 799: // ! 800: // N.B. If we ever decide to hang on to the resource list instead, ! 801: // we need to allocate it from non-paged pool (it is now paged pool). ! 802: // ! 803: ! 804: if (resources) ! 805: ExFreePool(resources); ! 806: ! 807: // ! 808: // Free the unicode strings. ! 809: // ! 810: ! 811: if (deviceNameSuffix.MaximumLength != 0) ! 812: ExFreePool(deviceNameSuffix.Buffer); ! 813: if (fullDeviceName.MaximumLength != 0) ! 814: ExFreePool(fullDeviceName.Buffer); ! 815: if (registryPath.MaximumLength != 0) ! 816: ExFreePool(registryPath.Buffer); ! 817: ! 818: InpPrint((1,"INPORT-InportInitialize: exit\n")); ! 819: ! 820: return(status); ! 821: ! 822: } ! 823: ! 824: BOOLEAN ! 825: InportInterruptService( ! 826: IN PKINTERRUPT Interrupt, ! 827: IN PVOID Context ! 828: ) ! 829: ! 830: /*++ ! 831: ! 832: Routine Description: ! 833: ! 834: This is the interrupt service routine for the mouse device. ! 835: ! 836: Arguments: ! 837: ! 838: Interrupt - A pointer to the interrupt object for this interrupt. ! 839: ! 840: Context - A pointer to the device object. ! 841: ! 842: Return Value: ! 843: ! 844: Returns TRUE if the interrupt was expected (and therefore processed); ! 845: otherwise, FALSE is returned. ! 846: ! 847: --*/ ! 848: ! 849: { ! 850: PDEVICE_EXTENSION deviceExtension; ! 851: PDEVICE_OBJECT deviceObject; ! 852: PUCHAR port; ! 853: UCHAR previousButtons; ! 854: UCHAR mode; ! 855: UCHAR status; ! 856: ! 857: UNREFERENCED_PARAMETER(Interrupt); ! 858: ! 859: InpPrint((2, "INPORT-InportInterruptService: enter\n")); ! 860: ! 861: // ! 862: // Get the device extension. ! 863: // ! 864: ! 865: deviceObject = (PDEVICE_OBJECT) Context; ! 866: deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; ! 867: ! 868: // ! 869: // Get the Inport mouse port address. ! 870: // ! 871: ! 872: port = deviceExtension->Configuration.DeviceRegisters[0]; ! 873: ! 874: // ! 875: // Note: It would be nice to verify that the interrupt really ! 876: // belongs to this driver, but it is currently not known how to ! 877: // make that determination. ! 878: // ! 879: ! 880: // ! 881: // Set the Inport hold bit. Note that there is a bug in the 1.1 version ! 882: // of the Inport chip in DATA mode. The interrupt signal doesn't get ! 883: // cleared in some cases, thus effectively disabling the device. The ! 884: // workaround is to set the HOLD bit twice. ! 885: // ! 886: ! 887: WRITE_PORT_UCHAR((PUCHAR) port, INPORT_MODE_REGISTER); ! 888: mode = READ_PORT_UCHAR((PUCHAR) (port + INPORT_DATA_REGISTER_1)); ! 889: WRITE_PORT_UCHAR( ! 890: (PUCHAR) (port + INPORT_DATA_REGISTER_1), ! 891: (UCHAR) (mode | INPORT_MODE_HOLD) ! 892: ); ! 893: WRITE_PORT_UCHAR( ! 894: (PUCHAR) (port + INPORT_DATA_REGISTER_1), ! 895: (UCHAR) (mode | INPORT_MODE_HOLD) ! 896: ); ! 897: ! 898: // ! 899: // Read the Inport status register. It contains the following information: ! 900: // ! 901: // XXXXXXXX ! 902: // | | |------ 1 if button 3 is down (right button) ! 903: // | |-------- 1 if button 1 is down (left button) ! 904: // |------------ 1 if the mouse has moved ! 905: // ! 906: ! 907: WRITE_PORT_UCHAR((PUCHAR) port, INPORT_STATUS_REGISTER); ! 908: status = READ_PORT_UCHAR((PUCHAR) (port + INPORT_DATA_REGISTER_1)); ! 909: ! 910: InpPrint((2, "INPORT-InportInterruptService: status byte 0x%x\n", status)); ! 911: ! 912: // ! 913: // Update CurrentInput with button transition data. ! 914: // I.e., set a button up/down bit in the Buttons field if ! 915: // the state of a given button has changed since we ! 916: // received the last packet. ! 917: // ! 918: ! 919: previousButtons = ! 920: deviceExtension->PreviousButtons; ! 921: ! 922: deviceExtension->CurrentInput.Buttons = 0; ! 923: ! 924: if ((!(previousButtons & INPORT_STATUS_BUTTON1)) ! 925: && (status & INPORT_STATUS_BUTTON1)) { ! 926: deviceExtension->CurrentInput.Buttons |= ! 927: MOUSE_LEFT_BUTTON_DOWN; ! 928: } else ! 929: if ((previousButtons & INPORT_STATUS_BUTTON1) ! 930: && !(status & INPORT_STATUS_BUTTON1)) { ! 931: deviceExtension->CurrentInput.Buttons |= ! 932: MOUSE_LEFT_BUTTON_UP; ! 933: } ! 934: if ((!(previousButtons & INPORT_STATUS_BUTTON3)) ! 935: && (status & INPORT_STATUS_BUTTON3)) { ! 936: deviceExtension->CurrentInput.Buttons |= ! 937: MOUSE_RIGHT_BUTTON_DOWN; ! 938: } else ! 939: if ((previousButtons & INPORT_STATUS_BUTTON3) ! 940: && !(status & INPORT_STATUS_BUTTON3)) { ! 941: deviceExtension->CurrentInput.Buttons |= ! 942: MOUSE_RIGHT_BUTTON_UP; ! 943: } ! 944: ! 945: // ! 946: // If the button position changed or the mouse moved, continue to process ! 947: // the interrupt. Otherwise, just clear the hold bit and ignore this ! 948: // interrupt's data. ! 949: // ! 950: ! 951: if (deviceExtension->CurrentInput.Buttons ! 952: || (status & INPORT_STATUS_MOVEMENT)) { ! 953: ! 954: deviceExtension->CurrentInput.UnitId = deviceExtension->UnitId; ! 955: ! 956: // ! 957: // Keep track of the state of the mouse buttons for the next ! 958: // interrupt. ! 959: // ! 960: ! 961: deviceExtension->PreviousButtons = ! 962: status & (INPORT_STATUS_BUTTON1 | INPORT_STATUS_BUTTON3); ! 963: ! 964: // ! 965: // If mouse movement was recorded, get the X and Y motion data. ! 966: // ! 967: ! 968: if (status & INPORT_STATUS_MOVEMENT) { ! 969: ! 970: // ! 971: // Select the Data1 register as the current data register, and ! 972: // get the X motion byte. ! 973: // ! 974: ! 975: WRITE_PORT_UCHAR((PUCHAR) port, INPORT_DATA_REGISTER_1); ! 976: deviceExtension->CurrentInput.LastX = ! 977: (LONG)(SCHAR) READ_PORT_UCHAR( ! 978: (PUCHAR) (port + INPORT_DATA_REGISTER_1)); ! 979: ! 980: // ! 981: // Select the Data2 register as the current data register, and ! 982: // get the Y motion byte. ! 983: // ! 984: ! 985: WRITE_PORT_UCHAR((PUCHAR) port, INPORT_DATA_REGISTER_2); ! 986: deviceExtension->CurrentInput.LastY = ! 987: (LONG)(SCHAR) READ_PORT_UCHAR( ! 988: (PUCHAR) (port + INPORT_DATA_REGISTER_1)); ! 989: } else { ! 990: deviceExtension->CurrentInput.LastX = 0; ! 991: deviceExtension->CurrentInput.LastY = 0; ! 992: } ! 993: ! 994: // ! 995: // Clear the Inport hold bit. ! 996: // ! 997: ! 998: WRITE_PORT_UCHAR((PUCHAR) port, INPORT_MODE_REGISTER); ! 999: mode = READ_PORT_UCHAR((PUCHAR) (port + INPORT_DATA_REGISTER_1)); ! 1000: WRITE_PORT_UCHAR( ! 1001: (PUCHAR) (port + INPORT_DATA_REGISTER_1), ! 1002: (UCHAR) (mode & ~INPORT_MODE_HOLD) ! 1003: ); ! 1004: ! 1005: // ! 1006: // Write the input data to the queue and request the ISR DPC to ! 1007: // finish processing the interrupt at DISPATCH_LEVEL. ! 1008: // ! 1009: ! 1010: if (!InpWriteDataToQueue( ! 1011: deviceExtension, ! 1012: &deviceExtension->CurrentInput ! 1013: )) { ! 1014: ! 1015: // ! 1016: // The mouse input data queue is full. Just drop the ! 1017: // latest input on the floor. ! 1018: // ! 1019: // Queue a DPC to log an overrun error. ! 1020: // ! 1021: ! 1022: InpPrint(( ! 1023: 1, ! 1024: "INPORT-InportInterruptService: queue overflow\n" ! 1025: )); ! 1026: ! 1027: if (deviceExtension->OkayToLogOverflow) { ! 1028: KeInsertQueueDpc( ! 1029: &deviceExtension->ErrorLogDpc, ! 1030: (PIRP) NULL, ! 1031: (PVOID) (ULONG) INPORT_MOU_BUFFER_OVERFLOW ! 1032: ); ! 1033: deviceExtension->OkayToLogOverflow = FALSE; ! 1034: } ! 1035: ! 1036: } else if (deviceExtension->DpcInterlockVariable >= 0) { ! 1037: ! 1038: // ! 1039: // The ISR DPC is already executing. Tell the ISR DPC it has ! 1040: // more work to do by incrementing the DpcInterlockVariable. ! 1041: // ! 1042: ! 1043: deviceExtension->DpcInterlockVariable += 1; ! 1044: ! 1045: } else { ! 1046: ! 1047: // ! 1048: // Queue the ISR DPC. ! 1049: // ! 1050: ! 1051: KeInsertQueueDpc( ! 1052: &deviceExtension->IsrDpc, ! 1053: deviceObject->CurrentIrp, ! 1054: NULL ! 1055: ); ! 1056: ! 1057: } ! 1058: ! 1059: } else { ! 1060: ! 1061: InpPrint(( ! 1062: 3, ! 1063: "INPORT-InportInterruptService: interrupt without button/motion change\n" ! 1064: )); ! 1065: ! 1066: ! 1067: // ! 1068: // Clear the Inport hold bit. ! 1069: // ! 1070: ! 1071: WRITE_PORT_UCHAR((PUCHAR) port, INPORT_MODE_REGISTER); ! 1072: mode = READ_PORT_UCHAR((PUCHAR) (port + INPORT_DATA_REGISTER_1)); ! 1073: WRITE_PORT_UCHAR( ! 1074: (PUCHAR) (port + INPORT_DATA_REGISTER_1), ! 1075: (UCHAR) (mode & ~INPORT_MODE_HOLD) ! 1076: ); ! 1077: ! 1078: } ! 1079: ! 1080: InpPrint((2, "INPORT-InportInterruptService: exit\n")); ! 1081: ! 1082: return(TRUE); ! 1083: } ! 1084: ! 1085: VOID ! 1086: InportUnload( ! 1087: IN PDRIVER_OBJECT DriverObject ! 1088: ) ! 1089: { ! 1090: UNREFERENCED_PARAMETER(DriverObject); ! 1091: ! 1092: InpPrint((2, "INPORT-InportUnload: enter\n")); ! 1093: InpPrint((2, "INPORT-InportUnload: exit\n")); ! 1094: } ! 1095: ! 1096: VOID ! 1097: InpBuildResourceList( ! 1098: IN PDEVICE_EXTENSION DeviceExtension, ! 1099: OUT PCM_RESOURCE_LIST *ResourceList, ! 1100: OUT PULONG ResourceListSize ! 1101: ) ! 1102: ! 1103: /*++ ! 1104: ! 1105: Routine Description: ! 1106: ! 1107: Creates a resource list that is used to query or report resource usage. ! 1108: ! 1109: Arguments: ! 1110: ! 1111: DeviceExtension - Pointer to the port's device extension. ! 1112: ! 1113: ResourceList - Pointer to a pointer to the resource list to be allocated ! 1114: and filled. ! 1115: ! 1116: ResourceListSize - Pointer to the returned size of the resource ! 1117: list (in bytes). ! 1118: ! 1119: Return Value: ! 1120: ! 1121: None. If the call succeeded, *ResourceList points to the built ! 1122: resource list and *ResourceListSize is set to the size (in bytes) ! 1123: of the resource list; otherwise, *ResourceList is NULL. ! 1124: ! 1125: Note: ! 1126: ! 1127: Memory is allocated here for *ResourceList. It must be ! 1128: freed up by the caller, by calling ExFreePool(); ! 1129: ! 1130: --*/ ! 1131: ! 1132: { ! 1133: ULONG count = 0; ! 1134: PIO_ERROR_LOG_PACKET errorLogEntry; ! 1135: ULONG i = 0; ! 1136: ULONG j = 0; ! 1137: ! 1138: count += DeviceExtension->Configuration.PortListCount; ! 1139: if (DeviceExtension->Configuration.MouseInterrupt.Type ! 1140: == CmResourceTypeInterrupt) ! 1141: count += 1; ! 1142: ! 1143: *ResourceListSize = sizeof(CM_RESOURCE_LIST) + ! 1144: ((count - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); ! 1145: ! 1146: *ResourceList = (PCM_RESOURCE_LIST) ExAllocatePool( ! 1147: PagedPool, ! 1148: *ResourceListSize ! 1149: ); ! 1150: ! 1151: // ! 1152: // Return NULL if the structure could not be allocated. ! 1153: // Otherwise, fill in the resource list. ! 1154: // ! 1155: ! 1156: if (!*ResourceList) { ! 1157: ! 1158: // ! 1159: // Could not allocate memory for the resource list. ! 1160: // ! 1161: ! 1162: InpPrint(( ! 1163: 1, ! 1164: "INPORT-InpBuildResourceList: Could not allocate resource list\n" ! 1165: )); ! 1166: ! 1167: // ! 1168: // Log an error. ! 1169: // ! 1170: ! 1171: errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry( ! 1172: DeviceExtension->DeviceObject, ! 1173: sizeof(IO_ERROR_LOG_PACKET) ! 1174: + sizeof(ULONG) ! 1175: ); ! 1176: ! 1177: if (errorLogEntry != NULL) { ! 1178: ! 1179: errorLogEntry->ErrorCode = INPORT_INSUFFICIENT_RESOURCES; ! 1180: errorLogEntry->DumpDataSize = sizeof(ULONG); ! 1181: errorLogEntry->SequenceNumber = 0; ! 1182: errorLogEntry->MajorFunctionCode = 0; ! 1183: errorLogEntry->IoControlCode = 0; ! 1184: errorLogEntry->RetryCount = 0; ! 1185: errorLogEntry->UniqueErrorValue = INPORT_ERROR_VALUE_BASE + 110; ! 1186: errorLogEntry->FinalStatus = STATUS_INSUFFICIENT_RESOURCES; ! 1187: errorLogEntry->DumpData[0] = *ResourceListSize; ! 1188: *ResourceListSize = 0; ! 1189: ! 1190: IoWriteErrorLogEntry(errorLogEntry); ! 1191: } ! 1192: ! 1193: return; ! 1194: ! 1195: } ! 1196: ! 1197: RtlZeroMemory( ! 1198: *ResourceList, ! 1199: *ResourceListSize ! 1200: ); ! 1201: ! 1202: // ! 1203: // Concoct one full resource descriptor. ! 1204: // ! 1205: ! 1206: (*ResourceList)->Count = 1; ! 1207: ! 1208: (*ResourceList)->List[0].InterfaceType = ! 1209: DeviceExtension->Configuration.InterfaceType; ! 1210: (*ResourceList)->List[0].BusNumber = ! 1211: DeviceExtension->Configuration.BusNumber; ! 1212: ! 1213: // ! 1214: // Build the partial resource descriptors for interrupt and port ! 1215: // resources from the saved values. ! 1216: // ! 1217: ! 1218: (*ResourceList)->List[0].PartialResourceList.Count = count; ! 1219: if (DeviceExtension->Configuration.MouseInterrupt.Type ! 1220: == CmResourceTypeInterrupt) ! 1221: (*ResourceList)->List[0].PartialResourceList.PartialDescriptors[i++] = ! 1222: DeviceExtension->Configuration.MouseInterrupt; ! 1223: ! 1224: for (j = 0; j < DeviceExtension->Configuration.PortListCount; j++) { ! 1225: (*ResourceList)->List[0].PartialResourceList.PartialDescriptors[i++] = ! 1226: DeviceExtension->Configuration.PortList[j]; ! 1227: } ! 1228: ! 1229: } ! 1230: ! 1231: VOID ! 1232: InpConfiguration( ! 1233: IN PDEVICE_EXTENSION DeviceExtension, ! 1234: IN PUNICODE_STRING RegistryPath, ! 1235: IN PUNICODE_STRING DeviceName ! 1236: ) ! 1237: ! 1238: /*++ ! 1239: ! 1240: Routine Description: ! 1241: ! 1242: This routine retrieves the configuration information for the mouse. ! 1243: ! 1244: Arguments: ! 1245: ! 1246: DeviceExtension - Pointer to the device extension. ! 1247: ! 1248: RegistryPath - Pointer to the null-terminated Unicode name of the ! 1249: registry path for this driver. ! 1250: ! 1251: DeviceName - Pointer to the Unicode string that will receive ! 1252: the port device name. ! 1253: ! 1254: Return Value: ! 1255: ! 1256: None. As a side-effect, may set DeviceExtension->HardwarePresent. ! 1257: ! 1258: --*/ ! 1259: { ! 1260: NTSTATUS status = STATUS_SUCCESS; ! 1261: PINPORT_CONFIGURATION_INFORMATION configuration; ! 1262: INTERFACE_TYPE interfaceType; ! 1263: CONFIGURATION_TYPE controllerType = PointerController; ! 1264: CONFIGURATION_TYPE peripheralType = PointerPeripheral; ! 1265: ULONG i; ! 1266: ! 1267: for (i = 0; i < MaximumInterfaceType; i++) { ! 1268: ! 1269: // ! 1270: // Get the registry information for this device. ! 1271: // ! 1272: ! 1273: interfaceType = i; ! 1274: status = IoQueryDeviceDescription(&interfaceType, ! 1275: NULL, ! 1276: &controllerType, ! 1277: NULL, ! 1278: &peripheralType, ! 1279: NULL, ! 1280: InpPeripheralCallout, ! 1281: (PVOID) DeviceExtension); ! 1282: ! 1283: if (DeviceExtension->HardwarePresent) { ! 1284: ! 1285: ! 1286: // ! 1287: // Get the service parameters (e.g., user-configurable ! 1288: // data input queue size, etc.). ! 1289: // ! 1290: ! 1291: InpServiceParameters(DeviceExtension, RegistryPath, DeviceName); ! 1292: configuration = &DeviceExtension->Configuration; ! 1293: ! 1294: // ! 1295: // Initialize mouse-specific configuration parameters. ! 1296: // ! 1297: ! 1298: configuration->MouseAttributes.MouseIdentifier = ! 1299: MOUSE_INPORT_HARDWARE; ! 1300: ! 1301: break; ! 1302: ! 1303: } else { ! 1304: ! 1305: InpPrint(( ! 1306: 1, ! 1307: "INPORT-InpConfiguration: IoQueryDeviceDescription for bus type %d failed\n", ! 1308: interfaceType ! 1309: )); ! 1310: } ! 1311: } ! 1312: } ! 1313: ! 1314: VOID ! 1315: InpDisableInterrupts( ! 1316: IN PVOID Context ! 1317: ) ! 1318: ! 1319: /*++ ! 1320: ! 1321: Routine Description: ! 1322: ! 1323: This routine is called from StartIo synchronously. It touches the ! 1324: hardware to disable interrupts. ! 1325: ! 1326: Arguments: ! 1327: ! 1328: Context - Pointer to the device extension. ! 1329: ! 1330: Return Value: ! 1331: ! 1332: None. ! 1333: ! 1334: --*/ ! 1335: ! 1336: { ! 1337: PUCHAR port; ! 1338: PLONG enableCount; ! 1339: UCHAR mode; ! 1340: ! 1341: // ! 1342: // Decrement the reference count for device enables. ! 1343: // ! 1344: ! 1345: enableCount = &((PDEVICE_EXTENSION) Context)->MouseEnableCount; ! 1346: *enableCount = *enableCount - 1; ! 1347: ! 1348: if (*enableCount == 0) { ! 1349: ! 1350: // ! 1351: // Get the port register address. ! 1352: // ! 1353: ! 1354: port = ((PDEVICE_EXTENSION) Context)->Configuration.DeviceRegisters[0]; ! 1355: ! 1356: // ! 1357: // Select the mode register as the current data register. ! 1358: // ! 1359: ! 1360: WRITE_PORT_UCHAR((PUCHAR) port, INPORT_MODE_REGISTER); ! 1361: ! 1362: // ! 1363: // Read the current mode. ! 1364: // ! 1365: ! 1366: mode = READ_PORT_UCHAR((PUCHAR) (port + INPORT_DATA_REGISTER_1)); ! 1367: ! 1368: // ! 1369: // Rewrite the mode byte with the interrupt disabled. ! 1370: // ! 1371: ! 1372: WRITE_PORT_UCHAR( ! 1373: (PUCHAR) (port + INPORT_DATA_REGISTER_1), ! 1374: (UCHAR) (mode & ~INPORT_DATA_INTERRUPT_ENABLE) ! 1375: ); ! 1376: } ! 1377: ! 1378: } ! 1379: ! 1380: VOID ! 1381: InpEnableInterrupts( ! 1382: IN PVOID Context ! 1383: ) ! 1384: ! 1385: /*++ ! 1386: ! 1387: Routine Description: ! 1388: ! 1389: This routine is called from StartIo synchronously. It touches the ! 1390: hardware to enable interrupts. ! 1391: ! 1392: Arguments: ! 1393: ! 1394: Context - Pointer to the device extension. ! 1395: ! 1396: Return Value: ! 1397: ! 1398: None. ! 1399: ! 1400: --*/ ! 1401: ! 1402: { ! 1403: PUCHAR port; ! 1404: PLONG enableCount; ! 1405: UCHAR mode; ! 1406: ! 1407: enableCount = &((PDEVICE_EXTENSION) Context)->MouseEnableCount; ! 1408: ! 1409: if (*enableCount == 0) { ! 1410: ! 1411: // ! 1412: // Get the port register address. ! 1413: // ! 1414: ! 1415: port = ((PDEVICE_EXTENSION) Context)->Configuration.DeviceRegisters[0]; ! 1416: ! 1417: // ! 1418: // Select the mode register as the current data register. ! 1419: // ! 1420: ! 1421: WRITE_PORT_UCHAR((PUCHAR) port, INPORT_MODE_REGISTER); ! 1422: ! 1423: // ! 1424: // Read the current mode. ! 1425: // ! 1426: ! 1427: mode = READ_PORT_UCHAR((PUCHAR) (port + INPORT_DATA_REGISTER_1)); ! 1428: ! 1429: // ! 1430: // Rewrite the mode byte with the interrupt enabled. ! 1431: // ! 1432: ! 1433: WRITE_PORT_UCHAR( ! 1434: (PUCHAR) (port + INPORT_DATA_REGISTER_1), ! 1435: (UCHAR) (mode | INPORT_DATA_INTERRUPT_ENABLE) ! 1436: ); ! 1437: } ! 1438: ! 1439: // ! 1440: // Increment the reference count for device enables. ! 1441: // ! 1442: ! 1443: *enableCount = *enableCount + 1; ! 1444: } ! 1445: ! 1446: NTSTATUS ! 1447: InpInitializeHardware( ! 1448: IN PDEVICE_OBJECT DeviceObject ! 1449: ) ! 1450: ! 1451: /*++ ! 1452: ! 1453: Routine Description: ! 1454: ! 1455: This routine initializes the Inport mouse. Note that this routine is ! 1456: only called at initialization time, so synchronization is not required. ! 1457: ! 1458: Arguments: ! 1459: ! 1460: DeviceObject - Pointer to the device object. ! 1461: ! 1462: Return Value: ! 1463: ! 1464: None. ! 1465: ! 1466: --*/ ! 1467: ! 1468: { ! 1469: PDEVICE_EXTENSION deviceExtension; ! 1470: PUCHAR mousePort; ! 1471: NTSTATUS status = STATUS_SUCCESS; ! 1472: ! 1473: InpPrint((2, "INPORT-InpInitializeHardware: enter\n")); ! 1474: ! 1475: // ! 1476: // Grab useful configuration parameters from the device extension. ! 1477: // ! 1478: ! 1479: deviceExtension = DeviceObject->DeviceExtension; ! 1480: mousePort = deviceExtension->Configuration.DeviceRegisters[0]; ! 1481: ! 1482: // ! 1483: // Reset the Inport chip, leaving interrupts off. ! 1484: // ! 1485: ! 1486: WRITE_PORT_UCHAR((PUCHAR) mousePort, INPORT_RESET); ! 1487: ! 1488: // ! 1489: // Select the mode register as the current data register. Set the ! 1490: // Inport mouse up for quadrature mode, and set the sample ! 1491: // rate (i.e., the interrupt Hz rate). Leave interrupts disabled. ! 1492: // ! 1493: ! 1494: WRITE_PORT_UCHAR((PUCHAR) mousePort, INPORT_MODE_REGISTER); ! 1495: WRITE_PORT_UCHAR( ! 1496: (PUCHAR) ((ULONG)mousePort + INPORT_DATA_REGISTER_1), ! 1497: (UCHAR) (deviceExtension->Configuration.HzMode ! 1498: | INPORT_MODE_QUADRATURE) ! 1499: ); ! 1500: ! 1501: InpPrint((2, "INPORT-InpInitializeHardware: exit\n")); ! 1502: ! 1503: return(status); ! 1504: ! 1505: } ! 1506: ! 1507: NTSTATUS ! 1508: InpPeripheralCallout( ! 1509: IN PVOID Context, ! 1510: IN PUNICODE_STRING PathName, ! 1511: IN INTERFACE_TYPE BusType, ! 1512: IN ULONG BusNumber, ! 1513: IN PKEY_VALUE_FULL_INFORMATION *BusInformation, ! 1514: IN CONFIGURATION_TYPE ControllerType, ! 1515: IN ULONG ControllerNumber, ! 1516: IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation, ! 1517: IN CONFIGURATION_TYPE PeripheralType, ! 1518: IN ULONG PeripheralNumber, ! 1519: IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation ! 1520: ) ! 1521: ! 1522: /*++ ! 1523: ! 1524: Routine Description: ! 1525: ! 1526: This is the callout routine sent as a parameter to ! 1527: IoQueryDeviceDescription. It grabs the pointer controller and ! 1528: peripheral configuration information. ! 1529: ! 1530: Arguments: ! 1531: ! 1532: Context - Context parameter that was passed in by the routine ! 1533: that called IoQueryDeviceDescription. ! 1534: ! 1535: PathName - The full pathname for the registry key. ! 1536: ! 1537: BusType - Bus interface type (Isa, Eisa, Mca, etc.). ! 1538: ! 1539: BusNumber - The bus sub-key (0, 1, etc.). ! 1540: ! 1541: BusInformation - Pointer to the array of pointers to the full value ! 1542: information for the bus. ! 1543: ! 1544: ControllerType - The controller type (should be PointerController). ! 1545: ! 1546: ControllerNumber - The controller sub-key (0, 1, etc.). ! 1547: ! 1548: ControllerInformation - Pointer to the array of pointers to the full ! 1549: value information for the controller key. ! 1550: ! 1551: PeripheralType - The peripheral type (should be PointerPeripheral). ! 1552: ! 1553: PeripheralNumber - The peripheral sub-key. ! 1554: ! 1555: PeripheralInformation - Pointer to the array of pointers to the full ! 1556: value information for the peripheral key. ! 1557: ! 1558: ! 1559: Return Value: ! 1560: ! 1561: None. If successful, will have the following side-effects: ! 1562: ! 1563: - Sets DeviceObject->DeviceExtension->HardwarePresent. ! 1564: - Sets configuration fields in ! 1565: DeviceObject->DeviceExtension->Configuration. ! 1566: ! 1567: --*/ ! 1568: { ! 1569: PDEVICE_EXTENSION deviceExtension; ! 1570: PINPORT_CONFIGURATION_INFORMATION configuration; ! 1571: UNICODE_STRING unicodeIdentifier; ! 1572: PUCHAR controllerData; ! 1573: NTSTATUS status = STATUS_SUCCESS; ! 1574: ULONG i; ! 1575: ULONG listCount; ! 1576: PCM_PARTIAL_RESOURCE_DESCRIPTOR resourceDescriptor; ! 1577: ANSI_STRING ansiString; ! 1578: BOOLEAN defaultInterruptShare; ! 1579: KINTERRUPT_MODE defaultInterruptMode; ! 1580: ! 1581: InpPrint(( ! 1582: 1, ! 1583: "INPORT-InpPeripheralCallout: Path @ 0x%x, Bus Type 0x%x, Bus Number 0x%x\n", ! 1584: PathName, BusType, BusNumber ! 1585: )); ! 1586: InpPrint(( ! 1587: 1, ! 1588: " Controller Type 0x%x, Controller Number 0x%x, Controller info @ 0x%x\n", ! 1589: ControllerType, ControllerNumber, ControllerInformation ! 1590: )); ! 1591: InpPrint(( ! 1592: 1, ! 1593: " Peripheral Type 0x%x, Peripheral Number 0x%x, Peripheral info @ 0x%x\n", ! 1594: PeripheralType, PeripheralNumber, PeripheralInformation ! 1595: )); ! 1596: ! 1597: // ! 1598: // Get the length of the peripheral identifier information. ! 1599: // ! 1600: ! 1601: unicodeIdentifier.Length = ! 1602: (*(PeripheralInformation + IoQueryDeviceIdentifier))->DataLength; ! 1603: ! 1604: // ! 1605: // If we already have the configuration information for the ! 1606: // mouse peripheral, or if the peripheral identifier is missing, ! 1607: // just return. ! 1608: // ! 1609: ! 1610: deviceExtension = (PDEVICE_EXTENSION) Context; ! 1611: if ((deviceExtension->HardwarePresent) || (unicodeIdentifier.Length == 0)){ ! 1612: return (status); ! 1613: } ! 1614: ! 1615: configuration = &deviceExtension->Configuration; ! 1616: ! 1617: // ! 1618: // Get the identifier information for the peripheral. ! 1619: // ! 1620: ! 1621: unicodeIdentifier.MaximumLength = unicodeIdentifier.Length; ! 1622: unicodeIdentifier.Buffer = (PWSTR) (((PUCHAR)(*(PeripheralInformation + ! 1623: IoQueryDeviceIdentifier))) + ! 1624: (*(PeripheralInformation + ! 1625: IoQueryDeviceIdentifier))->DataOffset); ! 1626: InpPrint(( ! 1627: 1, ! 1628: "INPORT-InpPeripheralCallout: Mouse type %ws\n", ! 1629: unicodeIdentifier.Buffer ! 1630: )); ! 1631: ! 1632: // ! 1633: // Verify that this is an Inport mouse. ! 1634: // ! 1635: ! 1636: status = RtlUnicodeStringToAnsiString( ! 1637: &ansiString, ! 1638: &unicodeIdentifier, ! 1639: TRUE ! 1640: ); ! 1641: ! 1642: if (!NT_SUCCESS(status)) { ! 1643: InpPrint(( ! 1644: 1, ! 1645: "INPORT-InpPeripheralCallout: Could not convert identifier to Ansi\n" ! 1646: )); ! 1647: return(status); ! 1648: } ! 1649: ! 1650: if (strstr(ansiString.Buffer, "INPORT")) { ! 1651: ! 1652: // ! 1653: // There is an Inport mouse present. ! 1654: // ! 1655: ! 1656: deviceExtension->HardwarePresent = TRUE; ! 1657: } ! 1658: ! 1659: RtlFreeAnsiString(&ansiString); ! 1660: ! 1661: if (!deviceExtension->HardwarePresent) { ! 1662: return(status); ! 1663: } ! 1664: ! 1665: // ! 1666: // Get the bus information. ! 1667: // ! 1668: ! 1669: configuration->InterfaceType = BusType; ! 1670: configuration->BusNumber = BusNumber; ! 1671: configuration->FloatingSave = INPORT_FLOATING_SAVE; ! 1672: ! 1673: if (BusType == MicroChannel) { ! 1674: defaultInterruptShare = TRUE; ! 1675: defaultInterruptMode = LevelSensitive; ! 1676: } else { ! 1677: defaultInterruptShare = INPORT_INTERRUPT_SHARE; ! 1678: defaultInterruptMode = INPORT_INTERRUPT_MODE; ! 1679: } ! 1680: ! 1681: // ! 1682: // Look through the resource list for interrupt and port ! 1683: // configuration information. ! 1684: // ! 1685: ! 1686: if ((*(ControllerInformation + IoQueryDeviceConfigurationData))->DataLength != 0){ ! 1687: controllerData = ((PUCHAR) (*(ControllerInformation + ! 1688: IoQueryDeviceConfigurationData))) + ! 1689: (*(ControllerInformation + ! 1690: IoQueryDeviceConfigurationData))->DataOffset; ! 1691: ! 1692: controllerData += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, ! 1693: PartialResourceList); ! 1694: ! 1695: listCount = ((PCM_PARTIAL_RESOURCE_LIST) controllerData)->Count; ! 1696: ! 1697: resourceDescriptor = ! 1698: ((PCM_PARTIAL_RESOURCE_LIST) controllerData)->PartialDescriptors; ! 1699: ! 1700: for (i = 0; i < listCount; i++, resourceDescriptor++) { ! 1701: switch(resourceDescriptor->Type) { ! 1702: case CmResourceTypePort: ! 1703: ! 1704: // ! 1705: // Copy the port information. Note that we only expect to ! 1706: // find one port range for the Inport mouse. ! 1707: // ! 1708: ! 1709: ASSERT(configuration->PortListCount == 0); ! 1710: configuration->PortList[configuration->PortListCount] = ! 1711: *resourceDescriptor; ! 1712: configuration->PortList[configuration->PortListCount].ShareDisposition = ! 1713: INPORT_REGISTER_SHARE? CmResourceShareShared: ! 1714: CmResourceShareDeviceExclusive; ! 1715: configuration->PortListCount += 1; ! 1716: ! 1717: break; ! 1718: ! 1719: case CmResourceTypeInterrupt: ! 1720: ! 1721: // ! 1722: // Copy the interrupt information. ! 1723: // ! 1724: ! 1725: configuration->MouseInterrupt = *resourceDescriptor; ! 1726: configuration->MouseInterrupt.ShareDisposition = ! 1727: defaultInterruptShare? CmResourceShareShared : ! 1728: CmResourceShareDeviceExclusive; ! 1729: ! 1730: break; ! 1731: ! 1732: default: ! 1733: break; ! 1734: } ! 1735: } ! 1736: } ! 1737: ! 1738: // ! 1739: // If no interrupt configuration information was found, use the ! 1740: // driver defaults. ! 1741: // ! 1742: ! 1743: if (!(configuration->MouseInterrupt.Type & CmResourceTypeInterrupt)) { ! 1744: ! 1745: InpPrint(( ! 1746: 1, ! 1747: "INPORT-InpPeripheralCallout: Using default mouse interrupt config\n" ! 1748: )); ! 1749: ! 1750: configuration->MouseInterrupt.Type = CmResourceTypeInterrupt; ! 1751: configuration->MouseInterrupt.ShareDisposition = ! 1752: defaultInterruptShare? CmResourceShareShared : ! 1753: CmResourceShareDeviceExclusive; ! 1754: configuration->MouseInterrupt.Flags = ! 1755: (defaultInterruptMode == Latched)? CM_RESOURCE_INTERRUPT_LATCHED : ! 1756: CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; ! 1757: configuration->MouseInterrupt.u.Interrupt.Level = MOUSE_IRQL; ! 1758: configuration->MouseInterrupt.u.Interrupt.Vector = MOUSE_VECTOR; ! 1759: } ! 1760: ! 1761: InpPrint(( ! 1762: 1, ! 1763: "INPORT-InpPeripheralCallout: Mouse interrupt config --\n" ! 1764: )); ! 1765: InpPrint(( ! 1766: 1, ! 1767: "%s, %s, Irq = %d\n", ! 1768: configuration->MouseInterrupt.ShareDisposition == CmResourceShareShared? ! 1769: "Sharable" : "NonSharable", ! 1770: configuration->MouseInterrupt.Flags == CM_RESOURCE_INTERRUPT_LATCHED? ! 1771: "Latched" : "Level Sensitive", ! 1772: configuration->MouseInterrupt.u.Interrupt.Vector ! 1773: )); ! 1774: ! 1775: // ! 1776: // If no port configuration information was found, use the ! 1777: // driver defaults. ! 1778: // ! 1779: ! 1780: if (configuration->PortListCount == 0) { ! 1781: ! 1782: // ! 1783: // No port configuration information was found, so use ! 1784: // the driver defaults. ! 1785: // ! 1786: ! 1787: InpPrint(( ! 1788: 1, ! 1789: "INPORT-InpPeripheralCallout: Using default port config\n" ! 1790: )); ! 1791: ! 1792: configuration->PortList[0].Type = CmResourceTypePort; ! 1793: configuration->PortList[0].Flags = INPORT_PORT_TYPE; ! 1794: configuration->PortList[0].Flags = CM_RESOURCE_PORT_IO; ! 1795: configuration->PortList[0].ShareDisposition = ! 1796: INPORT_REGISTER_SHARE? CmResourceShareShared: ! 1797: CmResourceShareDeviceExclusive; ! 1798: configuration->PortList[0].u.Port.Start.LowPart = ! 1799: INPORT_PHYSICAL_BASE; ! 1800: configuration->PortList[0].u.Port.Start.HighPart = 0; ! 1801: configuration->PortList[0].u.Port.Length = INPORT_REGISTER_LENGTH; ! 1802: ! 1803: configuration->PortListCount = 1; ! 1804: } ! 1805: ! 1806: for (i = 0; i < configuration->PortListCount; i++) { ! 1807: ! 1808: InpPrint(( ! 1809: 1, ! 1810: "%s, Ports 0x%x - 0x%x\n", ! 1811: configuration->PortList[i].ShareDisposition ! 1812: == CmResourceShareShared? "Sharable" : "NonSharable", ! 1813: configuration->PortList[i].u.Port.Start.LowPart, ! 1814: configuration->PortList[i].u.Port.Start.LowPart + ! 1815: configuration->PortList[i].u.Port.Length - 1 ! 1816: )); ! 1817: } ! 1818: ! 1819: return(status); ! 1820: } ! 1821: ! 1822: VOID ! 1823: InpServiceParameters( ! 1824: IN PDEVICE_EXTENSION DeviceExtension, ! 1825: IN PUNICODE_STRING RegistryPath, ! 1826: IN PUNICODE_STRING DeviceName ! 1827: ) ! 1828: ! 1829: /*++ ! 1830: ! 1831: Routine Description: ! 1832: ! 1833: This routine retrieves this driver's service parameters information ! 1834: from the registry. ! 1835: ! 1836: Arguments: ! 1837: ! 1838: DeviceExtension - Pointer to the device extension. ! 1839: ! 1840: RegistryPath - Pointer to the null-terminated Unicode name of the ! 1841: registry path for this driver. ! 1842: ! 1843: DeviceName - Pointer to the Unicode string that will receive ! 1844: the port device name. ! 1845: ! 1846: Return Value: ! 1847: ! 1848: None. As a side-effect, sets fields in DeviceExtension->Configuration. ! 1849: ! 1850: --*/ ! 1851: ! 1852: { ! 1853: PINPORT_CONFIGURATION_INFORMATION configuration; ! 1854: PRTL_QUERY_REGISTRY_TABLE parameters = NULL; ! 1855: UNICODE_STRING parametersPath; ! 1856: ULONG defaultDataQueueSize = DATA_QUEUE_SIZE; ! 1857: ULONG numberOfButtons = MOUSE_NUMBER_OF_BUTTONS; ! 1858: USHORT defaultNumberOfButtons = MOUSE_NUMBER_OF_BUTTONS; ! 1859: ULONG sampleRate = MOUSE_SAMPLE_RATE_50HZ; ! 1860: USHORT defaultSampleRate = MOUSE_SAMPLE_RATE_50HZ; ! 1861: ULONG hzMode = INPORT_MODE_50HZ; ! 1862: USHORT defaultHzMode = INPORT_MODE_50HZ; ! 1863: UNICODE_STRING defaultUnicodeName; ! 1864: NTSTATUS status = STATUS_SUCCESS; ! 1865: PWSTR path = NULL; ! 1866: USHORT queriesPlusOne = 6; ! 1867: ! 1868: configuration = &DeviceExtension->Configuration; ! 1869: parametersPath.Buffer = NULL; ! 1870: ! 1871: // ! 1872: // Registry path is already null-terminated, so just use it. ! 1873: // ! 1874: ! 1875: path = RegistryPath->Buffer; ! 1876: ! 1877: if (NT_SUCCESS(status)) { ! 1878: ! 1879: // ! 1880: // Allocate the Rtl query table. ! 1881: // ! 1882: ! 1883: parameters = ExAllocatePool( ! 1884: PagedPool, ! 1885: sizeof(RTL_QUERY_REGISTRY_TABLE) * queriesPlusOne ! 1886: ); ! 1887: ! 1888: if (!parameters) { ! 1889: ! 1890: InpPrint(( ! 1891: 1, ! 1892: "INPORT-InpServiceParameters: Couldn't allocate table for Rtl query to parameters for %ws\n", ! 1893: path ! 1894: )); ! 1895: ! 1896: status = STATUS_UNSUCCESSFUL; ! 1897: ! 1898: } else { ! 1899: ! 1900: RtlZeroMemory( ! 1901: parameters, ! 1902: sizeof(RTL_QUERY_REGISTRY_TABLE) * queriesPlusOne ! 1903: ); ! 1904: ! 1905: // ! 1906: // Form a path to this driver's Parameters subkey. ! 1907: // ! 1908: ! 1909: RtlInitUnicodeString( ! 1910: ¶metersPath, ! 1911: NULL ! 1912: ); ! 1913: ! 1914: parametersPath.MaximumLength = RegistryPath->Length + ! 1915: sizeof(L"\\Parameters"); ! 1916: ! 1917: parametersPath.Buffer = ExAllocatePool( ! 1918: PagedPool, ! 1919: parametersPath.MaximumLength ! 1920: ); ! 1921: ! 1922: if (!parametersPath.Buffer) { ! 1923: ! 1924: InpPrint(( ! 1925: 1, ! 1926: "INPORT-InpServiceParameters: Couldn't allocate string for path to parameters for %ws\n", ! 1927: path ! 1928: )); ! 1929: ! 1930: status = STATUS_UNSUCCESSFUL; ! 1931: ! 1932: } ! 1933: } ! 1934: } ! 1935: ! 1936: if (NT_SUCCESS(status)) { ! 1937: ! 1938: // ! 1939: // Form the parameters path. ! 1940: // ! 1941: ! 1942: RtlZeroMemory( ! 1943: parametersPath.Buffer, ! 1944: parametersPath.MaximumLength ! 1945: ); ! 1946: RtlAppendUnicodeToString( ! 1947: ¶metersPath, ! 1948: path ! 1949: ); ! 1950: RtlAppendUnicodeToString( ! 1951: ¶metersPath, ! 1952: L"\\Parameters" ! 1953: ); ! 1954: ! 1955: InpPrint(( ! 1956: 1, ! 1957: "INPORT-InpServiceParameters: parameters path is %ws\n", ! 1958: parametersPath.Buffer ! 1959: )); ! 1960: ! 1961: // ! 1962: // Form the default pointer port device name, in case it is not ! 1963: // specified in the registry. ! 1964: // ! 1965: ! 1966: RtlInitUnicodeString( ! 1967: &defaultUnicodeName, ! 1968: DD_POINTER_PORT_BASE_NAME_U ! 1969: ); ! 1970: ! 1971: // ! 1972: // Gather all of the "user specified" information from ! 1973: // the registry. ! 1974: // ! 1975: ! 1976: parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT; ! 1977: parameters[0].Name = L"MouseDataQueueSize"; ! 1978: parameters[0].EntryContext = ! 1979: &configuration->MouseAttributes.InputDataQueueLength; ! 1980: parameters[0].DefaultType = REG_DWORD; ! 1981: parameters[0].DefaultData = &defaultDataQueueSize; ! 1982: parameters[0].DefaultLength = sizeof(ULONG); ! 1983: ! 1984: parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT; ! 1985: parameters[1].Name = L"NumberOfButtons"; ! 1986: parameters[1].EntryContext = &numberOfButtons; ! 1987: parameters[1].DefaultType = REG_DWORD; ! 1988: parameters[1].DefaultData = &defaultNumberOfButtons; ! 1989: parameters[1].DefaultLength = sizeof(USHORT); ! 1990: ! 1991: parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT; ! 1992: parameters[2].Name = L"SampleRate"; ! 1993: parameters[2].EntryContext = &sampleRate; ! 1994: parameters[2].DefaultType = REG_DWORD; ! 1995: parameters[2].DefaultData = &defaultSampleRate; ! 1996: parameters[2].DefaultLength = sizeof(USHORT); ! 1997: ! 1998: parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT; ! 1999: parameters[3].Name = L"HzMode"; ! 2000: parameters[3].EntryContext = &hzMode; ! 2001: parameters[3].DefaultType = REG_DWORD; ! 2002: parameters[3].DefaultData = &defaultHzMode; ! 2003: parameters[3].DefaultLength = sizeof(USHORT); ! 2004: ! 2005: parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT; ! 2006: parameters[4].Name = L"PointerDeviceBaseName"; ! 2007: parameters[4].EntryContext = DeviceName; ! 2008: parameters[4].DefaultType = REG_SZ; ! 2009: parameters[4].DefaultData = defaultUnicodeName.Buffer; ! 2010: parameters[4].DefaultLength = 0; ! 2011: ! 2012: status = RtlQueryRegistryValues( ! 2013: RTL_REGISTRY_ABSOLUTE, ! 2014: parametersPath.Buffer, ! 2015: parameters, ! 2016: NULL, ! 2017: NULL ! 2018: ); ! 2019: ! 2020: if (!NT_SUCCESS(status)) { ! 2021: InpPrint(( ! 2022: 1, ! 2023: "INPORT-InpServiceParameters: RtlQueryRegistryValues failed with 0x%x\n", ! 2024: status ! 2025: )); ! 2026: } ! 2027: } ! 2028: ! 2029: if (!NT_SUCCESS(status)) { ! 2030: ! 2031: // ! 2032: // Go ahead and assign driver defaults. ! 2033: // ! 2034: ! 2035: configuration->MouseAttributes.InputDataQueueLength = ! 2036: defaultDataQueueSize; ! 2037: RtlCopyUnicodeString(DeviceName, &defaultUnicodeName); ! 2038: } ! 2039: ! 2040: InpPrint(( ! 2041: 1, ! 2042: "INPORT-InpServiceParameters: Pointer port base name = %ws\n", ! 2043: DeviceName->Buffer ! 2044: )); ! 2045: ! 2046: if (configuration->MouseAttributes.InputDataQueueLength == 0) { ! 2047: ! 2048: InpPrint(( ! 2049: 1, ! 2050: "INPORT-InpServiceParameters: overriding MouseInputDataQueueLength = 0x%x\n", ! 2051: configuration->MouseAttributes.InputDataQueueLength ! 2052: )); ! 2053: ! 2054: configuration->MouseAttributes.InputDataQueueLength = ! 2055: defaultDataQueueSize; ! 2056: } ! 2057: ! 2058: configuration->MouseAttributes.InputDataQueueLength *= ! 2059: sizeof(MOUSE_INPUT_DATA); ! 2060: ! 2061: InpPrint(( ! 2062: 1, ! 2063: "INPORT-InpServiceParameters: MouseInputDataQueueLength = 0x%x\n", ! 2064: configuration->MouseAttributes.InputDataQueueLength ! 2065: )); ! 2066: ! 2067: configuration->MouseAttributes.NumberOfButtons = numberOfButtons; ! 2068: InpPrint(( ! 2069: 1, ! 2070: "INPORT-InpServiceParameters: NumberOfButtons = %d\n", ! 2071: configuration->MouseAttributes.NumberOfButtons ! 2072: )); ! 2073: ! 2074: configuration->MouseAttributes.SampleRate = sampleRate; ! 2075: InpPrint(( ! 2076: 1, ! 2077: "INPORT-InpServiceParameters: SampleRate = %d\n", ! 2078: configuration->MouseAttributes.SampleRate ! 2079: )); ! 2080: ! 2081: configuration->HzMode = hzMode; ! 2082: InpPrint(( ! 2083: 1, ! 2084: "INPORT-InpServiceParameters: HzMode = %d\n", ! 2085: configuration->HzMode ! 2086: )); ! 2087: ! 2088: // ! 2089: // Free the allocated memory before returning. ! 2090: // ! 2091: ! 2092: if (parametersPath.Buffer) ! 2093: ExFreePool(parametersPath.Buffer); ! 2094: if (parameters) ! 2095: ExFreePool(parameters); ! 2096: ! 2097: } ! 2098: ! 2099: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.