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.

1019 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. ULONG cchBuffer = 0;
  45. HRESULT hr = S_OK;
  46. *ppObject = NULL;
  47. if (!RelativeName || !*RelativeName) {
  48. RRETURN(E_ADS_UNKNOWN_OBJECT);
  49. }
  50. cchBuffer += wcslen(ADsPath);
  51. cchBuffer += (bNamespaceRelative ? 2 : 1);
  52. cchBuffer += wcslen(RelativeName);
  53. cchBuffer += ((ClassName && *ClassName) ? (1 + wcslen(ClassName)) : 0);
  54. if (cchBuffer >= MAX_PATH) {
  55. RRETURN(E_OUTOFMEMORY);
  56. }
  57. memset(szBuffer, 0, sizeof(szBuffer));
  58. wcscpy(szBuffer, ADsPath);
  59. if (bNamespaceRelative)
  60. wcscat(szBuffer, L"//");
  61. else
  62. wcscat(szBuffer, L"/");
  63. wcscat(szBuffer, RelativeName);
  64. if (ClassName && *ClassName) {
  65. wcscat(szBuffer,L",");
  66. wcscat(szBuffer, ClassName);
  67. }
  68. hr = ::GetObject(
  69. szBuffer,
  70. Credentials,
  71. (LPVOID *)ppObject
  72. );
  73. BAIL_ON_FAILURE(hr);
  74. error:
  75. RRETURN(hr);
  76. }
  77. //+---------------------------------------------------------------------------
  78. // Function: GetObject
  79. //
  80. // Synopsis: Called by ResolvePathName to return an object
  81. //
  82. // Arguments: [LPWSTR szBuffer]
  83. // [LPVOID *ppObject]
  84. //
  85. // Returns: HRESULT
  86. //
  87. // Modifies: -
  88. //
  89. // History: 11-3-95 krishnag Created.
  90. //
  91. //----------------------------------------------------------------------------
  92. HRESULT
  93. GetObject(
  94. LPWSTR szBuffer,
  95. CCredentials& Credentials,
  96. LPVOID * ppObject
  97. )
  98. {
  99. HRESULT hr;
  100. DWORD dwStatus = NO_ERROR;
  101. DWORD dwNumberEntries = 0;
  102. DWORD dwModificationTime = 0;
  103. WCHAR szObjectClassName[MAX_PATH];
  104. WCHAR szObjectFullName[MAX_PATH];
  105. LPWSTR pszNDSPath = NULL;
  106. WCHAR szParent[MAX_PATH];
  107. WCHAR szCommonName[MAX_PATH];
  108. HANDLE hObject = NULL;
  109. OBJECTINFO ObjectInfo;
  110. POBJECTINFO pObjectInfo = &ObjectInfo;
  111. CLexer Lexer(szBuffer);
  112. IADs * pADs = NULL;
  113. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  114. hr = ADsObject(&Lexer, pObjectInfo);
  115. BAIL_ON_FAILURE(hr);
  116. //
  117. // Validate that this ADs pathname is to be processed by
  118. // us - as in the provider name is @NDS!
  119. //
  120. hr = ValidateProvider(pObjectInfo);
  121. BAIL_ON_FAILURE(hr);
  122. hr = ValidateObjectType(pObjectInfo);
  123. switch (pObjectInfo->ObjectType) {
  124. case TOKEN_NAMESPACE:
  125. //
  126. // This means that this is a namespace object;
  127. // instantiate the namespace object
  128. //
  129. hr = GetNamespaceObject(
  130. pObjectInfo,
  131. Credentials,
  132. ppObject
  133. );
  134. BAIL_ON_FAILURE(hr);
  135. break;
  136. case TOKEN_SCHEMA:
  137. hr = GetSchemaObject(
  138. pObjectInfo,
  139. Credentials,
  140. ppObject
  141. );
  142. BAIL_ON_FAILURE(hr);
  143. break;
  144. default:
  145. hr = BuildNDSPathFromADsPath(
  146. szBuffer,
  147. &pszNDSPath
  148. );
  149. BAIL_ON_FAILURE(hr);
  150. dwStatus = ADsNwNdsOpenObject(
  151. pszNDSPath,
  152. Credentials,
  153. &hObject,
  154. szObjectFullName,
  155. szObjectClassName,
  156. &dwModificationTime,
  157. &dwNumberEntries
  158. );
  159. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  160. hr = BuildADsParentPath(
  161. szBuffer,
  162. szParent,
  163. szCommonName
  164. );
  165. BAIL_ON_FAILURE(hr);
  166. hr = CNDSGenObject::CreateGenericObject(
  167. szParent,
  168. szCommonName,
  169. szObjectClassName,
  170. Credentials,
  171. ADS_OBJECT_BOUND,
  172. IID_IADs,
  173. (void **)&pADs
  174. );
  175. BAIL_ON_FAILURE(hr);
  176. //
  177. // InstantiateDerivedObject should add-ref this pointer for us.
  178. //
  179. hr = InstantiateDerivedObject(
  180. pADs,
  181. Credentials,
  182. IID_IUnknown,
  183. (void **)ppObject
  184. );
  185. if (FAILED(hr)) {
  186. hr = pADs->QueryInterface(
  187. IID_IUnknown,
  188. ppObject
  189. );
  190. BAIL_ON_FAILURE(hr);
  191. }
  192. break;
  193. }
  194. error:
  195. if (hObject) {
  196. NwNdsCloseObject(hObject);
  197. }
  198. if (pszNDSPath) {
  199. FreeADsStr(pszNDSPath);
  200. }
  201. if (pADs) {
  202. pADs->Release();
  203. }
  204. FreeObjectInfo( &ObjectInfo );
  205. RRETURN(hr);
  206. }
  207. HRESULT
  208. BuildADsPathFromNDSPath(
  209. LPWSTR szNDSTreeName,
  210. LPWSTR szNDSDNName,
  211. LPWSTR szADsPathName
  212. )
  213. {
  214. PKEYDATA pKeyData = NULL;
  215. DWORD dwCount = 0;
  216. DWORD i = 0;
  217. LPWSTR pszDisplayTreeName = NULL;
  218. LPWSTR pszDisplayDNName = NULL;
  219. HRESULT hr = S_OK;
  220. if (!szNDSTreeName || !szNDSDNName) {
  221. RRETURN(E_FAIL);
  222. }
  223. hr = GetDisplayName(
  224. szNDSTreeName,
  225. &pszDisplayTreeName
  226. );
  227. BAIL_ON_FAILURE(hr);
  228. wsprintf(szADsPathName,L"%s:%s", szProviderName, szNDSTreeName);
  229. hr = GetDisplayName(
  230. szNDSDNName,
  231. &pszDisplayDNName
  232. );
  233. BAIL_ON_FAILURE(hr);
  234. pKeyData = CreateTokenList(
  235. pszDisplayDNName,
  236. L'.'
  237. );
  238. if (pKeyData) {
  239. dwCount = pKeyData->cTokens;
  240. for (i = 0; i < dwCount; i++) {
  241. wcscat(szADsPathName, L"/");
  242. wcscat(szADsPathName, pKeyData->pTokens[dwCount - 1 - i]);
  243. }
  244. }
  245. if (pKeyData) {
  246. FreeADsMem(pKeyData);
  247. }
  248. error:
  249. if (pszDisplayTreeName) {
  250. FreeADsMem(pszDisplayTreeName);
  251. }
  252. if (pszDisplayDNName) {
  253. FreeADsMem(pszDisplayDNName);
  254. }
  255. RRETURN(hr);
  256. }
  257. HRESULT
  258. BuildNDSPathFromADsPath(
  259. LPWSTR szADsPathName,
  260. LPWSTR * pszNDSPathName
  261. )
  262. {
  263. OBJECTINFO ObjectInfo;
  264. POBJECTINFO pObjectInfo = &ObjectInfo;
  265. CLexer Lexer(szADsPathName);
  266. DWORD i = 0;
  267. DWORD dwNumComponents = 0;
  268. HRESULT hr;
  269. LPWSTR szNDSPathName = NULL;
  270. *pszNDSPathName = NULL;
  271. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  272. hr = ADsObject(&Lexer, pObjectInfo);
  273. BAIL_ON_FAILURE(hr);
  274. dwNumComponents = pObjectInfo->NumComponents;
  275. szNDSPathName = AllocADsStr(szADsPathName);
  276. if (!szNDSPathName) {
  277. hr = E_OUTOFMEMORY;
  278. BAIL_ON_FAILURE(hr);
  279. }
  280. wcscpy(szNDSPathName, L"\\\\");
  281. wcscat(szNDSPathName, pObjectInfo->TreeName);
  282. if (dwNumComponents) {
  283. wcscat(szNDSPathName, L"\\");
  284. for (i = dwNumComponents; i > 0; i--) {
  285. AppendComponent(
  286. szNDSPathName,
  287. &(pObjectInfo->ComponentArray[i-1])
  288. );
  289. if ((i - 1) > 0){
  290. wcscat(szNDSPathName, L".");
  291. }
  292. }
  293. }
  294. *pszNDSPathName = szNDSPathName;
  295. error:
  296. FreeObjectInfo( &ObjectInfo );
  297. RRETURN(hr);
  298. }
  299. HRESULT
  300. AppendComponent(
  301. LPWSTR szNDSPathName,
  302. PCOMPONENT pComponent
  303. )
  304. {
  305. if (pComponent->szComponent && pComponent->szValue) {
  306. wcscat(szNDSPathName, pComponent->szComponent);
  307. wcscat(szNDSPathName,L"=");
  308. wcscat(szNDSPathName, pComponent->szValue);
  309. }else if (pComponent->szComponent && !pComponent->szValue) {
  310. wcscat(szNDSPathName, pComponent->szComponent);
  311. }else {
  312. //
  313. // we should never hit this case
  314. //
  315. }
  316. RRETURN(S_OK);
  317. }
  318. HRESULT
  319. BuildADsParentPath(
  320. LPWSTR szBuffer,
  321. LPWSTR szParent,
  322. LPWSTR szCommonName
  323. )
  324. {
  325. OBJECTINFO ObjectInfo;
  326. POBJECTINFO pObjectInfo = &ObjectInfo;
  327. CLexer Lexer(szBuffer);
  328. HRESULT hr = S_OK;
  329. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  330. hr = ADsObject(&Lexer, pObjectInfo);
  331. BAIL_ON_FAILURE(hr);
  332. hr = BuildADsParentPath(
  333. pObjectInfo,
  334. szParent,
  335. szCommonName
  336. );
  337. error:
  338. FreeObjectInfo( &ObjectInfo );
  339. RRETURN(hr);
  340. }
  341. //+---------------------------------------------------------------------------
  342. // Function: GetNamespaceObject
  343. //
  344. // Synopsis: called by GetObject
  345. //
  346. // Arguments: [POBJECTINFO pObjectInfo]
  347. // [LPVOID * ppObject]
  348. //
  349. // Returns: HRESULT
  350. //
  351. // Modifies: -
  352. //
  353. // History: 11-3-95 krishnag Created.
  354. //
  355. //----------------------------------------------------------------------------
  356. HRESULT
  357. GetNamespaceObject(
  358. POBJECTINFO pObjectInfo,
  359. CCredentials& Credentials,
  360. LPVOID * ppObject
  361. )
  362. {
  363. HRESULT hr;
  364. hr = ValidateNamespaceObject(
  365. pObjectInfo
  366. );
  367. BAIL_ON_FAILURE(hr);
  368. hr = CNDSNamespace::CreateNamespace(
  369. L"ADs:",
  370. L"NDS:",
  371. Credentials,
  372. ADS_OBJECT_BOUND,
  373. IID_IUnknown,
  374. ppObject
  375. );
  376. error:
  377. RRETURN(hr);
  378. }
  379. HRESULT
  380. ValidateNamespaceObject(
  381. POBJECTINFO pObjectInfo
  382. )
  383. {
  384. if (!_wcsicmp(pObjectInfo->ProviderName, szProviderName)) {
  385. RRETURN(S_OK);
  386. }
  387. RRETURN(E_FAIL);
  388. }
  389. HRESULT
  390. ValidateProvider(
  391. POBJECTINFO pObjectInfo
  392. )
  393. {
  394. //
  395. // The provider name is case-sensitive. This is a restriction that OLE
  396. // has put on us.
  397. //
  398. if (!(wcscmp(pObjectInfo->ProviderName, szProviderName))) {
  399. RRETURN(S_OK);
  400. }
  401. RRETURN(E_FAIL);
  402. }
  403. //+---------------------------------------------------------------------------
  404. // Function: GetSchemaObject
  405. //
  406. // Synopsis: called by GetObject
  407. //
  408. // Arguments: [POBJECTINFO pObjectInfo]
  409. // [LPVOID * ppObject]
  410. //
  411. // Returns: HRESULT
  412. //
  413. // Modifies: -
  414. //
  415. // History: 11-3-95 krishnag Created.
  416. //
  417. //----------------------------------------------------------------------------
  418. HRESULT
  419. GetSchemaObject(
  420. POBJECTINFO pObjectInfo,
  421. CCredentials& Credentials,
  422. LPVOID * ppObject
  423. )
  424. {
  425. HRESULT hr = S_OK;
  426. WCHAR szParent[MAX_PATH];
  427. WCHAR szCommonName[MAX_PATH];
  428. WCHAR szNDSPathName[MAX_PATH];
  429. DWORD dwObjectType = 0;
  430. DWORD dwStatus;
  431. HANDLE hTree = NULL;
  432. hr = ValidateSchemaObject(
  433. pObjectInfo,
  434. &dwObjectType
  435. );
  436. BAIL_ON_FAILURE(hr);
  437. hr = BuildADsParentPath(
  438. pObjectInfo,
  439. szParent,
  440. szCommonName
  441. );
  442. BAIL_ON_FAILURE(hr);
  443. switch(dwObjectType) {
  444. case NDS_CLASS_ID:
  445. case NDS_PROPERTY_ID:
  446. case NDS_CLASSPROP_ID:
  447. wcscpy(szNDSPathName, L"\\\\");
  448. wcscat(szNDSPathName, pObjectInfo->TreeName);
  449. dwStatus = ADsNwNdsOpenObject(
  450. szNDSPathName,
  451. Credentials,
  452. &hTree,
  453. NULL,
  454. NULL,
  455. NULL,
  456. NULL
  457. );
  458. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  459. break;
  460. default:
  461. break;
  462. }
  463. //
  464. // Note: The "error:" tag is at the end of the switch statement,
  465. // so we can simply break out.
  466. //
  467. switch (dwObjectType) {
  468. case NDS_SCHEMA_ID:
  469. hr = CNDSSchema::CreateSchema(
  470. szParent,
  471. szCommonName,
  472. Credentials,
  473. ADS_OBJECT_BOUND,
  474. IID_IUnknown,
  475. ppObject
  476. );
  477. break;
  478. case NDS_CLASSPROP_ID:
  479. hr = CNDSClass::CreateClass(
  480. szParent,
  481. szCommonName,
  482. hTree,
  483. Credentials,
  484. ADS_OBJECT_BOUND,
  485. IID_IUnknown,
  486. ppObject
  487. );
  488. if (FAILED(hr)) {
  489. hr = CNDSProperty::CreateProperty(
  490. szParent,
  491. szCommonName,
  492. hTree,
  493. Credentials,
  494. ADS_OBJECT_BOUND,
  495. IID_IUnknown,
  496. ppObject
  497. );
  498. BAIL_ON_FAILURE(hr);
  499. }
  500. break;
  501. case NDS_CLASS_ID:
  502. hr = CNDSClass::CreateClass(
  503. szParent,
  504. szCommonName,
  505. hTree,
  506. Credentials,
  507. ADS_OBJECT_BOUND,
  508. IID_IUnknown,
  509. ppObject
  510. );
  511. break;
  512. case NDS_PROPERTY_ID:
  513. hr = CNDSProperty::CreateProperty(
  514. szParent,
  515. szCommonName,
  516. hTree,
  517. Credentials,
  518. ADS_OBJECT_BOUND,
  519. IID_IUnknown,
  520. ppObject
  521. );
  522. break;
  523. default:
  524. hr = E_ADS_UNKNOWN_OBJECT;
  525. break;
  526. }
  527. error:
  528. if (hTree) {
  529. NwNdsCloseObject(hTree);
  530. }
  531. RRETURN(hr);
  532. }
  533. HRESULT
  534. ValidateSchemaObject(
  535. POBJECTINFO pObjectInfo,
  536. PDWORD pdwObjectType
  537. )
  538. {
  539. DWORD dwNumComponents = 0;
  540. dwNumComponents = pObjectInfo->NumComponents;
  541. switch (dwNumComponents) {
  542. case 1:
  543. if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent, L"schema")) {
  544. *pdwObjectType = NDS_SCHEMA_ID;
  545. RRETURN(S_OK);
  546. }
  547. break;
  548. case 2:
  549. if (pObjectInfo->ClassName) {
  550. if (!_wcsicmp(pObjectInfo->ClassName, L"Property")) {
  551. *pdwObjectType = NDS_PROPERTY_ID;
  552. }
  553. else {
  554. *pdwObjectType = NDS_CLASS_ID;
  555. }
  556. }
  557. else {
  558. *pdwObjectType = NDS_CLASSPROP_ID;
  559. }
  560. RRETURN(S_OK);
  561. /* if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent, L"schema")) {
  562. *pdwObjectType = NDS_CLASS_ID;
  563. RRETURN(S_OK);
  564. }
  565. break;
  566. case 3:
  567. if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,SCHEMA_NAME)) {
  568. *pdwObjectType = NDS_PROPERTY_ID;
  569. RRETURN(S_OK);
  570. }
  571. break; */
  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. }