|
|
//---------------------------------------------------------------------------
//
// 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
//---------------------------------------------------------------------------
|