Enumerating serial ports

by Richard Russell, May 2014

The program below uses Windows Management Instrumentation (WMI) to enumerate the serial I/O ports (if any):

        INSTALL @lib$+"COMLIB"
        PROC_cominitlcid(1033)
 
        ON CLOSE PROCcleanup : QUIT
        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_SerialPort"")")
 
        nObjs% = FN_getvalueint(objSWbemObjectSet%, "Count")
        IF nObjs%=0 ERROR 100, "No serial ports 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 "Port ";i%;" name is: ";
          dummy% = FN_getvariant(Variant{(i%)}.ldata%, "Caption", _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

As shown the code prints the Caption string for each port, but any of the other members of the Win32_SerialPort class could be extracted instead.