308 lines
6.4 KiB
C
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);
|
|
}
|
|
|
|
}
|