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.

649 lines
16 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. isowmi.c
  5. Abstract:
  6. Environment:
  7. Kernel mode
  8. Notes:
  9. Copyright (c) 2000 Microsoft Corporation.
  10. All Rights Reserved.
  11. --*/
  12. #include "isousb.h"
  13. #include "isopnp.h"
  14. #include "isopwr.h"
  15. #include "isodev.h"
  16. #include "isowmi.h"
  17. #include "isousr.h"
  18. #include "isorwr.h"
  19. #include "isostrm.h"
  20. #define MOFRESOURCENAME L"MofResourceName"
  21. #define WMI_ISOUSB_DRIVER_INFORMATION 0
  22. DEFINE_GUID (ISOUSB_WMI_STD_DATA_GUID,
  23. 0xBBA21300, 0x6DD3, 0x11d2, 0xB8, 0x44, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71);
  24. WMIGUIDREGINFO IsoWmiGuidList[1] = { {
  25. &ISOUSB_WMI_STD_DATA_GUID, 1, 0 // driver information
  26. }
  27. };
  28. NTSTATUS
  29. IsoUsb_WmiRegistration(
  30. IN OUT PDEVICE_EXTENSION DeviceExtension
  31. )
  32. /*++
  33. Routine Description:
  34. Registers with WMI as a data provider for this
  35. instance of the device
  36. Arguments:
  37. Return Value:
  38. --*/
  39. {
  40. NTSTATUS ntStatus;
  41. PAGED_CODE();
  42. DeviceExtension->WmiLibInfo.GuidCount =
  43. sizeof (IsoWmiGuidList) / sizeof (WMIGUIDREGINFO);
  44. DeviceExtension->WmiLibInfo.GuidList = IsoWmiGuidList;
  45. DeviceExtension->WmiLibInfo.QueryWmiRegInfo = IsoUsb_QueryWmiRegInfo;
  46. DeviceExtension->WmiLibInfo.QueryWmiDataBlock = IsoUsb_QueryWmiDataBlock;
  47. DeviceExtension->WmiLibInfo.SetWmiDataBlock = IsoUsb_SetWmiDataBlock;
  48. DeviceExtension->WmiLibInfo.SetWmiDataItem = IsoUsb_SetWmiDataItem;
  49. DeviceExtension->WmiLibInfo.ExecuteWmiMethod = NULL;
  50. DeviceExtension->WmiLibInfo.WmiFunctionControl = NULL;
  51. //
  52. // Register with WMI
  53. //
  54. ntStatus = IoWMIRegistrationControl(DeviceExtension->FunctionalDeviceObject,
  55. WMIREG_ACTION_REGISTER);
  56. return ntStatus;
  57. }
  58. NTSTATUS
  59. IsoUsb_WmiDeRegistration(
  60. IN OUT PDEVICE_EXTENSION DeviceExtension
  61. )
  62. /*++
  63. Routine Description:
  64. Inform WMI to remove this DeviceObject from its
  65. list of providers. This function also
  66. decrements the reference count of the deviceobject.
  67. Arguments:
  68. Return Value:
  69. --*/
  70. {
  71. PAGED_CODE();
  72. return IoWMIRegistrationControl(DeviceExtension->FunctionalDeviceObject,
  73. WMIREG_ACTION_DEREGISTER);
  74. }
  75. NTSTATUS
  76. IsoUsb_DispatchSysCtrl(
  77. IN PDEVICE_OBJECT DeviceObject,
  78. IN PIRP Irp
  79. )
  80. /*++
  81. Routine Description:
  82. Arguments:
  83. Return Value:
  84. --*/
  85. {
  86. PDEVICE_EXTENSION deviceExtension;
  87. SYSCTL_IRP_DISPOSITION disposition;
  88. NTSTATUS ntStatus;
  89. PIO_STACK_LOCATION irpStack;
  90. PAGED_CODE();
  91. irpStack = IoGetCurrentIrpStackLocation (Irp);
  92. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  93. IsoUsb_DbgPrint(3, (WMIMinorFunctionString(irpStack->MinorFunction)));
  94. if(Removed == deviceExtension->DeviceState) {
  95. ntStatus = STATUS_DELETE_PENDING;
  96. Irp->IoStatus.Status = ntStatus;
  97. Irp->IoStatus.Information = 0;
  98. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  99. return ntStatus;
  100. }
  101. IsoUsb_DbgPrint(3, ("IsoUsb_DispatchSysCtrl::"));
  102. IsoUsb_IoIncrement(deviceExtension);
  103. ntStatus = WmiSystemControl(&deviceExtension->WmiLibInfo,
  104. DeviceObject,
  105. Irp,
  106. &disposition);
  107. switch(disposition) {
  108. case IrpProcessed:
  109. {
  110. //
  111. // This irp has been processed and may be completed or pending.
  112. //
  113. break;
  114. }
  115. case IrpNotCompleted:
  116. {
  117. //
  118. // This irp has not been completed, but has been fully processed.
  119. // we will complete it now
  120. //
  121. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  122. break;
  123. }
  124. case IrpForward:
  125. case IrpNotWmi:
  126. {
  127. //
  128. // This irp is either not a WMI irp or is a WMI irp targeted
  129. // at a device lower in the stack.
  130. //
  131. IoSkipCurrentIrpStackLocation (Irp);
  132. ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
  133. Irp);
  134. break;
  135. }
  136. default:
  137. {
  138. //
  139. // We really should never get here, but if we do just forward....
  140. //
  141. ASSERT(FALSE);
  142. IoSkipCurrentIrpStackLocation (Irp);
  143. ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
  144. Irp);
  145. break;
  146. }
  147. }
  148. IsoUsb_DbgPrint(3, ("IsoUsb_DispatchSysCtrl::"));
  149. IsoUsb_IoDecrement(deviceExtension);
  150. return ntStatus;
  151. }
  152. NTSTATUS
  153. IsoUsb_QueryWmiRegInfo(
  154. IN PDEVICE_OBJECT DeviceObject,
  155. OUT ULONG *RegFlags,
  156. OUT PUNICODE_STRING InstanceName,
  157. OUT PUNICODE_STRING *RegistryPath,
  158. OUT PUNICODE_STRING MofResourceName,
  159. OUT PDEVICE_OBJECT *Pdo
  160. )
  161. /*++
  162. Routine Description:
  163. This routine is a callback into the driver to retrieve the list of
  164. guids or data blocks that the driver wants to register with WMI. This
  165. routine may not pend or block. Driver should NOT call
  166. WmiCompleteRequest.
  167. Arguments:
  168. DeviceObject is the device whose data block is being queried
  169. *RegFlags returns with a set of flags that describe the guids being
  170. registered for this device. If the device wants enable and disable
  171. collection callbacks before receiving queries for the registered
  172. guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
  173. returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
  174. the instance name is determined from the PDO associated with the
  175. device object. Note that the PDO must have an associated devnode. If
  176. WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
  177. name for the device.
  178. InstanceName returns with the instance name for the guids if
  179. WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
  180. caller will call ExFreePool with the buffer returned.
  181. *RegistryPath returns with the registry path of the driver
  182. *MofResourceName returns with the name of the MOF resource attached to
  183. the binary file. If the driver does not have a mof resource attached
  184. then this can be returned as NULL.
  185. *Pdo returns with the device object for the PDO associated with this
  186. device if the WMIREG_FLAG_INSTANCE_PDO flag is returned in
  187. *RegFlags.
  188. Return Value:
  189. status
  190. --*/
  191. {
  192. PDEVICE_EXTENSION deviceExtension;
  193. PAGED_CODE();
  194. IsoUsb_DbgPrint(3, ("IsoUsb_QueryWmiRegInfo - begins\n"));
  195. deviceExtension = DeviceObject->DeviceExtension;
  196. *RegFlags = WMIREG_FLAG_INSTANCE_PDO;
  197. *RegistryPath = &Globals.IsoUsb_RegistryPath;
  198. *Pdo = deviceExtension->PhysicalDeviceObject;
  199. RtlInitUnicodeString(MofResourceName, MOFRESOURCENAME);
  200. IsoUsb_DbgPrint(3, ("IsoUsb_QueryWmiRegInfo - ends\n"));
  201. return STATUS_SUCCESS;
  202. }
  203. NTSTATUS
  204. IsoUsb_QueryWmiDataBlock(
  205. IN PDEVICE_OBJECT DeviceObject,
  206. IN PIRP Irp,
  207. IN ULONG GuidIndex,
  208. IN ULONG InstanceIndex,
  209. IN ULONG InstanceCount,
  210. IN OUT PULONG InstanceLengthArray,
  211. IN ULONG OutBufferSize,
  212. OUT PUCHAR Buffer
  213. )
  214. /*++
  215. Routine Description:
  216. This routine is a callback into the driver to query for the contents of
  217. a data block. When the driver has finished filling the data block it
  218. must call WmiCompleteRequest to complete the irp. The driver can
  219. return STATUS_PENDING if the irp cannot be completed immediately.
  220. Arguments:
  221. DeviceObject is the device whose data block is being queried
  222. Irp is the Irp that makes this request
  223. GuidIndex is the index into the list of guids provided when the
  224. device registered
  225. InstanceIndex is the index that denotes which instance of the data block
  226. is being queried.
  227. InstanceCount is the number of instances expected to be returned for
  228. the data block.
  229. InstanceLengthArray is a pointer to an array of ULONG that returns the
  230. lengths of each instance of the data block. If this is NULL then
  231. there was not enough space in the output buffer to fulfill the request
  232. so the irp should be completed with the buffer needed.
  233. OutBufferSize has the maximum size available to write the data
  234. block.
  235. Buffer on return is filled with the returned data block
  236. Return Value:
  237. status
  238. --*/
  239. {
  240. PDEVICE_EXTENSION deviceExtension;
  241. NTSTATUS ntStatus;
  242. ULONG size;
  243. WCHAR modelName[] = L"Aishverya\0\0";
  244. USHORT modelNameLen;
  245. PAGED_CODE();
  246. IsoUsb_DbgPrint(3, ("IsoUsb_QueryWmiDataBlock - begins\n"));
  247. size = 0;
  248. modelNameLen = (wcslen(modelName) + 1) * sizeof(WCHAR);
  249. //
  250. // Only ever registers 1 instance per guid
  251. //
  252. ASSERT((InstanceIndex == 0) &&
  253. (InstanceCount == 1));
  254. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  255. switch (GuidIndex) {
  256. case WMI_ISOUSB_DRIVER_INFORMATION:
  257. size = sizeof(ULONG) + modelNameLen + sizeof(USHORT);
  258. if (OutBufferSize < size ) {
  259. IsoUsb_DbgPrint(3, ("OutBuffer too small\n"));
  260. ntStatus = STATUS_INVALID_BUFFER_SIZE;
  261. break;
  262. }
  263. * (PULONG) Buffer = DebugLevel;
  264. Buffer += sizeof(ULONG);
  265. //
  266. // put length of string ahead of string
  267. //
  268. *((PUSHORT)Buffer) = modelNameLen;
  269. Buffer = (PUCHAR)Buffer + sizeof(USHORT);
  270. RtlCopyBytes((PVOID)Buffer, (PVOID)modelName, modelNameLen);
  271. *InstanceLengthArray = size ;
  272. ntStatus = STATUS_SUCCESS;
  273. break;
  274. default:
  275. ntStatus = STATUS_WMI_GUID_NOT_FOUND;
  276. }
  277. ntStatus = WmiCompleteRequest(DeviceObject,
  278. Irp,
  279. ntStatus,
  280. size,
  281. IO_NO_INCREMENT);
  282. IsoUsb_DbgPrint(3, ("IsoUsb_QueryWmiDataBlock - ends\n"));
  283. return ntStatus;
  284. }
  285. NTSTATUS
  286. IsoUsb_SetWmiDataItem(
  287. IN PDEVICE_OBJECT DeviceObject,
  288. IN PIRP Irp,
  289. IN ULONG GuidIndex,
  290. IN ULONG InstanceIndex,
  291. IN ULONG DataItemId,
  292. IN ULONG BufferSize,
  293. IN PUCHAR Buffer
  294. )
  295. /*++
  296. Routine Description:
  297. This routine is a callback into the driver to set for the contents of
  298. a data block. When the driver has finished filling the data block it
  299. must call WmiCompleteRequest to complete the irp. The driver can
  300. return STATUS_PENDING if the irp cannot be completed immediately.
  301. Arguments:
  302. DeviceObject is the device whose data block is being queried
  303. Irp is the Irp that makes this request
  304. GuidIndex is the index into the list of guids provided when the
  305. device registered
  306. InstanceIndex is the index that denotes which instance of the data block
  307. is being queried.
  308. DataItemId has the id of the data item being set
  309. BufferSize has the size of the data item passed
  310. Buffer has the new values for the data item
  311. Return Value:
  312. status
  313. --*/
  314. {
  315. PDEVICE_EXTENSION deviceExtension;
  316. NTSTATUS ntStatus;
  317. ULONG info;
  318. PAGED_CODE();
  319. IsoUsb_DbgPrint(3, ("IsoUsb_SetWmiDataItem - begins\n"));
  320. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  321. info = 0;
  322. switch(GuidIndex) {
  323. case WMI_ISOUSB_DRIVER_INFORMATION:
  324. if(DataItemId == 1) {
  325. if(BufferSize == sizeof(ULONG)) {
  326. DebugLevel = *((PULONG)Buffer);
  327. ntStatus = STATUS_SUCCESS;
  328. info = sizeof(ULONG);
  329. }
  330. else {
  331. ntStatus = STATUS_INFO_LENGTH_MISMATCH;
  332. }
  333. }
  334. else {
  335. ntStatus = STATUS_WMI_READ_ONLY;
  336. }
  337. break;
  338. default:
  339. ntStatus = STATUS_WMI_GUID_NOT_FOUND;
  340. }
  341. ntStatus = WmiCompleteRequest(DeviceObject,
  342. Irp,
  343. ntStatus,
  344. info,
  345. IO_NO_INCREMENT);
  346. IsoUsb_DbgPrint(3, ("IsoUsb_SetWmiDataItem - ends\n"));
  347. return ntStatus;
  348. }
  349. NTSTATUS
  350. IsoUsb_SetWmiDataBlock(
  351. IN PDEVICE_OBJECT DeviceObject,
  352. IN PIRP Irp,
  353. IN ULONG GuidIndex,
  354. IN ULONG InstanceIndex,
  355. IN ULONG BufferSize,
  356. IN PUCHAR Buffer
  357. )
  358. /*++
  359. Routine Description:
  360. This routine is a callback into the driver to set the contents of
  361. a data block. When the driver has finished filling the data block it
  362. must call WmiCompleteRequest to complete the irp. The driver can
  363. return STATUS_PENDING if the irp cannot be completed immediately.
  364. Arguments:
  365. DeviceObject is the device whose data block is being queried
  366. Irp is the Irp that makes this request
  367. GuidIndex is the index into the list of guids provided when the
  368. device registered
  369. InstanceIndex is the index that denotes which instance of the data block
  370. is being queried.
  371. BufferSize has the size of the data block passed
  372. Buffer has the new values for the data block
  373. Return Value:
  374. status
  375. --*/
  376. {
  377. PDEVICE_EXTENSION deviceExtension;
  378. NTSTATUS ntStatus;
  379. ULONG info;
  380. PAGED_CODE();
  381. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  382. info = 0;
  383. IsoUsb_DbgPrint(3, ("IsoUsb_SetWmiDataBlock - begins\n"));
  384. switch(GuidIndex) {
  385. case WMI_ISOUSB_DRIVER_INFORMATION:
  386. if(BufferSize == sizeof(ULONG)) {
  387. DebugLevel = *(PULONG) Buffer;
  388. ntStatus = STATUS_SUCCESS;
  389. info = sizeof(ULONG);
  390. }
  391. else {
  392. ntStatus = STATUS_INFO_LENGTH_MISMATCH;
  393. }
  394. break;
  395. default:
  396. ntStatus = STATUS_WMI_GUID_NOT_FOUND;
  397. }
  398. ntStatus = WmiCompleteRequest(DeviceObject,
  399. Irp,
  400. ntStatus,
  401. info,
  402. IO_NO_INCREMENT);
  403. IsoUsb_DbgPrint(3, ("IsoUsb_SetWmiDataBlock - ends\n"));
  404. return ntStatus;
  405. }
  406. PCHAR
  407. WMIMinorFunctionString (
  408. UCHAR MinorFunction
  409. )
  410. /*++
  411. Routine Description:
  412. Arguments:
  413. Return Value:
  414. --*/
  415. {
  416. switch (MinorFunction) {
  417. case IRP_MN_CHANGE_SINGLE_INSTANCE:
  418. return "IRP_MN_CHANGE_SINGLE_INSTANCE\n";
  419. case IRP_MN_CHANGE_SINGLE_ITEM:
  420. return "IRP_MN_CHANGE_SINGLE_ITEM\n";
  421. case IRP_MN_DISABLE_COLLECTION:
  422. return "IRP_MN_DISABLE_COLLECTION\n";
  423. case IRP_MN_DISABLE_EVENTS:
  424. return "IRP_MN_DISABLE_EVENTS\n";
  425. case IRP_MN_ENABLE_COLLECTION:
  426. return "IRP_MN_ENABLE_COLLECTION\n";
  427. case IRP_MN_ENABLE_EVENTS:
  428. return "IRP_MN_ENABLE_EVENTS\n";
  429. case IRP_MN_EXECUTE_METHOD:
  430. return "IRP_MN_EXECUTE_METHOD\n";
  431. case IRP_MN_QUERY_ALL_DATA:
  432. return "IRP_MN_QUERY_ALL_DATA\n";
  433. case IRP_MN_QUERY_SINGLE_INSTANCE:
  434. return "IRP_MN_QUERY_SINGLE_INSTANCE\n";
  435. case IRP_MN_REGINFO:
  436. return "IRP_MN_REGINFO\n";
  437. default:
  438. return "IRP_MN_?????\n";
  439. }
  440. }