获取系统硬件信息

获取系统硬件信息

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

获取电脑硬件信息的一些方法:
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;
        }
    }
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 是的,Golang 可以不依赖 WIM 获取系统硬件信息,包括 BIOS 和 CPU 信息。Golang 提供了对系统底层的访问能力,可以通过调用操作系统的 API 来获取硬件信息。例如,可以通过调用 Windows API 来获取 Windows 系统硬件信息,也可以通过调用 Unix 系统的 ioctl 等函数来获取 Unix 系统硬件信息。 ### 回答2: 是的,使用Golang编程语言可以获取系统硬件信息,而且不需要依赖Windows管理信息(WMI)。Golang提供了一些能够直接访问操作系统硬件信息的标准库和第三方库。 要获取BIOS信息,可以使用Golang的"os"包和"syscall"包。使用这些包,可以调用操作系统的接口来获取BIOS相关信息,例如使用"syscall.Sysctl"函数获取系统硬件和操作系统信息。 要获取CPU信息,可以使用Golang的"runtime"包。在这个包中,有一些函数可以获取CPU的数量和其他相关信息。例如,可以使用"runtime.NumCPU"函数获取系统中的CPU数量,使用"runtime.GOARCH"变量获取CPU架构信息。 除了使用这些标准库之外,还有一些第三方库在Golang社区中提供了更多的硬件信息获取功能,例如"gopsutil"和"hwinfo"等库。这些库使用操作系统提供的接口来获取各种硬件信息,包括CPU信息、内存信息、磁盘信息等。 总之,使用Golang编程语言可以轻松地获取系统硬件信息,包括BIOS和CPU信息,而无需依赖Windows管理信息(WMI)。 ### 回答3: 可以使用Golang的一些第三方库来获取系统硬件信息,而不依赖于WMI(Windows Management Instrumentation)。以下是一些Golang库可以实现获取系统硬件信息的功能: 1. sysinfo库:sysinfo库提供了一系列函数来检索系统硬件信息,包括CPU、内存、磁盘和网络信息等。你可以使用sysinfo库的函数来获取系统的BIOS和CPU信息。 2. gohardware库:gohardware库是一个轻量级的库,用于获取系统硬件信息,包括CPU、内存、磁盘、网络和GPU等。通过调用gohardware库的函数,你可以获取系统的BIOS和CPU信息。 通过使用上述的库,你可以在Golang中编写代码来获取系统硬件信息,而不需要依赖于WMI。这些库提供了一些函数或方法,可以直接在Golang程序中调用来获取所需的硬件信息。需要注意的是,不同的操作系统可能需要使用不同的库或方法来获取硬件信息。因此,在使用这些库之前,请确保你选择了适用于目标操作系统的库版本或适当的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值