Leaked source code of windows server 2003
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.
 
 
 
 
 
 

466 lines
11 KiB

//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: cenumGroupCollection.cxx
//
// Contents: Windows NT 3.5 GroupCollection Enumeration Code
//
// CWinNTGroupCollectionEnum::CWinNTGroupCollectionEnum()
// CWinNTGroupCollectionEnum::CWinNTGroupCollectionEnum
// CWinNTGroupCollectionEnum::EnumObjects
// CWinNTGroupCollectionEnum::EnumObjects
//
// History:
//----------------------------------------------------------------------------
#include "winnt.hxx"
#pragma hdrstop
//+---------------------------------------------------------------------------
//
// Function: CWinNTEnumVariant::Create
//
// Synopsis:
//
// Arguments: [pCollection]
// [ppEnumVariant]
//
// Returns: HRESULT
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT
CWinNTGroupCollectionEnum::Create(
CWinNTGroupCollectionEnum FAR* FAR* ppenumvariant,
BSTR Parent,
ULONG ParentType,
BSTR ADsPath,
BSTR DomainName,
BSTR ServerName,
BSTR GroupName,
ULONG GroupType,
VARIANT var,
CWinNTCredentials& Credentials
)
{
HRESULT hr = NOERROR;
CWinNTGroupCollectionEnum FAR* penumvariant = NULL;
*ppenumvariant = NULL;
penumvariant = new CWinNTGroupCollectionEnum();
if (!penumvariant) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
hr = ADsAllocString( Parent, &penumvariant->_Parent);
BAIL_ON_FAILURE(hr);
hr = ADsAllocString( DomainName, &penumvariant->_DomainName);
BAIL_ON_FAILURE(hr);
hr = ADsAllocString( ServerName, &penumvariant->_ServerName);
BAIL_ON_FAILURE(hr);
penumvariant->_ParentType = ParentType;
hr = ADsAllocString(ADsPath, &penumvariant->_ADsPath);
BAIL_ON_FAILURE(hr);
hr = ADsAllocString( GroupName, &penumvariant->_GroupName);
BAIL_ON_FAILURE(hr);
penumvariant->_GroupType = GroupType;
hr = ObjectTypeList::CreateObjectTypeList(
var,
&penumvariant->_pObjList
);
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;
RRETURN_EXP_IF_ERR(hr);
}
CWinNTGroupCollectionEnum::CWinNTGroupCollectionEnum():
_Parent(NULL),
_ParentType(0),
_ADsPath(NULL),
_DomainName(NULL),
_ServerName(NULL),
_GroupName(NULL),
_lpServerName(NULL),
_hGroup(NULL)
{
_pObjList = NULL;
}
CWinNTGroupCollectionEnum::CWinNTGroupCollectionEnum(ObjectTypeList ObjList):
_Parent(NULL),
_ParentType(0),
_ADsPath(NULL),
_DomainName(NULL),
_ServerName(NULL),
_GroupName(NULL),
_lpServerName(NULL),
_hGroup(NULL)
{
_pObjList = NULL;
}
CWinNTGroupCollectionEnum::~CWinNTGroupCollectionEnum()
{
if (_hGroup) {
if (_GroupType == WINNT_GROUP_GLOBAL) {
WinNTGlobalGroupClose(
_hGroup
);
}else {
WinNTLocalGroupClose(
_hGroup
);
}
}
if (_Parent) {
ADsFreeString(_Parent);
}
if (_DomainName) {
ADsFreeString(_DomainName);
}
if (_ServerName) {
ADsFreeString(_ServerName);
}
if (_ADsPath) {
ADsFreeString(_ADsPath);
}
if (_GroupName) {
ADsFreeString(_GroupName);
}
if (_pObjList) {
delete _pObjList;
}
if (_lpServerName) {
FreeADsStr(_lpServerName) ;
}
}
HRESULT
CWinNTGroupCollectionEnum::EnumGroupMembers(
ULONG cElements,
VARIANT FAR* pvar,
ULONG FAR* pcElementFetched
)
{
HRESULT hr = S_FALSE;
IDispatch *pDispatch = NULL;
DWORD i = 0;
IADs * pIADs = NULL;
BSTR pszClass = NULL;
DWORD dwClassID;
DWORD dwFilterID;
BOOL fFound = FALSE;
while (i < cElements) {
//
// This is the global group case
//
hr = GetDomainMemberObject(&pDispatch);
if (hr == S_FALSE) {
break;
}
//
// Apply the IADsMembers::put_Filter filter.
// If the enumerated object is not one of the types to be returned,
// go on to the next member of the group.
//
hr = pDispatch->QueryInterface(IID_IADs, (void **)&pIADs);
BAIL_ON_FAILURE(hr);
//
// Determine the object class of the enumerated object and the corresponding
// object class ID number (as specified in the Filters global array).
//
hr = pIADs->get_Class(&pszClass);
BAIL_ON_FAILURE(hr);
hr = IsValidFilter(pszClass, &dwClassID, gpFilters, gdwMaxFilters);
if (SUCCEEDED(hr)) {
//
// Enumerate through the object classes listed in the user-specified filter
// until we either find a match (fFound = TRUE) or we reach the end of the
// list.
//
hr = _pObjList->Reset();
while (SUCCEEDED(hr)) {
hr = _pObjList->GetCurrentObject(&dwFilterID);
if (SUCCEEDED(hr)
&& (dwFilterID == dwClassID)
) {
fFound = TRUE;
break;
}
hr = _pObjList->Next();
}
if (!fFound) {
//
// not on the list of objects to return, try again
// with the next member of the group
//
pDispatch->Release();
pIADs->Release();
if (pszClass) {
ADsFreeString(pszClass);
}
continue;
}
}
pIADs->Release();
if (pszClass) {
ADsFreeString(pszClass);
}
//
// Return it.
//
VariantInit(&pvar[i]);
pvar[i].vt = VT_DISPATCH;
pvar[i].pdispVal = pDispatch;
(*pcElementFetched)++;
i++;
}
RRETURN_EXP_IF_ERR(hr);
error:
if (pDispatch) {
pDispatch->Release();
}
if (pIADs) {
pIADs->Release();
}
if (pszClass) {
ADsFreeString(pszClass);
}
RRETURN_EXP_IF_ERR(hr);
}
HRESULT
CWinNTGroupCollectionEnum::GetDomainMemberObject(
IDispatch ** ppDispatch
)
{
HRESULT hr = S_OK;
LPDOMAIN_GROUP_MEMBER pDomainGrpMember = NULL;
LPBYTE pBuffer = NULL;
DWORD dwReturned = 0;
BOOL dwRet = 0;
WCHAR szHostServerName[MAX_PATH];
if (!_lpServerName) {
hr = WinNTGetCachedDCName(
_DomainName,
szHostServerName,
_Credentials.GetFlags()
);
BAIL_ON_FAILURE(hr);
if (!(_lpServerName = AllocADsStr(szHostServerName))) {
hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY) ;
BAIL_ON_FAILURE(hr);
}
}
if (!_hGroup) {
dwRet = WinNTGlobalGroupOpen(
_DomainName,
_lpServerName + 2, // skip the 2 leading back slashes
_GroupName,
&_hGroup
);
if (!dwRet) {
goto error;
}
}
dwRet = WinNTGlobalGroupEnum(
_hGroup,
1,
&pBuffer,
&dwReturned
);
if (!dwRet) {
goto error;
}
pDomainGrpMember = (LPDOMAIN_GROUP_MEMBER)pBuffer;
switch (pDomainGrpMember->Type) {
case WINNT_USER_ID :
hr = CWinNTUser::CreateUser(
pDomainGrpMember->Parent,
WINNT_DOMAIN_ID,
pDomainGrpMember->Domain,
NULL,
pDomainGrpMember->Name,
ADS_OBJECT_BOUND,
IID_IDispatch,
_Credentials,
(void **)ppDispatch
);
break;
case WINNT_GROUP_ID:
hr = CWinNTGroup::CreateGroup(
pDomainGrpMember->Parent,
WINNT_DOMAIN_ID,
pDomainGrpMember->Domain,
NULL,
pDomainGrpMember->Name,
WINNT_GROUP_GLOBAL,
ADS_OBJECT_BOUND,
IID_IDispatch,
_Credentials,
(void **)ppDispatch
);
break;
default:
goto error;
}
BAIL_ON_FAILURE(hr);
hr = S_OK;
cleanup:
if (pBuffer) {
FreeADsMem(pBuffer);
}
RRETURN(hr);
error:
*ppDispatch = NULL;
hr = S_FALSE;
goto cleanup;
}
//+---------------------------------------------------------------------------
//
// Function: CWinNTGroupCollectionEnum::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
CWinNTGroupCollectionEnum::Next(
ULONG cElements,
VARIANT FAR* pvar,
ULONG FAR* pcElementFetched
)
{
ULONG cElementFetched = 0;
HRESULT hr = S_OK;
if (NULL == pvar)
{
hr = S_FALSE;
}
else
{
hr = EnumGroupMembers(
cElements,
pvar,
&cElementFetched
);
}
if (pcElementFetched) {
*pcElementFetched = cElementFetched;
}
RRETURN_EXP_IF_ERR(hr);
}