|
|
//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: cenumGroupCollection.cxx
//
// Contents: Windows NT 3.5 GroupCollection Enumeration Code
//
// History:
//----------------------------------------------------------------------------
#include "winnt.hxx"
#pragma hdrstop
#define BASE_BUFFER_SIZE (4096 * sizeof(WCHAR))
CWinNTUserGroupsCollectionEnum::CWinNTUserGroupsCollectionEnum(): _ParentType(0), _ParentADsPath(NULL), _DomainName(NULL), _ServerName(NULL), _UserName(NULL), _pGlobalBuffer(NULL), _pLocalBuffer(NULL), _dwCurrent(0), _dwTotal(0), _dwGlobalTotal(0), _dwLocalTotal(0), _fIsDomainController(FALSE) { VariantInit(&_vFilter); }
CWinNTUserGroupsCollectionEnum::~CWinNTUserGroupsCollectionEnum() { if (_ParentADsPath) ADsFreeString(_ParentADsPath); if (_DomainName) ADsFreeString(_DomainName); if (_ServerName) ADsFreeString(_ServerName); if (_UserName) ADsFreeString(_UserName); if (_pGlobalBuffer) NetApiBufferFree(_pGlobalBuffer); if (_pLocalBuffer) NetApiBufferFree(_pLocalBuffer); VariantClear(&_vFilter); }
//+---------------------------------------------------------------------------
//
// Function: CWinNTEnumVariant::Create
//
// Synopsis:
//
// Arguments: [pCollection]
// [ppEnumVariant]
//
// Returns: HRESULT
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT CWinNTUserGroupsCollectionEnum::Create( CWinNTUserGroupsCollectionEnum FAR* FAR* ppenumvariant, ULONG ParentType, BSTR ParentADsPath, BSTR DomainName, BSTR ServerName, BSTR UserName, VARIANT vFilter, CWinNTCredentials& Credentials ) { HRESULT hr = NOERROR; CWinNTUserGroupsCollectionEnum FAR* penumvariant = NULL; LPSERVER_INFO_101 lpServerInfo =NULL; NET_API_STATUS nasStatus; WCHAR szServer[MAX_PATH];
//
// Should the checks below be assertions?
//
if (!ppenumvariant) return E_FAIL;
if (ParentType != WINNT_DOMAIN_ID && ParentType != WINNT_COMPUTER_ID) return E_FAIL;
*ppenumvariant = NULL;
penumvariant = new CWinNTUserGroupsCollectionEnum(); if (!penumvariant) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
penumvariant->_ParentType = ParentType;
hr = ADsAllocString(ParentADsPath , &penumvariant->_ParentADsPath); BAIL_ON_FAILURE(hr);
hr = ADsAllocString(DomainName, &penumvariant->_DomainName); BAIL_ON_FAILURE(hr);
hr = ADsAllocString(ServerName, &penumvariant->_ServerName); BAIL_ON_FAILURE(hr);
hr = ADsAllocString(UserName, &penumvariant->_UserName); BAIL_ON_FAILURE(hr);
//
// We currently copy the filter but do nothing with it!!!
//
hr = VariantCopy(&penumvariant->_vFilter, &vFilter); BAIL_ON_FAILURE(hr);
// check if the server is a DC
MakeUncName(ServerName, szServer); nasStatus = NetServerGetInfo( szServer, 101, (LPBYTE *)&lpServerInfo ); hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr);
if( (lpServerInfo->sv101_type & SV_TYPE_DOMAIN_CTRL) || (lpServerInfo->sv101_type & SV_TYPE_DOMAIN_BAKCTRL) ) { penumvariant->_fIsDomainController = TRUE; } else penumvariant->_fIsDomainController = FALSE;
hr = penumvariant->DoEnumeration(); BAIL_ON_FAILURE(hr);
penumvariant->_Credentials = Credentials; hr = penumvariant->_Credentials.Ref(ServerName, DomainName, ParentType); BAIL_ON_FAILURE(hr);
*ppenumvariant = penumvariant; RRETURN(hr);
error: delete penumvariant;
if(lpServerInfo) NetApiBufferFree(lpServerInfo);
RRETURN_EXP_IF_ERR(hr); }
HRESULT CWinNTUserGroupsCollectionEnum::DoEnumeration() { HRESULT hr;
if (_ParentType == WINNT_DOMAIN_ID) {
hr = DoGlobalEnumeration(); BAIL_ON_FAILURE(hr);
hr = DoLocalEnumeration();
} else if (_ParentType == WINNT_COMPUTER_ID) {
// We also want to try and get the global groups,
// as this will be empty if the user does not belong to
// any global groups.
// We need to be careful on where we fail as we should
// continue enumerating local groups for lots of cases.
hr = DoGlobalEnumeration();
if ((hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) || (hr == HRESULT_FROM_WIN32(NERR_InvalidComputer)) || (hr == HRESULT_FROM_WIN32(NERR_UserNotFound)) || (hr == E_FAIL)) { hr = S_OK; _dwGlobalTotal = 0; }
BAIL_ON_FAILURE(hr);
hr = DoLocalEnumeration();
} else { hr = E_FAIL; } error: _dwTotal = _dwGlobalTotal + _dwLocalTotal; RRETURN(hr); }
HRESULT CWinNTUserGroupsCollectionEnum::DoGlobalEnumeration() { HRESULT hr; DWORD dwStatus; DWORD dwRead = 0; WCHAR szServer[MAX_PATH]; LPGROUP_USERS_INFO_0 pGroupUserInfo = NULL; GROUP_INFO_2 *pGroupInfo2 = NULL; NET_API_STATUS nasStatus;
MakeUncName(_ServerName, szServer); dwStatus = NetUserGetGroups(szServer, _UserName, 0, (LPBYTE*)&_pGlobalBuffer, MAX_PREFERRED_LENGTH, &dwRead, &_dwGlobalTotal); hr = HRESULT_FROM_WIN32(dwStatus); BAIL_ON_FAILURE(hr);
if (dwRead != _dwGlobalTotal) hr = E_FAIL;
if (dwRead == 1) { //
// Check if it is the none group - dont want that
//
pGroupUserInfo = (LPGROUP_USERS_INFO_0)_pGlobalBuffer; if ( pGroupUserInfo->grui0_name && (FALSE == _fIsDomainController) && (1 == _dwGlobalTotal) ) { // check if this the none group. Only non-DCs will return this group.
nasStatus = NetGroupGetInfo( szServer, pGroupUserInfo->grui0_name, 2, (LPBYTE *) &pGroupInfo2 ); hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr); if (pGroupInfo2->grpi2_group_id == DOMAIN_GROUP_RID_USERS) {
//
// Set the global total to zero - destructor will dealloc.
//
_dwGlobalTotal = 0; } } }
error: if(pGroupInfo2) NetApiBufferFree(pGroupInfo2);
RRETURN(hr); }
HRESULT CWinNTUserGroupsCollectionEnum::DoLocalEnumeration() { HRESULT hr; DWORD dwStatus; DWORD dwRead = 0; WCHAR szServer[MAX_PATH];
MakeUncName(_ServerName, szServer); dwStatus = NetUserGetLocalGroups(szServer, _UserName, 0, 0, (LPBYTE*)&_pLocalBuffer, MAX_PREFERRED_LENGTH, &dwRead, &_dwLocalTotal); hr = HRESULT_FROM_WIN32(dwStatus); BAIL_ON_FAILURE(hr);
if (dwRead != _dwLocalTotal) hr = E_FAIL;
error: RRETURN(hr); }
//+---------------------------------------------------------------------------
//
// Function: CWinNTUserGroupsCollectionEnum::Next
//
// Synopsis: Returns cElements number of requested NetOle objects in the
// array supplied in pvar.
//
// Arguments: [cElements] -- The number of elements requested by client
// [pvar] -- ptr to array of VARIANTs to for return objects
// [pcElementFetched] -- if non-NULL, then number of elements
// -- actually returned is placed here
//
// Returns: HRESULT -- S_OK if number of elements requested are returned
// -- S_FALSE if number of elements is < requested
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
STDMETHODIMP CWinNTUserGroupsCollectionEnum::Next( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched ) { ULONG cElementFetched = 0; HRESULT hr = S_OK;
hr = EnumUserGroups( cElements, pvar, &cElementFetched );
if (pcElementFetched) { *pcElementFetched = cElementFetched; } RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CWinNTUserGroupsCollectionEnum::Skip(ULONG cElements) { //
// Note: we better not wrap around when we add!
//
_dwCurrent += cElements; _dwCurrent = min(_dwTotal, _dwCurrent);
if (_dwCurrent < _dwTotal) return S_OK; return S_FALSE; }
STDMETHODIMP CWinNTUserGroupsCollectionEnum::Reset() { _dwCurrent = 0; return S_OK; }
HRESULT CWinNTUserGroupsCollectionEnum::EnumUserGroups( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched ) { HRESULT hr = S_FALSE; IDispatch *pDispatch = NULL; DWORD i = 0;
while (i < cElements) {
hr = GetNextUserGroup(&pDispatch); if (hr == S_FALSE) { break; }
VariantInit(&pvar[i]); pvar[i].vt = VT_DISPATCH; pvar[i].pdispVal = pDispatch; (*pcElementFetched)++; i++; } RRETURN(hr); }
HRESULT CWinNTUserGroupsCollectionEnum::GetNextUserGroup( IDispatch ** ppDispatch ) { HRESULT hr; LPGROUP_USERS_INFO_0 lpInfo; LPWSTR GroupName; ULONG GroupType;
if (_dwCurrent >= _dwTotal) return S_FALSE;
if (_dwCurrent < _dwGlobalTotal) { lpInfo = (LPGROUP_USERS_INFO_0)_pGlobalBuffer + _dwCurrent; GroupType = WINNT_GROUP_GLOBAL; } else { lpInfo = (LPGROUP_USERS_INFO_0)_pLocalBuffer + _dwCurrent - _dwGlobalTotal; GroupType = WINNT_GROUP_LOCAL; }
_dwCurrent++;
GroupName = lpInfo->grui0_name;
//
// On an error, should we try to keep going?
//
if (GroupType == WINNT_GROUP_GLOBAL) { hr = CWinNTGroup::CreateGroup(_ParentADsPath, _ParentType, _DomainName, _ServerName, GroupName, GroupType, ADS_OBJECT_BOUND, IID_IDispatch, _Credentials, (void **)ppDispatch ); } else { hr = CWinNTGroup::CreateGroup(_ParentADsPath, _ParentType, _DomainName, _ServerName, GroupName, GroupType, ADS_OBJECT_BOUND, IID_IDispatch, _Credentials, (void **)ppDispatch ); } if (FAILED(hr)) return S_FALSE; return S_OK; }
|