|
|
//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: cggi.cxx
//
// Contents: This file contains the Group Object's
// IADsGroup and IADsGroupOperation methods
//
// History: 11-1-95 krishnag Created.
//
//----------------------------------------------------------------------------
#include "nds.hxx"
#pragma hdrstop
BOOL VerifyIfMember( BSTR bstrMember, VARIANT * VariantArray, ULONG cElementFetched );
// Class CNDSGroup
STDMETHODIMP CNDSGroup::get_Description(THIS_ BSTR FAR* retval) { GET_PROPERTY_BSTR((IADsGroup *)this,Description); }
STDMETHODIMP CNDSGroup::put_Description(THIS_ BSTR bstrDescription) { PUT_PROPERTY_BSTR((IADsGroup *)this,Description); }
STDMETHODIMP CNDSGroup::Members( THIS_ IADsMembers FAR* FAR* ppMembers ) { VARIANT varProp; HRESULT hr = S_OK; BSTR bstrADsPath = NULL;
if (!ppMembers) { RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER); }
VariantInit(&varProp);
hr = _pADs->GetEx(L"Member", &varProp);
//
// Do not bail out on failure here if you could not find
// any data set for the Members property. You need to
// pass it all the way through and on enumeration
// return nothing.
//
if (hr == E_ADS_PROPERTY_NOT_FOUND) { SAFEARRAY *aList = NULL;
VariantInit(&varProp);
SAFEARRAYBOUND aBound;
aBound.lLbound = 0; aBound.cElements = 0;
aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
if ( aList == NULL ) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
V_VT(&varProp) = VT_ARRAY | VT_VARIANT; V_ARRAY(&varProp) = aList; } else { BAIL_ON_FAILURE(hr); }
hr = _pADs->get_ADsPath(&bstrADsPath);
hr = CNDSGroupCollection::CreateGroupCollection( bstrADsPath, varProp, _Credentials, IID_IADsMembers, (void **)ppMembers );
BAIL_ON_FAILURE(hr);
error:
if (bstrADsPath) { ADsFreeString(bstrADsPath); }
VariantClear(&varProp);
RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CNDSGroup::IsMember( THIS_ BSTR bstrMember, VARIANT_BOOL FAR* bMember ) { IADsMembers FAR * pMembers = NULL; IUnknown FAR * pUnknown = NULL; IEnumVARIANT FAR * pEnumVar = NULL; DWORD i = 0; HRESULT hr = S_OK; VARIANT_BOOL fMember = FALSE; VARIANT VariantArray[10]; BOOL fContinue = TRUE; ULONG cElementFetched = 0;
if (!bstrMember) { RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER); }
if (!bMember) { RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER); }
hr = Members( &pMembers ); BAIL_ON_FAILURE(hr);
hr = pMembers->get__NewEnum( &pUnknown ); //
// If it has no members, we will return FALSE
//
if (hr == E_FAIL) { hr = S_OK; goto error; }
hr = pUnknown->QueryInterface( IID_IEnumVARIANT, (void **)&pEnumVar ); BAIL_ON_FAILURE(hr);
while (fContinue) {
hr = pEnumVar->Next( 10, VariantArray, &cElementFetched );
if (hr == S_FALSE) { fContinue = FALSE;
//
// Reset hr to S_OK, we want to return success
//
hr = S_OK; }
fMember = (VARIANT_BOOL)VerifyIfMember( bstrMember, VariantArray, cElementFetched ); if (fMember) {
fContinue = FALSE; }
for (i = 0; i < cElementFetched; i++ ) {
IDispatch *pDispatch = NULL;
pDispatch = VariantArray[i].pdispVal; pDispatch->Release();
}
memset(VariantArray, 0, sizeof(VARIANT)*10);
}
error:
*bMember = fMember? VARIANT_TRUE: VARIANT_FALSE;
if (pEnumVar) { pEnumVar->Release(); }
if (pUnknown) { pUnknown->Release(); }
if (pMembers) { pMembers->Release(); }
RRETURN_EXP_IF_ERR(hr); }
BOOL VerifyIfMember( BSTR bstrMember, VARIANT * VariantArray, ULONG cElementFetched ) { DWORD i = 0; HRESULT hr = S_OK; IADs FAR * pObject = NULL; IDispatch FAR * pDispatch = NULL;
for (i = 0; i < cElementFetched; i++ ) {
IDispatch *pDispatch = NULL; BSTR bstrName = NULL;
pDispatch = VariantArray[i].pdispVal;
hr = pDispatch->QueryInterface( IID_IADs, (VOID **) &pObject ); BAIL_ON_FAILURE(hr);
hr = pObject->get_ADsPath(&bstrName); BAIL_ON_FAILURE(hr);
if (!_wcsicmp(bstrName, bstrMember)) {
SysFreeString(bstrName); bstrName = NULL;
pObject->Release();
return(TRUE);
}
SysFreeString(bstrName); bstrName = NULL;
pObject->Release();
}
error:
return(FALSE);
}
STDMETHODIMP CNDSGroup::Add(THIS_ BSTR bstrNewItem) { HRESULT hr = S_OK;
WCHAR szNDSUserPathName[MAX_PATH]; WCHAR szNDSUserTreeName[MAX_PATH]; IUnknown * pUnknown = NULL; IADs * pUser = NULL;
WCHAR szNDSGroupPathName[MAX_PATH]; WCHAR szNDSGroupTreeName[MAX_PATH]; BSTR bstrPathName = NULL;
BSTR pszClass = NULL;
hr = ::GetObject( bstrNewItem, _Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr);
hr = pUnknown->QueryInterface(IID_IADs, (void **)&pUser); BAIL_ON_FAILURE(hr);
hr = BuildNDSPathFromADsPath( bstrNewItem, szNDSUserTreeName, szNDSUserPathName ); BAIL_ON_FAILURE(hr);
hr = _pADs->get_ADsPath(&bstrPathName); BAIL_ON_FAILURE(hr);
hr = BuildNDSPathFromADsPath( bstrPathName, szNDSGroupTreeName, szNDSGroupPathName ); BAIL_ON_FAILURE(hr);
hr = AddEntry(_pADs, L"Member",szNDSUserPathName); BAIL_ON_FAILURE(hr);
// hr = AddEntry(_pADs, L"Equivalent To Me", szNDSUserPathName);
// BAIL_ON_FAILURE(hr);
//
// Groups do not have a "Group Membership" attribute
//
hr = pUser->get_Class(&pszClass); BAIL_ON_FAILURE(hr);
if (_wcsicmp(pszClass, L"group") != 0) { hr = AddEntry(pUser, L"Group Membership", szNDSGroupPathName); BAIL_ON_FAILURE(hr); }
error:
if (pszClass) { ADsFreeString(pszClass); }
if (bstrPathName) { ADsFreeString(bstrPathName); }
if (pUnknown) { pUnknown->Release(); }
if (pUser) { pUser->Release(); }
RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CNDSGroup::Remove(THIS_ BSTR bstrNewItem) { HRESULT hr = S_OK;
WCHAR szNDSUserPathName[MAX_PATH]; WCHAR szNDSUserTreeName[MAX_PATH]; IUnknown * pUnknown = NULL; IADs * pUser = NULL;
WCHAR szNDSGroupPathName[MAX_PATH]; WCHAR szNDSGroupTreeName[MAX_PATH]; BSTR bstrPathName = NULL;
BSTR pszClass = NULL;
hr = ::GetObject( bstrNewItem, _Credentials, (void **)&pUnknown );
BAIL_ON_FAILURE(hr);
hr = pUnknown->QueryInterface(IID_IADs, (void **)&pUser); BAIL_ON_FAILURE(hr);
hr = BuildNDSPathFromADsPath( bstrNewItem, szNDSUserTreeName, szNDSUserPathName ); BAIL_ON_FAILURE(hr);
hr = _pADs->get_ADsPath(&bstrPathName); BAIL_ON_FAILURE(hr);
hr = BuildNDSPathFromADsPath( bstrPathName, szNDSGroupTreeName, szNDSGroupPathName ); BAIL_ON_FAILURE(hr);
hr = RemoveEntry(_pADs, L"Member",szNDSUserPathName); BAIL_ON_FAILURE(hr);
// hr = RemoveEntry(_pADs, L"Equivalent To Me", szNDSUserPathName);
// BAIL_ON_FAILURE(hr);
//
// Groups do not have a "Group Membership" attribute
//
hr = pUser->get_Class(&pszClass); BAIL_ON_FAILURE(hr);
if (_wcsicmp(pszClass, L"group") != 0) { hr = RemoveEntry(pUser, L"Group Membership", szNDSGroupPathName); BAIL_ON_FAILURE(hr); }
error:
if (pszClass) { ADsFreeString(pszClass); }
if (bstrPathName) { ADsFreeString(bstrPathName); }
if (pUnknown) { pUnknown->Release(); }
if (pUser) { pUser->Release(); }
RRETURN_EXP_IF_ERR(hr); }
HRESULT AddEntry( IADs * pADs, LPWSTR pszAttribute, LPWSTR pszValue ) {
HRESULT hr = S_OK; VARIANT vOldValue; VARIANT vNewValue; SAFEARRAY * pArray = NULL;
VariantInit(&vOldValue); VariantInit(&vNewValue);
#if defined(BUILD_FOR_NT40)
hr = pADs->Get(pszAttribute, &vOldValue); if (hr == E_ADS_PROPERTY_NOT_FOUND) {
VariantInit(&vNewValue); V_BSTR(&vNewValue) = SysAllocString(pszValue); V_VT(&vNewValue) = VT_BSTR;
hr = pADs->Put(pszAttribute, vNewValue); BAIL_ON_FAILURE(hr);
}else{
hr = VarAddEntry( pszValue, vOldValue, &vNewValue ); BAIL_ON_FAILURE(hr);
hr = pADs->Put(pszAttribute, vNewValue); BAIL_ON_FAILURE(hr); } #else
//
// NT5 supports appending values. So we don't need to read everything.
// append ourselves and write everything
//
SAFEARRAYBOUND sabNewArray; int i; VARIANT v;
sabNewArray.cElements = 1; sabNewArray.lLbound = 0;
pArray = SafeArrayCreate( VT_VARIANT, 1, &sabNewArray ); if (!pArray) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
VariantInit(&v);
V_BSTR(&v) = SysAllocString(pszValue); V_VT(&v) = VT_BSTR;
i = 0; hr = SafeArrayPutElement( pArray, (long *)&i, (void *)&v );
VariantClear(&v);
BAIL_ON_FAILURE(hr);
V_VT(&vNewValue) = VT_ARRAY | VT_VARIANT; V_ARRAY(&vNewValue) = pArray;
hr = pADs->PutEx(ADS_PROPERTY_APPEND, pszAttribute, vNewValue); BAIL_ON_FAILURE(hr);
#endif
hr = pADs->SetInfo(); BAIL_ON_FAILURE(hr);
error:
VariantClear(&vOldValue); VariantClear(&vNewValue);
RRETURN(hr); }
HRESULT RemoveEntry( IADs * pADs, LPWSTR pszAttribute, LPWSTR pszValue ) { HRESULT hr = S_OK; VARIANT vOldValue; VARIANT vNewValue; SAFEARRAY * pArray = NULL;
VariantInit(&vOldValue); VariantInit(&vNewValue);
#if defined(BUILD_FOR_NT40)
hr = pADs->Get(pszAttribute, &vOldValue); BAIL_ON_FAILURE(hr);
hr = VarRemoveEntry( pszValue, vOldValue, &vNewValue ); BAIL_ON_FAILURE(hr);
if (V_VT(&vNewValue) == VT_EMPTY) { hr = pADs->PutEx(ADS_PROPERTY_CLEAR, pszAttribute, vNewValue); }else { hr = pADs->Put(pszAttribute, vNewValue);
} BAIL_ON_FAILURE(hr);
#else
SAFEARRAYBOUND sabNewArray; VARIANT v; int i;
//
// NT5 supports deleting values. So we don't need to read everything.
// delete ourselves and write everything - Very inefficient!
//
sabNewArray.cElements = 1; sabNewArray.lLbound = 0;
pArray = SafeArrayCreate( VT_VARIANT, 1, &sabNewArray ); if (!pArray) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
VariantInit(&v);
V_BSTR(&v) = SysAllocString(pszValue); V_VT(&v) = VT_BSTR;
i = 0; hr = SafeArrayPutElement( pArray, (long *)&i, (void *)&v );
VariantClear(&v);
BAIL_ON_FAILURE(hr);
V_VT(&vNewValue) = VT_ARRAY | VT_VARIANT; V_ARRAY(&vNewValue) = pArray;
hr = pADs->PutEx(ADS_PROPERTY_DELETE, pszAttribute, vNewValue); BAIL_ON_FAILURE(hr);
#endif
hr = pADs->SetInfo(); BAIL_ON_FAILURE(hr);
error:
VariantClear(&vOldValue); VariantClear(&vNewValue);
RRETURN(hr); }
HRESULT VarFindEntry( LPWSTR pszNDSPathName, VARIANT varMembers ) { HRESULT hr = S_OK; DWORD dwSLBound = 0; DWORD dwSUBound = 0; DWORD i = 0; VARIANT v;
if (!(V_VT(&varMembers) == (VT_VARIANT|VT_ARRAY))) { return(E_FAIL); }
//
// Check that there is only one dimension in this array
//
if ((V_ARRAY(&varMembers))->cDims != 1) { hr = E_FAIL; BAIL_ON_FAILURE(hr); } //
// Check that there is atleast one element in this array
//
if ((V_ARRAY(&varMembers))->rgsabound[0].cElements == 0){ hr = E_FAIL; BAIL_ON_FAILURE(hr); }
//
// We know that this is a valid single dimension array
//
hr = SafeArrayGetLBound(V_ARRAY(&varMembers), 1, (long FAR *)&dwSLBound ); BAIL_ON_FAILURE(hr);
hr = SafeArrayGetUBound(V_ARRAY(&varMembers), 1, (long FAR *)&dwSUBound ); BAIL_ON_FAILURE(hr);
for (i = dwSLBound; i <= dwSUBound; i++) { VariantInit(&v); hr = SafeArrayGetElement(V_ARRAY(&varMembers), (long FAR *)&i, &v );
if (!_wcsicmp(V_BSTR(&v), pszNDSPathName)) { VariantClear(&v); RRETURN(S_OK); }
VariantClear(&v); }
error:
RRETURN(E_FAIL); }
HRESULT VarMultipleAddEntry( LPWSTR pszNDSPathName, VARIANT varMembers, VARIANT * pvarNewMembers ) { SAFEARRAYBOUND sabNewArray; SAFEARRAY * pFilter = NULL; HRESULT hr = S_OK; DWORD dwSLBound = 0; DWORD dwSUBound = 0; DWORD i = 0; VARIANT v;
VariantInit(pvarNewMembers);
if (!(V_VT(&varMembers) == (VT_VARIANT|VT_ARRAY))) { return(E_FAIL); }
//
// Check that there is only one dimension in this array
//
if ((V_ARRAY(&varMembers))->cDims != 1) { hr = E_FAIL; BAIL_ON_FAILURE(hr); } //
// Check that there is atleast one element in this array
//
if ((V_ARRAY(&varMembers))->rgsabound[0].cElements == 0){ hr = E_FAIL; BAIL_ON_FAILURE(hr); }
//
// We know that this is a valid single dimension array
//
hr = SafeArrayGetLBound(V_ARRAY(&varMembers), 1, (long FAR *)&dwSLBound ); BAIL_ON_FAILURE(hr);
hr = SafeArrayGetUBound(V_ARRAY(&varMembers), 1, (long FAR *)&dwSUBound ); BAIL_ON_FAILURE(hr);
sabNewArray.cElements = (dwSUBound - dwSLBound + 1) + 1; sabNewArray.lLbound = dwSLBound;
pFilter = SafeArrayCreate( VT_VARIANT, 1, &sabNewArray );
if (!pFilter) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
for (i = dwSLBound; i <= dwSUBound; i++) {
VariantInit(&v);
hr = SafeArrayGetElement( V_ARRAY(&varMembers), (long FAR *)&i, &v ); BAIL_ON_FAILURE(hr);
hr = SafeArrayPutElement( pFilter, (long*)&i, (void *)&v );
VariantClear(&v); BAIL_ON_FAILURE(hr);
}
VariantInit(&v); V_VT(&v) = VT_BSTR; V_BSTR(&v) = SysAllocString(pszNDSPathName);
hr = SafeArrayPutElement( pFilter, (long *)&i, (void *)&v ); VariantClear(&v); BAIL_ON_FAILURE(hr);
V_VT(pvarNewMembers) = VT_ARRAY | VT_VARIANT; V_ARRAY(pvarNewMembers) = pFilter;
RRETURN(S_OK);
error:
if (pFilter) { SafeArrayDestroy(pFilter); }
RRETURN(hr); }
HRESULT VarMultipleRemoveEntry( LPWSTR pszNDSPathName, VARIANT varMembers, VARIANT * pvarNewMembers ) { SAFEARRAYBOUND sabNewArray; SAFEARRAY * pFilter = NULL; HRESULT hr = S_OK; DWORD dwSLBound = 0; DWORD dwSUBound = 0; DWORD i = 0; DWORD dwNewCount = 0; VARIANT v;
VariantInit(pvarNewMembers);
if(!(V_VT(&varMembers) == (VT_VARIANT|VT_ARRAY))){ return(E_FAIL); }
//
// Check that there is only one dimension in this array
//
if ((V_ARRAY(&varMembers))->cDims != 1) { hr = E_FAIL; BAIL_ON_FAILURE(hr); } //
// Check that there is atleast one element in this array
//
if ((V_ARRAY(&varMembers))->rgsabound[0].cElements == 0){ hr = E_FAIL; BAIL_ON_FAILURE(hr); }
//
// We know that this is a valid single dimension array
//
hr = SafeArrayGetLBound(V_ARRAY(&varMembers), 1, (long FAR *)&dwSLBound ); BAIL_ON_FAILURE(hr);
hr = SafeArrayGetUBound(V_ARRAY(&varMembers), 1, (long FAR *)&dwSUBound ); BAIL_ON_FAILURE(hr);
sabNewArray.cElements = (dwSUBound - dwSLBound); sabNewArray.lLbound = dwSLBound;
pFilter = SafeArrayCreate( VT_VARIANT, 1, &sabNewArray );
if (!pFilter) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
for (i = dwSLBound, dwNewCount = dwSLBound; i <= dwSUBound; i++) { VariantInit(&v); hr = SafeArrayGetElement( V_ARRAY(&varMembers), (long FAR *)&i, &v );
if (!_wcsicmp(V_BSTR(&v), pszNDSPathName)) {
VariantClear(&v); //
// skip this entry
//
continue;
} hr = SafeArrayPutElement( pFilter, (long*)&dwNewCount, (void *)&v );
VariantClear(&v); BAIL_ON_FAILURE(hr);
dwNewCount++;
}
V_VT(pvarNewMembers) = VT_ARRAY | VT_VARIANT; V_ARRAY(pvarNewMembers) = pFilter;
RRETURN(S_OK);
error:
if (pFilter) { SafeArrayDestroy(pFilter); }
RRETURN(hr); }
HRESULT VarSingleAddEntry( LPWSTR pszNDSPathName, VARIANT varMembers, VARIANT * pvarNewMembers ) { SAFEARRAYBOUND sabNewArray; SAFEARRAY * pFilter = NULL; HRESULT hr = S_OK; DWORD dwSLBound = 0; DWORD dwSUBound = 0; DWORD i = 0; VARIANT v;
VariantInit(pvarNewMembers);
if(!((V_VT(&varMembers) & VT_TYPEMASK) == VT_BSTR)){ return(E_FAIL); }
sabNewArray.cElements = (1) + 1; sabNewArray.lLbound = 0;
pFilter = SafeArrayCreate( VT_VARIANT, 1, &sabNewArray ); if (!pFilter) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
i = 0; hr = SafeArrayPutElement( pFilter, (long *)&i, (void *)&varMembers ); BAIL_ON_FAILURE(hr);
i++;
VariantInit(&v); V_VT(&v) = VT_BSTR; V_BSTR(&v) = SysAllocString(pszNDSPathName);
hr = SafeArrayPutElement( pFilter, (long *)&i, (void *)&v ); VariantClear(&v); BAIL_ON_FAILURE(hr);
V_VT(pvarNewMembers) = VT_ARRAY | VT_VARIANT; V_ARRAY(pvarNewMembers) = pFilter;
RRETURN(S_OK);
error:
if (pFilter) { SafeArrayDestroy(pFilter); }
RRETURN(hr); }
HRESULT VarSingleRemoveEntry( LPWSTR pszNDSPathName, VARIANT varMembers, VARIANT * pvarNewMembers ) { HRESULT hr = S_OK;
VariantInit(pvarNewMembers);
if(!((V_VT(&varMembers) & VT_TYPEMASK) == VT_BSTR)){ return(E_FAIL); }
V_VT(pvarNewMembers) = VT_EMPTY; V_BSTR(pvarNewMembers) = NULL;
RRETURN(hr); }
HRESULT VarRemoveEntry( LPWSTR pszNDSPathName, VARIANT varMembers, VARIANT * pvarNewMembers ) { HRESULT hr = S_OK;
if (V_VT(&varMembers) == (VT_VARIANT|VT_ARRAY)) {
hr = VarMultipleRemoveEntry( pszNDSPathName, varMembers, pvarNewMembers ); RRETURN(hr);
}else if (V_VT(&varMembers) == VT_BSTR){
hr = VarSingleRemoveEntry( pszNDSPathName, varMembers, pvarNewMembers );
RRETURN(hr);
}else {
RRETURN(E_FAIL); } }
HRESULT VarAddEntry( LPWSTR pszNDSPathName, VARIANT varMembers, VARIANT * pvarNewMembers ) { HRESULT hr = S_OK;
if (V_VT(&varMembers) == (VT_VARIANT|VT_ARRAY)){
hr = VarMultipleAddEntry( pszNDSPathName, varMembers, pvarNewMembers ); RRETURN(hr);
}else if ((V_VT(&varMembers) & VT_TYPEMASK) == VT_BSTR){
hr = VarSingleAddEntry( pszNDSPathName, varMembers, pvarNewMembers );
RRETURN(hr);
}else {
RRETURN(E_FAIL); } }
|