兩個由 Turbo C++ 寫的在 DOS 下讀寫 DMI 的 sample code。
Sample code 1:這是使用搜尋方法尋找記憶體中 BIOS 區域 (F000:0000 ~ F000:FFFF) 中的 SMBIOS 與 DMI table來讀取 DMI 訊息的方法,這個方法只能讀取無法改寫 DMI 內容。
#include <stdio.h> #include <string.h> #include <dos.h> #include <conio.h> unsigned char far *TblAddr_Ptr; unsigned int TblLen; typedef struct { unsigned char type; unsigned char length; unsigned short handle; }Header; /*search two strings in one function*/ int Search_Strs(unsigned int seg_addr, unsigned int offset_addr, char *str1, char *str2) { unsigned char far *ptr; int j; ptr = (unsigned char far *)MK_FP(seg_addr, offset_addr); for (; (long)ptr <= 0xFFFF0;) { for (j = 0; j < strlen(str1); j++) /*search the first string*/ if (*(ptr + j) != *(str1 + j)) break; if (j >= strlen(str1)) { ptr += 0x10; for (j = 0; j < strlen(str2); j++) /*search the next*/ if (*(ptr + j) != *(str2 + j)) break; if (j >= strlen(str2)) {TblAddr_Ptr = ptr + 8; TblLen = *((unsigned int far *)(ptr + 6)); return 1;} } else { ptr += 0x10; } } return 0; } /*print the string in a structure specified by the number of it*/ void PrintSpecifiedStr(unsigned char far *HeadAddrOfTypeN, unsigned char length, unsigned char NumOfStr, char *HeaderOfStr) { unsigned char far *p = HeadAddrOfTypeN + length; int i = 1, j = 0; printf("%s", HeaderOfStr); if (!NumOfStr) {printf("Unknow\r\n"); return;} while (1) { while (*(p + (j++))); if (i == NumOfStr) { for (i = 0; i < j; i++) printf("%c", *(p + i)); printf("\r\n"); return; } else {i++; p += j; j = 0;} } } void main(void) { char *str1 = "_SM_"; char *str2 = "_DMI_"; unsigned int seg, offset; unsigned char far *TableAddr; unsigned char type, LenOfStructure; int i = 0, flag = 0; clrscr(); if (Search_Strs(0xF000, 0, str1, str2)) { /*get segment and offset address of SMBIOS Table*/ seg = *((unsigned int far *)(TblAddr_Ptr + 2)); seg <<= 12; offset = *((unsigned int far *)TblAddr_Ptr); TableAddr = (unsigned char far *)MK_FP(seg, offset); while (i < TblLen) { type = ((Header far *)TableAddr)->type; if (!type && !flag) { /*print Type 0*/ LenOfStructure = ((Header far *)TableAddr)->length; printf("\r\n"); printf("BIOS Information (Type 0)\r\n\r\n"); printf("Type:%d\r\n", type); printf("Length:%d\r\n", LenOfStructure); printf("Handle:%.4x\r\n", ((Header far *)TableAddr)->handle); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 4), "Vendor:"); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 5), "BIOS Version:"); printf("BIOS Starting Address Segment:%.4x\r\n", (*(unsigned int far *)(TableAddr + 6))); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 8), "BIOS Release Date:"); printf("BIOS ROM Size:%dKB\r\n", (*(TableAddr + 9) + 1) * 64); printf("BIOS Characteristics:%.8x%.8x\r\n", *((long far *)(TableAddr + 0x0e)), *((long far *)(TableAddr + 0x0a))); printf("BIOS Characterics Extension Bytes:%.4x\r\n", *((int far *)(TableAddr + 0x12))); printf("System BIOS Major Release:%d\r\n", *(TableAddr + 0x14)); printf("System BIOS Minor Release:%d\r\n", *(TableAddr + 0x15)); printf("Embedded Controller Firmware Major Release:%d\r\n", *(TableAddr + 0x16)); printf("Embedded Controller Firmware Minor Release:%d\r\n", *(TableAddr + 0x17)); flag = 1; printf("press any key to continue...\r\n"); getch(); clrscr(); } else if (type == 1) { /*print Type 1*/ LenOfStructure = ((Header far *)TableAddr)->length; printf("\r\n"); printf("System Information (Type 1)\r\n\r\n"); printf("Type:%d\r\n", type); printf("Length:%d\r\n", LenOfStructure); printf("Handle:%.4x\r\n", ((Header far *)TableAddr)->handle); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x04), "Manufacturer:"); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x05), "Product Name:"); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x06), "Version:"); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x07), "Serial Number:"); printf("UUID:%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X \r\n", *((char far *)(TableAddr + 0x08)), *((char far *)(TableAddr + 0x09)), *((char far *)(TableAddr + 0x0a)), *((char far *)(TableAddr + 0x0b)), *((char far *)(TableAddr + 0x0c)), *((char far *)(TableAddr + 0x0d)), *((char far *)(TableAddr + 0x0e)), *((char far *)(TableAddr + 0x0f)), *((char far *)(TableAddr + 0x10)), *((char far *)(TableAddr + 0x11)), *((char far *)(TableAddr + 0x12)), *((char far *)(TableAddr + 0x13)), *((char far *)(TableAddr + 0x14)), *((char far *)(TableAddr + 0x15)), *((char far *)(TableAddr + 0x16)), *((char far *)(TableAddr + 0x17)) ); printf("press any key to continue...\r\n"); getch(); clrscr(); } else if (type == 2) { /*print Type 2*/ LenOfStructure = ((Header far *)TableAddr)->length; printf("\r\n"); printf("Base Board Information (Type 2)\r\n\r\n"); printf("Type:%d\r\n", type); printf("Length:%d\r\n", LenOfStructure); printf("Handle:%.4x\r\n", ((Header far *)TableAddr)->handle); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x04), "Manufacturer:"); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x05), "Product Name:"); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x06), "Version:"); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x07), "Serial Number:"); printf("press any key to continue...\r\n"); getch(); clrscr(); } else if (type == 17) { /*print Type 17*/ LenOfStructure = ((Header far *)TableAddr)->length; printf("\r\n"); printf("Memory Device (Type 17)\r\n\r\n"); printf("Type:%d\r\n", type); printf("Length:%d\r\n", LenOfStructure); printf("Handle:%.4x\r\n", ((Header far *)TableAddr)->handle); printf("Physical Memory Array Handle:%.4x\r\n", *((int far *)(TableAddr + 4))); printf("Memory Error Information Handle:%.4x\r\n", *((int far *)(TableAddr + 6))); printf("Total Width:%d\r\n", *((int far *)(TableAddr + 8))); printf("Data Width:%d\r\n", *((int far *)(TableAddr + 10))); printf("size:%d%s\r\n", (*((int far *)(TableAddr + 0x0c)) & 0x7fff), (*((int far *)(TableAddr + 0x0c)) & 0x8000) ? "KB" : "MB"); printf("Form Factor:%d\r\n", *(TableAddr + 0x0e)); printf("Device Set:%d\r\n", *(TableAddr + 0x0f)); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x10), "Device Locator:"); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x11), "Bank Locator:"); printf("Meomroy Type:%d\r\n", *(TableAddr + 0x12)); printf("Type Detail:%.4x\r\n", *((int far *)(TableAddr + 0x13))); printf("Speed:%dMHz\r\n", *((int far *)(TableAddr + 0x15))); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x17), "Manufacturer:"); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x18), "Serial Number:"); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x19), "Asset Tag:"); PrintSpecifiedStr(TableAddr, LenOfStructure, *(TableAddr + 0x1a), "Part Number:"); printf("Attributes:%.2x\r\n", *(TableAddr + 0x1b)); getch(); break; } /*skip the unformatted string*/ TableAddr += ((Header far *)TableAddr)->length; while (*((int far *)TableAddr) != 0) TableAddr++; TableAddr += 2; i++; } } }
Sample Code 2:這個範例是透過標準的 PnP function 50h, 51h, 52h 來讀寫 DMI ,透過這方法可以讀取與寫入 DMI 資訊。
#include <stdio.h> #include <dos.h> #include <conio.h> #include <stdlib.h> #include <string.h> #include <stddef.h> typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; typedef BYTE near *PBYTE; typedef BYTE far *LPBYTE; typedef WORD near *PWORD; typedef WORD far *LPWORD; typedef DWORD near *PDWORD; typedef DWORD far *LPDWORD; typedef void near *LVOID; typedef void far *LPVOID; typedef struct { //PnP installation check data BYTE Signature[4]; // 00h "$PnP" BYTE Version; // 04h BYTE Length; // 05h WORD Control_Field; // 06h BYTE Checksum; // 08h DWORD Event_NF_Addr; // 09h Event notification flag address WORD RM_EP_Offset; // 0Dh Real Mode 16-bit offset to entry point WORD RM_EP_Segment; // 0Fh Real Mode 16-bit code segment address WORD PM_EP_Offset; // 11h 16-Bit Protected Mode offset to entry point DWORD PM_EP_Segment; // 13h 16-Bit Protected Mode code segment base address DWORD OEM_Device_ID; // 17h OEM Device Identifier WORD RM_BIOS_Data_Segment; // 1Bh Real Mode 16-bit data segment address DWORD PM_BIOS_Data_Segment; // 1Dh 16-Bit Protected Mode data segment base address } PNP_ICD; typedef short far (*entryPoint_Func50)( WORD Function, // PnP BIOS Function 50h LPBYTE dmiBIOSRevision, // Revision of the SMBIOS Extensions LPWORD NumStructures, // Max. Number of Structures the BIOS will return LPWORD StructureSize, // Size of largest SMBIOS Structure LPDWORD dmiStorageBase, // 32-bit physical base address for memory-mapped SMBIOS data LPWORD dmiStorageSize, // Size of the memory-mapped SMBIOS data WORD BiosSelector); // PnP BIOS readable/writable selector typedef short far (*entryPoint_Func51)( WORD Function, // PnP BIOS Function 51h LPWORD Structure, // Structure number/handle to retrieve LPBYTE dmiStrucBuffer, // Pointer to buffer to copy structure data WORD dmiSelector, // SMBIOS data read/write selector WORD BiosSelector); // PnP BIOS readable/writable selector typedef short far (*entryPoint_Func52)( WORD Function, // PnP BIOS Function 52h LPBYTE dmiDataBuffer, // Pointer to buffer with new/change data LPBYTE dmiWorkBuffer, // Pointer to work buffer area for the BIOS BYTE Control, // Conditions for performing operation WORD dmiSelector, // SMBIOS data read/write selector WORD BiosSelector); // PnP BIOS readable/writeable selector typedef short far (*entryPoint_Func53)( WORD Function, // PnP BIOS Function 53h LPBYTE dmiChangeStructure, // Pointer to SMBIOS Change structure WORD dmiSelector, // SMBIOS data read/write selector WORD BiosSelector); // PnP BIOS readable writable selector typedef short far (*entryPoint_Func54)( WORD Function, // PnP BIOS Function 54h WORD SubFunction, // Defines the specific control operation LPVOID *Data, // Input/output data buffer, SubFunction specific BYTE Control, // Conditions for setting the structure WORD dmiSelector, // SMBIOS data read/write selector WORD BiosSelector); // PnP BIOS readable/writeable selector typedef short far (*entryPoint_Func55)( WORD Function, // PnP BIOS Function 55h LPWORD Handle, // Identifies which GPNV to access LPWORD MinGPNVRWSize, // Minimum buffer size in bytes for GPNV access LPWORD GPNVSize, // Size allocated for GPNV within the R/W Block LPDWORD NVStorageBase, // 32-bit physical base address for... mem. mapped nonvolatile storage media WORD BiosSelector); // PnP BIOS readable/writable selector typedef short far (*entryPoint_Func56)( WORD Function, // PnP BIOS Function 56h WORD Handle, // Identifies which GPNV is to be read LPBYTE GPNVBuffer, // Address of buffer in which to return GPNV LPWORD GPNVLock, // Lock value WORD GPNVSelector, // Selector for GPNV Storage WORD BiosSelector); // PnP BIOS readable/writable selector typedef short far (*entryPoint_Func57)( WORD Function, // PnP BIOS Function 57h WORD Handle, // Identifies which GPNV is to be written LPBYTE GPNVBuffer, // Address of buffer containing complete GPNV to write WORD GPNVLock, // Lock value WORD GPNVSelector, // Selector for GPNV Storage WORD BiosSelector); // PnP BIOS readable/writable selector /** SMBIOS Structure Header - Common for all structures Describing the type, size of the fixed area, and handle of the structure. **/ typedef struct { BYTE Type; BYTE Length; WORD Handle; } SMBIOS_STRUCTURE_HEADER; /** Set SMBIOS Structure Data **/ typedef struct { BYTE Command; BYTE FieldOffset; DWORD ChangeMask; DWORD ChangeValue; WORD DataLength; SMBIOS_STRUCTURE_HEADER StructureHeader; BYTE StructureData[1]; } SET_SMBIOS_STRUCTURE_DATA; /** BIOS Information Structure (Type 0) **/ typedef struct { SMBIOS_STRUCTURE_HEADER StructureType; BYTE BiosVendor; // String number BYTE BiosVersion; // String number WORD BiosStartingAddrSegment; BYTE BiosReleaseDate; // String number BYTE BiosRomSize; DWORD BiosChar_1; DWORD BiosChar_2; BYTE BiosCharExtByte1; BYTE BiosCharExtByte2; BYTE SystemBiosMajorRelease; BYTE SystemBiosMinorRelease; BYTE ECFirmwareMajorRelease; BYTE ECFirmwareMinorRelease; } SMBIOS_BIOS_INFO; // TYPE 0 /** System Information Structure (Type 1) **/ typedef struct { SMBIOS_STRUCTURE_HEADER StructureType; BYTE Manufacturer; // String number BYTE ProductName; // String number BYTE Version; // String number BYTE SerialNumber; // String number BYTE Uuid[16]; BYTE WakeupType; BYTE SkuNumber; BYTE Family; } SMBIOS_SYSTEM_INFO; // TYPE 1 /** Base Board (or Module) Information Structure (Type 2) **/ typedef struct { SMBIOS_STRUCTURE_HEADER StructureType; BYTE Manufacturer; // String number BYTE ProductName; // String number BYTE Version; // String number BYTE SerialNumber; // String number BYTE AssetTag; // String number BYTE FeatureTag; BYTE Location; // String number WORD ChassisHandle; BYTE BoardType; BYTE NumberOfObjectHandles; } SMBIOS_BASE_BOARD_INFO; // TYPE 2 void PrintType0(SMBIOS_BIOS_INFO *type0); void PrintType1(SMBIOS_SYSTEM_INFO *type1); void PrintType2(SMBIOS_BASE_BOARD_INFO *type2); /***************************************/ /*Function:Get PnP Table /*In : struct PNP_ICD *PnPICDS /*Out: 0, No PnP Table /*Out: 1, Get PnP Table /***************************************/ int GetPnPTable(PNP_ICD *PnPICD) { LPBYTE BIOS; BIOS = (LPBYTE)MK_FP(0xf000, 0); for (DWORD i = 0; i < 0xfff0; i += 0x10) { if (BIOS[i] == '$' && BIOS[i + 1] == 'P' && BIOS[i + 2] == 'n' && BIOS[i + 3] == 'P') { for (DWORD j = 0; j <= sizeof(PNP_ICD); j++) { ((BYTE*)PnPICD)[j] = BIOS[i + j]; } return 1; } } return 0; } //return 1 if error int PrintDMI() { PNP_ICD *PnP; WORD rlt; BYTE dmiBIOSRevision; WORD NumStructures; WORD StructureSize; DWORD dmiStorageBase; WORD dmiStorageSize; WORD BiosSelector; WORD Structure; LPBYTE dmiStrucBuffer; WORD dmiSelector; PnP = (PNP_ICD *)malloc(sizeof(PNP_ICD)); if (GetPnPTable(PnP) == 0) { printf("Can't find PnP BIOS support Installation Check Data Structure.\n"); free(PnP); return 1; } printf("=========================================================\n"); printf("PnP Table\n\n"); printf("Signature: %c%c%c%c\n", PnP->Signature[0], PnP->Signature[1], PnP->Signature[2], PnP->Signature[3]); printf("Version: %02Xh\n", PnP->Version); printf("Length: %02Xh\n", PnP->Length); printf("Control Field: %04Xh\n", PnP->Control_Field); printf("Checksum: %02Xh\n", PnP->Checksum); printf("Event Notification Flag Address: %08Xh\n", PnP->Event_NF_Addr); printf("Real Mode 16-bit offset to entry point: %04Xh\n", PnP->RM_EP_Offset); printf("Real Mode 16-bit code segment address: %04Xh\n", PnP->RM_EP_Segment); printf("16-Bit Protected Mode offset to entry point: %04Xh\n", PnP->PM_EP_Offset); printf("16-Bit Protected Mode code segment base address: %08Xh\n", PnP->PM_EP_Segment); printf("OEM Device Identifier: %08Xh\n", PnP->OEM_Device_ID); printf("Real Mode 16-bit data segment address: %04Xh\n", PnP->RM_BIOS_Data_Segment); printf("16-Bit Protected Mode data segment base address: %08Xh\n", PnP->PM_BIOS_Data_Segment); printf("=========================================================\n\n"); getch(); BiosSelector = PnP->RM_BIOS_Data_Segment; entryPoint_Func50 Func50 = (entryPoint_Func50)MK_FP(PnP->RM_EP_Segment,PnP->RM_EP_Offset); entryPoint_Func51 Func51 = (entryPoint_Func51)MK_FP(PnP->RM_EP_Segment,PnP->RM_EP_Offset); rlt = Func50(0x50, &dmiBIOSRevision, &NumStructures, &StructureSize, &dmiStorageBase, &dmiStorageSize, BiosSelector ); if (rlt != 0x00) { printf("ERROR: %02Xh\n", rlt); exit(1); free(PnP); return 1; } printf("=========================================================\n"); printf("Function 50h: Get SMBIOS Information\n\n"); printf("Revision of the SMBIOS Extensions: %02Xh \n", dmiBIOSRevision); printf("Max. Number of Structures the BIOS will return: %04Xh \n", NumStructures); printf("Size of largest SMBIOS Structure: %04Xh \n", StructureSize); printf("32-bit physical base address for memory-mapped SMBIOS data: %08Xh \n", dmiStorageBase); printf("Size of the memory-mapped SMBIOS data: %04Xh \n", dmiStorageSize); printf("PnP BIOS readable/writable selector: %04Xh \n", BiosSelector); printf("=========================================================\n\n"); getch(); dmiSelector = (WORD)(dmiStorageBase >> 4); dmiStrucBuffer = (LPBYTE)malloc(sizeof(BYTE) * (StructureSize)); //If Structure contains zero, the system BIOS will return the first SMBIOS Structure. Structure = 0; while ((Structure) != 0xffff) { rlt = Func51( 0x51, &Structure, dmiStrucBuffer, dmiSelector, BiosSelector ); if (rlt != 0) { printf("ERROR: %02Xh\n", rlt); exit(1); free(PnP); free((void *)dmiStrucBuffer); return 1; } switch (((SMBIOS_STRUCTURE_HEADER*)dmiStrucBuffer)->Type) { case 0: //type 0 PrintType0((SMBIOS_BIOS_INFO*)dmiStrucBuffer); getch(); break; case 1: //type 1 PrintType1((SMBIOS_SYSTEM_INFO*)dmiStrucBuffer); getch(); break; case 2: //type 2 PrintType2((SMBIOS_BASE_BOARD_INFO*)dmiStrucBuffer); getch(); break; } } free(PnP); free((void *)dmiStrucBuffer); return 0; } int UpdateDMI() { PNP_ICD *PnP; WORD rlt; BYTE dmiBIOSRevision; WORD NumStructures; WORD StructureSize; DWORD dmiStorageBase; WORD dmiStorageSize; WORD BiosSelector; WORD Structure; LPBYTE dmiStrucBuffer; WORD dmiSelector; PnP = (PNP_ICD *)malloc(sizeof(PNP_ICD)); if (GetPnPTable(PnP) == 0) { printf("Can't find PnP BIOS support Installation Check Data Structure.\n"); free(PnP); return 1; } BiosSelector = PnP->RM_BIOS_Data_Segment; entryPoint_Func50 Func50 = (entryPoint_Func50)MK_FP(PnP->RM_EP_Segment,PnP->RM_EP_Offset); entryPoint_Func51 Func51 = (entryPoint_Func51)MK_FP(PnP->RM_EP_Segment,PnP->RM_EP_Offset); entryPoint_Func52 Func52 = (entryPoint_Func52)MK_FP(PnP->RM_EP_Segment,PnP->RM_EP_Offset); rlt = Func50(0x50, &dmiBIOSRevision, &NumStructures, &StructureSize, &dmiStorageBase, &dmiStorageSize, BiosSelector ); if (rlt != 0x00) { printf("ERROR: %02Xh\n", rlt); exit(1); free(PnP); return 1; } dmiSelector = (WORD)(dmiStorageBase >> 4); dmiStrucBuffer = (LPBYTE)malloc(sizeof(BYTE) * (StructureSize)); //If Structure contains zero, the system BIOS will return the first SMBIOS Structure. Structure = 0; while ((Structure) != 0xffff) { rlt = Func51( 0x51, &Structure, dmiStrucBuffer, dmiSelector, BiosSelector ); if (rlt != 0) { printf("ERROR: %02Xh\n", rlt); exit(1); free(PnP); free((void *)dmiStrucBuffer); return 1; } switch (((SMBIOS_STRUCTURE_HEADER*)dmiStrucBuffer)->Type) { case 1: //type 1 SET_SMBIOS_STRUCTURE_DATA *newData; printf("Wirte new TYPE1 UUID: 99887766 55443322 11001122 33445566\n"); printf("Press 'y' to Write\n"); if (getch() == 'y') { //Update Type 1 UUID BYTE NewUUID[16] = { 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; newData = (SET_SMBIOS_STRUCTURE_DATA *)malloc(sizeof(SET_SMBIOS_STRUCTURE_DATA) + 16); newData->Command = 0x06; //a block of information newData->FieldOffset = offsetof(SMBIOS_SYSTEM_INFO, Uuid); newData->ChangeMask = 0; newData->ChangeValue = 0; newData->DataLength = 16; newData->StructureHeader.Type = ((SMBIOS_SYSTEM_INFO *)dmiStrucBuffer)->StructureType.Type; newData->StructureHeader.Handle = ((SMBIOS_SYSTEM_INFO *)dmiStrucBuffer)->StructureType.Handle; newData->StructureHeader.Length = ((SMBIOS_SYSTEM_INFO *)dmiStrucBuffer)->StructureType.Length; for (int i = 0; i < 16; i++) { newData->StructureData[i] = NewUUID[i]; } rlt = Func52(0x52, (LPBYTE)newData, dmiStrucBuffer, 1, dmiSelector, BiosSelector); if (rlt != 0) { printf("ERROR: %02Xh\n", rlt); exit(1); free(newData); free(PnP); free((void *)dmiStrucBuffer); return 1; } else { printf("Success !!\n\n"); } free(newData); } else { printf("Cancel !!\n\n"); } //Update Type 1 Manufacturer string printf("Wirte new TYPE1 Manufacturer: \"New Manufacturer\"\n"); printf("Press 'y' to Write\n"); if (getch() == 'y') { WORD StringNumber = ((SMBIOS_SYSTEM_INFO *)dmiStrucBuffer)->Manufacturer + 3; BYTE NewManufacturer[] = "New Manufacturer"; WORD strLength = strlen(NewManufacturer); newData = (SET_SMBIOS_STRUCTURE_DATA *)malloc(sizeof(SET_SMBIOS_STRUCTURE_DATA) + strLength); newData->Command = 0x05; //a string value is to be changed newData->FieldOffset = StringNumber; newData->ChangeMask = 0; newData->ChangeValue = 0; newData->DataLength = strLength+1; newData->StructureHeader.Type = ((SMBIOS_SYSTEM_INFO *)dmiStrucBuffer)->StructureType.Type; newData->StructureHeader.Handle = ((SMBIOS_SYSTEM_INFO *)dmiStrucBuffer)->StructureType.Handle; newData->StructureHeader.Length = ((SMBIOS_SYSTEM_INFO *)dmiStrucBuffer)->StructureType.Length; strcpy((char*)newData->StructureData, (char*)NewManufacturer); rlt = Func52(0x52, (LPBYTE)newData, dmiStrucBuffer, 1, dmiSelector, BiosSelector); if (rlt != 0) { printf("ERROR: %02Xh\n", rlt); exit(1); free(newData); free(PnP); free((void *)dmiStrucBuffer); return 1; } else { printf("Success !!\n\n"); } free(newData); } else { printf("Cancel !!\n\n"); } break; } } free(PnP); free((void *)dmiStrucBuffer); return 0; } LPBYTE GetStrPtr(LPBYTE typeN, BYTE StirngNumber) { LPBYTE p = typeN + ((SMBIOS_STRUCTURE_HEADER*)typeN)->Length; int strNum = 1, j = 0; if (StirngNumber) { while (1) { while (*(p + (j++))); if (strNum == StirngNumber) { return p; } else { strNum++; p += j; j = 0; } } } return NULL; } void PrintType0(SMBIOS_BIOS_INFO *type0) { printf("=========================================================\n"); printf("Type 0: BIOS Information\n\n"); printf("Bios Vendor: \"%s\" \n", GetStrPtr((LPBYTE)type0, type0->BiosVendor)); printf("Bios Version: \"%s\" \n", GetStrPtr((LPBYTE)type0, type0->BiosVersion)); printf("Bios Release Date: \"%s\" \n", GetStrPtr((LPBYTE)type0, type0->BiosReleaseDate)); printf("BIOS ROM Size: %dK \n", (type0->BiosRomSize+1)*64); printf("=========================================================\n\n"); } void PrintType1(SMBIOS_SYSTEM_INFO *type1) { printf("=========================================================\n"); printf("Type 1: System Information\n\n"); printf("Manufacturer: \"%s\" \n", GetStrPtr((LPBYTE)type1, type1->Manufacturer)); printf("ProductName: \"%s\" \n", GetStrPtr((LPBYTE)type1, type1->ProductName)); printf("Version: \"%s\" \n", GetStrPtr((LPBYTE)type1, type1->Version)); printf("SerialNumber: \"%s\" \n", GetStrPtr((LPBYTE)type1, type1->SerialNumber)); printf("UUID: %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X \n", type1->Uuid[0], type1->Uuid[1], type1->Uuid[2], type1->Uuid[3], type1->Uuid[4], type1->Uuid[5], type1->Uuid[6], type1->Uuid[7], type1->Uuid[8], type1->Uuid[9], type1->Uuid[10], type1->Uuid[11], type1->Uuid[12], type1->Uuid[13], type1->Uuid[14], type1->Uuid[15]); printf("=========================================================\n\n"); } void PrintType2(SMBIOS_BASE_BOARD_INFO *type2) { printf("=========================================================\n"); printf("Type 2: Base Board Information\n\n"); printf("Manufacturer: \"%s\" \n", GetStrPtr((LPBYTE)type2, type2->Manufacturer)); printf("ProductName: \"%s\" \n", GetStrPtr((LPBYTE)type2, type2->ProductName)); printf("Version: \"%s\" \n", GetStrPtr((LPBYTE)type2, type2->Version)); printf("SerialNumber: \"%s\" \n", GetStrPtr((LPBYTE)type2, type2->SerialNumber)); printf("=========================================================\n\n"); } void main(void) { //Show DMI type0, type1, type2 information PrintDMI(); //Update DMI type1 UUID and Manfacturer UpdateDMI(); }
參考資料:Plug and Play BIOS Specification、System Management BIOS
Reference Specification