|
|
#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 = NULL; 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; }
|