⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysinfo.cpp

📁 一个操作系统资源监测器的需求、设计与实现
💻 CPP
字号:
#include "stdafx.h"
#include <stdlib.h>

#include "SysInfo.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

////////////////////////////////////////////////////////////
CDiskInfo::CDiskInfo()
{
	this->diskname="";
	this->disksize=0;
	this->disk_usedsize=0;
	this->clustersize=0;
	this->clusternum=0;
	this->cluster_usednum=0;

	this->error=FALSE;
	this->next=NULL;
}

void CDiskInfo::setDiskName(CString str)
{
	this->diskname=str;
}

void CDiskInfo::setDiskSize(int value)
{
	this->disksize=value;
}

void CDiskInfo::setDUsedSize(int value)
{
	this->disk_usedsize=value;
}

void CDiskInfo::setClusterSize(int value)
{
	this->clustersize=value;
}

void CDiskInfo::setClusterNum(int value)
{
	this->clusternum=value;
}

void CDiskInfo::setCUsedNum(int value)
{
	this->cluster_usednum=value;
}

CString CDiskInfo::getDiskName()
{
	return this->diskname;
}

int CDiskInfo::getDiskSize()
{
	return this->disksize;
}

int CDiskInfo::getDUsedSize()
{
	return this->disk_usedsize;
}

int CDiskInfo::getClusterSize()
{
	return this->clustersize;
}

int CDiskInfo::getClusterNum()
{
	return this->clusternum;
}

int CDiskInfo::getCUsedNum()
{
	return this->cluster_usednum;
}

///////////////////////////////////////////////////////
CProcessInfo::CProcessInfo()
{
	this->pname="";
	this->cpusize=0;
	this->memorysize=0;

	this->error=FALSE;
	this->next=NULL;
}

void CProcessInfo::setProcessName(CString str)
{
	this->pname=str;
}

void CProcessInfo::setPCpuSize(int value)
{
	this->cpusize=value;
}

void CProcessInfo::setPMemorySize(int value)
{
	this->memorysize=value;
}

CString CProcessInfo::getProcessName()
{
	return this->pname;
}

int CProcessInfo::getPCpuSize()
{
	return this->cpusize;
}

int CProcessInfo::getPMemorySize()
{
	return this->memorysize;
}

////////////////////////////////////////////////////////////////////////////
#include <snmp.h>
#include <mgmtapi.h>
/////////////////////////////////////////////////
#define SystemBasicInformation       0
#define SystemPerformanceInformation 2
#define SystemTimeInformation        3

#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))

#define TIMEOUT 6000
#define RETRIES 3

///////////////////////////////////////////////
typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);

typedef struct
{
    LARGE_INTEGER   liIdleTime;
    DWORD           dwSpare[76];
} SYSTEM_PERFORMANCE_INFORMATION;

typedef struct
{
    LARGE_INTEGER liKeBootTime;
    LARGE_INTEGER liKeSystemTime;
    LARGE_INTEGER liExpTimeZoneBias;
    ULONG         uCurrentTimeZoneId;
    DWORD         dwReserved;
} SYSTEM_TIME_INFORMATION;
/////////////////////////////////////////
AsnObjectIdentifier reqObject;
RFC1157VarBindList Varlist;
LPSNMP_MGR_SESSION Ses;
AsnObjectIdentifier root;
AsnInteger errorStatus;
AsnInteger errorIndex;

char hostip[]="127.0.0.1";
char profile[]="public";
//////////////////////////////////
BOOL serverFlag=FALSE;

PROCNTQSI NtQuerySystemInformation;
////////////////////////////////////////

CSysInfo::CSysInfo()
{
	Varlist.len=1;
	Varlist.list=(RFC1157VarBind *)SNMP_malloc(sizeof(RFC1157VarBind));

	Ses = SnmpMgrOpen(hostip, profile, TIMEOUT, RETRIES);

	/////////////////////
	m_liOldIdleTime.QuadPart= 0;
	m_liOldSystemTime.QuadPart = 0;

	DWORD winVer;
   
	winVer = GetVersion();

	if(winVer<0x80000000)
	{
	   serverFlag=TRUE;
	}

	if(serverFlag)
	{
		NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandle("ntdll"),"NtQuerySystemInformation");
	} 
}

