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.

463 lines
15 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation All Rights Reserved
  3. Module Name:
  4. wmi.c
  5. Abstract:
  6. This module controls access to the simulated configuration space
  7. of the SHPC.
  8. Config access is controlled in the following manner in this simulator:
  9. We assume that this simulator will be loaded on a bridge enumerated by
  10. the SoftPCI simulator. SoftPCI keeps an internal representation of the
  11. config space of the devices it controls. The function of this simulator,
  12. then, is to manage the SHPC register set and perform commands associated
  13. with writing the SHPC config space. However, the representation of config
  14. space is kept internal to SoftPCI.
  15. Environment:
  16. Kernel Mode
  17. Revision History:
  18. Davis Walker (dwalker) Sept 8 2000
  19. --*/
  20. // 625 comments on how this crap works.
  21. #include "hpsp.h"
  22. NTSTATUS
  23. HpsWmiRegInfo(
  24. IN PDEVICE_OBJECT DeviceObject,
  25. OUT PULONG RegFlags,
  26. OUT PUNICODE_STRING InstanceName,
  27. OUT PUNICODE_STRING *RegistryPath,
  28. OUT PUNICODE_STRING MofResourceName,
  29. OUT PDEVICE_OBJECT *Pdo
  30. )
  31. {
  32. PHPS_DEVICE_EXTENSION deviceExtension = (PHPS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
  33. *RegistryPath = &HpsRegistryPath;
  34. // 625 need to set unused parameters to null?
  35. *RegFlags = WMIREG_FLAG_INSTANCE_PDO;
  36. *Pdo = deviceExtension->PhysicalDO;
  37. return STATUS_SUCCESS;
  38. }
  39. NTSTATUS
  40. HpsWmiQueryDataBlock(
  41. IN PDEVICE_OBJECT DeviceObject,
  42. IN PIRP Irp,
  43. IN ULONG GuidIndex,
  44. IN ULONG InstanceIndex,
  45. IN ULONG InstanceCount,
  46. IN OUT PULONG InstanceLengthArray,
  47. IN ULONG BufferAvail,
  48. OUT PUCHAR Buffer
  49. )
  50. {
  51. NTSTATUS status;
  52. ULONG sizeNeeded = 0;
  53. PHPS_DEVICE_EXTENSION extension = (PHPS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
  54. PHPS_HWINIT_DESCRIPTOR hwInit;
  55. ASSERT(InstanceIndex == 0);
  56. ASSERT(InstanceCount == 1);
  57. if ((InstanceIndex !=0) ||
  58. (InstanceCount != 1)) {
  59. status = STATUS_WMI_INSTANCE_NOT_FOUND;
  60. } else {
  61. switch (GuidIndex) {
  62. case HPS_SLOT_METHOD_GUID_INDEX:
  63. //
  64. // Method classes do not have any data within them, but must
  65. // repond successfully to queries so that WMI method operation
  66. // work successfully.
  67. //
  68. sizeNeeded = sizeof(USHORT);
  69. if (BufferAvail < sizeof(USHORT)) {
  70. status = STATUS_BUFFER_TOO_SMALL;
  71. } else {
  72. *InstanceLengthArray = sizeof(USHORT);
  73. status = STATUS_SUCCESS;
  74. }
  75. break;
  76. case HPS_EVENT_CONTEXT_GUID_INDEX: // 625 comment sync or lack thereof for data blocks
  77. sizeNeeded = extension->WmiEventContextSize;
  78. if (BufferAvail < extension->WmiEventContextSize) {
  79. status = STATUS_BUFFER_TOO_SMALL;
  80. } else {
  81. *InstanceLengthArray = extension->WmiEventContextSize;
  82. RtlCopyMemory(Buffer, extension->WmiEventContext, extension->WmiEventContextSize);
  83. status = STATUS_SUCCESS;
  84. }
  85. break;
  86. case HPS_INIT_DATA_GUID_INDEX:
  87. sizeNeeded = sizeof(HPS_HWINIT_DESCRIPTOR);
  88. if (BufferAvail < sizeof(HPS_HWINIT_DESCRIPTOR)) {
  89. status = STATUS_BUFFER_TOO_SMALL;
  90. } else {
  91. *InstanceLengthArray = sizeof(HPS_HWINIT_DESCRIPTOR);
  92. RtlCopyMemory(Buffer, &extension->HwInitData, sizeof(HPS_HWINIT_DESCRIPTOR));
  93. status = STATUS_SUCCESS;
  94. }
  95. break;
  96. default:
  97. status = STATUS_WMI_GUID_NOT_FOUND;
  98. break;
  99. }
  100. }
  101. return WmiCompleteRequest(DeviceObject,
  102. Irp,
  103. status,
  104. sizeNeeded,
  105. IO_NO_INCREMENT
  106. );
  107. }
  108. NTSTATUS
  109. HpsWmiSetDataBlock(
  110. IN PDEVICE_OBJECT DeviceObject,
  111. IN PIRP Irp,
  112. IN ULONG GuidIndex,
  113. IN ULONG InstanceIndex,
  114. IN ULONG BufferSize,
  115. IN PUCHAR Buffer
  116. )
  117. {
  118. NTSTATUS status;
  119. PHPS_DEVICE_EXTENSION extension = (PHPS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
  120. ASSERT(InstanceIndex == 0);
  121. if (InstanceIndex !=0) {
  122. status = STATUS_WMI_INSTANCE_NOT_FOUND;
  123. } else if (GuidIndex == HPS_EVENT_CONTEXT_GUID_INDEX) {
  124. if (BufferSize == 0) { // 625 sync comment from above
  125. extension->WmiEventContextSize = 0;
  126. if (extension->WmiEventContext) {
  127. ExFreePool(extension->WmiEventContext);
  128. extension->WmiEventContext = NULL;
  129. }
  130. goto cleanup;
  131. }
  132. if (BufferSize > extension->WmiEventContextSize) {
  133. //
  134. // We need to allocate a bigger buffer.
  135. //
  136. if (extension->WmiEventContext) {
  137. ExFreePool(extension->WmiEventContext);
  138. }
  139. extension->WmiEventContext = ExAllocatePool(NonPagedPool,
  140. BufferSize
  141. );
  142. if (!extension->WmiEventContext) {
  143. extension->WmiEventContextSize = 0;
  144. status = STATUS_INSUFFICIENT_RESOURCES;
  145. goto cleanup;
  146. }
  147. }
  148. //
  149. // Copy the context
  150. //
  151. extension->WmiEventContextSize = BufferSize;
  152. RtlCopyMemory(extension->WmiEventContext, Buffer, extension->WmiEventContextSize);
  153. status = STATUS_SUCCESS;
  154. } else {
  155. status = STATUS_WMI_GUID_NOT_FOUND;
  156. }
  157. cleanup:
  158. return WmiCompleteRequest(DeviceObject,
  159. Irp,
  160. status,
  161. 0,
  162. IO_NO_INCREMENT
  163. );
  164. }
  165. NTSTATUS
  166. HpsWmiExecuteMethod(
  167. IN PDEVICE_OBJECT DeviceObject,
  168. IN PIRP Irp,
  169. IN ULONG GuidIndex,
  170. IN ULONG InstanceIndex,
  171. IN ULONG MethodId,
  172. IN ULONG InBufferSize,
  173. IN ULONG OutBufferSize,
  174. IN OUT PUCHAR Buffer
  175. )
  176. {
  177. PHPS_DEVICE_EXTENSION extension = (PHPS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
  178. NTSTATUS status;
  179. ULONG sizeNeeded = 0;
  180. PSOFTPCI_DEVICE softDevice;
  181. ULONG slotNum;
  182. PHPS_SLOT_EVENT event;
  183. if (GuidIndex == HPS_SLOT_METHOD_GUID_INDEX) {
  184. switch (MethodId) {
  185. case SlotMethod:
  186. if (InBufferSize < sizeof(HPS_SLOT_EVENT)) {
  187. status = STATUS_BUFFER_TOO_SMALL;
  188. } else {
  189. event = (PHPS_SLOT_EVENT)Buffer;
  190. DbgPrintEx(DPFLTR_HPS_ID,
  191. HPS_WMI_LEVEL,
  192. "HPS-Handle Slot Event at slot %d Type=%d\n",
  193. event->SlotNum,
  194. event->EventType
  195. );
  196. HpsHandleSlotEvent(extension,
  197. (PHPS_SLOT_EVENT)Buffer
  198. );
  199. status = STATUS_SUCCESS;
  200. }
  201. sizeNeeded = sizeof(HPS_SLOT_EVENT);
  202. break;
  203. case AddDeviceMethod:
  204. if (InBufferSize < sizeof(SOFTPCI_DEVICE)) {
  205. status = STATUS_BUFFER_TOO_SMALL;
  206. } else {
  207. softDevice = (PSOFTPCI_DEVICE)Buffer;
  208. //
  209. // SlotNum is the 0 indexed slot number of the slot a device is
  210. // being added to.
  211. //
  212. slotNum = softDevice->Slot.Device - extension->HwInitData.FirstDeviceID;
  213. if (slotNum < extension->HwInitData.NumSlots) {
  214. if (extension->SoftDevices[slotNum]) {
  215. ExFreePool(extension->SoftDevices[slotNum]);
  216. }
  217. extension->SoftDevices[slotNum] = ExAllocatePool(PagedPool, sizeof(SOFTPCI_DEVICE));
  218. if (!extension->SoftDevices[slotNum]) {
  219. status = STATUS_INSUFFICIENT_RESOURCES;
  220. } else {
  221. RtlCopyMemory(extension->SoftDevices[slotNum],softDevice,sizeof(SOFTPCI_DEVICE));
  222. //
  223. // Finally mark the device as present in the register set.
  224. //
  225. extension->RegisterSet.WorkingRegisters.SlotRegisters[slotNum].SlotStatus.PrsntState = SHPC_PRSNT_7_5_WATTS;
  226. status = STATUS_SUCCESS;
  227. }
  228. } else {
  229. ASSERT(FALSE);
  230. status = STATUS_INVALID_PARAMETER;
  231. }
  232. DbgPrintEx(DPFLTR_HPS_ID,
  233. HPS_WMI_LEVEL,
  234. "HPS-Add Device at Slot %d - Status=0x%x\n",
  235. slotNum,
  236. status
  237. );
  238. }
  239. sizeNeeded = sizeof(SOFTPCI_DEVICE);
  240. break;
  241. case RemoveDeviceMethod:
  242. if (InBufferSize < sizeof(UCHAR)) {
  243. status = STATUS_BUFFER_TOO_SMALL;
  244. } else {
  245. //
  246. // SlotNum is the 0 indexed slot number of the slot a device is
  247. // being added to.
  248. //
  249. slotNum = *(PUCHAR)Buffer;
  250. if (slotNum < extension->HwInitData.NumSlots) {
  251. if (extension->SoftDevices[slotNum]) {
  252. ExFreePool(extension->SoftDevices[slotNum]);
  253. extension->SoftDevices[slotNum] = NULL;
  254. }
  255. extension->RegisterSet.WorkingRegisters.SlotRegisters[slotNum].SlotStatus.PrsntState = SHPC_PRSNT_EMPTY;
  256. status = STATUS_SUCCESS;
  257. } else {
  258. ASSERT(FALSE);
  259. status = STATUS_INVALID_PARAMETER;
  260. }
  261. DbgPrintEx(DPFLTR_HPS_ID,
  262. HPS_WMI_LEVEL,
  263. "HPS-Remove Device at Slot %d=0x%x Status=0x%x\n",
  264. slotNum,
  265. extension->SoftDevices[slotNum],
  266. status
  267. );
  268. }
  269. sizeNeeded = sizeof(UCHAR);
  270. break;
  271. case GetDeviceMethod:
  272. if ((InBufferSize < sizeof(UCHAR)) ||
  273. (OutBufferSize < sizeof(SOFTPCI_DEVICE))) {
  274. status = STATUS_BUFFER_TOO_SMALL;
  275. } else {
  276. //
  277. // SlotNum is the 0 indexed slot number of the slot a device is
  278. // being added to.
  279. //
  280. slotNum = *(PUCHAR)Buffer;
  281. if (slotNum < extension->HwInitData.NumSlots) {
  282. if (extension->SoftDevices[slotNum]) {
  283. RtlCopyMemory(Buffer,
  284. extension->SoftDevices[slotNum],
  285. sizeof(SOFTPCI_DEVICE)
  286. );
  287. status = STATUS_SUCCESS;
  288. } else {
  289. status = STATUS_NO_SUCH_DEVICE;
  290. }
  291. } else {
  292. ASSERT(FALSE);
  293. status = STATUS_INVALID_PARAMETER;
  294. }
  295. DbgPrintEx(DPFLTR_HPS_ID,
  296. HPS_WMI_LEVEL,
  297. "HPS-Get Device at Slot %d=0x%x Status=0x%x\n",
  298. slotNum,
  299. extension->SoftDevices[slotNum],
  300. status
  301. );
  302. }
  303. sizeNeeded = sizeof(SOFTPCI_DEVICE);
  304. break;
  305. case GetSlotStatusMethod:
  306. if ((InBufferSize < sizeof(UCHAR)) ||
  307. (OutBufferSize < sizeof(SHPC_SLOT_STATUS_REGISTER))){
  308. status = STATUS_BUFFER_TOO_SMALL;
  309. } else {
  310. //
  311. // SlotNum is the 0 indexed slot number of the slot a device is
  312. // being added to.
  313. //
  314. slotNum = *(PUCHAR)Buffer;
  315. if (slotNum < extension->HwInitData.NumSlots) {
  316. RtlCopyMemory(Buffer,
  317. &extension->RegisterSet.WorkingRegisters.SlotRegisters[slotNum].SlotStatus,
  318. sizeof(SHPC_SLOT_STATUS_REGISTER)
  319. );
  320. status = STATUS_SUCCESS;
  321. } else {
  322. ASSERT(FALSE);
  323. status = STATUS_INVALID_PARAMETER;
  324. }
  325. }
  326. sizeNeeded = sizeof(SHPC_SLOT_STATUS_REGISTER);
  327. break;
  328. case CommandCompleteMethod:
  329. DbgPrintEx(DPFLTR_HPS_ID,
  330. HPS_WMI_LEVEL,
  331. "HPS-Command Completed\n"
  332. );
  333. HpsCommandCompleted(extension);
  334. status = STATUS_SUCCESS;
  335. break;
  336. default:
  337. status = STATUS_WMI_ITEMID_NOT_FOUND;
  338. DbgPrintEx(DPFLTR_HPS_ID,
  339. HPS_WMI_LEVEL,
  340. "HPS-Method ID not found: %d\n",
  341. MethodId
  342. );
  343. break;
  344. }
  345. } else {
  346. DbgPrintEx(DPFLTR_HPS_ID,
  347. HPS_WMI_LEVEL,
  348. "HPS-Guid ID not found: %d\n",
  349. GuidIndex
  350. );
  351. status = STATUS_WMI_GUID_NOT_FOUND;
  352. }
  353. return WmiCompleteRequest(DeviceObject,
  354. Irp,
  355. status,
  356. sizeNeeded,
  357. IO_NO_INCREMENT
  358. );
  359. }
  360. NTSTATUS
  361. HpsWmiFunctionControl(
  362. IN PDEVICE_OBJECT DeviceObject,
  363. IN PIRP Irp,
  364. IN ULONG GuidIndex,
  365. IN WMIENABLEDISABLECONTROL Function,
  366. IN BOOLEAN Enable
  367. )
  368. {
  369. PHPS_DEVICE_EXTENSION deviceExtension = (PHPS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
  370. if (Function == WmiEventControl) {
  371. deviceExtension->EventsEnabled = Enable;
  372. }
  373. return WmiCompleteRequest(DeviceObject,
  374. Irp,
  375. STATUS_SUCCESS,
  376. 0,
  377. IO_NO_INCREMENT
  378. );
  379. }