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.

507 lines
13 KiB

  1. /*++
  2. Copyright (c) 1997-1998 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. wmi.c
  5. Abstract:
  6. This module contains the code that handles the wmi IRPs for the
  7. AGP filter driver(s)
  8. Author:
  9. Environment:
  10. Kernel mode
  11. Revision History :
  12. --*/
  13. #include "agplib.h"
  14. #include <wmistr.h>
  15. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text(PAGE, AgpWmiRegistration)
  17. #pragma alloc_text(PAGE, AgpWmiDeRegistration)
  18. #pragma alloc_text(PAGE, AgpSystemControl)
  19. #pragma alloc_text(PAGE, AgpSetWmiDataItem)
  20. #pragma alloc_text(PAGE, AgpSetWmiDataBlock)
  21. #pragma alloc_text(PAGE, AgpQueryWmiDataBlock)
  22. #pragma alloc_text(PAGE, AgpQueryWmiRegInfo)
  23. #endif
  24. #define WMI_AGP_INFORMATION 0
  25. #define NUMBER_OF_WMI_GUIDS 1
  26. GUID AgpWmiGuid = AGP_WMI_STD_DATA_GUID;
  27. WMIGUIDREGINFO WmiGuidList[1] =
  28. {
  29. { &AgpWmiGuid, 1, 0 } // Pointer Port driver information
  30. };
  31. NTSTATUS
  32. AgpWmiRegistration(
  33. PTARGET_EXTENSION Extension
  34. )
  35. /*++
  36. Routine Description:
  37. Registers with WMI as a data provider for this
  38. instance of the device
  39. Arguments:
  40. Extension - Pointer to our taget extension
  41. Return Value:
  42. STATUS_SUCCESS or an appropriate error status
  43. --*/
  44. {
  45. NTSTATUS status;
  46. PAGED_CODE();
  47. Extension->WmiLibInfo.GuidCount = sizeof(WmiGuidList) /
  48. sizeof(WMIGUIDREGINFO);
  49. ASSERT (NUMBER_OF_WMI_GUIDS == Extension->WmiLibInfo.GuidCount);
  50. Extension->WmiLibInfo.GuidList = WmiGuidList;
  51. Extension->WmiLibInfo.QueryWmiRegInfo = AgpQueryWmiRegInfo;
  52. Extension->WmiLibInfo.QueryWmiDataBlock = AgpQueryWmiDataBlock;
  53. Extension->WmiLibInfo.SetWmiDataBlock = AgpSetWmiDataBlock;
  54. Extension->WmiLibInfo.SetWmiDataItem = AgpSetWmiDataItem;
  55. Extension->WmiLibInfo.ExecuteWmiMethod = NULL;
  56. Extension->WmiLibInfo.WmiFunctionControl = NULL;
  57. //
  58. // Register with WMI
  59. //
  60. status = IoWMIRegistrationControl(Extension->Self,
  61. WMIREG_ACTION_REGISTER
  62. );
  63. //
  64. // Initialize the Std device data structure
  65. //
  66. Globals.AgpCommand = 0;
  67. Globals.AgpStatus = 0;
  68. return status;
  69. }
  70. NTSTATUS
  71. AgpWmiDeRegistration(
  72. PTARGET_EXTENSION Extension
  73. )
  74. /*++
  75. Routine Description:
  76. Inform WMI to remove this DeviceObject from its
  77. list of providers. This function also
  78. decrements the reference count of the deviceobject.
  79. Arguments:
  80. Extension - Pointer to our target extension
  81. Return Value:
  82. STATUS_SUCCESS or error
  83. --*/
  84. {
  85. PAGED_CODE();
  86. return IoWMIRegistrationControl(Extension->Self,
  87. WMIREG_ACTION_DEREGISTER
  88. );
  89. }
  90. NTSTATUS
  91. AgpSystemControl(
  92. IN PDEVICE_OBJECT DeviceObject,
  93. IN PIRP Irp
  94. )
  95. /*++
  96. Routine Description
  97. We have just received a System Control IRP.
  98. Assume that this is a WMI IRP and call into the WMI system library and let
  99. it handle this IRP for us.
  100. Arguments:
  101. DeviceObject - Pointer to our device object
  102. Irp - Points to the corresponding I/O request packet
  103. Return Value:
  104. STATUS_SUCCESS or an appropriate error status
  105. --*/
  106. {
  107. PTARGET_EXTENSION deviceExtension;
  108. SYSCTL_IRP_DISPOSITION disposition;
  109. NTSTATUS status;
  110. PAGED_CODE();
  111. deviceExtension = (PTARGET_EXTENSION) DeviceObject->DeviceExtension;
  112. status = WmiSystemControl(&deviceExtension->WmiLibInfo,
  113. DeviceObject,
  114. Irp,
  115. &disposition);
  116. switch(disposition)
  117. {
  118. case IrpProcessed:
  119. {
  120. //
  121. // This irp has been processed and may be completed or pending.
  122. break;
  123. }
  124. case IrpNotCompleted:
  125. {
  126. //
  127. // This irp has not been completed, but has been fully processed.
  128. // we will complete it now
  129. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  130. break;
  131. }
  132. case IrpForward:
  133. case IrpNotWmi:
  134. {
  135. //
  136. // This irp is either not a WMI irp or is a WMI irp targetted
  137. // at a device lower in the stack.
  138. IoSkipCurrentIrpStackLocation (Irp);
  139. status =
  140. IoCallDriver(deviceExtension->CommonExtension.AttachedDevice,
  141. Irp);
  142. break;
  143. }
  144. default:
  145. {
  146. //
  147. // We really should never get here, but if we do just forward....
  148. ASSERT(FALSE);
  149. IoSkipCurrentIrpStackLocation (Irp);
  150. status =
  151. IoCallDriver(deviceExtension->CommonExtension.AttachedDevice,
  152. Irp);
  153. break;
  154. }
  155. }
  156. return(status);
  157. }
  158. NTSTATUS
  159. AgpSetWmiDataItem(
  160. IN PDEVICE_OBJECT DeviceObject,
  161. IN PIRP Irp,
  162. IN ULONG GuidIndex,
  163. IN ULONG InstanceIndex,
  164. IN ULONG DataItemId,
  165. IN ULONG BufferSize,
  166. IN PUCHAR Buffer
  167. )
  168. /*++
  169. Routine Description:
  170. This routine is a callback into the driver to set for the contents of
  171. a data block. When the driver has finished filling the data block it
  172. must call ClassWmiCompleteRequest to complete the irp. The driver can
  173. return STATUS_PENDING if the irp cannot be completed immediately.
  174. Arguments:
  175. DeviceObject is the device whose data block is being queried
  176. Irp is the Irp that makes this request
  177. GuidIndex is the index into the list of guids provided when the
  178. device registered
  179. DataItemId has the id of the data item being set
  180. BufferSize has the size of the data item passed
  181. Buffer has the new values for the data item
  182. Return Value:
  183. status
  184. --*/
  185. {
  186. PTARGET_EXTENSION deviceExtension;
  187. NTSTATUS status;
  188. PAGED_CODE();
  189. deviceExtension = (PTARGET_EXTENSION) DeviceObject->DeviceExtension;
  190. switch(GuidIndex) {
  191. case WMI_AGP_INFORMATION:
  192. status = STATUS_WMI_READ_ONLY;
  193. break;
  194. default:
  195. status = STATUS_WMI_GUID_NOT_FOUND;
  196. break;
  197. }
  198. status = WmiCompleteRequest( DeviceObject,
  199. Irp,
  200. status,
  201. 0,
  202. IO_NO_INCREMENT
  203. );
  204. return status;
  205. }
  206. NTSTATUS
  207. AgpSetWmiDataBlock(
  208. IN PDEVICE_OBJECT DeviceObject,
  209. IN PIRP Irp,
  210. IN ULONG GuidIndex,
  211. IN ULONG InstanceIndex,
  212. IN ULONG BufferSize,
  213. IN PUCHAR Buffer
  214. )
  215. /*++
  216. Routine Description:
  217. This routine is a callback into the driver to set the contents of
  218. a data block. When the driver has finished filling the data block it
  219. must call ClassWmiCompleteRequest to complete the irp. The driver can
  220. return STATUS_PENDING if the irp cannot be completed immediately.
  221. Arguments:
  222. DeviceObject is the device whose data block is being queried
  223. Irp is the Irp that makes this request
  224. GuidIndex is the index into the list of guids provided when the
  225. device registered
  226. BufferSize has the size of the data block passed
  227. Buffer has the new values for the data block
  228. Return Value:
  229. status
  230. --*/
  231. {
  232. PTARGET_EXTENSION deviceExtension;
  233. NTSTATUS status;
  234. PAGED_CODE();
  235. deviceExtension = (PTARGET_EXTENSION) DeviceObject->DeviceExtension;
  236. switch (GuidIndex) {
  237. case WMI_AGP_INFORMATION:
  238. status = STATUS_WMI_READ_ONLY;
  239. break;
  240. default:
  241. status = STATUS_WMI_GUID_NOT_FOUND;
  242. }
  243. status = WmiCompleteRequest( DeviceObject,
  244. Irp,
  245. status,
  246. 0,
  247. IO_NO_INCREMENT
  248. );
  249. return status;
  250. }
  251. NTSTATUS
  252. AgpQueryWmiDataBlock(
  253. IN PDEVICE_OBJECT DeviceObject,
  254. IN PIRP Irp,
  255. IN ULONG GuidIndex,
  256. IN ULONG InstanceIndex,
  257. IN ULONG InstanceCount,
  258. IN OUT PULONG InstanceLengthArray,
  259. IN ULONG OutBufferSize,
  260. OUT PUCHAR Buffer
  261. )
  262. /*++
  263. Routine Description:
  264. This routine is a callback into the driver to query for the contents of
  265. a data block. When the driver has finished filling the data block it
  266. must call ClassWmiCompleteRequest to complete the irp. The driver can
  267. return STATUS_PENDING if the irp cannot be completed immediately.
  268. Arguments:
  269. DeviceObject is the device whose data block is being queried
  270. Irp is the Irp that makes this request
  271. GuidIndex is the index into the list of guids provided when the
  272. device registered
  273. BufferAvail on has the maximum size available to write the data
  274. block.
  275. Buffer on return is filled with the returned data block
  276. Return Value:
  277. status
  278. --*/
  279. {
  280. PTARGET_EXTENSION deviceExtension;
  281. NTSTATUS status;
  282. ULONG size = 0;
  283. PAGED_CODE();
  284. ASSERT((InstanceIndex == 0) && (InstanceCount == 1));
  285. deviceExtension = (PTARGET_EXTENSION) DeviceObject->DeviceExtension;
  286. switch (GuidIndex) {
  287. case WMI_AGP_INFORMATION: {
  288. AGP_STD_DATA AgpData;
  289. size = sizeof(AGP_STD_DATA);
  290. if (OutBufferSize < size) {
  291. status = STATUS_BUFFER_TOO_SMALL;
  292. break;
  293. }
  294. AgpData.AgpStatus = Globals.AgpStatus;
  295. AgpData.AgpCommand = Globals.AgpCommand;
  296. AgpData.ApertureBase = deviceExtension->GartBase;
  297. AgpData.ApertureLength =
  298. deviceExtension->GartLengthInPages * PAGE_SIZE;
  299. *(PAGP_STD_DATA)Buffer = AgpData;
  300. *InstanceLengthArray = size;
  301. status = STATUS_SUCCESS;
  302. break;
  303. }
  304. default:
  305. status = STATUS_WMI_GUID_NOT_FOUND;
  306. break;
  307. }
  308. status = WmiCompleteRequest( DeviceObject,
  309. Irp,
  310. status,
  311. size,
  312. IO_NO_INCREMENT
  313. );
  314. return status;
  315. }
  316. NTSTATUS
  317. AgpQueryWmiRegInfo(
  318. IN PDEVICE_OBJECT DeviceObject,
  319. OUT PULONG RegFlags,
  320. OUT PUNICODE_STRING InstanceName,
  321. OUT PUNICODE_STRING *RegistryPath,
  322. OUT PUNICODE_STRING MofResourceName,
  323. OUT PDEVICE_OBJECT *Pdo
  324. )
  325. /*++
  326. Routine Description:
  327. This routine is a callback into the driver to retrieve information about
  328. the guids being registered.
  329. Implementations of this routine may be in paged memory
  330. Arguments:
  331. DeviceObject is the device whose registration information is needed
  332. *RegFlags returns with a set of flags that describe all of the guids being
  333. registered for this device. If the device wants enable and disable
  334. collection callbacks before receiving queries for the registered
  335. guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
  336. returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
  337. the instance name is determined from the PDO associated with the
  338. device object. Note that the PDO must have an associated devnode. If
  339. WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
  340. name for the device. These flags are ORed into the flags specified
  341. by the GUIDREGINFO for each guid.
  342. InstanceName returns with the instance name for the guids if
  343. WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
  344. caller will call ExFreePool with the buffer returned.
  345. *RegistryPath returns with the registry path of the driver. This is
  346. required
  347. *MofResourceName returns with the name of the MOF resource attached to
  348. the binary file. If the driver does not have a mof resource attached
  349. then this can be returned as NULL.
  350. *Pdo returns with the device object for the PDO associated with this
  351. device if the WMIREG_FLAG_INSTANCE_PDO flag is retured in
  352. *RegFlags.
  353. Return Value:
  354. status
  355. --*/
  356. {
  357. PTARGET_EXTENSION deviceExtension;
  358. PUNICODE_STRING regPath;
  359. PAGED_CODE();
  360. deviceExtension = DeviceObject->DeviceExtension;
  361. *RegFlags = WMIREG_FLAG_INSTANCE_PDO;
  362. *RegistryPath = &Globals.RegistryPath;
  363. *Pdo = deviceExtension->PDO;
  364. return STATUS_SUCCESS;
  365. }