windows-nt/Source/XPSP1/NT/admin/admt/wizards/wnetutil.cpp
2020-09-26 16:20:57 +08:00

281 lines
8.3 KiB
C++

#include "StdAfx.h"
#include "WNetUtil.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define VALD_NETDOMAIN_ENUM 1000666 // bad pointer validation signature
#define DOM_BUFFER_SIZE (32768) // buffer size held allocated by class
class TNetDomainEnum
{
public:
TNetDomainEnum();
~TNetDomainEnum();
DWORD GetMsNetProvider( NETRESOURCE * resourceInfo, DWORD infoSize );
WCHAR * GetNext();
DWORD GetLastRc() const { return rc; };
BOOL IsValid() const { return vald == VALD_NETDOMAIN_ENUM; };
private:
DWORD vald;
HANDLE hEnum;
NETRESOURCE * resourceBuffer;
DWORD rc,
totEntries,
nextEntry,
buffSize;
};
//-----------------------------------------------------------------------------
// TNetDomainEnum::TNetDomainEnum
//-----------------------------------------------------------------------------
TNetDomainEnum::TNetDomainEnum()
{
//--------------------------
// Initialize Class Members
//--------------------------
vald = VALD_NETDOMAIN_ENUM;
hEnum = INVALID_HANDLE_VALUE;
// init currEntry > totEntries to force first-time read
totEntries = 0;
nextEntry = 1;
resourceBuffer = (NETRESOURCE *)new char[DOM_BUFFER_SIZE];
if ( !resourceBuffer )
{
rc = 1;
}
else
{
//-----------------------------------
// Determine Network Provider to Use
//-----------------------------------
char buffer[16384];
NETRESOURCE * info = (NETRESOURCE *)buffer;
rc = GetMsNetProvider( info, sizeof(buffer));
if ( ! rc )
{
rc = WNetOpenEnum( RESOURCE_GLOBALNET,
RESOURCETYPE_ANY,
RESOURCEUSAGE_CONTAINER,
info,
&hEnum );
delete [] info->lpProvider;
}
if ( rc )
{
if ( resourceBuffer )
{
delete resourceBuffer;
resourceBuffer = NULL;
}
}
}
}
//-----------------------------------------------------------------------------
// TNetDomainEnum::~TNetDomainEnum
//-----------------------------------------------------------------------------
TNetDomainEnum::~TNetDomainEnum()
{
if ( hEnum != INVALID_HANDLE_VALUE )
{
WNetCloseEnum( hEnum );
hEnum = INVALID_HANDLE_VALUE;
}
vald = 0;
if ( resourceBuffer )
{
delete resourceBuffer;
}
}
//-----------------------------------------------------------------------------
// GetMsNetProvider - Retrieves network resource information for the 'Microsoft
// Windows Network' provider.
//
// Input: A pointer to a NETRESOURCE structure that we will fill if we find a
// resource meeting our needs.
//
// Output: 0 of we found a provider. resourceInfo populated in this case
// non-zero if no provider. resourceInfo contents undefined
//-----------------------------------------------------------------------------
DWORD TNetDomainEnum::GetMsNetProvider( NETRESOURCE * resourceInfo, DWORD infoSize )
{
_TCHAR szProvider[_MAX_PATH];
DWORD cchProvider = sizeof(szProvider) / sizeof(szProvider[0]);
DWORD dwError = WNetGetProviderName(WNNC_NET_LANMAN, szProvider, &cchProvider);
if (dwError == NO_ERROR)
{
memset(resourceInfo, 0, infoSize);
resourceInfo->dwScope = RESOURCE_GLOBALNET;
resourceInfo->dwType = RESOURCETYPE_ANY;
resourceInfo->dwDisplayType = RESOURCEDISPLAYTYPE_NETWORK;
resourceInfo->dwUsage = RESOURCEUSAGE_CONTAINER;
resourceInfo->lpProvider = new _TCHAR[_tcslen(szProvider) + 1];
if (resourceInfo->lpProvider)
{
_tcscpy(resourceInfo->lpProvider, szProvider);
rc = NO_ERROR;
}
else
{
rc = ERROR_OUTOFMEMORY;
}
}
else
{
rc = dwError;
}
return rc;
}
//-----------------------------------------------------------------------------
// TNetDomainEnum::GetNext()
//-----------------------------------------------------------------------------
WCHAR *
TNetDomainEnum::GetNext()
{
rc = (DWORD)-1; // init rc to internal error before reset
if ( hEnum == INVALID_HANDLE_VALUE )
return NULL;
if ( !resourceBuffer )
return NULL;
if ( nextEntry >= totEntries )
{
buffSize = DOM_BUFFER_SIZE;
totEntries = (DWORD)-1;
rc = WNetEnumResource(
hEnum,
&totEntries,
(void *)resourceBuffer,
&buffSize );
if ( rc == 0 )
nextEntry = 0;
else
{
totEntries = 0;
return NULL;
}
}
else
rc = 0;
return resourceBuffer[nextEntry++].lpRemoteName;
}
//#pragma page()
/*============================================================================*\
Windows Network Domain Enumeration APIs. These are a shell around the
TNetDomainEnum class member function. The handle used is nothing more
than the "this" pointer to the instantiated object.
\*============================================================================*/
//-----------------------------------------------------------------------------
// EaWNetDomainEnumOpen
//
// Creates the enumeration object and gives the caller the handle
//-----------------------------------------------------------------------------
DWORD _stdcall // ret-0 or error code
EaWNetDomainEnumOpen(
void ** handle // out-opaque handle addr to enum
)
{
TNetDomainEnum * domainEnum = new TNetDomainEnum();
*handle = (PVOID)domainEnum;
if ( ! domainEnum )
return (DWORD)-1; // internal error
return domainEnum->GetLastRc();
}
//-----------------------------------------------------------------------------
// EaWNetDomainEnumNext
//
// Sets the domain string buffer to the next domain name in the enumeration
//-----------------------------------------------------------------------------
DWORD _stdcall // ret-0 or error code
EaWNetDomainEnumNext(
void * handle ,// i/o-opaque handle to enumeration
EaWNetDomainInfo * domain // out-domain information structure
)
{
TNetDomainEnum * domainEnum = (TNetDomainEnum *)handle;
WCHAR * str;
if ( !domainEnum || !domainEnum->IsValid() )
return ERROR_INVALID_PARAMETER; // caller's error - invalid handle
str = domainEnum->GetNext();
if ( !str )
{
domain->name[0] = _T('\0');
}
else
{
wcsncpy(domain->name, str, EA_MAX_DOMAIN_NAME_SIZE);
domain->name[EA_MAX_DOMAIN_NAME_SIZE - 1] = _T('\0');
}
return domainEnum->GetLastRc();
}
//-----------------------------------------------------------------------------
// EaWNetDomainEnumFirst
//
// Sets the domain string buffer to the first domain name in the enumeration
//-----------------------------------------------------------------------------
DWORD _stdcall // ret-0 or error code
EaWNetDomainEnumFirst(
void * handle ,// i/o-opaque handle to enumeration
EaWNetDomainInfo * domain // out-domain information structure
)
{
// We're cheating here by making the first/next the same. We probably want to
// change this eventually to make "first" really properly reset the enum to the
// start
return EaWNetDomainEnumNext(handle, domain);
}
//-----------------------------------------------------------------------------
// EaWNetDomainEnumClose
//
// Closes and destroys the enumeration handle and the objects it contains
//-----------------------------------------------------------------------------
DWORD _stdcall // ret-0 or error code
EaWNetDomainEnumClose(
void * handle // i/o-opaque handle addr to enum
)
{
TNetDomainEnum * domainEnum = (TNetDomainEnum *)handle;
if ( !domainEnum || !domainEnum->IsValid() )
return ERROR_INVALID_PARAMETER; // caller's error - invalid handle
delete domainEnum;
return 0;
}