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.

1228 lines
30 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cNameTranslate.cxx
  7. //
  8. // Contents: NameTranslate object
  9. //
  10. // History: 11-1-95 krishnag Created.
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "ldap.hxx"
  14. #pragma hdrstop
  15. #define ABORT_ON_ERROR(err) \
  16. if ( 0 != (err) ) \
  17. { \
  18. hr = E_FAIL; \
  19. goto error; \
  20. }
  21. // Class CNameTranslate
  22. DEFINE_IDispatch_Implementation(CNameTranslate)
  23. //+---------------------------------------------------------------------------
  24. // Function: CNameTranslate::CNameTranslate
  25. //
  26. // Synopsis: Constructor
  27. //
  28. // Arguments:
  29. //
  30. // Returns: HRESULT
  31. //
  32. // Modifies: -
  33. //
  34. // History: 15-7-97 FelixW Created.
  35. //
  36. //----------------------------------------------------------------------------
  37. CNameTranslate::CNameTranslate():
  38. _pDispMgr(NULL)
  39. {
  40. ENLIST_TRACKING(CNameTranslate);
  41. _hDS = NULL;
  42. _rgszGuid = NULL;
  43. _rgDomainHandle = NULL;
  44. _cGuid = 0;
  45. _bChaseReferral = TRUE;
  46. _bAuthSet = FALSE;
  47. _pDomainHandle = new CDomainToHandle;
  48. }
  49. //+---------------------------------------------------------------------------
  50. // Function: CNameTranslate::CreateNameTranslate
  51. //
  52. // Synopsis:
  53. //
  54. // Arguments:
  55. //
  56. // Returns: HRESULT
  57. //
  58. // Modifies: -
  59. //
  60. // History: 15-7-97 FelixW Created.
  61. //
  62. //----------------------------------------------------------------------------
  63. HRESULT
  64. CNameTranslate::CreateNameTranslate(
  65. REFIID riid,
  66. void **ppvObj
  67. )
  68. {
  69. CNameTranslate FAR * pNameTranslate = NULL;
  70. HRESULT hr = S_OK;
  71. hr = AllocateNameTranslateObject(&pNameTranslate);
  72. BAIL_ON_FAILURE(hr);
  73. hr = pNameTranslate->QueryInterface(riid, ppvObj);
  74. BAIL_ON_FAILURE(hr);
  75. pNameTranslate->Release();
  76. RRETURN(hr);
  77. error:
  78. delete pNameTranslate;
  79. RRETURN(hr);
  80. }
  81. //+---------------------------------------------------------------------------
  82. // Function: CNameTranslate::~CNameTranslate
  83. //
  84. // Synopsis:
  85. //
  86. // Arguments:
  87. //
  88. // Returns: HRESULT
  89. //
  90. // Modifies: -
  91. //
  92. // History: 15-7-97 FelixW Created.
  93. //
  94. //----------------------------------------------------------------------------
  95. CNameTranslate::~CNameTranslate( )
  96. {
  97. DWORD i;
  98. if (_hDS) {
  99. DsUnBindWrapper(&_hDS);
  100. _hDS = NULL;
  101. }
  102. delete _pDispMgr;
  103. if (_rgszGuid) {
  104. for (i=0;i<_cGuid;i++) {
  105. FreeADsMem(_rgszGuid[i]);
  106. }
  107. FreeADsMem(_rgszGuid);
  108. }
  109. if (_rgDomainHandle) {
  110. FreeADsMem(_rgDomainHandle);
  111. }
  112. if (_bAuthSet) {
  113. DsFreePasswordCredentialsWrapper(_AuthIdentity);
  114. _bAuthSet = FALSE;
  115. }
  116. if (_pDomainHandle) {
  117. delete _pDomainHandle;
  118. }
  119. }
  120. //+---------------------------------------------------------------------------
  121. // Function: CNameTranslate::QueryInterface
  122. //
  123. // Synopsis:
  124. //
  125. // Arguments:
  126. //
  127. // Returns: HRESULT
  128. //
  129. // Modifies: -
  130. //
  131. // History: 15-7-97 FelixW Created.
  132. //
  133. //----------------------------------------------------------------------------
  134. STDMETHODIMP
  135. CNameTranslate::QueryInterface(
  136. REFIID iid,
  137. LPVOID FAR* ppv
  138. )
  139. {
  140. if (ppv == NULL) {
  141. return E_POINTER;
  142. }
  143. if (IsEqualIID(iid, IID_IUnknown))
  144. {
  145. *ppv = (IADsNameTranslate FAR *) this;
  146. }
  147. else if (IsEqualIID(iid, IID_IADsNameTranslate))
  148. {
  149. *ppv = (IADsNameTranslate FAR *) this;
  150. }
  151. else if (IsEqualIID(iid, IID_IDispatch))
  152. {
  153. *ppv = (IADsNameTranslate FAR *) this;
  154. }
  155. else
  156. {
  157. *ppv = NULL;
  158. return E_NOINTERFACE;
  159. }
  160. AddRef();
  161. return NOERROR;
  162. }
  163. HRESULT MapCrackErrToHR(DWORD dwErr)
  164. {
  165. HRESULT hr = S_OK;
  166. switch (dwErr) {
  167. case DS_NAME_NO_ERROR:
  168. hr = S_OK;
  169. break;
  170. case DS_NAME_ERROR_RESOLVING:
  171. hr = HRESULT_FROM_WIN32(ERROR_DS_NAME_ERROR_RESOLVING);
  172. break;
  173. case DS_NAME_ERROR_NOT_FOUND:
  174. hr = HRESULT_FROM_WIN32(ERROR_DS_NAME_ERROR_NOT_FOUND);
  175. break;
  176. case DS_NAME_ERROR_NOT_UNIQUE:
  177. hr = HRESULT_FROM_WIN32(ERROR_DS_NAME_ERROR_NOT_UNIQUE);
  178. break;
  179. case DS_NAME_ERROR_NO_MAPPING:
  180. hr = HRESULT_FROM_WIN32(ERROR_DS_NAME_ERROR_NO_MAPPING);
  181. break;
  182. case DS_NAME_ERROR_DOMAIN_ONLY:
  183. hr = HRESULT_FROM_WIN32(ERROR_DS_NAME_ERROR_DOMAIN_ONLY);
  184. break;
  185. case DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING:
  186. hr = HRESULT_FROM_WIN32(
  187. ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING
  188. );
  189. break;
  190. case DS_NAME_ERROR_TRUST_REFERRAL:
  191. hr = HRESULT_FROM_WIN32(ERROR_DS_NAME_ERROR_TRUST_REFERRAL);
  192. break;
  193. default:
  194. hr = E_FAIL;
  195. }
  196. return hr;
  197. }
  198. HRESULT MapAdsToCrack(DWORD dwType, DS_NAME_FORMAT *pdwReturn)
  199. {
  200. HRESULT hr = S_OK;
  201. switch (dwType) {
  202. case ADS_NAME_TYPE_1779:
  203. *pdwReturn = DS_FQDN_1779_NAME;
  204. break;
  205. case ADS_NAME_TYPE_CANONICAL:
  206. *pdwReturn = DS_CANONICAL_NAME;
  207. break;
  208. case ADS_NAME_TYPE_NT4:
  209. *pdwReturn = DS_NT4_ACCOUNT_NAME;
  210. break;
  211. case ADS_NAME_TYPE_DISPLAY:
  212. *pdwReturn = DS_DISPLAY_NAME;
  213. break;
  214. case ADS_NAME_TYPE_DOMAIN_SIMPLE:
  215. *pdwReturn = DS_DOMAIN_SIMPLE_NAME;
  216. break;
  217. case ADS_NAME_TYPE_ENTERPRISE_SIMPLE:
  218. *pdwReturn = DS_ENTERPRISE_SIMPLE_NAME;
  219. break;
  220. case ADS_NAME_TYPE_GUID:
  221. *pdwReturn = DS_UNIQUE_ID_NAME;
  222. break;
  223. case ADS_NAME_TYPE_USER_PRINCIPAL_NAME:
  224. *pdwReturn = DS_USER_PRINCIPAL_NAME;
  225. break;
  226. case ADS_NAME_TYPE_CANONICAL_EX:
  227. *pdwReturn = DS_CANONICAL_NAME_EX;
  228. break;
  229. case ADS_NAME_TYPE_SERVICE_PRINCIPAL_NAME:
  230. *pdwReturn = DS_SERVICE_PRINCIPAL_NAME;
  231. break;
  232. case ADS_NAME_TYPE_UNKNOWN:
  233. *pdwReturn = DS_UNKNOWN_NAME;
  234. break;
  235. case ADS_NAME_TYPE_SID_OR_SID_HISTORY_NAME:
  236. *pdwReturn = DS_SID_OR_SID_HISTORY_NAME;
  237. break;
  238. default:
  239. hr = E_ADS_BAD_PARAMETER;
  240. break;
  241. }
  242. return hr;
  243. }
  244. //+---------------------------------------------------------------------------
  245. // Function: CNameTranslate::AllocateNameTranslateObject
  246. //
  247. // Synopsis:
  248. //
  249. // Arguments:
  250. //
  251. // Returns: HRESULT
  252. //
  253. // Modifies: -
  254. //
  255. // History: 15-7-97 FelixW Created.
  256. //
  257. //----------------------------------------------------------------------------
  258. HRESULT
  259. CNameTranslate::AllocateNameTranslateObject(
  260. CNameTranslate ** ppNameTranslate
  261. )
  262. {
  263. CNameTranslate FAR * pNameTranslate = NULL;
  264. CDispatchMgr FAR * pDispMgr = NULL;
  265. HRESULT hr = S_OK;
  266. pNameTranslate = new CNameTranslate();
  267. if (pNameTranslate == NULL) {
  268. hr = E_OUTOFMEMORY;
  269. }
  270. BAIL_ON_FAILURE(hr);
  271. pDispMgr = new CDispatchMgr;
  272. if (pDispMgr == NULL) {
  273. hr = E_OUTOFMEMORY;
  274. }
  275. BAIL_ON_FAILURE(hr);
  276. hr = LoadTypeInfoEntry(
  277. pDispMgr,
  278. LIBID_ADs,
  279. IID_IADsNameTranslate,
  280. (IADsNameTranslate *)pNameTranslate,
  281. DISPID_REGULAR
  282. );
  283. BAIL_ON_FAILURE(hr);
  284. pNameTranslate->_pDispMgr = pDispMgr;
  285. *ppNameTranslate = pNameTranslate;
  286. RRETURN(hr);
  287. error:
  288. delete pDispMgr;
  289. RRETURN(hr);
  290. }
  291. //+---------------------------------------------------------------------------
  292. // Function: CNameTranslate::Set
  293. //
  294. // Synopsis: Sets the values of the NameTranslate object
  295. //
  296. // Arguments:
  297. //
  298. // Returns: HRESULT
  299. //
  300. // Modifies: -
  301. //
  302. // History: 15-7-97 FelixW Created.
  303. //
  304. //----------------------------------------------------------------------------
  305. STDMETHODIMP
  306. CNameTranslate::Set(long dwSetType,BSTR bstrADsPath)
  307. {
  308. DWORD dwErr = 0;
  309. DS_NAME_RESULTW *pResult = NULL;
  310. HANDLE hDS = NULL;
  311. HRESULT hr = E_FAIL;
  312. DS_NAME_FORMAT dsFormat;
  313. DWORD i;
  314. BOOL fDoNotFree = FALSE;
  315. //
  316. // fDoNotFree is used to determine if we need to free
  317. // the dsresul pResult or not. There are some cases when
  318. // the call can fail but the ptr modified, and in those
  319. // cases it should not be freed.
  320. //
  321. if (!bstrADsPath) {
  322. hr = E_ADS_BAD_PARAMETER;
  323. BAIL_ON_FAILURE(hr);
  324. }
  325. if (!_hDS) {
  326. hr = Init(ADS_NAME_INITTYPE_GC,NULL);
  327. BAIL_ON_FAILURE(hr);
  328. }
  329. if (_rgDomainHandle) {
  330. FreeADsMem(_rgDomainHandle);
  331. _rgDomainHandle = NULL;
  332. }
  333. hr = MapAdsToCrack(dwSetType,
  334. &dsFormat);
  335. BAIL_ON_FAILURE(hr);
  336. dwErr = DsCrackNamesWrapper(
  337. _hDS,
  338. DS_NAME_NO_FLAGS, // flags
  339. dsFormat, // format in
  340. DS_UNIQUE_ID_NAME, // format out
  341. 1, // name count
  342. &bstrADsPath,
  343. &pResult);
  344. if (dwErr) {
  345. fDoNotFree = TRUE;
  346. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
  347. }
  348. if (_bChaseReferral && pResult->rItems[0].status == DS_NAME_ERROR_DOMAIN_ONLY) {
  349. if (!pResult->rItems[0].pDomain) {
  350. BAIL_ON_FAILURE(hr = E_FAIL);
  351. }
  352. //
  353. // Chasing Referral
  354. //
  355. hr = _pDomainHandle->Find(bstrADsPath,
  356. &hDS);
  357. if (hr == E_FAIL ) {
  358. if (!_bAuthSet) {
  359. dwErr = DsBindWrapper(
  360. NULL,
  361. pResult->rItems[0].pDomain,
  362. &hDS);
  363. }
  364. else {
  365. dwErr = DsBindWithCredWrapper(
  366. NULL,
  367. pResult->rItems[0].pDomain,
  368. _AuthIdentity,
  369. &hDS);
  370. }
  371. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
  372. hr = _pDomainHandle->AddElement(bstrADsPath, hDS);
  373. BAIL_ON_FAILURE(hr);
  374. }
  375. dwErr = DsCrackNamesWrapper(
  376. hDS,
  377. DS_NAME_NO_FLAGS, // flags
  378. dsFormat, // format in
  379. DS_UNIQUE_ID_NAME, // format out
  380. 1, // name count
  381. &bstrADsPath,
  382. &pResult);
  383. if (dwErr) {
  384. fDoNotFree = FALSE;
  385. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
  386. }
  387. if (!_rgDomainHandle) {
  388. _rgDomainHandle = (HANDLE*)AllocADsMem(sizeof(HANDLE));
  389. if (!_rgDomainHandle) {
  390. hr = E_OUTOFMEMORY;
  391. BAIL_ON_FAILURE(hr);
  392. }
  393. }
  394. _rgDomainHandle [0] = hDS;
  395. }
  396. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
  397. //
  398. // All below will essentially return E_FAIL on failure.
  399. //
  400. ABORT_ON_ERROR(1 != pResult->cItems);
  401. ABORT_ON_ERROR(NULL == pResult->rItems);
  402. ABORT_ON_ERROR(pResult->rItems[0].status);
  403. ABORT_ON_ERROR(NULL == (pResult->rItems[0].pName));
  404. ABORT_ON_ERROR(0 == wcslen(pResult->rItems[0].pName));
  405. ABORT_ON_ERROR(NULL == pResult->rItems[0].pDomain);
  406. if (_rgszGuid) {
  407. for (i=0;i<_cGuid;i++) {
  408. FreeADsMem(_rgszGuid[i]);
  409. }
  410. FreeADsMem(_rgszGuid);
  411. _rgszGuid = NULL;
  412. }
  413. _rgszGuid = (LPWSTR*)AllocADsMem(sizeof(LPWSTR));
  414. if (!_rgszGuid) {
  415. hr = E_OUTOFMEMORY;
  416. BAIL_ON_FAILURE(hr);
  417. }
  418. _rgszGuid[0] = AllocADsStr(pResult->rItems[0].pName);
  419. if (!_rgszGuid[0]) {
  420. hr = E_OUTOFMEMORY;
  421. BAIL_ON_FAILURE(hr);
  422. }
  423. _cGuid = 1;
  424. if ((dwErr == 0) && (pResult) && (pResult->rItems[0].status != 0)) {
  425. hr = MapCrackErrToHR(pResult->rItems[0].status);
  426. }
  427. if (pResult) {
  428. DsFreeNameResultWrapper(pResult);
  429. }
  430. return hr;
  431. error:
  432. if (hDS) {
  433. DsUnBindWrapper(&hDS);
  434. hDS = NULL;
  435. }
  436. if ((dwErr == 0) && (pResult) && (pResult->rItems[0].status != 0)) {
  437. hr = MapCrackErrToHR(pResult->rItems[0].status);
  438. }
  439. if (pResult && !fDoNotFree) {
  440. DsFreeNameResultWrapper(pResult);
  441. }
  442. return hr;
  443. }
  444. //+---------------------------------------------------------------------------
  445. // Function: CNameTranslate::Init
  446. //
  447. // Synopsis: Initialize the object
  448. //
  449. // Arguments:
  450. //
  451. // Returns: HRESULT
  452. //
  453. // Modifies: -
  454. //
  455. // History: 15-7-97 FelixW Created.
  456. //
  457. //----------------------------------------------------------------------------
  458. STDMETHODIMP
  459. CNameTranslate::Init(long lnType,BSTR bstrADsPath)
  460. {
  461. DWORD dwErr;
  462. HANDLE hDS;
  463. HRESULT hr = E_FAIL;
  464. if (_hDS) {
  465. DsUnBindWrapper(&_hDS);
  466. _hDS = NULL;
  467. }
  468. _pDomainHandle->Init();
  469. switch (lnType) {
  470. case ADS_NAME_INITTYPE_SERVER:
  471. if (!bstrADsPath) {
  472. hr = E_ADS_BAD_PARAMETER;
  473. BAIL_ON_FAILURE(hr);
  474. }
  475. dwErr = DsBindWrapper(
  476. bstrADsPath,
  477. NULL,
  478. &hDS);
  479. break;
  480. case ADS_NAME_INITTYPE_DOMAIN:
  481. if (!bstrADsPath) {
  482. hr = E_ADS_BAD_PARAMETER;
  483. BAIL_ON_FAILURE(hr);
  484. }
  485. dwErr = DsBindWrapper(
  486. NULL,
  487. bstrADsPath,
  488. &hDS);
  489. break;
  490. case ADS_NAME_INITTYPE_GC:
  491. dwErr = DsBindWrapper(
  492. NULL,
  493. NULL,
  494. &hDS);
  495. break;
  496. default:
  497. hr = E_ADS_BAD_PARAMETER;
  498. BAIL_ON_FAILURE(hr);
  499. break;
  500. }
  501. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
  502. _hDS = hDS;
  503. hr = S_OK;
  504. error:
  505. return hr;
  506. }
  507. //+---------------------------------------------------------------------------
  508. // Function: CNameTranslate::InitEx
  509. //
  510. // Synopsis: Initialize the object with Credentials
  511. //
  512. // Arguments:
  513. //
  514. // Returns: HRESULT
  515. //
  516. // Modifies: -
  517. //
  518. // History: 14-2-98 FelixW Created.
  519. //
  520. //----------------------------------------------------------------------------
  521. STDMETHODIMP
  522. CNameTranslate::InitEx(long lnType,BSTR bstrADsPath,BSTR bstrUserID, BSTR bstrDomain, BSTR bstrPassword)
  523. {
  524. DWORD dwErr;
  525. HANDLE hDS;
  526. HRESULT hr = E_FAIL;
  527. if (_hDS) {
  528. DsUnBindWrapper(&_hDS);
  529. _hDS = NULL;
  530. }
  531. hr = _pDomainHandle->Init();
  532. BAIL_ON_FAILURE(hr);
  533. if (_bAuthSet) {
  534. DsFreePasswordCredentialsWrapper(_AuthIdentity);
  535. _bAuthSet = FALSE;
  536. }
  537. dwErr = DsMakePasswordCredentialsWrapper(
  538. bstrUserID,
  539. bstrDomain,
  540. bstrPassword,
  541. &_AuthIdentity
  542. );
  543. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
  544. _bAuthSet = TRUE;
  545. switch (lnType) {
  546. case ADS_NAME_INITTYPE_SERVER:
  547. if (!bstrADsPath) {
  548. hr = E_ADS_BAD_PARAMETER;
  549. BAIL_ON_FAILURE(hr);
  550. }
  551. dwErr = DsBindWithCredWrapper(
  552. bstrADsPath,
  553. NULL,
  554. _AuthIdentity,
  555. &hDS);
  556. break;
  557. case ADS_NAME_INITTYPE_DOMAIN:
  558. if (!bstrADsPath) {
  559. hr = E_ADS_BAD_PARAMETER;
  560. BAIL_ON_FAILURE(hr);
  561. }
  562. dwErr = DsBindWithCredWrapper(
  563. NULL,
  564. bstrADsPath,
  565. _AuthIdentity,
  566. &hDS);
  567. break;
  568. case ADS_NAME_INITTYPE_GC:
  569. dwErr = DsBindWithCredWrapper(
  570. NULL,
  571. NULL,
  572. _AuthIdentity,
  573. &hDS);
  574. break;
  575. default:
  576. hr = E_ADS_BAD_PARAMETER;
  577. BAIL_ON_FAILURE(hr);
  578. break;
  579. }
  580. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
  581. _hDS = hDS;
  582. hr = S_OK;
  583. return hr;
  584. error:
  585. if (_bAuthSet) {
  586. DsFreePasswordCredentialsWrapper(_AuthIdentity);
  587. _bAuthSet = FALSE;
  588. }
  589. return hr;
  590. }
  591. STDMETHODIMP
  592. CNameTranslate::put_ChaseReferral(THIS_ long lnChase)
  593. {
  594. _bChaseReferral = (BOOLEAN)lnChase;
  595. RRETURN(S_OK);
  596. }
  597. //+---------------------------------------------------------------------------
  598. // Function: CNameTranslate::Get
  599. //
  600. // Synopsis: Retrive the pathname as different formats
  601. //
  602. // Arguments:
  603. //
  604. // Returns: HRESULT
  605. //
  606. // Modifies: -
  607. //
  608. // History: 15-7-97 FelixW Created.
  609. //
  610. //----------------------------------------------------------------------------
  611. STDMETHODIMP
  612. CNameTranslate::Get(THIS_ long dwFormatType, BSTR FAR *pbstrName)
  613. {
  614. DS_NAME_RESULTW *pResult = NULL;
  615. HRESULT hr = E_FAIL;
  616. DWORD dwErr = 0;
  617. HANDLE hDS;
  618. DS_NAME_FORMAT dsFormat;
  619. BOOL fDoNotFree = FALSE;
  620. //
  621. // Look at ::Set for more info on fDoNotFree
  622. //
  623. if (!_hDS) {
  624. hr = Init(ADS_NAME_INITTYPE_GC,NULL);
  625. BAIL_ON_FAILURE(hr);
  626. }
  627. if (!pbstrName) {
  628. hr = E_ADS_BAD_PARAMETER;
  629. BAIL_ON_FAILURE(hr);
  630. }
  631. if (dwFormatType == ADS_NAME_TYPE_UNKNOWN) {
  632. hr = E_ADS_BAD_PARAMETER;
  633. BAIL_ON_FAILURE(hr);
  634. }
  635. if ((_cGuid) != 1) {
  636. hr = E_FAIL;
  637. BAIL_ON_FAILURE(hr);
  638. }
  639. hr = MapAdsToCrack(dwFormatType,
  640. &dsFormat);
  641. BAIL_ON_FAILURE(hr);
  642. if (_bChaseReferral && _rgDomainHandle && _rgDomainHandle[0]) {
  643. dwErr = DsCrackNamesWrapper(
  644. _rgDomainHandle[0],
  645. DS_NAME_NO_FLAGS, // flags
  646. DS_UNIQUE_ID_NAME, // format in
  647. dsFormat, // format out
  648. _cGuid, // name count
  649. _rgszGuid,
  650. &pResult);
  651. }
  652. else {
  653. dwErr = DsCrackNamesWrapper(
  654. _hDS,
  655. DS_NAME_NO_FLAGS, // flags
  656. DS_UNIQUE_ID_NAME, // format in
  657. dsFormat, // format out
  658. _cGuid, // name count
  659. _rgszGuid,
  660. &pResult);
  661. }
  662. if (dwErr) {
  663. fDoNotFree = TRUE;
  664. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
  665. }
  666. ABORT_ON_ERROR(1 != pResult->cItems);
  667. ABORT_ON_ERROR(NULL == pResult->rItems);
  668. ABORT_ON_ERROR(pResult->rItems[0].status);
  669. ABORT_ON_ERROR(NULL == (pResult->rItems[0].pName));
  670. ABORT_ON_ERROR(0 == wcslen(pResult->rItems[0].pName));
  671. ABORT_ON_ERROR(NULL == pResult->rItems[0].pDomain);
  672. hr = ADsAllocString(pResult->rItems[0].pName,
  673. pbstrName);
  674. error:
  675. if ((dwErr == 0) && (pResult) && (pResult->rItems[0].status != 0)) {
  676. hr = MapCrackErrToHR(pResult->rItems[0].status);
  677. }
  678. if (pResult && !fDoNotFree) {
  679. DsFreeNameResultWrapper(pResult);
  680. }
  681. return hr;
  682. }
  683. //+---------------------------------------------------------------------------
  684. // Function: CNameTranslate::GetEx
  685. //
  686. // Synopsis: Retrive the pathname as different formats
  687. //
  688. // Arguments:
  689. //
  690. // Returns: HRESULT
  691. //
  692. // Modifies: -
  693. //
  694. // History: 15-7-97 FelixW Created.
  695. //
  696. //----------------------------------------------------------------------------
  697. STDMETHODIMP
  698. CNameTranslate::GetEx(THIS_ long dwFormatType, VARIANT FAR *pvarstrName)
  699. {
  700. long i = 0;
  701. DWORD dwErr = 0;
  702. DS_NAME_RESULTW *pResult = NULL;
  703. HANDLE hDS;
  704. HRESULT hr = E_FAIL;
  705. DS_NAME_FORMAT dsFormat;
  706. LPWSTR szGuid = (LPWSTR)_szGuid;
  707. SAFEARRAY *aList = NULL;
  708. SAFEARRAYBOUND aBound;
  709. BOOL fDoNotFree = FALSE;
  710. //
  711. // Look at ::Set for info on fDoNotFree
  712. //
  713. if (!_hDS) {
  714. hr = Init(ADS_NAME_INITTYPE_GC,NULL);
  715. BAIL_ON_FAILURE(hr);
  716. }
  717. if (!pvarstrName) {
  718. hr = E_ADS_BAD_PARAMETER;
  719. BAIL_ON_FAILURE(hr);
  720. }
  721. if (dwFormatType == ADS_NAME_TYPE_UNKNOWN) {
  722. hr = E_ADS_BAD_PARAMETER;
  723. BAIL_ON_FAILURE(hr);
  724. }
  725. hr = MapAdsToCrack(dwFormatType,
  726. &dsFormat);
  727. BAIL_ON_FAILURE(hr);
  728. dwErr = DsCrackNamesWrapper(
  729. _hDS,
  730. DS_NAME_NO_FLAGS, // flags
  731. DS_UNIQUE_ID_NAME, // format in
  732. dsFormat, // format out
  733. _cGuid, // name count
  734. _rgszGuid,
  735. &pResult);
  736. if (dwErr) {
  737. fDoNotFree = TRUE;
  738. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
  739. }
  740. ABORT_ON_ERROR(NULL == pResult->rItems);
  741. ABORT_ON_ERROR(pResult->rItems[0].status);
  742. ABORT_ON_ERROR(NULL == (pResult->rItems[0].pName));
  743. ABORT_ON_ERROR(0 == wcslen(pResult->rItems[0].pName));
  744. ABORT_ON_ERROR(NULL == pResult->rItems[0].pDomain);
  745. VariantInit( pvarstrName );
  746. aBound.lLbound = 0;
  747. aBound.cElements = pResult->cItems;
  748. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  749. if ( aList == NULL )
  750. {
  751. hr = E_OUTOFMEMORY;
  752. BAIL_ON_FAILURE(hr);
  753. }
  754. for ( i = 0; i < (long) pResult->cItems; i++ )
  755. {
  756. VARIANT v;
  757. VariantInit(&v);
  758. hr = ADsAllocString(
  759. pResult->rItems[i].pName,
  760. &(v.bstrVal)
  761. );
  762. BAIL_ON_FAILURE(hr);
  763. v.vt = VT_BSTR;
  764. hr = SafeArrayPutElement( aList, &i, &v );
  765. VariantClear(&v);
  766. BAIL_ON_FAILURE(hr);
  767. }
  768. V_VT(pvarstrName) = VT_ARRAY | VT_VARIANT;
  769. V_ARRAY(pvarstrName) = aList;
  770. if ((dwErr == 0) && (pResult) && (pResult->rItems[0].status != 0)) {
  771. hr = MapCrackErrToHR(pResult->rItems[0].status);
  772. BAIL_ON_FAILURE(hr);
  773. }
  774. if (pResult) {
  775. DsFreeNameResultWrapper(pResult);
  776. }
  777. RRETURN(S_OK);
  778. error:
  779. if ((dwErr == 0) && (pResult) && (pResult->rItems[0].status != 0)) {
  780. hr = MapCrackErrToHR(pResult->rItems[0].status);
  781. }
  782. if (pResult && !fDoNotFree) {
  783. DsFreeNameResultWrapper(pResult);
  784. }
  785. if ( aList ) {
  786. SafeArrayDestroy( aList );
  787. }
  788. return hr;
  789. }
  790. HRESULT
  791. ConvertSafeArrayToBstrArray(
  792. VARIANT *pvarSafeArray,
  793. BSTR **ppVarArray,
  794. DWORD *pdwNumVariants
  795. )
  796. {
  797. HRESULT hr = S_OK;
  798. DWORD dwSLBound = 0;
  799. DWORD dwSUBound = 0;
  800. DWORD dwNumVariants = 0;
  801. DWORD i = 0;
  802. BSTR * pVarArray = NULL;
  803. SAFEARRAY * pArray = NULL;
  804. *pdwNumVariants = 0;
  805. *ppVarArray = 0;
  806. if(!((V_VT(pvarSafeArray) & VT_BSTR) && V_ISARRAY(pvarSafeArray)))
  807. return(E_FAIL);
  808. //
  809. // This handles by-ref and regular SafeArrays.
  810. //
  811. if (V_VT(pvarSafeArray) & VT_BYREF)
  812. pArray = *(V_ARRAYREF(pvarSafeArray));
  813. else
  814. pArray = V_ARRAY(pvarSafeArray);
  815. //
  816. // Check that there is only one dimension in this array
  817. //
  818. if (pArray->cDims != 1) {
  819. hr = E_FAIL;
  820. BAIL_ON_FAILURE(hr);
  821. }
  822. //
  823. // Check that there is at least one element in this array
  824. //
  825. if (pArray->rgsabound[0].cElements == 0){
  826. return(S_OK); // Return success and null array
  827. }
  828. //
  829. // We know that this is a valid single dimension array
  830. //
  831. hr = SafeArrayGetLBound(pArray,
  832. 1,
  833. (long FAR *)&dwSLBound
  834. );
  835. BAIL_ON_FAILURE(hr);
  836. hr = SafeArrayGetUBound(pArray,
  837. 1,
  838. (long FAR *)&dwSUBound
  839. );
  840. BAIL_ON_FAILURE(hr);
  841. dwNumVariants = dwSUBound - dwSLBound + 1;
  842. pVarArray = (BSTR*)AllocADsMem(
  843. sizeof(BSTR)*dwNumVariants
  844. );
  845. if (!pVarArray) {
  846. hr = E_OUTOFMEMORY;
  847. BAIL_ON_FAILURE(hr);
  848. }
  849. for (i = dwSLBound; i <= dwSUBound; i++) {
  850. hr = SafeArrayGetElement(pArray,
  851. (long FAR *)&i,
  852. (pVarArray + i)
  853. );
  854. if (FAILED(hr)) {
  855. continue;
  856. }
  857. }
  858. *ppVarArray = pVarArray;
  859. *pdwNumVariants = dwNumVariants;
  860. error:
  861. return(hr);
  862. }
  863. //+---------------------------------------------------------------------------
  864. // Function: CNameTranslate::SetEx
  865. //
  866. // Synopsis: Set multiple objects names
  867. //
  868. // Arguments:
  869. //
  870. // Returns: HRESULT
  871. //
  872. // Modifies: -
  873. //
  874. // History: 15-7-97 FelixW Created.
  875. //
  876. //----------------------------------------------------------------------------
  877. STDMETHODIMP
  878. CNameTranslate::SetEx(THIS_ long dwSetType, VARIANT varstrName)
  879. {
  880. DWORD dwErr = 0;
  881. DS_NAME_RESULTW *pResult = NULL;
  882. HANDLE hDS;
  883. HRESULT hr = E_FAIL;
  884. DS_NAME_FORMAT dsFormat;
  885. VARIANT *vVarArray = NULL;
  886. PWSTR *ppszStrArray = NULL;
  887. DWORD dwNum,i;
  888. BOOL fDoNotFree = FALSE;
  889. //
  890. // Look at ::Set for more info on fDoNotFree
  891. //
  892. if (!_hDS) {
  893. hr = Init(ADS_NAME_INITTYPE_GC,NULL);
  894. BAIL_ON_FAILURE(hr);
  895. }
  896. hr = MapAdsToCrack(dwSetType,
  897. &dsFormat);
  898. BAIL_ON_FAILURE(hr);
  899. hr = ConvertSafeArrayToVariantArray(
  900. varstrName,
  901. &vVarArray,
  902. &dwNum
  903. );
  904. // returns E_FAIL if varstrname is invalid
  905. if (hr == E_FAIL)
  906. hr = E_ADS_BAD_PARAMETER;
  907. BAIL_ON_FAILURE(hr);
  908. hr = ConvertVariantArrayToLDAPStringArray(
  909. vVarArray,
  910. &ppszStrArray,
  911. dwNum
  912. );
  913. BAIL_ON_FAILURE(hr);
  914. dwErr = DsCrackNamesWrapper(
  915. _hDS,
  916. DS_NAME_NO_FLAGS, // flags
  917. dsFormat, // format in
  918. DS_UNIQUE_ID_NAME, // format out
  919. dwNum, // name count
  920. ppszStrArray,
  921. &pResult
  922. );
  923. if (dwErr) {
  924. fDoNotFree = TRUE;
  925. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
  926. }
  927. ABORT_ON_ERROR(NULL == pResult->rItems);
  928. ABORT_ON_ERROR(pResult->rItems[0].status);
  929. ABORT_ON_ERROR(NULL == (pResult->rItems[0].pName));
  930. ABORT_ON_ERROR(0 == wcslen(pResult->rItems[0].pName));
  931. ABORT_ON_ERROR(NULL == pResult->rItems[0].pDomain);
  932. if (_rgszGuid) {
  933. for (i=0;i<_cGuid;i++) {
  934. FreeADsMem(_rgszGuid[i]);
  935. }
  936. FreeADsMem(_rgszGuid);
  937. }
  938. _rgszGuid = (LPWSTR*)AllocADsMem(dwNum * sizeof(LPWSTR));
  939. if (!_rgszGuid) {
  940. hr = E_OUTOFMEMORY;
  941. BAIL_ON_FAILURE(hr);
  942. }
  943. for (i=0;i<dwNum;i++) {
  944. _rgszGuid[i] = AllocADsStr(pResult->rItems[i].pName);
  945. if (!_rgszGuid[i]) {
  946. hr = E_OUTOFMEMORY;
  947. BAIL_ON_FAILURE(hr);
  948. }
  949. }
  950. _cGuid = dwNum;
  951. error:
  952. if (ppszStrArray) {
  953. for (i=0; i < dwNum; i++) {
  954. if (ppszStrArray[i]) {
  955. FreeADsStr(ppszStrArray[i]);
  956. }
  957. }
  958. FreeADsMem(ppszStrArray);
  959. }
  960. if (vVarArray) {
  961. for (i=0; i < dwNum; i++) {
  962. VariantClear(vVarArray + i);
  963. }
  964. FreeADsMem(vVarArray);
  965. }
  966. if ((dwErr == 0) && (pResult) && (pResult->rItems[0].status != 0)) {
  967. hr = MapCrackErrToHR(pResult->rItems[0].status);
  968. }
  969. if (pResult && !fDoNotFree) {
  970. DsFreeNameResultWrapper(pResult);
  971. }
  972. return hr;
  973. }
  974. CDomainToHandle::CDomainToHandle()
  975. {
  976. m_cszMax = 0;
  977. m_iszNext = 0;
  978. m_rgMap = NULL;
  979. }
  980. CDomainToHandle::~CDomainToHandle()
  981. {
  982. Free();
  983. }
  984. DWORD CDomainToHandle::NumElements()
  985. {
  986. return m_iszNext;
  987. }
  988. HRESULT CDomainToHandle::Init()
  989. {
  990. HRESULT hr = S_OK;
  991. Free();
  992. m_rgMap = (DomainToHandle*)AllocADsMem( STRINGPLEX_INC * sizeof(DomainToHandle) );
  993. if (!m_rgMap) {
  994. hr = E_OUTOFMEMORY;
  995. BAIL_ON_FAILURE(hr);
  996. }
  997. m_cszMax = STRINGPLEX_INC;
  998. m_iszNext = 0;
  999. memset(m_rgMap, 0, STRINGPLEX_INC * sizeof(DomainToHandle) );
  1000. error:
  1001. return hr;
  1002. }
  1003. HRESULT CDomainToHandle::AddElement(LPWSTR szValue, HANDLE hDS)
  1004. {
  1005. HRESULT hr = S_OK;
  1006. DomainToHandle *rgMap = NULL;
  1007. if (!szValue) {
  1008. return E_ADS_BAD_PARAMETER;
  1009. }
  1010. //
  1011. // If next index is larger than largest index
  1012. //
  1013. if (m_iszNext > (m_cszMax-1)) {
  1014. rgMap = (DomainToHandle*)ReallocADsMem(m_rgMap ,
  1015. m_cszMax*sizeof(DomainToHandle),
  1016. (m_cszMax + STRINGPLEX_INC)*sizeof(DomainToHandle));
  1017. if (!rgMap) {
  1018. hr = E_OUTOFMEMORY;
  1019. BAIL_ON_FAILURE(hr);
  1020. }
  1021. m_rgMap = rgMap;
  1022. m_cszMax+=STRINGPLEX_INC;
  1023. }
  1024. m_rgMap[m_iszNext].szDomain = AllocADsStr(szValue);
  1025. if (!m_rgMap[m_iszNext].szDomain) {
  1026. hr = E_OUTOFMEMORY;
  1027. BAIL_ON_FAILURE(hr);
  1028. }
  1029. m_rgMap[m_iszNext].hDS = hDS;
  1030. m_iszNext++;
  1031. error:
  1032. return hr;
  1033. }
  1034. HRESULT CDomainToHandle::Find(LPWSTR szValue, HANDLE *phDS)
  1035. {
  1036. HRESULT hr = E_FAIL;
  1037. UINT i;
  1038. if (!szValue) {
  1039. return E_ADS_BAD_PARAMETER;
  1040. }
  1041. for (i=0;i<m_iszNext;i++) {
  1042. if (wcscmp(m_rgMap[i].szDomain, szValue) == 0) {
  1043. *phDS = m_rgMap[i].hDS;
  1044. return S_OK;
  1045. }
  1046. }
  1047. return hr;
  1048. }
  1049. void CDomainToHandle::Free()
  1050. {
  1051. DWORD isz = 0;
  1052. if (m_rgMap) {
  1053. for (isz=0;isz<m_iszNext;isz++) {
  1054. if (m_rgMap[isz].szDomain) {
  1055. FreeADsMem(m_rgMap[isz].szDomain);
  1056. DsUnBindWrapper(&m_rgMap[isz].hDS);
  1057. }
  1058. }
  1059. FreeADsMem(m_rgMap);
  1060. m_rgMap = NULL;
  1061. }
  1062. m_cszMax = 0;
  1063. m_iszNext = 0;
  1064. }