读取SMBIOS信息

dag617712 2015-08-19 10:01:37
我是新人,可不可以发我一份读取SMBIOS信息的源程序代码参考一下,谢谢!
...全文
1134 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2015-08-20
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#define INITGUID
#include <windows.h>
#include <wmistr.h>

LONG WINAPI WmiOpenBlock(
    const GUID *DataBlockGuid,  // __in
    ULONG DesiredAccess,        // __in
    PVOID *DataBlockObject      // __inout
);

typedef LONG (WINAPI *PFN_WMI_OPEN_BLOCK)(LPCGUID, ULONG, PVOID *);

LONG WINAPI WmiQueryAllDataA(
    PVOID DataBlockObject,      // __in
    ULONG *InOutBufferSize,     // __inout
    PVOID OutBuffer             // __out_opt
);

typedef LONG (WINAPI *PFN_WMI_QUERY_ALL_DATAA)(PVOID, PULONG, PVOID);

LONG WINAPI WmiQueryAllDataW(
    PVOID DataBlockObject,      // __in
    ULONG *InOutBufferSize,     // __inout
    PVOID OutBuffer             // __out_opt
);

typedef LONG (WINAPI *PFN_WMI_QUERY_ALL_DATAW)(PVOID, PULONG, PVOID);

#ifndef UNICODE
#define WmiQueryAllData WmiQueryAllDataA
#else
#define WmiQueryAllData WmiQueryAllDataW
#endif

LONG WINAPI WmiCloseBlock(
    PVOID DataBlockObject       // __in
);

typedef LONG (WINAPI *PFN_WMI_CLOSE_BLOCK)(PVOID);

/*
 * wmidata.h
 */
DEFINE_GUID(MSSmBios_RawSMBiosTables_GUID, 0x8f680850,0xa584,0x11d1,0xbf,0x38,0x00,0xa0,0xc9,0x06,0x29,0x10);

#define MSSmBios_RawSMBiosTables_Used20CallingMethod_SIZE sizeof(BOOLEAN)
#define MSSmBios_RawSMBiosTables_Used20CallingMethod_ID 1
#define MSSmBios_RawSMBiosTables_SmbiosMajorVersion_SIZE sizeof(UCHAR)
#define MSSmBios_RawSMBiosTables_SmbiosMajorVersion_ID 2
#define MSSmBios_RawSMBiosTables_SmbiosMinorVersion_SIZE sizeof(UCHAR)
#define MSSmBios_RawSMBiosTables_SmbiosMinorVersion_ID 3
#define MSSmBios_RawSMBiosTables_DmiRevision_SIZE sizeof(UCHAR)
#define MSSmBios_RawSMBiosTables_DmiRevision_ID 4
#define MSSmBios_RawSMBiosTables_Size_SIZE sizeof(ULONG)
#define MSSmBios_RawSMBiosTables_Size_ID 5
#define MSSmBios_RawSMBiosTables_SMBiosData_ID 6

typedef struct _MSSmBios_RawSMBiosTables {
    BOOLEAN Used20CallingMethod;
    UCHAR SmbiosMajorVersion;
    UCHAR SmbiosMinorVersion;
    UCHAR DmiRevision;
    ULONG Size;
    UCHAR SMBiosData[];
} MSSmBios_RawSMBiosTables, *PMSSmBios_RawSMBiosTables;

/*
 * main
 */