int * CSysInfo::getMemoryInf()
{
	int result[4];

	MEMORYSTATUS mstatus;

	mstatus.dwLength=sizeof(MEMORYSTATUS);
	GlobalMemoryStatus(&mstatus);

	result[0]=mstatus.dwTotalPhys;  /**/
	result[1]=mstatus.dwAvailPhys;
	result[2]=mstatus.dwTotalVirtual;
	result[3]=mstatus.dwAvailVirtual;

	return result;
}

CDiskInfo CSysInfo::getDiskInfo()
{
	char* target[]={
		".1.3.6.1.2.1.25.2.3.1.3",//磁盘名称
		".1.3.6.1.2.1.25.2.3.1.4",//簇大小  
		".1.3.6.1.2.1.25.2.3.1.5",//簇的个数
		".1.3.6.1.2.1.25.2.3.1.6"//被使用簇的个数
	};

	CDiskInfo *result,*p,*q;
	p=result=q=NULL;

	CString str,sign,label;
	int pos,end;

	for(int i=0;i<4;i++)
	{
		SnmpMgrStrToOid(target[i], &reqObject);
		Varlist.list[0].name=reqObject;

		SnmpUtilOidCpy(&root, &Varlist.list[0].name);

		while(TRUE)
		{
			if(!SnmpMgrRequest(Ses, ASN_RFC1157_GETNEXTREQUEST, &Varlist,&errorStatus, &errorIndex))
			{
				result->error=TRUE;

				return *result;
			}

			if (errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME || SnmpUtilOidNCmp(&Varlist.list[0].name,&root, root.idLength))
			{
				break;
			}

			if(errorStatus > 0)
			{
				result->error=TRUE;

				return *result;
			}

			switch(i)
			{
			case 0:         //磁盘名称
				p=new CDiskInfo();

				if(result==NULL)
				{
					result=p;
				}

				if(q!=NULL)
				{
					q->next=p;
				}

				str=CString(Varlist.list[0].value.asnValue.string.stream);

				pos=str.Find(":\\",0);
				if(pos!=-1)
				{
					sign=str.Left(pos+1);

					pos=str.Find("Label:",pos);
					if(pos!=-1)
					{
						pos+=6;
						end=str.Find(" ",pos);
						label=str.Mid(pos,end-pos);
						
						str=label+"("+sign+")";
					}
					else
					{
						str=sign;
					}
				}
				else
				{
					str="Virtual Memory";
				}

				p->setDiskName(str);

				q=p;

				break;
			case 1:           //簇大小 
				p->setClusterSize(Varlist.list[0].value.asnValue.number);

				p=p->next;

				break;
			case 2:             //簇的个数
				p->setClusterNum(Varlist.list[0].value.asnValue.number);

				p=p->next;

				break;
			case 3:           //被使用簇的个数
				p->setCUsedNum(Varlist.list[0].value.asnValue.number);

				p=p->next;
			}
		}

		p=result;
	}

	p=result;

	int cnum,csize,unum;

	while(p!=NULL)
	{
		cnum=p->getClusterNum();
		csize=p->getClusterSize();
		unum=p->getCUsedNum();

		csize=csize/1024;
		int value=cnum*csize/1024/1024;

		p->setDiskSize(value);

		value=unum*csize/1024/1024;

		p->setDUsedSize(value);

		p=p->next;
	}

	return *result;
}

