905 lines
22 KiB
C++
905 lines
22 KiB
C++
//---------------------------------------------------------------------------
|
|
//
|
|
//
|
|
// 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);
|
|
}
|
|
|