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.

1092 lines
23 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: getobj.cxx
  7. //
  8. // Contents: Windows NT 3.5 GetObject functionality
  9. //
  10. // History:
  11. //----------------------------------------------------------------------------
  12. #include "nds.hxx"
  13. #pragma hdrstop
  14. extern LPWSTR szProviderName;
  15. //+---------------------------------------------------------------------------
  16. // Function: RelativeGetObject
  17. //
  18. // Synopsis: Gets object relative to given Active Directory path.
  19. //
  20. // Arguments: [BSTR ADsPath]
  21. // [BSTR ClassName]
  22. // [BSTR RelativeName]
  23. // [IUnknown** ppObject]
  24. // [BOOT bNamespaceRelative]
  25. //
  26. // Returns: HRESULT
  27. //
  28. // Modifies: *ppObject
  29. //
  30. // History: 08-02-96 t-danal Created as such.
  31. //
  32. //----------------------------------------------------------------------------
  33. HRESULT
  34. RelativeGetObject(
  35. BSTR ADsPath,
  36. BSTR ClassName,
  37. BSTR RelativeName,
  38. CCredentials& Credentials,
  39. IDispatch * FAR* ppObject,
  40. BOOL bNamespaceRelative
  41. )
  42. {
  43. WCHAR szBuffer[MAX_PATH];
  44. HRESULT hr = S_OK;
  45. *ppObject = NULL;
  46. if (!RelativeName || !*RelativeName) {
  47. RRETURN(E_ADS_UNKNOWN_OBJECT);
  48. }
  49. wcscpy(szBuffer, ADsPath);
  50. if (bNamespaceRelative)
  51. wcscat(szBuffer, L"//");
  52. else
  53. wcscat(szBuffer, L"/");
  54. wcscat(szBuffer, RelativeName);
  55. if (ClassName && *ClassName) {
  56. wcscat(szBuffer,L",");
  57. wcscat(szBuffer, ClassName);
  58. }
  59. hr = ::GetObject(
  60. szBuffer,
  61. Credentials,
  62. (LPVOID *)ppObject
  63. );
  64. BAIL_ON_FAILURE(hr);
  65. error:
  66. RRETURN(hr);
  67. }
  68. //+---------------------------------------------------------------------------
  69. // Function: GetObject
  70. //
  71. // Synopsis: Called by ResolvePathName to return an object
  72. //
  73. // Arguments: [LPWSTR szBuffer]
  74. // [LPVOID *ppObject]
  75. //
  76. // Returns: HRESULT
  77. //
  78. // Modifies: -
  79. //
  80. // History: 11-3-95 krishnag Created.
  81. //
  82. //----------------------------------------------------------------------------
  83. HRESULT
  84. GetObject(
  85. LPWSTR szBuffer,
  86. CCredentials& Credentials,
  87. LPVOID * ppObject
  88. )
  89. {
  90. HRESULT hr;
  91. DWORD dwStatus = NO_ERROR;
  92. LPWSTR pszNDSTreeName = NULL;
  93. LPWSTR pszNDSDn = NULL;
  94. WCHAR szParent[MAX_PATH];
  95. WCHAR szCommonName[MAX_PATH];
  96. LPWSTR pszObjectClassName = NULL;
  97. OBJECTINFO ObjectInfo;
  98. POBJECTINFO pObjectInfo = &ObjectInfo;
  99. CLexer Lexer(szBuffer);
  100. NDS_CONTEXT_HANDLE hADsContext = NULL;
  101. IADs * pADs = NULL;
  102. NWDSCCODE ccode;
  103. PNDS_CONTEXT pADsContext;
  104. NWDSContextHandle context;
  105. Object_Info_T ObjInfo;
  106. WCHAR ObjectDN[MAX_DN_CHARS+1];
  107. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  108. hr = ADsObject(&Lexer, pObjectInfo);
  109. BAIL_ON_FAILURE(hr);
  110. //
  111. // Validate that this ADs pathname is to be processed by
  112. // us - as in the provider name is @NDS!
  113. //
  114. hr = ValidateProvider(pObjectInfo);
  115. BAIL_ON_FAILURE(hr);
  116. hr = ValidateObjectType(pObjectInfo);
  117. switch (pObjectInfo->ObjectType) {
  118. case TOKEN_NAMESPACE:
  119. //
  120. // This means that this is a namespace object;
  121. // instantiate the namespace object
  122. //
  123. hr = GetNamespaceObject(
  124. pObjectInfo,
  125. Credentials,
  126. ppObject
  127. );
  128. BAIL_ON_FAILURE(hr);
  129. break;
  130. case TOKEN_SCHEMA:
  131. hr = GetSchemaObject(
  132. pObjectInfo,
  133. Credentials,
  134. ppObject
  135. );
  136. BAIL_ON_FAILURE(hr);
  137. break;
  138. default:
  139. hr = BuildNDSPathFromADsPath2(
  140. szBuffer,
  141. &pszNDSTreeName,
  142. &pszNDSDn
  143. );
  144. BAIL_ON_FAILURE(hr);
  145. hr = ADsNdsOpenContext(
  146. pszNDSTreeName,
  147. Credentials,
  148. &hADsContext
  149. );
  150. BAIL_ON_FAILURE(hr);
  151. pADsContext = (PNDS_CONTEXT) hADsContext;
  152. context = pADsContext->hContext;
  153. ccode = NWDSReadObjectInfo(
  154. context,
  155. (pnstr8) (!pszNDSDn || (*pszNDSDn == L'\0') ? L"[Root]" : pszNDSDn),
  156. (pnstr8) ObjectDN,
  157. &ObjInfo);
  158. CHECK_AND_SET_EXTENDED_ERROR(ccode, hr);
  159. pszObjectClassName = (LPWSTR) ObjInfo.baseClass;
  160. if (!pszObjectClassName) {
  161. BAIL_ON_FAILURE(E_FAIL);
  162. }
  163. hr = BuildADsParentPath(
  164. szBuffer,
  165. szParent,
  166. szCommonName
  167. );
  168. BAIL_ON_FAILURE(hr);
  169. hr = CNDSGenObject::CreateGenericObject(
  170. szParent,
  171. szCommonName,
  172. pszObjectClassName,
  173. Credentials,
  174. ADS_OBJECT_BOUND,
  175. IID_IADs,
  176. (void **)&pADs
  177. );
  178. BAIL_ON_FAILURE(hr);
  179. // InstantiateDerivedObject should add-ref this pointer for us.
  180. //
  181. hr = InstantiateDerivedObject(
  182. pADs,
  183. Credentials,
  184. IID_IUnknown,
  185. (void **)ppObject
  186. );
  187. if (FAILED(hr)) {
  188. hr = pADs->QueryInterface(
  189. IID_IUnknown,
  190. ppObject
  191. );
  192. BAIL_ON_FAILURE(hr);
  193. }
  194. break;
  195. }
  196. error:
  197. if (pszNDSTreeName) {
  198. FreeADsStr(pszNDSTreeName);
  199. }
  200. if (pszNDSDn) {
  201. FreeADsStr(pszNDSDn);
  202. }
  203. if (pADs) {
  204. pADs->Release();
  205. }
  206. if (hADsContext) {
  207. ADsNdsCloseContext( hADsContext );
  208. }
  209. FreeObjectInfo( &ObjectInfo );
  210. RRETURN(hr);
  211. }
  212. HRESULT
  213. BuildADsPathFromNDSPath(
  214. LPWSTR szNDSTreeName,
  215. LPWSTR szNDSDNName,
  216. LPWSTR *ppszADsPath
  217. )
  218. {
  219. PKEYDATA pKeyData = NULL;
  220. DWORD dwCount = 0;
  221. DWORD i = 0;
  222. LPWSTR pszDisplayTreeName = NULL;
  223. LPWSTR pszDisplayDNName = NULL;
  224. LPWSTR pszTemp = NULL;
  225. HRESULT hr = S_OK;
  226. if (!szNDSTreeName || !szNDSDNName || !ppszADsPath) {
  227. RRETURN(E_FAIL);
  228. }
  229. *ppszADsPath = NULL;
  230. hr = GetDisplayName(
  231. szNDSTreeName,
  232. &pszDisplayTreeName
  233. );
  234. BAIL_ON_FAILURE(hr);
  235. pszTemp = (LPWSTR) AllocADsMem(
  236. (wcslen(szProviderName) +
  237. wcslen(L"://") +
  238. wcslen(szNDSTreeName) +
  239. wcslen(L"/") +
  240. wcslen(szNDSDNName) +
  241. 1) * sizeof(WCHAR)
  242. );
  243. if (!pszTemp) {
  244. BAIL_ON_FAILURE(hr);
  245. }
  246. wsprintf(pszTemp,L"%s://%s", szProviderName, szNDSTreeName);
  247. hr = GetDisplayName(
  248. szNDSDNName,
  249. &pszDisplayDNName
  250. );
  251. BAIL_ON_FAILURE(hr);
  252. pKeyData = CreateTokenList(
  253. pszDisplayDNName,
  254. L'.'
  255. );
  256. if (pKeyData) {
  257. dwCount = pKeyData->cTokens;
  258. for (i = 0; i < dwCount; i++) {
  259. wcscat(pszTemp, L"/");
  260. wcscat(pszTemp, pKeyData->pTokens[dwCount - 1 - i]);
  261. }
  262. }
  263. if (pKeyData) {
  264. FreeADsMem(pKeyData);
  265. }
  266. *ppszADsPath = pszTemp;
  267. error:
  268. if (pszDisplayTreeName) {
  269. FreeADsMem(pszDisplayTreeName);
  270. }
  271. if (pszDisplayDNName) {
  272. FreeADsMem(pszDisplayDNName);
  273. }
  274. RRETURN(hr);
  275. }
  276. HRESULT
  277. BuildNDSPathFromADsPath(
  278. LPWSTR szADsPathName,
  279. LPWSTR * pszNDSPathName
  280. )
  281. {
  282. OBJECTINFO ObjectInfo;
  283. POBJECTINFO pObjectInfo = &ObjectInfo;
  284. CLexer Lexer(szADsPathName);
  285. DWORD i = 0;
  286. DWORD dwNumComponents = 0;
  287. HRESULT hr;
  288. LPWSTR szNDSPathName = NULL;
  289. *pszNDSPathName = NULL;
  290. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  291. hr = ADsObject(&Lexer, pObjectInfo);
  292. BAIL_ON_FAILURE(hr);
  293. dwNumComponents = pObjectInfo->NumComponents;
  294. szNDSPathName = AllocADsStr(szADsPathName);
  295. if (!szNDSPathName) {
  296. hr = E_OUTOFMEMORY;
  297. BAIL_ON_FAILURE(hr);
  298. }
  299. wcscpy(szNDSPathName, L"\\\\");
  300. wcscat(szNDSPathName, pObjectInfo->TreeName);
  301. if (dwNumComponents) {
  302. wcscat(szNDSPathName, L"\\");
  303. for (i = dwNumComponents; i > 0; i--) {
  304. AppendComponent(
  305. szNDSPathName,
  306. &(pObjectInfo->ComponentArray[i-1])
  307. );
  308. if ((i - 1) > 0){
  309. wcscat(szNDSPathName, L".");
  310. }
  311. }
  312. }
  313. *pszNDSPathName = szNDSPathName;
  314. error:
  315. FreeObjectInfo( &ObjectInfo );
  316. RRETURN(hr);
  317. }
  318. HRESULT
  319. AppendComponent(
  320. LPWSTR szNDSPathName,
  321. PCOMPONENT pComponent
  322. )
  323. {
  324. if (pComponent->szComponent && pComponent->szValue) {
  325. wcscat(szNDSPathName, pComponent->szComponent);
  326. wcscat(szNDSPathName,L"=");
  327. wcscat(szNDSPathName, pComponent->szValue);
  328. }else if (pComponent->szComponent && !pComponent->szValue) {
  329. wcscat(szNDSPathName, pComponent->szComponent);
  330. }else {
  331. //
  332. // we should never hit this case
  333. //
  334. }
  335. RRETURN(S_OK);
  336. }
  337. HRESULT
  338. BuildADsParentPath(
  339. LPWSTR szBuffer,
  340. LPWSTR szParent,
  341. LPWSTR szCommonName
  342. )
  343. {
  344. OBJECTINFO ObjectInfo;
  345. POBJECTINFO pObjectInfo = &ObjectInfo;
  346. CLexer Lexer(szBuffer);
  347. HRESULT hr = S_OK;
  348. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  349. hr = ADsObject(&Lexer, pObjectInfo);
  350. BAIL_ON_FAILURE(hr);
  351. hr = BuildADsParentPath(
  352. pObjectInfo,
  353. szParent,
  354. szCommonName
  355. );
  356. error:
  357. FreeObjectInfo( &ObjectInfo );
  358. RRETURN(hr);
  359. }
  360. //+---------------------------------------------------------------------------
  361. // Function: GetNamespaceObject
  362. //
  363. // Synopsis: called by GetObject
  364. //
  365. // Arguments: [POBJECTINFO pObjectInfo]
  366. // [LPVOID * ppObject]
  367. //
  368. // Returns: HRESULT
  369. //
  370. // Modifies: -
  371. //
  372. // History: 11-3-95 krishnag Created.
  373. //
  374. //----------------------------------------------------------------------------
  375. HRESULT
  376. GetNamespaceObject(
  377. POBJECTINFO pObjectInfo,
  378. CCredentials& Credentials,
  379. LPVOID * ppObject
  380. )
  381. {
  382. HRESULT hr;
  383. hr = ValidateNamespaceObject(
  384. pObjectInfo
  385. );
  386. BAIL_ON_FAILURE(hr);
  387. hr = CNDSNamespace::CreateNamespace(
  388. L"ADs:",
  389. L"NDS:",
  390. Credentials,
  391. ADS_OBJECT_BOUND,
  392. IID_IUnknown,
  393. ppObject
  394. );
  395. error:
  396. RRETURN(hr);
  397. }
  398. HRESULT
  399. ValidateNamespaceObject(
  400. POBJECTINFO pObjectInfo
  401. )
  402. {
  403. if (!_wcsicmp(pObjectInfo->ProviderName, szProviderName)) {
  404. RRETURN(S_OK);
  405. }
  406. RRETURN(E_FAIL);
  407. }
  408. HRESULT
  409. ValidateProvider(
  410. POBJECTINFO pObjectInfo
  411. )
  412. {
  413. //
  414. // The provider name is case-sensitive. This is a restriction that OLE
  415. // has put on us.
  416. //
  417. if (!(wcscmp(pObjectInfo->ProviderName, szProviderName))) {
  418. RRETURN(S_OK);
  419. }
  420. RRETURN(E_FAIL);
  421. }
  422. //+---------------------------------------------------------------------------
  423. // Function: GetSchemaObject
  424. //
  425. // Synopsis: called by GetObject
  426. //
  427. // Arguments: [POBJECTINFO pObjectInfo]
  428. // [LPVOID * ppObject]
  429. //
  430. // Returns: HRESULT
  431. //
  432. // Modifies: -
  433. //
  434. // History: 11-3-95 krishnag Created.
  435. //
  436. //----------------------------------------------------------------------------
  437. HRESULT
  438. GetSchemaObject(
  439. POBJECTINFO pObjectInfo,
  440. CCredentials& Credentials,
  441. LPVOID * ppObject
  442. )
  443. {
  444. HRESULT hr = S_OK;
  445. DWORD dwObjectType = 0;
  446. WCHAR szParent[MAX_PATH];
  447. WCHAR szCommonName[MAX_PATH];
  448. NDS_CONTEXT_HANDLE hADsContext = NULL;
  449. hr = ValidateSchemaObject(
  450. pObjectInfo,
  451. &dwObjectType
  452. );
  453. BAIL_ON_FAILURE(hr);
  454. hr = BuildADsParentPath(
  455. pObjectInfo,
  456. szParent,
  457. szCommonName
  458. );
  459. BAIL_ON_FAILURE(hr);
  460. switch(dwObjectType) {
  461. case NDS_CLASS_ID:
  462. case NDS_PROPERTY_ID:
  463. case NDS_CLASSPROP_ID:
  464. hr = ADsNdsOpenContext(
  465. pObjectInfo->TreeName,
  466. Credentials,
  467. &hADsContext
  468. );
  469. BAIL_ON_FAILURE(hr);
  470. break;
  471. default:
  472. break;
  473. }
  474. //
  475. // Note: The "error:" tag is at the end of the switch statement,
  476. // so we can simply break out.
  477. //
  478. switch (dwObjectType) {
  479. case NDS_SCHEMA_ID:
  480. hr = CNDSSchema::CreateSchema(
  481. szParent,
  482. szCommonName,
  483. Credentials,
  484. ADS_OBJECT_BOUND,
  485. IID_IUnknown,
  486. ppObject
  487. );
  488. break;
  489. case NDS_CLASSPROP_ID:
  490. hr = CNDSClass::CreateClass(
  491. szParent,
  492. szCommonName,
  493. hADsContext,
  494. Credentials,
  495. ADS_OBJECT_BOUND,
  496. IID_IUnknown,
  497. ppObject
  498. );
  499. if (FAILED(hr)) {
  500. hr = CNDSProperty::CreateProperty(
  501. szParent,
  502. szCommonName,
  503. hADsContext,
  504. Credentials,
  505. ADS_OBJECT_BOUND,
  506. IID_IUnknown,
  507. ppObject
  508. );
  509. BAIL_ON_FAILURE(hr);
  510. }
  511. break;
  512. case NDS_CLASS_ID:
  513. hr = CNDSClass::CreateClass(
  514. szParent,
  515. szCommonName,
  516. hADsContext,
  517. Credentials,
  518. ADS_OBJECT_BOUND,
  519. IID_IUnknown,
  520. ppObject
  521. );
  522. break;
  523. case NDS_PROPERTY_ID:
  524. hr = CNDSProperty::CreateProperty(
  525. szParent,
  526. szCommonName,
  527. hADsContext,
  528. Credentials,
  529. ADS_OBJECT_BOUND,
  530. IID_IUnknown,
  531. ppObject
  532. );
  533. break;
  534. default:
  535. hr = E_ADS_UNKNOWN_OBJECT;
  536. break;
  537. }
  538. error:
  539. if (hADsContext) {
  540. ADsNdsCloseContext(hADsContext);
  541. }
  542. RRETURN(hr);
  543. }
  544. HRESULT
  545. ValidateSchemaObject(
  546. POBJECTINFO pObjectInfo,
  547. PDWORD pdwObjectType
  548. )
  549. {
  550. DWORD dwNumComponents = 0;
  551. dwNumComponents = pObjectInfo->NumComponents;
  552. switch (dwNumComponents) {
  553. case 1:
  554. if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent, L"schema")) {
  555. *pdwObjectType = NDS_SCHEMA_ID;
  556. RRETURN(S_OK);
  557. }
  558. break;
  559. case 2:
  560. if (pObjectInfo->ClassName) {
  561. if (!_wcsicmp(pObjectInfo->ClassName, L"Property")) {
  562. *pdwObjectType = NDS_PROPERTY_ID;
  563. }
  564. else {
  565. *pdwObjectType = NDS_CLASS_ID;
  566. }
  567. }
  568. else {
  569. *pdwObjectType = NDS_CLASSPROP_ID;
  570. }
  571. RRETURN(S_OK);
  572. default:
  573. break;
  574. }
  575. RRETURN(E_FAIL);
  576. }
  577. HRESULT
  578. BuildADsParentPath(
  579. POBJECTINFO pObjectInfo,
  580. LPWSTR szParent,
  581. LPWSTR szCommonName
  582. )
  583. {
  584. DWORD i = 0;
  585. DWORD dwNumComponents = 0;
  586. HRESULT hr;
  587. dwNumComponents = pObjectInfo->NumComponents;
  588. if (!dwNumComponents && !pObjectInfo->DisplayTreeName) {
  589. //
  590. // There are no CNs in this pathname and
  591. // no tree name specified. This is the
  592. // namespace object - its parent is the
  593. // @ADs! object
  594. //
  595. wsprintf(szParent,L"ADs:");
  596. RRETURN(S_OK);
  597. } else if (!dwNumComponents && pObjectInfo->DisplayTreeName) {
  598. //
  599. // There are no CNs in this pathname and a tree
  600. // name has been specified. This is the root
  601. // object - its parent is the @NDS! object
  602. wsprintf(szParent, L"%s:", pObjectInfo->ProviderName);
  603. //
  604. // And the common name is the TreeName. Remember the
  605. // "//" will be added on when we reconstruct the full
  606. // pathname
  607. //
  608. wsprintf(szCommonName,L"%s", pObjectInfo->DisplayTreeName);
  609. RRETURN(S_OK);
  610. }else {
  611. //
  612. // There are one or more CNs, a tree name has been
  613. // specified. In the worst case the parent is the
  614. // root object. In the best case a long CN.
  615. //
  616. wsprintf(
  617. szParent, L"%s://%s",
  618. pObjectInfo->ProviderName,
  619. pObjectInfo->DisplayTreeName
  620. );
  621. for (i = 0; i < dwNumComponents - 1; i++) {
  622. wcscat(szParent, L"/");
  623. AppendComponent(szParent, &(pObjectInfo->DisplayComponentArray[i]));
  624. }
  625. //
  626. // And the common name is the last component
  627. //
  628. szCommonName[0] = '\0';
  629. AppendComponent(szCommonName, &(pObjectInfo->DisplayComponentArray[dwNumComponents-1]));
  630. }
  631. RRETURN(S_OK);
  632. }
  633. HRESULT
  634. ValidateObjectType(
  635. POBJECTINFO pObjectInfo
  636. )
  637. {
  638. pObjectInfo->ObjectType = TOKEN_NDSOBJECT;
  639. if (pObjectInfo->ProviderName && !pObjectInfo->TreeName
  640. && !pObjectInfo->NumComponents) {
  641. pObjectInfo->ObjectType = TOKEN_NAMESPACE;
  642. }else if (pObjectInfo->ProviderName && pObjectInfo->TreeName
  643. && pObjectInfo->NumComponents) {
  644. if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,L"schema")) {
  645. pObjectInfo->ObjectType = TOKEN_SCHEMA;
  646. }
  647. }
  648. RRETURN(S_OK);
  649. }
  650. HRESULT
  651. BuildNDSTreeNameFromADsPath(
  652. LPWSTR szBuffer,
  653. LPWSTR szNDSTreeName
  654. )
  655. {
  656. OBJECTINFO ObjectInfo;
  657. POBJECTINFO pObjectInfo = &ObjectInfo;
  658. CLexer Lexer(szBuffer);
  659. DWORD dwNumComponents = 0;
  660. HRESULT hr;
  661. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  662. hr = ADsObject(&Lexer, pObjectInfo);
  663. BAIL_ON_FAILURE(hr);
  664. dwNumComponents = pObjectInfo->NumComponents;
  665. if (!dwNumComponents && !pObjectInfo->TreeName) {
  666. //
  667. // There are no CNs in this pathname and
  668. // no tree name specified. This is the
  669. // namespace object - its parent is the
  670. // @ADs! object
  671. //
  672. hr = E_FAIL;
  673. } else if (!dwNumComponents && pObjectInfo->TreeName) {
  674. //
  675. // There are no CNs in this pathname and a tree
  676. // name has been specified. This is the root
  677. // object - its parent is the @NDS! object
  678. wsprintf(szNDSTreeName,L"\\\\%s", pObjectInfo->TreeName);
  679. hr = S_OK;
  680. }else {
  681. //
  682. // There are one or more CNs, a tree name has been
  683. // specified. In the worst case the parent is the
  684. // root object. In the best case a long CN.
  685. //
  686. wsprintf(szNDSTreeName,L"\\\\%s", pObjectInfo->TreeName);
  687. hr = S_OK;
  688. }
  689. error:
  690. FreeObjectInfo( &ObjectInfo );
  691. RRETURN(hr);
  692. }
  693. HRESULT
  694. BuildNDSPathFromADsPath(
  695. LPWSTR szADsPathName,
  696. LPWSTR szNDSTreeName,
  697. LPWSTR szNDSPathName
  698. )
  699. {
  700. OBJECTINFO ObjectInfo;
  701. POBJECTINFO pObjectInfo = &ObjectInfo;
  702. CLexer Lexer(szADsPathName);
  703. DWORD i = 0;
  704. DWORD dwNumComponents = 0;
  705. HRESULT hr;
  706. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  707. hr = ADsObject(&Lexer, pObjectInfo);
  708. BAIL_ON_FAILURE(hr);
  709. dwNumComponents = pObjectInfo->NumComponents;
  710. wcscpy(szNDSTreeName, L"\\\\");
  711. wcscat(szNDSTreeName, pObjectInfo->TreeName);
  712. *szNDSPathName = L'\0';
  713. if (dwNumComponents) {
  714. for (i = dwNumComponents; i > 0; i--) {
  715. AppendComponent(
  716. szNDSPathName,
  717. &(pObjectInfo->ComponentArray[i-1])
  718. );
  719. if ((i - 1) > 0){
  720. wcscat(szNDSPathName, L".");
  721. }
  722. }
  723. }
  724. error:
  725. FreeObjectInfo( &ObjectInfo );
  726. RRETURN(hr);
  727. }
  728. VOID
  729. FreeObjectInfo(
  730. POBJECTINFO pObjectInfo
  731. )
  732. {
  733. if ( !pObjectInfo )
  734. return;
  735. FreeADsStr( pObjectInfo->ProviderName );
  736. FreeADsStr( pObjectInfo->TreeName );
  737. FreeADsStr( pObjectInfo->DisplayTreeName );
  738. FreeADsStr( pObjectInfo->ClassName);
  739. for ( DWORD i = 0; i < pObjectInfo->NumComponents; i++ ) {
  740. FreeADsStr( pObjectInfo->ComponentArray[i].szComponent );
  741. FreeADsStr( pObjectInfo->ComponentArray[i].szValue );
  742. FreeADsStr( pObjectInfo->DisplayComponentArray[i].szComponent );
  743. FreeADsStr( pObjectInfo->DisplayComponentArray[i].szValue );
  744. }
  745. // We don't need to free pObjectInfo since the object is always a static
  746. // variable on the stack.
  747. }
  748. HRESULT
  749. GetDisplayName(
  750. LPWSTR szName,
  751. LPWSTR *ppszDisplayName
  752. )
  753. {
  754. HRESULT hr = S_OK;
  755. DWORD len = 0;
  756. LPWSTR pch = szName;
  757. LPWSTR pszDisplayCh = NULL, pszDisplay = NULL;
  758. BOOL fQuotingOn = FALSE;
  759. if (!ppszDisplayName ) {
  760. RRETURN (E_INVALIDARG);
  761. }
  762. *ppszDisplayName = NULL;
  763. if (!szName) {
  764. RRETURN (S_OK);
  765. }
  766. pch = szName;
  767. fQuotingOn = FALSE;
  768. for (len=0; *pch; pch++, len++) {
  769. if ((!(pch > szName && *(pch-1) == '\\')) &&
  770. (*pch == L'"') ) {
  771. fQuotingOn = ~fQuotingOn;
  772. }
  773. else if (!fQuotingOn && (!(pch > szName && *(pch-1) == '\\')) &&
  774. (*pch == L'/' || *pch == L'<' || *pch == L'>') ) {
  775. len++;
  776. }
  777. }
  778. pszDisplay = (LPWSTR) AllocADsMem((len+1) * sizeof(WCHAR));
  779. if (!pszDisplay) {
  780. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  781. }
  782. pch = szName;
  783. pszDisplayCh = pszDisplay;
  784. fQuotingOn = FALSE;
  785. for (; *pch; pch++, pszDisplayCh++) {
  786. if ((!(pch > szName && *(pch-1) == '\\')) &&
  787. (*pch == L'"') ) {
  788. fQuotingOn = ~fQuotingOn;
  789. }
  790. else if (!fQuotingOn && (!(pch > szName && *(pch-1) == '\\')) &&
  791. (*pch == L'/' || *pch == L'<' || *pch == L'>') ) {
  792. *pszDisplayCh++ = L'\\';
  793. }
  794. *pszDisplayCh = *pch;
  795. }
  796. *pszDisplayCh = L'\0';
  797. *ppszDisplayName = pszDisplay;
  798. error:
  799. RRETURN(hr);
  800. }
  801. HRESULT
  802. BuildNDSPathFromADsPath2(
  803. LPWSTR szADsPathName,
  804. LPWSTR * pszTreeName,
  805. LPWSTR * pszDn
  806. )
  807. {
  808. OBJECTINFO ObjectInfo;
  809. POBJECTINFO pObjectInfo = &ObjectInfo;
  810. CLexer Lexer(szADsPathName);
  811. DWORD i = 0;
  812. DWORD dwNumComponents = 0;
  813. HRESULT hr;
  814. LPWSTR szTreeName = NULL;
  815. LPWSTR szDn = NULL;
  816. *pszTreeName = NULL;
  817. *pszDn = NULL;
  818. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  819. hr = ADsObject(&Lexer, pObjectInfo);
  820. BAIL_ON_FAILURE(hr);
  821. dwNumComponents = pObjectInfo->NumComponents;
  822. szTreeName = AllocADsStr(pObjectInfo->TreeName);
  823. szDn = AllocADsStr(szADsPathName);
  824. szDn[0] = L'\0';
  825. if (!szDn) {
  826. hr = E_OUTOFMEMORY;
  827. BAIL_ON_FAILURE(hr);
  828. }
  829. if (dwNumComponents) {
  830. for (i = dwNumComponents; i > 0; i--) {
  831. AppendComponent(
  832. szDn,
  833. &(pObjectInfo->ComponentArray[i-1])
  834. );
  835. if ((i - 1) > 0){
  836. wcscat(szDn, L".");
  837. }
  838. }
  839. }
  840. *pszTreeName = szTreeName;
  841. *pszDn = szDn;
  842. error:
  843. FreeObjectInfo( &ObjectInfo );
  844. RRETURN(hr);
  845. }