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);
}