int CSysInfo::getCpuUsedRadio()
{
	/*char target[]={".1.3.6.1.2.1.25.3.3.1.2.1"};//CPU利用率

	SnmpMgrStrToOid(target, &reqObject);
	Varlist.list[0].name=reqObject;

	if(!SnmpMgrRequest(Ses, SNMP_PDU_GETNEXT, &Varlist,&errorStatus, &errorIndex))
	{
		return -1;
	}

	if(errorStatus > 0)
	{
		return -1;
	}

	return (int)Varlist.list[0].value.asnValue.number;*/   

	UINT m_fNewUsges=40;

	if(serverFlag)
	{
		SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
		SYSTEM_TIME_INFORMATION        SysTimeInfo;
		double                         dbIdleTime;
		double                         dbSystemTime;
		LONG                           status;

		//获取系统时间
		status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0);
		if (status!=NO_ERROR)
		{
		    return -1;
		}

		//获取CPU信息
		status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL);

		if (status != NO_ERROR)
		{
		   return -1;
		}

		 //跳过第一次
		if (m_liOldIdleTime.QuadPart != 0)
		{
			 // CurrentValue = NewValue - OldValue
			 dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(m_liOldIdleTime);
			 dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(m_liOldSystemTime);

		     // CurrentCpuIdle = IdleTime / SystemTime
		    dbIdleTime = dbIdleTime / dbSystemTime;

			 // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
			 dbIdleTime = 100.0 - dbIdleTime * 100.0 + 0.5;

			 m_fNewUsges = (UINT)dbIdleTime;
		 }

		 m_liOldIdleTime = SysPerfInfo.liIdleTime;
		 m_liOldSystemTime = SysTimeInfo.liKeSystemTime;
	}
	else
	{
		HKEY hkey;
		DWORD dwDataSize;
		DWORD dwType;
		DWORD dwCpuUsage;

		if ( RegOpenKeyEx( HKEY_DYN_DATA,"PerfStats\\StartStat",0,KEY_ALL_ACCESS,&hkey ) != ERROR_SUCCESS)
		{
			return -1;
		}

		dwDataSize=sizeof(DWORD);
	    RegQueryValueEx( hkey, "KERNEL\\CPUUsage",NULL,&dwType,(LPBYTE)&dwCpuUsage,&dwDataSize );
		RegCloseKey(hkey);

		// geting current counter's value
		if ( RegOpenKeyEx( HKEY_DYN_DATA,"PerfStats\\StatData",0,KEY_READ,&hkey ) != ERROR_SUCCESS)
		{
			return -1;
		}

		dwDataSize=sizeof(DWORD);
		RegQueryValueEx( hkey,"KERNEL\\CPUUsage",NULL,&dwType,(LPBYTE)&dwCpuUsage,&dwDataSize );

		m_fNewUsges = dwCpuUsage;
		RegCloseKey(hkey);

		// stoping the counter
		if ( RegOpenKeyEx( HKEY_DYN_DATA,"PerfStats\\StopStat",0,KEY_ALL_ACCESS,&hkey ) != ERROR_SUCCESS)
		{
			return -1;
		}

		dwDataSize=sizeof(DWORD);
		RegQueryValueEx( hkey, "KERNEL\\CPUUsage",NULL,&dwType,(LPBYTE)&dwCpuUsage,&dwDataSize );

		RegCloseKey(hkey);
	}

	return (int)m_fNewUsges;
}

//内存量单位为M
int * CSysInfo::getMemoryUsedInfo()
{
	/*char target[]={
		".1.3.6.1.2.1.25.2.2.0",//物理内存
	};

	int result[2];

	SnmpMgrStrToOid(target, &reqObject);
	Varlist.list[0].name=reqObject;

	if(!SnmpMgrRequest(Ses, ASN_RFC1157_GETREQUEST, &Varlist,&errorStatus, &errorIndex))
	{
		return NULL;
	}

	if(errorStatus > 0)
	{
		return NULL;
	}

	int phymem=Varlist.list[0].value.asnValue.number;

	CProcessInfo *p=&this->getProcessInfo();

	int usedmem=0;

	while(p!=NULL)
	{
		usedmem+=p->getPMemorySize();

		p=p->next;
	}

	result[0]=usedmem/1024;
	result[1]=(int)(100*((float)usedmem/phymem));

	return result;*/

	int *result=new int[2];

	MEMORYSTATUS memStatus;
	memStatus.dwLength=sizeof(MEMORYSTATUS);
	GlobalMemoryStatus(&memStatus);

	int usage=memStatus.dwMemoryLoad;
	int total=memStatus.dwTotalPhys;
	int avail=memStatus.dwAvailPhys;

	result[0]=(total-avail)/1024;   //使用量
	result[1]=usage;   //利用率

	return result;
}

