You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
374 lines
10 KiB
374 lines
10 KiB
/*****************************************************************/
|
|
/** Microsoft LAN Manager **/
|
|
/** Copyright(c) Microsoft Corp., 1989-1990 **/
|
|
/*****************************************************************/
|
|
|
|
/*
|
|
* Windows/Network Interface -- LAN Manager Version
|
|
*
|
|
* HISTORY
|
|
* terryk 01-Nov-1991 WIN32 conversion
|
|
* Yi-HsinS 31-Dec-1991 Unicode work
|
|
* terryk 03-Jan-1992 Removed the GetError call
|
|
* terryk 10-Jan-1992 Fixed SetNetError problem
|
|
* beng 06-Apr-1992 Unicode visitation
|
|
* terryk 10-Oct-1993 Remove ErrorPopup
|
|
*/
|
|
|
|
#define INCL_WINDOWS
|
|
#define INCL_DOSERRORS
|
|
#define INCL_NETERRORS
|
|
#define INCL_NETCONS
|
|
#define INCL_NETLIB
|
|
#define _WINNETWK_
|
|
#include <lmui.hxx>
|
|
#undef _WINNETWK_
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <winnetwk.h>
|
|
#include <npapi.h>
|
|
#include <winlocal.h>
|
|
#include <errornum.h>
|
|
#include <string.hxx>
|
|
#include <strchlit.hxx>
|
|
|
|
#define INCL_BLT_MSGPOPUP
|
|
#include <blt.hxx>
|
|
|
|
#include <uitrace.hxx>
|
|
|
|
extern HMODULE hModule ;
|
|
#define NETMSG_DLL SZ("NETMSG.DLL")
|
|
|
|
APIERR GetLMProviderName();
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: GetErrorText
|
|
|
|
SYNOPSIS: Internal get error text function. It is called by
|
|
WNetGetGetText and SetNetError.
|
|
|
|
ENTRY: UINT nError - error number
|
|
LPTSTR - return string
|
|
LPUINT - return buffer size (in TCHARs)
|
|
|
|
RETURNS: UINT - WN_NO_ERROR if the error number is too big or
|
|
cannot find the error string.
|
|
Otherwise, it will return WN_SUCCESS.
|
|
|
|
HISTORY:
|
|
terryk 11-Jan-92 Created
|
|
beng 06-Apr-1992 Clarify BYTEs vs TCHARs
|
|
(this will probably change)
|
|
beng 03-Aug-1992 Clarity TCHARs vs BYTEs
|
|
(see, it did change)
|
|
Yi-HsinS12-Nov-1992 Use NLS_STR::Load instead of LoadString
|
|
chuckc 10-Dec-1992 Use FormatMessage since NLS_STR::Load
|
|
has dependency on BltInit which may not
|
|
happen for non GUI uses of ntlanman.dll
|
|
anirudhs29-Mar-1996 Remove bogus call to GetUIErrorString
|
|
|
|
********************************************************************/
|
|
|
|
UINT GetErrorText( UINT nError,
|
|
LPTSTR lpBuffer,
|
|
LPUINT lpnBufferSize )
|
|
{
|
|
// Avoid returning text for internal strings
|
|
if (nError >= IDS_UI_SHELL_EXPORTED_LAST)
|
|
return WN_NET_ERROR;
|
|
::memsetf(lpBuffer, 0, *lpnBufferSize * sizeof(TCHAR)) ;
|
|
|
|
INT cch;
|
|
|
|
if ( nError >= IDS_UI_SHELL_BASE ) // in our own error range
|
|
{
|
|
// The code here used to call GetUIErrorString in ntlanui.dll.
|
|
// This would always fail because ntlanui.dll doesn't export
|
|
// GetUIErrorString. Also, there are no error strings in
|
|
// this range in ntlanui.dll.
|
|
ASSERT(!"Unexpected error from LanMan call");
|
|
|
|
// Fall through to FormatMessage.
|
|
}
|
|
|
|
// only get here if we want to call FormatMessage for either Net
|
|
// or system errors.
|
|
|
|
HANDLE hmod = NULL;
|
|
DWORD dwFlags = FORMAT_MESSAGE_IGNORE_INSERTS |
|
|
FORMAT_MESSAGE_MAX_WIDTH_MASK ;
|
|
|
|
if ( nError < MIN_LANMAN_MESSAGE_ID || nError > MAX_LANMAN_MESSAGE_ID )
|
|
{
|
|
// System errors
|
|
dwFlags |= FORMAT_MESSAGE_FROM_SYSTEM;
|
|
}
|
|
else
|
|
{
|
|
// must be Net errors
|
|
dwFlags |= FORMAT_MESSAGE_FROM_HMODULE;
|
|
hmod = ::LoadLibraryEx( NETMSG_DLL,
|
|
NULL,
|
|
LOAD_WITH_ALTERED_SEARCH_PATH );
|
|
|
|
if ( hmod == 0 )
|
|
{
|
|
return WN_NET_ERROR;
|
|
}
|
|
}
|
|
|
|
cch = (UINT) ::FormatMessage( dwFlags,
|
|
hmod,
|
|
nError,
|
|
0,
|
|
(LPTSTR) lpBuffer,
|
|
*lpnBufferSize,
|
|
NULL );
|
|
if (cch == 0)
|
|
return WN_NET_ERROR ;
|
|
|
|
*lpnBufferSize = cch + 1;
|
|
return WN_SUCCESS;
|
|
}
|
|
|
|
// we are UNICODE on Win32, hence below is OK,
|
|
// the proc name is deliberately ANSI since GetProcAddress
|
|
// takes ANSI only.
|
|
|
|
#define WNET_DLL SZ("MPR.DLL")
|
|
#define WNETSETLASTERROR_NAME "WNetSetLastErrorW"
|
|
#define WNETGETLASTERROR_NAME "WNetGetLastErrorW"
|
|
|
|
typedef VOID TYPE_WNetSetLastErrorW(
|
|
DWORD err,
|
|
LPWSTR lpError,
|
|
LPWSTR lpProviders
|
|
);
|
|
TYPE_WNetSetLastErrorW *vpfSetLastError = NULL ;
|
|
|
|
typedef VOID TYPE_WNetGetLastErrorW(
|
|
LPDWORD lpError,
|
|
LPWSTR lpErrorBuf,
|
|
DWORD nErrorBufLen,
|
|
LPWSTR lpNameBuf,
|
|
DWORD nNameBufLen
|
|
);
|
|
TYPE_WNetGetLastErrorW *vpfGetLastError = NULL ;
|
|
|
|
|
|
/*****
|
|
*
|
|
* SetNetError
|
|
*
|
|
* Purpose:
|
|
* Set network error for later retrieval.
|
|
* Should only be called from within MapError() in WIN32
|
|
*
|
|
* Parameters:
|
|
* err Network error code.
|
|
*
|
|
* Returns:
|
|
* Nothing.
|
|
*
|
|
* Globals:
|
|
* Sets WLastNetErrorCode, used in WNetGetError.
|
|
*
|
|
* Notes:
|
|
* CODEWORK - we have plans to put all message files in one
|
|
* dll. when that happens, the call to GetErrorText wont find
|
|
* the NERR errors, unless we mod GetErrorText.
|
|
*/
|
|
|
|
void SetNetError ( APIERR errNetErr )
|
|
{
|
|
// Initialize pszNTLanMan
|
|
APIERR err = GetLMProviderName();
|
|
if (err != WN_SUCCESS)
|
|
return ;
|
|
|
|
// if need, load the MPR dll to get hold of
|
|
// WNetSetLastError. If we cant get it, just return.
|
|
if (vpfSetLastError == NULL)
|
|
{
|
|
HMODULE hDLL ;
|
|
|
|
hDLL = ::LoadLibraryEx( WNET_DLL,
|
|
NULL,
|
|
LOAD_WITH_ALTERED_SEARCH_PATH );
|
|
if (hDLL == NULL)
|
|
return ;
|
|
|
|
vpfSetLastError = (TYPE_WNetSetLastErrorW *)
|
|
::GetProcAddress(hDLL, WNETSETLASTERROR_NAME) ;
|
|
if (vpfSetLastError == NULL)
|
|
return ;
|
|
}
|
|
|
|
TCHAR szBuffer[ MAX_TEXT_SIZE ];
|
|
UINT uBufSize = sizeof(szBuffer)/sizeof(szBuffer[0]) ;
|
|
err = GetErrorText( (UINT)errNetErr, szBuffer, &uBufSize );
|
|
|
|
// if we cannot find the string, use empty string but return the
|
|
// error and provider info.
|
|
if ( err == WN_SUCCESS )
|
|
(*vpfSetLastError)( (UINT)errNetErr, szBuffer, (TCHAR *) pszNTLanMan );
|
|
else
|
|
(*vpfSetLastError)( (UINT)errNetErr, SZ(""), (TCHAR *) pszNTLanMan );
|
|
|
|
} /* SetNetError */
|
|
|
|
/*****
|
|
*
|
|
* GetNetErrorCode
|
|
*
|
|
* Purpose:
|
|
* Get network error for the current thread.
|
|
*
|
|
* Parameters:
|
|
* None.
|
|
*
|
|
* Returns:
|
|
* Network error code.
|
|
*/
|
|
|
|
APIERR GetNetErrorCode ()
|
|
{
|
|
APIERR errNetErr = NERR_Success;
|
|
|
|
// if need, load the MPR dll to get hold of
|
|
// WNetGetLastError. If we cant get it, just return.
|
|
if (vpfGetLastError == NULL)
|
|
{
|
|
HMODULE hDLL ;
|
|
|
|
hDLL = ::LoadLibraryEx( WNET_DLL,
|
|
NULL,
|
|
LOAD_WITH_ALTERED_SEARCH_PATH );
|
|
if (hDLL == NULL)
|
|
return errNetErr;
|
|
|
|
vpfGetLastError = (TYPE_WNetGetLastErrorW *)
|
|
::GetProcAddress(hDLL, WNETGETLASTERROR_NAME) ;
|
|
if (vpfGetLastError == NULL)
|
|
return errNetErr;
|
|
}
|
|
|
|
WCHAR szError;
|
|
WCHAR szName;
|
|
|
|
(*vpfGetLastError)( (PULONG)&errNetErr, &szError, 1, &szName, 1 );
|
|
|
|
return errNetErr;
|
|
} /* GetNetErrorCode */
|
|
|
|
|
|
/*
|
|
* MapError
|
|
*
|
|
* This function maps a NERR error code to a WinNet error code.
|
|
* It also does a SetLastError/WnetSetLastError as need.
|
|
*
|
|
* If no mapping exists, this function calls WNetSetLastError and
|
|
* returns WN_EXTENDED_ERROR.
|
|
*
|
|
* Calling it with WN_SUCCESS or NERR_Success is a NO-OP.
|
|
*
|
|
* Parameters:
|
|
* usNetErr The standard (normally ERROR_* or NERR_*) error
|
|
* code to be mapped.
|
|
*
|
|
* Return value:
|
|
* The WinNet error code (WN_*) corresponding to the given usNetErr.
|
|
*
|
|
* Notes:
|
|
* The caller may use MapError as follows:
|
|
*
|
|
* WORD NPxxx( void )
|
|
* {
|
|
* // etc.
|
|
*
|
|
* USHORT usErr = NetXxx();
|
|
* switch ( usErr )
|
|
* {
|
|
* // special-case error returns here (when applicable)
|
|
* default:
|
|
* break;
|
|
* }
|
|
*
|
|
* return MapError( usErr );
|
|
*
|
|
* } // NPxxx
|
|
*
|
|
*
|
|
* Also, it is harmless to remap and error that has already
|
|
* been mapped to the WN_* range. This will just result in
|
|
* the same error.
|
|
*/
|
|
|
|
UINT MapError( APIERR err )
|
|
{
|
|
APIERR errMapped ;
|
|
|
|
switch ( err )
|
|
{
|
|
case NERR_Success:
|
|
errMapped = WN_SUCCESS;
|
|
break ;
|
|
|
|
case ERROR_NETWORK_ACCESS_DENIED:
|
|
case ERROR_ACCESS_DENIED:
|
|
errMapped = WN_ACCESS_DENIED;
|
|
break ;
|
|
|
|
case ERROR_BAD_NET_NAME:
|
|
errMapped = WN_BAD_NETNAME;
|
|
break ;
|
|
|
|
/*
|
|
* Fall through
|
|
*/
|
|
case ERROR_INVALID_PASSWORD:
|
|
case NERR_BadPasswordCore:
|
|
case NERR_BadPassword:
|
|
errMapped = WN_BAD_PASSWORD;
|
|
break ;
|
|
|
|
case NERR_BadUsername:
|
|
errMapped = WN_BAD_USER ;
|
|
break ;
|
|
|
|
case NERR_WkstaNotStarted:
|
|
errMapped = WN_NO_NETWORK ;
|
|
break ;
|
|
|
|
case NERR_UseNotFound:
|
|
errMapped = WN_NOT_CONNECTED ;
|
|
break ;
|
|
|
|
case NERR_OpenFiles:
|
|
errMapped = WN_OPEN_FILES ;
|
|
break ;
|
|
|
|
case NERR_DevInUse:
|
|
errMapped = WN_DEVICE_IN_USE ;
|
|
break ;
|
|
|
|
default:
|
|
if (err < NERR_BASE)
|
|
// not network error. assume it is base Win32
|
|
errMapped = err ;
|
|
else
|
|
{
|
|
SetNetError( err ); // let SetNetError figure it out
|
|
errMapped = WN_EXTENDED_ERROR; // its an extended error
|
|
}
|
|
}
|
|
|
|
// Don't need to SetLastError since MPR always does it for us
|
|
|
|
return((UINT)errMapped) ;
|
|
|
|
} // MapError
|