Subject |
Re: Computer serial number |
From |
Marc VdB <dbase@dbase.de> |
Date |
Sun, 21 Apr 2024 18:46:39 +0200 |
Newsgroups |
dbase.getting-started |
Attachment(s) |
getbiosdata.cc |
Thanks for the data, Mervyn. It shows a hack of a bending of the
specifications but is still conform :-)
And makes my previous code buggy.
Please try the revised version (1.2)
KR
>
> My pleasure. BIOS.TXT is attached.
>
> Mervyn.
| /****************************************************************************
Version 1.0 - Marc VdB 20-04-2024 (get_serial)
Version 1.1 21-04-2024 (showall)
Version 1.2 21-04-2024 Bugfix for Mervyns old BIOS :-)
(ok, the bug could have appeared in any BIOS)
Class to retrieve Bios data.
For now, it extracts only the serial number of the Bios (if there is one,
some of the older Bioses don't have one, in this case ERROR is returned)
Notes: The specification of the Bios-Table-Data can be found here:
https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.3.0.pdf
with the specs, one could add more methods like : get_biosdate() if needed
Dependencies: None
Example of use: set proc to getbiosdata.cc
o = new BiosData()
cserial = o.get_serial()
*****************************************************************************/
Class BiosData
this.serial = "Not defined"
this.smblen = 0
this.smbbuf = " "
// RSMB = 0x52534D42
extern CUINT GetSystemFirmwareTable(cuint,cuint,cptr,cuint) kernel32
function get_serial()
local offset,headerlength,strnr,i,startpoint
offset = 8
if not this.fillbuffer() ; return "ERROR" ; endif //couldn't get the data
/* to be used for testcases
f= new file()
f.open("bios.txt")
x=f.gets()
f.close()
this.smbbuf=Space(len(x))
this.smblen = len(x)/2
for i = 0 to len(x)/2-1
this.smbbuf.setbyte(i,htoi(substr(x,i*2+1,2)))
endfor
*/
// search the first datablock with type 01
do while true
if this.smbbuf.getbyte(offset) = 1
exit // we found the datablock with serial number
endif
headerlength = this.smbbuf.getbyte(offset+1)
headerlength = iif(headerlength=0,-2,headerlength)
offset = offset + headerlength
// find the next datablock, after the 0x0000
do while true
offset = this.getnull(offset)
if offset = 0 ; this.serial = "ERROR" ; return "ERROR" ; endif // no serial
// we are looking for a second Null
offset++
if this.smbbuf.getbyte(offset) = 0
offset++
exit // now offset is pointing to the next datablock and we start over
endif
enddo
enddo
// we have the offset of the serialnumber datablock get its headerlength
headerlength = this.smbbuf.getbyte(offset+1)
// and get the nr of the serial string
strnr = this.smbbuf.getbyte(offset+7)
if strnr = 0 ; this.serial = "ERROR" ; return "ERROR" ; endif // no serial
// jump to the nonformatted data
offset += headerlength
// Now get the offset of the nth string
for i = 1 to strnr
startpoint = offset
offset=this.getnull(offset)
if offset = 0 ; this.serial = "ERROR" ; return "ERROR" ; endif // no serial
offset++
endfor
// We have the startpoint and the endpoint of the serialnumber
this.serial = ''
for i=startpoint to offset-1
this.serial += chr(this.smbbuf.getbyte(i))
endfor
this.smbbuf = " "
return this.serial
function showall(tofile)
local a,b,c
if not this.fillbuffer()
? "ERROR"
return
endif //couldn't get the data
b= "" ; c =""
for i = 0 to this.smblen
a = this.smbbuf.getbyte(i)
c+=itoh(a,2)
b+=iif(a>31,chr(a),"#")
endfor
if tofile
a = new file()
a.create("BIOS.TXT","W")
a.puts(b)
a.puts(c)
a.close()
else
? b ; ? c
endif
return
function getnull(c)
do while c<this.smblen // till the end of the buffer
if this.smbbuf.getbyte(c) = 0
return c
else
c++
endif
enddo
return 0
function fillbuffer()
this.smblen = 0
// first get the length of the buffer
this.smblen = GetSystemFirmwareTable(0x52534D42,0,this.smbbuf,this.smblen)
if this.smblen = 0 ; this.serial = "ERROR" ; return false ; endif
// then get the buffer itself
this.smbbuf = replicate(chr(0),this.smblen+1)
this.smblen = GetSystemFirmwareTable(0x52534D42,0,this.smbbuf,this.smblen)
if this.smblen = 0 ; this.serial = "ERROR" ; return false ; endif
return true
endclass
|
|