int * CSysInfo::getMemoryUsedInfo(CProcessInfo *p)
{
	char target[]={
		".1.3.6.1.2.1.25.2.2.0",//物理内存
	};

	int result[2];

	SnmpMgrStrToOid(target, &reqObject);
	Varlist.list[0].name=reqObject;

	if(!SnmpMgrRequest(Ses, ASN_RFC1157_GETREQUEST, &Varlist,&errorStatus, &errorIndex))
	{
		return NULL;
	}

	if(errorStatus > 0)
	{
		return NULL;
	}

	int phymem=Varlist.list[0].value.asnValue.number;

	int usedmem=0;

	while(p!=NULL)
	{
		usedmem+=p->getPMemorySize();

		p=p->next;
	}

	result[0]=usedmem/1024;
	result[1]=(int)(100*((float)usedmem/phymem));

	return result;
}

int CSysInfo::getNetWorkInput()
{
	char target[]={".1.3.6.1.2.1.2.2.1.10.131074"};  //网络流入量

	SnmpMgrStrToOid(target, &reqObject);
	Varlist.list[0].name=reqObject;

	if(!SnmpMgrRequest(Ses, SNMP_PDU_GETNEXT, &Varlist,&errorStatus, &errorIndex))
	{
		return -1;
	}

	if(errorStatus > 0)
	{
		return -1;
	}

	return (int)Varlist.list[0].value.asnValue.number/1024;
}

int CSysInfo::getNetWorkOutput()
{
	char target[]={".1.3.6.1.2.1.2.2.1.16.131074"};  //网络流出量

	SnmpMgrStrToOid(target, &reqObject);
	Varlist.list[0].name=reqObject;

	if(!SnmpMgrRequest(Ses, SNMP_PDU_GETNEXT, &Varlist,&errorStatus, &errorIndex))
	{
		return -1;
	}

	if(errorStatus > 0)
	{
		return -1;
	}

	return (int)Varlist.list[0].value.asnValue.number/1024;
}

CProcessInfo CSysInfo::getProcessInfo()
{
	char* target[]={
		".1.3.6.1.2.1.25.4.2.1.2",//进程名称
		".1.3.6.1.2.1.25.5.1.1.2",//进程所需内存
		".1.3.6.1.2.1.25.5.1.1.1",//进程所消耗CPU
	};

	SnmpMgrStrToOid(target[0], &reqObject);
	Varlist.list[0].name=reqObject;

	CProcessInfo *result,*p,*q;
	p=result=q=NULL;

	CString str;
	int pos;
	int cputotal=0;

	for(int i=0;i<3;i++)
	{
		SnmpMgrStrToOid(target[i], &reqObject);
		Varlist.list[0].name=reqObject;

		SnmpUtilOidCpy(&root, &Varlist.list[0].name);

		while(TRUE)
		{
			if(!SnmpMgrRequest(Ses, ASN_RFC1157_GETNEXTREQUEST, &Varlist,&errorStatus, &errorIndex))
			{
				result->error=TRUE;

				return *result;
			}

			if (errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME || SnmpUtilOidNCmp(&Varlist.list[0].name,&root, root.idLength))
			{
				break;
			}

			if(errorStatus > 0)
			{
				result->error=TRUE;

				return *result;
			}

			switch(i)
			{
			case 0:         //进程名称
				p=new CProcessInfo();

				if(result==NULL)
				{
					result=p;
				}

				if(q!=NULL)
				{
					q->next=p;
				}

				str=CString(Varlist.list[0].value.asnValue.string.stream);

				pos=Varlist.list[0].value.asnValue.string.length;

				p->setProcessName(str.Left(pos));

				q=p;

				break;
			case 1:           //进程所需内存
				p->setPMemorySize(Varlist.list[0].value.asnValue.number);

				p=p->next;

				break;
			case 2:             //进程所消耗CPU
				cputotal+=Varlist.list[0].value.asnValue.number;
				p->setPCpuSize(Varlist.list[0].value.asnValue.number);

				p=p->next;
			}
		}

		p=result;
	}

	p=result;
	while(p!=NULL)
	{
		p->setPCpuSize((int)(100*((float)p->getPCpuSize()/cputotal)));

		p=p->next;
	}

	return *result;
}

void CSysInfo::Close()
{
	SnmpMgrClose(Ses);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -