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.

588 lines
14 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. wmi.c
  5. Abstract:
  6. This module contains the code that handles the wmi IRPs for the
  7. serial driver.
  8. Environment:
  9. Kernel mode
  10. Revision History :
  11. --*/
  12. #include "precomp.h"
  13. // Prototypes
  14. // -- CARD WMI Routines --
  15. NTSTATUS
  16. SpeedCard_WmiQueryRegInfo(IN PDEVICE_OBJECT pDevObject, OUT PULONG pRegFlags,
  17. OUT PUNICODE_STRING pInstanceName,
  18. OUT PUNICODE_STRING *pRegistryPath,
  19. OUT PUNICODE_STRING pMofResourceName,
  20. OUT PDEVICE_OBJECT *pPdo);
  21. NTSTATUS
  22. SpeedCard_WmiQueryDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  23. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  24. IN ULONG InstanceCount, IN OUT PULONG pInstanceLengthArray,
  25. IN ULONG OutBufferSize, OUT PUCHAR pBuffer);
  26. NTSTATUS
  27. SpeedCard_WmiSetDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  28. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  29. IN ULONG BufferSize, IN PUCHAR pBuffer);
  30. NTSTATUS
  31. SpeedCard_WmiSetDataItem(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  32. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  33. IN ULONG DataItemId, IN ULONG BufferSize,
  34. IN PUCHAR pBuffer);
  35. // End of prototypes.
  36. #ifdef ALLOC_PRAGMA
  37. #pragma alloc_text(PAGE, SpeedCard_WmiInitializeWmilibContext)
  38. #pragma alloc_text(PAGE, SpeedCard_WmiQueryRegInfo)
  39. #pragma alloc_text(PAGE, SpeedCard_WmiQueryDataBlock)
  40. #pragma alloc_text(PAGE, SpeedCard_WmiSetDataBlock)
  41. #pragma alloc_text(PAGE, SpeedCard_WmiSetDataItem)
  42. #endif
  43. #define WMI_FAST_CARD_PROP 0
  44. GUID FastCardWmiPropGuid = SPX_SPEED_WMI_FAST_CARD_PROP_GUID; // Fast Card Properties
  45. WMIGUIDREGINFO SpeedCard_WmiGuidList[] =
  46. {
  47. { &FastCardWmiPropGuid, 1, 0 },
  48. };
  49. #define SpeedCard_WmiGuidCount (sizeof(SpeedCard_WmiGuidList) / sizeof(WMIGUIDREGINFO))
  50. NTSTATUS
  51. SpeedCard_WmiInitializeWmilibContext(IN PWMILIB_CONTEXT WmilibContext)
  52. /*++
  53. Routine Description:
  54. This routine will initialize the wmilib context structure with the
  55. guid list and the pointers to the wmilib callback functions. This routine
  56. should be called before calling IoWmiRegistrationControl to register
  57. your device object.
  58. Arguments:
  59. WmilibContext is pointer to the wmilib context.
  60. Return Value:
  61. status
  62. --*/
  63. {
  64. PAGED_CODE();
  65. RtlZeroMemory(WmilibContext, sizeof(WMILIB_CONTEXT));
  66. WmilibContext->GuidCount = SpeedCard_WmiGuidCount;
  67. WmilibContext->GuidList = SpeedCard_WmiGuidList;
  68. WmilibContext->QueryWmiRegInfo = SpeedCard_WmiQueryRegInfo;
  69. WmilibContext->QueryWmiDataBlock = SpeedCard_WmiQueryDataBlock;
  70. WmilibContext->SetWmiDataBlock = SpeedCard_WmiSetDataBlock;
  71. WmilibContext->SetWmiDataItem = SpeedCard_WmiSetDataItem;
  72. WmilibContext->ExecuteWmiMethod = NULL; //SpeedCard_WmiExecuteMethod
  73. WmilibContext->WmiFunctionControl = NULL; //SpeedCard_WmiFunctionControl;
  74. return(STATUS_SUCCESS);
  75. }
  76. //
  77. // WMI System Call back functions
  78. //
  79. NTSTATUS
  80. SpeedCard_WmiQueryRegInfo(IN PDEVICE_OBJECT pDevObject, OUT PULONG pRegFlags,
  81. OUT PUNICODE_STRING pInstanceName,
  82. OUT PUNICODE_STRING *pRegistryPath,
  83. OUT PUNICODE_STRING MofResourceName,
  84. OUT PDEVICE_OBJECT *pPdo)
  85. {
  86. NTSTATUS status = STATUS_SUCCESS;
  87. PCARD_DEVICE_EXTENSION pCard = (PCARD_DEVICE_EXTENSION)pDevObject->DeviceExtension;
  88. PAGED_CODE();
  89. *pRegFlags = WMIREG_FLAG_INSTANCE_PDO;
  90. *pRegistryPath = &SavedRegistryPath;
  91. *pPdo = pCard->PDO; // Card device object's PDO.
  92. RtlInitUnicodeString(MofResourceName, L"MofResource");
  93. return(status);
  94. }
  95. NTSTATUS
  96. SpeedCard_WmiQueryDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  97. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  98. IN ULONG InstanceCount, IN OUT PULONG pInstanceLengthArray,
  99. IN ULONG OutBufferSize, OUT PUCHAR pBuffer)
  100. {
  101. PCARD_DEVICE_EXTENSION pCard = (PCARD_DEVICE_EXTENSION)pDevObject->DeviceExtension;
  102. NTSTATUS status;
  103. ULONG size = 0;
  104. PAGED_CODE();
  105. switch(GuidIndex)
  106. {
  107. case WMI_FAST_CARD_PROP:
  108. {
  109. size = sizeof(SPX_SPEED_WMI_FAST_CARD_PROP);
  110. if(OutBufferSize < size)
  111. {
  112. status = STATUS_BUFFER_TOO_SMALL;
  113. break;
  114. }
  115. *pInstanceLengthArray = size;
  116. // Update items that may have changed.
  117. if(pCard->CardOptions & DELAY_INTERRUPT_OPTION)
  118. ((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->DelayCardIntrrupt = TRUE;
  119. else
  120. ((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->DelayCardIntrrupt = FALSE;
  121. if(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION)
  122. ((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->SwapRTSForDTR = TRUE;
  123. else
  124. ((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->SwapRTSForDTR = FALSE;
  125. status = STATUS_SUCCESS;
  126. break;
  127. }
  128. default:
  129. status = STATUS_WMI_GUID_NOT_FOUND;
  130. break;
  131. }
  132. status = WmiCompleteRequest(pDevObject, pIrp, status, size, IO_NO_INCREMENT);
  133. return(status);
  134. }
  135. NTSTATUS
  136. SpeedCard_WmiSetDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  137. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  138. IN ULONG BufferSize, IN PUCHAR pBuffer)
  139. {
  140. PCARD_DEVICE_EXTENSION pCard = (PCARD_DEVICE_EXTENSION)pDevObject->DeviceExtension;
  141. NTSTATUS status;
  142. ULONG size = 0;
  143. PAGED_CODE();
  144. switch(GuidIndex)
  145. {
  146. case WMI_FAST_CARD_PROP:
  147. {
  148. // Device stopping?, Device not powered?, Device not started?
  149. if(SpxCheckPnpPowerFlags((PCOMMON_OBJECT_DATA)pCard, PPF_STOP_PENDING, PPF_POWERED | PPF_STARTED, FALSE))
  150. {
  151. status = STATUS_WMI_SET_FAILURE;
  152. break;
  153. }
  154. size = sizeof(SPX_SPEED_WMI_FAST_CARD_PROP);
  155. if(BufferSize < size)
  156. {
  157. status = STATUS_BUFFER_TOO_SMALL;
  158. break;
  159. }
  160. // Currently these options are only settable on PCI-Fast 16 and PCI-Fast 16 FMC
  161. if((pCard->CardType != Fast16_Pci) && (pCard->CardType != Fast16FMC_Pci))
  162. {
  163. status = STATUS_WMI_READ_ONLY;
  164. break;
  165. }
  166. if(((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->SwapRTSForDTR)
  167. {
  168. // This option is not settable on PCI-Fast 16 FMC
  169. if((pCard->CardType != Fast16_Pci))
  170. {
  171. status = STATUS_WMI_READ_ONLY;
  172. break;
  173. }
  174. }
  175. if(((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->DelayCardIntrrupt)
  176. {
  177. if(!(pCard->CardOptions & DELAY_INTERRUPT_OPTION)) // If not already set then set the option
  178. {
  179. if(KeSynchronizeExecution(pCard->Interrupt, SetCardToDelayInterrupt, pCard))
  180. {
  181. pCard->CardOptions |= DELAY_INTERRUPT_OPTION;
  182. }
  183. else
  184. {
  185. status = STATUS_WMI_SET_FAILURE;
  186. break;
  187. }
  188. }
  189. status = STATUS_SUCCESS;
  190. }
  191. else
  192. {
  193. if(pCard->CardOptions & DELAY_INTERRUPT_OPTION) // If set then unset the option.
  194. {
  195. if(KeSynchronizeExecution(pCard->Interrupt, SetCardNotToDelayInterrupt, pCard))
  196. {
  197. pCard->CardOptions &= ~DELAY_INTERRUPT_OPTION;
  198. }
  199. else
  200. {
  201. status = STATUS_WMI_SET_FAILURE;
  202. break;
  203. }
  204. }
  205. status = STATUS_SUCCESS;
  206. }
  207. if(((PSPX_SPEED_WMI_FAST_CARD_PROP)pBuffer)->SwapRTSForDTR)
  208. {
  209. if(!(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION)) // If not already set then set the option
  210. {
  211. if(KeSynchronizeExecution(pCard->Interrupt, SetCardToUseDTRInsteadOfRTS, pCard))
  212. {
  213. pCard->CardOptions |= SWAP_RTS_FOR_DTR_OPTION;
  214. }
  215. else
  216. {
  217. status = STATUS_WMI_SET_FAILURE;
  218. break;
  219. }
  220. }
  221. status = STATUS_SUCCESS;
  222. }
  223. else
  224. {
  225. if(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION) // If set then unset the option.
  226. {
  227. if(KeSynchronizeExecution(pCard->Interrupt, SetCardNotToUseDTRInsteadOfRTS, pCard))
  228. {
  229. pCard->CardOptions &= ~SWAP_RTS_FOR_DTR_OPTION;
  230. }
  231. else
  232. {
  233. status = STATUS_WMI_SET_FAILURE;
  234. break;
  235. }
  236. }
  237. status = STATUS_SUCCESS;
  238. }
  239. if(SPX_SUCCESS(status)) // If set was successful then save setting to registry.
  240. {
  241. HANDLE PnPKeyHandle;
  242. // Open PnP Reg Key and save new setting to registry.
  243. if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pCard->PDO, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, &PnPKeyHandle)))
  244. {
  245. ULONG TmpReg = 0;
  246. if(pCard->CardOptions & DELAY_INTERRUPT_OPTION)
  247. TmpReg = 0x1;
  248. else
  249. TmpReg = 0x0;
  250. Spx_PutRegistryKeyValue( PnPKeyHandle, DELAY_INTERRUPT, wcslen(DELAY_INTERRUPT) * sizeof(WCHAR), REG_DWORD,
  251. &TmpReg, sizeof(ULONG));
  252. if(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION)
  253. TmpReg = 0x1;
  254. else
  255. TmpReg = 0x0;
  256. Spx_PutRegistryKeyValue( PnPKeyHandle, SWAP_RTS_FOR_DTR, wcslen(SWAP_RTS_FOR_DTR) * sizeof(WCHAR), REG_DWORD,
  257. &TmpReg, sizeof(ULONG));
  258. ZwClose(PnPKeyHandle);
  259. }
  260. }
  261. break;
  262. }
  263. default:
  264. status = STATUS_WMI_GUID_NOT_FOUND;
  265. break;
  266. }
  267. status = WmiCompleteRequest(pDevObject, pIrp, status, size, IO_NO_INCREMENT);
  268. return(status);
  269. }
  270. NTSTATUS
  271. SpeedCard_WmiSetDataItem(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  272. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  273. IN ULONG DataItemId, IN ULONG BufferSize,
  274. IN PUCHAR pBuffer)
  275. {
  276. PCARD_DEVICE_EXTENSION pCard = (PCARD_DEVICE_EXTENSION)pDevObject->DeviceExtension;
  277. NTSTATUS status;
  278. ULONG size = 0;
  279. PAGED_CODE();
  280. switch(GuidIndex)
  281. {
  282. case WMI_FAST_CARD_PROP:
  283. {
  284. HANDLE PnPKeyHandle;
  285. // Device stopping?, Device not powered?, Device not started?
  286. if(SpxCheckPnpPowerFlags((PCOMMON_OBJECT_DATA)pCard, PPF_STOP_PENDING, PPF_POWERED | PPF_STARTED, FALSE))
  287. {
  288. status = STATUS_WMI_SET_FAILURE;
  289. break;
  290. }
  291. switch(DataItemId)
  292. {
  293. case SPX_SPEED_WMI_FAST_CARD_PROP_DelayCardIntrrupt_ID:
  294. {
  295. size = sizeof(SPX_SPEED_WMI_FAST_CARD_PROP_DelayCardIntrrupt_SIZE);
  296. if(BufferSize < size)
  297. {
  298. status = STATUS_BUFFER_TOO_SMALL;
  299. break;
  300. }
  301. if((pCard->CardType != Fast16_Pci) && (pCard->CardType != Fast16FMC_Pci))
  302. {
  303. status = STATUS_WMI_READ_ONLY;
  304. break;
  305. }
  306. if(*pBuffer)
  307. {
  308. if(!(pCard->CardOptions & DELAY_INTERRUPT_OPTION)) // If not already set then set the option
  309. {
  310. if(KeSynchronizeExecution(pCard->Interrupt, SetCardToDelayInterrupt, pCard))
  311. {
  312. pCard->CardOptions |= DELAY_INTERRUPT_OPTION;
  313. }
  314. else
  315. {
  316. status = STATUS_WMI_SET_FAILURE;
  317. break;
  318. }
  319. }
  320. status = STATUS_SUCCESS;
  321. }
  322. else
  323. {
  324. if(pCard->CardOptions & DELAY_INTERRUPT_OPTION) // If set then unset the option.
  325. {
  326. if(KeSynchronizeExecution(pCard->Interrupt, SetCardNotToDelayInterrupt, pCard))
  327. {
  328. pCard->CardOptions &= ~DELAY_INTERRUPT_OPTION;
  329. }
  330. else
  331. {
  332. status = STATUS_WMI_SET_FAILURE;
  333. break;
  334. }
  335. }
  336. status = STATUS_SUCCESS;
  337. }
  338. if(SPX_SUCCESS(status)) // If we set the option successfully then save the setting to the registry.
  339. {
  340. // Open PnP Reg Key and save new setting to registry.
  341. if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pCard->PDO, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, &PnPKeyHandle)))
  342. {
  343. ULONG TmpReg = 0;
  344. if(pCard->CardOptions & DELAY_INTERRUPT_OPTION)
  345. TmpReg = 0x1;
  346. else
  347. TmpReg = 0x0;
  348. Spx_PutRegistryKeyValue( PnPKeyHandle, DELAY_INTERRUPT, wcslen(DELAY_INTERRUPT) * sizeof(WCHAR), REG_DWORD,
  349. &TmpReg, sizeof(ULONG));
  350. ZwClose(PnPKeyHandle);
  351. }
  352. }
  353. break;
  354. }
  355. case SPX_SPEED_WMI_FAST_CARD_PROP_SwapRTSForDTR_ID:
  356. {
  357. size = sizeof(SPX_SPEED_WMI_FAST_CARD_PROP_SwapRTSForDTR_SIZE);
  358. if(BufferSize < size)
  359. {
  360. status = STATUS_BUFFER_TOO_SMALL;
  361. break;
  362. }
  363. if(pCard->CardType != Fast16_Pci)
  364. {
  365. status = STATUS_WMI_READ_ONLY;
  366. break;
  367. }
  368. if(*pBuffer)
  369. {
  370. if(!(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION)) // If not already set then set the option
  371. {
  372. if(KeSynchronizeExecution(pCard->Interrupt, SetCardToUseDTRInsteadOfRTS, pCard))
  373. {
  374. pCard->CardOptions |= SWAP_RTS_FOR_DTR_OPTION;
  375. }
  376. else
  377. {
  378. status = STATUS_WMI_SET_FAILURE;
  379. break;
  380. }
  381. }
  382. status = STATUS_SUCCESS;
  383. }
  384. else
  385. {
  386. if(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION) // If set then unset the option.
  387. {
  388. if(KeSynchronizeExecution(pCard->Interrupt, SetCardNotToUseDTRInsteadOfRTS, pCard))
  389. {
  390. pCard->CardOptions &= ~SWAP_RTS_FOR_DTR_OPTION;
  391. }
  392. else
  393. {
  394. status = STATUS_WMI_SET_FAILURE;
  395. break;
  396. }
  397. }
  398. status = STATUS_SUCCESS;
  399. }
  400. if(SPX_SUCCESS(status)) // If we set the option successfully then save the setting to the registry.
  401. {
  402. // Open PnP Reg Key and save new setting to registry.
  403. if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pCard->PDO, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, &PnPKeyHandle)))
  404. {
  405. ULONG TmpReg = 0;
  406. if(pCard->CardOptions & SWAP_RTS_FOR_DTR_OPTION)
  407. TmpReg = 0x1;
  408. else
  409. TmpReg = 0x0;
  410. Spx_PutRegistryKeyValue( PnPKeyHandle, SWAP_RTS_FOR_DTR, wcslen(SWAP_RTS_FOR_DTR) * sizeof(WCHAR), REG_DWORD,
  411. &TmpReg, sizeof(ULONG));
  412. ZwClose(PnPKeyHandle);
  413. }
  414. }
  415. break;
  416. }
  417. default:
  418. {
  419. status = STATUS_WMI_ITEMID_NOT_FOUND;
  420. break;
  421. }
  422. }
  423. break;
  424. }
  425. default:
  426. status = STATUS_WMI_GUID_NOT_FOUND;
  427. break;
  428. }
  429. status = WmiCompleteRequest(pDevObject, pIrp, status, size, IO_NO_INCREMENT);
  430. return(status);
  431. }