Source code for Issue Number 30

Copyright 1997-2000 by C&D Programming Corp. All Rights Reserved. Source code may not be reproduced except for use in a compiled executable. All rights reserved. If you would like to reprint any or all of this code please email us at info@codeoftheweek.com

Code of the Week Home


Source Code

Just paste this code into a new class module and change the name of the class to DialUpNetworking.

'----------------------------------------------------------------------
'
'   Module Name:    DialUpNetworking
'   Written By:     C&D Programming Corp.
'                   Rick G.
'   Create Date:    3/98
'   Copyright:      Copyright 1998 by C&D Programming Corp.  Source
'                   code may not be reproduced except for use in a
'                   compiled executable.  All rights reserved.  If
'                   you would like to reprint any or all of this
'                   code please email us at info@codeoftheweek.com
'----------------------------------------------------------------------
Option Explicit
'
'   Structure for accessing the RAS Dial functions
'
Private Type RASDIALPARAMS
    dwSize As Long
    szEntryName(256) As Byte
    szPhoneNumber(128) As Byte
    szCallbackNumber(128) As Byte
    szUserName(256) As Byte
    szPassword(256) As Byte
    szDomain(15) As Byte
End Type

Dim mlError As Long             ' Holds the error code
Dim mlConnection As Long        ' To track the active connection

'
'   Function to hangup a dialup networking call
'
Private Declare Function RasDialA Lib "RASAPI32.DLL" _
    (ByVal lpRasDialExtensions As Long, _
     ByVal lpszPhoneBook As Long, _
     lpRasDialParams As RASDIALPARAMS, _
     ByVal dwNotifierType As Long, _
     ByVal lpvNotifier As Long, _
     lphRasConn As Long) As Long

'
'   Function to hangup a RAS call.
'
Private Declare Function RasHangUpA Lib "RASAPI32.DLL" _
    (ByVal hRasConn As Long) As Long

'
'   RAS Error Codes - This should be a complete list of all
'   error codes that can occur in the RASAPI32.DLL module.
'
Private Const RASBASE = 600
Private Const SUCCESS = 0

