如何在windows下读取DMI table--原创

 DMI table记录有关系统硬件的信息,如BIOS版本,OEM厂商,CPU,RAM等信息.本文简要介绍如何在windows下读取DMItable里面的内容.

  系统在boot时会将DMI table map到memory里面,程式实现原理是从0xF000:0位置开始search DMI table 的entry point,即search string "_SM_" . 获得entry point后再获取DMI struct entry point,我们想要的讯息就都在这个struct里面了.

简要代码如下,读取时会需要底层IO驱动,我用的是WinIO. please use google to get WinIO.

 

#define BASEADDR 0xF0000

/

//define type structure to contain the types
typedef struct _TYPEINF_
{
 BYTE bTypeID;
 BYTE bLength;
 WORD wHandle;
 BYTE TypeInfoBuf[0xFF];
}SMBiosTypeInfo,*PSMBiosTypeInfo;

//define SMBIOS Entry structure
typedef struct _SMBIOSENTRY_
{
 BYTE AnchorStr[4];    //0x00 
 BYTE CheckSum;    //0x04
 BYTE EntryPointLength;  //0x05
 BYTE MajorVer;    //0x06 SMBIOS Major Version
 BYTE MinorVer;    //0x07
 WORD MaxStructSize;   //0x08 size of the largest SMBIOS structure
 BYTE EntryPointRev;   //0x0A
 BYTE FormattedArea[5];  //0x0B - 0x0F
 BYTE IntermediateAnchorString[5];//0x10
 BYTE IntermediateCheckSum;   //0x15
 WORD StructTableLength;    //0x16
 DWORD StructTableAddress;   //0x18
 WORD SmbiosStructNum;    //0x1C
 BYTE SmbiosBCDRev;     //0x1E
}SMBiosEntryStruct,*PSMBiosEntryStruct;

///

BOOL Get_DMIInfo(BYTE DMIEntryStruct[],BYTE DMITableStruct[],PWORD TableLength)
{
 HANDLE hPhysicalMemory;
 PBYTE pbLinAdr;
 PBYTE BufTmp=NULL;
 BYTE Buf[65536]={0};
 BYTE DMIEntryInfo[32]={0};
 BYTE DMITableInfo[65536]={0};
 DWORD dwCount=0;
 DWORD dwTmpVal=0;

 //Get DMI Entry Info
 pbLinAdr = MapPhysToLin((PBYTE)BASEADDR,65536,&hPhysicalMemory);
 if(pbLinAdr)
 {
  BufTmp = pbLinAdr;
  memcpy(Buf,BufTmp,65536);
  for(dwCount=0;dwCount<65536;dwCount++)
  {
   if((Buf[dwCount] == 0x5F) && (Buf[dwCount+1] == 0x53) && (Buf[dwCount+2]==0x4D) &&(Buf[dwCount+3]==0x5F))
    //search _SM_ string to get SMBIOS entry
   {
    for(int i=0;i<32;i++)
    {
     DMIEntryInfo[i] = Buf[dwCount+i];
    }
    break;
   }
   else
   {
    continue;
   }
  }
 }
 else
 {
  UnmapPhysicalMemory(hPhysicalMemory,pbLinAdr);
  return false;
 }
 UnmapPhysicalMemory(hPhysicalMemory,pbLinAdr);

 Get DMI table structure/
 BufTmp = NULL;
 DWORD dwDMITableAdr = (DMIEntryInfo[0x1B]<<24)+(DMIEntryInfo[0x1A]<<16)+(DMIEntryInfo[0x19]<<8) +(DMIEntryInfo[0x18]);
 WORD  SMBiosLength = DMIEntryInfo[0x17]*256+DMIEntryInfo[0x16];
 *TableLength = SMBiosLength;
 pbLinAdr = MapPhysToLin((PBYTE)dwDMITableAdr,SMBiosLength,&hPhysicalMemory);
 if(pbLinAdr)
 {
  BufTmp = pbLinAdr;
  memcpy(DMITableInfo,BufTmp,SMBiosLength);//move DMI structure
 }
 else
 {
  UnmapPhysicalMemory(hPhysicalMemory,pbLinAdr);
  return false;
 }

 UnmapPhysicalMemory(hPhysicalMemory,pbLinAdr);

 memcpy(DMIEntryStruct,DMIEntryInfo,31);
 memcpy(DMITableStruct,DMITableInfo,SMBiosLength);
 return true;
}

