Announcement

Collapse
No announcement yet.

Modem Enumeration in Win2k?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Modem Enumeration in Win2k?

    In Windows 95/98/Me, one can enumerate the modems on a machine,
    and what ports they are attached to, by examining the entries
    under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\Modem\

    For example, code like this generally works pretty well (search the forum
    to locate the GetStringValue sub).
    Code:
    FUNCTION EnumerateModemWindowsInit (ComPortToMatch AS INTEGER, ModemInitString AS STRING,_
                 ModemCommandPrefix AS STRING, ModemHangUp AS STRING, ModemDialPrefix AS STRING, _
                 ModemDialSuffix AS STRING, ModemSpeakerOff AS STRING, ModemNum AS INTEGER) AS STRING
       '
       '   Here we examine the Modem Registry Settings
       '   Find out which one is on ComPortToMatch
       '   and we get the Windows command strings for dialing, hanging up,
       '   turning off the speaker, and putting things back to the Windows
       '   defaults. Note that by getting the command & dial prefixes, and dial
       '   suffix, we are not restricted to Hayes compatible modems.
       '
       '    EnumerateModemWindowsInit itself is a string of the description of the modem
       '
    
        LOCAL I AS INTEGER
        LOCAL A$
        LOCAL KEY$
        ModemInitString=""
        KEY$="HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\Modem\"
        ModemNum=0
    CheckModem:
        A$ = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000")), "DriverDesc")
        IF A$="" AND ModemNum>8 THEN
                FUNCTION = ""
                ModemInitString=""
                ModemCommandPrefix=""
                ModemHangUp=""
                ModemDialPrefix=""
                ModemDialSuffix=""
                ModemSpeakerOff=""
           EXIT FUNCTION
        END IF
        IF A$<>"" THEN
            FUNCTION = A$
            A$ = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000")), "AttachedTo")
            A$=TRIM$(A$)
            A$=RIGHT$(A$,1)
            I=VAL(A$)
            IF I = ComPortToMatch THEN
               ModemInitString = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000"))+"\Init", "2")
               ModemInitString = REMOVE$(ModemInitString, "<cr>")
               ModemCommandPrefix = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000"))+"\Init", "1")
               ModemCommandPrefix = REMOVE$(ModemCommandPrefix, "<cr>")
               ModemHangUp = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000"))+"\Hangup", "1")
               ModemHangUp = REMOVE$(ModemHangUp, "<cr>")
               ModemDialPrefix = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000"))+"\Settings", "DialPrefix")
               ModemDialSuffix = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000"))+"\Settings", "DialSuffix")
               ModemSpeakerOff  = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000"))+"\Settings", "SpeakerMode_Off")
               EXIT FUNCTION
            END IF
        END IF
        ModemNum=ModemNum+1
        GOTO CheckModem
    END FUNCTION
    However, in Windows 2000 the modem info is stored elsewhere, as near
    as I can tell not in the System Registry at all. Does not appear (to
    me) to be available in the RAS routines either. Does anyone know
    how to find, in Windows 2000, what modem is assigned to what COM
    port?

    ------------------
    Michael Burns
    Michael Burns

  • #2
    Well, here is a modification to the code above that works, although (in Win 2k)
    it assumes the modem is Hayes comatible. Again, search for the GetStringValue
    routine. I've added the GetOSVersion the modem enumeration routine now requires.

    Code:
    FUNCTION GetOSVersion AS STRING
       '
       '    This gets what version of Windows you are running and returns it as a string
       '
       LOCAL OSVer AS OSVERSIONINFO
       LOCAL lResult  AS LONG
       OSVer.dwOSVersionInfoSize = SIZEOF(OSVer)
       lResult = GetVersionEx(OSVer)
       lResult= LOWRD(OSVer.dwBuildNumber)
       IF lResult = 950 THEN
          FUNCTION="Windows 95"
          EXIT FUNCTION
       END IF
       IF lResult = 1111 THEN
          FUNCTION="Windows 95 OSR2"
          EXIT FUNCTION
       END IF
       IF lResult = 1998 THEN
          FUNCTION="Windows 98"
          EXIT FUNCTION
       END IF
       IF lResult = 2222 THEN
          FUNCTION="Windows 98 SE"
          EXIT FUNCTION
       END IF
       IF lResult = 3000 THEN
          FUNCTION="Windows ME"
          EXIT FUNCTION
       END IF
       IF lResult = 1381 THEN
          FUNCTION="Windows NT v4"
          EXIT FUNCTION
       END IF
       IF lResult = 2195 THEN
          FUNCTION="Windows 2000"
          EXIT FUNCTION
       END IF
       FUNCTION="Windows version unknown"
    END FUNCTION   
    '********************************************
    FUNCTION EnumerateModemWindowsInit (ComPortToMatch AS INTEGER, ModemInitString AS STRING,_
                 ModemCommandPrefix AS STRING, ModemHangUp AS STRING, ModemDialPrefix AS STRING, _
                 ModemDialSuffix AS STRING, ModemSpeakerOff AS STRING, ModemNum AS INTEGER) AS STRING
       '
       '   Win 95/98/Me: Here we examine the Modem Registry Settings
       '   Find out which one is on ComPortToMatch
       '   and we get the Windows command strings for dialing, hanging up,
       '   turning off the speaker, and putting things back to the Windows
       '   defaults. Note that by getting the command & dial prefixes, and dial
       '   suffix, we are not restricted to Hayes compatible modems.
       '
       '   Win 2k/Nt: We are restricted (at present) to Hayes compatible modems.
       '
       '    EnumerateModemWindowsInit itself is a string of the description of the modem
       '
        'LOCAL ModemNum AS INTEGER
        LOCAL I AS INTEGER
        LOCAL A$
        LOCAL KEY$
        ModemInitString=""
        IF GetOSVersion<>"Windows 2000" AND GetOSVersion<>"Windows NT v4" THEN
            '
            '   Deal with situation for Win 95/98/Me
            '
            KEY$="HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\Modem\"
            ModemNum=0
    CheckModem:
            A$ = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000")), "DriverDesc")
            IF A$="" AND ModemNum>8 THEN
                FUNCTION = ""
                ModemInitString=""
                ModemCommandPrefix=""
                ModemHangUp=""
                ModemDialPrefix=""
                ModemDialSuffix=""
                ModemSpeakerOff=""
                EXIT FUNCTION
            END IF
            IF A$<>"" THEN
                FUNCTION = A$
                A$ = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000")), "AttachedTo")
                A$=TRIM$(A$)
                A$=RIGHT$(A$,1)
                I=VAL(A$)
                IF I = ComPortToMatch THEN
                    ModemInitString = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000"))+"\Init", "2")
                    ModemInitString = REMOVE$(ModemInitString, "<cr>")
                    ModemCommandPrefix = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000"))+"\Init", "1")
                    ModemCommandPrefix = REMOVE$(ModemCommandPrefix, "<cr>")
                    ModemHangUp = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000"))+"\Hangup", "1")
                    ModemHangUp = REMOVE$(ModemHangUp, "<cr>")
                    ModemDialPrefix = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000"))+"\Settings", "DialPrefix")
                    ModemDialSuffix = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000"))+"\Settings", "DialSuffix")
                    ModemSpeakerOff  = GetStringValue(KEY$+TRIM$(FORMAT$(ModemNum,"0000"))+"\Settings", "SpeakerMode_Off")
                    EXIT FUNCTION
                END IF
            END IF
            ModemNum=ModemNum+1
            GOTO CheckModem
        ELSE
            '
            '   Deal with situation for Win 2k/NT
            '   We assume the modem is Hayes compatible.
            '
            A$ = GetStringValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ras\Tapi Devices\Unimodem", "Friendly Name")
            IF A$<>"" THEN
               FUNCTION = A$
               A$ = GetStringValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ras\Tapi Devices\Unimodem", "Address")
               A$=TRIM$(A$)
               A$=RIGHT$(A$,1)
               I=VAL(A$)
               A$ = GetStringValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ras\Tapi Devices\Unimodem", "Media Type")
               IF I = ComPortToMatch AND A$="Modem" THEN
                  ModemInitString = "ATE0Q0&C1&D2V1"
                  ModemCommandPrefix = "AT"
                  ModemHangUp = "ATH"
                  ModemDialPrefix = "D"
                  ModemDialSuffix = ";"
                  ModemSpeakerOff  = "M"
                  EXIT FUNCTION
               ELSE
                  FUNCTION = ""
                  ModemInitString=""
                  ModemCommandPrefix=""
                  ModemHangUp=""
                  ModemDialPrefix=""
                  ModemDialSuffix=""
                  ModemSpeakerOff=""
                  EXIT FUNCTION
               END IF
            END IF
        END IF
    END FUNCTION


    ------------------
    Michael Burns
    Michael Burns

    Comment


    • #3
      I can't find the GetStringValue() function on the BBS, just a few references to the name.

      Could you please post that function too, Michael? Thanks!


      ------------------
      Lance
      PowerBASIC Support
      mailto:[email protected][email protected]</A>
      Lance
      mailto:[email protected]

      Comment


      • #4
        Code:
        getStringValue
        public String getStringValue(String name,String defval);
        
        
        Queries a string value from the registry. The name is a subkey of the current key. If the named value does not exist in the registry, the specified default value is returned. 
        
        Return Value: 
        
        Returns the default value if the named value does not exist in the registry. Otherwise, the method returns the string value contained in the subkey. 
        
        Parameter Description 
        name  The subkey containing the requested string.  
        defval  The default value to return.
        ------------------
        Sven Blumenstein
        IT-Trainee at DECOMA Exterior Systems, Germany
        E-Mail (work): mailto:[email protected][email protected]</A>
        E-Mail (home): mailto:[email protected][email protected]</A>
        Favorite Languages: PB/Dll, MASM, VB, VC++, LCC, VBA, WML

        Comment


        • #5
          Originally posted by Lance Edmonds:
          I can't find the GetStringValue() function on the BBS, just a few references to the name.

          Could you please post that function too, Michael? Thanks!

          For some reason I thought it was posted already. Here it is, along
          with the routines it calls:

          Code:
          GLOBAL True AS INTEGER
          GLOBAL False AS INTEGER
          GLOBAL rtn AS LONG 
          
          FUNCTION GetMainKeyHandle(MainKeyName AS STRING) AS LONG
          
          SELECT CASE MainKeyName
                 CASE "HKEY_CLASSES_ROOT"
                      GetMainKeyHandle = %HKEY_CLASSES_ROOT
                 CASE "HKEY_CURRENT_USER"
                      GetMainKeyHandle = %HKEY_CURRENT_USER
                 CASE "HKEY_LOCAL_MACHINE"
                      GetMainKeyHandle = %HKEY_LOCAL_MACHINE
                 CASE "HKEY_USERS"
                      GetMainKeyHandle = %HKEY_USERS
                 CASE "HKEY_PERFORMANCE_DATA"
                      GetMainKeyHandle = %HKEY_PERFORMANCE_DATA
                 CASE "HKEY_CURRENT_CONFIG"
                      GetMainKeyHandle = %HKEY_CURRENT_CONFIG
                 CASE "HKEY_DYN_DATA"
                      GetMainKeyHandle = %HKEY_DYN_DATA
          END SELECT
          
          END FUNCTION
          
          '********************************************************
          SUB ParseKey(Keyname AS STRING, Keyhandle AS LONG)
          
          rtn = INSTR(Keyname, "\") 'return if "\" is contained in the Keyname
          
          IF LEFT$(Keyname, 5) <> "HKEY_" OR RIGHT$(Keyname, 1) = "\" THEN 'if there is a "\" at the end of the Keyname then
             MSGBOX "Incorrect Format:" + CHR$(10) + CHR$(10) + Keyname,, "ParseKey" 'display error to the user
             EXIT SUB 'exit the procedure
          ELSEIF rtn = 0 THEN 'if the Keyname contains no "\"
             Keyhandle = GetMainKeyHandle(Keyname)
             Keyname = "" 'leave Keyname blank
          ELSE 'otherwise, Keyname contains "\"
             Keyhandle = GetMainKeyHandle(LEFT$(Keyname, rtn - 1)) 'seperate the Keyname
             Keyname = RIGHT$(Keyname, LEN(Keyname) - rtn)
          END IF
          
          END SUB
          
          '********************************************************
          FUNCTION GetStringValue(SubKey AS STRING, Entry AS STRING) AS STRING
          
          DIM rtn AS LONG
          DIM SubKeyz AS ASCIIZ * 256
          DIM sBufferz AS ASCIIZ * 256
          DIM Entryz AS ASCIIZ * 256
          
          CALL ParseKey(SubKey, MainKeyHandle)
          SubKeyz=SubKey + CHR$(0)
          Entryz=Entry + CHR$(0)
          IF MainKeyHandle THEN
             rtn = RegOpenKeyEx(MainKeyHandle, SubKeyz, 0, %KEY_READ, hKey) 'open the key
             IF rtn = %ERROR_SUCCESS THEN 'if the key could be opened then
                lBufferSize = 256
                rtn = RegQueryValueEx(hKey, Entryz, 0, %REG_SZ, sBufferz, 255) 'get the value from the registry
                IF rtn = %ERROR_SUCCESS THEN 'if the value could be retreived then
                   rtn = RegCloseKey(hKey)  'close the key
                   sBufferz = TRIM$(sBufferz)
                   GetStringValue = sBufferz 'return the value to the user
                ELSE                        'otherwise, if the value couldnt be retreived
                   GetStringValue = ""             ' return null string to user
                END IF
             ELSE 'otherwise, if the key couldnt be opened
                GetStringValue = ""             ' return null string to user
             END IF
          END IF
          END FUNCTION
          '********************************************************
          ------------------
          Michael Burns



          [This message has been edited by Michael Burns (edited September 10, 2001).]
          Michael Burns

          Comment


          • #6
            I should point out that the Win 95/98/Me modem enumeration
            routine above does require that the modem have its "AttachedTo"
            registry entry properly filled out. I have noticed that not all
            modems have this entry. I do have a routine, that is rather
            convoluted (and not very readable) that when called looks at all
            the modems it can find in
            HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\Modem\
            and checks for an AttachedTo entry. If there is none, then it looks
            for an MatchingDeviceID Key.

            If an MatchingDeviceID Key is found, it uses that to look in the
            HKEY_LOCAL_MACHINE\Enum\PCI\ area and its subkeys looking for a
            PORTNAME Key. If it finds a PORTNAME Key, it then goes back and
            patches the missing "AttachedTo" entry. If people are interested,
            I'll post it.

            ------------------
            Michael Burns

            [This message has been edited by Michael Burns (edited September 10, 2001).]
            Michael Burns

            Comment


            • #7
              Michael,

              Do a search for CreateRAS in the forums and you should find
              Daves code which includes a call to RASEmunDevices. It works
              for me on win2K.

              Have Fun.
              NJH.

              ------------------

              Comment

              Working...
              X