Private Const PENDING = (RASBASE + 0)
Private Const ERROR_INVALID_PORT_HANDLE = (RASBASE + 1)
Private Const ERROR_PORT_ALREADY_OPEN = (RASBASE + 2)
Private Const ERROR_BUFFER_TOO_SMALL = (RASBASE + 3)
Private Const ERROR_WRONG_INFO_SPECIFIED = (RASBASE + 4)
Private Const ERROR_CANNOT_SET_PORT_INFO = (RASBASE + 5)
Private Const ERROR_PORT_NOT_CONNECTED = (RASBASE + 6)
Private Const ERROR_EVENT_INVALID = (RASBASE + 7)
Private Const ERROR_DEVICE_DOES_NOT_EXIST = (RASBASE + 8)
Private Const ERROR_DEVICETYPE_DOES_NOT_EXIST = (RASBASE + 9)
Private Const ERROR_BUFFER_INVALID = (RASBASE + 10)
Private Const ERROR_ROUTE_NOT_AVAILABLE = (RASBASE + 11)
Private Const ERROR_ROUTE_NOT_ALLOCATED = (RASBASE + 12)
Private Const ERROR_INVALID_COMPRESSION_SPECIFIED = (RASBASE + 13)
Private Const ERROR_OUT_OF_BUFFERS = (RASBASE + 14)
Private Const ERROR_PORT_NOT_FOUND = (RASBASE + 15)
Private Const ERROR_ASYNC_REQUEST_PENDING = (RASBASE + 16)
Private Const ERROR_ALREADY_DISCONNECTING = (RASBASE + 17)
Private Const ERROR_PORT_NOT_OPEN = (RASBASE + 18)
Private Const ERROR_PORT_DISCONNECTED = (RASBASE + 19)
Private Const ERROR_NO_ENDPOINTS = (RASBASE + 20)
Private Const ERROR_CANNOT_OPEN_PHONEBOOK = (RASBASE + 21)
Private Const ERROR_CANNOT_LOAD_PHONEBOOK = (RASBASE + 22)
Private Const ERROR_CANNOT_FIND_PHONEBOOK_ENTRY = (RASBASE + 23)
Private Const ERROR_CANNOT_WRITE_PHONEBOOK = (RASBASE + 24)
Private Const ERROR_CORRUPT_PHONEBOOK = (RASBASE + 25)
Private Const ERROR_CANNOT_LOAD_STRING = (RASBASE + 26)
Private Const ERROR_KEY_NOT_FOUND = (RASBASE + 27)
Private Const ERROR_DISCONNECTION = (RASBASE + 28)
Private Const ERROR_REMOTE_DISCONNECTION = (RASBASE + 29)
Private Const ERROR_HARDWARE_FAILURE = (RASBASE + 30)
Private Const ERROR_USER_DISCONNECTION = (RASBASE + 31)
Private Const ERROR_INVALID_SIZE = (RASBASE + 32)
Private Const ERROR_PORT_NOT_AVAILABLE = (RASBASE + 33)
Private Const ERROR_CANNOT_PROJECT_CLIENT = (RASBASE + 34)
Private Const ERROR_UNKNOWN = (RASBASE + 35)
Private Const ERROR_WRONG_DEVICE_ATTACHED = (RASBASE + 36)
Private Const ERROR_BAD_STRING = (RASBASE + 37)
Private Const ERROR_REQUEST_TIMEOUT = (RASBASE + 38)
Private Const ERROR_CANNOT_GET_LANA = (RASBASE + 39)
Private Const ERROR_NETBIOS_ERROR = (RASBASE + 40)
Private Const ERROR_SERVER_OUT_OF_RESOURCES = (RASBASE + 41)
Private Const ERROR_NAME_EXISTS_ON_NET = (RASBASE + 42)
Private Const ERROR_SERVER_GENERAL_NET_FAILURE = (RASBASE + 43)
Private Const WARNING_MSG_ALIAS_NOT_ADDED = (RASBASE + 44)
Private Const ERROR_AUTH_INTERNAL = (RASBASE + 45)
Private Const ERROR_RESTRICTED_LOGON_HOURS = (RASBASE + 46)
Private Const ERROR_ACCT_DISABLED = (RASBASE + 47)
Private Const ERROR_PASSWD_EXPIRED = (RASBASE + 48)
Private Const ERROR_NO_DIALIN_PERMISSION = (RASBASE + 49)
Private Const ERROR_SERVER_NOT_RESPONDING = (RASBASE + 50)
Private Const ERROR_FROM_DEVICE = (RASBASE + 51)
Private Const ERROR_UNRECOGNIZED_RESPONSE = (RASBASE + 52)
Private Const ERROR_MACRO_NOT_FOUND = (RASBASE + 53)
Private Const ERROR_MACRO_NOT_DEFINED = (RASBASE + 54)
Private Const ERROR_MESSAGE_MACRO_NOT_FOUND = (RASBASE + 55)
Private Const ERROR_DEFAULTOFF_MACRO_NOT_FOUND = (RASBASE + 56)
Private Const ERROR_FILE_COULD_NOT_BE_OPENED = (RASBASE + 57)
Private Const ERROR_DEVICENAME_TOO_LONG = (RASBASE + 58)
Private Const ERROR_DEVICENAME_NOT_FOUND = (RASBASE + 59)
Private Const ERROR_NO_RESPONSES = (RASBASE + 60)
Private Const ERROR_NO_COMMAND_FOUND = (RASBASE + 61)
Private Const ERROR_WRONG_KEY_SPECIFIED = (RASBASE + 62)
Private Const ERROR_UNKNOWN_DEVICE_TYPE = (RASBASE + 63)
Private Const ERROR_ALLOCATING_MEMORY = (RASBASE + 64)
Private Const ERROR_PORT_NOT_CONFIGURED = (RASBASE + 65)
Private Const ERROR_DEVICE_NOT_READY = (RASBASE + 66)
Private Const ERROR_READING_INI_FILE = (RASBASE + 67)
Private Const ERROR_NO_CONNECTION = (RASBASE + 68)
Private Const ERROR_BAD_USAGE_IN_INI_FILE = (RASBASE + 69)
Private Const ERROR_READING_SECTIONNAME = (RASBASE + 70)
Private Const ERROR_READING_DEVICETYPE = (RASBASE + 71)
Private Const ERROR_READING_DEVICENAME = (RASBASE + 72)
Private Const ERROR_READING_USAGE = (RASBASE + 73)
Private Const ERROR_READING_MAXCONNECTBPS = (RASBASE + 74)
Private Const ERROR_READING_MAXCARRIERBPS = (RASBASE + 75)
Private Const ERROR_LINE_BUSY = (RASBASE + 76)
Private Const ERROR_VOICE_ANSWER = (RASBASE + 77)
Private Const ERROR_NO_ANSWER = (RASBASE + 78)
Private Const ERROR_NO_CARRIER = (RASBASE + 79)
Private Const ERROR_NO_DIALTONE = (RASBASE + 80)
Private Const ERROR_IN_COMMAND = (RASBASE + 81)
Private Const ERROR_WRITING_SECTIONNAME = (RASBASE + 82)
Private Const ERROR_WRITING_DEVICETYPE = (RASBASE + 83)
Private Const ERROR_WRITING_DEVICENAME = (RASBASE + 84)
Private Const ERROR_WRITING_MAXCONNECTBPS = (RASBASE + 85)
Private Const ERROR_WRITING_MAXCARRIERBPS = (RASBASE + 86)
Private Const ERROR_WRITING_USAGE = (RASBASE + 87)
Private Const ERROR_WRITING_DEFAULTOFF = (RASBASE + 88)
Private Const ERROR_READING_DEFAULTOFF = (RASBASE + 89)
Private Const ERROR_EMPTY_INI_FILE = (RASBASE + 90)
Private Const ERROR_AUTHENTICATION_FAILURE = (RASBASE + 91)
Private Const ERROR_PORT_OR_DEVICE = (RASBASE + 92)
Private Const ERROR_NOT_BINARY_MACRO = (RASBASE + 93)
Private Const ERROR_DCB_NOT_FOUND = (RASBASE + 94)
Private Const ERROR_STATE_MACHINES_NOT_STARTED = (RASBASE + 95)
Private Const ERROR_STATE_MACHINES_ALREADY_STARTED = (RASBASE + 96)
Private Const ERROR_PARTIAL_RESPONSE_LOOPING = (RASBASE + 97)
Private Const ERROR_UNKNOWN_RESPONSE_KEY = (RASBASE + 98)
Private Const ERROR_RECV_BUF_FULL = (RASBASE + 99)
Private Const ERROR_CMD_TOO_LONG = (RASBASE + 100)
Private Const ERROR_UNSUPPORTED_BPS = (RASBASE + 101)
Private Const ERROR_UNEXPECTED_RESPONSE = (RASBASE + 102)
Private Const ERROR_INTERACTIVE_MODE = (RASBASE + 103)
Private Const ERROR_BAD_CALLBACK_NUMBER = (RASBASE + 104)
Private Const ERROR_INVALID_AUTH_STATE = (RASBASE + 105)
Private Const ERROR_WRITING_INITBPS = (RASBASE + 106)
Private Const ERROR_X25_DIAGNOSTIC = (RASBASE + 107)
Private Const ERROR_ACCT_EXPIRED = (RASBASE + 108)
Private Const ERROR_CHANGING_PASSWORD = (RASBASE + 109)
Private Const ERROR_OVERRUN = (RASBASE + 110)
Private Const ERROR_RASMAN_CANNOT_INITIALIZE = (RASBASE + 111)
Private Const ERROR_BIPLEX_PORT_NOT_AVAILABLE = (RASBASE + 112)
Private Const ERROR_NO_ACTIVE_ISDN_LINES = (RASBASE + 113)
Private Const ERROR_NO_ISDN_CHANNELS_AVAILABLE = (RASBASE + 114)
Private Const ERROR_TOO_MANY_LINE_ERRORS = (RASBASE + 115)
Private Const ERROR_IP_CONFIGURATION = (RASBASE + 116)
Private Const ERROR_NO_IP_ADDRESSES = (RASBASE + 117)
Private Const ERROR_PPP_TIMEOUT = (RASBASE + 118)
Private Const ERROR_PPP_REMOTE_TERMINATED = (RASBASE + 119)
Private Const ERROR_PPP_NO_PROTOCOLS_CONFIGURED = (RASBASE + 120)
Private Const ERROR_PPP_NO_RESPONSE = (RASBASE + 121)
Private Const ERROR_PPP_INVALID_PACKET = (RASBASE + 122)
Private Const ERROR_PHONE_NUMBER_TOO_LONG = (RASBASE + 123)
Private Const ERROR_IPXCP_NO_DIALOUT_CONFIGURED = (RASBASE + 124)
Private Const ERROR_IPXCP_NO_DIALIN_CONFIGURED = (RASBASE + 125)
Private Const ERROR_IPXCP_DIALOUT_ALREADY_ACTIVE = (RASBASE + 126)
Private Const ERROR_ACCESSING_TCPCFGDLL = (RASBASE + 127)
Private Const ERROR_NO_IP_RAS_ADAPTER = (RASBASE + 128)
Private Const ERROR_SLIP_REQUIRES_IP = (RASBASE + 129)
Private Const ERROR_PROJECTION_NOT_COMPLETE = (RASBASE + 130)
Private Const ERROR_PROTOCOL_NOT_CONFIGURED = (RASBASE + 131)
Private Const ERROR_PPP_NOT_CONVERGING = (RASBASE + 132)
Private Const ERROR_PPP_CP_REJECTED = (RASBASE + 133)
Private Const ERROR_PPP_LCP_TERMINATED = (RASBASE + 134)
Private Const ERROR_PPP_REQUIRED_ADDRESS_REJECTED = (RASBASE + 135)
Private Const ERROR_PPP_NCP_TERMINATED = (RASBASE + 136)
Private Const ERROR_PPP_LOOPBACK_DETECTED = (RASBASE + 137)
Private Const ERROR_PPP_NO_ADDRESS_ASSIGNED = (RASBASE + 138)
Private Const ERROR_CANNOT_USE_LOGON_CREDENTIALS = (RASBASE + 139)
Private Const ERROR_TAPI_CONFIGURATION = (RASBASE + 140)
Private Const ERROR_NO_LOCAL_ENCRYPTION = (RASBASE + 141)
Private Const ERROR_NO_REMOTE_ENCRYPTION = (RASBASE + 142)
Private Const ERROR_REMOTE_REQUIRES_ENCRYPTION = (RASBASE + 143)
Private Const ERROR_IPXCP_NET_NUMBER_CONFLICT = (RASBASE + 144)
Private Const ERROR_INVALID_SMM = (RASBASE + 145)
Private Const ERROR_SMM_UNINITIALIZED = (RASBASE + 146)
Private Const ERROR_NO_MAC_FOR_PORT = (RASBASE + 147)
Private Const ERROR_SMM_TIMEOUT = (RASBASE + 148)
Private Const ERROR_BAD_PHONE_NUMBER = (RASBASE + 149)
Private Const ERROR_WRONG_MODULE = (RASBASE + 150)
Private Const ERROR_INVALID_CALLBACK_NUMBER = (RASBASE + 151)
Private Const ERROR_SCRIPT_SYNTAX = (RASBASE + 152)
'
'   Dials the entry specified by pEntryName
'
Public Function Dial(pEntryName As String, pUsername As String, pPassword As String) As Boolean
    Dim rdp As RASDIALPARAMS
    Dim c As Integer

    ' assign the size of the data structure to the size parameter
    ' this is used for checking which version is calling RasDialA
    rdp.dwSize = 1052

    ' Copy necessary data into the structure.
    ' we use byte arrays to ensure no problems when calling
    ' the API's.
    For c = 0 To (Len(pUsername) - 1)
        rdp.szUserName(c) = Asc(Mid(pUsername, c + 1, 1))
    Next
    For c = 0 To (Len(pPassword) - 1)
        rdp.szPassword(c) = Asc(Mid(pPassword, c + 1, 1))
    Next
    For c = 0 To (Len(pEntryName) - 1)
        rdp.szEntryName(c) = Asc(Mid(pEntryName, c + 1, 1))
    Next

    'RasDialA will place return code in Connect and return to calling routine
    mlError = RasDialA(0&, 0&, rdp, 0&, 0&, mlConnection)
    Dial = (mlError = SUCCESS)
