mirror of https://github.com/tongzx/nt5src
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.
815 lines
21 KiB
815 lines
21 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
wnres.cxx
|
|
|
|
Abstract:
|
|
|
|
Contains:
|
|
NPGetResourceInformation
|
|
NPGetResourceParent
|
|
|
|
Environment:
|
|
|
|
User Mode -Win32
|
|
|
|
Notes:
|
|
|
|
CODEWORK: Exorcize NLS_STR from this file!
|
|
|
|
Revision History:
|
|
|
|
21-Apr-1995 anirudhs
|
|
Ported from Windows 95 sources (msparent.c, msconn.c)
|
|
|
|
--*/
|
|
|
|
#define INCL_WINDOWS
|
|
#define INCL_NETERRORS
|
|
#define INCL_DOSERRORS
|
|
#define INCL_NETWKSTA
|
|
#define INCL_NETSERVER
|
|
#define INCL_NETSHARE
|
|
#define INCL_NETUSE
|
|
#define INCL_ICANON
|
|
#define _WINNETWK_
|
|
#include <lmui.hxx>
|
|
#undef _WINNETWK_
|
|
|
|
#include <winnetwk.h>
|
|
#include <npapi.h>
|
|
#include <tstr.h>
|
|
#include <netlib.h>
|
|
#include <lmapibuf.h>
|
|
#include <winlocal.h>
|
|
#include <errornum.h> // IDS_UnknownWorkgroup
|
|
#include <uiassert.hxx>
|
|
#include <uitrace.hxx>
|
|
#include <lmowks.hxx>
|
|
#include <miscapis.hxx>
|
|
|
|
#include <dfsutil.hxx>
|
|
|
|
extern "C" DWORD
|
|
I_NetDfsIsThisADomainName(
|
|
IN LPCWSTR wszName
|
|
);
|
|
|
|
APIERR GetLMProviderName();
|
|
|
|
VOID
|
|
ShareExistsFillInInfo(
|
|
SHARE_INFO_1 *psi,
|
|
DWORD *pdwType,
|
|
NLS_STR **ppnlsComment
|
|
);
|
|
|
|
|
|
extern HMODULE hModule ;
|
|
|
|
DWORD DisplayTypeToUsage(DWORD dwDisplayType)
|
|
{
|
|
switch (dwDisplayType) {
|
|
case RESOURCEDISPLAYTYPE_NETWORK:
|
|
case RESOURCEDISPLAYTYPE_DOMAIN:
|
|
case RESOURCEDISPLAYTYPE_SERVER:
|
|
return RESOURCEUSAGE_CONTAINER;
|
|
|
|
case RESOURCEDISPLAYTYPE_SHARE:
|
|
return RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_NOLOCALDEVICE;
|
|
|
|
case RESOURCEDISPLAYTYPE_SHAREADMIN:
|
|
return RESOURCEUSAGE_NOLOCALDEVICE;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
BOOLEAN IsThisADfsDomain(
|
|
IN LPCWSTR pwszDomainName)
|
|
{
|
|
DWORD dwErr;
|
|
|
|
if (pwszDomainName == NULL) {
|
|
return( FALSE );
|
|
}
|
|
|
|
if (wcslen(pwszDomainName) > 2 &&
|
|
pwszDomainName[0] == L'\\' &&
|
|
pwszDomainName[1] == L'\\') {
|
|
pwszDomainName += 2;
|
|
}
|
|
|
|
dwErr = I_NetDfsIsThisADomainName( pwszDomainName );
|
|
|
|
return( (dwErr == ERROR_SUCCESS) ? TRUE : FALSE );
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: CopyResourceToBuffer
|
|
|
|
SYNOPSIS: Copies the specified NETRESOURCE fields into the
|
|
specified buffer. If the buffer is not big enough,
|
|
returns WN_MORE_DATA and sets cbBuffer to the required
|
|
size; otherwise leaves cbBuffer untouched.
|
|
The strings are copied at the end of the buffer, to
|
|
match convention (though in order for this to be
|
|
useful, we ought to return a space remaining counter).
|
|
|
|
RETURNS: WN_SUCCESS or WN_MORE_DATA
|
|
|
|
NOTES: This function does the work of the ParentInfoEnumerator
|
|
class in the Win 95 MSNP sources.
|
|
|
|
HISTORY:
|
|
AnirudhS 24-Apr-1995 Created
|
|
|
|
********************************************************************/
|
|
|
|
DWORD CopyResourceToBuffer(
|
|
OUT LPBYTE lpBuffer,
|
|
IN OUT LPDWORD pcbBuffer,
|
|
IN DWORD dwScope,
|
|
IN DWORD dwType,
|
|
IN DWORD dwDisplayType,
|
|
IN DWORD dwUsage,
|
|
IN LPCWSTR lpLocalName,
|
|
IN LPCWSTR lpRemoteName,
|
|
IN LPCWSTR lpComment,
|
|
IN LPCWSTR lpProvider
|
|
)
|
|
{
|
|
// Calculate minimum required buffer size
|
|
DWORD cbTotalStringSize =
|
|
(lpLocalName ? WCSSIZE(lpLocalName) : 0)
|
|
+ (lpRemoteName ? WCSSIZE(lpRemoteName) : 0)
|
|
+ (lpComment ? WCSSIZE(lpComment) : 0)
|
|
+ (lpProvider ? WCSSIZE(lpProvider) : 0);
|
|
|
|
if (*pcbBuffer < sizeof(NETRESOURCE) + cbTotalStringSize)
|
|
{
|
|
*pcbBuffer = sizeof(NETRESOURCE) + cbTotalStringSize;
|
|
return WN_MORE_DATA;
|
|
}
|
|
|
|
// Calculate start of string area
|
|
LPWSTR pNextString = (LPWSTR) (lpBuffer + *pcbBuffer - cbTotalStringSize);
|
|
|
|
// Copy the data
|
|
LPNETRESOURCE pNetResource = (LPNETRESOURCE) lpBuffer;
|
|
pNetResource->dwScope = dwScope;
|
|
pNetResource->dwType = dwType;
|
|
pNetResource->dwDisplayType = dwDisplayType;
|
|
pNetResource->dwUsage = dwUsage;
|
|
|
|
#define COPYSTRINGFIELD(field) \
|
|
if (field) \
|
|
{ \
|
|
pNetResource->field = pNextString; \
|
|
wcscpy(pNextString, field); \
|
|
pNextString += wcslen(pNextString) + 1; \
|
|
} \
|
|
else \
|
|
{ \
|
|
pNetResource->field = NULL; \
|
|
}
|
|
|
|
COPYSTRINGFIELD(lpLocalName)
|
|
COPYSTRINGFIELD(lpRemoteName)
|
|
COPYSTRINGFIELD(lpComment)
|
|
COPYSTRINGFIELD(lpProvider)
|
|
#undef COPYSTRINGFIELD
|
|
|
|
return WN_SUCCESS;
|
|
}
|
|
|
|
|
|
DWORD GetDomainParent(NLS_STR& nlsServer)
|
|
{
|
|
LPCWSTR DomainName = nlsServer.QueryPch();
|
|
LPWSTR NewName;
|
|
LPWSTR UseName;
|
|
|
|
if (DomainName == NULL)
|
|
{
|
|
return WN_BAD_NETNAME;
|
|
}
|
|
|
|
NewName = new WCHAR[wcslen(DomainName) + 1];
|
|
if (NewName == NULL)
|
|
{
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
wcscpy(NewName, DomainName);
|
|
|
|
UseName = NewName;
|
|
|
|
while ((*UseName == L'\\') && (*UseName != 0))
|
|
{
|
|
UseName++;
|
|
}
|
|
|
|
nlsServer = UseName;
|
|
|
|
delete[] NewName;
|
|
|
|
return WN_SUCCESS;
|
|
}
|
|
|
|
DWORD GetServerParent(NLS_STR& nlsServer)
|
|
{
|
|
PWKSTA_INFO_100 pWkstaInfo = NULL;
|
|
NET_API_STATUS err = NetWkstaGetInfo(
|
|
(LPWSTR) nlsServer.QueryPch(),
|
|
100,
|
|
(PBYTE *)&pWkstaInfo
|
|
);
|
|
|
|
switch (err) {
|
|
case NERR_Success:
|
|
nlsServer = pWkstaInfo->wki100_langroup;
|
|
NetApiBufferFree(pWkstaInfo);
|
|
break;
|
|
case ERROR_NOT_SUPPORTED:
|
|
case ERROR_NETWORK_ACCESS_DENIED:
|
|
case ERROR_ACCESS_DENIED:
|
|
case ERROR_INVALID_LEVEL:
|
|
nlsServer.Load(IDS_UnknownWorkgroup, hModule);
|
|
break;
|
|
default:
|
|
return MapError( err ) ;
|
|
}
|
|
return WN_SUCCESS;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: NPGetResourceParent
|
|
|
|
SYNOPSIS:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
AnirudhS 21-Apr-1995 Ported from Win95 sources
|
|
|
|
********************************************************************/
|
|
|
|
DWORD NPGetResourceParent(
|
|
LPNETRESOURCE lpNetResource,
|
|
LPVOID lpBuffer,
|
|
LPDWORD cbBuffer
|
|
)
|
|
{
|
|
//
|
|
// Canonicalize the remote name, find its type, and find the
|
|
// beginning of the path portion of it
|
|
//
|
|
WCHAR wszCanonName[MAX_PATH]; // buffer for canonicalized name
|
|
ULONG iBackslash; // index into wszCanonName
|
|
REMOTENAMETYPE rnt = ParseRemoteName(
|
|
lpNetResource->lpRemoteName,
|
|
wszCanonName,
|
|
sizeof(wszCanonName),
|
|
&iBackslash);
|
|
|
|
//
|
|
// Convert to NLS string classes, for Win95 source compatibility
|
|
//
|
|
ALLOC_STR nlsRemote(wszCanonName, sizeof(wszCanonName), wszCanonName);
|
|
|
|
DWORD dwDisplayType;
|
|
LPCWSTR lpProvider = NULL;
|
|
NET_API_STATUS err;
|
|
|
|
switch (rnt) {
|
|
|
|
case REMOTENAMETYPE_INVALID:
|
|
return WN_BAD_NETNAME;
|
|
|
|
case REMOTENAMETYPE_WORKGROUP:
|
|
dwDisplayType = RESOURCEDISPLAYTYPE_NETWORK;
|
|
break;
|
|
|
|
case REMOTENAMETYPE_SERVER:
|
|
if (!IsThisADfsDomain(lpNetResource->lpRemoteName))
|
|
{
|
|
err = GetServerParent(nlsRemote);
|
|
if (err != WN_SUCCESS)
|
|
return err;
|
|
}
|
|
else
|
|
{
|
|
err = GetDomainParent(nlsRemote);
|
|
if (err != WN_SUCCESS)
|
|
return err;
|
|
}
|
|
dwDisplayType = RESOURCEDISPLAYTYPE_DOMAIN;
|
|
break;
|
|
|
|
case REMOTENAMETYPE_SHARE:
|
|
{
|
|
ISTR istrBackslash(nlsRemote);
|
|
istrBackslash += iBackslash;
|
|
|
|
nlsRemote.DelSubStr(istrBackslash); /* lop off sharename */
|
|
dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
|
|
}
|
|
break;
|
|
|
|
case REMOTENAMETYPE_PATH:
|
|
{
|
|
ISTR istrLastBackslash(nlsRemote);
|
|
ISTR istrBackslash(nlsRemote);
|
|
istrBackslash += iBackslash;
|
|
|
|
nlsRemote.strrchr(&istrLastBackslash, PATH_SEPARATOR);
|
|
if (istrLastBackslash == istrBackslash)
|
|
dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
|
|
else
|
|
dwDisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
|
|
nlsRemote.DelSubStr(istrLastBackslash);
|
|
}
|
|
break;
|
|
|
|
#ifdef DEBUG
|
|
default:
|
|
ASSERTSZ(FALSE,"ParseRemoteName reported unexpected type!");
|
|
#endif
|
|
}
|
|
|
|
LPCWSTR lpNewName;
|
|
if (dwDisplayType == RESOURCEDISPLAYTYPE_NETWORK)
|
|
lpNewName = NULL;
|
|
else
|
|
lpNewName = nlsRemote.QueryPch();
|
|
|
|
err = GetLMProviderName();
|
|
if (err != WN_SUCCESS)
|
|
return err;
|
|
lpProvider = pszNTLanMan;
|
|
|
|
return CopyResourceToBuffer(
|
|
(LPBYTE) lpBuffer, // lpBuffer
|
|
cbBuffer, // pcbBuffer
|
|
0, // dwScope
|
|
RESOURCETYPE_ANY, // dwType (we can't tell)
|
|
dwDisplayType, // dwDisplayType
|
|
DisplayTypeToUsage(dwDisplayType), // dwUsage
|
|
NULL, // lpLocalName
|
|
lpNewName, // lpRemoteName
|
|
NULL, // lpComment
|
|
lpProvider // lpProvider
|
|
);
|
|
}
|
|
|
|
|
|
BOOL WorkgroupExists(NLS_STR& nlsWorkgroup)
|
|
{
|
|
DWORD cEntriesRead, cTotalAvail = 0;
|
|
LPBYTE bufptr = NULL; // not used
|
|
|
|
NET_API_STATUS err = NetServerEnum(
|
|
NULL,
|
|
100,
|
|
&bufptr,
|
|
0,
|
|
&cEntriesRead,
|
|
&cTotalAvail,
|
|
SV_TYPE_ALL,
|
|
(LPWSTR) nlsWorkgroup.QueryPch(),
|
|
NULL
|
|
);
|
|
|
|
DBGEOL("NPGetResourceInformation - Error " << (ULONG) err <<
|
|
" returned from NetServerEnum") ;
|
|
|
|
// NetServerEnum allocates a 0-byte buffer that must be freed
|
|
if (bufptr != NULL)
|
|
{
|
|
NetApiBufferFree(bufptr);
|
|
}
|
|
|
|
return (cTotalAvail > 0 || err == NERR_Success);
|
|
}
|
|
|
|
|
|
BOOL ServerExists(NLS_STR& nlsServer, NLS_STR **ppnlsComment)
|
|
{
|
|
PWKSTA_INFO_100 pWkstaInfo = NULL;
|
|
NET_API_STATUS err = NetWkstaGetInfo(
|
|
(LPWSTR) nlsServer.QueryPch(),
|
|
100,
|
|
(PBYTE *)&pWkstaInfo
|
|
);
|
|
|
|
switch (err) {
|
|
case NERR_Success:
|
|
{
|
|
NetApiBufferFree(pWkstaInfo);
|
|
|
|
/* Now try NetServerGetInfo, to get the comment. May not be able
|
|
* to do this. Not the end of the world if we can't.
|
|
*/
|
|
PSERVER_INFO_101 pServerInfo;
|
|
if (NetServerGetInfo((LPWSTR) nlsServer.QueryPch(), 101, (PBYTE *)&pServerInfo)
|
|
== NERR_Success)
|
|
{
|
|
if (pServerInfo->sv101_comment != NULL)
|
|
{
|
|
*ppnlsComment = new NLS_STR(pServerInfo->sv101_comment);
|
|
if (*ppnlsComment && (*ppnlsComment)->QueryError())
|
|
{
|
|
delete *ppnlsComment;
|
|
*ppnlsComment = NULL;
|
|
}
|
|
}
|
|
NetApiBufferFree(pServerInfo);
|
|
}
|
|
}
|
|
// fall through
|
|
case ERROR_NOT_SUPPORTED:
|
|
case ERROR_NETWORK_ACCESS_DENIED:
|
|
case ERROR_ACCESS_DENIED:
|
|
case ERROR_INVALID_LEVEL:
|
|
case ERROR_BAD_NET_RESP:
|
|
return TRUE;
|
|
default:
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL AttemptUse(NLS_STR& nlsRemote)
|
|
{
|
|
USE_INFO_1 ui1;
|
|
|
|
ui1.ui1_local = NULL;
|
|
ui1.ui1_remote = (LPWSTR)nlsRemote.QueryPch();
|
|
ui1.ui1_password = NULL;
|
|
ui1.ui1_asg_type = USE_WILDCARD;
|
|
|
|
NET_API_STATUS err = NetUseAdd(NULL, 1, (LPBYTE)&ui1, NULL);
|
|
|
|
switch (err) {
|
|
case NERR_Success:
|
|
NetUseDel(NULL, (LPWSTR) nlsRemote.QueryPch(), USE_NOFORCE);
|
|
// fall through
|
|
case ERROR_INVALID_PASSWORD:
|
|
case NERR_BadPasswordCore:
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL ShareExists(NLS_STR& nlsShare, ISTR& istrBackslash, BOOL *pfServerOK,
|
|
DWORD *pdwType, NLS_STR **ppnlsComment)
|
|
{
|
|
*pfServerOK = FALSE;
|
|
*pdwType = RESOURCETYPE_ANY;
|
|
|
|
WCHAR szServer[MAX_PATH+1];
|
|
BOOL fDownLevel = FALSE;
|
|
DWORD cEntriesRead;
|
|
DWORD cTotalAvail;
|
|
BOOL fRet = FALSE;
|
|
|
|
wcsncpy(szServer, nlsShare, MAX_PATH);
|
|
szServer[MAX_PATH] = L'\0';
|
|
szServer[istrBackslash] = L'\0';
|
|
++istrBackslash;
|
|
|
|
PBYTE pBuf;
|
|
NET_API_STATUS err;
|
|
|
|
//
|
|
// This could be a domain based dfs share, so check to see if this is a
|
|
// Dfs name.
|
|
//
|
|
|
|
LPWSTR pwszPath;
|
|
if (IsDfsPath((LPWSTR)nlsShare.QueryPch(), 0, &pwszPath))
|
|
{
|
|
DWORD dwAttr;
|
|
BOOL retValue;
|
|
|
|
*pfServerOK = TRUE;
|
|
*pdwType = RESOURCETYPE_DISK;
|
|
|
|
dwAttr = GetFileAttributes( (LPWSTR)nlsShare.QueryPch());
|
|
if (dwAttr == (DWORD)-1)
|
|
{
|
|
retValue = FALSE;
|
|
}
|
|
else
|
|
{
|
|
retValue = TRUE;
|
|
}
|
|
return( retValue );
|
|
}
|
|
else {
|
|
err = NetShareGetInfo(
|
|
szServer,
|
|
szServer + istrBackslash,
|
|
1,
|
|
&pBuf
|
|
);
|
|
}
|
|
|
|
if (err != NERR_Success) {
|
|
|
|
//
|
|
// Win98, Win95, and Win3.11 don't implement NetShareGetInfo
|
|
// and all 3 return different errors in this case (Win95 actually
|
|
// returns ERROR_NETWORK_ACCESS_DENIED)
|
|
//
|
|
fDownLevel = TRUE;
|
|
|
|
err = NetShareEnum(
|
|
szServer,
|
|
1,
|
|
&pBuf,
|
|
0xffffffff,
|
|
&cEntriesRead,
|
|
&cTotalAvail,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
switch (err) {
|
|
case NERR_Success:
|
|
break;
|
|
|
|
case NERR_BadTransactConfig:
|
|
*pfServerOK = TRUE;
|
|
return AttemptUse(nlsShare);
|
|
|
|
case ERROR_ACCESS_DENIED:
|
|
case ERROR_NETWORK_ACCESS_DENIED:
|
|
*pfServerOK = TRUE;
|
|
// fall through
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
*pfServerOK = TRUE;
|
|
|
|
SHARE_INFO_1 *psi = (SHARE_INFO_1 *)pBuf;
|
|
|
|
if (!fDownLevel) {
|
|
ShareExistsFillInInfo(psi, pdwType, ppnlsComment);
|
|
fRet = TRUE;
|
|
}
|
|
else {
|
|
|
|
//
|
|
// We had to enumerate since this was a downlevel client -- check
|
|
// to see if the share in which we're interested is on the server
|
|
//
|
|
|
|
LPCWSTR pszShare = nlsShare.QueryPch(istrBackslash);
|
|
|
|
for (DWORD i = 0; i < cEntriesRead; i++, psi++) {
|
|
|
|
if (!_wcsicmp(pszShare, psi->shi1_netname)) {
|
|
|
|
//
|
|
// Found it
|
|
//
|
|
ShareExistsFillInInfo(psi, pdwType, ppnlsComment);
|
|
fRet = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
NetApiBufferFree(pBuf);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
VOID
|
|
ShareExistsFillInInfo(
|
|
SHARE_INFO_1 *psi,
|
|
DWORD *pdwType,
|
|
NLS_STR **ppnlsComment
|
|
)
|
|
{
|
|
switch (psi->shi1_type) {
|
|
|
|
case STYPE_DISKTREE:
|
|
*pdwType = RESOURCETYPE_DISK;
|
|
break;
|
|
|
|
case STYPE_PRINTQ:
|
|
*pdwType = RESOURCETYPE_PRINT;
|
|
break;
|
|
} /* default was set above */
|
|
|
|
if (psi->shi1_remark != NULL) {
|
|
|
|
*ppnlsComment = new NLS_STR(psi->shi1_remark);
|
|
|
|
if (*ppnlsComment && (*ppnlsComment)->QueryError()) {
|
|
delete *ppnlsComment;
|
|
*ppnlsComment = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: NPGetResourceInformation
|
|
|
|
SYNOPSIS:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
AnirudhS 21-Apr-1995 Ported from Win95 sources
|
|
AnirudhS 22-May-1996 Fixed buffer size calculations
|
|
|
|
********************************************************************/
|
|
|
|
DWORD NPGetResourceInformation(
|
|
LPNETRESOURCE lpNetResource,
|
|
LPVOID lpBuffer,
|
|
LPDWORD cbBuffer,
|
|
LPWSTR *lplpSystem
|
|
)
|
|
{
|
|
//
|
|
// Canonicalize the remote name, find its type, and find the
|
|
// beginning of the path portion of it
|
|
//
|
|
WCHAR wszCanonName[MAX_PATH]; // buffer for canonicalized name
|
|
ULONG iBackslash; // index into wszCanonName
|
|
REMOTENAMETYPE rnt = ParseRemoteName(
|
|
lpNetResource->lpRemoteName,
|
|
wszCanonName,
|
|
sizeof(wszCanonName),
|
|
&iBackslash
|
|
);
|
|
|
|
//
|
|
// Convert to NLS string classes, for Win95 source compatibility
|
|
//
|
|
ALLOC_STR nlsRemote(wszCanonName);
|
|
|
|
BOOL fExists = FALSE;
|
|
BOOL fServerOK = FALSE;
|
|
LPNETRESOURCE lpNROut = (LPNETRESOURCE)lpBuffer;
|
|
LPWSTR lpszNext = (LPWSTR)(lpNROut+1);
|
|
DWORD cbNeeded = sizeof(NETRESOURCE);
|
|
NLS_STR *pnlsComment = NULL;
|
|
DWORD dwType = RESOURCETYPE_ANY;
|
|
DWORD dwDisplayType = 0;
|
|
|
|
// set a few defaults
|
|
if (*cbBuffer >= cbNeeded)
|
|
{
|
|
lpNROut->dwScope = 0;
|
|
lpNROut->lpLocalName = NULL;
|
|
lpNROut->lpComment = NULL;
|
|
}
|
|
*lplpSystem = NULL;
|
|
|
|
switch (rnt) {
|
|
|
|
case REMOTENAMETYPE_INVALID:
|
|
return WN_BAD_NETNAME;
|
|
|
|
case REMOTENAMETYPE_WORKGROUP:
|
|
fExists = WorkgroupExists(nlsRemote);
|
|
dwDisplayType = RESOURCEDISPLAYTYPE_DOMAIN;
|
|
break;
|
|
|
|
case REMOTENAMETYPE_SERVER:
|
|
if (IsThisADfsDomain(lpNetResource->lpRemoteName))
|
|
{
|
|
fExists = TRUE;
|
|
dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
|
|
}
|
|
else
|
|
{
|
|
fExists = ServerExists(nlsRemote, &pnlsComment);
|
|
dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
|
|
}
|
|
break;
|
|
|
|
case REMOTENAMETYPE_PATH:
|
|
{
|
|
ISTR istrBackslash(nlsRemote);
|
|
istrBackslash += iBackslash;
|
|
|
|
UINT cbPath = WCSSIZE(nlsRemote.QueryPch(istrBackslash));
|
|
cbNeeded += cbPath;
|
|
if (*cbBuffer >= cbNeeded) {
|
|
*lplpSystem = lpszNext;
|
|
wcscpy(lpszNext, nlsRemote.QueryPch(istrBackslash));
|
|
lpszNext += cbPath/sizeof(WCHAR);
|
|
}
|
|
nlsRemote.DelSubStr(istrBackslash);
|
|
nlsRemote.strrchr(&istrBackslash, PATH_SEPARATOR);
|
|
|
|
fExists = ShareExists(nlsRemote,
|
|
istrBackslash,
|
|
&fServerOK,
|
|
&dwType,
|
|
&pnlsComment);
|
|
|
|
dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
|
|
}
|
|
break;
|
|
|
|
case REMOTENAMETYPE_SHARE:
|
|
{
|
|
ISTR istrBackslash(nlsRemote);
|
|
istrBackslash += iBackslash;
|
|
|
|
fExists = ShareExists(nlsRemote,
|
|
istrBackslash,
|
|
&fServerOK,
|
|
&dwType,
|
|
&pnlsComment);
|
|
|
|
dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
|
|
}
|
|
|
|
break;
|
|
|
|
#ifdef DEBUG
|
|
default:
|
|
ASSERTSZ(FALSE,"ParseRemoteName reported unexpected type!");
|
|
#endif
|
|
}
|
|
|
|
if (!fExists)
|
|
{
|
|
/* If we've been fed a UNC name, and the server exists but the share
|
|
* doesn't, Win95's MSNP customizes the error text thus, but we just
|
|
* return the standard text since our MPR doesn't support customization
|
|
* of text for standard errors:
|
|
* if (fServerOK)
|
|
* return MapNetError(ERROR_BAD_NET_NAME);
|
|
*/
|
|
|
|
return WN_BAD_NETNAME;
|
|
}
|
|
|
|
APIERR err = GetLMProviderName();
|
|
if (err != WN_SUCCESS)
|
|
return err;
|
|
UINT cbProvider = WCSSIZE(pszNTLanMan);
|
|
cbNeeded += cbProvider;
|
|
if (*cbBuffer >= cbNeeded) {
|
|
lpNROut->lpProvider = lpszNext;
|
|
wcscpy(lpszNext, pszNTLanMan);
|
|
lpszNext += cbProvider/sizeof(WCHAR);
|
|
}
|
|
|
|
cbNeeded += nlsRemote.QueryTextSize();
|
|
if (*cbBuffer >= cbNeeded) {
|
|
lpNROut->lpRemoteName = lpszNext;
|
|
wcscpy(lpszNext, nlsRemote);
|
|
lpszNext += nlsRemote.QueryTextSize()/sizeof(WCHAR);
|
|
}
|
|
|
|
if (pnlsComment != NULL) {
|
|
cbNeeded += pnlsComment->QueryTextSize();
|
|
if (*cbBuffer >= cbNeeded) {
|
|
lpNROut->lpComment = lpszNext;
|
|
wcscpy(lpszNext, pnlsComment->QueryPch());
|
|
lpszNext += pnlsComment->QueryTextSize()/sizeof(WCHAR);
|
|
}
|
|
delete pnlsComment;
|
|
}
|
|
|
|
if (*cbBuffer >= cbNeeded) {
|
|
lpNROut->dwType = dwType;
|
|
lpNROut->dwDisplayType = dwDisplayType;
|
|
lpNROut->dwUsage = DisplayTypeToUsage(lpNROut->dwDisplayType);
|
|
return WN_SUCCESS;
|
|
}
|
|
else {
|
|
*cbBuffer = cbNeeded;
|
|
return WN_MORE_DATA;
|
|
}
|
|
}
|
|
|