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.

464 lines
11 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. NTSTATUS
  15. SpxPort_WmiQueryRegInfo(IN PDEVICE_OBJECT pDevObject, OUT PULONG pRegFlags,
  16. OUT PUNICODE_STRING pInstanceName,
  17. OUT PUNICODE_STRING *pRegistryPath,
  18. OUT PUNICODE_STRING pMofResourceName,
  19. OUT PDEVICE_OBJECT *pPdo);
  20. NTSTATUS
  21. SpxPort_WmiQueryDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  22. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  23. IN ULONG InstanceCount, IN OUT PULONG pInstanceLengthArray,
  24. IN ULONG OutBufferSize, OUT PUCHAR pBuffer);
  25. NTSTATUS
  26. SpxPort_WmiSetDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  27. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  28. IN ULONG BufferSize, IN PUCHAR pBuffer);
  29. NTSTATUS
  30. SpxPort_WmiSetDataItem(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  31. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  32. IN ULONG DataItemId, IN ULONG BufferSize,
  33. IN PUCHAR pBuffer);
  34. // End of prototypes.
  35. #ifdef ALLOC_PRAGMA
  36. #pragma alloc_text(PAGE, Spx_DispatchSystemControl)
  37. #pragma alloc_text(PAGE, SpxPort_WmiInitializeWmilibContext)
  38. #pragma alloc_text(PAGE, SpxPort_WmiQueryRegInfo)
  39. #pragma alloc_text(PAGE, SpxPort_WmiQueryDataBlock)
  40. #pragma alloc_text(PAGE, SpxPort_WmiSetDataBlock)
  41. #pragma alloc_text(PAGE, SpxPort_WmiSetDataItem)
  42. #endif
  43. /********************************************************************************
  44. ******************** *****************************
  45. ******************** Spx_SystemControlDispatch *****************************
  46. ******************** *****************************
  47. ********************************************************************************/
  48. NTSTATUS
  49. Spx_DispatchSystemControl(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp)
  50. {
  51. PCOMMON_OBJECT_DATA pCommonData = (PCOMMON_OBJECT_DATA) pDevObject->DeviceExtension;
  52. SYSCTL_IRP_DISPOSITION IrpDisposition;
  53. PDEVICE_OBJECT pLowerDevObj = pCommonData->LowerDeviceObject;
  54. NTSTATUS status = pIrp->IoStatus.Status;
  55. PAGED_CODE();
  56. SpxDbgMsg(SPX_TRACE_CALLS,("%s: Entering Spx_DispatchSystemControl.\n", PRODUCT_NAME));
  57. status = WmiSystemControl(&pCommonData->WmiLibInfo, pDevObject, pIrp, &IrpDisposition);
  58. switch(IrpDisposition)
  59. {
  60. case IrpProcessed:
  61. {
  62. // This irp has been processed and may be completed or pending.
  63. break;
  64. }
  65. case IrpNotCompleted:
  66. {
  67. // This irp has not been completed, but has been fully processed, we will complete it now.
  68. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  69. break;
  70. }
  71. case IrpForward:
  72. case IrpNotWmi:
  73. {
  74. // This irp is either not a WMI irp or is a WMI irp targetted at a device lower in the stack.
  75. if(pLowerDevObj) // If we can pass the IRP down we must do so.
  76. {
  77. IoSkipCurrentIrpStackLocation(pIrp);
  78. status = IoCallDriver(pLowerDevObj, pIrp);
  79. }
  80. else // Otherwise complete the IRP.
  81. {
  82. status = pIrp->IoStatus.Status;
  83. //pIrp->IoStatus.Information = 0;
  84. IoCompleteRequest(pIrp,IO_NO_INCREMENT);
  85. }
  86. break;
  87. }
  88. default:
  89. {
  90. // We really should never get here, but if we do just forward....
  91. ASSERT(FALSE);
  92. if(pLowerDevObj) // If we can pass the IRP down we must do so.
  93. {
  94. IoSkipCurrentIrpStackLocation(pIrp);
  95. status = IoCallDriver(pLowerDevObj, pIrp);
  96. }
  97. else // Otherwise complete the IRP.
  98. {
  99. status = pIrp->IoStatus.Status;
  100. //pIrp->IoStatus.Information = 0;
  101. IoCompleteRequest(pIrp,IO_NO_INCREMENT);
  102. }
  103. break;
  104. }
  105. }
  106. return(status);
  107. }
  108. // End of prototypes.
  109. #define WMI_SERIAL_PORT_NAME_INFORMATION 0
  110. #define WMI_SERIAL_PORT_COMM_INFORMATION 1
  111. #define WMI_SERIAL_PORT_HW_INFORMATION 2
  112. #define WMI_SERIAL_PORT_PERF_INFORMATION 3
  113. #define WMI_SERIAL_PORT_PROPERTIES 4
  114. GUID StdSerialPortNameGuid = SERIAL_PORT_WMI_NAME_GUID; // Standard Serial WMI
  115. GUID StdSerialPortCommGuid = SERIAL_PORT_WMI_COMM_GUID; // Standard Serial WMI
  116. GUID StdSerialPortHWGuid = SERIAL_PORT_WMI_HW_GUID; // Standard Serial WMI
  117. GUID StdSerialPortPerfGuid = SERIAL_PORT_WMI_PERF_GUID; // Standard Serial WMI
  118. GUID StdSerialPortPropertiesGuid = SERIAL_PORT_WMI_PROPERTIES_GUID; // Standard Serial WMI
  119. WMIGUIDREGINFO SpxPort_WmiGuidList[] =
  120. {
  121. { &StdSerialPortNameGuid, 1, 0 },
  122. { &StdSerialPortCommGuid, 1, 0 },
  123. { &StdSerialPortHWGuid, 1, 0 },
  124. { &StdSerialPortPerfGuid, 1, 0 },
  125. { &StdSerialPortPropertiesGuid, 1, 0}
  126. };
  127. #define SpxPort_WmiGuidCount (sizeof(SpxPort_WmiGuidList) / sizeof(WMIGUIDREGINFO))
  128. NTSTATUS
  129. SpxPort_WmiInitializeWmilibContext(IN PWMILIB_CONTEXT WmilibContext)
  130. /*++
  131. Routine Description:
  132. This routine will initialize the wmilib context structure with the
  133. guid list and the pointers to the wmilib callback functions. This routine
  134. should be called before calling IoWmiRegistrationControl to register
  135. your device object.
  136. Arguments:
  137. WmilibContext is pointer to the wmilib context.
  138. Return Value:
  139. status
  140. --*/
  141. {
  142. PAGED_CODE();
  143. RtlZeroMemory(WmilibContext, sizeof(WMILIB_CONTEXT));
  144. WmilibContext->GuidCount = SpxPort_WmiGuidCount;
  145. WmilibContext->GuidList = SpxPort_WmiGuidList;
  146. WmilibContext->QueryWmiRegInfo = SpxPort_WmiQueryRegInfo;
  147. WmilibContext->QueryWmiDataBlock = SpxPort_WmiQueryDataBlock;
  148. WmilibContext->SetWmiDataBlock = SpxPort_WmiSetDataBlock;
  149. WmilibContext->SetWmiDataItem = SpxPort_WmiSetDataItem;
  150. WmilibContext->ExecuteWmiMethod = NULL;
  151. WmilibContext->WmiFunctionControl = NULL;
  152. return(STATUS_SUCCESS);
  153. }
  154. //
  155. // WMI System Call back functions
  156. //
  157. NTSTATUS
  158. SpxPort_WmiQueryRegInfo(IN PDEVICE_OBJECT pDevObject, OUT PULONG pRegFlags,
  159. OUT PUNICODE_STRING pInstanceName,
  160. OUT PUNICODE_STRING *pRegistryPath,
  161. OUT PUNICODE_STRING MofResourceName,
  162. OUT PDEVICE_OBJECT *pPdo)
  163. {
  164. NTSTATUS status = STATUS_SUCCESS;
  165. PPORT_DEVICE_EXTENSION pPort = (PPORT_DEVICE_EXTENSION)pDevObject->DeviceExtension;
  166. PAGED_CODE();
  167. *pRegFlags = WMIREG_FLAG_INSTANCE_PDO;
  168. *pRegistryPath = &SavedRegistryPath;
  169. *pPdo = pDevObject; // Port device object is a PDO.
  170. return(status);
  171. }
  172. NTSTATUS
  173. SpxPort_WmiQueryDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  174. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  175. IN ULONG InstanceCount, IN OUT PULONG pInstanceLengthArray,
  176. IN ULONG OutBufferSize, OUT PUCHAR pBuffer)
  177. {
  178. PPORT_DEVICE_EXTENSION pPort = (PPORT_DEVICE_EXTENSION)pDevObject->DeviceExtension;
  179. NTSTATUS status;
  180. ULONG size = 0;
  181. PAGED_CODE();
  182. switch(GuidIndex)
  183. {
  184. case WMI_SERIAL_PORT_NAME_INFORMATION:
  185. {
  186. size = pPort->DosName.Length;
  187. if(OutBufferSize < (size + sizeof(USHORT)))
  188. {
  189. size += sizeof(USHORT);
  190. status = STATUS_BUFFER_TOO_SMALL;
  191. break;
  192. }
  193. if(pPort->DosName.Buffer == NULL)
  194. {
  195. status = STATUS_INSUFFICIENT_RESOURCES;
  196. break;
  197. }
  198. // First, copy the string over containing our identifier
  199. *(USHORT *)pBuffer = (USHORT)size;
  200. (UCHAR *)pBuffer += sizeof(USHORT);
  201. RtlCopyMemory(pBuffer, pPort->DosName.Buffer, size);
  202. // Increment total size to include the WORD containing our len
  203. size += sizeof(USHORT);
  204. *pInstanceLengthArray = size;
  205. status = STATUS_SUCCESS;
  206. break;
  207. }
  208. case WMI_SERIAL_PORT_COMM_INFORMATION:
  209. {
  210. size = sizeof(SERIAL_WMI_COMM_DATA);
  211. if(OutBufferSize < size)
  212. {
  213. status = STATUS_BUFFER_TOO_SMALL;
  214. break;
  215. }
  216. *pInstanceLengthArray = size;
  217. *(PSERIAL_WMI_COMM_DATA)pBuffer = pPort->WmiCommData;
  218. status = STATUS_SUCCESS;
  219. break;
  220. }
  221. case WMI_SERIAL_PORT_HW_INFORMATION:
  222. {
  223. size = sizeof(SERIAL_WMI_HW_DATA);
  224. if(OutBufferSize < size)
  225. {
  226. status = STATUS_BUFFER_TOO_SMALL;
  227. break;
  228. }
  229. *pInstanceLengthArray = size;
  230. *(PSERIAL_WMI_HW_DATA)pBuffer = pPort->WmiHwData;
  231. status = STATUS_SUCCESS;
  232. break;
  233. }
  234. case WMI_SERIAL_PORT_PERF_INFORMATION:
  235. {
  236. size = sizeof(SERIAL_WMI_PERF_DATA);
  237. if(OutBufferSize < size)
  238. {
  239. status = STATUS_BUFFER_TOO_SMALL;
  240. break;
  241. }
  242. *pInstanceLengthArray = size;
  243. *(PSERIAL_WMI_PERF_DATA)pBuffer = pPort->WmiPerfData;
  244. status = STATUS_SUCCESS;
  245. break;
  246. }
  247. case WMI_SERIAL_PORT_PROPERTIES:
  248. {
  249. size = sizeof(SERIAL_COMMPROP) + sizeof(ULONG);
  250. if(OutBufferSize < size)
  251. {
  252. status = STATUS_BUFFER_TOO_SMALL;
  253. break;
  254. }
  255. *pInstanceLengthArray = size;
  256. SerialGetProperties(pPort, (PSERIAL_COMMPROP)pBuffer);
  257. *((PULONG)(((PSERIAL_COMMPROP)pBuffer)->ProvChar)) = 0;
  258. status = STATUS_SUCCESS;
  259. break;
  260. }
  261. default:
  262. status = STATUS_WMI_GUID_NOT_FOUND;
  263. break;
  264. }
  265. status = WmiCompleteRequest(pDevObject, pIrp, status, size, IO_NO_INCREMENT);
  266. return(status);
  267. }
  268. NTSTATUS
  269. SpxPort_WmiSetDataBlock(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  270. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  271. IN ULONG BufferSize, IN PUCHAR pBuffer)
  272. {
  273. PPORT_DEVICE_EXTENSION pPort = (PPORT_DEVICE_EXTENSION)pDevObject->DeviceExtension;
  274. NTSTATUS status;
  275. ULONG size = 0;
  276. PAGED_CODE();
  277. switch(GuidIndex)
  278. {
  279. case WMI_SERIAL_PORT_NAME_INFORMATION:
  280. case WMI_SERIAL_PORT_COMM_INFORMATION:
  281. case WMI_SERIAL_PORT_HW_INFORMATION:
  282. case WMI_SERIAL_PORT_PERF_INFORMATION:
  283. case WMI_SERIAL_PORT_PROPERTIES:
  284. status = STATUS_WMI_READ_ONLY;
  285. break;
  286. default:
  287. status = STATUS_WMI_GUID_NOT_FOUND;
  288. break;
  289. }
  290. status = WmiCompleteRequest(pDevObject, pIrp, status, size, IO_NO_INCREMENT);
  291. return(status);
  292. }
  293. NTSTATUS
  294. SpxPort_WmiSetDataItem(IN PDEVICE_OBJECT pDevObject, IN PIRP pIrp,
  295. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  296. IN ULONG DataItemId, IN ULONG BufferSize,
  297. IN PUCHAR pBuffer)
  298. {
  299. PPORT_DEVICE_EXTENSION pPort = (PPORT_DEVICE_EXTENSION)pDevObject->DeviceExtension;
  300. NTSTATUS status;
  301. ULONG size = 0;
  302. PAGED_CODE();
  303. switch(GuidIndex)
  304. {
  305. case WMI_SERIAL_PORT_NAME_INFORMATION:
  306. case WMI_SERIAL_PORT_COMM_INFORMATION:
  307. case WMI_SERIAL_PORT_HW_INFORMATION:
  308. case WMI_SERIAL_PORT_PERF_INFORMATION:
  309. case WMI_SERIAL_PORT_PROPERTIES:
  310. status = STATUS_WMI_READ_ONLY;
  311. break;
  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. }