Leaked source code of windows server 2003
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.

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