获取系统硬件信息

  • Post author:
  • Post category:其他



获取系统硬件信息






通常我们需要获取系统中不可变的的硬件信息来标识电脑的唯一性。






获取电脑硬件信息的一些方法:




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;




}




}