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.

238 lines
6.5 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: wmi.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "pch.h"
  11. #include <wmistr.h>
  12. #ifdef ALLOC_PRAGMA
  13. #pragma alloc_text(PAGEPARWMI0, PptWmiInitWmi)
  14. #pragma alloc_text(PAGEPARWMI0, PptWmiQueryWmiRegInfo)
  15. #pragma alloc_text(PAGEPARWMI0, PptWmiQueryWmiDataBlock)
  16. #endif
  17. //
  18. // Number of WMI GUIDs that we support
  19. //
  20. #define PPT_WMI_PDO_GUID_COUNT 1
  21. //
  22. // Index of GUID PptWmiAllocFreeCountsGuid in the array of supported WMI GUIDs
  23. //
  24. #define PPT_WMI_ALLOC_FREE_COUNTS_GUID_INDEX 0
  25. //
  26. // defined in wmidata.h:
  27. //
  28. // // {4BBB69EA-6853-11d2-8ECE-00C04F8EF481}
  29. // #define PARPORT_WMI_ALLOCATE_FREE_COUNTS_GUID {0x4bbb69ea, 0x6853, 0x11d2, 0x8e, 0xce, 0x0, 0xc0, 0x4f, 0x8e, 0xf4, 0x81}
  30. //
  31. // typedef struct _PARPORT_WMI_ALLOC_FREE_COUNTS {
  32. // ULONG PortAllocates; // number of Port Allocate requests granted
  33. // ULONG PortFrees; // number of Port Free requests granted
  34. // } PARPORT_WMI_ALLOC_FREE_COUNTS, *PPARPORT_WMI_ALLOC_FREE_COUNTS;
  35. //
  36. //
  37. // Define the (only at the moment) WMI GUID that we support
  38. //
  39. GUID PptWmiAllocFreeCountsGuid = PARPORT_WMI_ALLOCATE_FREE_COUNTS_GUID;
  40. //
  41. // Array of WMI GUIDs supported by driver
  42. //
  43. WMIGUIDREGINFO PptWmiGuidList[ PPT_WMI_PDO_GUID_COUNT ] =
  44. {
  45. { &PptWmiAllocFreeCountsGuid, 1, 0 }
  46. };
  47. //
  48. // Initialize WMI Context that we pass to WMILIB during the handling of
  49. // IRP_MJ_SYSTEM_CONTROL. This context lives in our device extension
  50. //
  51. // Register w/WMI that we are able to process WMI IRPs
  52. //
  53. NTSTATUS
  54. PptWmiInitWmi(PDEVICE_OBJECT DeviceObject)
  55. {
  56. PFDO_EXTENSION devExt = DeviceObject->DeviceExtension;
  57. PWMILIB_CONTEXT wmiContext = &devExt->WmiLibContext;
  58. PAGED_CODE();
  59. wmiContext->GuidCount = sizeof(PptWmiGuidList) / sizeof(WMIGUIDREGINFO);
  60. wmiContext->GuidList = PptWmiGuidList;
  61. wmiContext->QueryWmiRegInfo = PptWmiQueryWmiRegInfo; // required
  62. wmiContext->QueryWmiDataBlock = PptWmiQueryWmiDataBlock; // required
  63. wmiContext->SetWmiDataBlock = NULL; // optional
  64. wmiContext->SetWmiDataItem = NULL; // optional
  65. wmiContext->ExecuteWmiMethod = NULL; // optional
  66. wmiContext->WmiFunctionControl = NULL; // optional
  67. // Tell WMI that we can now accept WMI IRPs
  68. return IoWMIRegistrationControl( DeviceObject, WMIREG_ACTION_REGISTER );
  69. }
  70. NTSTATUS
  71. //
  72. // This is the dispatch routine for IRP_MJ_SYSTEM_CONTROL IRPs.
  73. //
  74. // We call WMILIB to process the IRP for us. WMILIB returns a disposition
  75. // that tells us what to do with the IRP.
  76. //
  77. PptFdoSystemControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
  78. {
  79. SYSCTL_IRP_DISPOSITION disposition;
  80. NTSTATUS status;
  81. PFDO_EXTENSION pDevExt = (PFDO_EXTENSION)DeviceObject->DeviceExtension;
  82. PAGED_CODE();
  83. status = WmiSystemControl( &pDevExt->WmiLibContext, DeviceObject, Irp, &disposition);
  84. switch(disposition) {
  85. case IrpProcessed:
  86. //
  87. // This irp has been processed and may be completed or pending.
  88. //
  89. break;
  90. case IrpNotCompleted:
  91. //
  92. // This irp has not been completed, but has been fully processed.
  93. // we will complete it now
  94. //
  95. P4CompleteRequest( Irp, Irp->IoStatus.Status, Irp->IoStatus.Information );
  96. break;
  97. case IrpForward:
  98. case IrpNotWmi:
  99. //
  100. // This irp is either not a WMI irp or is a WMI irp targetted
  101. // at a device lower in the stack.
  102. //
  103. IoSkipCurrentIrpStackLocation(Irp);
  104. status = IoCallDriver(pDevExt->ParentDeviceObject, Irp);
  105. break;
  106. default:
  107. //
  108. // We really should never get here, but if we do just forward....
  109. //
  110. ASSERT(FALSE);
  111. IoSkipCurrentIrpStackLocation(Irp);
  112. status = IoCallDriver(pDevExt->ParentDeviceObject, Irp);
  113. break;
  114. }
  115. return status;
  116. }
  117. //
  118. // This is our callback routine that WMI calls when it wants to find out
  119. // information about the data blocks and/or events that the device provides.
  120. //
  121. NTSTATUS
  122. PptWmiQueryWmiRegInfo(
  123. IN PDEVICE_OBJECT PDevObj,
  124. OUT PULONG PRegFlags,
  125. OUT PUNICODE_STRING PInstanceName,
  126. OUT PUNICODE_STRING *PRegistryPath,
  127. OUT PUNICODE_STRING MofResourceName,
  128. OUT PDEVICE_OBJECT *Pdo
  129. )
  130. {
  131. PFDO_EXTENSION devExt = PDevObj->DeviceExtension;
  132. UNREFERENCED_PARAMETER( PInstanceName );
  133. UNREFERENCED_PARAMETER( MofResourceName );
  134. PAGED_CODE();
  135. DD((PCE)devExt,DDT,"wmi::PptWmiQueryWmiRegInfo\n");
  136. *PRegFlags = WMIREG_FLAG_INSTANCE_PDO;
  137. *PRegistryPath = &RegistryPath;
  138. *Pdo = devExt->PhysicalDeviceObject;
  139. return STATUS_SUCCESS;
  140. }
  141. //
  142. // This is our callback routine that WMI calls to query a data block
  143. //
  144. NTSTATUS
  145. PptWmiQueryWmiDataBlock(
  146. IN PDEVICE_OBJECT DeviceObject,
  147. IN PIRP Irp,
  148. IN ULONG GuidIndex,
  149. IN ULONG InstanceIndex,
  150. IN ULONG InstanceCount,
  151. IN OUT PULONG InstanceLengthArray,
  152. IN ULONG OutBufferSize,
  153. OUT PUCHAR Buffer
  154. )
  155. {
  156. NTSTATUS status;
  157. ULONG size = sizeof(PARPORT_WMI_ALLOC_FREE_COUNTS);
  158. PFDO_EXTENSION devExt = DeviceObject->DeviceExtension;
  159. PAGED_CODE();
  160. //
  161. // Only ever registers 1 instance per guid
  162. //
  163. #if DBG
  164. ASSERT(InstanceIndex == 0 && InstanceCount == 1);
  165. #else
  166. UNREFERENCED_PARAMETER( InstanceCount );
  167. UNREFERENCED_PARAMETER( InstanceIndex );
  168. #endif
  169. switch (GuidIndex) {
  170. case PPT_WMI_ALLOC_FREE_COUNTS_GUID_INDEX:
  171. //
  172. // Request is for ParPort Alloc and Free Counts
  173. //
  174. // If caller's buffer is large enough then return the info, otherwise
  175. // tell the caller how large of a buffer is required so they can
  176. // call us again with a buffer of sufficient size.
  177. //
  178. if (OutBufferSize < size) {
  179. status = STATUS_BUFFER_TOO_SMALL;
  180. break;
  181. }
  182. *( (PPARPORT_WMI_ALLOC_FREE_COUNTS)Buffer ) = devExt->WmiPortAllocFreeCounts;
  183. *InstanceLengthArray = size;
  184. status = STATUS_SUCCESS;
  185. break;
  186. default:
  187. //
  188. // Index value larger than our largest supported - invalid request
  189. //
  190. status = STATUS_WMI_GUID_NOT_FOUND;
  191. break;
  192. }
  193. status = WmiCompleteRequest( DeviceObject, Irp, status, size, IO_NO_INCREMENT );
  194. return status;
  195. }