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.

296 lines
7.1 KiB

  1. /*++
  2. Copyright (c) 1996,1997 Microsoft Corporation
  3. Module Name:
  4. hidir.c
  5. Abstract: Human Input Device (HID) minidriver that creates an example
  6. device.
  7. --*/
  8. #include "pch.h"
  9. VOID
  10. HidIrCheckIfMediaCenter();
  11. #ifdef ALLOC_PRAGMA
  12. #pragma alloc_text(INIT,DriverEntry)
  13. #pragma alloc_text(INIT,HidIrCheckIfMediaCenter)
  14. #endif
  15. NTSTATUS
  16. DriverEntry(
  17. IN PDRIVER_OBJECT DriverObject,
  18. IN PUNICODE_STRING registryPath
  19. )
  20. /*++
  21. Routine Description:
  22. Installable driver initialization entry point.
  23. This entry point is called directly by the I/O system.
  24. Arguments:
  25. DriverObject - pointer to the driver object
  26. registryPath - pointer to a unicode string representing the path,
  27. to driver-specific key in the registry.
  28. Return Value:
  29. STATUS_SUCCESS if successful,
  30. STATUS_UNSUCCESSFUL otherwise
  31. --*/
  32. {
  33. NTSTATUS status = STATUS_SUCCESS;
  34. HID_MINIDRIVER_REGISTRATION HidIrdriverRegistration;
  35. HidIrKdPrint((3, "DriverEntry Enter"));
  36. HidIrKdPrint((3, "DriverObject (%lx)", DriverObject));
  37. //
  38. // Create dispatch points
  39. //
  40. // All of the other dispatch routines are handled by HIDCLASS, except for
  41. // IRP_MJ_POWER, which isn't implemented yet.
  42. //
  43. DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = HidIrIoctl;
  44. DriverObject->MajorFunction[IRP_MJ_PNP] = HidIrPnP;
  45. DriverObject->MajorFunction[IRP_MJ_POWER] = HidIrPower;
  46. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HidIrSystemControl;
  47. DriverObject->DriverExtension->AddDevice = HidIrAddDevice;
  48. DriverObject->DriverUnload = HidIrUnload;
  49. //
  50. // Register Sample layer with HIDCLASS.SYS module
  51. //
  52. HidIrdriverRegistration.Revision = HID_REVISION;
  53. HidIrdriverRegistration.DriverObject = DriverObject;
  54. HidIrdriverRegistration.RegistryPath = registryPath;
  55. HidIrdriverRegistration.DeviceExtensionSize = sizeof(HIDIR_EXTENSION);
  56. // HIDIR does not need to be polled.
  57. HidIrdriverRegistration.DevicesArePolled = FALSE;
  58. HidIrKdPrint((3, "DeviceExtensionSize = %x", HidIrdriverRegistration.DeviceExtensionSize));
  59. HidIrKdPrint((3, "Registering with HIDCLASS.SYS"));
  60. HidIrCheckIfMediaCenter();
  61. //
  62. // After registering with HIDCLASS, it takes over control of the device, and sends
  63. // things our way if they need device specific processing.
  64. //
  65. status = HidRegisterMinidriver(&HidIrdriverRegistration);
  66. HidIrKdPrint((3, "DriverEntry Exit = %x", status));
  67. return status;
  68. }
  69. ULONG RunningMediaCenter;
  70. VOID
  71. HidIrCheckIfMediaCenter()
  72. {
  73. OBJECT_ATTRIBUTES attributes;
  74. HANDLE skuRegKey;
  75. NTSTATUS status;
  76. ULONG resultLength;
  77. UNICODE_STRING regString;
  78. UCHAR buffer[sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof( ULONG )];
  79. PAGED_CODE();
  80. RunningMediaCenter = 0;
  81. //
  82. // Open the MediaCenter SKU registry key
  83. //
  84. RtlInitUnicodeString( &regString, L"\\REGISTRY\\MACHINE\\SYSTEM\\WPA\\MediaCenter" );
  85. InitializeObjectAttributes( &attributes,
  86. &regString,
  87. OBJ_CASE_INSENSITIVE,
  88. NULL,
  89. NULL );
  90. status = ZwOpenKey( &skuRegKey,
  91. KEY_READ,
  92. &attributes );
  93. if (!NT_SUCCESS( status )) {
  94. return;
  95. }
  96. //
  97. // Read the Installed value from the registry.
  98. //
  99. RtlInitUnicodeString( &regString, L"Installed" );
  100. status = ZwQueryValueKey( skuRegKey,
  101. &regString,
  102. KeyValuePartialInformation,
  103. buffer,
  104. sizeof(buffer),
  105. &resultLength );
  106. if (NT_SUCCESS( status )) {
  107. PKEY_VALUE_PARTIAL_INFORMATION info = (PKEY_VALUE_PARTIAL_INFORMATION) buffer;
  108. if (info->DataLength == sizeof(ULONG)) {
  109. RunningMediaCenter = *((ULONG*) &((info)->Data));
  110. }
  111. }
  112. //
  113. // Close the registry entry
  114. //
  115. ZwClose(skuRegKey);
  116. }
  117. NTSTATUS
  118. HidIrAddDevice(
  119. IN PDRIVER_OBJECT DriverObject,
  120. IN PDEVICE_OBJECT DeviceObject
  121. )
  122. /*++
  123. Routine Description:
  124. Process AddDevice. Provides the opportunity to initialize the DeviceObject or the
  125. DriverObject.
  126. Arguments:
  127. DriverObject - pointer to the driver object.
  128. DeviceObject - pointer to a device object.
  129. Return Value:
  130. NT status code.
  131. --*/
  132. {
  133. NTSTATUS status = STATUS_SUCCESS;
  134. PHIDIR_EXTENSION deviceExtension;
  135. LARGE_INTEGER timeout;
  136. timeout.HighPart = -1;
  137. timeout.LowPart = -1;
  138. HidIrKdPrint((3, "HidIrAddDevice Entry"));
  139. deviceExtension = GET_MINIDRIVER_HIDIR_EXTENSION( DeviceObject );
  140. deviceExtension->NumPendingRequests = 0;
  141. KeInitializeEvent( &deviceExtension->AllRequestsCompleteEvent,
  142. NotificationEvent,
  143. FALSE);
  144. deviceExtension->DeviceState = DEVICE_STATE_NONE;
  145. deviceExtension->DeviceObject = DeviceObject;
  146. deviceExtension->VersionNumber = 0x110;
  147. // deviceExtension->VendorID = 0x045e;
  148. // deviceExtension->ProductID = 0x006d;
  149. // Predispose timer to signalled.
  150. KeInitializeTimer(&deviceExtension->IgnoreStandbyTimer);
  151. KeSetTimer(&deviceExtension->IgnoreStandbyTimer, timeout, NULL);
  152. HidIrKdPrint((3, "HidIrAddDevice Exit = %x", status));
  153. return status;
  154. }
  155. VOID
  156. HidIrUnload(
  157. IN PDRIVER_OBJECT DriverObject
  158. )
  159. /*++
  160. Routine Description:
  161. Free all the allocated resources, etc. in anticipation of this driver being unloaded.
  162. Arguments:
  163. DriverObject - pointer to the driver object.
  164. Return Value:
  165. VOID.
  166. --*/
  167. {
  168. HidIrKdPrint((3, "HidIrUnload Enter"));
  169. HidIrKdPrint((3, "Unloading DriverObject = %x", DriverObject));
  170. HidIrKdPrint((3, "Unloading Exit = VOID"));
  171. }
  172. NTSTATUS
  173. HidIrSynchronousCompletion(
  174. IN PDEVICE_OBJECT DeviceObject,
  175. IN PIRP Irp,
  176. IN PVOID Context
  177. )
  178. {
  179. UNREFERENCED_PARAMETER (DeviceObject);
  180. KeSetEvent ((PKEVENT) Context, 1, FALSE);
  181. // No special priority
  182. // No Wait
  183. return STATUS_MORE_PROCESSING_REQUIRED; // Keep this IRP
  184. }
  185. NTSTATUS
  186. HidIrCallDriverSynchronous(
  187. PDEVICE_OBJECT DeviceObject,
  188. PIRP Irp
  189. )
  190. {
  191. KEVENT event;
  192. NTSTATUS status;
  193. // Set next stack location
  194. KeInitializeEvent(&event, NotificationEvent, FALSE);
  195. IoCopyCurrentIrpStackLocationToNext(Irp);
  196. IoSetCompletionRoutine(Irp,
  197. HidIrSynchronousCompletion,
  198. &event, // context
  199. TRUE,
  200. TRUE,
  201. TRUE );
  202. status = IoCallDriver(GET_NEXT_DEVICE_OBJECT(DeviceObject), Irp);
  203. if (status == STATUS_PENDING) {
  204. // wait for it...
  205. KeWaitForSingleObject(&event,
  206. Executive,
  207. KernelMode,
  208. FALSE,
  209. NULL);
  210. status = Irp->IoStatus.Status;
  211. }
  212. return status;
  213. }