void Do_SMBiosEntryInfo(BYTE DMIEntryStruct[],PSMBiosEntryStruct SMBiosEntryInfo)
{
 for(int i=0;i<4;i++)
 {
  SMBiosEntryInfo->AnchorStr[i] =    DMIEntryStruct[i];
 }
 
 for(int i=0;i<5;i++)
 {
  SMBiosEntryInfo->FormattedArea[i] =   DMIEntryStruct[0x0B+i];
 }
 for(int i=0;i<5;i++)
 {
  SMBiosEntryInfo->IntermediateAnchorString[i] = DMIEntryStruct[0x10+i];
 }
 SMBiosEntryInfo->CheckSum =      DMIEntryStruct[0x04];
 SMBiosEntryInfo->EntryPointLength =    DMIEntryStruct[0x05];
 SMBiosEntryInfo->EntryPointRev =    DMIEntryStruct[0x0A];
 SMBiosEntryInfo->IntermediateCheckSum =   DMIEntryStruct[0x15];
 SMBiosEntryInfo->MajorVer =      DMIEntryStruct[0x06];
 SMBiosEntryInfo->MinorVer =      DMIEntryStruct[0x07];
 SMBiosEntryInfo->MaxStructSize =    DMIEntryStruct[0x09]*256+DMIEntryStruct[0x08];
 SMBiosEntryInfo->SmbiosBCDRev =     DMIEntryStruct[0x1E];
 SMBiosEntryInfo->SmbiosStructNum =    DMIEntryStruct[0x1D]*256+DMIEntryStruct[0x1C];
 SMBiosEntryInfo->StructTableLength =   DMIEntryStruct[0x17]*256+DMIEntryStruct[0x16];
 SMBiosEntryInfo->StructTableAddress =   (DMIEntryStruct[0x1B]<<24)+(DMIEntryStruct[0x1A]<<16)+
             (DMIEntryStruct[0x19]<<8) +(DMIEntryStruct[0x18]);
 
}
void Print_SMBiosEntryInfo(__in PSMBiosEntryStruct SMBiosEntryInfo)
{
 printf("/n [DMI Entry Info]:/n");
 printf(" Anchor String:=");
 for(int i=0;i<4;i++)
 {
  printf("%c",SMBiosEntryInfo->AnchorStr[i]);
 }
 printf("/n");

 printf(" Entry Point Structure CheckSum=0x%02X/n",SMBiosEntryInfo->CheckSum);
 printf(" Entry Point Length=0x%02X/n",SMBiosEntryInfo->EntryPointLength);
 printf(" SMBIOS Version=%d.%d/n",SMBiosEntryInfo->MajorVer,SMBiosEntryInfo->MinorVer);
 printf(" Maximum Structure Size=0x%04X/n",SMBiosEntryInfo->MaxStructSize);
 printf(" Entry Point Revision=0x%02X/n",SMBiosEntryInfo->EntryPointRev);
 printf(" Formatted Area=");
 for(int i=0;i<5;i++)
 {
  printf(" 0x%02X",SMBiosEntryInfo->FormattedArea[i]);
 }
 printf("/n");

 printf(" Intermediate Anchor String=");
 for(int i=0;i<5;i++)
 {
  printf("%c",SMBiosEntryInfo->IntermediateAnchorString[i]);
 }
 printf("/n");
 printf(" Intermediate Checksum=0x%02X/n",SMBiosEntryInfo->IntermediateCheckSum);
 printf(" Struct Table Length=0x%04X/n",SMBiosEntryInfo->StructTableLength);
 printf(" Struct Table Address=0x%08X/n",SMBiosEntryInfo->StructTableAddress);
 printf(" Number of SMBIOS Structure=0x%04X/n",SMBiosEntryInfo->SmbiosStructNum);
 printf(" SMBIOS BCD Revision=0x%02X/n",SMBiosEntryInfo->SmbiosBCDRev);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值