281 lines
8.3 KiB
C++
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;
|
|
} |