Subject Re: Computer serial number
From Marc VdB <dbase@dbase.de>
Date Sun, 21 Apr 2024 00:25:07 +0200
Newsgroups dbase.getting-started
Attachment(s) getbiosdata.cc

Hi Rachhpal,
just in case you want a version without text file, you could use the
attached class.

set procedure to getbiosdata.cc
o = new biosdata()
? o.get_serial()

KR,
Marc



/****************************************************************************
        
        Version 1.0 - Marc VdB        20-04-2024  (get_serial)
                
   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                 = 9
                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 "ERROR" ; 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 "ERROR" ; endif
                
                // get the beginning of the first datablock
                
                headerlength = this.smbbuf.getbyte(offset)
                offset += headerlength

                // find the second datablock, given by a 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
                        endif
                enddo
                
                // we have the offset of the second datablock get its headerlength
                
                headerlength = this.smbbuf.getbyte(offset+1)
                
                // and get the nr of the serial string
                
                strnr = this.smbbuf.getbyte(offset+6)
                if strnr = 0 ; this.serial = "ERROR" ; return "ERROR" ; endif // no serial
                
                // jump to the second datablock
                
                offset += headerlength+1
                
                // Now get the offset of the nth string

                for i = 0 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 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
                
        
endclass