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.

452 lines
11 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. SmbWmi.c
  5. Abstract:
  6. Wmi section for Smart Battery Miniport Driver
  7. Author:
  8. Michael Hills
  9. Environment:
  10. Kernel mode
  11. Revision History:
  12. --*/
  13. #include "SmbBattp.h"
  14. #include <initguid.h>
  15. #include <wdmguid.h>
  16. #include <wmistr.h>
  17. #include <wmilib.h>
  18. NTSTATUS
  19. SmbBattQueryWmiRegInfo(
  20. IN PDEVICE_OBJECT DeviceObject,
  21. OUT ULONG *RegFlags,
  22. OUT PUNICODE_STRING InstanceName,
  23. OUT PUNICODE_STRING *RegistryPath,
  24. OUT PUNICODE_STRING MofResourceName,
  25. OUT PDEVICE_OBJECT *Pdo
  26. );
  27. NTSTATUS
  28. SmbBattQueryWmiDataBlock(
  29. IN PDEVICE_OBJECT DeviceObject,
  30. IN PIRP Irp,
  31. IN ULONG GuidIndex,
  32. IN ULONG InstanceIndex,
  33. IN ULONG InstanceCount,
  34. IN OUT PULONG InstanceLengthArray,
  35. IN ULONG OutBufferSize,
  36. OUT PUCHAR Buffer
  37. );
  38. #if DEBUG
  39. PCHAR
  40. WMIMinorFunctionString (
  41. UCHAR MinorFunction
  42. );
  43. #endif
  44. #ifdef ALLOC_PRAGMA
  45. #pragma alloc_text(PAGE,SmbBattWmiRegistration)
  46. #pragma alloc_text(PAGE,SmbBattWmiDeRegistration)
  47. #pragma alloc_text(PAGE,SmbBattSystemControl)
  48. #pragma alloc_text(PAGE,SmbBattQueryWmiRegInfo)
  49. #endif
  50. NTSTATUS
  51. SmbBattSystemControl(
  52. IN PDEVICE_OBJECT DeviceObject,
  53. IN PIRP Irp
  54. )
  55. /*++
  56. Routine Description:
  57. This routine passes the request down the stack
  58. Arguments:
  59. DeviceObject - The target
  60. Irp - The request
  61. Return Value:
  62. NTSTATUS
  63. --*/
  64. {
  65. NTSTATUS status;
  66. PSMB_NP_BATT SmbNPBatt;
  67. PIO_STACK_LOCATION stack;
  68. PDEVICE_OBJECT lowerDevice;
  69. SYSCTL_IRP_DISPOSITION disposition = IrpForward;
  70. PAGED_CODE();
  71. stack = IoGetCurrentIrpStackLocation (Irp);
  72. BattPrint((BAT_TRACE), ("SmbBatt: SystemControl: %s\n",
  73. WMIMinorFunctionString(stack->MinorFunction)));
  74. SmbNPBatt = (PSMB_NP_BATT) DeviceObject->DeviceExtension;
  75. //
  76. // Aquire remove lock
  77. //
  78. status = IoAcquireRemoveLock (&SmbNPBatt->RemoveLock, Irp);
  79. if (!NT_SUCCESS(status)) {
  80. Irp->IoStatus.Status = status;
  81. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  82. return status;
  83. }
  84. if (SmbNPBatt->SmbBattFdoType == SmbTypeBattery) {
  85. lowerDevice = SmbNPBatt->LowerDevice;
  86. status = BatteryClassSystemControl(SmbNPBatt->Class,
  87. &SmbNPBatt->WmiLibContext,
  88. DeviceObject,
  89. Irp,
  90. &disposition);
  91. } else if (SmbNPBatt->SmbBattFdoType == SmbTypeSubsystem) {
  92. lowerDevice = ((PSMB_BATT_SUBSYSTEM) DeviceObject->DeviceExtension)->LowerDevice;
  93. } else {
  94. //
  95. // There is no lower device. Just complete the IRP.
  96. //
  97. lowerDevice = NULL;
  98. disposition = IrpNotCompleted;
  99. status = Irp->IoStatus.Status;
  100. }
  101. switch(disposition)
  102. {
  103. case IrpProcessed:
  104. {
  105. //
  106. // This irp has been processed and may be completed or pending.
  107. BattPrint((BAT_TRACE), ("SmbBatt: SystemControl: Irp Processed\n"));
  108. break;
  109. }
  110. case IrpNotCompleted:
  111. {
  112. //
  113. // This irp has not been completed, but has been fully processed.
  114. // we will complete it now
  115. BattPrint((BAT_TRACE), ("SmbBatt: SystemControl: Irp Not Completed.\n"));
  116. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  117. break;
  118. }
  119. case IrpForward:
  120. case IrpNotWmi:
  121. {
  122. //
  123. // This irp is either not a WMI irp or is a WMI irp targeted
  124. // at a device lower in the stack.
  125. BattPrint((BAT_TRACE), ("SmbBatt: SystemControl: Irp Forward.\n"));
  126. IoSkipCurrentIrpStackLocation (Irp);
  127. status = IoCallDriver (lowerDevice, Irp);
  128. break;
  129. }
  130. default:
  131. {
  132. //
  133. // We really should never get here, but if we do just forward....
  134. ASSERT(FALSE);
  135. IoSkipCurrentIrpStackLocation (Irp);
  136. status = IoCallDriver (lowerDevice, Irp);
  137. break;
  138. }
  139. }
  140. //
  141. // Release Removal Lock
  142. //
  143. IoReleaseRemoveLock (&SmbNPBatt->RemoveLock, Irp);
  144. return status;
  145. }
  146. NTSTATUS
  147. SmbBattWmiRegistration(
  148. PSMB_NP_BATT SmbNPBatt
  149. )
  150. /*++
  151. Routine Description
  152. Registers with WMI as a data provider for this
  153. instance of the device
  154. --*/
  155. {
  156. NTSTATUS status;
  157. PAGED_CODE();
  158. //
  159. // This is essentially blank since smbbatt.sys doesn't have any
  160. // data to handle other than the default battery class data which is handled
  161. // by the battery class driver.
  162. // If there were driver specific data, such as Device Wake Enable controls,
  163. // it would be listed here.
  164. //
  165. SmbNPBatt->WmiLibContext.GuidCount = 0;
  166. SmbNPBatt->WmiLibContext.GuidList = NULL;
  167. SmbNPBatt->WmiLibContext.QueryWmiRegInfo = SmbBattQueryWmiRegInfo;
  168. SmbNPBatt->WmiLibContext.QueryWmiDataBlock = SmbBattQueryWmiDataBlock;
  169. SmbNPBatt->WmiLibContext.SetWmiDataBlock = NULL;
  170. SmbNPBatt->WmiLibContext.SetWmiDataItem = NULL;
  171. SmbNPBatt->WmiLibContext.ExecuteWmiMethod = NULL;
  172. SmbNPBatt->WmiLibContext.WmiFunctionControl = NULL;
  173. //
  174. // Register with WMI
  175. //
  176. status = IoWMIRegistrationControl(SmbNPBatt->Batt->DeviceObject,
  177. WMIREG_ACTION_REGISTER
  178. );
  179. return status;
  180. }
  181. NTSTATUS
  182. SmbBattWmiDeRegistration(
  183. PSMB_NP_BATT SmbNPBatt
  184. )
  185. /*++
  186. Routine Description
  187. Inform WMI to remove this DeviceObject from its
  188. list of providers. This function also
  189. decrements the reference count of the deviceobject.
  190. --*/
  191. {
  192. PAGED_CODE();
  193. return IoWMIRegistrationControl(SmbNPBatt->Batt->DeviceObject,
  194. WMIREG_ACTION_DEREGISTER
  195. );
  196. }
  197. //
  198. // WMI System Call back functions
  199. //
  200. NTSTATUS
  201. SmbBattQueryWmiRegInfo(
  202. IN PDEVICE_OBJECT DeviceObject,
  203. OUT ULONG *RegFlags,
  204. OUT PUNICODE_STRING InstanceName,
  205. OUT PUNICODE_STRING *RegistryPath,
  206. OUT PUNICODE_STRING MofResourceName,
  207. OUT PDEVICE_OBJECT *Pdo
  208. )
  209. /*++
  210. Routine Description:
  211. This routine is a callback into the driver to retrieve the list of
  212. guids or data blocks that the driver wants to register with WMI. This
  213. routine may not pend or block. Driver should NOT call
  214. WmiCompleteRequest.
  215. Arguments:
  216. DeviceObject is the device whose data block is being queried
  217. *RegFlags returns with a set of flags that describe the guids being
  218. registered for this device. If the device wants enable and disable
  219. collection callbacks before receiving queries for the registered
  220. guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
  221. returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
  222. the instance name is determined from the PDO associated with the
  223. device object. Note that the PDO must have an associated devnode. If
  224. WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
  225. name for the device.
  226. InstanceName returns with the instance name for the guids if
  227. WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
  228. caller will call ExFreePool with the buffer returned.
  229. *RegistryPath returns with the registry path of the driver
  230. *MofResourceName returns with the name of the MOF resource attached to
  231. the binary file. If the driver does not have a mof resource attached
  232. then this can be returned as NULL.
  233. *Pdo returns with the device object for the PDO associated with this
  234. device if the WMIREG_FLAG_INSTANCE_PDO flag is returned in
  235. *RegFlags.
  236. Return Value:
  237. status
  238. --*/
  239. {
  240. PSMB_NP_BATT SmbNPBatt = DeviceObject->DeviceExtension;
  241. PAGED_CODE();
  242. BattPrint ((BAT_TRACE), ("SmbBatt: Entered SmbBattQueryWmiRegInfo\n"));
  243. *RegFlags = WMIREG_FLAG_INSTANCE_PDO;
  244. *RegistryPath = &GlobalRegistryPath;
  245. *Pdo = SmbNPBatt->Batt->PDO;
  246. return STATUS_SUCCESS;
  247. }
  248. NTSTATUS
  249. SmbBattQueryWmiDataBlock(
  250. IN PDEVICE_OBJECT DeviceObject,
  251. IN PIRP Irp,
  252. IN ULONG GuidIndex,
  253. IN ULONG InstanceIndex,
  254. IN ULONG InstanceCount,
  255. IN OUT PULONG InstanceLengthArray,
  256. IN ULONG OutBufferSize,
  257. OUT PUCHAR Buffer
  258. )
  259. /*++
  260. Routine Description:
  261. This routine is a callback into the driver to query for the contents of
  262. a data block. When the driver has finished filling the data block it
  263. must call WmiCompleteRequest to complete the irp. The driver can
  264. return STATUS_PENDING if the irp cannot be completed immediately.
  265. Arguments:
  266. DeviceObject is the device whose data block is being queried
  267. Irp is the Irp that makes this request
  268. GuidIndex is the index into the list of guids provided when the
  269. device registered
  270. InstanceIndex is the index that denotes which instance of the data block
  271. is being queried.
  272. InstanceCount is the number of instances expected to be returned for
  273. the data block.
  274. InstanceLengthArray is a pointer to an array of ULONG that returns the
  275. lengths of each instance of the data block. If this is NULL then
  276. there was not enough space in the output buffer to fulfill the request
  277. so the irp should be completed with the buffer needed.
  278. BufferAvail on has the maximum size available to write the data
  279. block.
  280. Buffer on return is filled with the returned data block
  281. Return Value:
  282. status
  283. --*/
  284. {
  285. PSMB_NP_BATT SmbNPBatt = (PSMB_NP_BATT) DeviceObject->DeviceExtension;
  286. NTSTATUS status;
  287. PAGED_CODE();
  288. BattPrint ((BAT_TRACE), ("Entered SmbBattQueryWmiDataBlock\n"));
  289. //
  290. // Only ever registers 1 instance per guid
  291. ASSERT((InstanceIndex == 0) &&
  292. (InstanceCount == 1));
  293. status = BatteryClassQueryWmiDataBlock(
  294. SmbNPBatt->Class,
  295. DeviceObject,
  296. Irp,
  297. GuidIndex,
  298. InstanceLengthArray,
  299. OutBufferSize,
  300. Buffer);
  301. if (status != STATUS_WMI_GUID_NOT_FOUND) {
  302. BattPrint ((BAT_TRACE), ("SmbBattQueryWmiDataBlock: Handled by Battery Class.\n"));
  303. return status;
  304. }
  305. //
  306. // Fail Request: Smart battery has no other GUIDs
  307. //
  308. status = WmiCompleteRequest( DeviceObject,
  309. Irp,
  310. STATUS_WMI_GUID_NOT_FOUND,
  311. 0,
  312. IO_NO_INCREMENT);
  313. return status;
  314. }
  315. #if DEBUG
  316. PCHAR
  317. WMIMinorFunctionString (
  318. UCHAR MinorFunction
  319. )
  320. {
  321. switch (MinorFunction)
  322. {
  323. case IRP_MN_CHANGE_SINGLE_INSTANCE:
  324. return "IRP_MN_CHANGE_SINGLE_INSTANCE";
  325. case IRP_MN_CHANGE_SINGLE_ITEM:
  326. return "IRP_MN_CHANGE_SINGLE_ITEM";
  327. case IRP_MN_DISABLE_COLLECTION:
  328. return "IRP_MN_DISABLE_COLLECTION";
  329. case IRP_MN_DISABLE_EVENTS:
  330. return "IRP_MN_DISABLE_EVENTS";
  331. case IRP_MN_ENABLE_COLLECTION:
  332. return "IRP_MN_ENABLE_COLLECTION";
  333. case IRP_MN_ENABLE_EVENTS:
  334. return "IRP_MN_ENABLE_EVENTS";
  335. case IRP_MN_EXECUTE_METHOD:
  336. return "IRP_MN_EXECUTE_METHOD";
  337. case IRP_MN_QUERY_ALL_DATA:
  338. return "IRP_MN_QUERY_ALL_DATA";
  339. case IRP_MN_QUERY_SINGLE_INSTANCE:
  340. return "IRP_MN_QUERY_SINGLE_INSTANCE";
  341. case IRP_MN_REGINFO:
  342. return "IRP_MN_REGINFO";
  343. default:
  344. return "IRP_MN_?????";
  345. }
  346. }
  347. #endif