S.M.A.R.T. 全称是“Self-Monitoring,Analysis and Reporting Technology”,中文意思是“自我监测分析与报告技术”,它可以对硬盘的温度、内部电路、盘片表面介质材料等进行监测,力求及时分析出硬盘可能发出的问题,并发出警告,从而保护数据不受损失。SMART在96年已经成为硬盘存储行业的一个技术标准,主流硬盘企业均支持此技术。
SMART信息是一段512字节长度的信息,存放在硬盘控制中的内存中。
其中前2字节为SMART的版本信息。后面的内容每12字节为一个SMART属性。
1,ID# : 属性ID, 从1到255.
2,ATTRIBUTE_NAME : 属性名.
3,FLAG : 表示这个属性携带的标记. 使用-f brief可以打印.
4,VALUE: Normalized value正常值, 取值范围1到254. 越低表示越差. 越高表示越好.
当前值是各ID项在硬盘运行时根据实测数据(RAW_VALUE)通过公式计算的结果,计算公式由硬盘厂家自定。 硬盘出厂时各ID项目都有一个预设的最大正常值,也即出厂值,这个预设的依据及计算方法为硬盘厂家保密,不同型号的硬盘都不同,最大正常值通常为100或200或253,
新硬盘刚开始使用时显示的当前值可以认为是预设的最大正常值(有些ID项如温度等除外)。
随着使用损耗或出现错误,当前值会根据实测数据而不断刷新并逐渐减小。
因此,当前值接近临界值就意味着硬盘寿命的减少,发生故障的可能性增大,所以当前值也是判定硬盘健康状态或推测寿命的依据之一。
5,WORST: 最差值,表示SMART开启以来的, 所有Normalized values的最低值。
最差值是硬盘运行时各ID项曾出现过的最大的非正常值。
最差值是对硬盘运行中某项数据变劣的峰值统计,该数值也会不断刷新。
通常,最差值与当前值是相等的,如果最差值出现较大的波动(小于当前值),表明硬盘曾出现错误或曾经历过恶劣的工作环境(如温度)。
6,THRESH:阈值。当Normalized value小于等于THRESH值时, 表示这项指标已经failed了。
注意, 如果这个属性是pre-failure的, 那么这项如果出现Normalized value<=THRESH, 那么磁盘将马上failed掉.
7,TYPE:这里存在两种TYPE类型, Pre-failed和Old_age.
Pre-failed 类型的Normalized value可以用来预先知道磁盘是否要坏了. 例如Normalized value接近THRESH时, 就赶紧换硬盘吧.
Old_age 类型的Normalized value是指正常的使用损耗值, 当Normalized value 接近THRESH时, 也需要注意, 但是比Pre-failed要好一点.
8,UPDATED:这个字段表示这个属性的值在什么情况下会被更新.
一种是通常的操作和离线测试都更新(Always),
另一种是只在离线测试的情况下更新(Offline).
9,WHEN_FAILED:这个字段表示当前这个属性的状态。取值有以下三种:
failing_now(normalized_value <= THRESH),
或者in_the_past(WORST <= THRESH),
或者 - , 正常(normalized_value以及wrost >= THRESH).
10,RAW_VALUE:表示这个属性的未转换前的RAW值, 可能是计数, 也可能是温度, 也可能是其他的.
注意RAW_VALUE转换成Normalized value是由厂商的firmware提供的, smartmontools不提供转换.
B7(183)串口降速错误计数 SATA Downshift Error Count
这一项表示了SATA接口速率错误下降的次数。通常硬盘与主板之间的兼容问题会导致SATA传输级别降级运行。
// SmartReader.h: interface for the CSmartReader class.
//
//
#if !defined(AFX_SMARTREADER_H__494F15B9_0FFA_4BB4_BDD0_2D4C5129E530__INCLUDED_)
#define AFX_SMARTREADER_H__494F15B9_0FFA_4BB4_BDD0_2D4C5129E530__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define _WIN32_WINNT 0x500
#include
#include
#pragma warning(disable:4786)
#include
using namespace std;
typedef map<DWORD,LPVOID> SMARTINFOMAP;
#define SMART_ATTRIB_RAW_READ_ERROR_RATE 1
#define SMART_ATTRIB_THROUGHPUT_PERFORMANCE 2
#define SMART_ATTRIB_SPIN_UP_TIME 3
#define SMART_ATTRIB_START_STOP_COUNT 4
#define SMART_ATTRIB_START_REALLOCATION_SECTOR_COUNT 5
#define SMART_ATTRIB_SEEK_ERROR_RATE 7
#define SMART_ATTRIB_POWER_ON_HOURS_COUNT 9
#define SMART_ATTRIB_SPIN_RETRY_COUNT 10
#define SMART_ATTRIB_RECALIBRATION_RETRIES 11
#define SMART_ATTRIB_DEVICE_POWER_CYCLE_COUNT 12
#define SMART_ATTRIB_SOFT_READ_ERROR_RATE 13
#define SMART_ATTRIB_LOAD_UNLOAD_CYCLE_COUNT 193
#define SMART_ATTRIB_TEMPERATURE 194
#define SMART_ATTRIB_ECC_ON_THE_FLY_COUNT 195
#define SMART_ATTRIB_REALLOCATION_EVENT_COUNT 196
#define SMART_ATTRIB_CURRENT_PENDING_SECTOR_COUNT 197
#define SMART_ATTRIB_UNCORRECTABLE_SECTOR_COUNT 198
#define SMART_ATTRIB_ULTRA_DMA_CRC_ERROR_COUNT 199
#define SMART_ATTRIB_WRITE_ERROR_RATE 200
#define SMART_ATTRIB_TA_COUNTER_INCREASED 202
#define SMART_ATTRIB_GSENSE_ERROR_RATE 221
#define SMART_ATTRIB_POWER_OFF_RETRACT_COUNT 228
#define MAX_ATTRIBUTES 256
#define INDEX_ATTRIB_INDEX 0
#define INDEX_ATTRIB_UNKNOWN1 1
#define INDEX_ATTRIB_UNKNOWN2 2
#define INDEX_ATTRIB_VALUE 3
#define INDEX_ATTRIB_WORST 4
#define INDEX_ATTRIB_RAW 5
typedef struct
{
WORD wGenConfig;
WORD wNumCyls;
WORD wReserved;
WORD wNumHeads;
WORD wBytesPerTrack;
WORD wBytesPerSector;
WORD wSectorsPerTrack;
WORD wVendorUnique[3];
BYTE sSerialNumber[20];
WORD wBufferType;
WORD wBufferSize;
WORD wECCSize;
BYTE sFirmwareRev[8];
BYTE sModelNumber[39];
WORD wMoreVendorUnique;
WORD wDoubleWordIO;
WORD wCapabilities;
WORD wReserved1;
WORD wPIOTiming;
WORD wDMATiming;
WORD wBS;
WORD wNumCurrentCyls;
WORD wNumCurrentHeads;
WORD wNumCurrentSectorsPerTrack;
WORD ulCurrentSectorCapacity;
WORD wMultSectorStuff;
DWORD ulTotalAddressableSectors;
WORD wSingleWordDMA;
WORD wMultiWordDMA;
BYTE bReserved[127];
}ST_IDSECTOR;
typedef struct
{
BYTE bDriverError;
BYTE bIDEStatus;
BYTE bReserved[2];
DWORD dwReserved[2];
} ST_DRIVERSTAT;
typedef struct
{
DWORD cBufferSize;
ST_DRIVERSTAT DriverStatus;
BYTE bBuffer[1];
} ST_ATAOUTPARAM;
typedef struct
{
BYTE m_ucAttribIndex;
DWORD m_dwAttribValue;
BYTE m_ucValue;
BYTE m_ucWorst;
DWORD m_dwThreshold;
}ST_SMART_INFO;
typedef struct
{
GETVERSIONINPARAMS m_stGVIP;
ST_IDSECTOR m_stInfo;
ST_SMART_INFO m_stSmartInfo[256];
BYTE m_ucSmartValues;
BYTE m_ucDriveIndex;
CString m_csErrorString;
}ST_DRIVE_INFO;
typedef struct
{
BOOL m_bCritical;
BYTE m_ucAttribId;
CString m_csAttribName;
CString m_csAttribDetails;
}ST_SMART_DETAILS;
typedef map<BYTE,ST_SMART_DETAILS> SMARTDETAILSMAP;
class CSmartReader
{
public:
CSmartReader();
~CSmartReader();
BOOL ReadSMARTValuesForAllDrives();
ST_SMART_DETAILS *GetSMARTDetails(BYTE ucAttribIndex);
ST_SMART_INFO *GetSMARTValue(BYTE ucDriveIndex,BYTE ucAttribIndex);
ST_DRIVE_INFO *GetDriveInfo(BYTE ucDriveIndex);
BYTE m_ucDrivesWithInfo; // Number of drives with information read
BYTE m_ucDrives;// Fixed HDD's
ST_DRIVE_INFO m_stDrivesInfo[32];
private:
VOID InitAll();
VOID CloseAll();
VOID FillAttribGenericDetails();
VOID ConvertString(PBYTE pString,DWORD cbData);
BOOL ReadSMARTInfo(BYTE ucDriveIndex);
BOOL IsSmartEnabled(HANDLE hDevice,UCHAR ucDriveIndex);
BOOL CollectDriveInfo(HANDLE hDevice,UCHAR ucDriveIndex);
BOOL ReadSMARTAttributes(HANDLE hDevice,UCHAR ucDriveIndex);
ST_SMART_DETAILS m_stSmartDetails;
SMARTINFOMAP m_oSmartInfo;
SMARTDETAILSMAP m_oSMARTDetails;
};
#endif // !defined(AFX_SMARTREADER_H__494F15B9_0FFA_4BB4_BDD0_2D4C5129E530__INCLUDED_)
// SmartReader.cpp: implementation of the CSmartReader class.
//
//
#include "stdafx.h"
#include "SMART.h"
#include "SmartReader.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//
// Construction/Destruction
//
#define DRIVE_HEAD_REG 0xA0
CSmartReader::CSmartReader()
{
InitAll();
FillAttribGenericDetails();
}
CSmartReader::~CSmartReader()
{
CloseAll();
}
VOID CSmartReader::InitAll()
{
m_ucDrivesWithInfo=m_ucDrives=0;
m_oSmartInfo.clear();
}
VOID CSmartReader::CloseAll()
{
InitAll();
}
BOOL CSmartReader::ReadSMARTValuesForAllDrives()
{
DWORD dwBits,dwBitVal;
BOOL bFlag=0;
char szDrv[MAX_PATH]={0};
BYTE ucDriveIndex=0,ucT2=0;
CloseAll();
dwBits=GetLogicalDrives();
dwBitVal=1;ucT2=0;
bFlag=(dwBits & dwBitVal);
while(ucT2<32)
{
if(bFlag)
{
wsprintf(szDrv,"%c:\\",'A'+ucT2);
switch(GetDriveType(szDrv))
{
case DRIVE_FIXED:
ucDriveIndex=ucT2-2;
if(ReadSMARTInfo(ucDriveIndex))
m_ucDrivesWithInfo++;
m_ucDrives++;
break;
default:
break;
}
}
dwBitVal=dwBitVal*2;
bFlag=(dwBits & dwBitVal);
++ucT2;
}
if(m_ucDrives==m_ucDrivesWithInfo)
return TRUE;
else
return FALSE;
}
BOOL CSmartReader::ReadSMARTInfo(BYTE ucDriveIndex)
{
HANDLE hDevice=NULL;
char szT1[MAX_PATH]={0};
BOOL bRet=FALSE;
DWORD dwRet=0;
wsprintf(szT1,"\\\\.\\PHYSICALDRIVE%d",ucDriveIndex);
hDevice=CreateFile(szT1,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM,NULL);
if(hDevice!=INVALID_HANDLE_VALUE)
{
bRet=DeviceIoControl(hDevice,SMART_GET_VERSION,NULL,0,&m_stDrivesInfo[ucDriveIndex].m_stGVIP,sizeof(GETVERSIONINPARAMS),&dwRet,NULL);
if(bRet)
{
if((m_stDrivesInfo[ucDriveIndex].m_stGVIP.fCapabilities & CAP_SMART_CMD)==CAP_SMART_CMD)
{
if(IsSmartEnabled(hDevice,ucDriveIndex))
{
bRet=CollectDriveInfo(hDevice,ucDriveIndex);
bRet=ReadSMARTAttributes(hDevice,ucDriveIndex);
}
}
}
CloseHandle(hDevice);
}
return bRet;
}
BOOL CSmartReader::IsSmartEnabled(HANDLE hDevice,UCHAR ucDriveIndex)
{
SENDCMDINPARAMS stCIP={0};
SENDCMDOUTPARAMS stCOP={0};
DWORD dwRet=0;
BOOL bRet=FALSE;
stCIP.cBufferSize=0;
stCIP.bDriveNumber =ucDriveIndex;
stCIP.irDriveRegs.bFeaturesReg=ENABLE_SMART;
stCIP.irDriveRegs.bSectorCountReg = 1;
stCIP.irDriveRegs.bSectorNumberReg = 1;
stCIP.irDriveRegs.bCylLowReg = SMART_CYL_LOW;
stCIP.irDriveRegs.bCylHighReg = SMART_CYL_HI;
stCIP.irDriveRegs.bDriveHeadReg = DRIVE_HEAD_REG;
stCIP.irDriveRegs.bCommandReg = SMART_CMD;
bRet=DeviceIoControl(hDevice,SMART_SEND_DRIVE_COMMAND,&stCIP,sizeof(stCIP),&stCOP,sizeof(stCOP),&dwRet,NULL);
if(bRet)
{
}
else
{
dwRet=GetLastError();
m_stDrivesInfo[ucDriveIndex].m_csErrorString.Format("Error %d in reading SMART Enabled flag",dwRet);
}
return bRet;
}
BOOL CSmartReader::CollectDriveInfo(HANDLE hDevice,UCHAR ucDriveIndex)
{
BOOL bRet=FALSE;
SENDCMDINPARAMS stCIP={0};
DWORD dwRet=0;
#define OUT_BUFFER_SIZE IDENTIFY_BUFFER_SIZE+16
char szOutput[OUT_BUFFER_SIZE]={0};
stCIP.cBufferSize=IDENTIFY_BUFFER_SIZE;
stCIP.bDriveNumber =ucDriveIndex;
stCIP.irDriveRegs.bFeaturesReg=0;
stCIP.irDriveRegs.bSectorCountReg = 1;
stCIP.irDriveRegs.bSectorNumberReg = 1;
stCIP.irDriveRegs.bCylLowReg = 0;
stCIP.irDriveRegs.bCylHighReg = 0;
stCIP.irDriveRegs.bDriveHeadReg = DRIVE_HEAD_REG;
stCIP.irDriveRegs.bCommandReg = ID_CMD;
bRet=DeviceIoControl(hDevice,SMART_RCV_DRIVE_DATA,&stCIP,sizeof(stCIP),szOutput,OUT_BUFFER_SIZE,&dwRet,NULL);
if(bRet)
{
CopyMemory(&m_stDrivesInfo[ucDriveIndex].m_stInfo,szOutput+16,sizeof(ST_IDSECTOR));
ConvertString(m_stDrivesInfo[ucDriveIndex].m_stInfo.sModelNumber,39);
ConvertString(m_stDrivesInfo[ucDriveIndex].m_stInfo.sSerialNumber,20);
ConvertString(m_stDrivesInfo[ucDriveIndex].m_stInfo.sFirmwareRev,8);
}
else
dwRet=GetLastError();
return bRet;
}
VOID CSmartReader::ConvertString(PBYTE pString,DWORD cbData)
{
CString csT1;
char szT1[MAX_PATH]={0};
for(int nC1=0;nC1<cbData;nC1+=2)
{
szT1[nC1]=pString[nC1+1];
szT1[nC1+1]=pString[nC1];
}
csT1=szT1;csT1.TrimLeft();csT1.TrimRight();
lstrcpy(szT1,(PCHAR)(LPCTSTR)csT1);
memcpy(pString,szT1,cbData);
}
VOID CSmartReader::FillAttribGenericDetails()
{
char szINIFileName[MAX_PATH]={0},szKeyName[MAX_PATH]={0},szValue[1024]={0};
int nC1,nSmartAttribs;
ST_SMART_DETAILS stSD;
m_oSMARTDetails.clear();
// if(IsDebuggerPresent()==FALSE)
{
GetModuleFileName(NULL,szINIFileName,MAX_PATH);
szINIFileName[lstrlen(szINIFileName)-3]=0;
lstrcat(szINIFileName,"ini");
}
// else
// wsprintf(szINIFileName,"D:\\Saneesh\\Projects\\Helpers\\SMART\\Smart.ini");
nSmartAttribs=GetPrivateProfileInt("General","Max Attributes",0,szINIFileName);
for(nC1=0;nC1<nSmartAttribs;++nC1)
{
wsprintf(szKeyName,"Attrib%d",nC1);
stSD.m_ucAttribId=GetPrivateProfileInt(szKeyName,"Id",0,szINIFileName);
stSD.m_bCritical=GetPrivateProfileInt(szKeyName,"Critical",0,szINIFileName);
GetPrivateProfileString(szKeyName,"Name","",szValue,1024,szINIFileName);
stSD.m_csAttribName=szValue;
GetPrivateProfileString(szKeyName,"Details","",szValue,1024,szINIFileName);
stSD.m_csAttribDetails=szValue;
m_oSMARTDetails.insert(SMARTDETAILSMAP::value_type(stSD.m_ucAttribId,stSD));
}
}
ST_SMART_DETAILS *CSmartReader::GetSMARTDetails(BYTE ucAttribIndex)
{
SMARTDETAILSMAP::iterator pIt;
ST_SMART_DETAILS *pRet=NULL;
pIt=m_oSMARTDetails.find(ucAttribIndex);
if(pIt!=m_oSMARTDetails.end())
pRet=&pIt->second;
return pRet;
}
ST_SMART_INFO *CSmartReader::GetSMARTValue(BYTE ucDriveIndex,BYTE ucAttribIndex)
{
SMARTINFOMAP::iterator pIt;
ST_SMART_INFO *pRet=NULL;
pIt=m_oSmartInfo.find(MAKELPARAM(ucAttribIndex,ucDriveIndex));
if(pIt!=m_oSmartInfo.end())
pRet=(ST_SMART_INFO *)pIt->second;
return pRet;
}
BOOL CSmartReader::ReadSMARTAttributes(HANDLE hDevice,UCHAR ucDriveIndex)
{
SENDCMDINPARAMS stCIP={0};
DWORD dwRet=0;
BOOL bRet=FALSE;
BYTE szAttributes[sizeof(ST_ATAOUTPARAM) + READ_ATTRIBUTE_BUFFER_SIZE - 1];
UCHAR ucT1;
PBYTE pT1,pT3;PDWORD pT2;
ST_SMART_INFO *pSmartValues;
stCIP.cBufferSize=READ_ATTRIBUTE_BUFFER_SIZE;
stCIP.bDriveNumber =ucDriveIndex;
stCIP.irDriveRegs.bFeaturesReg=READ_ATTRIBUTES;
stCIP.irDriveRegs.bSectorCountReg = 1;
stCIP.irDriveRegs.bSectorNumberReg = 1;
stCIP.irDriveRegs.bCylLowReg = SMART_CYL_LOW;
stCIP.irDriveRegs.bCylHighReg = SMART_CYL_HI;
stCIP.irDriveRegs.bDriveHeadReg = DRIVE_HEAD_REG;
stCIP.irDriveRegs.bCommandReg = SMART_CMD;
bRet=DeviceIoControl(hDevice,SMART_RCV_DRIVE_DATA,&stCIP,sizeof(stCIP),szAttributes,sizeof(ST_ATAOUTPARAM) + READ_ATTRIBUTE_BUFFER_SIZE - 1,&dwRet,NULL);
if(bRet)
{
m_stDrivesInfo[ucDriveIndex].m_ucSmartValues=0;
m_stDrivesInfo[ucDriveIndex].m_ucDriveIndex=ucDriveIndex;
pT1=(PBYTE)(((ST_ATAOUTPARAM*)szAttributes)->bBuffer);
for(ucT1=0;ucT1<30;++ucT1)
{
pT3=&pT1[2+ucT1*12];
pT2=(PDWORD)&pT3[INDEX_ATTRIB_RAW];
pT3[INDEX_ATTRIB_RAW+2]=pT3[INDEX_ATTRIB_RAW+3]=pT3[INDEX_ATTRIB_RAW+4]=pT3[INDEX_ATTRIB_RAW+5]=pT3[INDEX_ATTRIB_RAW+6]=0;
if(pT3[INDEX_ATTRIB_INDEX]!=0)
{
pSmartValues=&m_stDrivesInfo[ucDriveIndex].m_stSmartInfo[m_stDrivesInfo[ucDriveIndex].m_ucSmartValues];
pSmartValues->m_ucAttribIndex=pT3[INDEX_ATTRIB_INDEX];
pSmartValues->m_ucValue=pT3[INDEX_ATTRIB_VALUE];
pSmartValues->m_ucWorst=pT3[INDEX_ATTRIB_WORST];
pSmartValues->m_dwAttribValue=pT2[0];
pSmartValues->m_dwThreshold=MAXDWORD;
m_oSmartInfo[MAKELPARAM(pSmartValues->m_ucAttribIndex,ucDriveIndex)]=pSmartValues;
m_stDrivesInfo[ucDriveIndex].m_ucSmartValues++;
}
}
}
else
dwRet=GetLastError();
stCIP.irDriveRegs.bFeaturesReg=READ_THRESHOLDS;
stCIP.cBufferSize=READ_THRESHOLD_BUFFER_SIZE; // Is same as attrib size
bRet=DeviceIoControl(hDevice,SMART_RCV_DRIVE_DATA,&stCIP,sizeof(stCIP),szAttributes,sizeof(ST_ATAOUTPARAM) + READ_ATTRIBUTE_BUFFER_SIZE - 1,&dwRet,NULL);
if(bRet)
{
pT1=(PBYTE)(((ST_ATAOUTPARAM*)szAttributes)->bBuffer);
for(ucT1=0;ucT1<30;++ucT1)
{
pT2=(PDWORD)&pT1[2+ucT1*12+5];
pT3=&pT1[2+ucT1*12];
pT3[INDEX_ATTRIB_RAW+2]=pT3[INDEX_ATTRIB_RAW+3]=pT3[INDEX_ATTRIB_RAW+4]=pT3[INDEX_ATTRIB_RAW+5]=pT3[INDEX_ATTRIB_RAW+6]=0;
if(pT3[0]!=0)
{
pSmartValues=GetSMARTValue(ucDriveIndex,pT3[0]);
if(pSmartValues)
pSmartValues->m_dwThreshold=pT2[0];
}
}
}
return bRet;
}
ST_DRIVE_INFO *CSmartReader::GetDriveInfo(BYTE ucDriveIndex)
{
return &m_stDrivesInfo[ucDriveIndex];
}
微软自Windows 2000之后提供了WMI组件,WMI组件主要用来查询电脑设备的属性,显卡温度、CPU温度、风扇转速…,还有硬盘的相关信息(包括SMART信息).
#ifndef _WMIINFO_H_
#define _WMIINFO_H_
#include
#pragma comment(lib,"WbemUuid.lib")
class CWmiInfo
{
public:
CWmiInfo();
~CWmiInfo();
public:
HRESULT InitWmi(); //初始化WMI
HRESULT ReleaseWmi(); //释放
BOOL GetSMARTItemInfo(CString ClassName,CString ClassMember,CString &chRetValue);
private:
void VariantToString(const LPVARIANT,CString &) const;//将Variant类型的变量转换为CString
private:
IEnumWbemClassObject* m_pEnumClsObj;
IWbemClassObject* m_pWbemClsObj;
IWbemServices* m_pWbemSvc;
IWbemLocator* m_pWbemLoc;
};
#endif
#include "stdafx.h"
#include "WmiInfo.h"
CWmiInfo::CWmiInfo(void)
{
m_pWbemSvc=NULL;
m_pWbemLoc=NULL;
m_pEnumClsObj = NULL;
}
CWmiInfo::~CWmiInfo(void)
{
m_pWbemSvc=NULL;
m_pWbemLoc=NULL;
m_pEnumClsObj = NULL;
}
HRESULT CWmiInfo::InitWmi()
{
HRESULT hr;
//一、初始化COM组件
//初始化COM
hr=::CoInitializeEx(0,COINIT_MULTITHREADED);
if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr)
{
//设置进程的安全级别,(调用COM组件时在初始化COM之后要调用CoInitializeSecurity设置进程安全级别,否则会被系统识别为病毒)
hr=CoInitializeSecurity(NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL);
//VERIFY(SUCCEEDED(hr));
//二、创建一个WMI命名空间连接
//创建一个CLSID_WbemLocator对象
hr=CoCreateInstance(CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID*)&m_pWbemLoc);
// VERIFY(SUCCEEDED(hr));
//使用m_pWbemLoc连接到"root\cimv2"并设置m_pWbemSvc的指针
//hr=m_pWbemLoc->ConnectServer(CComBSTR(L"ROOT\\CIMV2"),
hr=m_pWbemLoc->ConnectServer(CComBSTR(L"ROOT\\WMI"),
NULL,
NULL,
0,
NULL,
0,
0,
&m_pWbemSvc);
// VERIFY(SUCCEEDED(hr));
//三、设置WMI连接的安全性
hr=CoSetProxyBlanket(m_pWbemSvc,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE);
// VERIFY(SUCCEEDED(hr));
}
return(hr);
}
HRESULT CWmiInfo::ReleaseWmi()
{
HRESULT hr;
if (NULL != m_pWbemSvc)
{
hr=m_pWbemSvc->Release();
}
if (NULL != m_pWbemLoc)
{
hr=m_pWbemLoc->Release();
}
if (NULL != m_pEnumClsObj)
{
hr=m_pEnumClsObj->Release();
}
::CoUninitialize();
return(hr);
}
BOOL CWmiInfo::GetSMARTItemInfo(CString ClassName,CString ClassMember,CString &chRetValue)
{
USES_CONVERSION;
CComBSTR query("SELECT * FROM ");
VARIANT vtProp;
ULONG uReturn;
HRESULT hr;
BOOL bRet = FALSE;
if (NULL != m_pWbemSvc)
{
//查询类ClassName中的所有字段,保存到m_pEnumClsObj中
query+=CComBSTR(ClassName);
hr=m_pWbemSvc->ExecQuery(CComBSTR("WQL"),query,WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
0,&m_pEnumClsObj);
if (SUCCEEDED(hr))
{
//初始化vtProp值
VariantInit(&vtProp);
uReturn=0;
//返回从当前位置起的第一个对象到m_pWbemClsObj中
hr=m_pEnumClsObj->Next(WBEM_INFINITE,1,&m_pWbemClsObj,&uReturn);
if(SUCCEEDED(hr)&&uReturn>0)
{
//从m_pWbemClsObj中找出ClassMember标识的成员属性值,并保存到vtProp变量中
hr=m_pWbemClsObj->Get(CComBSTR(ClassMember),0,&vtProp,0,0);
if (SUCCEEDED(hr))
{
VariantToString(&vtProp,chRetValue);
VariantClear(&vtProp);//清空vtProp
bRet = TRUE;
}
}
}
}
if(NULL != m_pEnumClsObj)
{
hr=m_pEnumClsObj->Release();
m_pEnumClsObj = NULL;
}
if(NULL != m_pWbemClsObj)
{
hr=m_pWbemClsObj->Release();
m_pWbemClsObj = NULL;
}
return bRet;
}
#include "stdafx.h"
#include
#include "WMIInfo.h"
using namespace std;
int main()
{
CWmiInfo WMI;
WMI.InitWmi();
CString strSmart;
WMI.GetSMARTItemInfo(L"MSStorageDriver_ATAPISmartData", L"VendorSpecific", strSmart);
return 1;
}