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.

660 lines
19 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. // -- PORT WMI Routines --
  15. NTSTATUS
  16. SpeedPort_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. SpeedPort_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. SpeedPort_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. SpeedPort_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, SpeedPort_WmiInitializeWmilibContext)
  38. #pragma alloc_text(PAGE, SpeedPort_WmiQueryRegInfo)
  39. #pragma alloc_text(PAGE, SpeedPort_WmiQueryDataBlock)
  40. #pragma alloc_text(PAGE, SpeedPort_WmiSetDataBlock)
  41. #pragma alloc_text(PAGE, SpeedPort_WmiSetDataItem)
  42. #endif
  43. #define WMI_SERIAL_PORT_NAME_INFORMATION 0
  44. #define WMI_SERIAL_PORT_COMM_INFORMATION 1
  45. #define WMI_SERIAL_PORT_HW_INFORMATION 2
  46. #define WMI_SERIAL_PORT_PERF_INFORMATION 3
  47. #define WMI_SERIAL_PORT_PROPERTIES 4
  48. #define WMI_SPEED_PORT_FIFO_PROP 5
  49. GUID SpeedPortStdSerialWmiPortNameGuid = SERIAL_PORT_WMI_NAME_GUID; // Standard Serial WMI
  50. GUID SpeedPortStdSerialWmiPortCommGuid = SERIAL_PORT_WMI_COMM_GUID; // Standard Serial WMI
  51. GUID SpeedPortStdSerialWmiPortHWGuid = SERIAL_PORT_WMI_HW_GUID; // Standard Serial WMI
  52. GUID SpeedPortStdSerialWmiPortPerfGuid = SERIAL_PORT_WMI_PERF_GUID; // Standard Serial WMI
  53. GUID SpeedPortStdSerialWmiPortPropertiesGuid = SERIAL_PORT_WMI_PROPERTIES_GUID; // Standard Serial WMI
  54. GUID SpeedPortWmiFifoPropGuid = SPX_SPEED_WMI_FIFO_PROP_GUID; // Speed WMI
  55. WMIGUIDREGINFO SpeedPort_WmiGuidList[] =
  56. {
  57. { &SpeedPortStdSerialWmiPortNameGuid, 1, 0 },
  58. { &SpeedPortStdSerialWmiPortCommGuid, 1, 0 },
  59. { &SpeedPortStdSerialWmiPortHWGuid, 1, 0 },
  60. { &SpeedPortStdSerialWmiPortPerfGuid, 1, 0 },
  61. { &SpeedPortStdSerialWmiPortPropertiesGuid, 1, 0},
  62. { &SpeedPortWmiFifoPropGuid, 1, 0 },
  63. };
  64. #define SpeedPort_WmiGuidCount (sizeof(SpeedPort_WmiGuidList) / sizeof(WMIGUIDREGINFO))
  65. NTSTATUS
  66. SpeedPort_WmiInitializeWmilibContext(IN PWMILIB_CONTEXT WmilibContext)
  67. /*++
  68. Routine Description:
  69. This routine will initialize the wmilib context structure with the
  70. guid list and the pointers to the wmilib callback functions. This routine
  71. should be called before calling IoWmiRegistrationControl to register
  72. your device object.
  73. Arguments:
  74. WmilibContext is pointer to the wmilib context.
  75. Return Value:
  76. status
  77. --*/
  78. {
  79. PAGED_CODE();
  80. RtlZeroMemory(WmilibContext, sizeof(WMILIB_CONTEXT));
  81. WmilibContext->GuidCount = SpeedPort_WmiGuidCount;
  82. WmilibContext->GuidList = SpeedPort_WmiGuidList;
  83. WmilibContext->QueryWmiRegInfo = SpeedPort_WmiQueryRegInfo;
  84. WmilibContext->QueryWmiDataBlock = SpeedPort_WmiQueryDataBlock;
  85. WmilibContext->SetWmiDataBlock = SpeedPort_WmiSetDataBlock;
  86. WmilibContext->SetWmiDataItem = SpeedPort_WmiSetDataItem;
  87. WmilibContext->ExecuteWmiMethod = NULL; //SpeedPort_WmiExecuteMethod
  88. WmilibContext->WmiFunctionControl = NULL; //SpeedPort_WmiFunctionControl;
  89. return(STATUS_SUCCESS);
  90. }
  91. //
  92. // WMI System Call back functions
  93. //
  94. NTSTATUS
  95. SpeedPort_WmiQueryRegInfo(IN PDEVICE_OBJECT pDevObject, OUT PULONG pRegFlags,
  96. OUT PUNICODE_STRING pInstanceName,
  97. OUT PUNICODE_STRING *pRegistryPath,
  98. OUT PUNICODE_STRING MofResourceName,
  99. OUT PDEVICE_OBJECT *pPdo)
  100. {
  101. NTSTATUS status = STATUS_SUCCESS;
  102. PPORT_DEVICE_EXTENSION pPort = (PPORT_DEVICE_EXTENSION)pDevObject->DeviceExtension;
  103. PAGED_CODE();
  104. *pRegFlags = WMIREG_FLAG_INSTANCE_PDO;
  105. *pRegistryPath = &SavedRegistryPath;
  106. *pPdo = pDevObject; // Port device object is a PDO.
  107. RtlInitUnicodeString(MofResourceName, L"MofResource");
  108. return(status);
  109. }
  110. NTSTATUS
  111. SpeedPort_WmiQueryDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  112. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  113. IN ULONG InstanceCount, IN OUT PULONG pInstanceLengthArray,
  114. IN ULONG OutBufferSize, OUT PUCHAR pBuffer)
  115. {
  116. PPORT_DEVICE_EXTENSION pPort = (PPORT_DEVICE_EXTENSION)pDevObject->DeviceExtension;
  117. NTSTATUS status;
  118. ULONG size = 0;
  119. PAGED_CODE();
  120. switch(GuidIndex)
  121. {
  122. case WMI_SERIAL_PORT_NAME_INFORMATION:
  123. {
  124. size = pPort->DosName.Length;
  125. if(OutBufferSize < (size + sizeof(USHORT)))
  126. {
  127. size += sizeof(USHORT);
  128. status = STATUS_BUFFER_TOO_SMALL;
  129. break;
  130. }
  131. if(pPort->DosName.Buffer == NULL)
  132. {
  133. status = STATUS_INSUFFICIENT_RESOURCES;
  134. break;
  135. }
  136. // First, copy the string over containing our identifier
  137. *(USHORT *)pBuffer = (USHORT)size;
  138. (UCHAR *)pBuffer += sizeof(USHORT);
  139. RtlCopyMemory(pBuffer, pPort->DosName.Buffer, size);
  140. // Increment total size to include the WORD containing our len
  141. size += sizeof(USHORT);
  142. *pInstanceLengthArray = size;
  143. status = STATUS_SUCCESS;
  144. break;
  145. }
  146. case WMI_SERIAL_PORT_COMM_INFORMATION:
  147. {
  148. size = sizeof(SERIAL_WMI_COMM_DATA);
  149. if(OutBufferSize < size)
  150. {
  151. status = STATUS_BUFFER_TOO_SMALL;
  152. break;
  153. }
  154. *pInstanceLengthArray = size;
  155. *(PSERIAL_WMI_COMM_DATA)pBuffer = pPort->WmiCommData;
  156. status = STATUS_SUCCESS;
  157. break;
  158. }
  159. case WMI_SERIAL_PORT_HW_INFORMATION:
  160. {
  161. size = sizeof(SERIAL_WMI_HW_DATA);
  162. if(OutBufferSize < size)
  163. {
  164. status = STATUS_BUFFER_TOO_SMALL;
  165. break;
  166. }
  167. *pInstanceLengthArray = size;
  168. *(PSERIAL_WMI_HW_DATA)pBuffer = pPort->WmiHwData;
  169. status = STATUS_SUCCESS;
  170. break;
  171. }
  172. case WMI_SERIAL_PORT_PERF_INFORMATION:
  173. {
  174. size = sizeof(SERIAL_WMI_PERF_DATA);
  175. if(OutBufferSize < size)
  176. {
  177. status = STATUS_BUFFER_TOO_SMALL;
  178. break;
  179. }
  180. *pInstanceLengthArray = size;
  181. *(PSERIAL_WMI_PERF_DATA)pBuffer = pPort->WmiPerfData;
  182. status = STATUS_SUCCESS;
  183. break;
  184. }
  185. case WMI_SERIAL_PORT_PROPERTIES:
  186. {
  187. size = sizeof(SERIAL_COMMPROP) + sizeof(ULONG);
  188. if(OutBufferSize < size)
  189. {
  190. status = STATUS_BUFFER_TOO_SMALL;
  191. break;
  192. }
  193. *pInstanceLengthArray = size;
  194. SerialGetProperties(pPort, (PSERIAL_COMMPROP)pBuffer);
  195. *((PULONG)(((PSERIAL_COMMPROP)pBuffer)->ProvChar)) = 0;
  196. status = STATUS_SUCCESS;
  197. break;
  198. }
  199. case WMI_SPEED_PORT_FIFO_PROP:
  200. {
  201. size = sizeof(SPX_SPEED_WMI_FIFO_PROP);
  202. if(OutBufferSize < size)
  203. {
  204. status = STATUS_BUFFER_TOO_SMALL;
  205. break;
  206. }
  207. *pInstanceLengthArray = size;
  208. // Update items that may have changed.
  209. pPort->SpeedWmiFifoProp.TxFiFoLimit = pPort->TxFIFOSize;
  210. pPort->SpeedWmiFifoProp.TxFiFoTrigger = pPort->TxFIFOTrigLevel;
  211. pPort->SpeedWmiFifoProp.RxFiFoTrigger = pPort->RxFIFOTrigLevel;
  212. pPort->SpeedWmiFifoProp.LoFlowCtrlThreshold = pPort->LoFlowCtrlThreshold;
  213. pPort->SpeedWmiFifoProp.HiFlowCtrlThreshold = pPort->HiFlowCtrlThreshold;
  214. *(PSPX_SPEED_WMI_FIFO_PROP)pBuffer = pPort->SpeedWmiFifoProp;
  215. status = STATUS_SUCCESS;
  216. break;
  217. }
  218. default:
  219. status = STATUS_WMI_GUID_NOT_FOUND;
  220. break;
  221. }
  222. status = WmiCompleteRequest(pDevObject, pIrp, status, size, IO_NO_INCREMENT);
  223. return(status);
  224. }
  225. NTSTATUS
  226. SpeedPort_WmiSetDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  227. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  228. IN ULONG BufferSize, IN PUCHAR pBuffer)
  229. {
  230. PPORT_DEVICE_EXTENSION pPort = (PPORT_DEVICE_EXTENSION)pDevObject->DeviceExtension;
  231. PCARD_DEVICE_EXTENSION pCard = pPort->pParentCardExt;
  232. NTSTATUS status;
  233. ULONG size = 0;
  234. PAGED_CODE();
  235. switch(GuidIndex)
  236. {
  237. case WMI_SERIAL_PORT_NAME_INFORMATION:
  238. case WMI_SERIAL_PORT_COMM_INFORMATION:
  239. case WMI_SERIAL_PORT_HW_INFORMATION:
  240. case WMI_SERIAL_PORT_PERF_INFORMATION:
  241. case WMI_SERIAL_PORT_PROPERTIES:
  242. status = STATUS_WMI_READ_ONLY;
  243. break;
  244. case WMI_SPEED_PORT_FIFO_PROP:
  245. {
  246. // Device stopping?, Device not powered?, Device not started?
  247. if(SpxCheckPnpPowerFlags((PCOMMON_OBJECT_DATA)pPort, PPF_STOP_PENDING, PPF_POWERED | PPF_STARTED, FALSE))
  248. {
  249. status = STATUS_WMI_SET_FAILURE;
  250. break;
  251. }
  252. if(BufferSize < sizeof(SPX_SPEED_WMI_FIFO_PROP))
  253. {
  254. status = STATUS_BUFFER_TOO_SMALL;
  255. break;
  256. }
  257. // These Items are read only - If we have been asked to change them fail request.
  258. if((pPort->SpeedWmiFifoProp.MaxTxFiFoSize != ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->MaxTxFiFoSize)
  259. || (pPort->SpeedWmiFifoProp.MaxRxFiFoSize != ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->MaxRxFiFoSize)
  260. || (pPort->SpeedWmiFifoProp.DefaultTxFiFoLimit != ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->DefaultTxFiFoLimit)
  261. || (pPort->SpeedWmiFifoProp.DefaultTxFiFoTrigger != ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->DefaultTxFiFoTrigger)
  262. || (pPort->SpeedWmiFifoProp.DefaultRxFiFoTrigger != ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->DefaultRxFiFoTrigger)
  263. || (pPort->SpeedWmiFifoProp.DefaultLoFlowCtrlThreshold != ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->DefaultLoFlowCtrlThreshold)
  264. || (pPort->SpeedWmiFifoProp.DefaultHiFlowCtrlThreshold != ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->DefaultHiFlowCtrlThreshold))
  265. {
  266. status = STATUS_WMI_READ_ONLY;
  267. break;
  268. }
  269. if((pCard->CardType == Fast4_Isa) || (pCard->CardType == Fast4_Pci) || (pCard->CardType == RAS4_Pci)
  270. || (pCard->CardType == Fast8_Isa) || (pCard->CardType == Fast8_Pci) || (pCard->CardType == RAS8_Pci)
  271. || (pCard->CardType == Fast16_Isa) || (pCard->CardType == Fast16_Pci) || (pCard->CardType == Fast16FMC_Pci))
  272. {
  273. if((pPort->LoFlowCtrlThreshold != ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->LoFlowCtrlThreshold)
  274. || (pPort->HiFlowCtrlThreshold != ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->HiFlowCtrlThreshold))
  275. {
  276. status = STATUS_WMI_READ_ONLY; // Flow ctrl threshold cannot be modified on Fast cards.
  277. break;
  278. }
  279. }
  280. pPort->TxFIFOSize = ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->TxFiFoLimit;
  281. pPort->TxFIFOTrigLevel = ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->TxFiFoTrigger;
  282. pPort->RxFIFOTrigLevel = ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->RxFiFoTrigger;
  283. pPort->LoFlowCtrlThreshold = ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->LoFlowCtrlThreshold;
  284. pPort->HiFlowCtrlThreshold = ((PSPX_SPEED_WMI_FIFO_PROP)pBuffer)->HiFlowCtrlThreshold;
  285. // Make settings
  286. if(KeSynchronizeExecution(pPort->Interrupt, SetPortFiFoSettings, pPort))
  287. {
  288. HANDLE PnPKeyHandle;
  289. // Open PnP Reg Key and save new setting to registry.
  290. if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pDevObject, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, &PnPKeyHandle)))
  291. {
  292. Spx_PutRegistryKeyValue( PnPKeyHandle, TX_FIFO_LIMIT, wcslen(TX_FIFO_LIMIT) * sizeof(WCHAR), REG_DWORD,
  293. &pPort->TxFIFOSize, sizeof(ULONG));
  294. Spx_PutRegistryKeyValue( PnPKeyHandle, TX_FIFO_TRIG_LEVEL, wcslen(TX_FIFO_TRIG_LEVEL) * sizeof(WCHAR), REG_DWORD,
  295. &pPort->TxFIFOTrigLevel, sizeof(ULONG));
  296. Spx_PutRegistryKeyValue( PnPKeyHandle, RX_FIFO_TRIG_LEVEL, wcslen(RX_FIFO_TRIG_LEVEL) * sizeof(WCHAR), REG_DWORD,
  297. &pPort->RxFIFOTrigLevel, sizeof(ULONG));
  298. Spx_PutRegistryKeyValue( PnPKeyHandle, LO_FLOW_CTRL_LEVEL, wcslen(LO_FLOW_CTRL_LEVEL) * sizeof(WCHAR), REG_DWORD,
  299. &pPort->LoFlowCtrlThreshold, sizeof(ULONG));
  300. Spx_PutRegistryKeyValue( PnPKeyHandle, HI_FLOW_CTRL_LEVEL, wcslen(HI_FLOW_CTRL_LEVEL) * sizeof(WCHAR), REG_DWORD,
  301. &pPort->HiFlowCtrlThreshold, sizeof(ULONG));
  302. ZwClose(PnPKeyHandle);
  303. }
  304. status = STATUS_SUCCESS;
  305. }
  306. else
  307. {
  308. status = STATUS_WMI_SET_FAILURE;
  309. }
  310. break;
  311. }
  312. default:
  313. status = STATUS_WMI_GUID_NOT_FOUND;
  314. break;
  315. }
  316. status = WmiCompleteRequest(pDevObject, pIrp, status, size, IO_NO_INCREMENT);
  317. return(status);
  318. }
  319. NTSTATUS
  320. SpeedPort_WmiSetDataItem(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  321. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  322. IN ULONG DataItemId, IN ULONG BufferSize,
  323. IN PUCHAR pBuffer)
  324. {
  325. PPORT_DEVICE_EXTENSION pPort = (PPORT_DEVICE_EXTENSION)pDevObject->DeviceExtension;
  326. PCARD_DEVICE_EXTENSION pCard = pPort->pParentCardExt;
  327. NTSTATUS status;
  328. ULONG size = 0;
  329. PAGED_CODE();
  330. switch(GuidIndex)
  331. {
  332. case WMI_SERIAL_PORT_NAME_INFORMATION:
  333. case WMI_SERIAL_PORT_COMM_INFORMATION:
  334. case WMI_SERIAL_PORT_HW_INFORMATION:
  335. case WMI_SERIAL_PORT_PERF_INFORMATION:
  336. case WMI_SERIAL_PORT_PROPERTIES:
  337. status = STATUS_WMI_READ_ONLY;
  338. break;
  339. case WMI_SPEED_PORT_FIFO_PROP:
  340. {
  341. HANDLE PnPKeyHandle;
  342. // Device stopping?, Device not powered?, Device not started?
  343. if(SpxCheckPnpPowerFlags((PCOMMON_OBJECT_DATA)pPort, PPF_STOP_PENDING, PPF_POWERED | PPF_STARTED, FALSE))
  344. {
  345. status = STATUS_WMI_SET_FAILURE;
  346. break;
  347. }
  348. switch(DataItemId)
  349. {
  350. case SPX_SPEED_WMI_FIFO_PROP_MaxTxFiFoSize_ID:
  351. case SPX_SPEED_WMI_FIFO_PROP_MaxRxFiFoSize_ID:
  352. case SPX_SPEED_WMI_FIFO_PROP_DefaultTxFiFoLimit_ID:
  353. case SPX_SPEED_WMI_FIFO_PROP_DefaultTxFiFoTrigger_ID:
  354. case SPX_SPEED_WMI_FIFO_PROP_DefaultRxFiFoTrigger_ID:
  355. case SPX_SPEED_WMI_FIFO_PROP_DefaultLoFlowCtrlThreshold_ID:
  356. case SPX_SPEED_WMI_FIFO_PROP_DefaultHiFlowCtrlThreshold_ID:
  357. status = STATUS_WMI_READ_ONLY;
  358. break;
  359. case SPX_SPEED_WMI_FIFO_PROP_TxFiFoLimit_ID:
  360. pPort->TxFIFOSize = *pBuffer;
  361. if(KeSynchronizeExecution(pPort->Interrupt, SetPortFiFoSettings, pPort))
  362. {
  363. // Open PnP Reg Key and save new setting to registry.
  364. if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pDevObject, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, &PnPKeyHandle)))
  365. {
  366. Spx_PutRegistryKeyValue( PnPKeyHandle, TX_FIFO_LIMIT, wcslen(TX_FIFO_LIMIT) * sizeof(WCHAR), REG_DWORD,
  367. &pPort->TxFIFOSize, sizeof(ULONG));
  368. ZwClose(PnPKeyHandle);
  369. }
  370. status = STATUS_SUCCESS;
  371. }
  372. else
  373. {
  374. status = STATUS_WMI_SET_FAILURE;
  375. }
  376. break;
  377. case SPX_SPEED_WMI_FIFO_PROP_TxFiFoTrigger_ID:
  378. pPort->TxFIFOTrigLevel = *pBuffer;
  379. if(KeSynchronizeExecution(pPort->Interrupt, SetPortFiFoSettings, pPort))
  380. {
  381. // Open PnP Reg Key and save new setting to registry.
  382. if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pDevObject, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, &PnPKeyHandle)))
  383. {
  384. Spx_PutRegistryKeyValue( PnPKeyHandle, TX_FIFO_TRIG_LEVEL, wcslen(TX_FIFO_TRIG_LEVEL) * sizeof(WCHAR), REG_DWORD,
  385. &pPort->TxFIFOTrigLevel, sizeof(ULONG));
  386. ZwClose(PnPKeyHandle);
  387. }
  388. status = STATUS_SUCCESS;
  389. }
  390. else
  391. {
  392. status = STATUS_WMI_SET_FAILURE;
  393. }
  394. break;
  395. case SPX_SPEED_WMI_FIFO_PROP_RxFiFoTrigger_ID:
  396. pPort->RxFIFOTrigLevel = *pBuffer;
  397. if(KeSynchronizeExecution(pPort->Interrupt, SetPortFiFoSettings, pPort))
  398. {
  399. // Open PnP Reg Key and save new setting to registry.
  400. if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pDevObject, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, &PnPKeyHandle)))
  401. {
  402. Spx_PutRegistryKeyValue( PnPKeyHandle, RX_FIFO_TRIG_LEVEL, wcslen(RX_FIFO_TRIG_LEVEL) * sizeof(WCHAR), REG_DWORD,
  403. &pPort->RxFIFOTrigLevel, sizeof(ULONG));
  404. ZwClose(PnPKeyHandle);
  405. }
  406. status = STATUS_SUCCESS;
  407. }
  408. else
  409. {
  410. status = STATUS_WMI_SET_FAILURE;
  411. }
  412. break;
  413. case SPX_SPEED_WMI_FIFO_PROP_LoFlowCtrlThreshold_ID:
  414. if((pCard->CardType == Fast4_Isa) || (pCard->CardType == Fast4_Pci) || (pCard->CardType == RAS4_Pci)
  415. || (pCard->CardType == Fast8_Isa) || (pCard->CardType == Fast8_Pci) || (pCard->CardType == RAS8_Pci)
  416. || (pCard->CardType == Fast16_Isa) || (pCard->CardType == Fast16_Pci) || (pCard->CardType == Fast16FMC_Pci))
  417. {
  418. if(pPort->SpeedWmiFifoProp.LoFlowCtrlThreshold != *pBuffer)
  419. {
  420. status = STATUS_WMI_READ_ONLY; // Flow ctrl threshold cannot be modified on Fast cards.
  421. break;
  422. }
  423. }
  424. pPort->LoFlowCtrlThreshold = *pBuffer;
  425. if(KeSynchronizeExecution(pPort->Interrupt, SetPortFiFoSettings, pPort))
  426. {
  427. // Open PnP Reg Key and save new setting to registry.
  428. if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pDevObject, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, &PnPKeyHandle)))
  429. {
  430. Spx_PutRegistryKeyValue( PnPKeyHandle, LO_FLOW_CTRL_LEVEL, wcslen(LO_FLOW_CTRL_LEVEL) * sizeof(WCHAR), REG_DWORD,
  431. &pPort->LoFlowCtrlThreshold, sizeof(ULONG));
  432. ZwClose(PnPKeyHandle);
  433. }
  434. status = STATUS_SUCCESS;
  435. }
  436. else
  437. {
  438. status = STATUS_WMI_SET_FAILURE;
  439. }
  440. break;
  441. case SPX_SPEED_WMI_FIFO_PROP_HiFlowCtrlThreshold_ID:
  442. if((pCard->CardType == Fast4_Isa) || (pCard->CardType == Fast4_Pci) || (pCard->CardType == RAS4_Pci)
  443. || (pCard->CardType == Fast8_Isa) || (pCard->CardType == Fast8_Pci) || (pCard->CardType == RAS8_Pci)
  444. || (pCard->CardType == Fast16_Isa) || (pCard->CardType == Fast16_Pci) || (pCard->CardType == Fast16FMC_Pci))
  445. {
  446. if(pPort->SpeedWmiFifoProp.HiFlowCtrlThreshold != *pBuffer)
  447. {
  448. status = STATUS_WMI_READ_ONLY; // Flow ctrl threshold cannot be modified on Fast cards.
  449. break;
  450. }
  451. }
  452. pPort->HiFlowCtrlThreshold = *pBuffer;
  453. if(KeSynchronizeExecution(pPort->Interrupt, SetPortFiFoSettings, pPort))
  454. {
  455. // Open PnP Reg Key and save new setting to registry.
  456. if(SPX_SUCCESS(IoOpenDeviceRegistryKey(pDevObject, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_WRITE, &PnPKeyHandle)))
  457. {
  458. Spx_PutRegistryKeyValue( PnPKeyHandle, HI_FLOW_CTRL_LEVEL, wcslen(HI_FLOW_CTRL_LEVEL) * sizeof(WCHAR), REG_DWORD,
  459. &pPort->HiFlowCtrlThreshold, sizeof(ULONG));
  460. ZwClose(PnPKeyHandle);
  461. }
  462. status = STATUS_SUCCESS;
  463. }
  464. else
  465. {
  466. status = STATUS_WMI_SET_FAILURE;
  467. }
  468. break;
  469. default:
  470. status = STATUS_WMI_ITEMID_NOT_FOUND;
  471. break;
  472. }
  473. break;
  474. }
  475. default:
  476. status = STATUS_WMI_GUID_NOT_FOUND;
  477. break;
  478. }
  479. status = WmiCompleteRequest(pDevObject, pIrp, status, size, IO_NO_INCREMENT);
  480. return(status);
  481. }