Source code for Issue Number 28

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 any class module and change the name of the module to cNetworkInterface.

'----------------------------------------------------------------------
'
'   Module Name:    cNetworkInterface
'   Written By:     C&D Programming Corp.
'   Create Date:    2/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

'
'   Maximum length of a network path allowed in several of the
'   networking API calls
'
Private Const MAX_PATH = 260

'
'   Other Error Codes
'
Private Const WN_SUCCESS = 0&
Private Const ERROR_INVALID_PASSWORD = 86&
Private Const ERROR_NOT_ENOUGH_MEMORY = 8&
Private Const ERROR_INVALID_PARAMETER = 87&
Private Const ERROR_NO_MORE_ITEMS = 259&

Private Const ERROR_NOT_SUPPORTED = 50&
Private Const ERROR_REM_NOT_LIST = 51&
Private Const ERROR_DUP_NAME = 52&
Private Const ERROR_BAD_NETPATH = 53&
Private Const ERROR_NETWORK_BUSY = 54&
Private Const ERROR_DEV_NOT_EXIST = 55 '  dderror
Private Const ERROR_TOO_MANY_CMDS = 56&
Private Const ERROR_ADAP_HDW_ERR = 57&
Private Const ERROR_BAD_NET_RESP = 58&
Private Const ERROR_UNEXP_NET_ERR = 59&
Private Const ERROR_BAD_REM_ADAP = 60&
Private Const ERROR_PRINTQ_FULL = 61&
Private Const ERROR_NO_SPOOL_SPACE = 62&
Private Const ERROR_PRINT_CANCELLED = 63&
Private Const ERROR_NETNAME_DELETED = 64&
Private Const ERROR_NETWORK_ACCESS_DENIED = 65&
Private Const ERROR_BAD_DEV_TYPE = 66&
Private Const ERROR_BAD_NET_NAME = 67&
Private Const ERROR_TOO_MANY_NAMES = 68&
Private Const ERROR_TOO_MANY_SESS = 69&
Private Const ERROR_SHARING_PAUSED = 70&
Private Const ERROR_REQ_NOT_ACCEP = 71&
Private Const ERROR_REDIR_PAUSED = 72&

'
'  Winnet32 Status Codes
'
Private Const ERROR_BAD_USERNAME = 2202&
Private Const ERROR_NOT_CONNECTED = 2250&
Private Const ERROR_OPEN_FILES = 2401&
Private Const ERROR_DEVICE_IN_USE = 2404&
Private Const ERROR_BAD_DEVICE = 1200&
Private Const ERROR_CONNECTION_UNAVAIL = 1201&
Private Const ERROR_DEVICE_ALREADY_REMEMBERED = 1202&
Private Const ERROR_NO_NET_OR_BAD_PATH = 1203&
Private Const ERROR_BAD_PROVIDER = 1204&
Private Const ERROR_CANNOT_OPEN_PROFILE = 1205&
Private Const ERROR_BAD_PROFILE = 1206&
Private Const ERROR_NOT_CONTAINER = 1207&
Private Const ERROR_EXTENDED_ERROR = 1208&
Private Const ERROR_INVALID_GROUPNAME = 1209&
Private Const ERROR_INVALID_COMPUTERNAME = 1210&
Private Const ERROR_INVALID_EVENTNAME = 1211&
Private Const ERROR_INVALID_DOMAINNAME = 1212&
Private Const ERROR_INVALID_SERVICENAME = 1213&
Private Const ERROR_INVALID_NETNAME = 1214&
Private Const ERROR_INVALID_SHARENAME = 1215&
Private Const ERROR_INVALID_PASSWORDNAME = 1216&
Private Const ERROR_INVALID_MESSAGENAME = 1217&
Private Const ERROR_INVALID_MESSAGEDEST = 1218&
Private Const ERROR_SESSION_CREDENTIAL_CONFLICT = 1219&
Private Const ERROR_REMOTE_SESSION_LIMIT_EXCEEDED = 1220&
Private Const ERROR_DUP_DOMAINNAME = 1221&
Private Const ERROR_NO_NETWORK = 1222&
Private Const ERROR_CANCELLED = 1223
Private Const ERROR_USER_MAPPED_FILE = 1224
Private Const ERROR_CONNECTION_REFUSED = 1225
Private Const ERROR_GRACEFUL_DISCONNECT = 1226
Private Const ERROR_ADDRESS_ALREADY_ASSOCIATED = 1227
Private Const ERROR_ADDRESS_NOT_ASSOCIATED = 1228
Private Const ERROR_CONNECTION_INVALID = 1229
Private Const ERROR_CONNECTION_ACTIVE = 1230
Private Const ERROR_NETWORK_UNREACHABLE = 1231
Private Const ERROR_HOST_UNREACHABLE = 1232
Private Const ERROR_PROTOCOL_UNREACHABLE = 1233
Private Const ERROR_PORT_UNREACHABLE = 1234
Private Const ERROR_REQUEST_ABORTED = 1235
Private Const ERROR_CONNECTION_ABORTED = 1236
Private Const ERROR_RETRY = 1237
Private Const ERROR_CONNECTION_COUNT_LIMIT = 1238
Private Const ERROR_LOGIN_TIME_RESTRICTION = 1239
Private Const ERROR_LOGIN_WKSTA_RESTRICTION = 1240
Private Const ERROR_INCORRECT_ADDRESS = 1241
Private Const ERROR_ALREADY_REGISTERED = 1242
Private Const ERROR_SERVICE_NOT_FOUND = 1243
Private Const ERROR_NOT_AUTHENTICATED = 1244
Private Const ERROR_NOT_LOGGED_ON = 1245
Private Const ERROR_CONTINUE = 1246
Private Const ERROR_ALREADY_INITIALIZED = 1247
Private Const ERROR_NO_MORE_DEVICES = 1248
Private Const ERROR_NO_SUCH_SITE = 1249
Private Const ERROR_DOMAIN_CONTROLLER_EXISTS = 1250
Private Const ERROR_DS_NOT_INSTALLED = 1251

