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.

1106 lines
30 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. BYTE lpBuffer[2048];
  26. WCHAR *pszNDSPathName = NULL ;
  27. HANDLE hObject = NULL;
  28. HANDLE hOperationData = NULL;
  29. DWORD i = 0;
  30. PADS_ATTR_INFO pThisAttribute = NULL;
  31. DWORD dwStatus = 0;
  32. PNDSOBJECT pNdsDestObjects = NULL;
  33. DWORD dwNumNdsValues = 0;
  34. DWORD dwSyntaxId = 0;
  35. DWORD dwNumNDSAttributeReturn = 0;
  36. *pdwNumAttributesModified = 0;
  37. if (dwNumAttributes <= 0) {
  38. RRETURN(E_FAIL);
  39. }
  40. hr = BuildNDSPathFromADsPath(
  41. _ADsPath,
  42. &pszNDSPathName
  43. );
  44. BAIL_ON_FAILURE(hr);
  45. dwStatus = ADsNwNdsOpenObject(
  46. pszNDSPathName,
  47. _Credentials,
  48. &hObject,
  49. NULL,
  50. NULL,
  51. NULL,
  52. NULL
  53. );
  54. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  55. dwStatus = NwNdsCreateBuffer(
  56. NDS_OBJECT_MODIFY,
  57. &hOperationData
  58. );
  59. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  60. for (i = 0; i < dwNumAttributes; i++) {
  61. pThisAttribute = pAttributeEntries + i;
  62. switch (pThisAttribute->dwControlCode) {
  63. case ADS_ATTR_UPDATE:
  64. hr = AdsTypeToNdsTypeCopyConstruct(
  65. pThisAttribute->pADsValues,
  66. pThisAttribute->dwNumValues,
  67. &pNdsDestObjects,
  68. &dwNumNdsValues,
  69. &dwSyntaxId
  70. );
  71. CONTINUE_ON_FAILURE(hr);
  72. hr = MarshallNDSSynIdToNDS(
  73. dwSyntaxId,
  74. pNdsDestObjects,
  75. dwNumNdsValues,
  76. lpBuffer
  77. );
  78. dwStatus = NwNdsPutInBuffer(
  79. pThisAttribute->pszAttrName,
  80. dwSyntaxId,
  81. NULL,
  82. 0,
  83. NDS_ATTR_CLEAR,
  84. hOperationData
  85. );
  86. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  87. dwStatus = NwNdsPutInBuffer(
  88. pThisAttribute->pszAttrName,
  89. dwSyntaxId,
  90. lpBuffer,
  91. dwNumNdsValues,
  92. NDS_ATTR_ADD,
  93. hOperationData
  94. );
  95. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  96. dwNumNDSAttributeReturn++;
  97. break;
  98. case ADS_ATTR_APPEND:
  99. hr = AdsTypeToNdsTypeCopyConstruct(
  100. pThisAttribute->pADsValues,
  101. pThisAttribute->dwNumValues,
  102. &pNdsDestObjects,
  103. &dwNumNdsValues,
  104. &dwSyntaxId
  105. );
  106. CONTINUE_ON_FAILURE(hr);
  107. hr = MarshallNDSSynIdToNDS(
  108. dwSyntaxId,
  109. pNdsDestObjects,
  110. dwNumNdsValues,
  111. lpBuffer
  112. );
  113. dwStatus = NwNdsPutInBuffer(
  114. pThisAttribute->pszAttrName,
  115. dwSyntaxId,
  116. lpBuffer,
  117. dwNumNdsValues,
  118. NDS_ATTR_ADD_VALUE,
  119. hOperationData
  120. );
  121. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  122. dwNumNDSAttributeReturn++;
  123. break;
  124. case ADS_ATTR_DELETE:
  125. hr = AdsTypeToNdsTypeCopyConstruct(
  126. pThisAttribute->pADsValues,
  127. pThisAttribute->dwNumValues,
  128. &pNdsDestObjects,
  129. &dwNumNdsValues,
  130. &dwSyntaxId
  131. );
  132. CONTINUE_ON_FAILURE(hr);
  133. hr = MarshallNDSSynIdToNDS(
  134. dwSyntaxId,
  135. pNdsDestObjects,
  136. dwNumNdsValues,
  137. lpBuffer
  138. );
  139. dwStatus = NwNdsPutInBuffer(
  140. pThisAttribute->pszAttrName,
  141. dwSyntaxId,
  142. lpBuffer,
  143. dwNumNdsValues,
  144. NDS_ATTR_REMOVE_VALUE,
  145. hOperationData
  146. );
  147. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  148. dwNumNDSAttributeReturn++;
  149. break;
  150. case ADS_ATTR_CLEAR:
  151. dwStatus = NwNdsPutInBuffer(
  152. pThisAttribute->pszAttrName,
  153. dwSyntaxId,
  154. NULL,
  155. 0,
  156. NDS_ATTR_CLEAR,
  157. hOperationData
  158. );
  159. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  160. dwNumNDSAttributeReturn++;
  161. break;
  162. default:
  163. //
  164. // Ignore this attribute and move on.
  165. //
  166. break;
  167. }
  168. if (pNdsDestObjects) {
  169. FreeMarshallMemory(
  170. dwSyntaxId,
  171. dwNumNdsValues,
  172. lpBuffer
  173. );
  174. NdsTypeFreeNdsObjects(
  175. pNdsDestObjects,
  176. dwNumNdsValues
  177. );
  178. pNdsDestObjects = NULL;
  179. }
  180. }
  181. dwStatus = NwNdsModifyObject(
  182. hObject,
  183. hOperationData
  184. );
  185. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  186. *pdwNumAttributesModified = dwNumNDSAttributeReturn;
  187. error:
  188. if (pNdsDestObjects) {
  189. FreeMarshallMemory(
  190. dwSyntaxId,
  191. dwNumNdsValues,
  192. lpBuffer
  193. );
  194. NdsTypeFreeNdsObjects(
  195. pNdsDestObjects,
  196. dwNumNdsValues
  197. );
  198. }
  199. if (hOperationData) {
  200. dwStatus = NwNdsFreeBuffer(hOperationData);
  201. }
  202. if (hObject) {
  203. dwStatus = NwNdsCloseObject(hObject);
  204. }
  205. if (pszNDSPathName) {
  206. (void) FreeADsStr(pszNDSPathName) ;
  207. }
  208. RRETURN(hr);
  209. }
  210. HRESULT
  211. CNDSGenObject::GetObjectAttributes(
  212. LPWSTR * pAttributeNames,
  213. DWORD dwNumberAttributes,
  214. PADS_ATTR_INFO *ppAttributeEntries,
  215. DWORD * pdwNumAttributesReturned
  216. )
  217. {
  218. HRESULT hr = S_OK;
  219. BYTE lpBuffer[2048];
  220. WCHAR *pszNDSPathName = NULL ;
  221. DWORD i = 0;
  222. HANDLE hOperationData = NULL;
  223. PNDSOBJECT pNdsDestObjects = NULL;
  224. DWORD dwNdsSyntaxId = 0;
  225. DWORD dwNumValues = 0;
  226. DWORD dwStatus = 0;
  227. HANDLE hObject = NULL;
  228. LPWSTR * pThisAttributeName = NULL;
  229. PADS_ATTR_INFO pAdsAttributes = NULL;
  230. PADS_ATTR_INFO pThisAttributeDef = NULL;
  231. DWORD dwAttrCount = 0;
  232. DWORD dwNumberOfEntries = 0;
  233. LPNDS_ATTR_INFO lpEntries = NULL;
  234. PNDSOBJECT pNdsObject = NULL;
  235. PADSVALUE pAdsDestValues = NULL;
  236. DWORD j = 0;
  237. PADS_ATTR_INFO pThisAdsSrcAttribute = NULL;
  238. PADS_ATTR_INFO pThisAdsTargAttribute = NULL;
  239. PADS_ATTR_INFO pAttrEntry = NULL;
  240. PADSVALUE pAttrValue = NULL;
  241. DWORD dwMemSize = 0;
  242. LPBYTE pAttributeBuffer = NULL;
  243. LPBYTE pValueBuffer = NULL;
  244. LPBYTE pDataBuffer = NULL;
  245. PADSVALUE pThisAdsSrcValue = NULL;
  246. PADSVALUE pThisAdsTargValue = NULL;
  247. DWORD dwTotalValues = 0;
  248. hr = BuildNDSPathFromADsPath(
  249. _ADsPath,
  250. &pszNDSPathName
  251. );
  252. BAIL_ON_FAILURE(hr);
  253. dwStatus = ADsNwNdsOpenObject(
  254. pszNDSPathName,
  255. _Credentials,
  256. &hObject,
  257. NULL,
  258. NULL,
  259. NULL,
  260. NULL
  261. );
  262. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  263. if (dwNumberAttributes != (DWORD)-1) {
  264. //
  265. // Package attributes into NDS structure
  266. //
  267. dwStatus = NwNdsCreateBuffer(
  268. NDS_OBJECT_READ,
  269. &hOperationData
  270. );
  271. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  272. for (i = 0; i < dwNumberAttributes; i++) {
  273. pThisAttributeName = pAttributeNames + i;
  274. dwStatus = NwNdsPutInBuffer(
  275. *pThisAttributeName,
  276. NULL,
  277. NULL,
  278. 0,
  279. 0,
  280. hOperationData
  281. );
  282. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  283. }
  284. }else {
  285. //
  286. // Tell the server to give us back whatever it has
  287. //
  288. hOperationData = NULL;
  289. }
  290. //
  291. // Read the DS Object
  292. //
  293. dwStatus = NwNdsReadObject(
  294. hObject,
  295. 1,
  296. &hOperationData
  297. );
  298. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  299. //
  300. // Compute the number of attributes in the
  301. // read buffer.
  302. //
  303. dwStatus = NwNdsGetAttrListFromBuffer(
  304. hOperationData,
  305. &dwNumberOfEntries,
  306. &lpEntries
  307. );
  308. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  309. //
  310. // Allocate an attribute buffer which is as large as the
  311. // number of attributes present
  312. //
  313. //
  314. pAdsAttributes = (PADS_ATTR_INFO)AllocADsMem(
  315. sizeof(ADS_ATTR_INFO)*dwNumberOfEntries
  316. );
  317. if (!pAdsAttributes){
  318. hr = E_OUTOFMEMORY;
  319. BAIL_ON_FAILURE(hr);
  320. }
  321. for (i = 0; i < dwNumberOfEntries; i++) {
  322. pThisAttributeDef = pAdsAttributes + dwAttrCount;
  323. hr = UnMarshallNDSToNDSSynId(
  324. lpEntries[i].dwSyntaxId,
  325. lpEntries[i].dwNumberOfValues,
  326. lpEntries[i].lpValue,
  327. &pNdsObject
  328. );
  329. CONTINUE_ON_FAILURE(hr);
  330. dwNumValues = lpEntries[i].dwNumberOfValues;
  331. hr = NdsTypeToAdsTypeCopyConstruct(
  332. pNdsObject,
  333. dwNumValues,
  334. &pAdsDestValues
  335. );
  336. if (FAILED(hr)){
  337. if (pNdsObject) {
  338. NdsTypeFreeNdsObjects(pNdsObject, dwNumValues);
  339. }
  340. continue;
  341. }
  342. pThisAttributeDef->pszAttrName =
  343. AllocADsStr(lpEntries[i].szAttributeName);
  344. pThisAttributeDef->pADsValues = pAdsDestValues;
  345. pThisAttributeDef->dwNumValues = dwNumValues;
  346. pThisAttributeDef->dwADsType = g_MapNdsTypeToADsType[lpEntries[i].dwSyntaxId];
  347. if (pNdsObject) {
  348. NdsTypeFreeNdsObjects(pNdsObject, dwNumValues);
  349. }
  350. dwAttrCount++;
  351. }
  352. //
  353. // Now package this data into a single contiguous buffer
  354. //
  355. hr = ComputeAttributeBufferSize(
  356. pAdsAttributes,
  357. dwAttrCount,
  358. &dwMemSize
  359. );
  360. BAIL_ON_FAILURE(hr);
  361. hr = ComputeNumberofValues(
  362. pAdsAttributes,
  363. dwAttrCount,
  364. &dwTotalValues
  365. );
  366. BAIL_ON_FAILURE(hr);
  367. pAttributeBuffer = (LPBYTE)AllocADsMem(dwMemSize);
  368. if (!pAttributeBuffer) {
  369. hr = E_OUTOFMEMORY;
  370. BAIL_ON_FAILURE(hr);
  371. }
  372. pValueBuffer = pAttributeBuffer + dwAttrCount * (sizeof(ADS_ATTR_INFO));
  373. pDataBuffer = pValueBuffer + dwTotalValues * sizeof(ADSVALUE);
  374. pAttrEntry = (PADS_ATTR_INFO)pAttributeBuffer;
  375. pAttrValue = (PADSVALUE)pValueBuffer;
  376. for (i = 0; i < dwAttrCount; i++) {
  377. pThisAdsSrcAttribute = pAdsAttributes + i;
  378. pThisAdsTargAttribute = pAttrEntry + i;
  379. pThisAdsTargAttribute->pADsValues = pAttrValue;
  380. pThisAdsTargAttribute->dwNumValues = pThisAdsSrcAttribute->dwNumValues;
  381. pThisAdsTargAttribute->dwADsType = pThisAdsSrcAttribute->dwADsType;
  382. dwNumValues = pThisAdsSrcAttribute->dwNumValues;
  383. pThisAdsSrcValue = pThisAdsSrcAttribute->pADsValues;
  384. pThisAdsTargValue = pAttrValue;
  385. for (j = 0; j < dwNumValues; j++) {
  386. pDataBuffer = AdsTypeCopy(
  387. pThisAdsSrcValue,
  388. pThisAdsTargValue,
  389. pDataBuffer
  390. );
  391. pAttrValue++;
  392. pThisAdsTargValue = pAttrValue;
  393. pThisAdsSrcValue++;
  394. }
  395. pDataBuffer = AdsCopyAttributeName(
  396. pThisAdsSrcAttribute,
  397. pThisAdsTargAttribute,
  398. pDataBuffer
  399. );
  400. }
  401. hr = S_OK;
  402. cleanup:
  403. //
  404. // Clean up the header based Ods structures
  405. //
  406. if (pAdsDestValues) {
  407. }
  408. if (hOperationData) {
  409. dwStatus = NwNdsFreeBuffer(hOperationData);
  410. }
  411. if (hObject) {
  412. dwStatus = NwNdsCloseObject(hObject);
  413. }
  414. if (pszNDSPathName) {
  415. (void) FreeADsStr(pszNDSPathName) ;
  416. }
  417. if (pAdsAttributes) {
  418. DWORD dwAttr = 0;
  419. for (i = 0; i < dwNumberOfEntries; i++) {
  420. pThisAttributeDef = pAdsAttributes + dwAttr;
  421. if (pThisAttributeDef->pszAttrName) {
  422. FreeADsMem(pThisAttributeDef->pszAttrName);
  423. }
  424. if (pThisAttributeDef->pADsValues) {
  425. AdsFreeAdsValues(
  426. pThisAttributeDef->pADsValues,
  427. pThisAttributeDef->dwNumValues
  428. );
  429. FreeADsMem(pThisAttributeDef->pADsValues);
  430. }
  431. dwAttr++;
  432. }
  433. FreeADsMem(pAdsAttributes);
  434. }
  435. *ppAttributeEntries = (PADS_ATTR_INFO)pAttributeBuffer;
  436. *pdwNumAttributesReturned = dwAttrCount;
  437. RRETURN(hr);
  438. error:
  439. if (pAttributeBuffer) {
  440. FreeADsMem(pAttributeBuffer);
  441. }
  442. if (pAdsAttributes) {
  443. DWORD dwAttr = 0;
  444. for (i = 0; i < dwNumberOfEntries; i++) {
  445. pThisAttributeDef = pAdsAttributes + dwAttr;
  446. if (pThisAttributeDef->pszAttrName) {
  447. FreeADsMem(pThisAttributeDef->pszAttrName);
  448. }
  449. if (pThisAttributeDef->pADsValues) {
  450. AdsFreeAdsValues(
  451. pThisAttributeDef->pADsValues,
  452. pThisAttributeDef->dwNumValues
  453. );
  454. FreeADsMem(pThisAttributeDef->pADsValues);
  455. }
  456. dwAttr++;
  457. }
  458. FreeADsMem(pAdsAttributes);
  459. }
  460. goto cleanup;
  461. }
  462. HRESULT
  463. CNDSGenObject::CreateDSObject(
  464. LPWSTR pszRDNName,
  465. PADS_ATTR_INFO pAttributeEntries,
  466. DWORD dwNumAttributes,
  467. IDispatch * FAR* ppObject
  468. )
  469. {
  470. HRESULT hr = S_OK;
  471. BYTE lpBuffer[2048];
  472. WCHAR *pszNDSPathName = NULL;
  473. HANDLE hObject = NULL;
  474. HANDLE hOperationData = NULL;
  475. DWORD i = 0;
  476. PADS_ATTR_INFO pThisAttribute = NULL;
  477. DWORD dwStatus = 0;
  478. PNDSOBJECT pNdsDestObjects = NULL;
  479. DWORD dwNumNdsValues = 0;
  480. DWORD dwSyntaxId = 0;
  481. IADs *pADs = NULL;
  482. TCHAR szADsClassName[64];
  483. hr = BuildNDSPathFromADsPath(
  484. _ADsPath,
  485. &pszNDSPathName
  486. );
  487. BAIL_ON_FAILURE(hr);
  488. dwStatus = ADsNwNdsOpenObject(
  489. pszNDSPathName,
  490. _Credentials,
  491. &hObject,
  492. NULL,
  493. NULL,
  494. NULL,
  495. NULL
  496. );
  497. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  498. dwStatus = NwNdsCreateBuffer(
  499. NDS_OBJECT_ADD,
  500. &hOperationData
  501. );
  502. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  503. for (i = 0; i < dwNumAttributes; i++) {
  504. pThisAttribute = pAttributeEntries + i;
  505. hr = AdsTypeToNdsTypeCopyConstruct(
  506. pThisAttribute->pADsValues,
  507. pThisAttribute->dwNumValues,
  508. &pNdsDestObjects,
  509. &dwNumNdsValues,
  510. &dwSyntaxId
  511. );
  512. CONTINUE_ON_FAILURE(hr);
  513. hr = MarshallNDSSynIdToNDS(
  514. dwSyntaxId,
  515. pNdsDestObjects,
  516. dwNumNdsValues,
  517. lpBuffer
  518. );
  519. dwStatus = NwNdsPutInBuffer(
  520. pThisAttribute->pszAttrName,
  521. dwSyntaxId,
  522. NULL,
  523. 0,
  524. NDS_ATTR_CLEAR,
  525. hOperationData
  526. );
  527. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  528. dwStatus = NwNdsPutInBuffer(
  529. pThisAttribute->pszAttrName,
  530. dwSyntaxId,
  531. lpBuffer,
  532. dwNumNdsValues,
  533. NDS_ATTR_ADD,
  534. hOperationData
  535. );
  536. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  537. FreeMarshallMemory(
  538. dwSyntaxId,
  539. dwNumNdsValues,
  540. lpBuffer
  541. );
  542. NdsTypeFreeNdsObjects(
  543. pNdsDestObjects,
  544. dwNumNdsValues
  545. );
  546. pNdsDestObjects = NULL;
  547. }
  548. dwStatus = NwNdsAddObject(
  549. hObject,
  550. pszRDNName,
  551. hOperationData
  552. );
  553. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  554. for (i = 0; i < dwNumAttributes; i++) {
  555. pThisAttribute = pAttributeEntries + i;
  556. if ( _tcsicmp( pThisAttribute->pszAttrName,
  557. TEXT("Object Class")) == 0 ) {
  558. _tcscpy( szADsClassName,
  559. (LPTSTR)pThisAttribute->pADsValues->CaseIgnoreString);
  560. break;
  561. }
  562. }
  563. hr = CNDSGenObject::CreateGenericObject(
  564. _ADsPath,
  565. pszRDNName,
  566. szADsClassName,
  567. _Credentials,
  568. ADS_OBJECT_BOUND,
  569. IID_IADs,
  570. (void **)&pADs
  571. );
  572. BAIL_ON_FAILURE(hr);
  573. hr = InstantiateDerivedObject(
  574. pADs,
  575. _Credentials,
  576. IID_IDispatch,
  577. (void **)ppObject
  578. );
  579. if (FAILED(hr)) {
  580. hr = pADs->QueryInterface(
  581. IID_IDispatch,
  582. (void **)ppObject
  583. );
  584. BAIL_ON_FAILURE(hr);
  585. }
  586. error:
  587. if (pADs) {
  588. pADs->Release();
  589. }
  590. if (pNdsDestObjects) {
  591. FreeMarshallMemory(
  592. dwSyntaxId,
  593. dwNumNdsValues,
  594. lpBuffer
  595. );
  596. NdsTypeFreeNdsObjects(
  597. pNdsDestObjects,
  598. dwNumNdsValues
  599. );
  600. }
  601. if (hOperationData) {
  602. dwStatus = NwNdsFreeBuffer(hOperationData);
  603. }
  604. if (hObject) {
  605. dwStatus = NwNdsCloseObject(hObject);
  606. }
  607. if (pszNDSPathName) {
  608. (void) FreeADsStr(pszNDSPathName) ;
  609. }
  610. RRETURN(hr);
  611. }
  612. HRESULT
  613. CNDSGenObject::DeleteDSObject(
  614. LPWSTR pszRDNName
  615. )
  616. {
  617. WCHAR *pszNDSPathName = NULL ;
  618. HRESULT hr = S_OK;
  619. DWORD dwStatus = 0;
  620. HANDLE hParentObject = NULL;
  621. hr = BuildNDSPathFromADsPath(
  622. _ADsPath,
  623. &pszNDSPathName
  624. );
  625. BAIL_ON_FAILURE(hr);
  626. dwStatus = ADsNwNdsOpenObject(
  627. pszNDSPathName,
  628. _Credentials,
  629. &hParentObject,
  630. NULL,
  631. NULL,
  632. NULL,
  633. NULL
  634. );
  635. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  636. dwStatus = NwNdsRemoveObject(
  637. hParentObject,
  638. pszRDNName
  639. );
  640. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  641. error:
  642. if (hParentObject) {
  643. NwNdsCloseObject(
  644. hParentObject
  645. );
  646. }
  647. if (pszNDSPathName) {
  648. (void) FreeADsStr(pszNDSPathName) ;
  649. }
  650. RRETURN(hr);
  651. }
  652. HRESULT
  653. ComputeAttributeBufferSize(
  654. PADS_ATTR_INFO pAdsAttributes,
  655. DWORD dwNumAttributes,
  656. PDWORD pdwSize
  657. )
  658. {
  659. DWORD i = 0;
  660. DWORD j = 0;
  661. PADS_ATTR_INFO pThisAttribute = NULL;
  662. PADSVALUE pAdsSrcValues = NULL;
  663. DWORD dwSize = 0;
  664. DWORD dwVarSz = 0;
  665. DWORD dwNumValues = 0;
  666. HRESULT hr = S_OK;
  667. for (i = 0; i < dwNumAttributes; i++) {
  668. pThisAttribute = pAdsAttributes + i;
  669. dwNumValues = pThisAttribute->dwNumValues;
  670. pAdsSrcValues = pThisAttribute->pADsValues;
  671. for (j = 0; j < dwNumValues; j++) {
  672. dwVarSz = AdsTypeSize(pAdsSrcValues + j);
  673. dwSize += dwVarSz;
  674. dwSize += sizeof(ADSVALUE);
  675. }
  676. dwSize += sizeof(ADS_ATTR_INFO);
  677. dwSize += (wcslen(pThisAttribute->pszAttrName) + 1)*sizeof(WCHAR);
  678. }
  679. *pdwSize = dwSize;
  680. RRETURN(S_OK);
  681. }
  682. HRESULT
  683. ComputeNumberofValues(
  684. PADS_ATTR_INFO pAdsAttributes,
  685. DWORD dwNumAttributes,
  686. PDWORD pdwNumValues
  687. )
  688. {
  689. DWORD i = 0;
  690. PADS_ATTR_INFO pThisAttribute = NULL;
  691. DWORD dwNumValues = 0;
  692. DWORD dwTotalNumValues = 0;
  693. for (i = 0; i < dwNumAttributes; i++) {
  694. pThisAttribute = pAdsAttributes + i;
  695. dwNumValues = pThisAttribute->dwNumValues;
  696. dwTotalNumValues += dwNumValues;
  697. }
  698. *pdwNumValues = dwTotalNumValues;
  699. RRETURN(S_OK);
  700. }
  701. DWORD
  702. ComputeObjectInfoSize(
  703. PADS_OBJECT_INFO pObjectInfo
  704. )
  705. {
  706. DWORD dwLen = 0;
  707. dwLen += (wcslen(pObjectInfo->pszRDN) + 1) * sizeof(WCHAR);
  708. dwLen += (wcslen(pObjectInfo->pszObjectDN) + 1) * sizeof(WCHAR);
  709. dwLen += (wcslen(pObjectInfo->pszParentDN) + 1) * sizeof(WCHAR);
  710. dwLen += (wcslen(pObjectInfo->pszSchemaDN) + 1) * sizeof(WCHAR);
  711. dwLen += (wcslen(pObjectInfo->pszClassName) + 1) * sizeof(WCHAR);
  712. dwLen += sizeof(ADS_OBJECT_INFO);
  713. return(dwLen);
  714. }
  715. LPBYTE
  716. PackStrings(
  717. LPWSTR *pSource,
  718. LPBYTE pDest,
  719. DWORD *DestOffsets,
  720. LPBYTE pEnd
  721. );
  722. //
  723. // This assumes that addr is an LPBYTE type.
  724. //
  725. #define WORD_ALIGN_DOWN(addr) \
  726. addr = ((LPBYTE)((UINT_PTR)addr & ~1))
  727. DWORD ObjectInfoStrings[] =
  728. {
  729. FIELD_OFFSET(ADS_OBJECT_INFO, pszRDN),
  730. FIELD_OFFSET(ADS_OBJECT_INFO, pszObjectDN),
  731. FIELD_OFFSET(ADS_OBJECT_INFO, pszParentDN),
  732. FIELD_OFFSET(ADS_OBJECT_INFO, pszSchemaDN),
  733. FIELD_OFFSET(ADS_OBJECT_INFO, pszClassName),
  734. 0xFFFFFFFF
  735. };
  736. HRESULT
  737. MarshallObjectInfo(
  738. PADS_OBJECT_INFO pSrcObjectInfo,
  739. LPBYTE pDestObjectInfo,
  740. LPBYTE pEnd
  741. )
  742. {
  743. LPWSTR SourceStrings[sizeof(ADS_OBJECT_INFO)/sizeof(LPWSTR)];
  744. LPWSTR *pSourceStrings=SourceStrings;
  745. memset(SourceStrings, 0, sizeof(ADS_OBJECT_INFO));
  746. *pSourceStrings++ = pSrcObjectInfo->pszRDN;
  747. *pSourceStrings++ = pSrcObjectInfo->pszObjectDN;
  748. *pSourceStrings++ = pSrcObjectInfo->pszParentDN;
  749. *pSourceStrings++ = pSrcObjectInfo->pszSchemaDN;
  750. *pSourceStrings++ = pSrcObjectInfo->pszClassName;
  751. pEnd = PackStrings(
  752. SourceStrings,
  753. pDestObjectInfo,
  754. ObjectInfoStrings,
  755. pEnd
  756. );
  757. RRETURN(S_OK);
  758. }
  759. HRESULT
  760. CNDSGenObject::GetObjectInformation(
  761. THIS_ PADS_OBJECT_INFO * ppObjInfo
  762. )
  763. {
  764. ADS_OBJECT_INFO ObjectInfo;
  765. PADS_OBJECT_INFO pObjectInfo = &ObjectInfo;
  766. LPBYTE pBuffer = NULL;
  767. DWORD dwSize = 0;
  768. HRESULT hr = S_OK;
  769. pObjectInfo->pszRDN = _Name;
  770. pObjectInfo->pszObjectDN = _ADsPath;
  771. pObjectInfo->pszParentDN = _Parent;
  772. pObjectInfo->pszSchemaDN = _Schema;
  773. pObjectInfo->pszClassName = _ADsClass;
  774. dwSize = ComputeObjectInfoSize(pObjectInfo);
  775. pBuffer = (LPBYTE)AllocADsMem(dwSize);
  776. if (!pBuffer) {
  777. hr = E_OUTOFMEMORY;
  778. BAIL_ON_FAILURE(hr);
  779. }
  780. hr = MarshallObjectInfo(
  781. pObjectInfo,
  782. pBuffer,
  783. pBuffer + dwSize
  784. );
  785. BAIL_ON_FAILURE(hr);
  786. *ppObjInfo = (PADS_OBJECT_INFO)pBuffer;
  787. error:
  788. RRETURN(hr);
  789. }
  790. LPBYTE
  791. PackStrings(
  792. LPWSTR *pSource,
  793. LPBYTE pDest,
  794. DWORD *DestOffsets,
  795. LPBYTE pEnd
  796. )
  797. {
  798. DWORD cbStr;
  799. WORD_ALIGN_DOWN(pEnd);
  800. while (*DestOffsets != -1) {
  801. if (*pSource) {
  802. cbStr = wcslen(*pSource)*sizeof(WCHAR) + sizeof(WCHAR);
  803. pEnd -= cbStr;
  804. CopyMemory( pEnd, *pSource, cbStr);
  805. *(LPWSTR *)(pDest+*DestOffsets) = (LPWSTR)pEnd;
  806. } else {
  807. *(LPWSTR *)(pDest+*DestOffsets)=0;
  808. }
  809. pSource++;
  810. DestOffsets++;
  811. }
  812. return pEnd;
  813. }
  814. LPBYTE
  815. AdsCopyAttributeName(
  816. PADS_ATTR_INFO pThisAdsSrcAttribute,
  817. PADS_ATTR_INFO pThisAdsTargAttribute,
  818. LPBYTE pDataBuffer
  819. )
  820. {
  821. LPWSTR pCurrentPos = (LPWSTR)pDataBuffer;
  822. wcscpy(pCurrentPos, pThisAdsSrcAttribute->pszAttrName);
  823. pThisAdsTargAttribute->pszAttrName = pCurrentPos;
  824. pDataBuffer = pDataBuffer + (wcslen(pThisAdsSrcAttribute->pszAttrName) + 1)*sizeof(WCHAR);
  825. return(pDataBuffer);
  826. }