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.

284 lines
8.4 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1998 - 1998
  3. Module Name:
  4. wmi.c
  5. Abstract:
  6. This module contains the code that handles the wmi IRPs for
  7. parallel driver PDOs and PODOs.
  8. Environment:
  9. Kernel mode
  10. Revision History :
  11. --*/
  12. #include "pch.h"
  13. #include <wmistr.h>
  14. #include "wmipdo.h"
  15. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text(PAGEPARWMI0, ParWmiPdoInitWmi)
  17. #pragma alloc_text(PAGEPARWMI0, ParWmiPdoSystemControlDispatch)
  18. #pragma alloc_text(PAGEPARWMI0, ParWmiPdoQueryWmiRegInfo)
  19. #pragma alloc_text(PAGEPARWMI0, ParWmiPdoQueryWmiDataBlock)
  20. #endif
  21. #define PAR_WMI_PDO_GUID_COUNT 1
  22. #define PAR_WMI_BYTES_TRANSFERRED_GUID_INDEX 0
  23. GUID ParWmiPdoBytesTransferredGuid = PARALLEL_WMI_BYTES_TRANSFERRED_GUID;
  24. WMIGUIDREGINFO ParWmiPdoGuidList[ PAR_WMI_PDO_GUID_COUNT ] =
  25. {
  26. { &ParWmiPdoBytesTransferredGuid, 1, 0 }
  27. };
  28. NTSTATUS
  29. ParWmiPdoInitWmi(PDEVICE_OBJECT DeviceObject)
  30. {
  31. PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
  32. PWMILIB_CONTEXT wmiContext = &devExt->WmiLibContext;
  33. PAGED_CODE();
  34. wmiContext->GuidCount = sizeof(ParWmiPdoGuidList) / sizeof(WMIGUIDREGINFO);
  35. wmiContext->GuidList = ParWmiPdoGuidList;
  36. wmiContext->QueryWmiRegInfo = ParWmiPdoQueryWmiRegInfo;
  37. wmiContext->QueryWmiDataBlock = ParWmiPdoQueryWmiDataBlock;
  38. wmiContext->SetWmiDataBlock = NULL;
  39. wmiContext->SetWmiDataItem = NULL;
  40. wmiContext->ExecuteWmiMethod = NULL;
  41. wmiContext->WmiFunctionControl = NULL;
  42. return ParWMIRegistrationControl( DeviceObject, WMIREG_ACTION_REGISTER );
  43. }
  44. NTSTATUS
  45. ParWmiPdoSystemControlDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
  46. {
  47. SYSCTL_IRP_DISPOSITION disposition;
  48. NTSTATUS status;
  49. PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
  50. PAGED_CODE();
  51. status = WmiSystemControl( &pDevExt->WmiLibContext, DeviceObject, Irp, &disposition);
  52. switch(disposition) {
  53. case IrpProcessed:
  54. //
  55. // This irp has been processed and may be completed or pending.
  56. //
  57. break;
  58. case IrpNotCompleted:
  59. //
  60. // This irp has not been completed, but has been fully processed.
  61. // we will complete it now
  62. //
  63. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  64. break;
  65. case IrpForward:
  66. case IrpNotWmi:
  67. default:
  68. //
  69. // This irp is either not a WMI irp or is a WMI irp targetted
  70. // at a device lower in the stack.
  71. //
  72. // If this was an FDO we would pass the IRP down the stack, but
  73. // this is a PDO (or PODO) so there no one below us in the
  74. // stack.
  75. //
  76. Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
  77. status = STATUS_INVALID_DEVICE_REQUEST;
  78. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  79. break;
  80. }
  81. return status;
  82. }
  83. NTSTATUS
  84. ParWmiPdoQueryWmiRegInfo(
  85. IN PDEVICE_OBJECT PDevObj,
  86. OUT PULONG PRegFlags,
  87. OUT PUNICODE_STRING PInstanceName,
  88. OUT PUNICODE_STRING *PRegistryPath,
  89. OUT PUNICODE_STRING MofResourceName,
  90. OUT PDEVICE_OBJECT *Pdo
  91. )
  92. {
  93. PDEVICE_EXTENSION devExt = (PDEVICE_EXTENSION)PDevObj->DeviceExtension;
  94. PAGED_CODE();
  95. if( ParIsPodo(PDevObj) ) {
  96. // This is a PODO
  97. PWSTR buffer = ExAllocatePool(PagedPool, devExt->SymbolicLinkName.MaximumLength);
  98. ParDumpV( ("wmipdo::ParWmiPdoQueryWmiRegInfo: PODO - %wZ\n", &devExt->SymbolicLinkName) );
  99. if( !buffer ) {
  100. PInstanceName->Length = 0;
  101. PInstanceName->MaximumLength = 0;
  102. PInstanceName->Buffer = NULL;
  103. } else {
  104. PInstanceName->Length = 0;
  105. PInstanceName->MaximumLength = devExt->SymbolicLinkName.MaximumLength;
  106. PInstanceName->Buffer = buffer;
  107. *PRegFlags = WMIREG_FLAG_INSTANCE_BASENAME;
  108. RtlCopyUnicodeString( PInstanceName, &devExt->SymbolicLinkName );
  109. }
  110. *PRegistryPath = &RegistryPath;
  111. } else {
  112. // this is a PDO
  113. ParDumpV( ("wmipdo::ParWmiPdoQueryWmiRegInfo: PDO - %x\n", PDevObj) );
  114. *PRegFlags = WMIREG_FLAG_INSTANCE_PDO;
  115. *PRegistryPath = &RegistryPath;
  116. *Pdo = PDevObj;
  117. }
  118. return STATUS_SUCCESS;
  119. }
  120. NTSTATUS
  121. ParWmiPdoQueryWmiDataBlock(
  122. IN PDEVICE_OBJECT DeviceObject,
  123. IN PIRP Irp,
  124. IN ULONG GuidIndex,
  125. IN ULONG InstanceIndex,
  126. IN ULONG InstanceCount,
  127. IN OUT PULONG InstanceLengthArray,
  128. IN ULONG OutBufferSize,
  129. OUT PUCHAR Buffer
  130. )
  131. {
  132. NTSTATUS status;
  133. ULONG size = sizeof(PARALLEL_WMI_LOG_INFO);
  134. PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
  135. PAGED_CODE();
  136. //
  137. // Only ever registers 1 instance per guid
  138. //
  139. ASSERT(InstanceIndex == 0 && InstanceCount == 1);
  140. switch (GuidIndex) {
  141. case PAR_WMI_BYTES_TRANSFERRED_GUID_INDEX:
  142. //
  143. // Request is for Bytes Transferred
  144. //
  145. if (OutBufferSize < size) {
  146. status = STATUS_BUFFER_TOO_SMALL;
  147. break;
  148. }
  149. *( (PPARALLEL_WMI_LOG_INFO)Buffer ) = devExt->log;
  150. *InstanceLengthArray = size;
  151. status = STATUS_SUCCESS;
  152. break;
  153. default:
  154. //
  155. // Index value larger than our largest supported - invalid request
  156. //
  157. status = STATUS_WMI_GUID_NOT_FOUND;
  158. break;
  159. }
  160. status = WmiCompleteRequest( DeviceObject, Irp, status, size, IO_NO_INCREMENT );
  161. return status;
  162. }
  163. NTSTATUS
  164. ParWMIRegistrationControl(
  165. IN PDEVICE_OBJECT DeviceObject,
  166. IN ULONG Action
  167. )
  168. /*+
  169. Wrapper function for IoWMIRegistrationControl that uses Device
  170. Extension variable WmiRegistrationCount to prevent device from
  171. registering more than once or from unregistering if not
  172. registered.
  173. -*/
  174. {
  175. PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
  176. NTSTATUS status;
  177. LONG count;
  178. ParDumpV( ("wmipdo::ParWMIRegistrationControl: enter - %wZ\n", &devExt->SymbolicLinkName) );
  179. switch( Action ) {
  180. case WMIREG_ACTION_REGISTER :
  181. //
  182. // Verify that we don't register more than once
  183. //
  184. count = InterlockedIncrement(&devExt->WmiRegistrationCount);
  185. if( count == 1 ) {
  186. status = IoWMIRegistrationControl(DeviceObject, Action);
  187. if( !NT_SUCCESS(status) ) {
  188. ParDumpV( ("wmipdo::ParWMIRegistrationControl: REGISTER - FAIL\n") );
  189. // registration failed - back out the increment
  190. InterlockedDecrement(&devExt->WmiRegistrationCount);
  191. } else {
  192. ParDumpV( ("wmipdo::ParWMIRegistrationControl: REGISTER - SUCCEED\n") );
  193. }
  194. } else {
  195. ParDumpV( ("wmipdo::ParWMIRegistrationControl: REGISTER - ABORT - already REGISTERed\n") );
  196. // back out the increment
  197. InterlockedDecrement(&devExt->WmiRegistrationCount);
  198. status = STATUS_UNSUCCESSFUL;
  199. // ASSERTMSG( "Already registered for WMI registration, fail registration", FALSE );
  200. }
  201. break;
  202. case WMIREG_ACTION_DEREGISTER :
  203. //
  204. // verify that we don't unregister if we are not registered
  205. //
  206. count = InterlockedDecrement(&devExt->WmiRegistrationCount);
  207. if( count == 0 ) {
  208. status = IoWMIRegistrationControl(DeviceObject, Action);
  209. if( !NT_SUCCESS(status) ) {
  210. ParDumpV( ("wmipdo::ParWMIRegistrationControl: DEREGISTER - FAIL\n") );
  211. // unregistration failed?
  212. // ASSERTMSG( "WMI unregistration failed?", FALSE );
  213. InterlockedIncrement(&devExt->WmiRegistrationCount);
  214. } else {
  215. ParDumpV( ("wmipdo::ParWMIRegistrationControl: DEREGISTER - SUCCEED\n") );
  216. }
  217. } else {
  218. ParDumpV( ("wmipdo::ParWMIRegistrationControl: DEREGISTER - ABORT - not registered\n") );
  219. // unregistration failed - back out the decrement
  220. InterlockedIncrement(&devExt->WmiRegistrationCount);
  221. status = STATUS_UNSUCCESSFUL;
  222. // ASSERTMSG( "Not registered for WMI, fail unregister", FALSE );
  223. }
  224. break;
  225. default:
  226. // unrecognized action
  227. status = STATUS_UNSUCCESSFUL;
  228. ASSERTMSG("wmipdo::ParWMIRegistrationControl: Unrecognized WMI registration Action \n",FALSE);
  229. }
  230. return status;
  231. }