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.

474 lines
11 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. WmiLog.c
  5. Abstract:
  6. This module contains Wmi loging support.
  7. Author:
  8. Hanumant Yadav (hanumany) 18-Dec-2000
  9. Revision History:
  10. --*/
  11. #include "pch.h"
  12. #include <evntrace.h>
  13. #ifdef WMI_TRACING
  14. //
  15. //Globals
  16. //
  17. GUID GUID_List[] =
  18. {
  19. {0xF2E0E060L, 0xBF32, 0x4B88, 0xB8, 0xE4, 0x5C, 0xAD, 0x15, 0xAF, 0x6A, 0xE9} /* AMLI log GUID */
  20. /* Add new logging GUIDS here */
  21. };
  22. ULONG ACPIWmiTraceEnable = 0;
  23. ULONG ACPIWmiTraceGlobalEnable = 0;
  24. TRACEHANDLE ACPIWmiLoggerHandle = 0;
  25. // End Globals
  26. VOID
  27. ACPIWmiInitLog(
  28. IN PDEVICE_OBJECT ACPIDeviceObject
  29. )
  30. /*++
  31. Routine Description:
  32. This is a initialization function in which we call IoWMIRegistrationControl
  33. to register for WMI loging.
  34. Arguments:
  35. ACPIDeviceObject.
  36. Return Value:
  37. None.
  38. --*/
  39. {
  40. NTSTATUS status;
  41. //
  42. // Register with WMI.
  43. //
  44. status = IoWMIRegistrationControl(ACPIDeviceObject,
  45. WMIREG_ACTION_REGISTER);
  46. if (!NT_SUCCESS(status))
  47. {
  48. ACPIPrint( (
  49. DPFLTR_ERROR_LEVEL,
  50. "ACPIWmiInitLog: Failed to register for WMI support\n"
  51. ) );
  52. }
  53. return;
  54. }
  55. VOID
  56. ACPIWmiUnRegisterLog(
  57. IN PDEVICE_OBJECT ACPIDeviceObject
  58. )
  59. /*++
  60. Routine Description:
  61. This is a unregistration function in which we call IoWMIRegistrationControl
  62. to unregister for WMI loging.
  63. Arguments:
  64. ACPIDeviceObject.
  65. Return Value:
  66. None.
  67. --*/
  68. {
  69. NTSTATUS status;
  70. //
  71. // Register with WMI.
  72. //
  73. status = IoWMIRegistrationControl(ACPIDeviceObject,
  74. WMIREG_ACTION_DEREGISTER);
  75. if (!NT_SUCCESS(status))
  76. {
  77. ACPIPrint( (
  78. DPFLTR_ERROR_LEVEL,
  79. "ACPIWmiInitLog: Failed to unregister for WMI support\n"
  80. ) );
  81. }
  82. return;
  83. }
  84. NTSTATUS
  85. ACPIWmiRegisterGuids(
  86. IN PWMIREGINFO WmiRegInfo,
  87. IN ULONG wmiRegInfoSize,
  88. IN PULONG pReturnSize
  89. )
  90. /*++
  91. Routine Description:
  92. This function handles WMI GUID registration goo.
  93. Arguments:
  94. WmiRegInfo,
  95. wmiRegInfoSize,
  96. pReturnSize
  97. Return Value:
  98. STATUS_SUCCESS on success.
  99. --*/
  100. {
  101. //
  102. // Register a Control Guid as a Trace Guid.
  103. //
  104. ULONG SizeNeeded;
  105. PWMIREGGUIDW WmiRegGuidPtr;
  106. ULONG Status;
  107. ULONG GuidCount;
  108. LPGUID ControlGuid;
  109. ULONG RegistryPathSize;
  110. ULONG MofResourceSize;
  111. PUCHAR ptmp;
  112. GUID ACPITraceGuid = {0xDAB01D4DL, 0x2D48, 0x477D, 0xB1, 0xC3, 0xDA, 0xAD, 0x0C, 0xE6, 0xF0, 0x6B};
  113. *pReturnSize = 0;
  114. GuidCount = 1;
  115. ControlGuid = &ACPITraceGuid;
  116. //
  117. // Allocate WMIREGINFO for controlGuid + GuidCount.
  118. //
  119. RegistryPathSize = sizeof(ACPI_REGISTRY_KEY) - sizeof(WCHAR) + sizeof(USHORT);
  120. MofResourceSize = sizeof(ACPI_TRACE_MOF_FILE) - sizeof(WCHAR) + sizeof(USHORT);
  121. SizeNeeded = sizeof(WMIREGINFOW) + GuidCount * sizeof(WMIREGGUIDW) +
  122. RegistryPathSize +
  123. MofResourceSize;
  124. if (SizeNeeded > wmiRegInfoSize) {
  125. *((PULONG)WmiRegInfo) = SizeNeeded;
  126. *pReturnSize = sizeof(ULONG);
  127. return STATUS_SUCCESS;
  128. }
  129. RtlZeroMemory(WmiRegInfo, SizeNeeded);
  130. WmiRegInfo->BufferSize = SizeNeeded;
  131. WmiRegInfo->GuidCount = GuidCount;
  132. WmiRegInfo->RegistryPath = sizeof(WMIREGINFOW) + GuidCount * sizeof(WMIREGGUIDW);
  133. WmiRegInfo->MofResourceName = WmiRegInfo->RegistryPath + RegistryPathSize; //ACPI_TRACE_MOF_FILE;
  134. WmiRegGuidPtr = &WmiRegInfo->WmiRegGuid[0];
  135. WmiRegGuidPtr->Guid = *ControlGuid;
  136. WmiRegGuidPtr->Flags |= WMIREG_FLAG_TRACED_GUID;
  137. WmiRegGuidPtr->Flags |= WMIREG_FLAG_TRACE_CONTROL_GUID;
  138. WmiRegGuidPtr->InstanceCount = 0;
  139. WmiRegGuidPtr->InstanceInfo = 0;
  140. ptmp = (PUCHAR)&WmiRegInfo->WmiRegGuid[1];
  141. *((PUSHORT)ptmp) = sizeof(ACPI_REGISTRY_KEY) - sizeof(WCHAR);
  142. ptmp += sizeof(USHORT);
  143. RtlCopyMemory(ptmp, ACPI_REGISTRY_KEY, sizeof(ACPI_REGISTRY_KEY) - sizeof(WCHAR));
  144. ptmp = (PUCHAR)WmiRegInfo + WmiRegInfo->MofResourceName;
  145. *((PUSHORT)ptmp) = sizeof(ACPI_TRACE_MOF_FILE) - sizeof(WCHAR);
  146. ptmp += sizeof(USHORT);
  147. RtlCopyMemory(ptmp, ACPI_TRACE_MOF_FILE, sizeof(ACPI_TRACE_MOF_FILE) - sizeof(WCHAR));
  148. *pReturnSize = SizeNeeded;
  149. return(STATUS_SUCCESS);
  150. }
  151. VOID
  152. ACPIGetWmiLogGlobalHandle(
  153. VOID
  154. )
  155. /*++
  156. Routine Description:
  157. This function gets the global wmi logging handle. We need this to log
  158. at boot time, before we start getting wmi messages.
  159. Arguments:
  160. None.
  161. Return Value:
  162. None.
  163. --*/
  164. {
  165. WmiSetLoggerId(WMI_GLOBAL_LOGGER_ID, &ACPIWmiLoggerHandle);
  166. if(ACPIWmiLoggerHandle)
  167. {
  168. ACPIPrint( (
  169. DPFLTR_INFO_LEVEL,
  170. "ACPIGetWmiLogGlobalHandle: Global handle aquired. Handle = %I64u\n",
  171. ACPIWmiLoggerHandle
  172. ) );
  173. ACPIWmiTraceGlobalEnable = 1;
  174. }
  175. return;
  176. }
  177. NTSTATUS
  178. ACPIWmiEnableLog(
  179. IN PVOID Buffer,
  180. IN ULONG BufferSize
  181. )
  182. /*++
  183. Routine Description:
  184. This function is the handler for IRP_MN_ENABLE_EVENTS.
  185. Arguments:
  186. Buffer,
  187. BufferSize
  188. Return Value:
  189. NTSTATUS
  190. --*/
  191. {
  192. PWNODE_HEADER Wnode=NULL;
  193. InterlockedExchange(&ACPIWmiTraceEnable, 1);
  194. Wnode = (PWNODE_HEADER)Buffer;
  195. if (BufferSize >= sizeof(WNODE_HEADER)) {
  196. ACPIWmiLoggerHandle = Wnode->HistoricalContext;
  197. //
  198. // reset the global logger if it is active.
  199. //
  200. if(ACPIWmiTraceGlobalEnable)
  201. ACPIWmiTraceGlobalEnable = 0;
  202. ACPIPrint( (
  203. DPFLTR_INFO_LEVEL,
  204. "ACPIWmiEnableLog: LoggerHandle = %I64u. BufferSize = %d. Flags = %x. Version = %x\n",
  205. ACPIWmiLoggerHandle,
  206. Wnode->BufferSize,
  207. Wnode->Flags,
  208. Wnode->Version
  209. ) );
  210. }
  211. return(STATUS_SUCCESS);
  212. }
  213. NTSTATUS
  214. ACPIWmiDisableLog(
  215. VOID
  216. )
  217. /*++
  218. Routine Description:
  219. This function is the handler for IRP_MN_DISABLE_EVENTS.
  220. Arguments:
  221. None.
  222. Return Value:
  223. NTSTATUS
  224. --*/
  225. {
  226. InterlockedExchange(&ACPIWmiTraceEnable, 0);
  227. ACPIWmiLoggerHandle = 0;
  228. return(STATUS_SUCCESS);
  229. }
  230. NTSTATUS
  231. ACPIWmiLogEvent(
  232. IN UCHAR LogLevel,
  233. IN UCHAR LogType,
  234. IN GUID LogGUID,
  235. IN PUCHAR Format,
  236. IN ...
  237. )
  238. /*++
  239. Routine Description:
  240. This is the main wmi logging funcion. This function should be used
  241. throughtout the ACPI driver where WMI logging is required.
  242. Arguments:
  243. LogLevel,
  244. LogType,
  245. LogGUID,
  246. Format,
  247. ...
  248. Return Value:
  249. NTSTATUS
  250. --*/
  251. {
  252. static char Buffer[1024];
  253. va_list marker;
  254. WMI_LOG_DATA Wmi_log_data ={0,0};
  255. EVENT_TRACE_HEADER *Wnode;
  256. NTSTATUS status = STATUS_UNSUCCESSFUL;
  257. va_start(marker, Format);
  258. vsprintf(Buffer, Format, marker);
  259. va_end(marker);
  260. if(ACPIWmiTraceEnable || ACPIWmiTraceGlobalEnable)
  261. {
  262. if(ACPIWmiLoggerHandle)
  263. {
  264. Wmi_log_data.Data.DataPtr = (ULONG64)&Buffer;
  265. Wmi_log_data.Data.Length = strlen(Buffer) + 1;
  266. Wmi_log_data.Header.Size = sizeof(WMI_LOG_DATA);
  267. Wmi_log_data.Header.Flags = WNODE_FLAG_TRACED_GUID | WNODE_FLAG_USE_MOF_PTR;
  268. Wmi_log_data.Header.Class.Type = LogType;
  269. Wmi_log_data.Header.Class.Level = LogLevel;
  270. Wmi_log_data.Header.Guid = LogGUID;
  271. Wnode = &Wmi_log_data.Header;
  272. ((PWNODE_HEADER)Wnode)->HistoricalContext = ACPIWmiLoggerHandle;
  273. //
  274. // Call TraceLogger to write this event
  275. //
  276. status = IoWMIWriteEvent((PVOID)&(Wmi_log_data.Header));
  277. //
  278. // if IoWMIWriteEvent fails and we are using the global logger handle,
  279. // we need to stop loging.
  280. //
  281. if(status != STATUS_SUCCESS)
  282. {
  283. if(ACPIWmiTraceGlobalEnable)
  284. {
  285. ACPIWmiLoggerHandle = 0;
  286. ACPIWmiTraceGlobalEnable = 0;
  287. ACPIPrint( (
  288. ACPI_PRINT_INFO,
  289. "ACPIWmiLogEvent: Disabling WMI loging using global handle. status = %x\n",
  290. status
  291. ) );
  292. }
  293. else
  294. {
  295. ACPIPrint( (
  296. DPFLTR_ERROR_LEVEL,
  297. "ACPIWmiLogEvent: Failed to log. status = %x\n",
  298. status
  299. ) );
  300. }
  301. }
  302. }
  303. }
  304. return status;
  305. }
  306. NTSTATUS
  307. ACPIDispatchWmiLog(
  308. IN PDEVICE_OBJECT DeviceObject,
  309. IN PIRP Irp
  310. )
  311. {
  312. NTSTATUS status;
  313. PIO_STACK_LOCATION irpSp;
  314. UCHAR minorFunction;
  315. irpSp = IoGetCurrentIrpStackLocation(Irp);
  316. //
  317. // Get the dispatch table that we will be using and the minor code as well,
  318. // so that we can look it when required
  319. //
  320. ASSERT(RootDeviceExtension->DeviceObject == DeviceObject);
  321. if (DeviceObject != (PDEVICE_OBJECT) irpSp->Parameters.WMI.ProviderId) {
  322. return ACPIDispatchForwardIrp(DeviceObject, Irp);
  323. }
  324. minorFunction = irpSp->MinorFunction;
  325. switch(minorFunction){
  326. case IRP_MN_REGINFO:{
  327. ULONG ReturnSize = 0;
  328. ULONG BufferSize = irpSp->Parameters.WMI.BufferSize;
  329. PVOID Buffer = irpSp->Parameters.WMI.Buffer;
  330. status=ACPIWmiRegisterGuids(
  331. Buffer,
  332. BufferSize,
  333. &ReturnSize
  334. );
  335. Irp->IoStatus.Information = ReturnSize;
  336. Irp->IoStatus.Status = status;
  337. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  338. return status;
  339. }
  340. case IRP_MN_ENABLE_EVENTS:{
  341. status=ACPIWmiEnableLog(
  342. irpSp->Parameters.WMI.Buffer,
  343. irpSp->Parameters.WMI.BufferSize
  344. );
  345. Irp->IoStatus.Status = status;
  346. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  347. return status;
  348. }
  349. case IRP_MN_DISABLE_EVENTS:{
  350. status=ACPIWmiDisableLog();
  351. Irp->IoStatus.Status = status;
  352. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  353. return status;
  354. }
  355. default:{
  356. status = ACPIDispatchForwardIrp(DeviceObject, Irp);
  357. return status;
  358. }
  359. }
  360. return status;
  361. }
  362. #endif //WMI_TRACING