|
|
//---------------------------------------------------------------------------
//
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: cdsobj.cxx
//
// Contents: Microsoft ADs NDS Provider Generic Object
//
//
// History: 01-10-97 krishnag Created.
//
//----------------------------------------------------------------------------
#include "nds.hxx"
#pragma hdrstop
HRESULT CNDSGenObject::SetObjectAttributes( PADS_ATTR_INFO pAttributeEntries, DWORD dwNumAttributes, DWORD *pdwNumAttributesModified ) { HRESULT hr = S_OK;
NDS_BUFFER_HANDLE hOperationData = NULL;
DWORD i = 0; PADS_ATTR_INFO pThisAttribute = NULL;
DWORD dwStatus = 0; PNDSOBJECT pNdsDestObjects = NULL; DWORD dwNumNdsValues = 0; DWORD dwSyntaxId = 0; DWORD dwNumNDSAttributeReturn = 0;
*pdwNumAttributesModified = 0; if (dwNumAttributes <= 0) {
RRETURN(E_FAIL); }
hr = ADsNdsCreateBuffer( _hADsContext, DSV_MODIFY_ENTRY, &hOperationData ); BAIL_ON_FAILURE(hr);
for (i = 0; i < dwNumAttributes; i++) {
pThisAttribute = pAttributeEntries + i;
switch (pThisAttribute->dwControlCode) { case ADS_ATTR_UPDATE: hr = AdsTypeToNdsTypeCopyConstruct( pThisAttribute->pADsValues, pThisAttribute->dwNumValues, &pNdsDestObjects, &dwNumNdsValues, &dwSyntaxId ); CONTINUE_ON_FAILURE(hr); hr = ADsNdsPutInBuffer( _hADsContext, hOperationData, pThisAttribute->pszAttrName, dwSyntaxId, NULL, 0, DS_CLEAR_ATTRIBUTE ); BAIL_ON_FAILURE(hr); hr = ADsNdsPutInBuffer( _hADsContext, hOperationData, pThisAttribute->pszAttrName, dwSyntaxId, pNdsDestObjects, dwNumNdsValues, DS_ADD_ATTRIBUTE ); BAIL_ON_FAILURE(hr); dwNumNDSAttributeReturn++; break;
case ADS_ATTR_APPEND: hr = AdsTypeToNdsTypeCopyConstruct( pThisAttribute->pADsValues, pThisAttribute->dwNumValues, &pNdsDestObjects, &dwNumNdsValues, &dwSyntaxId ); CONTINUE_ON_FAILURE(hr); hr = ADsNdsPutInBuffer( _hADsContext, hOperationData, pThisAttribute->pszAttrName, dwSyntaxId, pNdsDestObjects, dwNumNdsValues, DS_ADD_VALUE ); BAIL_ON_FAILURE(hr); dwNumNDSAttributeReturn++; break;
case ADS_ATTR_DELETE: hr = AdsTypeToNdsTypeCopyConstruct( pThisAttribute->pADsValues, pThisAttribute->dwNumValues, &pNdsDestObjects, &dwNumNdsValues, &dwSyntaxId ); CONTINUE_ON_FAILURE(hr); hr = ADsNdsPutInBuffer( _hADsContext, hOperationData, pThisAttribute->pszAttrName, dwSyntaxId, pNdsDestObjects, dwNumNdsValues, DS_REMOVE_VALUE ); BAIL_ON_FAILURE(hr); dwNumNDSAttributeReturn++; break;
case ADS_ATTR_CLEAR:
hr = ADsNdsPutInBuffer( _hADsContext, hOperationData, pThisAttribute->pszAttrName, dwSyntaxId, NULL, 0, DS_CLEAR_ATTRIBUTE ); BAIL_ON_FAILURE(hr);
dwNumNDSAttributeReturn++; break;
default:
//
// Ignore this attribute and move on.
//
break;
}
// Clean-up in preparation for next iteration.
// Need to set pNdsDestObjects to NULL so we
// don't try to free it again in exit code.
if (pNdsDestObjects) { NdsTypeFreeNdsObjects( pNdsDestObjects, dwNumNdsValues );
pNdsDestObjects = NULL; }
}
hr = ADsNdsModifyObject( _hADsContext, _pszNDSDn, hOperationData ); BAIL_ON_FAILURE(hr);
*pdwNumAttributesModified = dwNumNDSAttributeReturn;
error:
if (pNdsDestObjects) {
NdsTypeFreeNdsObjects( pNdsDestObjects, dwNumNdsValues ); }
if (hOperationData) {
ADsNdsFreeBuffer(hOperationData); }
RRETURN(hr);
}
HRESULT CNDSGenObject::GetObjectAttributes( LPWSTR * pAttributeNames, DWORD dwNumberAttributes, PADS_ATTR_INFO *ppAttributeEntries, DWORD * pdwNumAttributesReturned ) { HRESULT hr = S_OK; DWORD i = 0; DWORD dwNdsSyntaxId = 0; DWORD dwNumValues = 0;
NDS_BUFFER_HANDLE hOperationData = NULL;
DWORD dwStatus = 0; HANDLE hObject = NULL; LPWSTR * pThisAttributeName = NULL;
PADS_ATTR_INFO pAdsAttributes = NULL; PADS_ATTR_INFO pThisAttributeDef = NULL; DWORD dwAttrCount = 0;
DWORD dwNumberOfEntries = 0; LPNDS_ATTR_INFO lpEntries = NULL;
PADSVALUE pAdsDestValues = NULL;
DWORD j = 0;
PADS_ATTR_INFO pThisAdsSrcAttribute = NULL; PADS_ATTR_INFO pThisAdsTargAttribute = NULL;
PADS_ATTR_INFO pAttrEntry = NULL; PADSVALUE pAttrValue = NULL;
DWORD dwMemSize = 0;
LPBYTE pAttributeBuffer = NULL; LPBYTE pValueBuffer = NULL; LPBYTE pDataBuffer = NULL;
PADSVALUE pThisAdsSrcValue = NULL;
PADSVALUE pThisAdsTargValue = NULL; DWORD dwTotalValues = 0;
hr = ADsNdsReadObject( _hADsContext, _pszNDSDn, DS_ATTRIBUTE_VALUES, pAttributeNames, dwNumberAttributes, NULL, &lpEntries, &dwNumberOfEntries ); BAIL_ON_FAILURE(hr);
//
// Allocate an attribute buffer which is as large as the
// number of attributes present
//
//
pAdsAttributes = (PADS_ATTR_INFO)AllocADsMem( sizeof(ADS_ATTR_INFO)*dwNumberOfEntries ); if (!pAdsAttributes){
hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr);
}
for (i = 0; i < dwNumberOfEntries; i++) {
pThisAttributeDef = pAdsAttributes + dwAttrCount;
dwNumValues = lpEntries[i].dwNumberOfValues;
hr = NdsTypeToAdsTypeCopyConstruct( lpEntries[i].lpValue, lpEntries[i].dwNumberOfValues, &pAdsDestValues ); if (FAILED(hr)){ continue; }
pThisAttributeDef->pszAttrName = AllocADsStr(lpEntries[i].szAttributeName);
pThisAttributeDef->pADsValues = pAdsDestValues;
pThisAttributeDef->dwNumValues = dwNumValues;
pThisAttributeDef->dwADsType = g_MapNdsTypeToADsType[lpEntries[i].dwSyntaxId];
dwAttrCount++;
}
//
// Now package this data into a single contiguous buffer
//
hr = ComputeAttributeBufferSize( pAdsAttributes, dwAttrCount, &dwMemSize ); BAIL_ON_FAILURE(hr);
hr = ComputeNumberofValues( pAdsAttributes, dwAttrCount, &dwTotalValues ); BAIL_ON_FAILURE(hr);
pAttributeBuffer = (LPBYTE)AllocADsMem(dwMemSize);
if (!pAttributeBuffer) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
pValueBuffer = pAttributeBuffer + dwAttrCount * (sizeof(ADS_ATTR_INFO));
pDataBuffer = pValueBuffer + dwTotalValues * sizeof(ADSVALUE);
pAttrEntry = (PADS_ATTR_INFO)pAttributeBuffer;
pAttrValue = (PADSVALUE)pValueBuffer;
for (i = 0; i < dwAttrCount; i++) {
pThisAdsSrcAttribute = pAdsAttributes + i;
pThisAdsTargAttribute = pAttrEntry + i;
pThisAdsTargAttribute->pADsValues = pAttrValue;
pThisAdsTargAttribute->dwNumValues = pThisAdsSrcAttribute->dwNumValues;
pThisAdsTargAttribute->dwADsType = pThisAdsSrcAttribute->dwADsType;
dwNumValues = pThisAdsSrcAttribute->dwNumValues;
pThisAdsSrcValue = pThisAdsSrcAttribute->pADsValues;
pThisAdsTargValue = pAttrValue;
for (j = 0; j < dwNumValues; j++) {
pDataBuffer = AdsTypeCopy( pThisAdsSrcValue, pThisAdsTargValue, pDataBuffer ); pAttrValue++; pThisAdsTargValue = pAttrValue; pThisAdsSrcValue++;
}
pDataBuffer = AdsCopyAttributeName( pThisAdsSrcAttribute, pThisAdsTargAttribute, pDataBuffer );
}
hr = S_OK;
*ppAttributeEntries = (PADS_ATTR_INFO)pAttributeBuffer; *pdwNumAttributesReturned = dwAttrCount;
cleanup:
//
// Clean up the header based Ods structures
//
FreeNdsAttrInfo( lpEntries, dwNumberOfEntries );
if (pAdsAttributes) {
for (i = 0; i < dwAttrCount; i++) { pThisAttributeDef = pAdsAttributes + i;
if (pThisAttributeDef->pszAttrName) FreeADsStr(pThisAttributeDef->pszAttrName);
AdsFreeAdsValues( pThisAttributeDef->pADsValues, pThisAttributeDef->dwNumValues );
FreeADsMem(pThisAttributeDef->pADsValues); }
FreeADsMem(pAdsAttributes); }
RRETURN(hr);
error:
if (pAttributeBuffer) { FreeADsMem(pAttributeBuffer); }
*ppAttributeEntries = (PADS_ATTR_INFO) NULL; *pdwNumAttributesReturned = 0;
goto cleanup; }
HRESULT CNDSGenObject::CreateDSObject( LPWSTR pszRDNName, PADS_ATTR_INFO pAttributeEntries, DWORD dwNumAttributes, IDispatch * FAR* ppObject ) { HRESULT hr = S_OK; WCHAR *pszNDSTreeName = NULL; WCHAR *pszNDSDn = NULL;
NDS_BUFFER_HANDLE hOperationData = NULL;
DWORD i = 0; PADS_ATTR_INFO pThisAttribute = NULL;
DWORD dwStatus = 0; PNDSOBJECT pNdsDestObjects = NULL; DWORD dwNumNdsValues = 0; DWORD dwSyntaxId = 0; IADs *pADs = NULL; TCHAR szADsClassName[64]; BSTR bstrChildPath = NULL;
hr = BuildADsPath( _ADsPath, pszRDNName, &bstrChildPath ); BAIL_ON_FAILURE(hr);
hr = BuildNDSPathFromADsPath2( bstrChildPath, &pszNDSTreeName, &pszNDSDn ); BAIL_ON_FAILURE(hr);
hr = ADsNdsCreateBuffer( _hADsContext, DSV_ADD_ENTRY, &hOperationData ); BAIL_ON_FAILURE(hr);
for (i = 0; i < dwNumAttributes; i++) {
pThisAttribute = pAttributeEntries + i;
hr = AdsTypeToNdsTypeCopyConstruct( pThisAttribute->pADsValues, pThisAttribute->dwNumValues, &pNdsDestObjects, &dwNumNdsValues, &dwSyntaxId ); CONTINUE_ON_FAILURE(hr);
hr = ADsNdsPutInBuffer( _hADsContext, hOperationData, pThisAttribute->pszAttrName, dwSyntaxId, pNdsDestObjects, dwNumNdsValues, DS_ADD_ATTRIBUTE ); BAIL_ON_FAILURE(hr);
if (pNdsDestObjects) {
NdsTypeFreeNdsObjects( pNdsDestObjects, dwNumNdsValues );
pNdsDestObjects = NULL; }
}
hr = ADsNdsAddObject( _hADsContext, pszNDSDn, hOperationData ); BAIL_ON_FAILURE(hr);
for (i = 0; i < dwNumAttributes; i++) { pThisAttribute = pAttributeEntries + i; if ( _tcsicmp( pThisAttribute->pszAttrName, TEXT("Object Class")) == 0 ) { _tcscpy( szADsClassName, (LPTSTR)pThisAttribute->pADsValues->CaseIgnoreString); break; } }
//
// If the object is a user object, we set the initial password to NULL.
//
if (_wcsicmp(szADsClassName, L"user") == 0) { hr = ADsNdsGenObjectKey(_hADsContext, pszNDSDn); BAIL_ON_FAILURE(hr); } hr = CNDSGenObject::CreateGenericObject( _ADsPath, pszRDNName, szADsClassName, _Credentials, ADS_OBJECT_BOUND, IID_IADs, (void **)&pADs ); BAIL_ON_FAILURE(hr);
hr = InstantiateDerivedObject( pADs, _Credentials, IID_IDispatch, (void **)ppObject );
if (FAILED(hr)) { hr = pADs->QueryInterface( IID_IDispatch, (void **)ppObject ); BAIL_ON_FAILURE(hr); }
error:
if (pADs) { pADs->Release(); } if (pNdsDestObjects) {
NdsTypeFreeNdsObjects( pNdsDestObjects, dwNumNdsValues ); }
if (pszNDSTreeName) {
FreeADsStr(pszNDSTreeName); }
if (pszNDSDn) {
FreeADsStr(pszNDSDn); }
if (bstrChildPath) { SysFreeString(bstrChildPath); }
if (hOperationData) {
ADsNdsFreeBuffer(hOperationData); }
RRETURN(hr);
}
HRESULT CNDSGenObject::DeleteDSObject( LPWSTR pszRDNName ) { WCHAR *pszNDSTreeName = NULL, *pszNDSDn = NULL ; HRESULT hr = S_OK; DWORD dwStatus = 0; BSTR bstrChildPath = NULL;
hr = BuildADsPath( _ADsPath, pszRDNName, &bstrChildPath ); BAIL_ON_FAILURE(hr);
hr = BuildNDSPathFromADsPath2( bstrChildPath, &pszNDSTreeName, &pszNDSDn ); BAIL_ON_FAILURE(hr);
hr = ADsNdsRemoveObject( _hADsContext, pszNDSDn ); BAIL_ON_FAILURE(hr);
error: if (bstrChildPath) { SysFreeString(bstrChildPath); }
if (pszNDSTreeName) { FreeADsStr(pszNDSTreeName);
}
if (pszNDSDn) { FreeADsStr(pszNDSDn);
}
RRETURN(hr); }
HRESULT ComputeAttributeBufferSize( PADS_ATTR_INFO pAdsAttributes, DWORD dwNumAttributes, PDWORD pdwSize ) { DWORD i = 0; DWORD j = 0; PADS_ATTR_INFO pThisAttribute = NULL; PADSVALUE pAdsSrcValues = NULL; DWORD dwSize = 0; DWORD dwVarSz = 0; DWORD dwNumValues = 0; HRESULT hr = S_OK;
for (i = 0; i < dwNumAttributes; i++) {
pThisAttribute = pAdsAttributes + i;
dwNumValues = pThisAttribute->dwNumValues;
pAdsSrcValues = pThisAttribute->pADsValues;
for (j = 0; j < dwNumValues; j++) {
dwVarSz = AdsTypeSize(pAdsSrcValues + j);
dwSize += dwVarSz;
dwSize += sizeof(ADSVALUE);
}
dwSize += sizeof(ADS_ATTR_INFO);
dwSize += (wcslen(pThisAttribute->pszAttrName) + 1)*sizeof(WCHAR); }
*pdwSize = dwSize;
RRETURN(S_OK); }
HRESULT ComputeNumberofValues( PADS_ATTR_INFO pAdsAttributes, DWORD dwNumAttributes, PDWORD pdwNumValues ) { DWORD i = 0; PADS_ATTR_INFO pThisAttribute = NULL; DWORD dwNumValues = 0; DWORD dwTotalNumValues = 0;
for (i = 0; i < dwNumAttributes; i++) {
pThisAttribute = pAdsAttributes + i;
dwNumValues = pThisAttribute->dwNumValues;
dwTotalNumValues += dwNumValues;
}
*pdwNumValues = dwTotalNumValues;
RRETURN(S_OK); }
DWORD ComputeObjectInfoSize( PADS_OBJECT_INFO pObjectInfo ) { DWORD dwLen = 0;
dwLen += (wcslen(pObjectInfo->pszRDN) + 1) * sizeof(WCHAR); dwLen += (wcslen(pObjectInfo->pszObjectDN) + 1) * sizeof(WCHAR); dwLen += (wcslen(pObjectInfo->pszParentDN) + 1) * sizeof(WCHAR); dwLen += (wcslen(pObjectInfo->pszSchemaDN) + 1) * sizeof(WCHAR); dwLen += (wcslen(pObjectInfo->pszClassName) + 1) * sizeof(WCHAR);
dwLen += sizeof(ADS_OBJECT_INFO);
return(dwLen); }
LPBYTE PackStrings( LPWSTR *pSource, LPBYTE pDest, DWORD *DestOffsets, LPBYTE pEnd );
//
// This assumes that addr is an LPBYTE type.
//
#define WORD_ALIGN_DOWN(addr) \
addr = ((LPBYTE)((DWORD)addr & ~1))
DWORD ObjectInfoStrings[] =
{ FIELD_OFFSET(ADS_OBJECT_INFO, pszRDN), FIELD_OFFSET(ADS_OBJECT_INFO, pszObjectDN), FIELD_OFFSET(ADS_OBJECT_INFO, pszParentDN), FIELD_OFFSET(ADS_OBJECT_INFO, pszSchemaDN), FIELD_OFFSET(ADS_OBJECT_INFO, pszClassName), 0xFFFFFFFF };
HRESULT MarshallObjectInfo( PADS_OBJECT_INFO pSrcObjectInfo, LPBYTE pDestObjectInfo, LPBYTE pEnd ) { LPWSTR SourceStrings[sizeof(ADS_OBJECT_INFO)/sizeof(LPWSTR)]; LPWSTR *pSourceStrings=SourceStrings;
memset(SourceStrings, 0, sizeof(ADS_OBJECT_INFO)); *pSourceStrings++ = pSrcObjectInfo->pszRDN; *pSourceStrings++ = pSrcObjectInfo->pszObjectDN; *pSourceStrings++ = pSrcObjectInfo->pszParentDN; *pSourceStrings++ = pSrcObjectInfo->pszSchemaDN; *pSourceStrings++ = pSrcObjectInfo->pszClassName;
pEnd = PackStrings( SourceStrings, pDestObjectInfo, ObjectInfoStrings, pEnd );
RRETURN(S_OK); }
HRESULT CNDSGenObject::GetObjectInformation( THIS_ PADS_OBJECT_INFO * ppObjInfo ) {
ADS_OBJECT_INFO ObjectInfo; PADS_OBJECT_INFO pObjectInfo = &ObjectInfo; LPBYTE pBuffer = NULL; DWORD dwSize = 0;
HRESULT hr = S_OK;
pObjectInfo->pszRDN = _Name; pObjectInfo->pszObjectDN = _ADsPath; pObjectInfo->pszParentDN = _Parent; pObjectInfo->pszSchemaDN = _Schema; pObjectInfo->pszClassName = _ADsClass;
dwSize = ComputeObjectInfoSize(pObjectInfo);
pBuffer = (LPBYTE)AllocADsMem(dwSize); if (!pBuffer) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
hr = MarshallObjectInfo( pObjectInfo, pBuffer, pBuffer + dwSize ); BAIL_ON_FAILURE(hr);
*ppObjInfo = (PADS_OBJECT_INFO)pBuffer;
error:
RRETURN(hr); }
LPBYTE PackStrings( LPWSTR *pSource, LPBYTE pDest, DWORD *DestOffsets, LPBYTE pEnd ) { DWORD cbStr; WORD_ALIGN_DOWN(pEnd);
while (*DestOffsets != -1) { if (*pSource) { cbStr = wcslen(*pSource)*sizeof(WCHAR) + sizeof(WCHAR); pEnd -= cbStr; CopyMemory( pEnd, *pSource, cbStr); *(LPWSTR *)(pDest+*DestOffsets) = (LPWSTR)pEnd; } else { *(LPWSTR *)(pDest+*DestOffsets)=0; } pSource++; DestOffsets++; } return pEnd; }
LPBYTE AdsCopyAttributeName( PADS_ATTR_INFO pThisAdsSrcAttribute, PADS_ATTR_INFO pThisAdsTargAttribute, LPBYTE pDataBuffer ) {
LPWSTR pCurrentPos = (LPWSTR)pDataBuffer;
wcscpy(pCurrentPos, pThisAdsSrcAttribute->pszAttrName);
pThisAdsTargAttribute->pszAttrName = pCurrentPos;
pDataBuffer = pDataBuffer + (wcslen(pThisAdsSrcAttribute->pszAttrName) + 1)*sizeof(WCHAR);
return(pDataBuffer); }
|