Finding+drive+serial+numbers

//by Richard Russell, October 2015//

Disk drives (including internal and external hard drives, USB flash drives etc.) have two kinds of serial number. One is the **volume serial number** which is created when the drive is formatted, and can later be changed, and the other is the **hardware serial number** which is assigned by the manufacturer and cannot be changed (at least, not in a straightforward way). The volume serial number is easily discovered (e.g. using the [|GetVolumeInformation] API function) but finding the hardware serial number is more tricky.

The program below lists the hardware serial numbers of each of the mounted drives in the system:

code format="bb4w" INSTALL @lib$+"COMLIB" PROC_cominitlcid(1033)

ON ERROR PROCcleanup : SYS "MessageBox", @hwnd%, REPORT$, 0, 0 : END

objSWbemLocator% = FN_createobject("WbemScripting.SWbemLocator")

objWMIService% = FN_getobject(objSWbemLocator%, \     \                            "ConnectServer(""."", ""root\CIMV2"")")

objSWbemObjectSet% = FN_getobject(objWMIService%, \     \                "execQuery(""select * from win32_physicalMedia"")")

nObjs% = FN_getvalueint(objSWbemObjectSet%, "Count") IF nObjs%=0 ERROR 100, "No disk drives present"

SYS !(!objSWbemObjectSet%+28), objSWbemObjectSet%, ^pEnum% IF pEnum%=0 ERROR 100, "SWbemObjectSet::NewEnum failed"

DIM Variant{(nObjs%) type%, pad%, ldata%, hdata%}

SYS !(!pEnum%+20), pEnum% : REM IEnumVARIANT::Reset FOR i% = 1 TO nObjs% SYS !(!pEnum%+12), pEnum%, 1, Variant{(i%)}, ^celtFetched% IF celtFetched%<>1 ERROR 100, "IEnumVARIANT::Next failed" NEXT i%     SYS !(!pEnum%+8), pEnum% : REM IEnumVARIANT::Release

FOR i% = 1 TO nObjs% PRINT "Drive ";i%;" serial number is: "; dummy% = FN_getvariant(Variant{(i%)}.ldata%, "SerialNumber", _ret{}) IF _ret.vartype% = 8 THEN PRINT _ret.data$ ELSE PRINT "Not available" ENDIF NEXT i%

PROCcleanup END

DEF PROCcleanup PROC_releaseobject(objSWbemLocator%) PROC_comexit ENDPROC code