SMBIOS Ⅳ-读取SMBIOS信息

时间:2023-02-11 11:44:22

读取SMBIOS信息,在windows下,给我提供了如下两种方法:

1.用WMI(Windows Management Instrumentation)读取SMBIOS信息。

2.系统APIS去读SMBIOS信息:EnumSystemFirmwareTables() and GetSystemFirmwareTable()

(没去写过,希望有时间去study)

在DOS下,我们可以直接去读取SMBIOS信息通过前面我们讲过的方法。

1.找到EPS结构表这样才可以获取TYPE数和address。

unsigned char far *TblAddress;
unsigned int TblLen;
/*seach the table's address*/
int Search_Strs()
{
 char *str1="_SM_";
 char *str2="_DMI_";
 unsigned char far *ptr;  
 int j;
 //initialise the address pointer
 ptr=(unsigned char far *)0xf0000000;
 //seach the address,0x000F0000-0x000FFFFF ,but under the dos,we will use the 20bit,so the address is F000:0000 - F000:FFFF
 for(;ptr<=0xf000FFFf;)
 {  
    for(j=0;j<strlen(str1);j++)
      {
        if(*(ptr+j)!=*(str1+j))
        break;
      }
     if(j>=strlen(str1)) /*则已找到第一个字符串'_SM_',在其后16byte的5个byte是否是关键字'_DMI_'*/
     {
          ptr+=0x10;//地址加16个byte
          for(j=0;j<strlen(str2);j++)
         {
          if(*(ptr+j)!=*(str2+j))
          break;
          }
         if(j>=strlen(str2))//找到第二个字符串'_DMI_'
         {
           TblAddress=ptr+8;//SMBIOS结构表地址

           TblLen=*((unsigned int far *)(ptr+6));
           return 1;
         }

      }
     else
     {
      ptr+=0x10;//没有找到第一个字符串,ptr+0x10重新search。
     }
 }  
 return 0;  
}

2.假如我们已经找到了,那么我可以打印出TYPE0了:

 unsigned int seg,offset;
 unsigned char far *TableAddr;  
 unsigned char type,LenOfStructure;

if(Search_Strs())

{

//地址转换要注意!

//因为 x86 采用小端字节序,低字节存放的是高位的值,因此重新写成 " 高位 低位 "

  seg=*(unsigned int far *)(TableAddr+2);//int 类型16bit在dos下?

  seg<<12;//获取到TYPE0的段地址

 offset=*(unsigned int far *)(TableAddr);

TableAddr=((unsigned long )(seg)<<16)+((unsigned )(offset));

 

//print TYPE0

   printf("\nType 0(BIOS Information:)\n");  
    printf("Type:%d\n",*(TableAddr));
    printf("Length:%xH\n",*(TableAddr+1));
    printf("Handle:%.4x\n",*((unsigned int far*)(TableAddr+2)));
    printf("BIOS Starting Address Segment:%.4x\n",(*(unsigned int far *)(TableAddr+6)));
    printf("BIOS ROM Size:%dKB\n",(*(TableAddr+9)+1)*64);  
    printf("BIOS Characteristics:%.8x%.8x\n",*((unsigned long far *)(TableAddr+0x0e)),*((unsigned long far *)(TableAddr+0x0a)));
    printf("BIOS Characterics Extension Bytes:%.4x\n",*((unsigned int far *)(TableAddr+0x12)));
    printf("System BIOS Major Release:%xH\n",*(TableAddr+0x14));
    printf("System BIOS Minor Release:%xH\n",*(TableAddr+0x15));
    printf("Embedded Controller Firmware Major Release:%xH\n",*(TableAddr+0x16));
    printf("Embedded Controller Firmware Minor Release:%xH\n",*(TableAddr+0x17));
    TableAddr+=*(TableAddr+1);
    printf("Verdor:");
    TableAddr+=(print(TableAddr)+1);
    printf("BIOS Version:");
    TableAddr+=(print(TableAddr)+1);
    printf("BIOS Release Date:");
    TableAddr+=print(TableAddr);

}

哎,大概是理解完了,地址转换的时候要注意啊!

阅读全文
类别: Bios  查看评论