Leaked source code of windows server 2003
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.

428 lines
9.8 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. oprghdlr.c
  5. Abstract:
  6. This module contains the code that implements ACPI op region
  7. registration DLL
  8. Author:
  9. Vincent Geglia (vincentg) 09-Feb-2000
  10. Environment:
  11. Kernel mode
  12. Notes:
  13. Revision History:
  14. --*/
  15. //
  16. // Standard includes
  17. //
  18. #include "stdarg.h"
  19. #include "stdio.h"
  20. #include "wdm.h"
  21. //
  22. // Oprghdlr dll specific includes
  23. //
  24. #include "oprghdlr.h"
  25. //
  26. // Definitions / static definitions
  27. //
  28. #define DEBUG_INFO 1
  29. #define DEBUG_WARN 2
  30. #define DEBUG_ERROR 4
  31. static const UCHAR DebugPrepend[] = {'O', 'P', 'R', 'G', 'H', 'D', 'L', 'R', ':'};
  32. //
  33. // IRP_MJ_INTERNAL_DEVICE_CONTROL CODES
  34. //
  35. #define IOCTL_ACPI_REGISTER_OPREGION_HANDLER CTL_CODE(FILE_DEVICE_ACPI, 0x2, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
  36. #define IOCTL_ACPI_UNREGISTER_OPREGION_HANDLER CTL_CODE(FILE_DEVICE_ACPI, 0x3, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
  37. //
  38. // Signatures for Register, Unregister of OpRegions
  39. //
  40. #define ACPI_REGISTER_OPREGION_HANDLER_BUFFER_SIGNATURE 'HorA'
  41. #define ACPI_UNREGISTER_OPREGION_HANDLER_BUFFER_SIGNATURE 'HouA'
  42. //
  43. // Globals / Externals
  44. //
  45. extern ULONG OprghdlrDebugLevel = 0;
  46. //
  47. // Structures / type definitions
  48. //
  49. typedef struct _ACPI_REGISTER_OPREGION_HANDLER_BUFFER {
  50. ULONG Signature;
  51. ULONG AccessType;
  52. ULONG RegionSpace;
  53. PACPI_OP_REGION_HANDLER Handler;
  54. PVOID Context;
  55. } ACPI_REGISTER_OPREGION_HANDLER_BUFFER, *PACPI_REGISTER_OPREGION_HANDLER_BUFFER;
  56. typedef struct _ACPI_UNREGISTER_OPREGION_HANDLER_BUFFER {
  57. ULONG Signature;
  58. PVOID OperationRegionObject;
  59. } ACPI_UNREGISTER_OPREGION_HANDLER_BUFFER,*PACPI_UNREGISTER_OPREGION_HANDLER_BUFFER;
  60. //
  61. // Define the local routines used by this driver module.
  62. //
  63. VOID
  64. DebugPrint (
  65. IN ULONG DebugLevel,
  66. IN PUCHAR DebugMessage,
  67. ...
  68. );
  69. NTSTATUS
  70. DriverEntry (
  71. PDRIVER_OBJECT DriverObject,
  72. PUNICODE_STRING RegistryPath
  73. );
  74. //
  75. // Function code
  76. //
  77. NTSTATUS
  78. RegisterOpRegionHandler (
  79. IN PDEVICE_OBJECT DeviceObject,
  80. IN ULONG AccessType,
  81. IN ULONG RegionSpace,
  82. IN PACPI_OP_REGION_HANDLER Handler,
  83. IN PVOID Context,
  84. IN ULONG Flags,
  85. IN OUT PVOID *OperationRegionObject
  86. )
  87. /*++
  88. Routine Description:
  89. This is the operation region registration routine. It builds the appropriate
  90. IOCTL, and sends it to ACPI to register the op region handler.
  91. Arguments:
  92. DeviceObject - Pointer to device object for ACPI PDO
  93. AccessType - Specifies accesstype for which to register the op region handler
  94. (see oprghdlr.h)
  95. RegionSpace - Specifies the region space type for which the op region handler should
  96. be called for
  97. Handler - Pointer to a function that will handle the op region accesses
  98. Context - Context passed to handler when op region access occurs
  99. OperationRegionObject - Contains a pointer to the op region object returned by ACPI
  100. Return Value:
  101. STATUS_SUCCESS if sucessful, otherwise error status.
  102. --*/
  103. {
  104. ACPI_REGISTER_OPREGION_HANDLER_BUFFER inputData;
  105. ACPI_UNREGISTER_OPREGION_HANDLER_BUFFER outputData;
  106. IO_STATUS_BLOCK ioStatus;
  107. KEVENT event;
  108. NTSTATUS status = STATUS_SUCCESS;
  109. PIRP irp;
  110. DebugPrint (DEBUG_INFO,
  111. "Entering RegisterOpRegionHandler\n");
  112. //
  113. // Zero out IOCTL buffers
  114. //
  115. RtlZeroMemory (&inputData, sizeof (inputData));
  116. RtlZeroMemory (&outputData, sizeof (outputData));
  117. //
  118. // Init our synchronization event
  119. //
  120. KeInitializeEvent (&event, SynchronizationEvent, FALSE);
  121. //
  122. // Set up the IOCTL buffer
  123. //
  124. inputData.Signature = ACPI_REGISTER_OPREGION_HANDLER_BUFFER_SIGNATURE;
  125. inputData.AccessType = AccessType;
  126. inputData.RegionSpace = RegionSpace;
  127. inputData.Handler = Handler;
  128. inputData.Context = Context;
  129. //
  130. // Build the IOCTL
  131. //
  132. irp = IoBuildDeviceIoControlRequest (IOCTL_ACPI_REGISTER_OPREGION_HANDLER,
  133. DeviceObject,
  134. &inputData,
  135. sizeof(ACPI_REGISTER_OPREGION_HANDLER_BUFFER),
  136. &outputData,
  137. sizeof(ACPI_UNREGISTER_OPREGION_HANDLER_BUFFER),
  138. FALSE,
  139. &event,
  140. &ioStatus);
  141. if (!irp) {
  142. return STATUS_INSUFFICIENT_RESOURCES;
  143. }
  144. //
  145. // Send to ACPI driver
  146. //
  147. status = IoCallDriver (DeviceObject, irp);
  148. if (status == STATUS_PENDING) {
  149. //
  150. // Wait for request to be completed
  151. //
  152. KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
  153. //
  154. // Get the real status
  155. //
  156. status = ioStatus.Status;
  157. }
  158. //
  159. // Check the status code
  160. //
  161. if (!NT_SUCCESS(status)) {
  162. DebugPrint (DEBUG_ERROR,
  163. "Registration IRP was failed by ACPI (%lx)\n",
  164. status);
  165. return status;
  166. }
  167. //
  168. // Check the signature
  169. //
  170. if (outputData.Signature != ACPI_UNREGISTER_OPREGION_HANDLER_BUFFER_SIGNATURE) {
  171. status = STATUS_ACPI_INVALID_DATA;
  172. DebugPrint (DEBUG_ERROR,
  173. "Signature returned from ACPI is invalid. Registration failed.\n");
  174. return status;
  175. }
  176. *OperationRegionObject = outputData.OperationRegionObject;
  177. return status;
  178. }
  179. NTSTATUS
  180. DeRegisterOpRegionHandler (
  181. IN PDEVICE_OBJECT DeviceObject,
  182. IN PVOID OperationRegionObject
  183. )
  184. /*++
  185. Routine Description:
  186. This is the operation region deregistration routine. It builds the appropriate
  187. IOCTL, and sends it to ACPI to deregister the op region handler.
  188. Arguments:
  189. DeviceObject - Pointer to device object for ACPI PDO
  190. OperationRegionObject - Contains a pointer to the op region object returned
  191. during registration
  192. Return Value:
  193. STATUS_SUCCESS if sucessful, otherwise error status.
  194. --*/
  195. {
  196. ACPI_UNREGISTER_OPREGION_HANDLER_BUFFER inputData;
  197. IO_STATUS_BLOCK ioStatus;
  198. KEVENT event;
  199. NTSTATUS status;
  200. PIRP irp;
  201. DebugPrint (DEBUG_INFO,
  202. "Entering DeRegisterOpRegionHandler\n");
  203. //
  204. // Zero out IOCTL buffer
  205. //
  206. RtlZeroMemory (&inputData, sizeof (inputData));
  207. //
  208. // Init our synchronization event
  209. //
  210. KeInitializeEvent (&event, SynchronizationEvent, FALSE);
  211. //
  212. // Set up the IOCTL buffer
  213. //
  214. inputData.Signature = ACPI_UNREGISTER_OPREGION_HANDLER_BUFFER_SIGNATURE;
  215. inputData.OperationRegionObject = OperationRegionObject;
  216. //
  217. // Build the IOCTL
  218. //
  219. irp = IoBuildDeviceIoControlRequest (IOCTL_ACPI_UNREGISTER_OPREGION_HANDLER,
  220. DeviceObject,
  221. &inputData,
  222. sizeof(ACPI_REGISTER_OPREGION_HANDLER_BUFFER),
  223. NULL,
  224. 0,
  225. FALSE,
  226. &event,
  227. &ioStatus);
  228. if (!irp) {
  229. return STATUS_INSUFFICIENT_RESOURCES;
  230. }
  231. //
  232. // Send to ACPI driver
  233. //
  234. status = IoCallDriver (DeviceObject, irp);
  235. if (status == STATUS_PENDING) {
  236. //
  237. // Wait for request to be completed
  238. //
  239. KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
  240. //
  241. // Get the real status
  242. //
  243. status = ioStatus.Status;
  244. }
  245. //
  246. // Check the status code
  247. //
  248. if (!NT_SUCCESS(status)) {
  249. DebugPrint (DEBUG_ERROR,
  250. "Deregistration IRP was failed by ACPI (%lx)\n",
  251. status);
  252. }
  253. return status;
  254. }
  255. VOID
  256. DebugPrint (
  257. IN ULONG DebugLevel,
  258. IN PUCHAR DebugMessage,
  259. ...
  260. )
  261. /*++
  262. Routine Description:
  263. This is the general debug printing routine.
  264. Arguments:
  265. DebugLevel - Debug level for which this message should be printed
  266. DebugMessage - Pointer to a buffer for the message to be printed
  267. ... - Variable length argument list
  268. Return Value:
  269. None
  270. --*/
  271. {
  272. UCHAR Text[200];
  273. va_list va;
  274. RtlCopyMemory (Text, DebugPrepend, sizeof (DebugPrepend));
  275. va_start (va, DebugMessage);
  276. vsprintf ((PVOID) ((ULONG_PTR) Text + sizeof (DebugPrepend)), DebugMessage, va);
  277. va_end (va);
  278. if (OprghdlrDebugLevel & DebugLevel) {
  279. DbgPrint (Text);
  280. }
  281. }
  282. /*++
  283. Routine Description:
  284. Required DriverEntry routine. Not used as this is an EXPORT_DRIVER type.
  285. Arguments:
  286. DriverObject - Address of DriverObject
  287. RegistryPath - Address of the registry path
  288. Return Value:
  289. STATUS_SUCCESS, always
  290. --*/
  291. NTSTATUS
  292. DriverEntry (
  293. PDRIVER_OBJECT DriverObject,
  294. PUNICODE_STRING RegistryPath
  295. )
  296. {
  297. return STATUS_SUCCESS;
  298. }