/*****************************************************************/ /** 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 #undef _WINNETWK_ extern "C" { #include #include #include #include } #include #include #include #include #include #include // for DEVICE object #include #include // for string and character literals #include #include /* 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; } }