windows-nt/Source/XPSP1/NT/admin/netui/shell/util/miscapis.cxx
2020-09-26 16:20:57 +08:00

312 lines
9.1 KiB
C++

/*****************************************************************/
/** Microsoft LAN Manager **/
/** Copyright(c) Microsoft Corp., 1990 **/
/*****************************************************************/
/*
MiscAPIs.cxx
Miscallaneous APIs
FILE HISTORY:
jonn 14-Jan-1991 Split from winprof.cxx
jonn 17-Jan-1991 Split off lm21util.cxx, lm30spfc.cxx
jonn 02-Feb-1991 Removed unused routines
rustanl 12-Apr-1991 Added UI_UNCPathCompare and
UI_UNCPathValidate
beng 17-May-1991 Correct lmui.hxx usage
jonn 22-May-1991 Added MyNetUseAdd (was in winprof.cxx)
rustanl 24-May-1991 Added AUTO_CURSOR to MyNetUseAdd
terryk 31-Oct-1991 add mnet.h and change I_NetXXX to
I_MNetXXX
Yi-HsinS 31-Dec-1991 Unicode work
terryk 10-Oct-1993 deleted MyNetUseAdd
*/
#define INCL_WINDOWS
#define INCL_WINDOWS_GDI
#define INCL_DOSERRORS
#define INCL_NETERRORS
#define INCL_NETCONS
#define INCL_NETACCESS
#define INCL_NETSERVER
#define INCL_NETWKSTA
#define INCL_NETSERVICE
#define INCL_NETLIB
#define INCL_ICANON
#define INCL_NETUSE // for NetUseAdd
#define _WINNETWK_
#include <lmui.hxx>
#undef _WINNETWK_
extern "C"
{
#include <mnet.h>
#include <winnetwk.h>
#include <npapi.h>
#include <lmsname.h>
}
#include <uiassert.hxx>
#include <uitrace.hxx>
#include <string.hxx>
#include <lmowks.hxx>
#include <lmodom.hxx>
#include <lmodev.hxx> // for DEVICE object
#include <uibuffer.hxx>
#include <strchlit.hxx> // for string and character literals
#include <lmsvc.hxx>
#include <miscapis.hxx>
/* Local prototypes */
/* functions */
/*******************************************************************
NAME: CheckLMService
SYNOPSIS: Checks to make sure the LM Wksta service is willing to
accept requests.
RETURNS: NERR_Success if the service is happy happy
WN_NO_NETWORK if the service is stopped or stopping
WN_FUNCTION_BUSY if the service is starting
Other error if an error occurred getting the status
NOTES:
HISTORY:
Johnl 09-Sep-1992 Created
********************************************************************/
APIERR CheckLMService( void )
{
APIERR err = NERR_Success ;
//
// we almost always hit the wksta soon after this call & the wksta
// is usually started. so this check will avoid paging in the service
// controller. it just ends up paging in the wksta a bit earlier.
// only if the call fails do we hit the service controller for the
// actual status.
//
WKSTA_10 wksta_10 ;
if ( (wksta_10.QueryError() == NERR_Success) &&
(wksta_10.GetInfo() == NERR_Success) )
{
return NERR_Success ;
}
LM_SERVICE service( NULL, (const TCHAR *)SERVICE_WORKSTATION );
if ( err = service.QueryError() )
{
return err ;
}
switch ( service.QueryStatus( &err ) )
{
case LM_SVC_STOPPED:
case LM_SVC_STOPPING:
if ( !err )
err = WN_NO_NETWORK ;
TRACEEOL("::CheckLMService - Returning WN_NO_NETWORK") ;
break ;
case LM_SVC_STARTING:
if ( !err )
err = WN_FUNCTION_BUSY ;
TRACEEOL("::CheckLMService - Returning WN_FUNCTION_BUSY") ;
break ;
case LM_SVC_STATUS_UNKNOWN:
case LM_SVC_STARTED:
case LM_SVC_PAUSED:
case LM_SVC_PAUSING:
case LM_SVC_CONTINUING:
default:
/* Return unadultered error code
*/
break ;
}
return err ;
}
/*******************************************************************
NAME: ParseRemoteName
SYNOPSIS: Canonicalizes a remote resource name and determines
its type
ARGUMENTS:
RemoteName - Remote resource name to be parsed
CanonName - Buffer for canonicalized name, assumed to be
MAX_PATH characters long
CanonNameSize - Size, in bytes, of output buffer
PathStart - Set to the offset, in characters, of the start
of the "\share" portion (in the REMOTENAMETYPE_SHARE case)
or the "\path" portion (in the REMOTENAMETYPE_PATH case)
of the name within CanonName. Not set in other cases.
RETURNS:
If nlsRemote is like Then returns
-------------------- ------------
workgroup REMOTENAMETYPE_WORKGROUP
\\server REMOTENAMETYPE_SERVER
\\server\share REMOTENAMETYPE_SHARE
\\server\share\path REMOTENAMETYPE_PATH
(other) REMOTENAMETYPE_INVALID
NOTES:
HISTORY:
AnirudhS 21-Apr-1995 Ported from Win95 sources - used netlib
functions rather than ad hoc parsing, introduced comments
********************************************************************/
REMOTENAMETYPE ParseRemoteName(
IN LPWSTR RemoteName,
OUT LPWSTR CanonName,
IN DWORD CanonNameSize,
OUT PULONG PathStart
)
{
//
// Determine the path type
//
DWORD PathType = 0;
NET_API_STATUS Status = I_NetPathType(NULL, RemoteName, &PathType, 0);
if (Status != NERR_Success)
{
return REMOTENAMETYPE_INVALID;
}
//
// I_NetPathType doesn't give us quite as fine a classification of
// path types as we need, so we still need to do a little more parsing
//
switch (PathType)
{
case ITYPE_PATH_RELND:
//
// A driveless relative path
// A valid workgroup or domain name would be classified as
// such, but it still needs to be validated as a workgroup name
//
Status = I_NetNameCanonicalize(
NULL, // ServerName
RemoteName, // Name
CanonName, // Outbuf
CanonNameSize, // OutbufLen
NAMETYPE_WORKGROUP, // NameType
0 // Flags
);
if (Status == NERR_Success)
{
return REMOTENAMETYPE_WORKGROUP;
}
else
{
return REMOTENAMETYPE_INVALID;
}
case ITYPE_UNC_COMPNAME:
//
// A UNC computername, "\\server"
//
{
//
// HACK: I_NetPathCanonicalize likes "\\server\share" but not
// "\\server", so append a dummy share name to canonicalize.
// We assume that the CanonName buffer will still be big
// enough (which it will, in the calls made from this file).
//
if (wcslen(RemoteName) + 3 > NNLEN)
{
return REMOTENAMETYPE_INVALID;
}
WCHAR wszDummy[NNLEN];
wcscpy(wszDummy, RemoteName);
wcscat(wszDummy, L"\\a");
UIASSERT(CanonNameSize >= sizeof(wszDummy));
PathType = ITYPE_UNC;
Status = I_NetPathCanonicalize(
NULL, // ServerName
wszDummy, // PathName
CanonName, // Outbuf
CanonNameSize, // OutbufLen
NULL, // Prefix
&PathType, // PathType
0 // Flags
);
}
if (Status != NERR_Success)
{
return REMOTENAMETYPE_INVALID;
}
CanonName[ wcslen(CanonName) - 2 ] = 0;
return REMOTENAMETYPE_SERVER;
case ITYPE_UNC:
//
// A UNC path, either "\\server\share" or "\\server\share\path" -
// canonicalize and determine which one
//
Status = I_NetPathCanonicalize(
NULL, // ServerName
RemoteName, // PathName
CanonName, // Outbuf
CanonNameSize, // OutbufLen
NULL, // Prefix
&PathType, // PathType
0 // Flags
);
if (Status != NERR_Success)
{
return REMOTENAMETYPE_INVALID;
}
{
WCHAR * pSlash = wcschr(CanonName+2, PATH_SEPARATOR);
UIASSERT(pSlash);
*PathStart = (ULONG)(pSlash - CanonName);
// Look for a fourth slash
pSlash = wcschr(pSlash+1, PATH_SEPARATOR);
if (pSlash)
{
*PathStart = (ULONG)(pSlash - CanonName);
return REMOTENAMETYPE_PATH;
}
else
{
return REMOTENAMETYPE_SHARE;
}
}
default:
return REMOTENAMETYPE_INVALID;
}
}