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.

308 lines
7.6 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Module: perf.c
  4. //
  5. // Description:
  6. //
  7. //
  8. //@@BEGIN_MSINTERNAL
  9. //
  10. // History: Date Author Comment
  11. // --------------------------------------------------------------
  12. // 12/12/00 ArthurZ Created
  13. //
  14. //@@END_MSINTERNAL
  15. //---------------------------------------------------------------------------
  16. //
  17. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  18. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  19. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  20. // PURPOSE.
  21. //
  22. // Copyright (c) 1995-1999 Microsoft Corporation. All Rights Reserved.
  23. //
  24. //---------------------------------------------------------------------------
  25. #include "private.h"
  26. #include "perf.h"
  27. #define PROC_REG_PATH L"System\\CurrentControlSet\\Services\\Portcls"
  28. GUID ControlGuid =
  29. { 0x28cf047a, 0x2437, 0x4b24, 0xb6, 0x53, 0xb9, 0x44, 0x6a, 0x41, 0x9a, 0x69 };
  30. GUID TraceGuid =
  31. { 0x9d447297, 0xc576, 0x4015, 0x87, 0xb5, 0xa5, 0xa6, 0x98, 0xfd, 0x4d, 0xd1 };
  32. GUID TraceDMAGuid =
  33. { 0xf27b2e65, 0x15f0, 0x4d01, 0xab, 0xe2, 0xf7, 0x68, 0x5d, 0xf6, 0xe5, 0x72 };
  34. ULONG TraceEnable;
  35. TRACEHANDLE LoggerHandle;
  36. typedef struct PERFINFO_AUDIOGLITCH {
  37. ULONGLONG cycleCounter;
  38. ULONG glitchType;
  39. LONGLONG sampleTime;
  40. LONGLONG previousTime;
  41. ULONG_PTR instanceId;
  42. } PERFINFO_AUDIOGLITCH, *PPERFINFO_AUDIOGLITCH;
  43. typedef struct PERFINFO_WMI_AUDIOGLITCH {
  44. EVENT_TRACE_HEADER header;
  45. PERFINFO_AUDIOGLITCH data;
  46. } PERFINFO_WMI_AUDIO_GLITCH, *PPERFINFO_WMI_AUDIOGLITCH;
  47. ///////////////////////////////////////////////////////////////////////////
  48. VOID
  49. PerfRegisterProvider (
  50. IN PDEVICE_OBJECT DeviceObject
  51. )
  52. /*++
  53. Routine Description:
  54. This routine registers this component as a WMI event tracing provider.
  55. --*/
  56. {
  57. IoWMIRegistrationControl (DeviceObject, WMIREG_ACTION_REGISTER);
  58. }
  59. ///////////////////////////////////////////////////////////////////////////
  60. VOID
  61. PerfUnregisterProvider (
  62. IN PDEVICE_OBJECT DeviceObject
  63. )
  64. /*++
  65. Routine Description:
  66. This routine unregisters this component as a WMI event tracing provider.
  67. --*/
  68. {
  69. IoWMIRegistrationControl (DeviceObject, WMIREG_ACTION_DEREGISTER);
  70. }
  71. ///////////////////////////////////////////////////////////////////////////
  72. NTSTATUS
  73. RegisterWmiGuids (
  74. IN PWMIREGINFO WmiRegInfo,
  75. IN ULONG RegInfoSize,
  76. IN PULONG ReturnSize
  77. )
  78. /*++
  79. Routine Description:
  80. This routine registers WMI event tracing streams.
  81. --*/
  82. {
  83. ULONG SizeNeeded;
  84. PWMIREGGUIDW WmiRegGuidPtr;
  85. ULONG status;
  86. ULONG GuidCount;
  87. ULONG RegistryPathSize;
  88. PUCHAR Temp;
  89. if (WmiRegInfo == NULL ||
  90. ReturnSize == NULL ) {
  91. return STATUS_INVALID_PARAMETER;
  92. }
  93. GuidCount = 1;
  94. RegistryPathSize = sizeof (PROC_REG_PATH) - sizeof (WCHAR) + sizeof (USHORT);
  95. SizeNeeded = sizeof (WMIREGINFOW) + GuidCount * sizeof (WMIREGGUIDW) + RegistryPathSize;
  96. if (SizeNeeded > RegInfoSize) {
  97. if ( RegInfoSize >= sizeof(ULONG) ) {
  98. *((PULONG)WmiRegInfo) = SizeNeeded;
  99. *ReturnSize = sizeof (ULONG);
  100. return STATUS_BUFFER_OVERFLOW;
  101. }
  102. else {
  103. *ReturnSize = 0;
  104. return STATUS_BUFFER_TOO_SMALL;
  105. }
  106. }
  107. RtlZeroMemory (WmiRegInfo, SizeNeeded);
  108. WmiRegInfo->BufferSize = SizeNeeded;
  109. WmiRegInfo->GuidCount = GuidCount;
  110. WmiRegGuidPtr = WmiRegInfo->WmiRegGuid;
  111. WmiRegGuidPtr->Guid = ControlGuid;
  112. WmiRegGuidPtr->Flags |= (WMIREG_FLAG_TRACED_GUID | WMIREG_FLAG_TRACE_CONTROL_GUID);
  113. Temp = (PUCHAR)(WmiRegGuidPtr + 1);
  114. WmiRegInfo->RegistryPath = PtrToUlong ((PVOID)(Temp - (PUCHAR)WmiRegInfo));
  115. *((PUSHORT)Temp) = (USHORT)(sizeof (PROC_REG_PATH) - sizeof (WCHAR));
  116. Temp += sizeof (USHORT);
  117. RtlCopyMemory (Temp, PROC_REG_PATH, sizeof (PROC_REG_PATH) - sizeof (WCHAR));
  118. *ReturnSize = SizeNeeded;
  119. return STATUS_SUCCESS;
  120. }
  121. ///////////////////////////////////////////////////////////////////////////
  122. NTSTATUS
  123. PcDispatchSystemControl
  124. (
  125. IN PDEVICE_OBJECT pDeviceObject,
  126. IN PIRP pIrp
  127. );
  128. NTSTATUS
  129. PerfWmiDispatch (
  130. IN PDEVICE_OBJECT DeviceObject,
  131. IN PIRP Irp
  132. )
  133. /*++
  134. Routine Description:
  135. This routine handles IRP_MJ_SYSTEM_CONTROL calls. It processes
  136. WMI requests and passes everything else on to KS.
  137. --*/
  138. {
  139. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation (Irp);
  140. ULONG ReturnSize=0;
  141. PWNODE_HEADER Wnode;
  142. NTSTATUS ntStatus = STATUS_SUCCESS;
  143. if ((PDEVICE_OBJECT)IrpSp->Parameters.WMI.ProviderId != DeviceObject) {
  144. return PcDispatchSystemControl(DeviceObject, Irp);
  145. }
  146. switch (IrpSp->MinorFunction) {
  147. case IRP_MN_REGINFO:
  148. ntStatus = RegisterWmiGuids ((PWMIREGINFO)IrpSp->Parameters.WMI.Buffer,
  149. IrpSp->Parameters.WMI.BufferSize,
  150. &ReturnSize);
  151. break;
  152. case IRP_MN_ENABLE_EVENTS:
  153. InterlockedExchange ((PLONG)&TraceEnable, 1);
  154. Wnode = (PWNODE_HEADER)IrpSp->Parameters.WMI.Buffer;
  155. if (IrpSp->Parameters.WMI.BufferSize >= sizeof (WNODE_HEADER)) {
  156. LoggerHandle = Wnode->HistoricalContext;
  157. }
  158. break;
  159. case IRP_MN_DISABLE_EVENTS:
  160. InterlockedExchange ((PLONG)&TraceEnable, 0);
  161. break;
  162. case IRP_MN_ENABLE_COLLECTION:
  163. case IRP_MN_DISABLE_COLLECTION:
  164. break;
  165. default:
  166. ntStatus = STATUS_NOT_SUPPORTED;
  167. }
  168. // Do not modify Irp Status if this WMI call is not
  169. // handled.
  170. //
  171. if (STATUS_NOT_SUPPORTED == ntStatus)
  172. {
  173. ntStatus = Irp->IoStatus.Status;
  174. }
  175. else
  176. {
  177. Irp->IoStatus.Status = ntStatus;
  178. Irp->IoStatus.Information = ReturnSize;
  179. }
  180. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  181. return ntStatus;
  182. }
  183. ///////////////////////////////////////////////////////////////////////////
  184. VOID
  185. PerfLogGlitch (
  186. IN GUID Guid,
  187. IN ULONG_PTR InstanceId,
  188. IN ULONG Type,
  189. IN LONGLONG CurrentTime,
  190. IN LONGLONG PreviousTime
  191. )
  192. /*++
  193. Routine Description:
  194. This routine logs a WMI event tracing event with an audio glitch GUID
  195. and the supplied glitch type.
  196. --*/
  197. {
  198. PERFINFO_WMI_AUDIO_GLITCH Event;
  199. if (LoggerHandle == (TRACEHANDLE)NULL || TraceEnable == 0) {
  200. return;
  201. }
  202. RtlZeroMemory (&Event, sizeof (Event));
  203. Event.header.Size = sizeof (Event);
  204. Event.header.Flags = WNODE_FLAG_TRACED_GUID;
  205. Event.header.Guid = Guid;
  206. Event.data.glitchType = Type;
  207. Event.data.instanceId = InstanceId;
  208. Event.data.sampleTime = CurrentTime;
  209. Event.data.previousTime = PreviousTime;
  210. ((PWNODE_HEADER)&Event)->HistoricalContext = LoggerHandle;
  211. IoWMIWriteEvent ((PVOID)&Event);
  212. }
  213. VOID
  214. PerfLogInsertSilenceGlitch (
  215. IN ULONG_PTR InstanceId,
  216. IN ULONG Type,
  217. IN LONGLONG CurrentTime,
  218. IN LONGLONG PreviousTime
  219. )
  220. {
  221. PerfLogGlitch (TraceGuid,InstanceId,Type,CurrentTime,PreviousTime);
  222. }
  223. VOID
  224. PerfLogDMAGlitch (
  225. IN ULONG_PTR InstanceId,
  226. IN ULONG Type,
  227. IN LONGLONG CurrentTime,
  228. IN LONGLONG PreviousTime
  229. )
  230. {
  231. PerfLogGlitch (TraceDMAGuid,InstanceId,Type,CurrentTime,PreviousTime);
  232. }
  233. //---------------------------------------------------------------------------
  234. // End of File: perf.c
  235. //---------------------------------------------------------------------------