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

Hi Mervyn,
thanks for testing this.
Could you use the attached cc, execute the following statements and post
the BIOS.TXT file?

set procedure to getbiosdata.cc
o = new BiosData()
o.showall(true)

tia

Marc

>
> Hi Marc,
>
> I'm afraid we're back to the definition of "test data". :-) It doesn't
> work for me either.
>
> The WMI command returns 3RD8F3J
>
> GetBiosData prints what looks like two narrow hollow upright rectangles.
>
> When I mark it to copy it an extra narrow square bracket with the legs
> pointing to the right appears after a space while the left mouse button
> is down but this disappears when I release the mouse button.
>
> When saved to a variable the length is 4.
>
> for n = 0 to 7;??a.getbyte(n);next  produces the following output.
>
> 3         0         4         0         7         0         0         0
>
> The computer is a DELL.
>
> The BIOS setup shows the following.
>
> System = OptiPlex 755
> BIOS version = A22 (06/11/12)
> Service Tag = 3RD8F3J
> Express Service Code = 8185161583
> Asset Tag = {none}
>
>
> Mervyn.
>
>
>
>
>
>
> 
>



/****************************************************************************
        
        Version 1.0 - Marc VdB        20-04-2024  (get_serial)
        Version 1.1 21-04-2024 (showall)        
        
   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
                if not this.fillbuffer() ; return "ERROR" ; endif  //couldn't get the data
                
                // 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 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