UPDATE : If you want access the SMBIOS using Delphi or Free Pascal try the TSMBIOS project.
The system management BIOS (SMBIOS) is a specification of how the system vendors present management information about their products in a standard format, so you can use the SMBIOS to discover information about the hardware platform, such as the system manufacturer, the system BIOS version, processor installed characteristics and so on. From windows you can acceess the SMBIOS tables using the WMI or the WinApi. In this article I will show how you can gain access to the SMBios tables using the WMI and Delphi.
The SMBIOS Tables
The tables are located directly adjacent to each other in memory. Each table is composed of a 4-byte header, a specific structure , and an optional string table.
Header
This is the header description of each table
The type field present in the header define how each table must be interpreted, this is a list of a few table types
- BIOS Information (Type 0)
- System Information (Type 1)
- System Enclosure (Type 3)
- Processor Information (Type 4)
- Cache Information (Type 7)
- System Slots (Type 9)
- Physical Memory Array (Type 16)
- Memory Device (Type 17)
- Memory Array Mapped Address (Type 19)
- System Boot Information (Type 32)
Text Strings
The text strings associated with a given SMBIOS table are appended directly after the formatted portion of the structure. Each string is terminated with a null (00h) BYTE and the set of strings is terminated with an additional null (00h) BYTE. When the formatted portion of a SMBIOS structure references a string, it does so by specifying a non-zero string number within the structure’s string-set. For example, if a string field contains 02h, it references the second string following the formatted portion of the SMBIOS structure. If a string field references no string, a null (0) is placed in that string field.
Check the next representation of a BIOS Table (Type
db 0 ; Indicates BIOS Structure Type | db 13h ; Length of information in bytes | Header of the table dw ? ; Reserved for handle | db 01h ; String 1 is the Vendor Name | db 02h ; String 2 is the BIOS version | dw 0E800h ; BIOS Starting Address | db 03h ; String 3 is the BIOS Build Date | formatted portion db 1 ; Size of BIOS ROM is 128K (64K * (1 + 1)) | dq BIOS_Char ; BIOS Characteristics | db 0 ; BIOS Characteristics Extension Byte 1 | db ‘System BIOS Vendor Name’,0 ; | db ‘4.04’,0 ; | Text Strings (unformatted portion) db ‘00/00/0000’,0 ; | db 0 ; End of structure
WMI
Now which you know the basics about the SMBios table structures, you need a way to retrieve such tables. the WMI provides a way to get the raw SMBIOS data in a single buffer using the class MSSmBios_RawSMBiosTables this class is in the root\WMI namespace and is available since Windows XP.
Check this small snippet to retrieve the SMBios tables buffer contained in the SMBiosData property
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; vArray : variant; Value : integer; i : integer; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); //connect to the Wmi service FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\WMI', '', ''); //execute the WQL sentence FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM MSSmBios_RawSMBiosTables', 'WQL', wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumvariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin //store the size of the buffer FSize := FWbemObject.Size; GetMem(FBuffer, FSize); //get the addtional properties like the SMBIos version FDmiRevision:= FWbemObject.DmiRevision; FSmbiosMajorVersion :=FWbemObject.SmbiosMajorVersion; FSmbiosMinorVersion :=FWbemObject.SmbiosMinorVersion; //get the buffer of the SMBios tables vArray := FWbemObject.SMBiosData; FWbemObject := Unassigned; end; end;
Delphi
From the Delphi side we need to create a few structures to hold the data of the tables and write some helper functions to parse the information.
type // http://www.dmtf.org/standards/smbios SMBiosTables = ( BIOSInformation = 0, SystemInformation = 1, BaseBoardInformation = 2, EnclosureInformation = 3, ProcessorInformation = 4, MemoryControllerInformation = 5, MemoryModuleInformation = 6, CacheInformation = 7, PortConnectorInformation = 8, SystemSlotsInformation = 9, OnBoardDevicesInformation = 10, OEMStrings = 11, SystemConfigurationOptions = 12, BIOSLanguageInformation = 13, GroupAssociations = 14, SystemEventLog = 15, PhysicalMemoryArray = 16, MemoryDevice = 17, MemoryErrorInformation = 18, MemoryArrayMappedAddress = 19, MemoryDeviceMappedAddress = 20, EndofTable = 127); //for more tables check the official specifications http://www.dmtf.org/standards/smbios //the header of each SMBios table TSmBiosTableHeader = packed record TableType: Byte; Length: Byte; Handle: Word; end; //this is a helper record to store the header and index of each table stored in the buffer TSMBiosTableEntry = record Header: TSmBiosTableHeader; Index : Integer; end; //this is the record to store Bios information about the table Type 0 TBiosInfo = packed record Header: TSmBiosTableHeader; Vendor: Byte; Version: Byte; StartingSegment: Word; ReleaseDate: Byte; BiosRomSize: Byte; Characteristics: Int64; ExtensionBytes : array [0..1] of Byte; end;
The next code show how you can parse the buffer with the raw data and fill a Generic TList of TSMBiosTableEntry records.
function GetSMBiosTablesList(Buffer : PByteArray): TList; Var Index : integer; Header: TSmBiosTableHeader; Entry : TSMBiosTableEntry; begin Result := TList.Create; Index := 0; repeat //read the header Move(Buffer[Index], Header, SizeOf(Header)); Entry.Header:=Header; Entry.Index:=Index; //add to the list Result.Add(Entry); //check if the tale type is 127 (end of tables) if Header.TableType=Ord(SMBiosTables.EndofTable) then break; //increase the Index in the length of the formatted data inc(Index, Header.Length); //Text strings zone //check for the boundaries of the buffer if Index+1>FSize then Break; //check for $00 $00 -> table termination while not((Buffer[Index] = 0) and (Buffer[Index + 1] = 0)) do if Index+1>FSize then Break else inc(Index); inc(Index, 2); until (Index>FSize); end;
Now to retrieve a text string from a SMBios table
//the Entry Parameter is the buffer to the unformatted data //The index is the number of the text string to retrieve function GetSMBiosString(Entry, Index: integer): AnsiString; var i: integer; p: PAnsiChar; begin Result := ''; for i := 1 to Index do begin p := PAnsiChar(@Buffer[Entry]); if i = Index then begin Result := p; break; end else inc(Entry, StrLen(p) + 1); end; end;
A unit to retrieve the Smbios tables
Here I leave a unit to retrieve and parse the SMBios tables, the unit does not cover all the tables types (you can read the official specification)
//Author Rodrigo Ruz V. //2011-08-01 unit uSMBIOS; interface uses SysUtils, Windows, Generics.Collections, Classes; type // http://www.dmtf.org/standards/smbios SMBiosTables = ( BIOSInformation = 0, SystemInformation = 1, BaseBoardInformation = 2, EnclosureInformation = 3, ProcessorInformation = 4, MemoryControllerInformation = 5, MemoryModuleInformation = 6, CacheInformation = 7, PortConnectorInformation = 8, SystemSlotsInformation = 9, OnBoardDevicesInformation = 10, OEMStrings = 11, SystemConfigurationOptions = 12, BIOSLanguageInformation = 13, GroupAssociations = 14, SystemEventLog = 15, PhysicalMemoryArray = 16, MemoryDevice = 17, MemoryErrorInformation = 18, MemoryArrayMappedAddress = 19, MemoryDeviceMappedAddress = 20, EndofTable = 127); TSmBiosTableHeader = packed record TableType: Byte; Length: Byte; Handle: Word; end; TBiosInfo = packed record Header: TSmBiosTableHeader; Vendor: Byte; Version: Byte; StartingSegment: Word; ReleaseDate: Byte; BiosRomSize: Byte; Characteristics: Int64; ExtensionBytes : array [0..1] of Byte; end; TSysInfo = packed record Header: TSmBiosTableHeader; Manufacturer: Byte; ProductName: Byte; Version: Byte; SerialNumber: Byte; UUID: array [0 .. 15] of Byte; WakeUpType: Byte; end; TBaseBoardInfo = packed record Header: TSmBiosTableHeader; Manufacturer: Byte; Product: Byte; Version: Byte; SerialNumber: Byte; end; TEnclosureInfo = packed record Header: TSmBiosTableHeader; Manufacturer: Byte; &Type: Byte; Version: Byte; SerialNumber: Byte; AssetTagNumber: Byte; BootUpState: Byte; PowerSupplyState: Byte; ThermalState: Byte; SecurityStatus: Byte; OEM_Defined: DWORD; end; TProcessorInfo = packed record Header: TSmBiosTableHeader; SocketDesignation: Byte; ProcessorType: Byte; ProcessorFamily: Byte; ProcessorManufacturer: Byte; ProcessorID: Int64; // QWORD; ProcessorVersion: Byte; Voltaje: Byte; ExternalClock: Word; MaxSpeed: Word; CurrentSpeed: Word; Status: Byte; ProcessorUpgrade: Byte; L1CacheHandler: Word; L2CacheHandler: Word; L3CacheHandler: Word; SerialNumber: Byte; AssetTag: Byte; PartNumber: Byte; end; TCacheInfo = packed record Header: TSmBiosTableHeader; SocketDesignation: Byte; CacheConfiguration: DWORD; MaximumCacheSize: Word; InstalledSize: Word; SupportedSRAMType: Word; CurrentSRAMType: Word; CacheSpeed: Byte; ErrorCorrectionType: Byte; SystemCacheType: Byte; Associativity: Byte; end; TSMBiosTableEntry = record Header: TSmBiosTableHeader; Index : Integer; end; TSMBios = class private FSize: integer; FBuffer: PByteArray; FDataString: AnsiString; FBiosInfo: TBiosInfo; FSysInfo: TSysInfo; FBaseBoardInfo: TBaseBoardInfo; FEnclosureInfo: TEnclosureInfo; FProcessorInfo: TProcessorInfo; FBiosInfoIndex: Integer; FSysInfoIndex: Integer; FBaseBoardInfoIndex: Integer; FEnclosureInfoIndex: Integer; FProcessorInfoIndex: Integer; FDmiRevision: Integer; FSmbiosMajorVersion: Integer; FSmbiosMinorVersion: Integer; FSMBiosTablesList: TList; procedure LoadSMBIOS; procedure ReadSMBiosTables; function GetHasBiosInfo: Boolean; function GetHasSysInfo: Boolean; function GetHasBaseBoardInfo: Boolean; function GetHasEnclosureInfo: Boolean; function GetHasProcessorInfo: Boolean; function GetSMBiosTablesList:TList; public constructor Create; destructor Destroy; override; function SearchSMBiosTable(TableType: SMBiosTables): integer; function GetSMBiosTableIndex(TableType: SMBiosTables): integer; function GetSMBiosString(Entry, Index: integer): AnsiString; property Size: integer read FSize; property Buffer: PByteArray read FBuffer; property DataString: AnsiString read FDataString; property DmiRevision: Integer read FDmiRevision; property SmbiosMajorVersion : Integer read FSmbiosMajorVersion; property SmbiosMinorVersion : Integer read FSmbiosMinorVersion; property SMBiosTablesList : TList read FSMBiosTablesList; property BiosInfo: TBiosInfo read FBiosInfo Write FBiosInfo; property BiosInfoIndex: Integer read FBiosInfoIndex Write FBiosInfoIndex; property HasBiosInfo : Boolean read GetHasBiosInfo; property SysInfo: TSysInfo read FSysInfo Write FSysInfo; property SysInfoIndex: Integer read FSysInfoIndex Write FSysInfoIndex; property HasSysInfo : Boolean read GetHasSysInfo; property BaseBoardInfo: TBaseBoardInfo read FBaseBoardInfo write FBaseBoardInfo; property BaseBoardInfoIndex: Integer read FBaseBoardInfoIndex Write FBaseBoardInfoIndex; property HasBaseBoardInfo : Boolean read GetHasBaseBoardInfo; property EnclosureInfo: TEnclosureInfo read FEnclosureInfo write FEnclosureInfo; property EnclosureInfoIndex: Integer read FEnclosureInfoIndex Write FEnclosureInfoIndex; property HasEnclosureInfo : Boolean read GetHasEnclosureInfo; property ProcessorInfo: TProcessorInfo read FProcessorInfo write FProcessorInfo; property ProcessorInfoIndex: Integer read FProcessorInfoIndex Write FProcessorInfoIndex; property HasProcessorInfo : Boolean read GetHasProcessorInfo; end; implementation uses ComObj, ActiveX, Variants; { TSMBios } constructor TSMBios.Create; begin Inherited; FBuffer := nil; FSMBiosTablesList:=nil; LoadSMBIOS; ReadSMBiosTables; end; destructor TSMBios.Destroy; begin if Assigned(FBuffer) and (FSize > 0) then FreeMem(FBuffer); if Assigned(FSMBiosTablesList) then FSMBiosTablesList.Free; Inherited; end; function TSMBios.GetHasBaseBoardInfo: Boolean; begin Result:=FBaseBoardInfoIndex>=0; end; function TSMBios.GetHasBiosInfo: Boolean; begin Result:=FBiosInfoIndex>=0; end; function TSMBios.GetHasEnclosureInfo: Boolean; begin Result:=FEnclosureInfoIndex>=0; end; function TSMBios.GetHasProcessorInfo: Boolean; begin Result:=FProcessorInfoIndex>=0; end; function TSMBios.GetHasSysInfo: Boolean; begin Result:=FSysInfoIndex>=0; end; function TSMBios.SearchSMBiosTable(TableType: SMBiosTables): integer; Var Index : integer; Header : TSmBiosTableHeader; begin Index := 0; repeat Move(Buffer[Index], Header, SizeOf(Header)); if Header.TableType = Ord(TableType) then break else begin inc(Index, Header.Length); if Index+1>FSize then begin Index:=-1; Break; end; while not((Buffer[Index] = 0) and (Buffer[Index + 1] = 0)) do if Index+1>FSize then begin Index:=-1; Break; end else inc(Index); inc(Index, 2); end; until (Index>FSize); Result := Index; end; function TSMBios.GetSMBiosString(Entry, Index: integer): AnsiString; var i: integer; p: PAnsiChar; begin Result := ''; for i := 1 to Index do begin p := PAnsiChar(@Buffer[Entry]); if i = Index then begin Result := p; break; end else inc(Entry, StrLen(p) + 1); end; end; function TSMBios.GetSMBiosTableIndex(TableType: SMBiosTables): integer; Var Entry : TSMBiosTableEntry; begin Result:=-1; for Entry in FSMBiosTablesList do if Entry.Header.TableType=Ord(TableType) then begin Result:=Entry.Index; Break; end; end; function TSMBios.GetSMBiosTablesList: TList; Var Index : integer; Header: TSmBiosTableHeader; Entry : TSMBiosTableEntry; begin Result := TList.Create; Index := 0; repeat Move(Buffer[Index], Header, SizeOf(Header)); Entry.Header:=Header; Entry.Index:=Index; Result.Add(Entry); if Header.TableType=Ord(SMBiosTables.EndofTable) then break; inc(Index, Header.Length);// + 1); if Index+1>FSize then Break; while not((Buffer[Index] = 0) and (Buffer[Index + 1] = 0)) do if Index+1>FSize then Break else inc(Index); inc(Index, 2); until (Index>FSize); end; procedure TSMBios.LoadSMBIOS; const wbemFlagForwardOnly = $00000020; var FSWbemLocator: OLEVariant; FWMIService: OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject: OLEVariant; oEnum: IEnumvariant; iValue: LongWord; vArray: variant; Value: integer; i: integer; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\WMI', '', ''); FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM MSSmBios_RawSMBiosTables', 'WQL', wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumvariant; if oEnum.Next(1, FWbemObject, iValue) = 0 then begin FSize := FWbemObject.Size; GetMem(FBuffer, FSize); FDmiRevision:= FWbemObject.DmiRevision; FSmbiosMajorVersion :=FWbemObject.SmbiosMajorVersion; FSmbiosMinorVersion :=FWbemObject.SmbiosMinorVersion; vArray := FWbemObject.SMBiosData; if (VarType(vArray) and VarArray) <> 0 then for i := VarArrayLowBound(vArray, 1) to VarArrayHighBound(vArray, 1) do begin Value := vArray[i]; Buffer[i] := Value; if Value in [$20..$7E] then FDataString := FDataString + AnsiString(Chr(Value)) else FDataString := FDataString + '.'; end; FSMBiosTablesList:=GetSMBiosTablesList; FWbemObject := Unassigned; end; end; procedure TSMBios.ReadSMBiosTables; begin FBiosInfoIndex := GetSMBiosTableIndex(BIOSInformation); if FBiosInfoIndex >= 0 then Move(Buffer[FBiosInfoIndex], FBiosInfo, SizeOf(FBiosInfo)); FSysInfoIndex := GetSMBiosTableIndex(SystemInformation); if FSysInfoIndex >= 0 then Move(Buffer[FSysInfoIndex], FSysInfo, SizeOf(FSysInfo)); FBaseBoardInfoIndex := GetSMBiosTableIndex(BaseBoardInformation); if FBaseBoardInfoIndex >= 0 then Move(Buffer[FBaseBoardInfoIndex], FBaseBoardInfo, SizeOf(FBaseBoardInfo)); FEnclosureInfoIndex := GetSMBiosTableIndex(EnclosureInformation); if FEnclosureInfoIndex >= 0 then Move(Buffer[FEnclosureInfoIndex], FEnclosureInfo, SizeOf(FEnclosureInfo)); FProcessorInfoIndex := GetSMBiosTableIndex(ProcessorInformation); if FProcessorInfoIndex >= 0 then Move(Buffer[FProcessorInfoIndex], FProcessorInfo, SizeOf(FProcessorInfo)); end; end.
Sample project
This console application show how use this unit
{$APPTYPE CONSOLE} uses Classes, SysUtils, ActiveX, ComObj, uSMBIOS in 'uSMBIOS.pas'; procedure GetMSSmBios_RawSMBiosTablesInfo; Var SMBios : TSMBios; UUID : Array[0..31] of Char; Entry : TSMBiosTableEntry; begin SMBios:=TSMBios.Create; try With SMBios do begin Writeln(Format('%d SMBios tables found',[SMBiosTablesList.Count])); Writeln(''); Writeln('Type Handle Length Index'); for Entry in SMBiosTablesList do Writeln(Format('%3d %4x %3d %4d',[Entry.Header.TableType, Entry.Header.Handle, Entry.Header.Length, Entry.Index])); Readln; if HasBiosInfo then begin WriteLn('Bios Information'); WriteLn('Vendor '+GetSMBiosString(BiosInfoIndex + BiosInfo.Header.Length, BiosInfo.Vendor)); WriteLn('Version '+GetSMBiosString(BiosInfoIndex + BiosInfo.Header.Length, BiosInfo.Version)); WriteLn('Start Segment '+IntToHex(BiosInfo.StartingSegment,4)); WriteLn('ReleaseDate '+GetSMBiosString(BiosInfoIndex + BiosInfo.Header.Length, BiosInfo.ReleaseDate)); WriteLn(Format('Bios Rom Size %d k',[64*(BiosInfo.BiosRomSize+1)])); WriteLn(''); end; if HasSysInfo then begin WriteLn('System Information'); WriteLn('Manufacter '+GetSMBiosString(SysInfoIndex + SysInfo.Header.Length, SysInfo.Manufacturer)); WriteLn('Product Name '+GetSMBiosString(SysInfoIndex + SysInfo.Header.Length, SysInfo.ProductName)); WriteLn('Version '+GetSMBiosString(SysInfoIndex + SysInfo.Header.Length, SysInfo.Version)); WriteLn('Serial Number '+GetSMBiosString(SysInfoIndex + SysInfo.Header.Length, SysInfo.SerialNumber)); BinToHex(@SysInfo.UUID,UUID,SizeOf(SysInfo.UUID)); WriteLn('UUID '+UUID); WriteLn(''); end; if HasBaseBoardInfo then begin WriteLn('BaseBoard Information'); WriteLn('Manufacter '+GetSMBiosString(BaseBoardInfoIndex + BaseBoardInfo.Header.Length, BaseBoardInfo.Manufacturer)); WriteLn('Product '+GetSMBiosString(BaseBoardInfoIndex + BaseBoardInfo.Header.Length, BaseBoardInfo.Product)); WriteLn('Version '+GetSMBiosString(BaseBoardInfoIndex + BaseBoardInfo.Header.Length, BaseBoardInfo.Version)); WriteLn('Serial Number '+GetSMBiosString(BaseBoardInfoIndex + BaseBoardInfo.Header.Length, BaseBoardInfo.SerialNumber)); WriteLn(''); end; if HasEnclosureInfo then begin WriteLn('Enclosure Information'); WriteLn('Manufacter '+GetSMBiosString(EnclosureInfoIndex + EnclosureInfo.Header.Length, EnclosureInfo.Manufacturer)); WriteLn('Version '+GetSMBiosString(EnclosureInfoIndex + EnclosureInfo.Header.Length, EnclosureInfo.Version)); WriteLn('Serial Number '+GetSMBiosString(EnclosureInfoIndex + EnclosureInfo.Header.Length, EnclosureInfo.SerialNumber)); WriteLn('Asset Tag Number '+GetSMBiosString(EnclosureInfoIndex + EnclosureInfo.Header.Length, EnclosureInfo.AssetTagNumber)); WriteLn(''); end; if HasProcessorInfo then begin WriteLn('Processor Information'); WriteLn('Socket Designation '+GetSMBiosString(ProcessorInfoIndex + ProcessorInfo.Header.Length, ProcessorInfo.SocketDesignation)); WriteLn('Processor Manufacturer '+GetSMBiosString(ProcessorInfoIndex + ProcessorInfo.Header.Length, ProcessorInfo.ProcessorManufacturer)); WriteLn('Serial Number '+GetSMBiosString(ProcessorInfoIndex + ProcessorInfo.Header.Length, ProcessorInfo.SerialNumber)); WriteLn('Asset Tag '+GetSMBiosString(ProcessorInfoIndex + ProcessorInfo.Header.Length, ProcessorInfo.AssetTag)); WriteLn('Part Number '+GetSMBiosString(ProcessorInfoIndex + ProcessorInfo.Header.Length, ProcessorInfo.PartNumber)); WriteLn(''); end; end; finally SMBios.Free; end; end; begin try CoInitialize(nil); try GetMSSmBios_RawSMBiosTablesInfo; finally CoUninitialize; end; except on E:EOleException do Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode])); on E:Exception do Writeln(E.Classname, ':', E.Message); end; Writeln('Press Enter to exit'); Readln; end.
Check these samples images of the console App.
Additional Information
Check the next resources to get more info about the SMBios
- System Management BIOS DMTF Specification
- SMBIOS Demystified (C++ article to parse and show the raw data of the SMBios tables)
- SMBIOS Support in Windows
- GetSystemFirmwareTable
- EnumSystemFirmwareTables
August 3, 2011 at 12:11 am
Very nice. I haven’t been fiddling with hardware for a long time. Reminds me of DOS era :)
August 3, 2011 at 12:21 am
François, while I wrote this article had the same memories..like reading the Bios and CMOS memory using Turbo Pascal – those were good times :)
August 3, 2011 at 2:59 am
Hi. This is just something for me right now. Unfortunately I have great difficulties reading grey characters on black background. Hope what is written there are just examples on output.
August 3, 2011 at 3:09 am
Sorry for that, the images only shows the output of the app, so don’t worry. for that.
August 4, 2011 at 7:35 pm
wow THIS VERY AWESOME!!! thanks Rodrigo, really love ur article.
August 7, 2011 at 8:48 am
Rodrigo: I give you 5* thumbs, all of your tutorial article are very clear and detail. Thanks a lot. God bless you.
regards
August 18, 2011 at 8:17 am
Great article, old solution with whole bios dump not working anymore.
Delphi 7 is not support generic (Generics.Collections). Is it there a workaround for delphi 7.
Thank you.
August 18, 2011 at 9:25 am
In Delphi 7, you can replace the generics with a TList or an dynamic array,
August 20, 2011 at 2:18 pm
I am successfully modified unit “uSMBIOS” for Delphi 7 using dynamic array like you suggested.
Thank you once more.
August 20, 2011 at 2:26 pm
You are welcome, glad to help you
June 30, 2012 at 4:11 am
ivica,
I also have Delphi 7. I really don’t understand Generics.Collections and stuff like that.
Could you be so kind as to share your Delphi 7 version of this code?
I am sure I am not alone :)
August 9, 2012 at 12:09 pm
Leave your email and i will send you working example for D7.
August 17, 2012 at 8:21 am
ivica, could you share modified code for delphi7… (oztruva@gmail.com)
August 20, 2011 at 4:12 am
Thank you for this posting, i am currently using your code to write a reader for all the tables, hopefully i can share it with you when it’s complete
September 16, 2011 at 4:38 pm
It was failed to compiled using Lazarus.. :(
Would you mind to make it works to compile using Lazarus too??
I’m newbie.. But I want to use your Unit for my knowledge..
Thank You,
Onix Tan.
January 8, 2012 at 10:40 pm
Thanks very much for sharing your knowledge and Delphi code, it saved me alot of work.
Pingback: SMBios: BiosHelp geht nicht - Delphi-PRAXiS
July 9, 2012 at 7:13 am
Thanks for this excellent example. I’ve been trying to get some of the numeric values out of SMBIOS, like L1 Cache Handle which is a WORD value. In my tests L1, L2 and L3 contain 770, 772 and 771 respectively. I think this might be pointing to these values in a similar way to the way strings are handled in SMBIOS because clearly these aren’t proper values. This is different to CoreCount which has the correct value when I load the the buffer into the ProcessorInfo. Try as I might, I cannot seem to get it to reference correctly and return decent values. Could I ask if you have found a way to do this? I’m wondering if you might have a GetSMBIOSWord equivalent?
July 9, 2012 at 10:32 am
Riichard, these fileds store the handles of the cache structure table (type 7), you must decode this table using the SMBIOS spec http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf and then compare the handle values.
Pingback: SMBios Ungenauigkeiten? - Delphi-PRAXiS