//这是头文件cpu.h==================
#include <stdio.h>
#include <windows.h>
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004)
typedef LONG NTSTATUS;
#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))
//self def struct.
typedef struct CpuData
{
DWORD dwPID;
UINT cpuusage;
__int64 lastidle;
__int64 lastsys;
LARGE_INTEGER qCputime;
LARGE_INTEGER qKernelTime;
LARGE_INTEGER qUserTime;
} *pCpuData;
typedef struct _SYSTEM_PERFORMANCE_INFORMATION
{
LARGE_INTEGER IdleTime; //CPU空闲时间;
LARGE_INTEGER ReadTransferCount; //I/O读操作数目;
LARGE_INTEGER WriteTransferCount; //I/O写操作数目;
LARGE_INTEGER OtherTransferCount; //I/O其他操作数目;
ULONG ReadOperationCount; //I/O读数据数目;
ULONG WriteOperationCount; //I/O写数据数目;
ULONG OtherOperationCount; //I/O其他操作数据数目;
ULONG AvailablePages; //可获得的页数目;
ULONG TotalCommittedPages; //总共提交页数目;
ULONG TotalCommitLimit; //已提交页数目;
ULONG PeakCommitment; //页提交峰值;
ULONG PageFaults; //页故障数目;
ULONG WriteCopyFaults; //Copy-On-Write故障数目;
ULONG TransitionFaults; //软页故障数目;
ULONG CacheTransitionFaults; //=================
ULONG DemandZeroFaults; //需求0故障数;
ULONG PagesRead; //读页数目;
ULONG PageReadIos; //读页I/O操作数;
ULONG CacheReadFaults;
ULONG CacheIoFaults;
ULONG PagefilePagesWritten; //已写页文件页数;
ULONG PagefilePageWriteIos; //已写页文件操作数;
ULONG MappedFilePagesWritten; //已写映射文件页数;
ULONG MappedFileWriteIos; //已写映射文件操作数;
ULONG PagedPoolUsage; //分页池使用;
ULONG NonPagedPoolUsage; //非分页池使用;
ULONG PagedPoolAllocs; //分页池分配情况;
ULONG PagedPoolFrees; //分页池释放情况;
ULONG NonPagedPoolAllocs; //非分页池分配情况;
ULONG NonPagedPoolFress; //非分页池释放情况;
ULONG TotalFreeSystemPtes; //系统页表项释放总数;
ULONG SystemCodePage; //操作系统代码页数;
ULONG TotalSystemDriverPages; //可分页驱动程序页数;
ULONG TotalSystemCodePages; //操作系统代码页总数;
ULONG SmallNonPagedLookasideListAllocateHits; //小非分页侧视列表分配次数;
ULONG SmallPagedLookasideListAllocateHits; //小分页侧视列表分配次数;
ULONG Reserved3;
ULONG MmSystemCachePage; //系统缓存页数;
ULONG PagedPoolPage; //分页池页数;
ULONG SystemDriverPage; //可分页驱动页数;
ULONG FastReadNoWait; //异步快速读数目;
ULONG FastReadWait; //同步快速读数目;
ULONG FastReadResourceMiss; //快速读资源冲突数;
ULONG FastReadNotPossible; //快速读失败数;
ULONG FastMdlReadNoWait; //异步MDL快速读数目;
ULONG FastMdlReadWait; //同步MDL快速读数目;
ULONG FastMdlReadResourceMiss; //MDL读资源冲突数;
ULONG FastMdlReadNotPossible; //MDL读失败数;
ULONG MapDataNoWait; //异步映射数据次数;
ULONG MapDataWait; //同步映射数据次数;
ULONG MapDataNoWaitMiss; //异步映射数据冲突次数;
ULONG MapDataWaitMiss; //同步映射数据冲突次数;
ULONG PinMappedDataCount; //牵制映射数据数目;
ULONG PinReadNoWait; //牵制异步读数目;
ULONG PinReadWait; //牵制同步读数目;
ULONG PinReadNoWaitMiss; //牵制异步读冲突数目;
ULONG PinReadWaitMiss; //牵制同步读冲突数目;
ULONG CopyReadNoWait; //异步拷贝读次数;
ULONG CopyReadWait; //同步拷贝读次数;
ULONG CopyReadNoWaitMiss; //异步拷贝读故障次数;
ULONG CopyReadWaitMiss; //同步拷贝读故障次数;
ULONG MdlReadNoWait; //异步MDL读次数;
ULONG MdlReadWait; //同步MDL读次数;
ULONG MdlReadNoWaitMiss; //异步MDL读故障次数;
ULONG MdlReadWaitMiss; //同步MDL读故障次数;
ULONG ReadAheadIos; //向前读操作数目;
ULONG LazyWriteIos; //LAZY写操作数目;
ULONG LazyWritePages; //LAZY写页文件数目;
ULONG DataFlushes; //缓存刷新次数;
ULONG DataPages; //缓存刷新页数;
ULONG ContextSwitches; //环境切换数目;
ULONG FirstLevelTbFills; //第一层缓冲区填充次数;
ULONG SecondLevelTbFills; //第二层缓冲区填充次数;
ULONG SystemCall; //系统调用次数;
}SYSTEM_PERFORMANCE_INFORMATION,*PSYSTEM_PERFORMANCE_INFORMATION;
typedef struct _SYSTEM_TIMEOFDAY_INFORMATION
{
LARGE_INTEGER BootTime;
LARGE_INTEGER CurrentTime;
LARGE_INTEGER TimeZoneBias;
ULONG TimeZoneId;
ULONG Reserved;
} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;
//include sys header
typedef struct _THREAD_INFO
{
LARGE_INTEGER CreateTime;
DWORD dwUnknown1;
DWORD dwStartAddress;
DWORD StartEIP;
DWORD dwOwnerPID;
DWORD dwThreadId;
DWORD dwCurrentPriority;
DWORD dwBasePriority;
DWORD dwContextSwitches;
DWORD Unknown;
DWORD WaitReason;
}THREADINFO, *PTHREADINFO;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaxLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef struct _SYSTEM_PROCESS_INFORMATION
{
DWORD dwNextEntryOffset;
DWORD dwNumberOfThreads;
LARGE_INTEGER qSpareLi1;
LARGE_INTEGER qSpareLi2;
LARGE_INTEGER qSpareLi3;
LARGE_INTEGER qCreateTime;
LARGE_INTEGER qUserTime;
LARGE_INTEGER qKernelTime;
UNICODE_STRING ImageName;
int nBasePriority;
DWORD dwProcessId;
DWORD dwInheritedFromUniqueProcessId;
DWORD dwHandleCount;
DWORD dwSessionId;
ULONG dwSpareUl3;
SIZE_T tPeakVirtualSize;
SIZE_T tVirtualSize;
DWORD dwPageFaultCount;
DWORD dwPeakWorkingSetSize;
DWORD dwWorkingSetSize;
SIZE_T tQuotaPeakPagedPoolUsage;
SIZE_T tQuotaPagedPoolUsage;
SIZE_T tQuotaPeakNonPagedPoolUsage;
SIZE_T tQuotaNonPagedPoolUsage;
SIZE_T tPagefileUsage;
SIZE_T tPeakPagefileUsage;
SIZE_T tPrivatePageCount;
LARGE_INTEGER qReadOperationCount;
LARGE_INTEGER qWriteOperationCount;
LARGE_INTEGER qOtherOperationCount;
LARGE_INTEGER qReadTransferCount;
LARGE_INTEGER qWriteTransferCount;
LARGE_INTEGER qOtherTransferCount;
}SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER DpcTime;
LARGE_INTEGER InterruptTime;
ULONG InterruptCount;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
typedef struct _SYSTEM_BASIC_INFORMATION
{
DWORD dwUnknown1; // 0
ULONG uKeMaximumIncrement; // x86: 0x0002625A or 0x00018730
ULONG uPageSize; // bytes
ULONG uMmNumberOfPhysicalPages;
ULONG uMmLowestPhysicalPage;
ULONG uMmHighestPhysicalPage;
ULONG uAllocationGranularity; // bytes
PVOID pLowestUserAddress;
PVOID pMmHighestUserAddress;
LONG * uKeActiveProcessors;
BYTE bKeNumberProcessors; //系统cpu个数
BYTE bUnknown2;
WORD wUnknown3;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
====================================
//下面是cpu.cpp文件=================================
#include <iostream>
using namespace std;
#include "cpu.h"
#define SystemBasicInformation 0
#define SystemPerformanceInformation 2
#define SystemTimeOfDayInformation 3
#define SystemProcessInformation 5 //5 per process SystemProcessesAndThreadsInformation
#define SystemProcessorPerformanceInformation 8 //8 per cpu SystemProcessorCounters
CRITICAL_SECTION PerfDataCriticalSection;
CpuData *pPerfDataOld = NULL; /* Older perf data (saved to establish delta values) */
CpuData *pPerfData = NULL; /* Most recent copy of perf data */
ULONG ProcessCountOld = 0;
ULONG ProcessCount = 0;
SYSTEM_BASIC_INFORMATION SystemBasicInfo;
SYSTEM_PERFORMANCE_INFORMATION SystemPerfInfo;
PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SystemProcessorTimeInfo = NULL;
LARGE_INTEGER liOldIdleTime = {{0,0}};
double dbIdleTime;
double dbKernelTime;
double dbSystemTime;
double OldKernelTime = 0;
LARGE_INTEGER liOldSystemTime = {{0,0}};
//long (WINAPI *NtQuerySystemInformation )( DWORD, PVOID, DWORD, DWORD* );
typedef LONG (WINAPI *Fun_NtQuerySystemInformation) ( int SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT ULONG * pReturnLength OPTIONAL);
Fun_NtQuerySystemInformation NtQuerySystemInformation;
BOOL PerfDataInitialize(void)
{
SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
NTSTATUS status; //typedef LONG NTSTATUS;
InitializeCriticalSection(&PerfDataCriticalSection);
NtQuerySystemInformation = (Fun_NtQuerySystemInformation)GetProcAddress(LoadLibraryA("ntdll.dll"), "NtQuerySystemInformation");
//这里也可以通过GetModuleHandle()获取实例句柄
/*
* Get number of processors in the system
*/
status = NtQuerySystemInformation(SystemBasicInformation, &SystemBasicInfo, sizeof(SystemBasicInfo), NULL);
if (status != NO_ERROR)
return FALSE;
/*
* Create the SYSTEM Sid
*/
return TRUE;
}
void PerfDataUninitialize(void)
{
DeleteCriticalSection(&PerfDataCriticalSection);
}
void GetAllProcCPUUsage()
{
ULONG ulSize;
LONG status;
LPBYTE pBuffer;
ULONG BufferSize;
PSYSTEM_PROCESS_INFORMATION pSPI;
pCpuData pPDOld;
ULONG Idx, Idx2;
HANDLE hProcess;
HANDLE hProcessToken;
double CurrentKernelTime;
SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
SYSTEM_TIMEOFDAY_INFORMATION SysTimeInfo;
PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcessorTimeInfo;
ULONG Buffer[64]; /* must be 4 bytes aligned! */
/* Get new system time */
status = NtQuerySystemInformation (SystemTimeOfDayInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
if (status != NO_ERROR) //如果返回值status不为0,则表示成功
return;
/* Get new CPU's idle time */
status = NtQuerySystemInformation (SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL);
if (status != NO_ERROR)
return;
/* Get processor time information */
HANDLE myHeadHandle = GetProcessHeap();
if(NULL != myHeadHandle)
{
SysProcessorTimeInfo =
(PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)
HeapAlloc(myHeadHandle, 0, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.bKeNumberProcessors);
}
status = NtQuerySystemInformation(
SystemProcessorPerformanceInformation,
SysProcessorTimeInfo,
sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.bKeNumberProcessors,
&ulSize);
if (status != NO_ERROR)
return;
/* Get process information
* We don't know how much data there is so just keep
* increasing the buffer size until the call succeeds
*/
BufferSize = 0;
do
{
BufferSize += 0x10000;
pBuffer = (LPBYTE)HeapAlloc(myHeadHandle, 0, BufferSize);
status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize);
if (status == STATUS_INFO_LENGTH_MISMATCH)
{
HeapFree(myHeadHandle, 0, pBuffer);
}
} while (status == STATUS_INFO_LENGTH_MISMATCH);
EnterCriticalSection(&PerfDataCriticalSection);
/*
* Save system performance info
*/
memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION));
/*
* Save system processor time info
*/
if (SystemProcessorTimeInfo)
{
HeapFree(myHeadHandle, 0, SystemProcessorTimeInfo);
}
SystemProcessorTimeInfo = SysProcessorTimeInfo;
/*
* Save system handle info
*/
for (CurrentKernelTime = 0, Idx = 0; Idx < (ULONG)SystemBasicInfo.bKeNumberProcessors; Idx++)
{
CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime);
CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].DpcTime);
CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].InterruptTime);
}
/* If it's a first call - skip idle time calcs */
if (liOldIdleTime.QuadPart != 0)
{
/* CurrentValue = NewValue - OldValue */
dbIdleTime = Li2Double(SysPerfInfo.IdleTime) - Li2Double(liOldIdleTime);
dbKernelTime = CurrentKernelTime - OldKernelTime;
dbSystemTime = Li2Double(SysTimeInfo.CurrentTime) - Li2Double(liOldSystemTime);
/* CurrentCpuIdle = IdleTime / SystemTime */
dbIdleTime = dbIdleTime / dbSystemTime;
dbKernelTime = dbKernelTime / dbSystemTime;
/* CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */
dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
}
/* Store new CPU's idle and system time */
liOldIdleTime = SysPerfInfo.IdleTime;
liOldSystemTime = SysTimeInfo.CurrentTime;
OldKernelTime = CurrentKernelTime;
/* Determine the process count
* We loop through the data we got from NtQuerySystemInformation
* and count how many structures there are (until RelativeOffset is 0)
*/
ProcessCountOld = ProcessCount;
ProcessCount = 0;
pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
while (pSPI)
{
ProcessCount++;
if (pSPI->dwNextEntryOffset == 0)
break;
pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->dwNextEntryOffset);
}
/* Now alloc a new PERFDATA array and fill in the data */
if (pPerfDataOld)
{
HeapFree(GetProcessHeap(), 0, pPerfDataOld);
}
pPerfDataOld = pPerfData;
pPerfData = (pCpuData)HeapAlloc(GetProcessHeap(), 0, sizeof(CpuData) * ProcessCount);
pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
for (Idx = 0; Idx < ProcessCount; Idx++)
{
/* Get the old perf data for this process (if any) */
/* so that we can establish delta values */
pPDOld = NULL;
for (Idx2=0; Idx2 < ProcessCountOld; Idx2++)
{
if (pPerfDataOld[Idx2].dwPID == pSPI->dwProcessId)
{
pPDOld = &pPerfDataOld[Idx2];
break;
}
}
/* Clear out process perf data structure */
memset(&pPerfData[Idx], 0, sizeof(CpuData));
pPerfData[Idx].dwPID = pSPI->dwProcessId;
if (pPDOld)
{
double CurTime = Li2Double(pSPI->qKernelTime) + Li2Double(pSPI->qUserTime);
double OldTime = Li2Double(pPDOld->qKernelTime) + Li2Double(pPDOld->qUserTime);
double CpuTime = (CurTime - OldTime) / dbSystemTime;
CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
pPerfData[Idx].cpuusage = (ULONG)CpuTime;
}
pPerfData[Idx].qCputime.QuadPart = pSPI->qUserTime.QuadPart + pSPI->qKernelTime.QuadPart;
if (pSPI->dwProcessId != NULL)
{
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | READ_CONTROL, FALSE, PtrToUlong(pSPI->dwProcessId));
if (hProcess)
{
/* don't query the information of the system process. It's possible but
returns Administrators as the owner of the process instead of SYSTEM */
if (pSPI->dwProcessId != 0x4)
{
if (OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
{
DWORD RetLen = 0;
BOOL Ret;
Ret = GetTokenInformation(hProcessToken, TokenUser, (LPVOID)Buffer, sizeof(Buffer), &RetLen);
CloseHandle(hProcessToken);
}
}
CloseHandle(hProcess);
}
}
pPerfData[Idx].qUserTime.QuadPart = pSPI->qUserTime.QuadPart;
pPerfData[Idx].qKernelTime.QuadPart = pSPI->qKernelTime.QuadPart;
pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->dwNextEntryOffset);
}
HeapFree(GetProcessHeap(), 0, pBuffer);
LeaveCriticalSection(&PerfDataCriticalSection);
}
int PerfGetIndexByProcessId(DWORD dwProcessId)
{
int Index, FoundIndex = -1;
EnterCriticalSection(&PerfDataCriticalSection);
for (Index = 0; Index < (int)ProcessCount; Index++)
{
if ((DWORD)pPerfData[Index].dwPID == dwProcessId)
{
FoundIndex = Index;
break;
}
}
LeaveCriticalSection(&PerfDataCriticalSection);
return FoundIndex;
}
ULONG PerfDataGetCPUUsage(DWORD dwProcessId)
{
ULONG CpuUsage;
int Index, FoundIndex = -1;
EnterCriticalSection(&PerfDataCriticalSection);
for (Index = 0; Index < (int)ProcessCount; Index++)
{
if ((DWORD)pPerfData[Index].dwPID == dwProcessId)
{
FoundIndex = Index;
break;
}
}
if (Index < (int)ProcessCount)
CpuUsage = pPerfData[Index].cpuusage;
else
CpuUsage = 0;
LeaveCriticalSection(&PerfDataCriticalSection);
return CpuUsage;
}
int main(void)
{
PerfDataInitialize();
while(1)
{
GetAllProcCPUUsage();
printf("PID:0 CPU:%u/n", PerfDataGetCPUUsage(0));
printf("PID:2608 CPU:%u/n", PerfDataGetCPUUsage(2608));
Sleep(1000);
}
return 1;
}