Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
5.3 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. services.c
  5. Abstract
  6. Service entry points exposed by the HID class driver.
  7. Author:
  8. Forrest Foltz
  9. Ervin P.
  10. Environment:
  11. Kernel mode only
  12. Revision History:
  13. --*/
  14. #include "pch.h"
  15. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text(PAGE, HidRegisterMinidriver)
  17. #endif
  18. /*
  19. ********************************************************************************
  20. * HidRegisterMinidriver
  21. ********************************************************************************
  22. *
  23. * Routine Description:
  24. *
  25. * This public service is called by a HidOnXxx minidriver from its
  26. * driverentry routine to register itself as a newly loaded HID minidriver.
  27. *
  28. * It creates a HIDCLASS_DRIVER_EXTENSION and returns it as reference data
  29. * to the minidriver.
  30. *
  31. * Arguments:
  32. *
  33. * MinidriverRegistration - pointer to a registration packet that must be
  34. * completely filled in by the minidriver.
  35. *
  36. * Return Value:
  37. *
  38. * Standard NT return value.
  39. *
  40. *
  41. */
  42. NTSTATUS HidRegisterMinidriver(IN PHID_MINIDRIVER_REGISTRATION MinidriverRegistration)
  43. {
  44. PHIDCLASS_DRIVER_EXTENSION hidDriverExtension;
  45. PDRIVER_EXTENSION driverExtension;
  46. PDRIVER_OBJECT minidriverObject;
  47. NTSTATUS status;
  48. PUNICODE_STRING regPath;
  49. PAGED_CODE();
  50. if (MinidriverRegistration->Revision > HID_REVISION){
  51. DBGERR(("Revision mismatch: HIDCLASS revision is %xh, minidriver requires hidclass revision %xh.", HID_REVISION, MinidriverRegistration->Revision))
  52. status = STATUS_REVISION_MISMATCH;
  53. goto HidRegisterMinidriverExit;
  54. }
  55. /*
  56. * Allocate a driver extension for this driver object
  57. * and associate it with the object.
  58. * (By using this interface, we never have to free
  59. * this context; it gets freed when the driver object
  60. * is freed).
  61. */
  62. status = IoAllocateDriverObjectExtension(
  63. MinidriverRegistration->DriverObject,
  64. (PVOID)"HIDCLASS",
  65. sizeof(HIDCLASS_DRIVER_EXTENSION),
  66. &hidDriverExtension
  67. );
  68. if (!NT_SUCCESS(status)){
  69. goto HidRegisterMinidriverExit;
  70. }
  71. RtlZeroMemory(hidDriverExtension, sizeof(HIDCLASS_DRIVER_EXTENSION));
  72. //
  73. // Fill in various fields in our per-minidriver extension.
  74. //
  75. hidDriverExtension->MinidriverObject = MinidriverRegistration->DriverObject;
  76. hidDriverExtension->DeviceExtensionSize = MinidriverRegistration->DeviceExtensionSize;
  77. #if DBG
  78. hidDriverExtension->Signature = HID_DRIVER_EXTENSION_SIG;
  79. #endif
  80. //
  81. // Copy the regpath.
  82. //
  83. regPath = &hidDriverExtension->RegistryPath;
  84. regPath->MaximumLength = MinidriverRegistration->RegistryPath->Length
  85. + sizeof (UNICODE_NULL);
  86. regPath->Buffer = ALLOCATEPOOL(NonPagedPool, regPath->MaximumLength);
  87. if (!regPath->Buffer) {
  88. DBGWARN(("Failed unicode string alloc."))
  89. status = STATUS_INSUFFICIENT_RESOURCES;
  90. goto HidRegisterMinidriverExit;
  91. }
  92. RtlCopyUnicodeString(regPath, MinidriverRegistration->RegistryPath);
  93. //
  94. // Make a copy of the minidriver's original dispatch table and AddDevice routine
  95. //
  96. minidriverObject = MinidriverRegistration->DriverObject;
  97. RtlCopyMemory( hidDriverExtension->MajorFunction,
  98. minidriverObject->MajorFunction,
  99. sizeof( PDRIVER_DISPATCH ) * (IRP_MJ_MAXIMUM_FUNCTION + 1) );
  100. driverExtension = minidriverObject->DriverExtension;
  101. hidDriverExtension->DevicesArePolled = MinidriverRegistration->DevicesArePolled;
  102. //
  103. // Now set the minidriver's major dispatch functions (the ones that
  104. // we care about) to our dispatch routine instead
  105. //
  106. minidriverObject->MajorFunction[ IRP_MJ_CLOSE ] =
  107. minidriverObject->MajorFunction[ IRP_MJ_CREATE ] =
  108. minidriverObject->MajorFunction[ IRP_MJ_DEVICE_CONTROL ] =
  109. minidriverObject->MajorFunction[ IRP_MJ_INTERNAL_DEVICE_CONTROL ] =
  110. minidriverObject->MajorFunction[ IRP_MJ_PNP ] =
  111. minidriverObject->MajorFunction[ IRP_MJ_POWER ] =
  112. minidriverObject->MajorFunction[ IRP_MJ_READ ] =
  113. minidriverObject->MajorFunction[ IRP_MJ_WRITE ] =
  114. minidriverObject->MajorFunction[ IRP_MJ_SYSTEM_CONTROL ] =
  115. HidpMajorHandler;
  116. /*
  117. * Hook the lower driver's AddDevice;
  118. * our HidpAddDevice will chain the call down to the
  119. * miniport's handler.
  120. */
  121. ASSERT(driverExtension->AddDevice);
  122. hidDriverExtension->AddDevice = driverExtension->AddDevice;
  123. driverExtension->AddDevice = HidpAddDevice;
  124. /*
  125. * Hook the lower driver's Unload
  126. */
  127. ASSERT(minidriverObject->DriverUnload);
  128. hidDriverExtension->DriverUnload = minidriverObject->DriverUnload;
  129. minidriverObject->DriverUnload = HidpDriverUnload;
  130. /*
  131. * Initialize the ReferenceCount to zero.
  132. * It will be incremented for each AddDevice and decremented for
  133. * each REMOVE_DEVICE.
  134. */
  135. hidDriverExtension->ReferenceCount = 0;
  136. //
  137. // Place the hid driver extension on our global list so we can find
  138. // it later (given a pointer to the minidriver object for which it
  139. // was created
  140. //
  141. if (!EnqueueDriverExt(hidDriverExtension)){
  142. status = STATUS_DEVICE_CONFIGURATION_ERROR;
  143. }
  144. HidRegisterMinidriverExit:
  145. DBGSUCCESS(status, TRUE)
  146. return status;
  147. }