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.

930 lines
21 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cnamesp.cxx
  7. //
  8. // Contents: Windows NT 3.5 Namespace Object
  9. //
  10. //
  11. // History: 01-30-95 krishnag Created.
  12. //
  13. //----------------------------------------------------------------------------
  14. #include "NWCOMPAT.hxx"
  15. #pragma hdrstop
  16. DEFINE_IDispatch_Implementation(CNWCOMPATNamespace)
  17. DEFINE_IADs_Implementation(CNWCOMPATNamespace)
  18. // Class CNWCOMPATNamespace
  19. CNWCOMPATNamespace::CNWCOMPATNamespace()
  20. {
  21. VariantInit(&_vFilter);
  22. ENLIST_TRACKING(CNWCOMPATNamespace);
  23. }
  24. HRESULT
  25. CNWCOMPATNamespace::CreateNamespace(
  26. BSTR Parent,
  27. BSTR NamespaceName,
  28. CCredentials &Credentials,
  29. DWORD dwObjectState,
  30. REFIID riid,
  31. void **ppvObj
  32. )
  33. {
  34. CNWCOMPATNamespace FAR * pNamespace = NULL;
  35. HRESULT hr = S_OK;
  36. hr = AllocateNamespaceObject(&pNamespace);
  37. BAIL_ON_FAILURE(hr);
  38. hr = pNamespace->InitializeCoreObject(
  39. Parent,
  40. NamespaceName,
  41. NAMESPACE_CLASS_NAME,
  42. NO_SCHEMA,
  43. CLSID_NWCOMPATNamespace,
  44. dwObjectState
  45. );
  46. BAIL_ON_FAILURE(hr);
  47. pNamespace->_Credentials = Credentials;
  48. hr = pNamespace->QueryInterface(riid, ppvObj);
  49. BAIL_ON_FAILURE(hr);
  50. pNamespace->Release(); // <- WHY?
  51. RRETURN(hr);
  52. error:
  53. delete pNamespace;
  54. NW_RRETURN_EXP_IF_ERR(hr);
  55. }
  56. CNWCOMPATNamespace::~CNWCOMPATNamespace( )
  57. {
  58. delete _pDispMgr;
  59. VariantClear(&_vFilter);
  60. }
  61. STDMETHODIMP
  62. CNWCOMPATNamespace::QueryInterface(
  63. REFIID iid,
  64. LPVOID FAR* ppv
  65. )
  66. {
  67. if (ppv == NULL) {
  68. RRETURN(E_POINTER);
  69. }
  70. if (IsEqualIID(iid, IID_IUnknown))
  71. {
  72. *ppv = (IADs FAR *)this;
  73. }else if (IsEqualIID(iid, IID_IDispatch))
  74. {
  75. *ppv = (IADs FAR *)this;
  76. }
  77. else if (IsEqualIID(iid, IID_ISupportErrorInfo))
  78. {
  79. *ppv = (ISupportErrorInfo *) this;
  80. }
  81. else if (IsEqualIID(iid, IID_IADsContainer))
  82. {
  83. *ppv = (IADsContainer FAR *) this;
  84. }
  85. else if (IsEqualIID(iid, IID_IADs))
  86. {
  87. *ppv = (IADs FAR *) this;
  88. }
  89. else if (IsEqualIID(iid, IID_IADsOpenDSObject))
  90. {
  91. *ppv = (IADsOpenDSObject FAR *) this;
  92. }
  93. else if (IsEqualIID(iid, IID_IADsPathnameProvider))
  94. {
  95. *ppv = (IADsPathnameProvider FAR *) this;
  96. }
  97. else
  98. {
  99. *ppv = NULL;
  100. return E_NOINTERFACE;
  101. }
  102. AddRef();
  103. return NOERROR;
  104. }
  105. STDMETHODIMP
  106. CNWCOMPATNamespace::InterfaceSupportsErrorInfo(
  107. THIS_ REFIID riid
  108. )
  109. {
  110. if (IsEqualIID(riid, IID_IADs) ||
  111. IsEqualIID(riid, IID_IADsContainer)) {
  112. RRETURN(S_OK);
  113. } else {
  114. RRETURN(S_FALSE);
  115. }
  116. }
  117. STDMETHODIMP
  118. CNWCOMPATNamespace::SetInfo(
  119. THIS
  120. )
  121. {
  122. NW_RRETURN_EXP_IF_ERR(E_NOTIMPL);
  123. }
  124. STDMETHODIMP
  125. CNWCOMPATNamespace::GetInfo(
  126. THIS
  127. )
  128. {
  129. NW_RRETURN_EXP_IF_ERR(E_NOTIMPL);
  130. }
  131. /* IADsContainer methods */
  132. STDMETHODIMP
  133. CNWCOMPATNamespace::get_Count(
  134. long FAR* retval
  135. )
  136. {
  137. NW_RRETURN_EXP_IF_ERR(E_NOTIMPL);
  138. }
  139. STDMETHODIMP
  140. CNWCOMPATNamespace::get_Filter(
  141. THIS_ VARIANT FAR* pVar
  142. )
  143. {
  144. HRESULT hr;
  145. VariantInit(pVar);
  146. hr = VariantCopy(pVar, &_vFilter);
  147. NW_RRETURN_EXP_IF_ERR(hr);
  148. }
  149. STDMETHODIMP
  150. CNWCOMPATNamespace::put_Filter(
  151. THIS_ VARIANT Var
  152. )
  153. {
  154. HRESULT hr;
  155. hr = VariantCopy(&_vFilter, &Var);
  156. NW_RRETURN_EXP_IF_ERR(hr);
  157. }
  158. STDMETHODIMP
  159. CNWCOMPATNamespace::put_Hints(THIS_ VARIANT Var)
  160. {
  161. NW_RRETURN_EXP_IF_ERR( E_NOTIMPL);
  162. }
  163. STDMETHODIMP
  164. CNWCOMPATNamespace::get_Hints(THIS_ VARIANT FAR* pVar)
  165. {
  166. NW_RRETURN_EXP_IF_ERR(E_NOTIMPL);
  167. }
  168. STDMETHODIMP
  169. CNWCOMPATNamespace::GetObject(
  170. THIS_ BSTR ClassName,
  171. BSTR RelativeName,
  172. IDispatch * FAR* ppObject
  173. )
  174. {
  175. WCHAR szBuffer[MAX_PATH];
  176. HRESULT hr = S_OK;
  177. if (!RelativeName || !*RelativeName) {
  178. NW_RRETURN_EXP_IF_ERR(E_ADS_UNKNOWN_OBJECT);
  179. }
  180. wcscpy(szBuffer, _ADsPath);
  181. wcscat(szBuffer, L"//");
  182. wcscat(szBuffer, RelativeName);
  183. if (ClassName && *ClassName) {
  184. wcscat(szBuffer,L",");
  185. wcscat(szBuffer, ClassName);
  186. }
  187. hr = ::GetObject(
  188. szBuffer,
  189. _Credentials,
  190. (LPVOID *)ppObject
  191. );
  192. BAIL_ON_FAILURE(hr);
  193. error:
  194. NW_RRETURN_EXP_IF_ERR(hr);
  195. }
  196. STDMETHODIMP
  197. CNWCOMPATNamespace::get__NewEnum(
  198. THIS_ IUnknown * FAR* retval
  199. )
  200. {
  201. HRESULT hr;
  202. IUnknown FAR* punkEnum=NULL;
  203. IEnumVARIANT * penum = NULL;
  204. *retval = NULL;
  205. //
  206. // Create new enumerator for items currently
  207. // in collection and QI for IUnknown
  208. //
  209. hr = CNWCOMPATNamespaceEnum::Create(
  210. _Credentials,
  211. (CNWCOMPATNamespaceEnum **)&penum
  212. );
  213. BAIL_ON_FAILURE(hr);
  214. hr = penum->QueryInterface(
  215. IID_IUnknown,
  216. (VOID FAR* FAR*)retval
  217. );
  218. BAIL_ON_FAILURE(hr);
  219. if (penum) {
  220. penum->Release();
  221. }
  222. return NOERROR;
  223. error:
  224. if (penum) {
  225. delete penum;
  226. }
  227. NW_RRETURN_EXP_IF_ERR(hr);
  228. }
  229. STDMETHODIMP
  230. CNWCOMPATNamespace::Create(
  231. THIS_ BSTR ClassName,
  232. BSTR RelativeName,
  233. IDispatch * FAR* ppObject
  234. )
  235. {
  236. NW_RRETURN_EXP_IF_ERR(E_NOTIMPL);
  237. }
  238. STDMETHODIMP
  239. CNWCOMPATNamespace::Delete(
  240. THIS_ BSTR SourceName,
  241. BSTR Type
  242. )
  243. {
  244. NW_RRETURN_EXP_IF_ERR(E_NOTIMPL);
  245. }
  246. STDMETHODIMP
  247. CNWCOMPATNamespace::CopyHere(
  248. THIS_ BSTR SourceName,
  249. BSTR NewName,
  250. IDispatch * FAR* ppObject
  251. )
  252. {
  253. NW_RRETURN_EXP_IF_ERR(E_NOTIMPL);
  254. }
  255. STDMETHODIMP
  256. CNWCOMPATNamespace::MoveHere(
  257. THIS_ BSTR SourceName,
  258. BSTR NewName,
  259. IDispatch * FAR* ppObject
  260. )
  261. {
  262. NW_RRETURN_EXP_IF_ERR(E_NOTIMPL);
  263. }
  264. HRESULT
  265. CNWCOMPATNamespace::AllocateNamespaceObject(
  266. CNWCOMPATNamespace ** ppNamespace
  267. )
  268. {
  269. CNWCOMPATNamespace FAR * pNamespace = NULL;
  270. CDispatchMgr FAR * pDispMgr = NULL;
  271. HRESULT hr = S_OK;
  272. pNamespace = new CNWCOMPATNamespace();
  273. if (pNamespace == NULL) {
  274. hr = E_OUTOFMEMORY;
  275. }
  276. BAIL_ON_FAILURE(hr);
  277. pDispMgr = new CDispatchMgr;
  278. if (pDispMgr == NULL) {
  279. hr = E_OUTOFMEMORY;
  280. }
  281. BAIL_ON_FAILURE(hr);
  282. hr = LoadTypeInfoEntry(
  283. pDispMgr,
  284. LIBID_ADs,
  285. IID_IADs,
  286. (IADs *)pNamespace,
  287. DISPID_REGULAR
  288. );
  289. BAIL_ON_FAILURE(hr);
  290. hr = LoadTypeInfoEntry(pDispMgr,
  291. LIBID_ADs,
  292. IID_IADsOpenDSObject,
  293. (IADsOpenDSObject *)pNamespace,
  294. DISPID_REGULAR
  295. );
  296. BAIL_ON_FAILURE(hr);
  297. hr = LoadTypeInfoEntry(
  298. pDispMgr,
  299. LIBID_ADs,
  300. IID_IADsContainer,
  301. (IADsContainer *)pNamespace,
  302. DISPID_NEWENUM
  303. );
  304. BAIL_ON_FAILURE(hr);
  305. pNamespace->_pDispMgr = pDispMgr;
  306. *ppNamespace = pNamespace;
  307. RRETURN(hr);
  308. error:
  309. delete pDispMgr;
  310. RRETURN(hr);
  311. }
  312. STDMETHODIMP
  313. CNWCOMPATNamespace::OpenDSObject(
  314. BSTR lpszDNName,
  315. BSTR lpszUserName,
  316. BSTR lpszPassword,
  317. LONG lnReserved,
  318. IDispatch FAR * * ppADsObj
  319. )
  320. {
  321. HRESULT hr = S_OK;
  322. IUnknown * pObject = NULL;
  323. CCredentials Credentials(lpszUserName, lpszPassword, 0L);
  324. hr = ::GetObject(
  325. lpszDNName,
  326. Credentials,
  327. (LPVOID *)&pObject
  328. );
  329. BAIL_ON_FAILURE(hr);
  330. hr = pObject->QueryInterface(
  331. IID_IDispatch,
  332. (void **)ppADsObj
  333. );
  334. BAIL_ON_FAILURE(hr);
  335. error:
  336. if (pObject) {
  337. pObject->Release();
  338. }
  339. RRETURN(hr);
  340. }
  341. HRESULT
  342. CNWCOMPATNamespace::ParsePath(
  343. BSTR bstrADsPath,
  344. DWORD dwType,
  345. PPATH_OBJECTINFO pObjectInfo
  346. )
  347. /*++
  348. Routine Description:
  349. Parse a path based on the type and return the information in pObjectInfo
  350. Arguments:
  351. bstrADsPath - ads path to be parsed
  352. dwType - the type of path to be parsed:
  353. ADS_PARSE_FULL
  354. ADS_PARSE_DN
  355. ADS_PARSE_COMPONENT
  356. pObjectInfo - the place where the parsed object is stored
  357. Return Value:
  358. S_OK on success, error code otherwise.
  359. --*/
  360. {
  361. HRESULT hr = S_OK;
  362. OBJECTINFO ObjInfo;
  363. POBJECTINFO pObjInfo = &ObjInfo;
  364. PWSTR szPath = NULL;
  365. memset(pObjInfo, 0, sizeof(OBJECTINFO));
  366. switch (dwType) {
  367. case ADS_PARSE_FULL:
  368. {
  369. CLexer Lexer(bstrADsPath);
  370. hr = Object(&Lexer, pObjInfo);
  371. BAIL_ON_FAILURE(hr);
  372. break;
  373. }
  374. case ADS_PARSE_DN:
  375. {
  376. WCHAR szToken[MAX_TOKEN_LENGTH];
  377. DWORD dwToken;
  378. //
  379. // Collecting new information
  380. //
  381. CLexer Lexer(bstrADsPath);
  382. Lexer.SetAtDisabler(TRUE);
  383. hr = PathName(&Lexer,
  384. pObjInfo);
  385. BAIL_ON_FAILURE(hr);
  386. hr = Lexer.GetNextToken(szToken,
  387. &dwToken);
  388. BAIL_ON_FAILURE(hr);
  389. if (dwToken != TOKEN_END) {
  390. hr = E_ADS_BAD_PATHNAME;
  391. }
  392. break;
  393. }
  394. case ADS_PARSE_COMPONENT:
  395. {
  396. CLexer Lexer(bstrADsPath);
  397. Lexer.SetAtDisabler(TRUE);
  398. hr = Component(&Lexer,
  399. pObjInfo);
  400. BAIL_ON_FAILURE(hr);
  401. break;
  402. }
  403. default:
  404. break;
  405. }
  406. //
  407. // Setting new info
  408. //
  409. if (pObjInfo->ProviderName) {
  410. pObjectInfo->ProviderName = AllocADsStr(pObjInfo->ProviderName);
  411. if (!pObjectInfo->ProviderName) {
  412. hr = E_OUTOFMEMORY;
  413. BAIL_ON_FAILURE(hr);
  414. }
  415. }
  416. hr = SetObjInfoComponents(pObjInfo,
  417. pObjectInfo);
  418. BAIL_ON_FAILURE(hr);
  419. pObjectInfo->NumComponents = pObjInfo->NumComponents;
  420. pObjectInfo->dwPathType = ADS_PATHTYPE_ROOTFIRST;
  421. error:
  422. FreeObjectInfo(pObjInfo,TRUE);
  423. if (szPath != NULL) {
  424. FreeADsStr(szPath);
  425. }
  426. return (hr);
  427. }
  428. HRESULT
  429. CNWCOMPATNamespace::SetObjInfoComponents(
  430. OBJECTINFO *pObjectInfo,
  431. PATH_OBJECTINFO *pObjectInfoTarget
  432. )
  433. /*++
  434. Routine Description:
  435. Set all the compoents in an objinfo from another objinfo. Assumes that the
  436. components in the target objinfo is empty. Users of this function can call
  437. FreeObjInfo to free that data prior to this function call.
  438. Arguments:
  439. Return Value:
  440. S_OK on success, error code otherwise.
  441. --*/
  442. {
  443. DWORD NumComponents;
  444. HRESULT hr = S_OK;
  445. NumComponents = 0;
  446. while (NumComponents < pObjectInfo->NumComponents) {
  447. if (pObjectInfo->ComponentArray[NumComponents]) {
  448. pObjectInfoTarget->ComponentArray[NumComponents].szComponent =
  449. AllocADsStr(pObjectInfo->ComponentArray[NumComponents]);
  450. if (pObjectInfoTarget->ComponentArray[NumComponents].szComponent == NULL) {
  451. pObjectInfoTarget->NumComponents = NumComponents;
  452. hr = E_OUTOFMEMORY;
  453. BAIL_ON_FAILURE(hr);
  454. }
  455. }
  456. if (pObjectInfo->DisplayComponentArray[NumComponents]) {
  457. pObjectInfoTarget->DisplayComponentArray[NumComponents].szComponent =
  458. AllocADsStr(pObjectInfo->DisplayComponentArray[NumComponents]);
  459. if (pObjectInfoTarget->DisplayComponentArray[NumComponents].szComponent == NULL) {
  460. pObjectInfoTarget->NumComponents = NumComponents;
  461. hr = E_OUTOFMEMORY;
  462. BAIL_ON_FAILURE(hr);
  463. }
  464. }
  465. NumComponents++;
  466. }
  467. pObjectInfoTarget->NumComponents = pObjectInfo->NumComponents;
  468. return hr;
  469. error:
  470. FreeObjInfoComponents(pObjectInfoTarget);
  471. RRETURN_EXP_IF_ERR(hr);
  472. }
  473. void
  474. CNWCOMPATNamespace::FreeObjInfoComponents(
  475. PATH_OBJECTINFO *pObjectInfo
  476. )
  477. /*++
  478. Routine Description:
  479. Free all the compoents in an objinfo
  480. Arguments:
  481. Return Value:
  482. S_OK on success, error code otherwise.
  483. --*/
  484. {
  485. DWORD NumComponents;
  486. while (pObjectInfo->NumComponents > 0) {
  487. pObjectInfo->NumComponents--;
  488. NumComponents = pObjectInfo->NumComponents;
  489. if (pObjectInfo->ComponentArray[NumComponents].szComponent) {
  490. FreeADsStr(
  491. pObjectInfo->ComponentArray[NumComponents].szComponent);
  492. pObjectInfo->ComponentArray[NumComponents].szComponent = NULL;
  493. }
  494. if (pObjectInfo->ComponentArray[NumComponents].szValue) {
  495. FreeADsStr(
  496. pObjectInfo->ComponentArray[NumComponents].szValue);
  497. pObjectInfo->ComponentArray[NumComponents].szValue = NULL;
  498. }
  499. if (pObjectInfo->DisplayComponentArray[NumComponents].szComponent) {
  500. FreeADsStr(
  501. pObjectInfo->DisplayComponentArray[NumComponents].szComponent);
  502. pObjectInfo->DisplayComponentArray[NumComponents].szComponent = NULL;
  503. }
  504. if (pObjectInfo->DisplayComponentArray[NumComponents].szValue) {
  505. FreeADsStr(
  506. pObjectInfo->DisplayComponentArray[NumComponents].szValue);
  507. pObjectInfo->DisplayComponentArray[NumComponents].szValue = NULL;
  508. }
  509. }
  510. }
  511. void
  512. CNWCOMPATNamespace::SetComponent(
  513. LPWSTR szReturn,
  514. DWORD cComponents,
  515. BOOL fEscaped
  516. )
  517. /*++
  518. Routine Description:
  519. Set an individual component in the pathname. For internal use only.
  520. Not exposed.
  521. Arguments:
  522. szReturn - the buffer to store the return value
  523. cComponents - the component number to be set
  524. Return Value:
  525. S_OK on success, error code otherwise.
  526. --*/
  527. {
  528. PATH_COMPONENT* pComponent = NULL;
  529. if (fEscaped) {
  530. pComponent = _pObjectInfo->DisplayComponentArray;
  531. }
  532. else {
  533. pComponent = _pObjectInfo->ComponentArray;
  534. }
  535. if (pComponent[cComponents].szValue) {
  536. //
  537. // If value exist, only show display value
  538. //
  539. wcscat(szReturn,
  540. pComponent[cComponents].szValue);
  541. }
  542. else {
  543. //
  544. // else value is only stored in Component
  545. //
  546. wcscat(szReturn,
  547. pComponent[cComponents].szComponent);
  548. }
  549. }
  550. HRESULT
  551. CNWCOMPATNamespace::SetComponents(
  552. LPWSTR szReturn,
  553. LPWSTR chSeparator,
  554. DWORD dwType,
  555. BOOL fEscaped
  556. )
  557. /*++
  558. Routine Description:
  559. Set components in the pathname. For internal use only. Not exposed.
  560. Arguments:
  561. szReturn - the buffer to store the return value
  562. chSeparator - separator to be used
  563. dwType - the type to be set
  564. ADS_COMPONENT_LEAF
  565. ADS_COMPONENT_DN
  566. ADS_COMPONENT_PARENT
  567. Return Value:
  568. S_OK on success, error code otherwise.
  569. --*/
  570. {
  571. HRESULT hr = S_OK;
  572. long cComponents;
  573. long dwLimit;
  574. long dwOtherLimit = 0;
  575. if (dwType == ADS_COMPONENT_LEAF) {
  576. //
  577. // Only returns the leaf component
  578. //
  579. if (_pObjectInfo->dwPathType == ADS_PATHTYPE_ROOTFIRST) {
  580. if (_pObjectInfo->NumComponents > 0) {
  581. SetComponent(szReturn,
  582. _pObjectInfo->NumComponents - 1,
  583. fEscaped);
  584. }
  585. else {
  586. hr = E_ADS_BAD_PATHNAME;
  587. }
  588. }
  589. else {
  590. if (_pObjectInfo->NumComponents != 0) {
  591. SetComponent(szReturn,
  592. 0,
  593. fEscaped);
  594. }
  595. else {
  596. hr = E_ADS_BAD_PATHNAME;
  597. }
  598. }
  599. RRETURN(hr);
  600. }
  601. dwLimit = _pObjectInfo->NumComponents;
  602. if (dwType == ADS_COMPONENT_PARENT) {
  603. dwLimit--;
  604. }
  605. if (dwOtherLimit >= dwLimit) {
  606. hr = E_ADS_BAD_PATHNAME;
  607. goto error;
  608. }
  609. for (cComponents = dwOtherLimit; cComponents < dwLimit; cComponents++) {
  610. SetComponent(szReturn,
  611. cComponents,
  612. fEscaped);
  613. if (cComponents != dwLimit - 1) {
  614. wcscat(szReturn,
  615. chSeparator);
  616. }
  617. }
  618. error:
  619. RRETURN(S_OK);
  620. }
  621. DWORD CountPath(
  622. PPATH_OBJECTINFO pObjectInfo
  623. )
  624. {
  625. DWORD dwPath = 4; // Basic needs '://' and '/' for servername
  626. DWORD i;
  627. if (pObjectInfo->ProviderName) {
  628. dwPath += wcslen(pObjectInfo->ProviderName);
  629. }
  630. if (pObjectInfo->DisplayServerName) {
  631. dwPath += wcslen(pObjectInfo->DisplayServerName);
  632. }
  633. for (i=0;i<pObjectInfo->NumComponents;i++) {
  634. if (pObjectInfo->DisplayComponentArray[i].szComponent) {
  635. dwPath += wcslen(pObjectInfo->DisplayComponentArray[i].szComponent);
  636. }
  637. if (pObjectInfo->DisplayComponentArray[i].szValue) {
  638. dwPath += wcslen(pObjectInfo->DisplayComponentArray[i].szValue);
  639. }
  640. //
  641. // Add one for comma separator, one for equal sign
  642. //
  643. dwPath+=2;
  644. }
  645. return dwPath;
  646. }
  647. STDMETHODIMP
  648. CNWCOMPATNamespace::ConstructPath(
  649. PPATH_OBJECTINFO pObjectInfo,
  650. DWORD dwFormatType,
  651. DWORD dwFlag,
  652. DWORD dwEscapedMode,
  653. BSTR *pbstrADsPath
  654. )
  655. {
  656. HRESULT hr = S_OK;
  657. PWSTR szReturn = NULL;
  658. long cComponents;
  659. DWORD dwPath = 0;
  660. BOOL fEscaped = FALSE;
  661. switch (dwEscapedMode) {
  662. case ADS_ESCAPEDMODE_OFF:
  663. case ADS_ESCAPEDMODE_DEFAULT:
  664. case ADS_ESCAPEDMODE_OFF_EX:
  665. fEscaped = FALSE;
  666. break;
  667. case ADS_ESCAPEDMODE_ON:
  668. fEscaped = TRUE;
  669. break;
  670. default:
  671. hr = E_INVALIDARG;
  672. goto error;
  673. }
  674. if (!pbstrADsPath) {
  675. hr = E_INVALIDARG;
  676. goto error;
  677. }
  678. dwPath = CountPath(pObjectInfo);
  679. szReturn = (PWSTR)AllocADsMem((dwPath + 1)* sizeof(WCHAR));
  680. if (szReturn == NULL) {
  681. hr = E_OUTOFMEMORY;
  682. goto error;
  683. }
  684. _pObjectInfo = pObjectInfo;
  685. wcscpy(szReturn,TEXT(""));
  686. switch (dwFormatType) {
  687. case ADS_FORMAT_WINDOWS:
  688. case ADS_FORMAT_WINDOWS_NO_SERVER:
  689. if (dwEscapedMode == ADS_ESCAPEDMODE_DEFAULT) {
  690. fEscaped = TRUE;
  691. }
  692. if (!pObjectInfo->ProviderName) {
  693. hr = E_FAIL; // Need Error Code
  694. goto error;
  695. }
  696. wcscat(szReturn,pObjectInfo->ProviderName);
  697. wcscat(szReturn,TEXT("://"));
  698. if (dwFormatType == ADS_FORMAT_WINDOWS) {
  699. if (pObjectInfo->DisplayServerName && (*(pObjectInfo->DisplayServerName))) {
  700. wcscat(szReturn,pObjectInfo->DisplayServerName);
  701. if (pObjectInfo->NumComponents>0) {
  702. wcscat(szReturn,TEXT("/"));
  703. }
  704. }
  705. }
  706. hr = SetComponents(szReturn,
  707. TEXT("/"),
  708. ADS_COMPONENT_DN,
  709. fEscaped);
  710. BAIL_ON_FAILURE(hr);
  711. break;
  712. case ADS_FORMAT_WINDOWS_DN:
  713. hr = SetComponents(szReturn,
  714. TEXT("/"),
  715. ADS_COMPONENT_DN,
  716. fEscaped);
  717. BAIL_ON_FAILURE(hr);
  718. break;
  719. case ADS_FORMAT_WINDOWS_PARENT:
  720. hr = SetComponents(szReturn,
  721. TEXT("/"),
  722. ADS_COMPONENT_PARENT,
  723. fEscaped);
  724. BAIL_ON_FAILURE(hr);
  725. break;
  726. case ADS_FORMAT_X500:
  727. case ADS_FORMAT_X500_NO_SERVER:
  728. case ADS_FORMAT_X500_DN:
  729. case ADS_FORMAT_X500_PARENT:
  730. hr = E_NOTIMPL;
  731. BAIL_ON_FAILURE(hr);
  732. break;
  733. case ADS_FORMAT_LEAF:
  734. //
  735. // Reverse only if pathtype is X500. In that case, we need to get
  736. // the first element but not the last
  737. //
  738. hr = SetComponents(szReturn,
  739. NULL,
  740. ADS_COMPONENT_LEAF,
  741. fEscaped);
  742. BAIL_ON_FAILURE(hr);
  743. break;
  744. default:
  745. hr = E_INVALIDARG;
  746. goto error;
  747. }
  748. hr = ADsAllocString(szReturn, pbstrADsPath);
  749. error:
  750. if (szReturn) {
  751. FreeADsMem(szReturn);
  752. }
  753. RRETURN_EXP_IF_ERR(hr);
  754. }
  755. STDMETHODIMP
  756. CNWCOMPATNamespace::GetEscapedElement(
  757. LONG lnReserved,
  758. BSTR bstrInStr,
  759. BSTR* pbstrOutStr
  760. )
  761. {
  762. RRETURN(E_NOTIMPL);
  763. }