获取系统硬件信息
通常我们需要获取系统中不可变的的硬件信息来标识电脑的唯一性。
获取电脑硬件信息的一些方法:
1.通过WMI查询系统的硬件信息(通过COM接口查询系统硬件信息)
(这种方式需要基于COM,使用比较方便,不过我不太喜欢COM)
使用流程(相对固定):
初始化COM:CoInitializeEx(NULL, COINIT_MULTITHREADED)
|
设置COM的安全认证级别
CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
|
获得WMI连接COM接口
CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator,(LPVOID *) &pLoc);
|
通过连接接口连接WMI的内核对象名”ROOT\\CIMV2″
pLoc->ConnectServer(_bstr_t(L”ROOT\\CIMV2″), NULL, NULL, 0, NULL, 0, 0, &pSvc );
|
设置请求代理的安全级别(请求代理就是一个标识请求发出者的对象,它可以屏蔽实际的通信(例如屏蔽网络通信))
CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE);
|
通过请求代理来向WMI发送请求,请求的语法和SQL非常相似,例如查询bios的信息的字符串语句:
“Select * from Win32_BIOS”
需要注意的是这个字符串是以BSTR形式保存的,可以通过:
BSTR sql = _bstr_t(“Select * from Win32_BIOS”) 来初始化
如果使用CString类,它可以通过成员函数SysAllocString进行转换
如果使用API,可以通过WideCharToMultiByte/MultiByteToWideChar/ConvertBSTRToString等相关函数进行转换
|
获得查询结果的枚举封装接口pEnumClassObject
pSvc->ExecQuery(bsWQL, bsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject)
|
循环枚举所有的结果对象
pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned)
pClassObject接口映射的是名-值对数组
SAFEARRAY *pvNames = NULL;
pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames)
|
获取名值数组数目并历遍所有单元
SafeArrayGetLBound(pvNames, 1, &vbl);
SafeArrayGetUBound(pvNames, 1, &vbu);
…
[循环获取每个单元的信息]
wchar_t *wsName = 0;
VARIANT vValue;
VariantInit(&vValue);
SafeArrayGetElement(pvNames, &aidx, &wsName);//获取名称key值
(这里比较麻烦的是名字值UNICODE形式保存的(如果需要使用MBCS的话都需要自己进行转换))
BSTR bs = SysAllocString(wsName);
pClassObject->Get(bs, 0, &vValue, NULL, 0); //获取名称对应的值
得到的值都是通过VARIANT保存的,用户可以自己格式化它最后的表现形式(特别需要注意的是字符串都是BSTR)
WMI可以查询的信息种类(备忘):
Win32_1394Controller
Win32_BaseBoard
Win32_Battery
Win32_BIOS
Win32_Bus
Win32_CacheMemory
Win32_CDROMDrive
Win32_CurrentProbe
Win32_DesktopMonitor
Win32_DeviceMemoryAddress
Win32_DiskDrive
Win32_DisplayConfiguration
Win32_DisplayControllerConfiguration
Win32_DMAChannel
Win32_Fan
Win32_FloppyController
Win32_FloppyDrive
Win32_HeatPipe
Win32_IDEController
Win32_InfraredDevice
Win32_IRQResource
Win32_Keyboard
Win32_MemoryArray
Win32_MemoryDevice
Win32_MotherboardDevice
Win32_NetworkAdapter
Win32_NetworkAdapterConfiguration
Win32_OnBoardDevice
Win32_ParallelPort
Win32_PCMCIAController
Win32_PhysicalMemory
Win32_PhysicalMemoryArray
Win32_PnPEntity
Win32_PointingDevice
Win32_PortableBattery
Win32_PortConnector
Win32_PortResource
Win32_POTSModem
Win32_PowerManagementEvent
Win32_Printer
Win32_PrinterConfiguration
Win32_PrintJob
Win32_Processor
Win32_Refrigeration
Win32_SerialPort
Win32_SerialPortConfiguration
Win32_SMBIOSMemory
Win32_SoundDevice
Win32_SystemEnclosure
Win32_SystemMemoryResource
Win32_SystemSlot
Win32_TapeDrive
Win32_TemperatureProbe
Win32_UninterruptiblePowerSupply
Win32_USBController
Win32_VideoConfiguration
Win32_VideoController
Win32_VoltageProbe
2.通过HID获取系统中的设备信息(Human Interface Device)
这个标准主要是面向与用户直接交互的接口设备的,例如鼠标/键盘/操作杆等等,但是它也能够查询本地电脑
的硬件信息,而且它的使用相对简单.
初始化设备枚举句柄
hDevInfo = SetupDiGetClassDevs(
&val, //(LPGUID) &GUID_DEVCLASS_KEYBOARD,
0, // Enumerator
0,
//DIGCF_PRESENT | DIGCF_ALLCLASSES );
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
);
|
枚举所有的信息
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,
&DeviceInfoData);i++)
{
DWORD DataT;
LPTSTR buffer = NULL;
DWORD buffersize = 0;
//
// Call function with null to begin with,
// then use the returned buffer size
// to Alloc the buffer. Keep calling until
// success or an unknown failure.
//
//#define SPDRP_DEVICEDESC (0x00000000) // DeviceDesc (R/W)
//#define SPDRP_HARDWAREID (0x00000001) // HardwareID (R/W)
//#define SPDRP_COMPATIBLEIDS (0x00000002) // CompatibleIDs (R/W)
//#define SPDRP_UNUSED0 (0x00000003) // unused
//#define SPDRP_SERVICE (0x00000004) // Service (R/W)
//#define SPDRP_UNUSED1 (0x00000005) // unused
//#define SPDRP_UNUSED2 (0x00000006) // unused
//#define SPDRP_CLASS (0x00000007) // Class (R–tied to ClassGUID)
//#define SPDRP_CLASSGUID (0x00000008) // ClassGUID (R/W)
//#define SPDRP_DRIVER (0x00000009) // Driver (R/W)
//#define SPDRP_CONFIGFLAGS (0x0000000A) // ConfigFlags (R/W)
//#define SPDRP_MFG (0x0000000B) // Mfg (R/W)
//#define SPDRP_FRIENDLYNAME (0x0000000C) // FriendlyName (R/W)
//#define SPDRP_LOCATION_INFORMATION (0x0000000D) // LocationInformation (R/W)
//#define SPDRP_PHYSICAL_DEVICE_OBJECT_NAME (0x0000000E) // PhysicalDeviceObjectName (R)
//#define SPDRP_CAPABILITIES (0x0000000F) // Capabilities (R)
//#define SPDRP_UI_NUMBER (0x00000010) // UiNumber (R)
//#define SPDRP_UPPERFILTERS (0x00000011) // UpperFilters (R/W)
//#define SPDRP_LOWERFILTERS (0x00000012) // LowerFilters (R/W)
//#define SPDRP_BUSTYPEGUID (0x00000013) // BusTypeGUID (R)
//#define SPDRP_LEGACYBUSTYPE (0x00000014) // LegacyBusType (R)
//#define SPDRP_BUSNUMBER (0x00000015) // BusNumber (R)
//#define SPDRP_ENUMERATOR_NAME (0x00000016) // Enumerator Name (R)
//#define SPDRP_SECURITY (0x00000017) // Security (R/W, binary form)
//#define SPDRP_SECURITY_SDS (0x00000018) // Security (W, SDS form)
//#define SPDRP_DEVTYPE (0x00000019) // Device Type (R/W)
//#define SPDRP_EXCLUSIVE (0x0000001A) // Device is exclusive-access (R/W)
//#define SPDRP_CHARACTERISTICS (0x0000001B) // Device Characteristics (R/W)
//#define SPDRP_ADDRESS (0x0000001C) // Device Address (R)
//#define SPDRP_UI_NUMBER_DESC_FORMAT (0X0000001D) // UiNumberDescFormat (R/W)
//#define SPDRP_DEVICE_POWER_DATA (0x0000001E) // Device Power Data (R)
//#define SPDRP_REMOVAL_POLICY (0x0000001F) // Removal Policy (R)
//#define SPDRP_REMOVAL_POLICY_HW_DEFAULT (0x00000020) // Hardware Removal Policy (R)
//#define SPDRP_REMOVAL_POLICY_OVERRIDE (0x00000021) // Removal Policy Override (RW)
//#define SPDRP_INSTALL_STATE (0x00000022) // Device Install State (R)
//#define SPDRP_LOCATION_PATHS (0x00000023) // Device Location Paths (R)
printf(“=========================================================================\n”);
const char * pinfo[] = {
“设备描述”,
“硬件id”,
“兼容id”,
“保留1”,
“服务”,
“保留2”,
“保留3”,
“设备类名”,
“类id(自定义)”,
“驱动名称”,
“配置符号”,
“MFG”,
“友好的名称”,
“本地信息”,
“物理设备对象名称”,
“设备能力”,
“UI_NUMBER “,
“大写过滤UpperFilters”,
“小写过滤UpperFilters”,
“繁忙类型GUID”,
“总线类型”,
“总线号”,
“枚举器的名称”,
“安全信息”,
“安全信息SDS格式”,
“设备类型”,
“设备独占访问类型”,
“设备特性”,
“设备地址”,
“UI_NUMBER_DESC_FORMAT”,
“设备电源数据”,
“设备策略”,
“设备删除策略”,
“设备覆盖(写)策略”,
“设备安装状态”,
“设备本地路径”
};
char data[2046];
//循环枚举所有的信息
for (unsigned int k = 0; k <= 0x00000023; ++k)
{
while (!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&DeviceInfoData,
k,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() ==
ERROR_INSUFFICIENT_BUFFER)
{
// Change the buffer size.
if (buffer) LocalFree((HLOCAL)buffer);
buffer = (LPTSTR)LocalAlloc(LPTR,buffersize);
}
else
{
// Insert error handling here.
break;
}
}
string val = Byte2String(buffer, buffersize);
printf(“Result:%s–>[%s]\n”,pinfo[k], val.c_str());
}
if (buffer) LocalFree(buffer);
}
|
|
//关闭枚举句柄
SetupDiDestroyDeviceInfoList(hDevInfo);
可以供查询的类型包括:
DEFINE_GUID( GUID_DEVCLASS_1394, 0x6bdd1fc1L, 0x810f, 0x11d0, 0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f );
DEFINE_GUID( GUID_DEVCLASS_1394DEBUG, 0x66f250d6L, 0x7801, 0x4a64, 0xb1, 0x39, 0xee, 0xa8, 0x0a, 0x45, 0x0b, 0x24 );
DEFINE_GUID( GUID_DEVCLASS_61883, 0x7ebefbc0L, 0x3200, 0x11d2, 0xb4, 0xc2, 0x00, 0xa0, 0xc9, 0x69, 0x7d, 0x07 );
DEFINE_GUID( GUID_DEVCLASS_ADAPTER, 0x4d36e964L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_APMSUPPORT,0xd45b1c18L, 0xc8fa, 0x11d1, 0x9f, 0x77, 0x00, 0x00, 0xf8, 0x05, 0xf5, 0x30 );
DEFINE_GUID( GUID_DEVCLASS_AVC, 0xc06ff265L, 0xae09, 0x48f0, 0x81, 0x2c, 0x16, 0x75, 0x3d, 0x7c, 0xba, 0x83 );
DEFINE_GUID( GUID_DEVCLASS_BATTERY, 0x72631e54L, 0x78a4, 0x11d0, 0xbc, 0xf7, 0x00, 0xaa, 0x00, 0xb7, 0xb3, 0x2a );
DEFINE_GUID( GUID_DEVCLASS_BLUETOOTH,0xe0cbf06cL, 0xcd8b, 0x4647, 0xbb, 0x8a, 0x26, 0x3b, 0x43, 0xf0, 0xf9, 0x74 );
DEFINE_GUID( GUID_DEVCLASS_CDROM,0x4d36e965L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_COMPUTER,0x4d36e966L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_DECODER, 0x6bdd1fc2L, 0x810f, 0x11d0, 0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f );
DEFINE_GUID( GUID_DEVCLASS_DISKDRIVE, 0x4d36e967L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_DISPLAY, 0x4d36e968L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_DOT4, 0x48721b56L, 0x6795, 0x11d2, 0xb1, 0xa8, 0x00, 0x80, 0xc7, 0x2e, 0x74, 0xa2 );
DEFINE_GUID( GUID_DEVCLASS_DOT4PRINT, 0x49ce6ac8L, 0x6f86, 0x11d2, 0xb1, 0xe5, 0x00, 0x80, 0xc7, 0x2e, 0x74, 0xa2 );
DEFINE_GUID( GUID_DEVCLASS_ENUM1394, 0xc459df55L, 0xdb08, 0x11d1, 0xb0, 0x09, 0x00, 0xa0, 0xc9, 0x08, 0x1f, 0xf6 );
DEFINE_GUID( GUID_DEVCLASS_FDC, 0x4d36e969L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_FLOPPYDISK,0x4d36e980L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_GPS,0x6bdd1fc3L, 0x810f, 0x11d0, 0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f );
DEFINE_GUID( GUID_DEVCLASS_HDC,0x4d36e96aL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_HIDCLASS,0x745a17a0L, 0x74d3, 0x11d0, 0xb6, 0xfe, 0x00, 0xa0, 0xc9, 0x0f, 0x57, 0xda );
DEFINE_GUID( GUID_DEVCLASS_IMAGE,0x6bdd1fc6L, 0x810f, 0x11d0, 0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f );
DEFINE_GUID( GUID_DEVCLASS_INFINIBAND,0x30ef7132L, 0xd858, 0x4a0c, 0xac, 0x24, 0xb9, 0x02, 0x8a, 0x5c, 0xca, 0x3f );
DEFINE_GUID( GUID_DEVCLASS_INFRARED,0x6bdd1fc5L, 0x810f, 0x11d0, 0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f );
DEFINE_GUID( GUID_DEVCLASS_KEYBOARD,0x4d36e96bL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_LEGACYDRIVER,0x8ecc055dL, 0x047f, 0x11d1, 0xa5, 0x37, 0x00, 0x00, 0xf8, 0x75, 0x3e, 0xd1 );
DEFINE_GUID( GUID_DEVCLASS_MEDIA,0x4d36e96cL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_MEDIUM_CHANGER,0xce5939aeL, 0xebde, 0x11d0, 0xb1, 0x81, 0x00, 0x00, 0xf8, 0x75, 0x3e, 0xc4 );
DEFINE_GUID( GUID_DEVCLASS_MODEM,0x4d36e96dL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_MONITOR,0x4d36e96eL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_MOUSE,0x4d36e96fL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_MTD,0x4d36e970L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_MULTIFUNCTION,0x4d36e971L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_MULTIPORTSERIAL,0x50906cb8L, 0xba12, 0x11d1, 0xbf, 0x5d, 0x00, 0x00, 0xf8, 0x05, 0xf5, 0x30 );
DEFINE_GUID( GUID_DEVCLASS_NET,0x4d36e972L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_NETCLIENT,0x4d36e973L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_NETSERVICE,0x4d36e974L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_NETTRANS,0x4d36e975L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_NODRIVER,0x4d36e976L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_PCMCIA,0x4d36e977L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_PNPPRINTERS,0x4658ee7eL, 0xf050, 0x11d1, 0xb6, 0xbd, 0x00, 0xc0, 0x4f, 0xa3, 0x72, 0xa7 );
DEFINE_GUID( GUID_DEVCLASS_PORTS,0x4d36e978L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_PRINTER,0x4d36e979L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_PRINTERUPGRADE,0x4d36e97aL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_PROCESSOR,0x50127dc3L, 0x0f36, 0x415e, 0xa6, 0xcc, 0x4c, 0xb3, 0xbe, 0x91, 0x0B, 0x65 );
DEFINE_GUID( GUID_DEVCLASS_SBP2,0xd48179beL, 0xec20, 0x11d1, 0xb6, 0xb8, 0x00, 0xc0, 0x4f, 0xa3, 0x72, 0xa7 );
DEFINE_GUID( GUID_DEVCLASS_SCSIADAPTER,0x4d36e97bL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_SECURITYACCELERATOR, 0x268c95a1L, 0xedfe, 0x11d3, 0x95, 0xc3, 0x00, 0x10, 0xdc, 0x40, 0x50, 0xa5 );
DEFINE_GUID( GUID_DEVCLASS_SMARTCARDREADER,0x50dd5230L, 0xba8a, 0x11d1, 0xbf, 0x5d, 0x00, 0x00, 0xf8, 0x05, 0xf5, 0x30 );
DEFINE_GUID( GUID_DEVCLASS_SOUND,0x4d36e97cL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_SYSTEM,0x4d36e97dL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_TAPEDRIVE,0x6d807884L, 0x7d21, 0x11cf, 0x80, 0x1c, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_UNKNOWN,0x4d36e97eL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
DEFINE_GUID( GUID_DEVCLASS_USB,0x36fc9e60L, 0xc465, 0x11cf, 0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 );
DEFINE_GUID( GUID_DEVCLASS_VOLUME,0x71a27cddL, 0x812a, 0x11d0, 0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f );
DEFINE_GUID( GUID_DEVCLASS_VOLUMESNAPSHOT,0x533c5b84L, 0xec70, 0x11d2, 0x95, 0x05, 0x00, 0xc0, 0x4f, 0x79, 0xde, 0xaf );
DEFINE_GUID( GUID_DEVCLASS_WCEUSBS,0x25dbce51L, 0x6c8f, 0x4a72, 0x8a, 0x6d, 0xb5, 0x4c, 0x2b, 0x4f, 0xc8, 0x35 );
DEFINE_GUID( GUID_DEVCLASS_BTRANS,0x4d36e97dL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
3.[转载]获取硬盘序列号的方法
———————————————————-转载结束———————————————————–
char *ConvertToString(DWORD diskdata [256], int firstIndex, int astIndex)
{
static char string[1024];
int index = 0;
int position = 0;
for(index = firstIndex; index <= lastIndex; index++)
{
string[position] = (char)(diskdata[index] / 256);
position++;
string[position] = (char)(diskdata[index] % 256);
position++;
}
string[position] = ‘\0’;
for(index = position – 1; index > 0 && ‘ ‘ == string[index]; index–) string[index] = ‘\0’;
return string;
}
int WinNTHDSerialNumAsScsiRead(DWORD * buffer)
{
buffer[0]=’\n’;
int controller = 0;
HANDLE hScsiDriveIOCTL = 0;
char driveName[256];
sprintf (driveName, “\\\\.\\Scsi%d:”, controller);
hScsiDriveIOCTL = CreateFile(driveName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hScsiDriveIOCTL !=INVALID_HANDLE_VALUE)
{
int drive = 0;
for(drive = 0; drive < 2; drive++)
{
char buffer[sizeof(SRB_IO_CONTROL) + SENDIDLENGTH];
SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;
SENDCMDINPARAMS *pin = (SENDCMDINPARAMS *)(buffer + sizeof(SRB_IO_CONTROL));
DWORD dummy;
memset(buffer, 0, sizeof(buffer));
p->HeaderLength = sizeof(SRB_IO_CONTROL);
p->Timeout = 10000;
p->Length = SENDIDLENGTH;
p->ControlCode =IOCTL_SCSI_MINIPORT_IDENTIFY;
strncpy((char *) p->Signature, “SCSIDISK”, 8);
pin->irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
pin->bDriveNumber = drive;
if(DeviceIoControl(hScsiDriveIOCTL,IOCTL_SCSI_MINIPORT, buffer,sizeof(SRB_IO_CONTROL)+sizeof(SENDCMDINPARAMS) – 1, buffer,sizeof(SRB_IO_CONTROL) + SENDIDLENGTH,&dummy, NULL))
{
SENDCMDOUTPARAMS *pOut = (SENDCMDOUTPARAMS *) (buffer + sizeof(SRB_IO_CONTROL));
IDSECTOR *pId = (IDSECTOR *)(pOut->bBuffer);
if (pId->sModelNumber[0])
{
int ijk = 0;
USHORT *pIdSector = (USHORT *) pId;
for(ijk = 0; ijk < 256; ijk++) buffer[ijk] = pIdSector[ijk];
return 1;
}
}
}
CloseHandle(hScsiDriveIOCTL);
}
return -1;
}
BOOL DoIDENTIFY (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,PDWORD lpcbBytesReturned)
{
pSCIP->cBufferSize= IDENTIFY_BUFFER_SIZE;
pSCIP->irDriveRegs.bFeaturesReg = 0;
pSCIP->irDriveRegs.bSectorCountReg = 1;
pSCIP->irDriveRegs.bSectorNumberReg = 1;
pSCIP->irDriveRegs.bCylLowReg = 0;
pSCIP->irDriveRegs.bCylHighReg = 0;
pSCIP->irDriveRegs.bDriveHeadReg = 0xA0 |((bDriveNum & 1) << 4);
pSCIP->irDriveRegs.bCommandReg = bIDCmd;
pSCIP->bDriveNumber = bDriveNum;
pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
return (DeviceIoControl(hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA,(LPVOID) pSCIP,sizeof(SENDCMDINPARAMS) – 1,
(LPVOID)pSCOP,sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE – 1, lpcbBytesReturned, NULL));
}
int WinNTHDSerialNumAsPhysicalRead(DWORD * buffer)
{
#define DFP_GET_VERSION 0x00074080
BYTE IdOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE-1];
int done = FALSE;
int drive = 0;
HANDLE hPhysicalDriveIOCTL = 0;
char driveName[256];
sprintf(driveName, “\\\\.\\PhysicalDrive%d”, drive);
hPhysicalDriveIOCTL = CreateFile(driveName,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, 0, NULL);
if(hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
{
GETVERSIONOUTPARAMS VersionParams;
DWORD cbBytesReturned = 0;
memset((void*)&VersionParams, 0, sizeof(VersionParams));
if(VersionParams.bIDEDeviceMap > 0)
{
BYTE bIDCmd = 0;
SENDCMDINPARAMS scip;
bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
memset(&scip, 0, sizeof(scip));
memset(IdOutCmd, 0, sizeof(IdOutCmd));
if(DoIDENTIFY(hPhysicalDriveIOCTL, &scip,
(PSENDCMDOUTPARAMS)&IdOutCmd,(BYTE)bIDCmd,(BYTE)drive, &cbBytesReturned))
{
int ijk = 0;
USHORT *pIdSector = (USHORT *)
((PSENDCMDOUTPARAMS)IdOutCmd)->bBuffer;
for(ijk= 0;ijk < 256; ijk++)
buffer[ijk]=pIdSector[ijk];
done = TRUE;
}
}
CloseHandle(hPhysicalDriveIOCTL);
}
return done;
}
———————————————————-转载结束———————————————————–
4.手工读取操作系统启动后bios所映射的内存信息(不使用COM)
通过WMI获取的信息可以理解为操作系统对硬件信息(在系统启动过程中得到的信息和驱动安装得到的信息的并集)的再组织. 我们还可以自己到内存中读取系统启动时由主板bios和NT加载时填写的信息.要自己解析内存中的bios信息(包括bios本身/主板/CPU等),需 要知道SMB的保存信息的结构.
打开bios所映射的内存
|
对于98(可以直接访问物理内存)而言,bios地址可以直接初始化为0xF0000开始的0xffff个字节的内容
对于NT内核(不能直接读取物理内存)而言,需要通过设备”\\Device\\PhysicalMemory”来映射物理内存;
OBJECT_ATTRIBUTES obj_ar;
static BYTE buf[BIOS_SIZE];
HANDLE hSection;
DWORD ba;
LARGE_INTEGER so;
SIZE_T ssize;
so.LowPart=0x000f0000;//物理内存的基址,就是f000:0000
so.HighPart=0x00000000;
ssize=BIOS_SIZE;
wchar_t strPH[100]=L”\\Device\\PhysicalMemory”;
//变量初始化
ba=0;//联系后的基址将在这里返回
struniph.Buffer=strPH;
struniph.Length=0x2c;//注意大小是按字节算
struniph.MaximumLength =0x2e;//也是字节
obj_ar.Attributes =64;//属性
obj_ar.Length =24;//OBJECT_ATTRIBUTES类型的长度
obj_ar.ObjectName=&struniph;//指向对象的指针
obj_ar.RootDirectory=0;
obj_ar.SecurityDescriptor=0;
obj_ar.SecurityQualityOfService =0;
//初始化内存映射句柄
Status = ZwOpenSection(&hSection,4,&obj_ar);
//映射内存
Status = ZwMapViewOfSection(
(HANDLE)hSection,
(HANDLE)0xffffffff,
(PVOID *)&ba,
0,
BIOS_SIZE,
&so,
(PSIZE_T)&ssize,
(SECTION_INHERIT)1,
0,
2
);
//拷贝信息
memcpy(buf, (BYTE *)ba, BIOS_SIZE);
|
bios内容获得后(以获取bios中的描述字符串为例),我们就可以进行分析
1.检查bios是否遵守SMB标准,实际上就是查询字符串_SM_(由于PC通常是低序保存数据的),所以查询的时候我们要查的是_MS_,找到 _SM_后还需要判断它后面的第16个字节开始依次是_DMI_,只有符合这种数据内容的情况下才可以认为它符合SMBois规范
2.对于有的bios,它会包含一个修正指针,指向真正的信息保存位置,所以在和的bios内容后需要进行修正
以98为例:
//修正指针
if ((((DWORD)ptable) >> 16) != 0xF)
{
//需要重新读取
memcpy(buf, (BYTE*)ptable, total);
ptable = buf;
}
3.查询各个数据起始位置
BIOS_HEADER *ptarget = NULL;
handle = 0xFFFF;
while( i < StructureCount && ptarget == NULL )
{
i++;
lasttype = ((BIOS_HEADER *)TableAddress)->Type;
if( lasttype == Type )
{
ptarget = (BIOS_HEADER *)TableAddress;
handle = ((BIOS_HEADER *)TableAddress)->Handle;
}
else
{
TableAddress += ((BIOS_HEADER *)TableAddress)->Length;
while( *((ushort *)TableAddress) != 0 )
{
TableAddress++;
}
TableAddress += 2;
}
}
3.获取bios的数据段获取字符串描述信息
while( i < StructureCount )
{
i++;
lasttype = ((BIOS_HEADER *)TableAddress)->Type;
if( lasttype == Type )
{
ptarget = (BIOS_HEADER *)TableAddress;
TableAddress += ((BIOS_HEADER *)TableAddress)->Length;
string temp;
while( *((ushort *)TableAddress) != 0 )
{
temp = TableAddress;
if (temp.length() > 0)
{
TableAddress += temp.length();
}else{
TableAddress ++;
}
str += temp;
}
break;
}
else
{
TableAddress += ((BIOS_HEADER *)TableAddress)->Length;
while( *((ushort *)TableAddress) != 0 )
{
TableAddress++;
}
TableAddress += 2;
}
}