'
' Error retrieval function for the network library API
'
Private Declare Function WNetGetLastError Lib "mpr.dll" _
    Alias "WNetGetLastErrorA" _
    (lpError As Long, ByVal lpErrorBuf As String, _
    ByVal nErrorBufSize As Long, ByVal lpNameBuf As String, _
    ByVal nNameBufSize As Long) As Long

'
'   Simple Network Resource connection and disconnection API calls.
'
Private Declare Function WNetAddConnection Lib "mpr.dll" Alias "WNetAddConnectionA" _
    (ByVal lpszNetPath As String, ByVal lpszPassword As String, _
    ByVal lpszLocalName As String) As Long
Private Declare Function WNetCancelConnection Lib "mpr.dll" Alias "WNetCancelConnectionA" _
    (ByVal lpszName As String, ByVal bForce As Long) As Long

Public Function ConnectResource(sLocalName As String, sRemoteName As String, _
                                sPassword As String)
    Dim lReturnVal As Long

    lReturnVal = WNetAddConnection(sRemoteName, sPassword & vbNullChar, _
                                    sLocalName & vbNullChar)
    If lReturnVal <> WN_SUCCESS Then
        Err.Raise lReturnVal, "cNetworkInterface.ConnectResource", WNetErrorDescription(lReturnVal)
        Exit Function
    End If
End Function

Public Function DisconnectResource(sLocalName As String, Optional bForce As Boolean = False)
    Dim lReturnVal As Long

    lReturnVal = WNetCancelConnection(sLocalName, bForce)
    If lReturnVal <> WN_SUCCESS Then
        Err.Raise lReturnVal, "cNetworkInterface.DisconnectResource", WNetErrorDescription(lReturnVal)
        Exit Function
    End If
End Function

'
'   When calling API functions, the strings returned often have a Null
'   (or vbNullChar, which is the VB shortcut) character at the end of the
'   string.  This function removes the Null character.
'
Private Function RemoveNull(sData As String) As String
    Dim iNullPos As Integer

    iNullPos = InStr(sData, vbNullChar)
    If iNullPos <> 0 Then
        RemoveNull = Left(sData, iNullPos - 1)
    Else
        RemoveNull = sData
    End If
End Function