int main(int argc, char *argv[])
{
    HMODULE hinstDLL = LoadLibrary(_T("advapi32.dll"));
    if (hinstDLL != NULL) {
        PFN_WMI_OPEN_BLOCK pfnWmiOpenBlock = (PFN_WMI_OPEN_BLOCK)GetProcAddress(hinstDLL, "WmiOpenBlock");
#ifndef UNICODE
        PFN_WMI_QUERY_ALL_DATAA pfnWmiQueryAllData = (PFN_WMI_QUERY_ALL_DATAA)GetProcAddress(hinstDLL, "WmiQueryAllDataA");
#else
        PFN_WMI_QUERY_ALL_DATAW pfnWmiQueryAllData = (PFN_WMI_QUERY_ALL_DATAW)GetProcAddress(hinstDLL, "WmiQueryAllDataW");
#endif
        PFN_WMI_CLOSE_BLOCK pfnWmiCloseBlock = (PFN_WMI_CLOSE_BLOCK)GetProcAddress(hinstDLL, "WmiCloseBlock");

        if (pfnWmiOpenBlock != NULL && pfnWmiQueryAllData != NULL && pfnWmiCloseBlock != NULL) {
            LPVOID *lpBlock = NULL;
            LONG lResult = pfnWmiOpenBlock(&MSSmBios_RawSMBiosTables_GUID, WMIGUID_QUERY, (void **)&lpBlock);
            if (lResult == ERROR_SUCCESS) {
                DWORD dwSize = 0;
                pfnWmiQueryAllData(lpBlock, &dwSize, NULL);
                WNODE_ALL_DATA *wmiSMBiosInfo = (WNODE_ALL_DATA *)LocalAlloc(LPTR, dwSize);
                if (wmiSMBiosInfo != NULL) {
                    lResult = pfnWmiQueryAllData(lpBlock, &dwSize, wmiSMBiosInfo);
                    if (lResult == ERROR_SUCCESS) {
                        MSSmBios_RawSMBiosTables *lpSMBios = (MSSmBios_RawSMBiosTables *)((BYTE *)wmiSMBiosInfo + wmiSMBiosInfo->DataBlockOffset);
                        printf( "Used20CallingMethod:   %u\n"
                                "SmbiosMajorVersion:    %u\n"
                                "SmbiosMinorVersion:    %u\n"
                                "DmiRevision:           %u\n"
                                "Size:                  %u\n"
                                "\n",
                                lpSMBios->Used20CallingMethod,
                                lpSMBios->SmbiosMajorVersion,
                                lpSMBios->SmbiosMinorVersion,
                                lpSMBios->DmiRevision,
                                lpSMBios->Size );
                        // 写入 SMBIOS 数据到文件
                        HANDLE hFile = CreateFile(_T("smbios.bin"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
                        if (hFile != INVALID_HANDLE_VALUE) {
                            DWORD dwBytesWritten = 0;
                            WriteFile(hFile, lpSMBios->SMBiosData, lpSMBios->Size, &dwBytesWritten, NULL);
                            CloseHandle(hFile);
                        }
                    }
                    LocalFree(wmiSMBiosInfo);
                }
                pfnWmiCloseBlock(lpBlock);
            }
        }
        FreeLibrary(hinstDLL);
    }
    return 0;
}
BurnellLiu 2015-08-19
  • 打赏
  • 举报
回复
#pragma pack(1)

/// @brief SMBIOS EPS表结构
struct S_SM_EPS
{
    BYTE SMKey[4]; ///< 固定是"_SM_"
    BYTE CheckSum; ///< 检验和
    BYTE EPSSize; ///< EPS表的长度
    BYTE MajorVersion; ///< SMBIOS主版本
    BYTE MinorVersion; ///< SMBIOS次版本
    BYTE Other[22];
};
#pragma pack()

/// @brief 查找EPS(Entry Point Structure)表地址
///  
/// @return 成功返回地址, 失败返回(0)
DWORD FindEPSAddress()
{
    const DWORD StartAddress = 0x000F0000; // EPS表所在的物理内存起始地址
    const DWORD EndAddress = 0x000FFFFF; // EPS表所在的物理内存结束地址

    BYTE _SM_[4] = {0};
    BYTE _DMI_[5] = {0};
    DWORD count = 0;
    for (DWORD address = StartAddress; address < EndAddress; address++)
    {
        count = ReadPhysicalMemory(address, _SM_, 4, 1);
        if (count != 4)
            continue;

        if (_SM_[0] != '_' || _SM_[1] != 'S' || _SM_[2] != 'M' || _SM_[3] != '_')
            continue;

        count = ReadPhysicalMemory(address + 16, _DMI_, 5, 1);
        if (count != 5)
            continue;

        if (_DMI_[0] != '_' || _DMI_[1] != 'D' || _DMI_[2] != 'M' || _DMI_[3] != 'I' || _DMI_[4] != '_')
            continue;

        return address;
    }

    return 0;
}

bool FillSMBiosEPS(DWORD address, S_SM_EPS* pEPS)
{
    DWORD count = ReadPhysicalMemory(address, (PBYTE)pEPS, sizeof(S_SM_EPS), 1);
    if (count != sizeof(S_SM_EPS))
    {
        return false;
    }

    return true;
}

int main()
{
    DWORD address = FindEPSAddress();
    if (address != 0)
    {
        printf("Find EPS Address Success\n");
    }

    S_SM_EPS eps;
    bool bRet = FillSMBiosEPS(address, &eps);
    if (bRet)
    {
        printf("Fill SMBios Success\n");
    }
    system("pause");
    return 0;
}
SMBIOS内容的解析需要你自己做 以上代码需要用到ReadPhysicalMemory方法 ReadPhysicalMemory在WinRing0中(重新编译,开启读写物理内存) 你也可以使用其他库来进行读取物理内存

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