2025-04-27 07:49:33 -04:00

308 lines
6.4 KiB
C

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
cpuevent.c
Abstract:
Monitor Processor Driver Events
Author:
Todd Carpenter
Environment:
user mode
Notes:
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) 2000 Microsoft Corporation. All Rights Reserved.
Revision History:
03-15-2001 : ToddCar - created
--*/
#include "cpuevent.h"
VOID
__cdecl
_tmain(
IN INT argc,
IN TCHAR *argv[]
)
/*++
Routine Description:
Main()
Arguments:
Return Value:
--*/
{
ULONG status;
PTSTR instanceName = NULL;
status = GetInstanceName(&instanceName);
_tprintf(TEXT("InstanceName == %s\n"), instanceName);
if (status != ERROR_SUCCESS) {
if (status == ERROR_WMI_GUID_NOT_FOUND) {
_tprintf(TEXT("\n"));
_tprintf(TEXT("This processor driver does not support WMI interface\n"));
_tprintf(TEXT("\n"));
} else {
_tprintf(TEXT("GetInstanceName() Failed! rc=0x%x\n"), status);
}
return;
}
//
// Register for Notifications
//
_tprintf(TEXT("Registering for events...\n"));
status = WmiNotificationRegistration((LPGUID) &ProcessorPStateEventGuid,
(BOOLEAN) TRUE,
EventCallBackRoutine,
PStateEventId,
NOTIFICATION_CALLBACK_DIRECT);
if (status != ERROR_SUCCESS) {
_tprintf(TEXT("WmiNotificationRegistration() Failed! rc=0x%x\n"), status);
}
status = WmiNotificationRegistration((LPGUID) &ProcessorNewPStatesEventGuid,
(BOOLEAN) TRUE,
EventCallBackRoutine,
NewPStatesEventId,
NOTIFICATION_CALLBACK_DIRECT);
if (status != ERROR_SUCCESS) {
_tprintf(TEXT("WmiNotificationRegistration() Failed! rc=0x%x\n"), status);
}
status = WmiNotificationRegistration((LPGUID) &ProcessorNewCStatesEventGuid,
(BOOLEAN) TRUE,
EventCallBackRoutine,
NewCStatesEventId,
NOTIFICATION_CALLBACK_DIRECT);
if (status != ERROR_SUCCESS) {
_tprintf(TEXT("WmiNotificationRegistration() Failed! rc=0x%x\n"), status);
}
_tprintf(TEXT("Waiting.... press 'q' to quit\n\n"));
while(_getch() != 'q');
return;
}
ULONG
GetInstanceName(
OUT PTSTR *Buffer
)
/*++
Routine Description:
GetInstanceName()
Arguments:
Return Value:
--*/
{
ULONG status;
ULONG sizeNeeded;
PUCHAR buffer;
PTSTR instanceName;
ULONG instanceNameOffset;
WMIHANDLE wmiStatusHandle;
//
// NOTE: must use ProcessorMethodGuid to get Instance Name ... not
// sure why others guid don't work.
//
//
// Open connection
//
status = WmiOpenBlock(&ProcessorMethodGuid,
GENERIC_READ,
&wmiStatusHandle);
if (status != ERROR_SUCCESS) {
//_tprintf(TEXT("GetInstanceName: WmiOpenBlock() Failed! rc=0x%x\n"), status);
goto GetProcessorPerformanceStatusDataExit;
}
//
// Query for buffer size needed
//
status = WmiQueryAllData(wmiStatusHandle,
&sizeNeeded,
0);
if (status != ERROR_INSUFFICIENT_BUFFER) {
_tprintf(TEXT("GetInstanceName:WmiQueryAllData(0) Failed! rc=0x%x\n"), status);
goto GetProcessorPerformanceStatusDataExit;
}
//
// Allocate buffer
//
buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeNeeded);
if (!buffer) {
_tprintf(TEXT("GetInstanceName: HeapAlloc(size=0x%x) Failed!\n"), sizeNeeded);
status = ERROR_INSUFFICIENT_BUFFER;
goto GetProcessorPerformanceStatusDataExit;
}
//
// Retrieve Data
//
status = WmiQueryAllData(wmiStatusHandle,
&sizeNeeded,
buffer);
if (status != ERROR_SUCCESS) {
_tprintf(TEXT("GetInstanceName: WmiQueryAllData() Failed! rc=0x%x\n"), status);
goto GetProcessorPerformanceStatusDataExit;
}
//
// Get instance name.
//
instanceNameOffset = (ULONG) buffer[((PWNODE_ALL_DATA)buffer)->OffsetInstanceNameOffsets];
instanceName = (PTSTR) &buffer[instanceNameOffset + sizeof(USHORT)];
//
// Copy instance name
//
if (instanceName && Buffer) {
ULONG nameSize = lstrlen(instanceName) + sizeof(TCHAR);
*Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nameSize);
if (!(*Buffer)) {
status = ERROR_INSUFFICIENT_BUFFER;
goto GetProcessorPerformanceStatusDataExit;
}
lstrcpyn(*Buffer, instanceName, nameSize);
}
//
// Close connection
//
WmiCloseBlock(wmiStatusHandle);
GetProcessorPerformanceStatusDataExit:
if (buffer) {
//HeapFree(GetProcessHeap(), 0, buffer);
}
return status;
}
VOID
EventCallBackRoutine(
IN PWNODE_HEADER WnodeHeader,
IN UINT_PTR Context
)
{
PWNODE_SINGLE_INSTANCE wnode = (PWNODE_SINGLE_INSTANCE) WnodeHeader;
switch (Context) {
case PStateEventId:
{
PPSTATE_EVENT data = (PPSTATE_EVENT)((ULONG_PTR)wnode + (ULONG_PTR)wnode->DataBlockOffset);
_tprintf(TEXT("Perf State Transition:\n"));
_tprintf(TEXT(" New State = %u\n"), data->State);
_tprintf(TEXT(" Status = 0x%x\n"), data->Status);
_tprintf(TEXT(" Cpu Speed = %u mhz\n\n"), data->Speed);
break;
}
case NewPStatesEventId:
{
PNEW_PSTATES_EVENT data = (PNEW_PSTATES_EVENT)((ULONG_PTR)wnode + (ULONG_PTR)wnode->DataBlockOffset);
_tprintf(TEXT("New Perf States:\n"));
_tprintf(TEXT(" Highest Available State = %u\n\n"), data->HighestState);
break;
}
case NewCStatesEventId:
_tprintf(TEXT("New CStates!\n"));
break;
default:
_tprintf(TEXT("Unknown Event Id = %u\n\n"), Context);
}
}