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

//---------------------------------------------------------------------------
//
// Module: perf.c
//
// Description:
//
//
//@@BEGIN_MSINTERNAL
//
// History: Date Author Comment
// --------------------------------------------------------------
// 12/12/00 ArthurZ Created
//
//@@END_MSINTERNAL
//---------------------------------------------------------------------------
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1995-1999 Microsoft Corporation. All Rights Reserved.
//
//---------------------------------------------------------------------------
#include "private.h"
#include "perf.h"
#define PROC_REG_PATH L"System\\CurrentControlSet\\Services\\Portcls"
GUID ControlGuid =
{ 0x28cf047a, 0x2437, 0x4b24, 0xb6, 0x53, 0xb9, 0x44, 0x6a, 0x41, 0x9a, 0x69 };
GUID TraceGuid =
{ 0x9d447297, 0xc576, 0x4015, 0x87, 0xb5, 0xa5, 0xa6, 0x98, 0xfd, 0x4d, 0xd1 };
GUID TraceDMAGuid =
{ 0xf27b2e65, 0x15f0, 0x4d01, 0xab, 0xe2, 0xf7, 0x68, 0x5d, 0xf6, 0xe5, 0x72 };
ULONG TraceEnable;
TRACEHANDLE LoggerHandle;
typedef struct PERFINFO_AUDIOGLITCH {
ULONGLONG cycleCounter;
ULONG glitchType;
LONGLONG sampleTime;
LONGLONG previousTime;
ULONG_PTR instanceId;
} PERFINFO_AUDIOGLITCH, *PPERFINFO_AUDIOGLITCH;
typedef struct PERFINFO_WMI_AUDIOGLITCH {
EVENT_TRACE_HEADER header;
PERFINFO_AUDIOGLITCH data;
} PERFINFO_WMI_AUDIO_GLITCH, *PPERFINFO_WMI_AUDIOGLITCH;
///////////////////////////////////////////////////////////////////////////
VOID
PerfRegisterProvider (
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
This routine registers this component as a WMI event tracing provider.
--*/
{
IoWMIRegistrationControl (DeviceObject, WMIREG_ACTION_REGISTER);
}
///////////////////////////////////////////////////////////////////////////
VOID
PerfUnregisterProvider (
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
This routine unregisters this component as a WMI event tracing provider.
--*/
{
IoWMIRegistrationControl (DeviceObject, WMIREG_ACTION_DEREGISTER);
}
///////////////////////////////////////////////////////////////////////////
NTSTATUS
RegisterWmiGuids (
IN PWMIREGINFO WmiRegInfo,
IN ULONG RegInfoSize,
IN PULONG ReturnSize
)
/*++
Routine Description:
This routine registers WMI event tracing streams.
--*/
{
ULONG SizeNeeded;
PWMIREGGUIDW WmiRegGuidPtr;
ULONG status;
ULONG GuidCount;
ULONG RegistryPathSize;
PUCHAR Temp;
if (WmiRegInfo == NULL ||
ReturnSize == NULL ) {
return STATUS_INVALID_PARAMETER;
}
GuidCount = 1;
RegistryPathSize = sizeof (PROC_REG_PATH) - sizeof (WCHAR) + sizeof (USHORT);
SizeNeeded = sizeof (WMIREGINFOW) + GuidCount * sizeof (WMIREGGUIDW) + RegistryPathSize;
if (SizeNeeded > RegInfoSize) {
if ( RegInfoSize >= sizeof(ULONG) ) {
*((PULONG)WmiRegInfo) = SizeNeeded;
*ReturnSize = sizeof (ULONG);
return STATUS_BUFFER_OVERFLOW;
}
else {
*ReturnSize = 0;
return STATUS_BUFFER_TOO_SMALL;
}
}
RtlZeroMemory (WmiRegInfo, SizeNeeded);
WmiRegInfo->BufferSize = SizeNeeded;
WmiRegInfo->GuidCount = GuidCount;
WmiRegGuidPtr = WmiRegInfo->WmiRegGuid;
WmiRegGuidPtr->Guid = ControlGuid;
WmiRegGuidPtr->Flags |= (WMIREG_FLAG_TRACED_GUID | WMIREG_FLAG_TRACE_CONTROL_GUID);
Temp = (PUCHAR)(WmiRegGuidPtr + 1);
WmiRegInfo->RegistryPath = PtrToUlong ((PVOID)(Temp - (PUCHAR)WmiRegInfo));
*((PUSHORT)Temp) = (USHORT)(sizeof (PROC_REG_PATH) - sizeof (WCHAR));
Temp += sizeof (USHORT);
RtlCopyMemory (Temp, PROC_REG_PATH, sizeof (PROC_REG_PATH) - sizeof (WCHAR));
*ReturnSize = SizeNeeded;
return STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////
NTSTATUS
PcDispatchSystemControl
(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
);
NTSTATUS
PerfWmiDispatch (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine handles IRP_MJ_SYSTEM_CONTROL calls. It processes
WMI requests and passes everything else on to KS.
--*/
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation (Irp);
ULONG ReturnSize=0;
PWNODE_HEADER Wnode;
NTSTATUS ntStatus = STATUS_SUCCESS;
if ((PDEVICE_OBJECT)IrpSp->Parameters.WMI.ProviderId != DeviceObject) {
return PcDispatchSystemControl(DeviceObject, Irp);
}
switch (IrpSp->MinorFunction) {
case IRP_MN_REGINFO:
ntStatus = RegisterWmiGuids ((PWMIREGINFO)IrpSp->Parameters.WMI.Buffer,
IrpSp->Parameters.WMI.BufferSize,
&ReturnSize);
break;
case IRP_MN_ENABLE_EVENTS:
InterlockedExchange ((PLONG)&TraceEnable, 1);
Wnode = (PWNODE_HEADER)IrpSp->Parameters.WMI.Buffer;
if (IrpSp->Parameters.WMI.BufferSize >= sizeof (WNODE_HEADER)) {
LoggerHandle = Wnode->HistoricalContext;
}
break;
case IRP_MN_DISABLE_EVENTS:
InterlockedExchange ((PLONG)&TraceEnable, 0);
break;
case IRP_MN_ENABLE_COLLECTION:
case IRP_MN_DISABLE_COLLECTION:
break;
default:
ntStatus = STATUS_NOT_SUPPORTED;
}
// Do not modify Irp Status if this WMI call is not
// handled.
//
if (STATUS_NOT_SUPPORTED == ntStatus)
{
ntStatus = Irp->IoStatus.Status;
}
else
{
Irp->IoStatus.Status = ntStatus;
Irp->IoStatus.Information = ReturnSize;
}
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return ntStatus;
}
///////////////////////////////////////////////////////////////////////////
VOID
PerfLogGlitch (
IN GUID Guid,
IN ULONG_PTR InstanceId,
IN ULONG Type,
IN LONGLONG CurrentTime,
IN LONGLONG PreviousTime
)
/*++
Routine Description:
This routine logs a WMI event tracing event with an audio glitch GUID
and the supplied glitch type.
--*/
{
PERFINFO_WMI_AUDIO_GLITCH Event;
if (LoggerHandle == (TRACEHANDLE)NULL || TraceEnable == 0) {
return;
}
RtlZeroMemory (&Event, sizeof (Event));
Event.header.Size = sizeof (Event);
Event.header.Flags = WNODE_FLAG_TRACED_GUID;
Event.header.Guid = Guid;
Event.data.glitchType = Type;
Event.data.instanceId = InstanceId;
Event.data.sampleTime = CurrentTime;
Event.data.previousTime = PreviousTime;
((PWNODE_HEADER)&Event)->HistoricalContext = LoggerHandle;
IoWMIWriteEvent ((PVOID)&Event);
}
VOID
PerfLogInsertSilenceGlitch (
IN ULONG_PTR InstanceId,
IN ULONG Type,
IN LONGLONG CurrentTime,
IN LONGLONG PreviousTime
)
{
PerfLogGlitch (TraceGuid,InstanceId,Type,CurrentTime,PreviousTime);
}
VOID
PerfLogDMAGlitch (
IN ULONG_PTR InstanceId,
IN ULONG Type,
IN LONGLONG CurrentTime,
IN LONGLONG PreviousTime
)
{
PerfLogGlitch (TraceDMAGuid,InstanceId,Type,CurrentTime,PreviousTime);
}
//---------------------------------------------------------------------------
// End of File: perf.c
//---------------------------------------------------------------------------