Public Function WNetErrorDescription(lError As Long)
    Dim sMsg As String

    Select Case lError
        '
        ' 32-Bit Networking Error Codes
        '
        Case ERROR_EXTENDED_ERROR
            sMsg = "An extended error has occurred. " & WNetExtendedError(lError)
        Case ERROR_BAD_USERNAME
            sMsg = "The specified username is invalid."
        Case ERROR_NOT_CONNECTED
            sMsg = "This network connection does not exist."
        Case ERROR_OPEN_FILES
            sMsg = "This network connection has files open or requests pending."
        Case ERROR_DEVICE_IN_USE
            sMsg = "The device is in use by an active process and cannot be disconnected."
        Case ERROR_BAD_DEVICE
            sMsg = "The specified device name is invalid."
        Case ERROR_CONNECTION_UNAVAIL
            sMsg = "The device is not currently connected but it is a remembered connection."
        Case ERROR_DEVICE_ALREADY_REMEMBERED
            sMsg = "An attempt was made to remember a device that had previously been remembered."
        Case ERROR_NO_NET_OR_BAD_PATH
            sMsg = "No network provider accepted the given network path."
        Case ERROR_BAD_PROVIDER
            sMsg = "The specified network provider name is invalid."
        Case ERROR_CANNOT_OPEN_PROFILE
            sMsg = "Unable to open the network connection profile."
        Case ERROR_BAD_PROFILE
            sMsg = "The network connection profile is corrupt."
        Case ERROR_NOT_CONTAINER
            sMsg = "Cannot enumerate a non-container."
        Case ERROR_INVALID_GROUPNAME
            sMsg = "The format of the specified group name is invalid."
        Case ERROR_INVALID_COMPUTERNAME
            sMsg = "The format of the specified computer name is invalid."
        Case ERROR_INVALID_EVENTNAME
            sMsg = "The format of the specified event name is invalid."
        Case ERROR_INVALID_DOMAINNAME
            sMsg = "The format of the specified domain name is invalid."
        Case ERROR_INVALID_SERVICENAME
            sMsg = "The format of the specified service name is invalid."
        Case ERROR_INVALID_NETNAME
            sMsg = "The format of the specified network name is invalid."
        Case ERROR_INVALID_SHARENAME
            sMsg = "The format of the specified share name is invalid."
        Case ERROR_INVALID_PASSWORDNAME
            sMsg = "The format of the specified password is invalid."
        Case ERROR_INVALID_MESSAGENAME
            sMsg = "The format of the specified message name is invalid."
        Case ERROR_INVALID_MESSAGEDEST
            sMsg = "The format of the specified message destination is invalid."
        Case ERROR_SESSION_CREDENTIAL_CONFLICT
            sMsg = "The credentials supplied conflict with an existing set of credentials."
        Case ERROR_REMOTE_SESSION_LIMIT_EXCEEDED
            sMsg = "An attempt was made to establish a session to a Lan Manager server, but there are already too many sessions established to that server."
        Case ERROR_DUP_DOMAINNAME
            sMsg = "The workgroup or domain name is already in use by another computer on the network."
        Case ERROR_NO_NETWORK
            sMsg = "The network is not present or not started."
        Case ERROR_CANCELLED
            sMsg = "The operation was canceled by the user."
        Case ERROR_USER_MAPPED_FILE
            sMsg = "The requested operation cannot be performed on a file with a user-mapped section open."
        Case ERROR_CONNECTION_REFUSED
            sMsg = "The remote system refused the network connection."
        Case ERROR_GRACEFUL_DISCONNECT
            sMsg = "The network connection was gracefully closed."
        Case ERROR_ADDRESS_ALREADY_ASSOCIATED
            sMsg = "The network transport endpoint already has an address associated with it."
        Case ERROR_ADDRESS_NOT_ASSOCIATED
            sMsg = "An address has not yet been associated with the network endpoint."
        Case ERROR_CONNECTION_INVALID
            sMsg = "An operation was attempted on a nonexistent network connection."
        Case ERROR_CONNECTION_ACTIVE
            sMsg = "An invalid operation was attempted on an active network connection."
        Case ERROR_NETWORK_UNREACHABLE
            sMsg = "The remote network is not reachable by the transport."
        Case ERROR_HOST_UNREACHABLE
            sMsg = "The remote system is not reachable by the transport."
        Case ERROR_PROTOCOL_UNREACHABLE
            sMsg = "The remote system does not support the transport protocol."
        Case ERROR_PORT_UNREACHABLE
            sMsg = "No service is operating at the destination network endpoint on the remote system."
        Case ERROR_REQUEST_ABORTED
            sMsg = "The request was aborted."
        Case ERROR_CONNECTION_ABORTED
            sMsg = "The network connection was aborted by the local system."
        Case ERROR_RETRY
            sMsg = "The operation could not be completed. A retry should be performed."
        Case ERROR_CONNECTION_COUNT_LIMIT
            sMsg = "A connection to the server could not be made because the limit on the number of concurrent connections for this account has been reached."
        Case ERROR_LOGIN_TIME_RESTRICTION
            sMsg = "Attempting to log in during an unauthorized time of day for this account."
        Case ERROR_LOGIN_WKSTA_RESTRICTION
            sMsg = "The account is not authorized to log in from this station."
        Case ERROR_INCORRECT_ADDRESS
            sMsg = "The network address could not be used for the operation requested."
        Case ERROR_ALREADY_REGISTERED
            sMsg = "The service is already registered."
        Case ERROR_SERVICE_NOT_FOUND
            sMsg = "The specified service does not exist."
        Case ERROR_NOT_AUTHENTICATED
            sMsg = "The operation being requested was not performed because the user has not been authenticated."
        Case ERROR_NOT_LOGGED_ON
            sMsg = "The operation being requested was not performed because the user has not logged on to the network. The specified service does not exist."
        Case ERROR_CONTINUE
            sMsg = "Continue with work in progress."
        Case ERROR_ALREADY_INITIALIZED
            sMsg = "An attempt was made to perform an initialization operation when initialization has already been completed."
        Case ERROR_NO_MORE_DEVICES
            sMsg = "No more local devices."
        Case ERROR_NO_SUCH_SITE
            sMsg = "The specified site does not exist."
        Case ERROR_DOMAIN_CONTROLLER_EXISTS
            sMsg = "A domain controller with the specified name already exists."
        Case ERROR_DS_NOT_INSTALLED
            sMsg = "An error occurred while installing the Windows NT directory service. Please view the event log for more information."

        '
        ' Non 32-Bit Error Codes
        '
        Case ERROR_INVALID_PASSWORD '  = 86&
            sMsg = "Invalid password to access resource"
        Case ERROR_NOT_ENOUGH_MEMORY ' = 8&
            sMsg = "Not enough memory to process the request"
        Case ERROR_INVALID_PARAMETER ' = 87&
            sMsg = "Invalid parameter"
        Case ERROR_NO_MORE_ITEMS ' = 259&
            sMsg = "No more items available"
        Case ERROR_NOT_SUPPORTED ' 50&
            sMsg = "The network request is not supported."
        Case ERROR_REM_NOT_LIST ' 51&
            sMsg = "The remote computer is not available."
        Case ERROR_DUP_NAME ' 52&
            sMsg = "A duplicate name exists on the network."
        Case ERROR_BAD_NETPATH ' 53&
            sMsg = "The network path was not found."
        Case ERROR_NETWORK_BUSY ' 54&
            sMsg = "The network is busy."
        Case ERROR_DEV_NOT_EXIST ' 55 '  dderror
            sMsg = "The specified network resource or device is no longer available."
        Case ERROR_TOO_MANY_CMDS ' 56&
            sMsg = "The network BIOS command limit has been reached."
        Case ERROR_ADAP_HDW_ERR ' 57&
            sMsg = "A network adapter hardware error occurred."
        Case ERROR_BAD_NET_RESP ' 58&
            sMsg = "The specified server cannot perform the requested operation."
        Case ERROR_UNEXP_NET_ERR ' 59&
            sMsg = "An unexpected network error occurred."
        Case ERROR_BAD_REM_ADAP ' 60&
            sMsg = "The remote adapter is not compatible."
        Case ERROR_PRINTQ_FULL ' 61&
            sMsg = "The printer queue is full."
        Case ERROR_NO_SPOOL_SPACE ' 62&
            sMsg = "Space to store the file waiting to be printed is not available on the server."
        Case ERROR_PRINT_CANCELLED ' 63&
            sMsg = "Your file waiting to be printed was deleted."
        Case ERROR_NETNAME_DELETED ' 64&
            sMsg = "The specified network name is no longer available."
        Case ERROR_NETWORK_ACCESS_DENIED ' 65&
            sMsg = "Network access is denied."
        Case ERROR_BAD_DEV_TYPE ' 66&
            sMsg = "The network resource type is not correct."
        Case ERROR_BAD_NET_NAME ' 67&
            sMsg = "The network name cannot be found."
        Case ERROR_TOO_MANY_NAMES ' 68&
            sMsg = "The name limit for the local computer network adapter card was exceeded."
        Case ERROR_TOO_MANY_SESS ' 69&
            sMsg = "The network BIOS session limit was exceeded."
        Case ERROR_SHARING_PAUSED ' 70&
            sMsg = "The remote server has been paused or is in the process of being started."
        Case ERROR_REQ_NOT_ACCEP ' 71&
            sMsg = "The network request was not accepted."
        Case ERROR_REDIR_PAUSED ' 72&
            sMsg = "The specified printer or disk device has been paused."
        Case Else
            sMsg = "Error " & lError & " occurred.  No description defined for this error code."
    End Select
    WNetErrorDescription = sMsg
End Function

Public Function WNetExtendedError(lError As Long) As String
    Dim lRet As Long
    Dim lErrorBuf As Long
    Dim sErrorBuf As String
    Dim lNameBuf As Long
    Dim sNameBuf As String

    ' This should work in Windows 95 or NT
    sErrorBuf = Space(256)
    lErrorBuf = Len(sErrorBuf)
    sNameBuf = Space(256)
    lNameBuf = Len(sNameBuf)

    lRet = WNetGetLastError(lError, sErrorBuf, lErrorBuf, sNameBuf, lNameBuf)
    ' for now, just return the error text
    WNetExtendedError = RemoveNull(sErrorBuf)
End Function