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.

885 lines
23 KiB

  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright(C) 1997-1998 Microsoft Corporation all rights reserved.
  4. //
  5. // Module: sdomachine.cpp
  6. //
  7. // Project: Everest
  8. //
  9. // Description: SDO Machine Implementation
  10. //
  11. // Author: TLP 9/1/98
  12. //
  13. ///////////////////////////////////////////////////////////////////////////
  14. #include "stdafx.h"
  15. #include <ias.h>
  16. #include <lm.h>
  17. #include <dsrole.h>
  18. #include "sdomachine.h"
  19. #include "sdofactory.h"
  20. #include "sdo.h"
  21. #include "dspath.h"
  22. #include "sdodictionary.h"
  23. #include "sdoschema.h"
  24. #include "activeds.h"
  25. HRESULT
  26. WINAPI
  27. IASGetLDAPPathForUser(
  28. PCWSTR computerName,
  29. PCWSTR userName,
  30. BSTR* path
  31. ) throw ()
  32. {
  33. HRESULT hr;
  34. // Check the pointers.
  35. if (!computerName || !userName || !path) { return E_POINTER; }
  36. // Check the string lengths, so we don't have to worry about overflow.
  37. if (wcslen(computerName) > MAX_PATH || wcslen(userName) > MAX_PATH)
  38. { return E_INVALIDARG; }
  39. // Initialize the out parameter.
  40. *path = NULL;
  41. // Form the LDAP path for the target computer.
  42. WCHAR root[8 + MAX_PATH];
  43. wcscat(wcscpy(root, L"LDAP://"), computerName);
  44. // Get the IDirectorySearch interface.
  45. CComPtr<IDirectorySearch> search;
  46. // tperraut 453050
  47. hr = ADsOpenObject(
  48. root,
  49. NULL,
  50. NULL,
  51. ADS_SECURE_AUTHENTICATION |
  52. ADS_USE_SIGNING |
  53. ADS_USE_SEALING,
  54. __uuidof(IDirectorySearch),
  55. (PVOID*)&search
  56. );
  57. if (FAILED(hr)) { return hr; }
  58. // Form the search filter.
  59. WCHAR filter[18 + MAX_PATH];
  60. wcscat(wcscat(wcscpy(filter, L"(sAMAccountName="), userName), L")");
  61. // Execute the search.
  62. PWSTR attrs[] = { L"distinguishedName" };
  63. ADS_SEARCH_HANDLE result;
  64. hr = search->ExecuteSearch(
  65. filter,
  66. attrs,
  67. 1,
  68. &result
  69. );
  70. if (FAILED(hr)) { return hr; }
  71. // Get the first row.
  72. hr = search->GetFirstRow(result);
  73. if (SUCCEEDED(hr))
  74. {
  75. // Get the column containing the distinguishedName.
  76. ADS_SEARCH_COLUMN column;
  77. hr = search->GetColumn(result, attrs[0], &column);
  78. if (SUCCEEDED(hr))
  79. {
  80. // Sanity check the struct.
  81. if (column.dwADsType == ADSTYPE_DN_STRING && column.dwNumValues)
  82. {
  83. // Extract the DN.
  84. PCWSTR dn = column.pADsValues[0].DNString;
  85. // Get the Pathname object.
  86. IADsPathname* pathname;
  87. hr = CoCreateInstance(
  88. __uuidof(Pathname),
  89. NULL,
  90. CLSCTX_INPROC_SERVER,
  91. __uuidof(IADsPathname),
  92. (PVOID*)&pathname
  93. );
  94. if (SUCCEEDED(hr))
  95. {
  96. do
  97. {
  98. /////////
  99. // Build the ADSI path.
  100. /////////
  101. hr = pathname->Set(L"LDAP", ADS_SETTYPE_PROVIDER);
  102. if (FAILED(hr)) { break; }
  103. hr = pathname->Set((PWSTR)computerName, ADS_SETTYPE_SERVER);
  104. if (FAILED(hr)) { break; }
  105. hr = pathname->Set((PWSTR)dn, ADS_SETTYPE_DN);
  106. if (FAILED(hr)) { break; }
  107. hr = pathname->Retrieve(ADS_FORMAT_WINDOWS, path);
  108. } while (FALSE);
  109. pathname->Release();
  110. }
  111. }
  112. else
  113. {
  114. // We got back a bogus ADS_SEARCH_COLUMN struct.
  115. hr = E_FAIL;
  116. }
  117. // Free the column data.
  118. search->FreeColumn(&column);
  119. }
  120. }
  121. // Close the search handle.
  122. search->CloseSearchHandle(result);
  123. return hr;
  124. }
  125. //////////////////////////////////////////////////////////////////////////////
  126. CSdoMachine::CSdoMachine()
  127. : m_fAttached(false),
  128. m_fSchemaInitialized(false),
  129. m_pSdoSchema(NULL),
  130. m_pSdoDictionary(NULL),
  131. dsType(Directory_Unknown)
  132. {
  133. }
  134. //////////////////////////////////////////////////////////////////////////////
  135. CSdoMachine::~CSdoMachine()
  136. {
  137. if ( m_fAttached )
  138. {
  139. m_dsIAS.Disconnect();
  140. m_dsAD.Disconnect();
  141. m_pSdoSchema->Release();
  142. if ( m_pSdoDictionary )
  143. m_pSdoDictionary->Release();
  144. IASUninitialize();
  145. }
  146. }
  147. //////////////////////
  148. // ISdoMachine Methods
  149. //////////////////////////////////////////////////////////////////////////////
  150. STDMETHODIMP CSdoMachine::Attach(
  151. /*[in]*/ BSTR computerName
  152. )
  153. {
  154. CSdoLock theLock(*this);
  155. _ASSERT( ! m_fAttached );
  156. if ( m_fAttached )
  157. return E_FAIL;
  158. HRESULT hr = E_FAIL;
  159. try
  160. {
  161. if ( computerName )
  162. IASTracePrintf("Machine SDO is attempting to attach to computer: '%ls'...", computerName);
  163. else
  164. IASTracePrintf("Machine SDO is attempting to attach to the local computer...");
  165. IASTracePrintf("Machine SDO is initializing the IAS support services...");
  166. if ( IASInitialize() )
  167. {
  168. hr = m_dsIAS.Connect(computerName, NULL, NULL);
  169. if ( SUCCEEDED(hr) )
  170. {
  171. IASTracePrintf("Machine SDO is creating the SDO schema...");
  172. hr = CreateSDOSchema();
  173. if ( SUCCEEDED(hr) )
  174. {
  175. IASTracePrintf("Machine SDO has successfully attached to computer: '%ls'...",m_dsIAS.GetServerName());
  176. m_fAttached = true;
  177. }
  178. else
  179. {
  180. m_dsIAS.Disconnect();
  181. IASUninitialize();
  182. }
  183. }
  184. else
  185. {
  186. IASTracePrintf("Error in Machine SDO - Attach() - Could not connect to IAS data store...");
  187. }
  188. }
  189. else
  190. {
  191. IASTracePrintf("Error in Machine SDO - Attach() - Could not initialize IAS support services...");
  192. }
  193. }
  194. catch(...)
  195. {
  196. IASTracePrintf("Error in Machine SDO - Attach() - Caught unknown exception...");
  197. hr = E_UNEXPECTED;
  198. }
  199. return hr;
  200. }
  201. //////////////////////////////////////////////////////////////////////////////
  202. STDMETHODIMP CSdoMachine::GetDictionarySDO(
  203. /*[out]*/ IUnknown** ppDictionarySdo
  204. )
  205. {
  206. CSdoLock theLock(*this);
  207. IASTracePrintf("Machine SDO is retrieving the Dictionary SDO...");
  208. HRESULT hr = S_OK;
  209. try
  210. {
  211. do
  212. {
  213. // Check preconditions
  214. //
  215. _ASSERT( m_fAttached );
  216. if ( ! m_fAttached )
  217. {
  218. hr = E_FAIL;
  219. break;
  220. }
  221. _ASSERT( NULL != ppDictionarySdo );
  222. if ( NULL == ppDictionarySdo )
  223. {
  224. hr = E_POINTER;
  225. break;
  226. }
  227. // The dictionary is a singleton...
  228. //
  229. if (NULL == m_pSdoDictionary)
  230. {
  231. hr = InitializeSDOSchema();
  232. if ( FAILED(hr) )
  233. {
  234. IASTracePrintf("Error in Machine SDO - GetDictionarySDO() - Could not initialize the SDO schema...");
  235. break;
  236. }
  237. // Create the Dictionary SDO
  238. CComPtr<SdoDictionary> pSdoDictionary;
  239. hr = SdoDictionary::createInstance(
  240. m_dsIAS.GetConfigPath(),
  241. !m_dsIAS.IsRemoteServer(),
  242. (SdoDictionary**)&m_pSdoDictionary
  243. );
  244. if (FAILED(hr))
  245. {
  246. IASTraceFailure("SdoDictionary::createInstance", hr);
  247. break;
  248. }
  249. }
  250. // Return the dictionary interface to the caller
  251. //
  252. (*ppDictionarySdo = m_pSdoDictionary)->AddRef();
  253. } while ( FALSE );
  254. }
  255. catch(...)
  256. {
  257. IASTracePrintf("Error in Machine SDO - GetDictionarySDO() - Caught unknown exception...");
  258. hr = E_UNEXPECTED;
  259. }
  260. return hr;
  261. }
  262. const wchar_t g_IASService[] = L"IAS";
  263. const wchar_t g_RASService[] = L"RemoteAccess";
  264. const wchar_t g_Sentinel[] = L"Sentinel";
  265. LPCWSTR CSdoMachine::m_SupportedServices[MACHINE_MAX_SERVICES] = {
  266. g_IASService,
  267. g_RASService,
  268. g_Sentinel
  269. };
  270. //////////////////////////////////////////////////////////////////////////////
  271. STDMETHODIMP CSdoMachine::GetServiceSDO(
  272. /*[in]*/ IASDATASTORE dataStore,
  273. /*[in]*/ BSTR serviceName,
  274. /*[out]*/ IUnknown** ppServiceSdo
  275. )
  276. {
  277. CSdoLock theLock(*this);
  278. _ASSERT( m_fAttached );
  279. if ( ! m_fAttached )
  280. return E_FAIL;
  281. _ASSERT(
  282. ( DATA_STORE_LOCAL == dataStore || DATA_STORE_DIRECTORY == dataStore ) &&
  283. NULL != serviceName &&
  284. NULL != ppServiceSdo
  285. );
  286. if ( ( DATA_STORE_LOCAL != dataStore && DATA_STORE_DIRECTORY != dataStore ) ||
  287. NULL == serviceName ||
  288. NULL == ppServiceSdo
  289. )
  290. {
  291. return E_INVALIDARG;
  292. }
  293. IASTracePrintf("Machine SDO is attempting to retrieve the Service SDO for service: %ls...", serviceName);
  294. int i;
  295. for ( i = 0; i < MACHINE_MAX_SERVICES; i++ )
  296. {
  297. if ( ! lstrcmp(serviceName, m_SupportedServices[i]) )
  298. {
  299. break;
  300. }
  301. else
  302. {
  303. if ( ! lstrcmp(m_SupportedServices[i], g_Sentinel ) )
  304. return E_INVALIDARG;
  305. }
  306. }
  307. HRESULT hr = E_INVALIDARG;
  308. try
  309. {
  310. do
  311. {
  312. hr = InitializeSDOSchema();
  313. if ( FAILED(hr) )
  314. {
  315. IASTracePrintf("Error in Machine SDO - GetServiceSDO() - Could not initialize the SDO schema...");
  316. break;
  317. }
  318. CComBSTR bstrServiceName(DS_OBJECT_SERVICE);
  319. if (!bstrServiceName)
  320. {
  321. hr = E_OUTOFMEMORY;
  322. break;
  323. }
  324. CComPtr<IDataStoreObject> pDSObject;
  325. hr = (m_dsIAS.GetDSRootContainer())->Item(bstrServiceName, &pDSObject);
  326. if ( FAILED(hr) )
  327. {
  328. IASTracePrintf("Error in Machine SDO - GetServiceSDO() - Could not locate IAS service data store...");
  329. break;
  330. }
  331. CComPtr<ISdo> pSdoService;
  332. pSdoService.p = ::MakeSDO(
  333. serviceName,
  334. SDO_PROG_ID_SERVICE,
  335. static_cast<ISdoMachine*>(this),
  336. pDSObject,
  337. NULL,
  338. false
  339. );
  340. if ( NULL == pSdoService.p )
  341. {
  342. IASTracePrintf("Error in Machine SDO - GetServiceSDO() - MakeSDO() failed...");
  343. hr = E_FAIL;
  344. break;
  345. }
  346. hr = pSdoService->QueryInterface(IID_IDispatch, (void**)ppServiceSdo);
  347. if ( FAILED(hr) )
  348. {
  349. IASTracePrintf("Error in Machine SDO - GetServiceSDO() - QueryInterface(IDispatch) failed...");
  350. break;
  351. }
  352. } while ( FALSE );
  353. }
  354. catch(...)
  355. {
  356. IASTracePrintf("Error in Machine SDO - GetServiceSDO() - Caught unknown exception...");
  357. hr = E_UNEXPECTED;
  358. }
  359. return hr;
  360. }
  361. //////////////////////////////////////////////////////////////////////////////
  362. const wchar_t DOWNLEVEL_NAME[] = L"downlevel";
  363. STDMETHODIMP CSdoMachine::GetUserSDO(
  364. /*[in]*/ IASDATASTORE eDataStore,
  365. /*[in]*/ BSTR bstrUserName,
  366. /*[out]*/ IUnknown** ppUserSdo
  367. )
  368. {
  369. CSdoLock theLock(*this);
  370. _ASSERT( m_fAttached );
  371. if ( ! m_fAttached )
  372. return E_FAIL;
  373. _ASSERT(
  374. ( DATA_STORE_LOCAL == eDataStore || DATA_STORE_DIRECTORY == eDataStore ) &&
  375. NULL != bstrUserName &&
  376. NULL != ppUserSdo
  377. );
  378. if ( ( DATA_STORE_LOCAL != eDataStore && DATA_STORE_DIRECTORY != eDataStore ) ||
  379. NULL == bstrUserName ||
  380. NULL == ppUserSdo
  381. )
  382. return E_INVALIDARG;
  383. HRESULT hr = E_FAIL;
  384. // Map local users to the DS if we're attached to a machine with
  385. // a directory.
  386. if (eDataStore == DATA_STORE_LOCAL && hasDirectory())
  387. {
  388. eDataStore = DATA_STORE_DIRECTORY;
  389. }
  390. // If we're connecting to a directory and the username doesn't begin with
  391. // "LDAP://", then we'll assume it's a SAM account name.
  392. BSTR ldapPath = NULL;
  393. if (eDataStore == DATA_STORE_DIRECTORY &&
  394. wcsncmp(bstrUserName, L"LDAP://", 7))
  395. {
  396. hr = IASGetLDAPPathForUser(
  397. m_dsIAS.GetServerName(),
  398. bstrUserName,
  399. &ldapPath
  400. );
  401. if (FAILED(hr)) { return hr; }
  402. bstrUserName = ldapPath;
  403. }
  404. IASTracePrintf("Machine SDO is attempting to retrieve the RAS User SDO for user: %ls...", bstrUserName);
  405. ISdo* pSdoUser = NULL;
  406. try
  407. {
  408. do
  409. {
  410. // Get the IDataStoreObject interface for the new User SDO.
  411. // We'll use the IDataStoreObject interface to read/write User SDO properties.
  412. //
  413. bool fUseDownLevelAPI = false;
  414. bool fUseNetAPI = true;
  415. CComPtr<IDataStoreObject> pDSObject;
  416. _variant_t vtSAMAccountName;
  417. if ( DATA_STORE_DIRECTORY == eDataStore )
  418. {
  419. // Make sure we're connected to the directory
  420. //
  421. if ( ! m_dsAD.IsConnected() )
  422. {
  423. hr = m_dsAD.Connect(m_dsIAS.GetServerName(), NULL, NULL);
  424. if ( FAILED(hr) )
  425. {
  426. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not connect to the directory data store...");
  427. break;
  428. }
  429. }
  430. // Make sure it's initialized.
  431. hr = m_dsAD.InitializeDS();
  432. if ( FAILED(hr) )
  433. {
  434. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not initialize the directory data store...");
  435. break;
  436. }
  437. // Get the user object from the directory
  438. //
  439. hr = (m_dsAD.GetDSRoot())->OpenObject(bstrUserName, &pDSObject);
  440. if ( FAILED(hr) )
  441. {
  442. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not retrieve user object from DS...");
  443. break;
  444. }
  445. // If we're connected to a dc in a mixed domain we'll need to first get the users
  446. // SAM account name from the user object in the active directory and then treat the
  447. // GetUserSDO() call as if the caller specified DATA_STORE_LOCAL. We also use
  448. // downlevel APIs (SAM) because its a mixed domain.
  449. //
  450. if ( m_dsAD.IsMixedMode() )
  451. {
  452. IASTracePrintf("Machine SDO - GetUserSDO() - Current DC (Server) %ls is in a mixed mode domain...", m_dsAD.GetServerName());
  453. hr = pDSObject->GetValue(IAS_NTDS_SAM_ACCOUNT_NAME, &vtSAMAccountName);
  454. if ( FAILED(hr) )
  455. {
  456. IASTracePrintf("Error in Server SDO - GetUserSDO() - Could not retrieve users SAM account name...");
  457. break;
  458. }
  459. bstrUserName = V_BSTR(&vtSAMAccountName);
  460. fUseDownLevelAPI = true;
  461. pDSObject.Release();
  462. IASTracePrintf("Server SDO - GetUserSDO() - User's SAM account name is: %ls...", (LPWSTR)bstrUserName);
  463. }
  464. else
  465. {
  466. // Use the directory data store object for all subsequent property read/write
  467. // operations on this User SDO.
  468. //
  469. IASTracePrintf("Server SDO - GetUserSDO() - Using active directory for user properties...");
  470. fUseNetAPI = false;
  471. }
  472. }
  473. if ( fUseNetAPI )
  474. {
  475. // Create the net data store and aquire the data store object interfaces
  476. // we'll use to complete the GetUserSDO() operation
  477. //
  478. CComPtr<IDataStore2> pDSNet;
  479. hr = CoCreateInstance(
  480. __uuidof(NetDataStore),
  481. NULL,
  482. CLSCTX_INPROC_SERVER,
  483. IID_IDataStore2,
  484. (void**)&pDSNet
  485. );
  486. if ( FAILED(hr) )
  487. {
  488. IASTracePrintf("Error in Machine SDO - GetUserSDO() - CoCreateInstance(NetDataStore) failed...");
  489. break;
  490. }
  491. hr = pDSNet->Initialize(NULL, NULL, NULL);
  492. if ( FAILED(hr) )
  493. {
  494. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not initialize net data store...");
  495. break;
  496. }
  497. CComPtr<IDataStoreObject> pDSRootObject;
  498. hr = pDSNet->get_Root(&pDSRootObject);
  499. if ( FAILED(hr) )
  500. {
  501. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not get Root object from net data store...");
  502. break;
  503. }
  504. CComPtr<IDataStoreContainer> pDSContainer;
  505. hr = pDSRootObject->QueryInterface(IID_IDataStoreContainer, (void**)&pDSContainer);
  506. if ( FAILED(hr) )
  507. {
  508. IASTracePrintf("Error in Machine SDO - GetUserSDO() - QueryInterface(IID_IDataStoreContainer) failed...");
  509. break;
  510. }
  511. // Get the name of the attached computer and use it to aquire a "Server"
  512. // (machine) object from the data store.
  513. //
  514. CComPtr<IDataStoreObject> pDSObjectMachine;
  515. if ( fUseDownLevelAPI )
  516. {
  517. _bstr_t bstrServerName = m_dsAD.GetServerName();
  518. IASTracePrintf("Machine SDO - GetUserSDO() - Using server %ls with downlevel APIs...", (LPWSTR)bstrServerName);
  519. hr = pDSContainer->Item(bstrServerName, &pDSObjectMachine);
  520. if ( FAILED(hr) )
  521. {
  522. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not obtain server object from net data store...");
  523. break;
  524. }
  525. _bstr_t bstrDownLevel = DOWNLEVEL_NAME;
  526. _variant_t vtDownLevel;
  527. V_BOOL(&vtDownLevel) = VARIANT_TRUE;
  528. V_VT(&vtDownLevel) = VT_BOOL;
  529. hr = pDSObjectMachine->PutValue(bstrDownLevel, &vtDownLevel);
  530. if ( FAILED(hr) )
  531. {
  532. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not set downlevel data store mode...");
  533. break;
  534. }
  535. }
  536. else
  537. {
  538. _bstr_t bstrServerName = m_dsIAS.GetServerName();
  539. IASTracePrintf("Machine SDO - GetUserSDO() - Using server %ls with Net APIs...", (LPWSTR)bstrServerName);
  540. hr = pDSContainer->Item(bstrServerName, &pDSObjectMachine);
  541. if ( FAILED(hr) )
  542. {
  543. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not obtain server object from data store...");
  544. break;
  545. }
  546. }
  547. pDSContainer.Release();
  548. // Get "User" object from the "Server" object. We'll use the "User" object in
  549. // all subsequent read/write operations on the User SDO.
  550. //
  551. hr = pDSObjectMachine->QueryInterface(IID_IDataStoreContainer, (void**)&pDSContainer);
  552. if ( FAILED(hr) )
  553. {
  554. IASTracePrintf("Error in Machine SDO - GetUserSDO() - QueryInterface(IID_IDataStoreContainer) failed...");
  555. break;
  556. }
  557. hr = pDSContainer->Item(bstrUserName, &pDSObject);
  558. if ( FAILED(hr) )
  559. {
  560. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not obtain user object from data store...");
  561. break;
  562. }
  563. }
  564. // Create and initialize the User SDO
  565. //
  566. pSdoUser = ::MakeSDO(
  567. NULL,
  568. SDO_PROG_ID_USER,
  569. static_cast<ISdoMachine*>(this),
  570. pDSObject,
  571. NULL,
  572. false
  573. );
  574. if ( NULL == pSdoUser )
  575. {
  576. IASTracePrintf("Error in Machine SDO - GetUserSDO() - MakeSDO() failed...");
  577. hr = E_FAIL;
  578. }
  579. else
  580. {
  581. CComPtr<IDispatch> pSdoDispatch;
  582. hr = pSdoUser->QueryInterface(IID_IDispatch, (void**)&pSdoDispatch);
  583. if ( FAILED(hr) )
  584. IASTracePrintf("Error in Machine SDO - GetUserSDO() - QueryInterface(IDispatch) failed...");
  585. else
  586. (*ppUserSdo = pSdoDispatch)->AddRef();
  587. }
  588. }
  589. while ( FALSE);
  590. }
  591. catch(...)
  592. {
  593. IASTracePrintf("Error in Server SDO - GetUserSDO() - Caught unknown exception...");
  594. hr = E_FAIL;
  595. }
  596. if ( pSdoUser )
  597. pSdoUser->Release();
  598. if (ldapPath) { SysFreeString(ldapPath); }
  599. return hr;
  600. }
  601. //////////////////////////////////////////////////////////////////////////////
  602. STDMETHODIMP CSdoMachine::GetOSType(
  603. /*[out]*/ IASOSTYPE* eOSType
  604. )
  605. {
  606. CSdoLock theLock(*this);
  607. _ASSERT( m_fAttached );
  608. if ( ! m_fAttached )
  609. return E_FAIL;
  610. _ASSERT( NULL != eOSType );
  611. if ( NULL == eOSType )
  612. return E_INVALIDARG;
  613. // Get the OS info now
  614. //
  615. HRESULT hr = m_objServerInfo.GetOSInfo (
  616. (LPWSTR)m_dsIAS.GetServerName(),
  617. eOSType
  618. );
  619. if ( FAILED (hr) )
  620. IASTracePrintf("Error in Machine SDO - GetOSType() failed with error: %lx...", hr);
  621. return hr;
  622. }
  623. //////////////////////////////////////////////////////////////////////////////
  624. STDMETHODIMP CSdoMachine::GetDomainType(
  625. /*[out]*/ IASDOMAINTYPE* eDomainType
  626. )
  627. {
  628. CSdoLock theLock(*this);
  629. _ASSERT( m_fAttached );
  630. if ( ! m_fAttached )
  631. return E_FAIL;
  632. _ASSERT( NULL != eDomainType );
  633. if ( NULL == eDomainType )
  634. return E_INVALIDARG;
  635. HRESULT hr = m_objServerInfo.GetDomainInfo (
  636. OBJECT_TYPE_COMPUTER,
  637. (LPWSTR)m_dsIAS.GetServerName(),
  638. eDomainType
  639. );
  640. if (FAILED (hr))
  641. IASTracePrintf("Error in Machine SDO - GetDomainType() - failed with error: %lx...", hr);
  642. return hr;
  643. }
  644. //////////////////////////////////////////////////////////////////////////////
  645. STDMETHODIMP CSdoMachine::IsDirectoryAvailable(
  646. /*[out]*/ VARIANT_BOOL* boolDirectoryAvailable
  647. )
  648. {
  649. CSdoLock theLock(*this);
  650. _ASSERT( m_fAttached );
  651. if ( ! m_fAttached )
  652. return E_FAIL;
  653. _ASSERT( NULL != boolDirectoryAvailable );
  654. if ( NULL == boolDirectoryAvailable )
  655. return E_INVALIDARG;
  656. *boolDirectoryAvailable = VARIANT_FALSE;
  657. return S_OK;
  658. }
  659. //////////////////////////////////////////////////////////////////////////////
  660. STDMETHODIMP CSdoMachine::GetAttachedComputer(
  661. /*[out]*/ BSTR* bstrComputerName
  662. )
  663. {
  664. CSdoLock theLock(*this);
  665. _ASSERT( m_fAttached );
  666. if ( ! m_fAttached )
  667. return E_FAIL;
  668. _ASSERT( NULL != bstrComputerName );
  669. if ( NULL == bstrComputerName )
  670. return E_INVALIDARG;
  671. *bstrComputerName = SysAllocString(m_dsIAS.GetServerName());
  672. if ( NULL != *bstrComputerName )
  673. return S_OK;
  674. else
  675. return E_OUTOFMEMORY;
  676. }
  677. //////////////////////////////////////////////////////////////////////////////
  678. STDMETHODIMP CSdoMachine::GetSDOSchema(
  679. /*[out]*/ IUnknown** ppSDOSchema
  680. )
  681. {
  682. CSdoLock theLock(*this);
  683. _ASSERT( m_fAttached );
  684. if ( ! m_fAttached )
  685. return E_FAIL;
  686. _ASSERT( NULL != ppSDOSchema );
  687. if ( NULL == ppSDOSchema )
  688. return E_INVALIDARG;
  689. (*ppSDOSchema = m_pSdoSchema)->AddRef();
  690. return S_OK;
  691. }
  692. ///////////////////////////////////////////////////////////////////////////////
  693. // Private member functions
  694. ///////////////////////////////////////////////////////////////////////////////
  695. HRESULT CSdoMachine::CreateSDOSchema()
  696. {
  697. auto_ptr<SDO_SCHEMA_OBJ> pSchema (new SDO_SCHEMA_OBJ);
  698. HRESULT hr = pSchema->Initialize(NULL);
  699. if ( SUCCEEDED(hr) )
  700. m_pSdoSchema = dynamic_cast<ISdoSchema*>(pSchema.release());
  701. return hr;
  702. }
  703. ///////////////////////////////////////////////////////////////////////////////
  704. HRESULT CSdoMachine::InitializeSDOSchema()
  705. {
  706. HRESULT hr = S_OK;
  707. if ( ! m_fSchemaInitialized )
  708. {
  709. // First initialize the IAS data store
  710. //
  711. hr = m_dsIAS.InitializeDS();
  712. if ( SUCCEEDED(hr) )
  713. {
  714. // Get the root data store object for the SDO schema
  715. //
  716. CComPtr<IDataStoreContainer> pDSRootContainer = m_dsIAS.GetDSRootContainer();
  717. _bstr_t bstrSchemaName = SDO_SCHEMA_ROOT_OBJECT;
  718. CComPtr<IDataStoreObject> pSchemaDataStore;
  719. hr = pDSRootContainer->Item(bstrSchemaName, &pSchemaDataStore);
  720. if ( SUCCEEDED(hr) )
  721. {
  722. // Initialize the SDO schema from the SDO schema data store
  723. //
  724. PSDO_SCHEMA_OBJ pSchema = dynamic_cast<PSDO_SCHEMA_OBJ>(m_pSdoSchema);
  725. hr = pSchema->Initialize(pSchemaDataStore);
  726. if ( SUCCEEDED(hr) )
  727. m_fSchemaInitialized = true;
  728. }
  729. else
  730. {
  731. IASTracePrintf("Error in Machine SDO - InitializeSDOSchema() - Could not locate schema data store...");
  732. }
  733. }
  734. else
  735. {
  736. IASTracePrintf("Error in Machine SDO - InitializeSDOSchema() - Could not initialize the IAS data store...");
  737. }
  738. }
  739. return hr;
  740. }
  741. // Returns TRUE if the attached machine has a DS.
  742. BOOL CSdoMachine::hasDirectory() throw ()
  743. {
  744. if (dsType == Directory_Unknown)
  745. {
  746. PDSROLE_PRIMARY_DOMAIN_INFO_BASIC info;
  747. DWORD error = DsRoleGetPrimaryDomainInformation(
  748. m_dsIAS.GetServerName(),
  749. DsRolePrimaryDomainInfoBasic,
  750. (PBYTE*)&info
  751. );
  752. if (error == NO_ERROR)
  753. {
  754. if (info->Flags & DSROLE_PRIMARY_DS_RUNNING)
  755. {
  756. dsType = Directory_Available;
  757. }
  758. else
  759. {
  760. dsType = Directory_None;
  761. }
  762. NetApiBufferFree(info);
  763. }
  764. }
  765. return dsType == Directory_Available;
  766. }