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.

1129 lines
23 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cPathname.cxx
  7. //
  8. // Contents: Pathname object
  9. //
  10. // History: 11-1-95 krishnag Created.
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "ldap.hxx"
  14. #pragma hdrstop
  15. #define DEFAULT_NC _T(LDAP_OPATT_DEFAULT_NAMING_CONTEXT)
  16. #define SCHEMA_NC _T(LDAP_OPATT_SCHEMA_NAMING_CONTEXT)
  17. CRITICAL_SECTION g_SystemAPICritSect;
  18. #define ENTER_SYSTEMAPI_CRITICAL_SECTION() EnterCriticalSection(&g_SystemAPICritSect);
  19. #define LEAVE_SYSTEMAPI_CRITICAL_SECTION() LeaveCriticalSection(&g_SystemAPICritSect);
  20. HANDLE g_hSecur32Dll = NULL;
  21. // Class CADSystemInfo
  22. DEFINE_IDispatch_Implementation(CADSystemInfo)
  23. //+---------------------------------------------------------------------------
  24. // Function: CADSystemInfo::CADSystemInfo
  25. //
  26. // Synopsis: Constructor
  27. //
  28. // Arguments:
  29. //
  30. // Returns: HRESULT
  31. //
  32. // Modifies: -
  33. //
  34. // History:
  35. //
  36. //----------------------------------------------------------------------------
  37. CADSystemInfo::CADSystemInfo():
  38. _pDispMgr(NULL),
  39. _hSecur32(NULL),
  40. _Secur32LoadAttempted(FALSE),
  41. _hNetApi32(NULL),
  42. _NetApi32LoadAttempted(FALSE)
  43. {
  44. ENLIST_TRACKING(CADSystemInfo);
  45. }
  46. //+---------------------------------------------------------------------------
  47. // Function: CADSystemInfo::CreateADSystemInfo
  48. //
  49. // Synopsis:
  50. //
  51. // Arguments:
  52. //
  53. // Returns: HRESULT
  54. //
  55. // Modifies: -
  56. //
  57. // History:
  58. //
  59. //----------------------------------------------------------------------------
  60. HRESULT
  61. CADSystemInfo::CreateADSystemInfo(
  62. REFIID riid,
  63. void **ppvObj
  64. )
  65. {
  66. CADSystemInfo FAR * pADSystemInfo = NULL;
  67. HRESULT hr = S_OK;
  68. hr = AllocateADSystemInfoObject(&pADSystemInfo);
  69. BAIL_ON_FAILURE(hr);
  70. hr = pADSystemInfo->QueryInterface(riid, ppvObj);
  71. BAIL_ON_FAILURE(hr);
  72. pADSystemInfo->Release();
  73. RRETURN(hr);
  74. error:
  75. delete pADSystemInfo;
  76. RRETURN(hr);
  77. }
  78. //+---------------------------------------------------------------------------
  79. // Function: CADSystemInfo::~CADSystemInfo
  80. //
  81. // Synopsis:
  82. //
  83. // Arguments:
  84. //
  85. // Returns: HRESULT
  86. //
  87. // Modifies: -
  88. //
  89. // History:
  90. //
  91. //----------------------------------------------------------------------------
  92. CADSystemInfo::~CADSystemInfo( )
  93. {
  94. delete _pDispMgr;
  95. if (_hSecur32)
  96. FreeLibrary(_hSecur32);
  97. if (_hNetApi32)
  98. FreeLibrary(_hNetApi32);
  99. }
  100. //+---------------------------------------------------------------------------
  101. // Function: CADSystemInfo::QueryInterface
  102. //
  103. // Synopsis:
  104. //
  105. // Arguments:
  106. //
  107. // Returns: HRESULT
  108. //
  109. // Modifies: -
  110. //
  111. // History:
  112. //
  113. //----------------------------------------------------------------------------
  114. STDMETHODIMP
  115. CADSystemInfo::QueryInterface(
  116. REFIID iid,
  117. LPVOID FAR* ppv
  118. )
  119. {
  120. if (ppv == NULL) {
  121. RRETURN(E_POINTER);
  122. }
  123. if (IsEqualIID(iid, IID_IUnknown))
  124. {
  125. *ppv = (IADsADSystemInfo FAR *) this;
  126. }
  127. else if (IsEqualIID(iid, IID_IADsADSystemInfo))
  128. {
  129. *ppv = (IADsADSystemInfo FAR *) this;
  130. }
  131. else if (IsEqualIID(iid, IID_IDispatch))
  132. {
  133. *ppv = (IADsADSystemInfo FAR *) this;
  134. }
  135. else if (IsEqualIID(iid, IID_ISupportErrorInfo))
  136. {
  137. *ppv = (ISupportErrorInfo FAR *) this;
  138. }
  139. else
  140. {
  141. *ppv = NULL;
  142. return E_NOINTERFACE;
  143. }
  144. AddRef();
  145. return NOERROR;
  146. }
  147. //+---------------------------------------------------------------------------
  148. // Function: CADSystemInfo::AllocateADSystemInfoObject
  149. //
  150. // Synopsis:
  151. //
  152. // Arguments:
  153. //
  154. // Returns: HRESULT
  155. //
  156. // Modifies: -
  157. //
  158. // History:
  159. //
  160. //----------------------------------------------------------------------------
  161. HRESULT
  162. CADSystemInfo::AllocateADSystemInfoObject(
  163. CADSystemInfo ** ppADSystemInfo
  164. )
  165. {
  166. CADSystemInfo FAR * pADSystemInfo = NULL;
  167. CAggregatorDispMgr FAR * pDispMgr = NULL;
  168. HRESULT hr = S_OK;
  169. pADSystemInfo = new CADSystemInfo();
  170. if (pADSystemInfo == NULL) {
  171. hr = E_OUTOFMEMORY;
  172. }
  173. BAIL_ON_FAILURE(hr);
  174. pDispMgr = new CAggregatorDispMgr;
  175. if (pDispMgr == NULL) {
  176. hr = E_OUTOFMEMORY;
  177. }
  178. BAIL_ON_FAILURE(hr);
  179. hr = LoadTypeInfoEntry(
  180. pDispMgr,
  181. LIBID_ADs,
  182. IID_IADsADSystemInfo,
  183. (IADsADSystemInfo *)pADSystemInfo,
  184. DISPID_REGULAR
  185. );
  186. BAIL_ON_FAILURE(hr);
  187. pADSystemInfo->_pDispMgr = pDispMgr;
  188. *ppADSystemInfo = pADSystemInfo;
  189. RRETURN(hr);
  190. error:
  191. delete pADSystemInfo;
  192. delete pDispMgr;
  193. RRETURN_EXP_IF_ERR(hr);
  194. }
  195. //+---------------------------------------------------------------------------
  196. // Function: CADSystemInfo::InterfaceSupportsErrorInfo
  197. //
  198. // Synopsis:
  199. //
  200. // Arguments:
  201. //
  202. // Returns: HRESULT
  203. //
  204. // Modifies: -
  205. //
  206. // History:
  207. //
  208. //----------------------------------------------------------------------------
  209. HRESULT
  210. CADSystemInfo::InterfaceSupportsErrorInfo(THIS_ REFIID riid)
  211. {
  212. if (IsEqualIID(riid, IID_IADsADSystemInfo)) {
  213. RRETURN(S_OK);
  214. } else {
  215. RRETURN(S_FALSE);
  216. }
  217. }
  218. HRESULT
  219. CADSystemInfo::get_UserName(
  220. BSTR * bstrUserName
  221. )
  222. {
  223. PWSTR pszUserDN = NULL;
  224. ULONG uLength;
  225. GETUSERNAMEEX pGetUserNameEx;
  226. HRESULT hr;
  227. HINSTANCE hModule;
  228. //
  229. // Validate parameters
  230. //
  231. if ( !bstrUserName )
  232. {
  233. RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
  234. }
  235. //
  236. // Get handle to secur32.dll, and get required entry point
  237. //
  238. hr = GetSecur32Handle(&hModule);
  239. BAIL_ON_FAILURE(hr);
  240. pGetUserNameEx = (GETUSERNAMEEX) GetProcAddress(hModule, "GetUserNameExW");
  241. if (!pGetUserNameEx)
  242. {
  243. RRETURN(E_FAIL);
  244. }
  245. //
  246. // Get length of buffer to be allocated
  247. //
  248. uLength = 0;
  249. (*pGetUserNameEx)(NameFullyQualifiedDN,
  250. NULL,
  251. &uLength);
  252. if (uLength > 0)
  253. {
  254. //
  255. // Allocated memory and do the real work
  256. //
  257. pszUserDN = (PWSTR)AllocADsMem(uLength * sizeof(WCHAR));
  258. if (!pszUserDN)
  259. {
  260. RRETURN(E_OUTOFMEMORY);
  261. }
  262. if ((*pGetUserNameEx)(NameFullyQualifiedDN,
  263. pszUserDN,
  264. &uLength))
  265. {
  266. hr = ADsAllocString(pszUserDN, bstrUserName);
  267. BAIL_ON_FAILURE(hr);
  268. }
  269. else
  270. hr = HRESULT_FROM_WIN32(GetLastError());
  271. }
  272. else
  273. hr = HRESULT_FROM_WIN32(GetLastError());
  274. error:
  275. if (pszUserDN)
  276. {
  277. FreeADsMem(pszUserDN);
  278. }
  279. RRETURN(hr);
  280. }
  281. HRESULT
  282. CADSystemInfo::get_ComputerName(
  283. BSTR * bstrComputerName
  284. )
  285. {
  286. PWSTR pszComputerName = NULL;
  287. ULONG uLength;
  288. GETCOMPUTEROBJECTNAME pGetComputerObjectName;
  289. HRESULT hr;
  290. HINSTANCE hModule;
  291. //
  292. // Validate parameters
  293. //
  294. if (!bstrComputerName)
  295. {
  296. RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
  297. }
  298. //
  299. // Get handle to secur32.dll, and get required entry point
  300. //
  301. hr = GetSecur32Handle(&hModule);
  302. BAIL_ON_FAILURE(hr);
  303. pGetComputerObjectName = (GETCOMPUTEROBJECTNAME)GetProcAddress(hModule, "GetComputerObjectNameW");
  304. if (!pGetComputerObjectName)
  305. {
  306. RRETURN(E_FAIL);
  307. }
  308. //
  309. // Get length of buffer to be allocated
  310. //
  311. uLength = 0;
  312. (*pGetComputerObjectName)(NameFullyQualifiedDN,
  313. NULL,
  314. &uLength);
  315. if (uLength > 0)
  316. {
  317. //
  318. // Allocated memory and do the real work
  319. //
  320. pszComputerName = (PWSTR)AllocADsMem(uLength * sizeof(WCHAR));
  321. if (!pszComputerName)
  322. {
  323. RRETURN(E_OUTOFMEMORY);
  324. }
  325. if ((*pGetComputerObjectName)(NameFullyQualifiedDN,
  326. pszComputerName,
  327. &uLength))
  328. {
  329. hr = ADsAllocString(pszComputerName, bstrComputerName);
  330. BAIL_ON_FAILURE(hr);
  331. }
  332. else
  333. hr = HRESULT_FROM_WIN32(GetLastError());
  334. }
  335. else
  336. hr = HRESULT_FROM_WIN32(GetLastError());
  337. error:
  338. if (pszComputerName)
  339. {
  340. FreeADsMem(pszComputerName);
  341. }
  342. RRETURN(hr);
  343. }
  344. HRESULT
  345. CADSystemInfo::get_SiteName(
  346. BSTR * bstrSiteName
  347. )
  348. {
  349. DOMAIN_CONTROLLER_INFO *pdcInfo = NULL;
  350. DSGETDCNAME pDsGetDcName;
  351. DWORD err;
  352. HRESULT hr = S_OK;
  353. //
  354. // Validate parameters
  355. //
  356. if (!bstrSiteName)
  357. {
  358. RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
  359. }
  360. //
  361. // Get function pointer to DsGetDcName
  362. //
  363. pDsGetDcName = GetDsGetDcName();
  364. if (! pDsGetDcName)
  365. {
  366. RRETURN(E_FAIL);
  367. }
  368. //
  369. // Call DsGetDcName to find client site
  370. //
  371. err = (*pDsGetDcName)(NULL, NULL, NULL, NULL, 0, &pdcInfo);
  372. if (err != ERROR_SUCCESS)
  373. {
  374. RRETURN(HRESULT_FROM_WIN32(err));
  375. }
  376. hr = ADsAllocString(pdcInfo->ClientSiteName, bstrSiteName);
  377. BAIL_ON_FAILURE(hr);
  378. error:
  379. if (pdcInfo)
  380. {
  381. NetApiBufferFree(pdcInfo);
  382. }
  383. RRETURN(hr);
  384. }
  385. HRESULT
  386. CADSystemInfo::get_DomainShortName(
  387. BSTR * bstrDomainName
  388. )
  389. {
  390. DOMAIN_CONTROLLER_INFO *pdcInfo = NULL;
  391. DSGETDCNAME pDsGetDcName;
  392. DWORD err;
  393. HRESULT hr = S_OK;
  394. //
  395. // Validate parameters
  396. //
  397. if (!bstrDomainName )
  398. {
  399. RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
  400. }
  401. //
  402. // Get function pointer to DsGetDcName
  403. //
  404. pDsGetDcName = GetDsGetDcName();
  405. if (! pDsGetDcName)
  406. {
  407. RRETURN(E_FAIL);
  408. }
  409. //
  410. // Call DsGetDcName to find domain short name
  411. //
  412. err = (*pDsGetDcName)(NULL, NULL, NULL, NULL, DS_RETURN_FLAT_NAME, &pdcInfo);
  413. if (err != ERROR_SUCCESS)
  414. {
  415. RRETURN(HRESULT_FROM_WIN32(err));
  416. }
  417. hr = ADsAllocString(pdcInfo->DomainName, bstrDomainName);
  418. BAIL_ON_FAILURE(hr);
  419. error:
  420. if (pdcInfo)
  421. {
  422. NetApiBufferFree(pdcInfo);
  423. }
  424. RRETURN(hr);
  425. }
  426. HRESULT
  427. CADSystemInfo::get_DomainDNSName(
  428. BSTR * bstrDomainDNSName
  429. )
  430. {
  431. DOMAIN_CONTROLLER_INFO *pdcInfo = NULL;
  432. DSGETDCNAME pDsGetDcName;
  433. DWORD err;
  434. HRESULT hr = S_OK;
  435. //
  436. // Validate parameters
  437. //
  438. if (!bstrDomainDNSName )
  439. {
  440. RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
  441. }
  442. //
  443. // Get function pointer to DsGetDcName
  444. //
  445. pDsGetDcName = GetDsGetDcName();
  446. if (! pDsGetDcName)
  447. {
  448. RRETURN(E_FAIL);
  449. }
  450. //
  451. // Call DsGetDcName to find domain DNS name
  452. //
  453. err = (*pDsGetDcName)(NULL, NULL, NULL, NULL, DS_RETURN_DNS_NAME, &pdcInfo);
  454. if (err != ERROR_SUCCESS)
  455. {
  456. RRETURN(HRESULT_FROM_WIN32(err));
  457. }
  458. hr = ADsAllocString(pdcInfo->DomainName, bstrDomainDNSName);
  459. BAIL_ON_FAILURE(hr);
  460. error:
  461. if (pdcInfo)
  462. {
  463. NetApiBufferFree(pdcInfo);
  464. }
  465. RRETURN(hr);
  466. }
  467. HRESULT
  468. CADSystemInfo::get_ForestDNSName(
  469. BSTR * bstrForestDNSName
  470. )
  471. {
  472. DOMAIN_CONTROLLER_INFO *pdcInfo = NULL;
  473. DSGETDCNAME pDsGetDcName;
  474. DWORD err;
  475. HRESULT hr = S_OK;
  476. //
  477. // Validate parameters
  478. //
  479. if (!bstrForestDNSName )
  480. {
  481. RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
  482. }
  483. //
  484. // Get function pointer to DsGetDcName
  485. //
  486. pDsGetDcName = GetDsGetDcName();
  487. if (! pDsGetDcName)
  488. {
  489. RRETURN(E_FAIL);
  490. }
  491. //
  492. // Call DsGetDcName to find forest DNS name
  493. //
  494. err = (*pDsGetDcName)(NULL, NULL, NULL, NULL, 0, &pdcInfo);
  495. if (err != ERROR_SUCCESS)
  496. {
  497. RRETURN(HRESULT_FROM_WIN32(err));
  498. }
  499. hr = ADsAllocString(pdcInfo->DnsForestName, bstrForestDNSName);
  500. BAIL_ON_FAILURE(hr);
  501. error:
  502. if (pdcInfo)
  503. {
  504. NetApiBufferFree(pdcInfo);
  505. }
  506. RRETURN(hr);
  507. }
  508. HRESULT
  509. CADSystemInfo::get_PDCRoleOwner(
  510. BSTR * bstrPDCRoleOwner
  511. )
  512. {
  513. RRETURN(GetfSMORoleOwner(DEFAULT_NC, bstrPDCRoleOwner));
  514. }
  515. HRESULT
  516. CADSystemInfo::get_SchemaRoleOwner(
  517. BSTR * bstrSchemaRoleOwner
  518. )
  519. {
  520. RRETURN(GetfSMORoleOwner(SCHEMA_NC, bstrSchemaRoleOwner));
  521. }
  522. HRESULT
  523. CADSystemInfo::get_IsNativeMode(
  524. VARIANT_BOOL *retVal
  525. )
  526. {
  527. IADs *pADs = NULL;
  528. IDirectoryObject *pDir = NULL;
  529. HRESULT hr;
  530. ADS_ATTR_INFO *pAttrInfo = NULL;
  531. DWORD dwReturn = 0;
  532. LPWSTR pAttrNames[] = {L"nTMixedDomain" };
  533. DWORD dwNumAttr = sizeof(pAttrNames)/sizeof(LPWSTR);
  534. //
  535. // Validate parameters
  536. //
  537. if (!retVal)
  538. {
  539. RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
  540. }
  541. hr = GetNCHead(DEFAULT_NC, &pADs);
  542. BAIL_ON_FAILURE(hr);
  543. hr = pADs->QueryInterface(IID_IDirectoryObject, (void**) &pDir);
  544. BAIL_ON_FAILURE(hr);
  545. //
  546. // Get the nTMixedDomain attribute
  547. //
  548. hr = pDir->GetObjectAttributes(pAttrNames,
  549. dwNumAttr,
  550. &pAttrInfo,
  551. &dwReturn);
  552. BAIL_ON_FAILURE(hr);
  553. if (dwReturn == 0)
  554. {
  555. BAIL_ON_FAILURE(hr=E_FAIL);
  556. }
  557. *retVal = pAttrInfo->pADsValues->Boolean == FALSE ? VARIANT_TRUE : VARIANT_FALSE;
  558. error:
  559. //
  560. // Clean-up
  561. //
  562. if (pAttrInfo)
  563. FreeADsMem(pAttrInfo);
  564. if (pDir)
  565. pDir->Release();
  566. if (pADs)
  567. pADs->Release();
  568. return hr;
  569. }
  570. HRESULT
  571. CADSystemInfo::GetAnyDCName(
  572. BSTR *bstrDCName
  573. )
  574. {
  575. DOMAIN_CONTROLLER_INFO *pdcInfo = NULL;
  576. DSGETDCNAME pDsGetDcName;
  577. DWORD err;
  578. HRESULT hr = S_OK;
  579. //
  580. // Validate parameters
  581. //
  582. if (!bstrDCName)
  583. {
  584. RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
  585. }
  586. //
  587. // Get function pointer to DsGetDcName
  588. //
  589. pDsGetDcName = GetDsGetDcName();
  590. if (! pDsGetDcName)
  591. {
  592. RRETURN(E_FAIL);
  593. }
  594. //
  595. // Call DsGetDcName to find DC name
  596. //
  597. err = (*pDsGetDcName)(NULL, NULL, NULL, NULL, 0, &pdcInfo);
  598. if (err != ERROR_SUCCESS)
  599. {
  600. RRETURN(HRESULT_FROM_WIN32(err));
  601. }
  602. hr = ADsAllocString(&pdcInfo->DomainControllerName[2], bstrDCName); // skip "\\"
  603. BAIL_ON_FAILURE(hr);
  604. error:
  605. if (pdcInfo)
  606. {
  607. NetApiBufferFree(pdcInfo);
  608. }
  609. RRETURN(hr);
  610. }
  611. HRESULT
  612. CADSystemInfo::GetDCSiteName(
  613. BSTR bstrDCName,
  614. BSTR *bstrSiteName
  615. )
  616. {
  617. DOMAIN_CONTROLLER_INFO *pdcInfo = NULL;
  618. DSGETDCNAME pDsGetDcName;
  619. DWORD err;
  620. HRESULT hr = S_OK;
  621. //
  622. // Validate parameters
  623. //
  624. if (!bstrDCName|| !bstrSiteName)
  625. {
  626. RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
  627. }
  628. //
  629. // Get function pointer to DsGetDcName
  630. //
  631. pDsGetDcName = GetDsGetDcName();
  632. if (! pDsGetDcName)
  633. {
  634. RRETURN(E_FAIL);
  635. }
  636. //
  637. // Call DsGetDcName to find DC site name
  638. //
  639. err = (*pDsGetDcName)(bstrDCName, NULL, NULL, NULL, 0, &pdcInfo);
  640. if (err != ERROR_SUCCESS)
  641. {
  642. RRETURN(HRESULT_FROM_WIN32(err));
  643. }
  644. hr = ADsAllocString(pdcInfo->DcSiteName, bstrSiteName);
  645. BAIL_ON_FAILURE(hr);
  646. error:
  647. if (pdcInfo)
  648. {
  649. NetApiBufferFree(pdcInfo);
  650. }
  651. RRETURN(hr);
  652. }
  653. HRESULT
  654. CADSystemInfo::RefreshSchemaCache(
  655. void
  656. )
  657. {
  658. IADs *pRootDSE = NULL;
  659. VARIANT var;
  660. HRESULT hr;
  661. VariantInit( &var );
  662. hr = ADsGetObject(L"LDAP://RootDSE", IID_IADs, (void**) &pRootDSE);
  663. BAIL_ON_FAILURE(hr);
  664. V_VT(&var) = VT_I4;
  665. V_I4(&var) = 1;
  666. hr = pRootDSE->Put(LDAP_OPATT_SCHEMA_UPDATE_NOW_W, var);
  667. BAIL_ON_FAILURE(hr);
  668. hr = pRootDSE->SetInfo();
  669. BAIL_ON_FAILURE(hr);
  670. error:
  671. VariantClear( &var );
  672. if (pRootDSE)
  673. pRootDSE->Release();
  674. RRETURN(hr);
  675. }
  676. HRESULT
  677. CADSystemInfo::GetTrees(
  678. VARIANT *pVar
  679. )
  680. {
  681. PDS_DOMAIN_TRUSTS pDomains = NULL;
  682. DSENUMERATEDOMAINTRUSTS pDsEnumerateDomainTrusts;
  683. SAFEARRAYBOUND rgsabound[1];
  684. SAFEARRAY *psa = NULL;
  685. DWORD dwErr = 0;
  686. ULONG i, lCount;
  687. HRESULT hr = S_OK;
  688. DWORD count;
  689. //
  690. // Validate parameters
  691. //
  692. if (!pVar )
  693. {
  694. RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
  695. }
  696. //
  697. // Get function pointer to NetEnumerateTrustedDomainsEx
  698. //
  699. pDsEnumerateDomainTrusts = GetDsEnumerateDomainTrusts();
  700. if (! pDsEnumerateDomainTrusts)
  701. {
  702. RRETURN(E_FAIL);
  703. }
  704. //
  705. // Enumerate all trusted domains
  706. //
  707. dwErr = (*pDsEnumerateDomainTrusts)(
  708. NULL,
  709. DS_DOMAIN_PRIMARY
  710. | DS_DOMAIN_IN_FOREST
  711. | DS_DOMAIN_DIRECT_OUTBOUND,
  712. &pDomains,
  713. &lCount
  714. );
  715. if (dwErr) {
  716. hr = HRESULT_FROM_WIN32(dwErr);
  717. }
  718. BAIL_ON_FAILURE(hr);
  719. //
  720. // Count number of domains that are tree roots
  721. //
  722. count = 0;
  723. for(i = 0; i < lCount; i++)
  724. {
  725. if (pDomains[i].Flags & DS_DOMAIN_TREE_ROOT)
  726. {
  727. ASSERT(pDomains[i].DnsDomainName);
  728. count++;
  729. }
  730. }
  731. //
  732. // We have no tree roots - we must be on an NT4 domain, return
  733. // an empty variant
  734. //
  735. if (count == 0)
  736. {
  737. VariantClear(pVar);
  738. V_VT(pVar) = VT_EMPTY;
  739. RRETURN(S_OK);
  740. }
  741. //
  742. // Create Safe Array
  743. //
  744. rgsabound[0].lLbound = 0;
  745. rgsabound[0].cElements = count;
  746. psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
  747. if (! psa)
  748. {
  749. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  750. }
  751. VariantClear(pVar);
  752. V_VT(pVar) = VT_VARIANT|VT_ARRAY;
  753. V_ARRAY(pVar) = psa;
  754. VARIANT varItem;
  755. //
  756. // Now iterate through each returned element and
  757. // add it to the variant array if it is a tree root
  758. //
  759. count = 0;
  760. for(i = 0; i < lCount; i++)
  761. {
  762. if (pDomains[i].Flags & DS_DOMAIN_TREE_ROOT)
  763. {
  764. VariantInit(&varItem);
  765. V_VT(&varItem) = VT_BSTR;
  766. hr = ADsAllocString(pDomains[i].DnsDomainName, &(V_BSTR(&varItem)));
  767. BAIL_ON_FAILURE(hr);
  768. hr = SafeArrayPutElement(psa, (long *) &count, &varItem);
  769. VariantClear(&varItem);
  770. BAIL_ON_FAILURE(hr);
  771. count++;
  772. }
  773. }
  774. error:
  775. if (pDomains)
  776. NetApiBufferFree(pDomains);
  777. if (FAILED(hr) && psa)
  778. SafeArrayDestroy(psa);
  779. return hr;
  780. }
  781. HRESULT
  782. CADSystemInfo::GetNCHead(
  783. LPTSTR szNCName,
  784. IADs **pADs
  785. )
  786. {
  787. WCHAR szPathName[MAX_PATH];
  788. VARIANT var;
  789. HRESULT hr;
  790. IADs *pRootDSE = NULL;
  791. //
  792. // Open RootDSE and query for NC object name
  793. //
  794. hr = ADsGetObject(L"LDAP://RootDSE", IID_IADs, (void**) &pRootDSE );
  795. BAIL_ON_FAILURE(hr);
  796. hr = pRootDSE->Get(szNCName, &var);
  797. BAIL_ON_FAILURE(hr);
  798. //
  799. // Build LDAP://<naming context>
  800. //
  801. wcscpy(szPathName, L"LDAP://");
  802. wcscat(szPathName, V_BSTR(&var));
  803. //
  804. // Get pointer to NC object
  805. //
  806. hr = ADsGetObject(szPathName, IID_IADs, (void**) pADs);
  807. BAIL_ON_FAILURE(hr);
  808. error:
  809. if (pRootDSE)
  810. {
  811. pRootDSE->Release();
  812. }
  813. RRETURN(hr);
  814. }
  815. HRESULT
  816. CADSystemInfo::GetfSMORoleOwner(
  817. LPTSTR szNCName,
  818. BSTR *bstrRoleOwner
  819. )
  820. {
  821. IADs *pADs = NULL;
  822. IDirectoryObject *pDir = NULL;
  823. ADS_ATTR_INFO *pAttrInfo = NULL;
  824. LPWSTR pAttrNames[] = {L"fSMORoleOwner" };
  825. DWORD dwNumAttrs = sizeof(pAttrNames)/sizeof(LPWSTR);
  826. HRESULT hr;
  827. DWORD dwReturn;
  828. //
  829. // Validate parameters
  830. //
  831. if (!bstrRoleOwner )
  832. {
  833. RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
  834. }
  835. hr = GetNCHead(szNCName, &pADs);
  836. BAIL_ON_FAILURE(hr);
  837. hr = pADs->QueryInterface(IID_IDirectoryObject, (void**) &pDir);
  838. BAIL_ON_FAILURE(hr);
  839. //
  840. // Get the fSMORoleOwner
  841. //
  842. hr = pDir->GetObjectAttributes(pAttrNames,
  843. dwNumAttrs,
  844. &pAttrInfo,
  845. &dwReturn);
  846. BAIL_ON_FAILURE(hr);
  847. if (dwReturn == 0)
  848. {
  849. BAIL_ON_FAILURE(hr=E_FAIL);
  850. }
  851. hr = ADsAllocString(pAttrInfo->pADsValues->CaseIgnoreString, bstrRoleOwner);
  852. BAIL_ON_FAILURE(hr);
  853. error:
  854. //
  855. // Clean-up
  856. //
  857. if (pDir)
  858. pDir->Release();
  859. if (pADs)
  860. pADs->Release();
  861. FreeADsMem(pAttrInfo);
  862. RRETURN(hr);
  863. }
  864. HRESULT
  865. CADSystemInfo::GetSecur32Handle(
  866. HINSTANCE *pHandle
  867. )
  868. {
  869. if(!_Secur32LoadAttempted)
  870. {
  871. ENTER_SYSTEMAPI_CRITICAL_SECTION()
  872. if (! _Secur32LoadAttempted)
  873. {
  874. _hSecur32 = LoadLibraryHelper(__TEXT("secur32.dll"));
  875. _Secur32LoadAttempted = TRUE;
  876. }
  877. LEAVE_SYSTEMAPI_CRITICAL_SECTION()
  878. }
  879. *pHandle = _hSecur32;
  880. if (_hSecur32)
  881. RRETURN(S_OK);
  882. else
  883. RRETURN(E_FAIL);
  884. }
  885. DSGETDCNAME
  886. CADSystemInfo::GetDsGetDcName(
  887. void
  888. )
  889. {
  890. DSGETDCNAME pDsGetDcName = NULL;
  891. if(!_NetApi32LoadAttempted)
  892. {
  893. ENTER_SYSTEMAPI_CRITICAL_SECTION()
  894. if (! _NetApi32LoadAttempted)
  895. {
  896. _hNetApi32 = LoadLibraryHelper(__TEXT("netapi32.dll"));
  897. _NetApi32LoadAttempted = TRUE;
  898. }
  899. LEAVE_SYSTEMAPI_CRITICAL_SECTION()
  900. }
  901. if (_hNetApi32)
  902. {
  903. pDsGetDcName = (DSGETDCNAME)GetProcAddress(_hNetApi32, "DsGetDcNameW");
  904. }
  905. return pDsGetDcName;
  906. }
  907. DSENUMERATEDOMAINTRUSTS
  908. CADSystemInfo::GetDsEnumerateDomainTrusts(
  909. void
  910. )
  911. {
  912. DSENUMERATEDOMAINTRUSTS pDsEnumerateDomainTrusts = NULL;
  913. if(!_NetApi32LoadAttempted)
  914. {
  915. ENTER_SYSTEMAPI_CRITICAL_SECTION()
  916. if (! _NetApi32LoadAttempted)
  917. {
  918. _hNetApi32 = LoadLibraryHelper(__TEXT("netapi32.dll"));
  919. _NetApi32LoadAttempted = TRUE;
  920. }
  921. LEAVE_SYSTEMAPI_CRITICAL_SECTION()
  922. }
  923. if (_hNetApi32)
  924. {
  925. pDsEnumerateDomainTrusts = (DSENUMERATEDOMAINTRUSTS)
  926. GetProcAddress(
  927. _hNetApi32,
  928. "DsEnumerateDomainTrustsW"
  929. );
  930. }
  931. return pDsEnumerateDomainTrusts;
  932. }
  933. STDMETHODIMP
  934. CADSystemInfoCF::CreateInstance(
  935. IUnknown * pUnkOuter,
  936. REFIID iid,
  937. LPVOID * ppv
  938. )
  939. {
  940. HRESULT hr = E_FAIL;
  941. if (pUnkOuter)
  942. RRETURN(E_FAIL);
  943. hr = CADSystemInfo::CreateADSystemInfo(
  944. iid,
  945. ppv
  946. );
  947. RRETURN(hr);
  948. }