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.

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