Source code of Windows XP (NT5)
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.

904 lines
22 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. //
  4. // Microsoft Windows
  5. // Copyright (C) Microsoft Corporation, 1992 - 1995
  6. //
  7. // File: cdsobj.cxx
  8. //
  9. // Contents: Microsoft ADs NDS Provider Generic Object
  10. //
  11. //
  12. // History: 01-10-97 krishnag Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "nds.hxx"
  16. #pragma hdrstop
  17. HRESULT
  18. CNDSGenObject::SetObjectAttributes(
  19. PADS_ATTR_INFO pAttributeEntries,
  20. DWORD dwNumAttributes,
  21. DWORD *pdwNumAttributesModified
  22. )
  23. {
  24. HRESULT hr = S_OK;
  25. NDS_BUFFER_HANDLE hOperationData = NULL;
  26. DWORD i = 0;
  27. PADS_ATTR_INFO pThisAttribute = NULL;
  28. DWORD dwStatus = 0;
  29. PNDSOBJECT pNdsDestObjects = NULL;
  30. DWORD dwNumNdsValues = 0;
  31. DWORD dwSyntaxId = 0;
  32. DWORD dwNumNDSAttributeReturn = 0;
  33. *pdwNumAttributesModified = 0;
  34. if (dwNumAttributes <= 0) {
  35. RRETURN(E_FAIL);
  36. }
  37. hr = ADsNdsCreateBuffer(
  38. _hADsContext,
  39. DSV_MODIFY_ENTRY,
  40. &hOperationData
  41. );
  42. BAIL_ON_FAILURE(hr);
  43. for (i = 0; i < dwNumAttributes; i++) {
  44. pThisAttribute = pAttributeEntries + i;
  45. switch (pThisAttribute->dwControlCode) {
  46. case ADS_ATTR_UPDATE:
  47. hr = AdsTypeToNdsTypeCopyConstruct(
  48. pThisAttribute->pADsValues,
  49. pThisAttribute->dwNumValues,
  50. &pNdsDestObjects,
  51. &dwNumNdsValues,
  52. &dwSyntaxId
  53. );
  54. CONTINUE_ON_FAILURE(hr);
  55. hr = ADsNdsPutInBuffer(
  56. _hADsContext,
  57. hOperationData,
  58. pThisAttribute->pszAttrName,
  59. dwSyntaxId,
  60. NULL,
  61. 0,
  62. DS_CLEAR_ATTRIBUTE
  63. );
  64. BAIL_ON_FAILURE(hr);
  65. hr = ADsNdsPutInBuffer(
  66. _hADsContext,
  67. hOperationData,
  68. pThisAttribute->pszAttrName,
  69. dwSyntaxId,
  70. pNdsDestObjects,
  71. dwNumNdsValues,
  72. DS_ADD_ATTRIBUTE
  73. );
  74. BAIL_ON_FAILURE(hr);
  75. dwNumNDSAttributeReturn++;
  76. break;
  77. case ADS_ATTR_APPEND:
  78. hr = AdsTypeToNdsTypeCopyConstruct(
  79. pThisAttribute->pADsValues,
  80. pThisAttribute->dwNumValues,
  81. &pNdsDestObjects,
  82. &dwNumNdsValues,
  83. &dwSyntaxId
  84. );
  85. CONTINUE_ON_FAILURE(hr);
  86. hr = ADsNdsPutInBuffer(
  87. _hADsContext,
  88. hOperationData,
  89. pThisAttribute->pszAttrName,
  90. dwSyntaxId,
  91. pNdsDestObjects,
  92. dwNumNdsValues,
  93. DS_ADD_VALUE
  94. );
  95. BAIL_ON_FAILURE(hr);
  96. dwNumNDSAttributeReturn++;
  97. break;
  98. case ADS_ATTR_DELETE:
  99. hr = AdsTypeToNdsTypeCopyConstruct(
  100. pThisAttribute->pADsValues,
  101. pThisAttribute->dwNumValues,
  102. &pNdsDestObjects,
  103. &dwNumNdsValues,
  104. &dwSyntaxId
  105. );
  106. CONTINUE_ON_FAILURE(hr);
  107. hr = ADsNdsPutInBuffer(
  108. _hADsContext,
  109. hOperationData,
  110. pThisAttribute->pszAttrName,
  111. dwSyntaxId,
  112. pNdsDestObjects,
  113. dwNumNdsValues,
  114. DS_REMOVE_VALUE
  115. );
  116. BAIL_ON_FAILURE(hr);
  117. dwNumNDSAttributeReturn++;
  118. break;
  119. case ADS_ATTR_CLEAR:
  120. hr = ADsNdsPutInBuffer(
  121. _hADsContext,
  122. hOperationData,
  123. pThisAttribute->pszAttrName,
  124. dwSyntaxId,
  125. NULL,
  126. 0,
  127. DS_CLEAR_ATTRIBUTE
  128. );
  129. BAIL_ON_FAILURE(hr);
  130. dwNumNDSAttributeReturn++;
  131. break;
  132. default:
  133. //
  134. // Ignore this attribute and move on.
  135. //
  136. break;
  137. }
  138. // Clean-up in preparation for next iteration.
  139. // Need to set pNdsDestObjects to NULL so we
  140. // don't try to free it again in exit code.
  141. if (pNdsDestObjects)
  142. {
  143. NdsTypeFreeNdsObjects(
  144. pNdsDestObjects,
  145. dwNumNdsValues
  146. );
  147. pNdsDestObjects = NULL;
  148. }
  149. }
  150. hr = ADsNdsModifyObject(
  151. _hADsContext,
  152. _pszNDSDn,
  153. hOperationData
  154. );
  155. BAIL_ON_FAILURE(hr);
  156. *pdwNumAttributesModified = dwNumNDSAttributeReturn;
  157. error:
  158. if (pNdsDestObjects) {
  159. NdsTypeFreeNdsObjects(
  160. pNdsDestObjects,
  161. dwNumNdsValues
  162. );
  163. }
  164. if (hOperationData) {
  165. ADsNdsFreeBuffer(hOperationData);
  166. }
  167. RRETURN(hr);
  168. }
  169. HRESULT
  170. CNDSGenObject::GetObjectAttributes(
  171. LPWSTR * pAttributeNames,
  172. DWORD dwNumberAttributes,
  173. PADS_ATTR_INFO *ppAttributeEntries,
  174. DWORD * pdwNumAttributesReturned
  175. )
  176. {
  177. HRESULT hr = S_OK;
  178. DWORD i = 0;
  179. DWORD dwNdsSyntaxId = 0;
  180. DWORD dwNumValues = 0;
  181. NDS_BUFFER_HANDLE hOperationData = NULL;
  182. DWORD dwStatus = 0;
  183. HANDLE hObject = NULL;
  184. LPWSTR * pThisAttributeName = NULL;
  185. PADS_ATTR_INFO pAdsAttributes = NULL;
  186. PADS_ATTR_INFO pThisAttributeDef = NULL;
  187. DWORD dwAttrCount = 0;
  188. DWORD dwNumberOfEntries = 0;
  189. LPNDS_ATTR_INFO lpEntries = NULL;
  190. PADSVALUE pAdsDestValues = NULL;
  191. DWORD j = 0;
  192. PADS_ATTR_INFO pThisAdsSrcAttribute = NULL;
  193. PADS_ATTR_INFO pThisAdsTargAttribute = NULL;
  194. PADS_ATTR_INFO pAttrEntry = NULL;
  195. PADSVALUE pAttrValue = NULL;
  196. DWORD dwMemSize = 0;
  197. LPBYTE pAttributeBuffer = NULL;
  198. LPBYTE pValueBuffer = NULL;
  199. LPBYTE pDataBuffer = NULL;
  200. PADSVALUE pThisAdsSrcValue = NULL;
  201. PADSVALUE pThisAdsTargValue = NULL;
  202. DWORD dwTotalValues = 0;
  203. hr = ADsNdsReadObject(
  204. _hADsContext,
  205. _pszNDSDn,
  206. DS_ATTRIBUTE_VALUES,
  207. pAttributeNames,
  208. dwNumberAttributes,
  209. NULL,
  210. &lpEntries,
  211. &dwNumberOfEntries
  212. );
  213. BAIL_ON_FAILURE(hr);
  214. //
  215. // Allocate an attribute buffer which is as large as the
  216. // number of attributes present
  217. //
  218. //
  219. pAdsAttributes = (PADS_ATTR_INFO)AllocADsMem(
  220. sizeof(ADS_ATTR_INFO)*dwNumberOfEntries
  221. );
  222. if (!pAdsAttributes){
  223. hr = E_OUTOFMEMORY;
  224. BAIL_ON_FAILURE(hr);
  225. }
  226. for (i = 0; i < dwNumberOfEntries; i++) {
  227. pThisAttributeDef = pAdsAttributes + dwAttrCount;
  228. dwNumValues = lpEntries[i].dwNumberOfValues;
  229. hr = NdsTypeToAdsTypeCopyConstruct(
  230. lpEntries[i].lpValue,
  231. lpEntries[i].dwNumberOfValues,
  232. &pAdsDestValues
  233. );
  234. if (FAILED(hr)){
  235. continue;
  236. }
  237. pThisAttributeDef->pszAttrName =
  238. AllocADsStr(lpEntries[i].szAttributeName);
  239. pThisAttributeDef->pADsValues = pAdsDestValues;
  240. pThisAttributeDef->dwNumValues = dwNumValues;
  241. pThisAttributeDef->dwADsType = g_MapNdsTypeToADsType[lpEntries[i].dwSyntaxId];
  242. dwAttrCount++;
  243. }
  244. //
  245. // Now package this data into a single contiguous buffer
  246. //
  247. hr = ComputeAttributeBufferSize(
  248. pAdsAttributes,
  249. dwAttrCount,
  250. &dwMemSize
  251. );
  252. BAIL_ON_FAILURE(hr);
  253. hr = ComputeNumberofValues(
  254. pAdsAttributes,
  255. dwAttrCount,
  256. &dwTotalValues
  257. );
  258. BAIL_ON_FAILURE(hr);
  259. pAttributeBuffer = (LPBYTE)AllocADsMem(dwMemSize);
  260. if (!pAttributeBuffer) {
  261. hr = E_OUTOFMEMORY;
  262. BAIL_ON_FAILURE(hr);
  263. }
  264. pValueBuffer = pAttributeBuffer + dwAttrCount * (sizeof(ADS_ATTR_INFO));
  265. pDataBuffer = pValueBuffer + dwTotalValues * sizeof(ADSVALUE);
  266. pAttrEntry = (PADS_ATTR_INFO)pAttributeBuffer;
  267. pAttrValue = (PADSVALUE)pValueBuffer;
  268. for (i = 0; i < dwAttrCount; i++) {
  269. pThisAdsSrcAttribute = pAdsAttributes + i;
  270. pThisAdsTargAttribute = pAttrEntry + i;
  271. pThisAdsTargAttribute->pADsValues = pAttrValue;
  272. pThisAdsTargAttribute->dwNumValues = pThisAdsSrcAttribute->dwNumValues;
  273. pThisAdsTargAttribute->dwADsType = pThisAdsSrcAttribute->dwADsType;
  274. dwNumValues = pThisAdsSrcAttribute->dwNumValues;
  275. pThisAdsSrcValue = pThisAdsSrcAttribute->pADsValues;
  276. pThisAdsTargValue = pAttrValue;
  277. for (j = 0; j < dwNumValues; j++) {
  278. pDataBuffer = AdsTypeCopy(
  279. pThisAdsSrcValue,
  280. pThisAdsTargValue,
  281. pDataBuffer
  282. );
  283. pAttrValue++;
  284. pThisAdsTargValue = pAttrValue;
  285. pThisAdsSrcValue++;
  286. }
  287. pDataBuffer = AdsCopyAttributeName(
  288. pThisAdsSrcAttribute,
  289. pThisAdsTargAttribute,
  290. pDataBuffer
  291. );
  292. }
  293. hr = S_OK;
  294. *ppAttributeEntries = (PADS_ATTR_INFO)pAttributeBuffer;
  295. *pdwNumAttributesReturned = dwAttrCount;
  296. cleanup:
  297. //
  298. // Clean up the header based Ods structures
  299. //
  300. FreeNdsAttrInfo( lpEntries, dwNumberOfEntries );
  301. if (pAdsAttributes) {
  302. for (i = 0; i < dwAttrCount; i++)
  303. {
  304. pThisAttributeDef = pAdsAttributes + i;
  305. if (pThisAttributeDef->pszAttrName)
  306. FreeADsStr(pThisAttributeDef->pszAttrName);
  307. AdsFreeAdsValues(
  308. pThisAttributeDef->pADsValues,
  309. pThisAttributeDef->dwNumValues
  310. );
  311. FreeADsMem(pThisAttributeDef->pADsValues);
  312. }
  313. FreeADsMem(pAdsAttributes);
  314. }
  315. RRETURN(hr);
  316. error:
  317. if (pAttributeBuffer) {
  318. FreeADsMem(pAttributeBuffer);
  319. }
  320. *ppAttributeEntries = (PADS_ATTR_INFO) NULL;
  321. *pdwNumAttributesReturned = 0;
  322. goto cleanup;
  323. }
  324. HRESULT
  325. CNDSGenObject::CreateDSObject(
  326. LPWSTR pszRDNName,
  327. PADS_ATTR_INFO pAttributeEntries,
  328. DWORD dwNumAttributes,
  329. IDispatch * FAR* ppObject
  330. )
  331. {
  332. HRESULT hr = S_OK;
  333. WCHAR *pszNDSTreeName = NULL;
  334. WCHAR *pszNDSDn = NULL;
  335. NDS_BUFFER_HANDLE hOperationData = NULL;
  336. DWORD i = 0;
  337. PADS_ATTR_INFO pThisAttribute = NULL;
  338. DWORD dwStatus = 0;
  339. PNDSOBJECT pNdsDestObjects = NULL;
  340. DWORD dwNumNdsValues = 0;
  341. DWORD dwSyntaxId = 0;
  342. IADs *pADs = NULL;
  343. TCHAR szADsClassName[64];
  344. BSTR bstrChildPath = NULL;
  345. hr = BuildADsPath(
  346. _ADsPath,
  347. pszRDNName,
  348. &bstrChildPath
  349. );
  350. BAIL_ON_FAILURE(hr);
  351. hr = BuildNDSPathFromADsPath2(
  352. bstrChildPath,
  353. &pszNDSTreeName,
  354. &pszNDSDn
  355. );
  356. BAIL_ON_FAILURE(hr);
  357. hr = ADsNdsCreateBuffer(
  358. _hADsContext,
  359. DSV_ADD_ENTRY,
  360. &hOperationData
  361. );
  362. BAIL_ON_FAILURE(hr);
  363. for (i = 0; i < dwNumAttributes; i++) {
  364. pThisAttribute = pAttributeEntries + i;
  365. hr = AdsTypeToNdsTypeCopyConstruct(
  366. pThisAttribute->pADsValues,
  367. pThisAttribute->dwNumValues,
  368. &pNdsDestObjects,
  369. &dwNumNdsValues,
  370. &dwSyntaxId
  371. );
  372. CONTINUE_ON_FAILURE(hr);
  373. hr = ADsNdsPutInBuffer(
  374. _hADsContext,
  375. hOperationData,
  376. pThisAttribute->pszAttrName,
  377. dwSyntaxId,
  378. pNdsDestObjects,
  379. dwNumNdsValues,
  380. DS_ADD_ATTRIBUTE
  381. );
  382. BAIL_ON_FAILURE(hr);
  383. if (pNdsDestObjects) {
  384. NdsTypeFreeNdsObjects(
  385. pNdsDestObjects,
  386. dwNumNdsValues
  387. );
  388. pNdsDestObjects = NULL;
  389. }
  390. }
  391. hr = ADsNdsAddObject(
  392. _hADsContext,
  393. pszNDSDn,
  394. hOperationData
  395. );
  396. BAIL_ON_FAILURE(hr);
  397. for (i = 0; i < dwNumAttributes; i++) {
  398. pThisAttribute = pAttributeEntries + i;
  399. if ( _tcsicmp( pThisAttribute->pszAttrName,
  400. TEXT("Object Class")) == 0 ) {
  401. _tcscpy( szADsClassName,
  402. (LPTSTR)pThisAttribute->pADsValues->CaseIgnoreString);
  403. break;
  404. }
  405. }
  406. //
  407. // If the object is a user object, we set the initial password to NULL.
  408. //
  409. if (_wcsicmp(szADsClassName, L"user") == 0) {
  410. hr = ADsNdsGenObjectKey(_hADsContext,
  411. pszNDSDn);
  412. BAIL_ON_FAILURE(hr);
  413. }
  414. hr = CNDSGenObject::CreateGenericObject(
  415. _ADsPath,
  416. pszRDNName,
  417. szADsClassName,
  418. _Credentials,
  419. ADS_OBJECT_BOUND,
  420. IID_IADs,
  421. (void **)&pADs
  422. );
  423. BAIL_ON_FAILURE(hr);
  424. hr = InstantiateDerivedObject(
  425. pADs,
  426. _Credentials,
  427. IID_IDispatch,
  428. (void **)ppObject
  429. );
  430. if (FAILED(hr)) {
  431. hr = pADs->QueryInterface(
  432. IID_IDispatch,
  433. (void **)ppObject
  434. );
  435. BAIL_ON_FAILURE(hr);
  436. }
  437. error:
  438. if (pADs) {
  439. pADs->Release();
  440. }
  441. if (pNdsDestObjects) {
  442. NdsTypeFreeNdsObjects(
  443. pNdsDestObjects,
  444. dwNumNdsValues
  445. );
  446. }
  447. if (pszNDSTreeName) {
  448. FreeADsStr(pszNDSTreeName);
  449. }
  450. if (pszNDSDn) {
  451. FreeADsStr(pszNDSDn);
  452. }
  453. if (bstrChildPath) {
  454. SysFreeString(bstrChildPath);
  455. }
  456. if (hOperationData) {
  457. ADsNdsFreeBuffer(hOperationData);
  458. }
  459. RRETURN(hr);
  460. }
  461. HRESULT
  462. CNDSGenObject::DeleteDSObject(
  463. LPWSTR pszRDNName
  464. )
  465. {
  466. WCHAR *pszNDSTreeName = NULL, *pszNDSDn = NULL ;
  467. HRESULT hr = S_OK;
  468. DWORD dwStatus = 0;
  469. BSTR bstrChildPath = NULL;
  470. hr = BuildADsPath(
  471. _ADsPath,
  472. pszRDNName,
  473. &bstrChildPath
  474. );
  475. BAIL_ON_FAILURE(hr);
  476. hr = BuildNDSPathFromADsPath2(
  477. bstrChildPath,
  478. &pszNDSTreeName,
  479. &pszNDSDn
  480. );
  481. BAIL_ON_FAILURE(hr);
  482. hr = ADsNdsRemoveObject(
  483. _hADsContext,
  484. pszNDSDn
  485. );
  486. BAIL_ON_FAILURE(hr);
  487. error:
  488. if (bstrChildPath) {
  489. SysFreeString(bstrChildPath);
  490. }
  491. if (pszNDSTreeName) {
  492. FreeADsStr(pszNDSTreeName);
  493. }
  494. if (pszNDSDn) {
  495. FreeADsStr(pszNDSDn);
  496. }
  497. RRETURN(hr);
  498. }
  499. HRESULT
  500. ComputeAttributeBufferSize(
  501. PADS_ATTR_INFO pAdsAttributes,
  502. DWORD dwNumAttributes,
  503. PDWORD pdwSize
  504. )
  505. {
  506. DWORD i = 0;
  507. DWORD j = 0;
  508. PADS_ATTR_INFO pThisAttribute = NULL;
  509. PADSVALUE pAdsSrcValues = NULL;
  510. DWORD dwSize = 0;
  511. DWORD dwVarSz = 0;
  512. DWORD dwNumValues = 0;
  513. HRESULT hr = S_OK;
  514. for (i = 0; i < dwNumAttributes; i++) {
  515. pThisAttribute = pAdsAttributes + i;
  516. dwNumValues = pThisAttribute->dwNumValues;
  517. pAdsSrcValues = pThisAttribute->pADsValues;
  518. for (j = 0; j < dwNumValues; j++) {
  519. dwVarSz = AdsTypeSize(pAdsSrcValues + j);
  520. dwSize += dwVarSz;
  521. dwSize += sizeof(ADSVALUE);
  522. }
  523. dwSize += sizeof(ADS_ATTR_INFO);
  524. dwSize += (wcslen(pThisAttribute->pszAttrName) + 1)*sizeof(WCHAR);
  525. }
  526. *pdwSize = dwSize;
  527. RRETURN(S_OK);
  528. }
  529. HRESULT
  530. ComputeNumberofValues(
  531. PADS_ATTR_INFO pAdsAttributes,
  532. DWORD dwNumAttributes,
  533. PDWORD pdwNumValues
  534. )
  535. {
  536. DWORD i = 0;
  537. PADS_ATTR_INFO pThisAttribute = NULL;
  538. DWORD dwNumValues = 0;
  539. DWORD dwTotalNumValues = 0;
  540. for (i = 0; i < dwNumAttributes; i++) {
  541. pThisAttribute = pAdsAttributes + i;
  542. dwNumValues = pThisAttribute->dwNumValues;
  543. dwTotalNumValues += dwNumValues;
  544. }
  545. *pdwNumValues = dwTotalNumValues;
  546. RRETURN(S_OK);
  547. }
  548. DWORD
  549. ComputeObjectInfoSize(
  550. PADS_OBJECT_INFO pObjectInfo
  551. )
  552. {
  553. DWORD dwLen = 0;
  554. dwLen += (wcslen(pObjectInfo->pszRDN) + 1) * sizeof(WCHAR);
  555. dwLen += (wcslen(pObjectInfo->pszObjectDN) + 1) * sizeof(WCHAR);
  556. dwLen += (wcslen(pObjectInfo->pszParentDN) + 1) * sizeof(WCHAR);
  557. dwLen += (wcslen(pObjectInfo->pszSchemaDN) + 1) * sizeof(WCHAR);
  558. dwLen += (wcslen(pObjectInfo->pszClassName) + 1) * sizeof(WCHAR);
  559. dwLen += sizeof(ADS_OBJECT_INFO);
  560. return(dwLen);
  561. }
  562. LPBYTE
  563. PackStrings(
  564. LPWSTR *pSource,
  565. LPBYTE pDest,
  566. DWORD *DestOffsets,
  567. LPBYTE pEnd
  568. );
  569. //
  570. // This assumes that addr is an LPBYTE type.
  571. //
  572. #define WORD_ALIGN_DOWN(addr) \
  573. addr = ((LPBYTE)((DWORD)addr & ~1))
  574. DWORD ObjectInfoStrings[] =
  575. {
  576. FIELD_OFFSET(ADS_OBJECT_INFO, pszRDN),
  577. FIELD_OFFSET(ADS_OBJECT_INFO, pszObjectDN),
  578. FIELD_OFFSET(ADS_OBJECT_INFO, pszParentDN),
  579. FIELD_OFFSET(ADS_OBJECT_INFO, pszSchemaDN),
  580. FIELD_OFFSET(ADS_OBJECT_INFO, pszClassName),
  581. 0xFFFFFFFF
  582. };
  583. HRESULT
  584. MarshallObjectInfo(
  585. PADS_OBJECT_INFO pSrcObjectInfo,
  586. LPBYTE pDestObjectInfo,
  587. LPBYTE pEnd
  588. )
  589. {
  590. LPWSTR SourceStrings[sizeof(ADS_OBJECT_INFO)/sizeof(LPWSTR)];
  591. LPWSTR *pSourceStrings=SourceStrings;
  592. memset(SourceStrings, 0, sizeof(ADS_OBJECT_INFO));
  593. *pSourceStrings++ = pSrcObjectInfo->pszRDN;
  594. *pSourceStrings++ = pSrcObjectInfo->pszObjectDN;
  595. *pSourceStrings++ = pSrcObjectInfo->pszParentDN;
  596. *pSourceStrings++ = pSrcObjectInfo->pszSchemaDN;
  597. *pSourceStrings++ = pSrcObjectInfo->pszClassName;
  598. pEnd = PackStrings(
  599. SourceStrings,
  600. pDestObjectInfo,
  601. ObjectInfoStrings,
  602. pEnd
  603. );
  604. RRETURN(S_OK);
  605. }
  606. HRESULT
  607. CNDSGenObject::GetObjectInformation(
  608. THIS_ PADS_OBJECT_INFO * ppObjInfo
  609. )
  610. {
  611. ADS_OBJECT_INFO ObjectInfo;
  612. PADS_OBJECT_INFO pObjectInfo = &ObjectInfo;
  613. LPBYTE pBuffer = NULL;
  614. DWORD dwSize = 0;
  615. HRESULT hr = S_OK;
  616. pObjectInfo->pszRDN = _Name;
  617. pObjectInfo->pszObjectDN = _ADsPath;
  618. pObjectInfo->pszParentDN = _Parent;
  619. pObjectInfo->pszSchemaDN = _Schema;
  620. pObjectInfo->pszClassName = _ADsClass;
  621. dwSize = ComputeObjectInfoSize(pObjectInfo);
  622. pBuffer = (LPBYTE)AllocADsMem(dwSize);
  623. if (!pBuffer) {
  624. hr = E_OUTOFMEMORY;
  625. BAIL_ON_FAILURE(hr);
  626. }
  627. hr = MarshallObjectInfo(
  628. pObjectInfo,
  629. pBuffer,
  630. pBuffer + dwSize
  631. );
  632. BAIL_ON_FAILURE(hr);
  633. *ppObjInfo = (PADS_OBJECT_INFO)pBuffer;
  634. error:
  635. RRETURN(hr);
  636. }
  637. LPBYTE
  638. PackStrings(
  639. LPWSTR *pSource,
  640. LPBYTE pDest,
  641. DWORD *DestOffsets,
  642. LPBYTE pEnd
  643. )
  644. {
  645. DWORD cbStr;
  646. WORD_ALIGN_DOWN(pEnd);
  647. while (*DestOffsets != -1) {
  648. if (*pSource) {
  649. cbStr = wcslen(*pSource)*sizeof(WCHAR) + sizeof(WCHAR);
  650. pEnd -= cbStr;
  651. CopyMemory( pEnd, *pSource, cbStr);
  652. *(LPWSTR *)(pDest+*DestOffsets) = (LPWSTR)pEnd;
  653. } else {
  654. *(LPWSTR *)(pDest+*DestOffsets)=0;
  655. }
  656. pSource++;
  657. DestOffsets++;
  658. }
  659. return pEnd;
  660. }
  661. LPBYTE
  662. AdsCopyAttributeName(
  663. PADS_ATTR_INFO pThisAdsSrcAttribute,
  664. PADS_ATTR_INFO pThisAdsTargAttribute,
  665. LPBYTE pDataBuffer
  666. )
  667. {
  668. LPWSTR pCurrentPos = (LPWSTR)pDataBuffer;
  669. wcscpy(pCurrentPos, pThisAdsSrcAttribute->pszAttrName);
  670. pThisAdsTargAttribute->pszAttrName = pCurrentPos;
  671. pDataBuffer = pDataBuffer + (wcslen(pThisAdsSrcAttribute->pszAttrName) + 1)*sizeof(WCHAR);
  672. return(pDataBuffer);
  673. }