End Function
'
'   Hangs up the connection made in Dial
'
Public Function HangUp() As Boolean
    mlError = RasHangUpA(mlConnection)
    HangUp = (mlError = SUCCESS)
End Function
'
'   Returns the error message that occurred in any of
'   the functions in this class.  The mlError is set in
'   the routines that call the RAS API functions.
'
Public Function ErrorMessage() As String
    Dim sMsg As String

    If mlError = 0 Then
        ErrorMessage = ""
        Exit Function
    End If
    Select Case mlError
        Case PENDING ' (RASBASE+0)
            sMsg = "An operation is pending. "
        Case ERROR_INVALID_PORT_HANDLE ' (RASBASE+1)
            sMsg = "The port handle is invalid. "
        Case ERROR_PORT_ALREADY_OPEN ' (RASBASE+2)
            sMsg = "The port is already open. "
        Case ERROR_BUFFER_TOO_SMALL ' (RASBASE+3)
            sMsg = "Caller's buffer is too small. "
        Case ERROR_WRONG_INFO_SPECIFIED ' (RASBASE+4)
            sMsg = "Wrong information specified. "
        Case ERROR_CANNOT_SET_PORT_INFO ' (RASBASE+5)
            sMsg = "Cannot set port information. "
        Case ERROR_PORT_NOT_CONNECTED ' (RASBASE+6)
            sMsg = "The port is not connected. "
        Case ERROR_EVENT_INVALID ' (RASBASE+7)
            sMsg = "The event is invalid. "
        Case ERROR_DEVICE_DOES_NOT_EXIST ' (RASBASE+8)
            sMsg = "The device does not exist. "
        Case ERROR_DEVICETYPE_DOES_NOT_EXIST ' (RASBASE+9)
            sMsg = "The device type does not exist. "
        Case ERROR_BUFFER_INVALID ' (RASBASE+10)
            sMsg = "The buffer is invalid. "
        Case ERROR_ROUTE_NOT_AVAILABLE ' (RASBASE+11)
            sMsg = "The route is not available. "
        Case ERROR_ROUTE_NOT_ALLOCATED ' (RASBASE+12)
            sMsg = "The route is not allocated. "
        Case ERROR_INVALID_COMPRESSION_SPECIFIED ' (RASBASE+13)
            sMsg = "Invalid compression specified. "
        Case ERROR_OUT_OF_BUFFERS ' (RASBASE+14)
            sMsg = "Out of buffers. "
        Case ERROR_PORT_NOT_FOUND ' (RASBASE+15)
            sMsg = "The port was not found. "
        Case ERROR_ASYNC_REQUEST_PENDING ' (RASBASE+16)
            sMsg = "An asynchronous request is pending. "
        Case ERROR_ALREADY_DISCONNECTING ' (RASBASE+17)
            sMsg = "The port or device is already disconnecting. "
        Case ERROR_PORT_NOT_OPEN ' (RASBASE+18)
            sMsg = "The port is not open. "
        Case ERROR_PORT_DISCONNECTED ' (RASBASE+19)
            sMsg = "The port is disconnected. "
        Case ERROR_NO_ENDPOINTS ' (RASBASE+20)
            sMsg = "There are no endpoints. "
        Case ERROR_CANNOT_OPEN_PHONEBOOK ' (RASBASE+21)
            sMsg = "Cannot open the phone book file. "
        Case ERROR_CANNOT_LOAD_PHONEBOOK ' (RASBASE+22)
            sMsg = "Cannot load the phone book file. "
        Case ERROR_CANNOT_FIND_PHONEBOOK_ENTRY ' (RASBASE+23)
            sMsg = "Cannot find the phone book entry. "
        Case ERROR_CANNOT_WRITE_PHONEBOOK ' (RASBASE+24)
            sMsg = "Cannot write the phone book file. "
        Case ERROR_CORRUPT_PHONEBOOK ' (RASBASE+25)
            sMsg = "Invalid information found in the phone book file. "
        Case ERROR_CANNOT_LOAD_STRING ' (RASBASE+26)
            sMsg = "Cannot load a string. "
        Case ERROR_KEY_NOT_FOUND ' (RASBASE+27)
            sMsg = "Cannot find key. "
        Case ERROR_DISCONNECTION ' (RASBASE+28)
            sMsg = "The port was disconnected. "
        Case ERROR_REMOTE_DISCONNECTION ' (RASBASE+29)
            sMsg = "The port was disconnected by the remote machine. "
        Case ERROR_HARDWARE_FAILURE ' (RASBASE+30)
            sMsg = "The port was disconnected due to hardware failure. "
        Case ERROR_USER_DISCONNECTION ' (RASBASE+31)
            sMsg = "The port was disconnected by the user. "
        Case ERROR_INVALID_SIZE ' (RASBASE+32)
            sMsg = "The structure size is incorrect. "
        Case ERROR_PORT_NOT_AVAILABLE ' (RASBASE+33)
            sMsg = "The port is already in use or is not configured for Remote Access dial out. "
        Case ERROR_CANNOT_PROJECT_CLIENT ' (RASBASE+34)
            sMsg = "Cannot register your computer on on the remote network. "
        Case ERROR_UNKNOWN ' (RASBASE+35)
            sMsg = "Unknown error. "
        Case ERROR_WRONG_DEVICE_ATTACHED ' (RASBASE+36)
            sMsg = "The wrong device is attached to the port. "
        Case ERROR_BAD_STRING ' (RASBASE+37)
            sMsg = "The string could not be converted. "
        Case ERROR_REQUEST_TIMEOUT ' (RASBASE+38)
            sMsg = "The request has timed out. "
        Case ERROR_CANNOT_GET_LANA ' (RASBASE+39)
            sMsg = "No asynchronous net available. "
        Case ERROR_NETBIOS_ERROR ' (RASBASE+40)
            sMsg = "A NetBIOS error has occurred. "
        Case ERROR_SERVER_OUT_OF_RESOURCES ' (RASBASE+41)
            sMsg = "The server cannot allocate NetBIOS resources needed to support the client. "
        Case ERROR_NAME_EXISTS_ON_NET ' (RASBASE+42)
            sMsg = "One of your NetBIOS names is already registered on the remote network. "
        Case ERROR_SERVER_GENERAL_NET_FAILURE ' (RASBASE+43)
            sMsg = "A network adapter at the server failed. "
        Case WARNING_MSG_ALIAS_NOT_ADDED ' (RASBASE+44)
            sMsg = "You will not receive network message popups. "
        Case ERROR_AUTH_INTERNAL ' (RASBASE+45)
            sMsg = "Internal authentication error. "
        Case ERROR_RESTRICTED_LOGON_HOURS ' (RASBASE+46)
            sMsg = "The account is not permitted to logon at this time of day. "
        Case ERROR_ACCT_DISABLED ' (RASBASE+47)
            sMsg = "The account is disabled. "
        Case ERROR_PASSWD_EXPIRED ' (RASBASE+48)
            sMsg = "The password has expired. "
        Case ERROR_NO_DIALIN_PERMISSION ' (RASBASE+49)
            sMsg = "The account does not have Remote Access permission. "
        Case ERROR_SERVER_NOT_RESPONDING ' (RASBASE+50)
            sMsg = "The Remote Access server is not responding. "
        Case ERROR_FROM_DEVICE ' (RASBASE+51)
            sMsg = "Your modem ' (or other connecting device) has reported an error. "
        Case ERROR_UNRECOGNIZED_RESPONSE ' (RASBASE+52)
            sMsg = "Unrecognized response from the device. "
        Case ERROR_MACRO_NOT_FOUND ' (RASBASE+53)
            sMsg = "A macro required by the device was not found in the device .INF file section. "
        Case ERROR_MACRO_NOT_DEFINED ' (RASBASE+54)
            sMsg = "A command or response in the device .INF file section refers to an undefined macro. "
        Case ERROR_MESSAGE_MACRO_NOT_FOUND ' (RASBASE+55)
            sMsg = "The  macro was not found in the device .INF file section. "
        Case ERROR_DEFAULTOFF_MACRO_NOT_FOUND ' (RASBASE+56)
            sMsg = "The  macro in the device .INF file section contains an undefined macro. "
        Case ERROR_FILE_COULD_NOT_BE_OPENED ' (RASBASE+57)
            sMsg = "The device .INF file could not be opened. "
        Case ERROR_DEVICENAME_TOO_LONG ' (RASBASE+58)
            sMsg = "The device name in the device .INF or media .INI file is too long. "
        Case ERROR_DEVICENAME_NOT_FOUND ' (RASBASE+59)
            sMsg = "The media .INI file refers to an unknown device name. "
        Case ERROR_NO_RESPONSES ' (RASBASE+60)
            sMsg = "The device .INF file contains no responses for the command. "
        Case ERROR_NO_COMMAND_FOUND ' (RASBASE+61)
            sMsg = "The device .INF file is missing a command. "
        Case ERROR_WRONG_KEY_SPECIFIED ' (RASBASE+62)
            sMsg = "Attempted to set a macro not listed in device .INF file section. "
        Case ERROR_UNKNOWN_DEVICE_TYPE ' (RASBASE+63)
            sMsg = "The media .INI file refers to an unknown device type. "
        Case ERROR_ALLOCATING_MEMORY ' (RASBASE+64)
            sMsg = "Cannot allocate memory. "
        Case ERROR_PORT_NOT_CONFIGURED ' (RASBASE+65)
            sMsg = "The port is not configured for Remote Access. "
        Case ERROR_DEVICE_NOT_READY ' (RASBASE+66)
            sMsg = "Your modem ' (or other connecting device) is not functioning. "
        Case ERROR_READING_INI_FILE ' (RASBASE+67)
            sMsg = "Cannot read the media .INI file. "
        Case ERROR_NO_CONNECTION ' (RASBASE+68)
            sMsg = "The connection dropped. "
        Case ERROR_BAD_USAGE_IN_INI_FILE ' (RASBASE+69)
            sMsg = "The usage parameter in the media .INI file is invalid. "
        Case ERROR_READING_SECTIONNAME ' (RASBASE+70)
            sMsg = "Cannot read the section name from the media .INI file. "
        Case ERROR_READING_DEVICETYPE ' (RASBASE+71)
            sMsg = "Cannot read the device type from the media .INI file. "
        Case ERROR_READING_DEVICENAME ' (RASBASE+72)
            sMsg = "Cannot read the device name from the media .INI file. "
        Case ERROR_READING_USAGE ' (RASBASE+73)
            sMsg = "Cannot read the usage from the media .INI file. "
        Case ERROR_READING_MAXCONNECTBPS ' (RASBASE+74)
            sMsg = "Cannot read the maximum connection BPS rate from the media .INI file. "
        Case ERROR_READING_MAXCARRIERBPS ' (RASBASE+75)
            sMsg = "Cannot read the maximum carrier BPS rate from the media .INI file. "
        Case ERROR_LINE_BUSY ' (RASBASE+76)
            sMsg = "The line is busy. "
        Case ERROR_VOICE_ANSWER ' (RASBASE+77)
            sMsg = "A person answered instead of a modem. "
        Case ERROR_NO_ANSWER ' (RASBASE+78)
            sMsg = "There is no answer. "
        Case ERROR_NO_CARRIER ' (RASBASE+79)
            sMsg = "Cannot detect carrier. "
        Case ERROR_NO_DIALTONE ' (RASBASE+80)
            sMsg = "There is no dial tone. "
        Case ERROR_IN_COMMAND ' (RASBASE+81)
            sMsg = "General error reported by device. "
        Case ERROR_WRITING_SECTIONNAME ' (RASBASE+82)
            sMsg = "ERROR_WRITING_SECTIONNAME "
        Case ERROR_WRITING_DEVICETYPE ' (RASBASE+83)
            sMsg = "ERROR_WRITING_DEVICETYPE "
        Case ERROR_WRITING_DEVICENAME ' (RASBASE+84)
            sMsg = "ERROR_WRITING_DEVICENAME "
        Case ERROR_WRITING_MAXCONNECTBPS ' (RASBASE+85)
            sMsg = "ERROR_WRITING_MAXCONNECTBPS "
        Case ERROR_WRITING_MAXCARRIERBPS ' (RASBASE+86)
            sMsg = "ERROR_WRITING_MAXCARRIERBPS "
        Case ERROR_WRITING_USAGE ' (RASBASE+87)
            sMsg = "ERROR_WRITING_USAGE "
        Case ERROR_WRITING_DEFAULTOFF ' (RASBASE+88)
            sMsg = "ERROR_WRITING_DEFAULTOFF "
        Case ERROR_READING_DEFAULTOFF ' (RASBASE+89)
            sMsg = "ERROR_READING_DEFAULTOFF "
        Case ERROR_EMPTY_INI_FILE ' (RASBASE+90)
            sMsg = "ERROR_EMPTY_INI_FILE "
        Case ERROR_AUTHENTICATION_FAILURE ' (RASBASE+91)
            sMsg = "Access denied because username and/or password is invalid on the domain. "
        Case ERROR_PORT_OR_DEVICE ' (RASBASE+92)
            sMsg = "Hardware failure in port or attached device. "
        Case ERROR_NOT_BINARY_MACRO ' (RASBASE+93)
            sMsg = "ERROR_NOT_BINARY_MACRO "
        Case ERROR_DCB_NOT_FOUND ' (RASBASE+94)
            sMsg = "ERROR_DCB_NOT_FOUND "
        Case ERROR_STATE_MACHINES_NOT_STARTED ' (RASBASE+95)
            sMsg = "ERROR_STATE_MACHINES_NOT_STARTED "
        Case ERROR_STATE_MACHINES_ALREADY_STARTED ' (RASBASE+96)
            sMsg = "ERROR_STATE_MACHINES_ALREADY_STARTED "
        Case ERROR_PARTIAL_RESPONSE_LOOPING ' (RASBASE+97)
            sMsg = "ERROR_PARTIAL_RESPONSE_LOOPING "
        Case ERROR_UNKNOWN_RESPONSE_KEY ' (RASBASE+98)
            sMsg = "A response keyname in the device .INF file is not in the expected format. "
        Case ERROR_RECV_BUF_FULL ' (RASBASE+99)
            sMsg = "The device response caused buffer overflow. "
        Case ERROR_CMD_TOO_LONG ' (RASBASE+100)
            sMsg = "The expanded command in the device .INF file is too long. "
        Case ERROR_UNSUPPORTED_BPS ' (RASBASE+101)
            sMsg = "The device moved to a BPS rate not supported by the COM driver. "
        Case ERROR_UNEXPECTED_RESPONSE ' (RASBASE+102)
            sMsg = "Device response received when none expected. "
        Case ERROR_INTERACTIVE_MODE ' (RASBASE+103)
            sMsg = "ERROR_INTERACTIVE_MODE "
        Case ERROR_BAD_CALLBACK_NUMBER ' (RASBASE+104)
            sMsg = "ERROR_BAD_CALLBACK_NUMBER "
        Case ERROR_INVALID_AUTH_STATE ' (RASBASE+105)
            sMsg = "ERROR_INVALID_AUTH_STATE "
        Case ERROR_WRITING_INITBPS ' (RASBASE+106)
            sMsg = "ERROR_WRITING_INITBPS "
        Case ERROR_X25_DIAGNOSTIC ' (RASBASE+107)
            sMsg = "X.25 diagnostic indication. "
        Case ERROR_ACCT_EXPIRED ' (RASBASE+108)
            sMsg = "The account has expired. "
        Case ERROR_CHANGING_PASSWORD ' (RASBASE+109)
            sMsg = "Error changing password on domain. The password may be too short or may match a previously used password. "
        Case ERROR_OVERRUN ' (RASBASE+110)
            sMsg = "Serial overrun errors were detected while communicating with your modem. "
        Case ERROR_RASMAN_CANNOT_INITIALIZE ' (RASBASE+111)
            sMsg = "RasMan initialization failure. Check the event log. "
        Case ERROR_BIPLEX_PORT_NOT_AVAILABLE ' (RASBASE+112)
            sMsg = "Biplex port initializing. Wait a few seconds and redial. "
        Case ERROR_NO_ACTIVE_ISDN_LINES ' (RASBASE+113)
            sMsg = "No active ISDN lines are available. "
        Case ERROR_NO_ISDN_CHANNELS_AVAILABLE ' (RASBASE+114)
            sMsg = "No ISDN channels are available to make the call. "
        Case ERROR_TOO_MANY_LINE_ERRORS ' (RASBASE+115)
            sMsg = "Too many errors occured because of poor phone line quality. "
        Case ERROR_IP_CONFIGURATION ' (RASBASE+116)
            sMsg = "The Remote Access IP configuration is unusable. "
        Case ERROR_NO_IP_ADDRESSES ' (RASBASE+117)
            sMsg = "No IP addresses are available in the static pool of Remote Access IP addresses. "
        Case ERROR_PPP_TIMEOUT ' (RASBASE+118)
            sMsg = "Timed out waiting for a valid response from the remote PPP peer. "
        Case ERROR_PPP_REMOTE_TERMINATED ' (RASBASE+119)
            sMsg = "PPP terminated by remote machine. "
        Case ERROR_PPP_NO_PROTOCOLS_CONFIGURED ' (RASBASE+120)
            sMsg = "No PPP control protocols configured. "
        Case ERROR_PPP_NO_RESPONSE ' (RASBASE+121)
            sMsg = "Remote PPP peer is not responding. "
        Case ERROR_PPP_INVALID_PACKET ' (RASBASE+122)
            sMsg = "The PPP packet is invalid. "
        Case ERROR_PHONE_NUMBER_TOO_LONG ' (RASBASE+123)
            sMsg = "The phone number including prefix and suffix is too long. "
        Case ERROR_IPXCP_NO_DIALOUT_CONFIGURED ' (RASBASE+124)
            sMsg = "The IPX protocol cannot dial-out on the port because the machine is an IPX router. "
        Case ERROR_IPXCP_NO_DIALIN_CONFIGURED ' (RASBASE+125)
            sMsg = "The IPX protocol cannot dial-in on the port because the IPX router is not installed. "
        Case ERROR_IPXCP_DIALOUT_ALREADY_ACTIVE ' (RASBASE+126)
            sMsg = "The IPX protocol cannot be used for dial-out on more than one port at a time. "
        Case ERROR_ACCESSING_TCPCFGDLL ' (RASBASE+127)
            sMsg = "Cannot access TCPCFG.DLL. "
        Case ERROR_NO_IP_RAS_ADAPTER ' (RASBASE+128)
            sMsg = "Cannot find an IP adapter bound to Remote Access. "
        Case ERROR_SLIP_REQUIRES_IP ' (RASBASE+129)
            sMsg = "SLIP cannot be used unless the IP protocol is installed. "
        Case ERROR_PROJECTION_NOT_COMPLETE ' (RASBASE+130)
            sMsg = "Computer registration is not complete. "
        Case ERROR_PROTOCOL_NOT_CONFIGURED ' (RASBASE+131)
            sMsg = "The protocol is not configured. "
        Case ERROR_PPP_NOT_CONVERGING ' (RASBASE+132)
            sMsg = "The PPP negotiation is not converging. "
        Case ERROR_PPP_CP_REJECTED ' (RASBASE+133)
            sMsg = "The PPP control protocol for this network protocol is not available on the server. "
        Case ERROR_PPP_LCP_TERMINATED ' (RASBASE+134)
            sMsg = "The PPP link control protocol terminated. "
        Case ERROR_PPP_REQUIRED_ADDRESS_REJECTED ' (RASBASE+135)
            sMsg = "The requested address was rejected by the server. "
        Case ERROR_PPP_NCP_TERMINATED ' (RASBASE+136)
            sMsg = "The remote computer terminated the control protocol. "
        Case ERROR_PPP_LOOPBACK_DETECTED ' (RASBASE+137)
            sMsg = "Loopback detected. "
        Case ERROR_PPP_NO_ADDRESS_ASSIGNED ' (RASBASE+138)
            sMsg = "The server did not assign an address. "
        Case ERROR_CANNOT_USE_LOGON_CREDENTIALS ' (RASBASE+139)
            sMsg = "The authentication protocol required by the remote server cannot use the Windows NT encrypted password. Redial, entering the password explicitly. "
        Case ERROR_TAPI_CONFIGURATION ' (RASBASE+140)
            sMsg = "Invalid TAPI configuration. "
        Case ERROR_NO_LOCAL_ENCRYPTION ' (RASBASE+141)
            sMsg = "The local computer does not support encryption. "
        Case ERROR_NO_REMOTE_ENCRYPTION ' (RASBASE+142)
            sMsg = "The remote server does not support encryption. "
        Case ERROR_REMOTE_REQUIRES_ENCRYPTION ' (RASBASE+143)
            sMsg = "The remote server requires encryption. "
        Case ERROR_IPXCP_NET_NUMBER_CONFLICT ' (RASBASE+144)
            sMsg = "Cannot use the IPX network number assigned by remote server. Check the event log. "
        Case ERROR_INVALID_SMM ' (RASBASE+145)
            sMsg = "ERROR_INVALID_SMM "
        Case ERROR_SMM_UNINITIALIZED ' (RASBASE+146)
            sMsg = "ERROR_SMM_UNINITIALIZED "
        Case ERROR_NO_MAC_FOR_PORT ' (RASBASE+147)
            sMsg = "ERROR_NO_MAC_FOR_PORT "
        Case ERROR_SMM_TIMEOUT ' (RASBASE+148)
            sMsg = "ERROR_SMM_TIMEOUT "
        Case ERROR_BAD_PHONE_NUMBER ' (RASBASE+149)
            sMsg = "ERROR_BAD_PHONE_NUMBER "
        Case ERROR_WRONG_MODULE ' (RASBASE+150)
            sMsg = "ERROR_WRONG_MODULE "
        Case ERROR_INVALID_CALLBACK_NUMBER ' (RASBASE+151)
            sMsg = "Invalid callback number. Only the characters 0 to 9, T, P, W, ' (, ), -, @, and space are allowed in the number. "
        Case ERROR_SCRIPT_SYNTAX ' (RASBASE+152)
            sMsg = "A syntax error was encountered while processing a script. "
        Case Else
            sMsg = "Unknown error number " & mlError & " occurred."
    End Select
    ErrorMessage = sMsg
End Function