PlatformVB

RASEnumEntries

The RASEnumEntries function will return a list of all dial up networking entries. From the PlatformSDK, the function is declared as follows:

Declare Function RasEnumEntries _
      Lib "rasapi32.dll" Alias "RasEnumEntriesA" ( _
          ByVal lpStrNull As String, _
          ByVal lpszPhonebook As String, _
          lprasentryname As RASENTRYNAME, _
          lpCb As Long, _
          lpCEntries As Long) _
As Long

The RASENTRYNAME structure is different depending on the version of windows.  In the Platform SDK the RASENTRYNAME structure is as follows:

typedef struct _RASENTRYNAME { 
  DWORD  dwSize; 
  TCHAR  szEntryName[RAS_MaxEntryName + 1]; 
#if (WINVER >= 0x500)
  DWORD dwFlags;
  CHAR  szPhonebookPath[MAX_PATH + 1];
#endif
} RASENTRYNAME; 

Note how it has two extra members if the Windows Version is &H500 or greater (win2000).  Also the RAS_MaxEntryName constant is different for different platforms.  For windows 95/98 and NT4 or later, it's value is 256.  For earlier versions of NT it's value is 20.  This gives us a possible 3 different sized structures for the RASENTRYNAME structure.

A common approach to this problem is to declare 3 different structures, check the windows version by calling the GetVersionEX() API function, then pass our values to and from the appropriate structure.  I call this the SDKtoVB approach. The problem with that approach is it is difficult to update in the future, and the structures themselves are not really VB friendly - strings are stored as fixed length byte arrays , etc.

Another approach, is to start from the VB end and work towards the SDK format.  I call this the VBtoSDK approach.  The first step in this approach is to define the information we want as we would handle it in VB.  For the RASENTRYNAME structure, our VB declaration would be as follows:

Public Type VBRasEntryName
   entryname As String
   Win2000_SystemPhonebook As Boolean
   PhonebookPath As String
End Type

In our structure above, note how we have declared the strings as variable length strings (the" VB way") and we have a member called Win2000_SystemPhonebook which will return true if the phonebook is in the AllUsers profile for Windows 2000.

The next step is to find a way to pass our VB structure to the RASAPI32.dll.  Well, it really is quite simple.  The RASAPI is only looking for a consecutive series of bytes for the structure, so we can use a dynamic byte array to pass to the RASAPI, and use the CopyMemory API to pass values to and from our VB structure to the byte array.  The only thing we need to know is the size of the byte array or the size of the structure the RASAPI is expecting.  From the definitions in the Ras.h header file, we find the possible sizes for the RASENTRYNAME structure are 528, 264 or 28 bytes (rounded up to the nearest multiple of 4)

Finally we have to work out how to set the appropriate size of our byte array. The RasEnumEntries function performs differently depending on the windows platform.  On windows 95/98 it will tell us the appropriate size even if we don't set the first four bytes of our byte array to the appropriate value. It will return an error value of 603 (ERROR_BUFFER_TOO_SMALL) and also return two useful variables to us, being lpCb which is the count of bytes needed to store all the RASENTRYNAMEs , and lpCEntries which is the count of the number of entries. On NT4, we need to set the first four bytes of our byte array to the appropriate value, otherwise it will return an error value of 632 and tell us nothing about the size needed.

This following sample function demonstrates using RASEnumEntries.  To use it, you would declare a dynamic array of type VBRasEntryName and pass it to the function VBRasGetAllEntries which would populate the array and return the number of entries as a long. eg:

Dim myEntries() as VBRasEntryName
Dim lngCount as long
lngCount = VBRasGetAllEntries(myEntries)

Note: On NT you can also use the strPhoneBook variable to specify the full path and file name of a phonebook to use.  If not specified, the default phonebook is used.

 

Public Type VBRasEntryName
   entryname As String
   Win2000_SystemPhonebook As Boolean
   PhonebookPath As String
End Type

Public Declare Function RasEnumEntries _ 
    Lib "rasapi32.dll" Alias "RasEnumEntriesA" _
    (ByVal lpStrNull As String, ByVal lpszPhonebook As String, _
    lpRasEntryName As Any, lpCb As Long, lpCEntries As Long) As Long

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
         (Destination As Any, Source As Any, ByVal Length As Long)
'_____________________________________________________________________

Function VBRasGetAllEntries(clsRasEntryName() As VBRasEntryName, _
		          Optional strPhoneBook As String) As Long
   
   Dim rtn As Long, i As Long
   Dim lpCb As Long   'count of bytes
   Dim lpCEntries As Long  'count of entries
   Dim b() As Byte
   Dim strTemp As String
   Dim dwSize As Long 'size of each entry
   Dim lngLen As Long
   Dim lngBLen As Variant
   ReDim b(3)
   
   'determine appropiate size for b()
   
   lngBLen = Array(532&, 264&, 28&)
   For i = 0 To 2
      CopyMemory b(0), CLng(lngBLen(i)), 4
      rtn = RasEnumEntries(vbNullString, strPhoneBook, _
			 b(0), lpCb, lpCEntries)
      If rtn <> 632 Then Exit For
   Next i
   
   VBRasGetAllEntries = lpCEntries

   If lpCEntries = 0 Then Exit Function
   
   dwSize = lpCb \ lpCEntries
   
   ReDim b(lpCb - 1)
   
   CopyMemory b(0), dwSize, 4
   
   rtn = RasEnumEntries(vbNullString, strPhoneBook, _
			 b(0), lpCb, lpCEntries)
   
   If rtn <> 0 Then MsgBox VBRASErrorHandler(rtn)
   
   strTemp = String(dwSize - 4, 0)
   
   ReDim clsRasEntryName(lpCEntries - 1)
   
   If dwSize = 28 Then lngLen = 21 Else lngLen = 257
   For i = 0 To lpCEntries - 1
     CopyMemory ByVal strTemp, b((i * dwSize) + 4), lngLen
     clsRasEntryName(i).entryname = _
			Left(strTemp, InStr(strTemp, Chr$(0)) - 1)
   Next i
   If dwSize > 264 Then
      For i = 0 To lpCEntries - 1
        CopyMemory clsRasEntryName(i).Win2000_SystemPhonebook, _
                b((i * dwSize) + 264), 2&
        CopyMemory ByVal strTemp, b((i * dwSize) + 268), 260&
        clsRasEntryName(i).PhonebookPath = _
         Left(strTemp, InStr(strTemp, Chr$(0)) - 1)
      Next i
   Else
      For i = 0 To lpCEntries - 1
         clsRasEntryName(i).PhonebookPath = strPhoneBook
      Next i
   End If
End Function

 

 

See Also: Contents, Introduction, RasErrorHandler.