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.

907 lines
28 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. memset(&m_Limits, 0, sizeof(m_Limits));
  134. }
  135. //////////////////////////////////////////////////////////////////////////////
  136. CSdoMachine::~CSdoMachine()
  137. {
  138. if ( m_fAttached )
  139. {
  140. m_dsIAS.Disconnect();
  141. m_dsAD.Disconnect();
  142. m_pSdoSchema->Release();
  143. if ( m_pSdoDictionary )
  144. m_pSdoDictionary->Release();
  145. IASUninitialize();
  146. }
  147. }
  148. //////////////////////
  149. // ISdoMachine Methods
  150. //////////////////////////////////////////////////////////////////////////////
  151. STDMETHODIMP CSdoMachine::Attach(
  152. /*[in]*/ BSTR computerName
  153. )
  154. {
  155. CSdoLock theLock(*this);
  156. _ASSERT( ! m_fAttached );
  157. if ( m_fAttached )
  158. return E_FAIL;
  159. HRESULT hr = E_FAIL;
  160. try
  161. {
  162. if ( computerName )
  163. IASTracePrintf("Machine SDO is attempting to attach to computer: '%ls'...", computerName);
  164. else
  165. IASTracePrintf("Machine SDO is attempting to attach to the local computer...");
  166. IASTracePrintf("Machine SDO is initializing the IAS support services...");
  167. if ( IASInitialize() )
  168. {
  169. hr = m_dsIAS.Connect(computerName, NULL, NULL);
  170. if ( SUCCEEDED(hr) )
  171. {
  172. DWORD error = IASGetProductLimits(computerName, &m_Limits);
  173. if (error == NO_ERROR)
  174. {
  175. IASTracePrintf("Machine SDO is creating the SDO schema...");
  176. hr = CreateSDOSchema();
  177. if ( SUCCEEDED(hr) )
  178. {
  179. IASTracePrintf("Machine SDO has successfully attached to computer: '%ls'...",m_dsIAS.GetServerName());
  180. m_fAttached = true;
  181. }
  182. else
  183. {
  184. m_dsIAS.Disconnect();
  185. IASUninitialize();
  186. }
  187. }
  188. else
  189. {
  190. hr = HRESULT_FROM_WIN32(error);
  191. m_dsIAS.Disconnect();
  192. IASUninitialize();
  193. }
  194. }
  195. else
  196. {
  197. IASTracePrintf("Error in Machine SDO - Attach() - Could not connect to IAS data store...");
  198. }
  199. }
  200. else
  201. {
  202. IASTracePrintf("Error in Machine SDO - Attach() - Could not initialize IAS support services...");
  203. }
  204. }
  205. catch(...)
  206. {
  207. IASTracePrintf("Error in Machine SDO - Attach() - Caught unknown exception...");
  208. hr = E_UNEXPECTED;
  209. }
  210. return hr;
  211. }
  212. //////////////////////////////////////////////////////////////////////////////
  213. STDMETHODIMP CSdoMachine::GetDictionarySDO(
  214. /*[out]*/ IUnknown** ppDictionarySdo
  215. )
  216. {
  217. CSdoLock theLock(*this);
  218. IASTracePrintf("Machine SDO is retrieving the Dictionary SDO...");
  219. HRESULT hr = S_OK;
  220. try
  221. {
  222. do
  223. {
  224. // Check preconditions
  225. //
  226. _ASSERT( m_fAttached );
  227. if ( ! m_fAttached )
  228. {
  229. hr = E_FAIL;
  230. break;
  231. }
  232. _ASSERT( NULL != ppDictionarySdo );
  233. if ( NULL == ppDictionarySdo )
  234. {
  235. hr = E_POINTER;
  236. break;
  237. }
  238. // The dictionary is a singleton...
  239. //
  240. if (NULL == m_pSdoDictionary)
  241. {
  242. hr = InitializeSDOSchema();
  243. if ( FAILED(hr) )
  244. {
  245. IASTracePrintf("Error in Machine SDO - GetDictionarySDO() - Could not initialize the SDO schema...");
  246. break;
  247. }
  248. // Create the Dictionary SDO
  249. CComPtr<SdoDictionary> pSdoDictionary;
  250. hr = SdoDictionary::createInstance(
  251. m_dsIAS.GetConfigPath(),
  252. !m_dsIAS.IsRemoteServer(),
  253. (SdoDictionary**)&m_pSdoDictionary
  254. );
  255. if (FAILED(hr))
  256. {
  257. IASTraceFailure("SdoDictionary::createInstance", hr);
  258. break;
  259. }
  260. }
  261. // Return the dictionary interface to the caller
  262. //
  263. (*ppDictionarySdo = m_pSdoDictionary)->AddRef();
  264. } while ( FALSE );
  265. }
  266. catch(...)
  267. {
  268. IASTracePrintf("Error in Machine SDO - GetDictionarySDO() - Caught unknown exception...");
  269. hr = E_UNEXPECTED;
  270. }
  271. return hr;
  272. }
  273. const wchar_t g_IASService[] = L"IAS";
  274. const wchar_t g_RASService[] = L"RemoteAccess";
  275. const wchar_t g_Sentinel[] = L"Sentinel";
  276. LPCWSTR CSdoMachine::m_SupportedServices[MACHINE_MAX_SERVICES] = {
  277. g_IASService,
  278. g_RASService,
  279. g_Sentinel
  280. };
  281. //////////////////////////////////////////////////////////////////////////////
  282. STDMETHODIMP CSdoMachine::GetServiceSDO(
  283. /*[in]*/ IASDATASTORE dataStore,
  284. /*[in]*/ BSTR serviceName,
  285. /*[out]*/ IUnknown** ppServiceSdo
  286. )
  287. {
  288. CSdoLock theLock(*this);
  289. _ASSERT( m_fAttached );
  290. if ( ! m_fAttached )
  291. return E_FAIL;
  292. _ASSERT(
  293. ( DATA_STORE_LOCAL == dataStore || DATA_STORE_DIRECTORY == dataStore ) &&
  294. NULL != serviceName &&
  295. NULL != ppServiceSdo
  296. );
  297. if ( ( DATA_STORE_LOCAL != dataStore && DATA_STORE_DIRECTORY != dataStore ) ||
  298. NULL == serviceName ||
  299. NULL == ppServiceSdo
  300. )
  301. {
  302. return E_INVALIDARG;
  303. }
  304. IASTracePrintf("Machine SDO is attempting to retrieve the Service SDO for service: %ls...", serviceName);
  305. int i;
  306. for ( i = 0; i < MACHINE_MAX_SERVICES; i++ )
  307. {
  308. if ( ! lstrcmp(serviceName, m_SupportedServices[i]) )
  309. {
  310. break;
  311. }
  312. else
  313. {
  314. if ( ! lstrcmp(m_SupportedServices[i], g_Sentinel ) )
  315. return E_INVALIDARG;
  316. }
  317. }
  318. HRESULT hr = E_INVALIDARG;
  319. try
  320. {
  321. do
  322. {
  323. hr = InitializeSDOSchema();
  324. if ( FAILED(hr) )
  325. {
  326. IASTracePrintf("Error in Machine SDO - GetServiceSDO() - Could not initialize the SDO schema...");
  327. break;
  328. }
  329. CComBSTR bstrServiceName(DS_OBJECT_SERVICE);
  330. if (!bstrServiceName)
  331. {
  332. hr = E_OUTOFMEMORY;
  333. break;
  334. }
  335. CComPtr<IDataStoreObject> pDSObject;
  336. hr = (m_dsIAS.GetDSRootContainer())->Item(bstrServiceName, &pDSObject);
  337. if ( FAILED(hr) )
  338. {
  339. IASTracePrintf("Error in Machine SDO - GetServiceSDO() - Could not locate IAS service data store...");
  340. break;
  341. }
  342. CComPtr<ISdo> pSdoService;
  343. pSdoService.p = ::MakeSDO(
  344. serviceName,
  345. SDO_PROG_ID_SERVICE,
  346. static_cast<ISdoMachine*>(this),
  347. pDSObject,
  348. NULL,
  349. false
  350. );
  351. if ( NULL == pSdoService.p )
  352. {
  353. IASTracePrintf("Error in Machine SDO - GetServiceSDO() - MakeSDO() failed...");
  354. hr = E_FAIL;
  355. break;
  356. }
  357. hr = pSdoService->QueryInterface(IID_IDispatch, (void**)ppServiceSdo);
  358. if ( FAILED(hr) )
  359. {
  360. IASTracePrintf("Error in Machine SDO - GetServiceSDO() - QueryInterface(IDispatch) failed...");
  361. break;
  362. }
  363. } while ( FALSE );
  364. }
  365. catch(...)
  366. {
  367. IASTracePrintf("Error in Machine SDO - GetServiceSDO() - Caught unknown exception...");
  368. hr = E_UNEXPECTED;
  369. }
  370. return hr;
  371. }
  372. //////////////////////////////////////////////////////////////////////////////
  373. const wchar_t DOWNLEVEL_NAME[] = L"downlevel";
  374. STDMETHODIMP CSdoMachine::GetUserSDO(
  375. /*[in]*/ IASDATASTORE eDataStore,
  376. /*[in]*/ BSTR bstrUserName,
  377. /*[out]*/ IUnknown** ppUserSdo
  378. )
  379. {
  380. CSdoLock theLock(*this);
  381. _ASSERT( m_fAttached );
  382. if ( ! m_fAttached )
  383. return E_FAIL;
  384. _ASSERT(
  385. ( DATA_STORE_LOCAL == eDataStore || DATA_STORE_DIRECTORY == eDataStore ) &&
  386. NULL != bstrUserName &&
  387. NULL != ppUserSdo
  388. );
  389. if ( ( DATA_STORE_LOCAL != eDataStore && DATA_STORE_DIRECTORY != eDataStore ) ||
  390. NULL == bstrUserName ||
  391. NULL == ppUserSdo
  392. )
  393. return E_INVALIDARG;
  394. HRESULT hr = E_FAIL;
  395. // Map local users to the DS if we're attached to a machine with
  396. // a directory.
  397. if (eDataStore == DATA_STORE_LOCAL && hasDirectory())
  398. {
  399. eDataStore = DATA_STORE_DIRECTORY;
  400. }
  401. // If we're connecting to a directory and the username doesn't begin with
  402. // "LDAP://", then we'll assume it's a SAM account name.
  403. BSTR ldapPath = NULL;
  404. if (eDataStore == DATA_STORE_DIRECTORY &&
  405. wcsncmp(bstrUserName, L"LDAP://", 7))
  406. {
  407. hr = IASGetLDAPPathForUser(
  408. m_dsIAS.GetServerName(),
  409. bstrUserName,
  410. &ldapPath
  411. );
  412. if (FAILED(hr)) { return hr; }
  413. bstrUserName = ldapPath;
  414. }
  415. IASTracePrintf("Machine SDO is attempting to retrieve the RAS User SDO for user: %ls...", bstrUserName);
  416. ISdo* pSdoUser = NULL;
  417. try
  418. {
  419. do
  420. {
  421. // Get the IDataStoreObject interface for the new User SDO.
  422. // We'll use the IDataStoreObject interface to read/write User SDO properties.
  423. //
  424. bool fUseDownLevelAPI = false;
  425. bool fUseNetAPI = true;
  426. CComPtr<IDataStoreObject> pDSObject;
  427. _variant_t vtSAMAccountName;
  428. if ( DATA_STORE_DIRECTORY == eDataStore )
  429. {
  430. // Make sure we're connected to the directory
  431. //
  432. if ( ! m_dsAD.IsConnected() )
  433. {
  434. hr = m_dsAD.Connect(m_dsIAS.GetServerName(), NULL, NULL);
  435. if ( FAILED(hr) )
  436. {
  437. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not connect to the directory data store...");
  438. break;
  439. }
  440. }
  441. // Make sure it's initialized.
  442. hr = m_dsAD.InitializeDS();
  443. if ( FAILED(hr) )
  444. {
  445. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not initialize the directory data store...");
  446. break;
  447. }
  448. // Get the user object from the directory
  449. //
  450. hr = (m_dsAD.GetDSRoot())->OpenObject(bstrUserName, &pDSObject);
  451. if ( FAILED(hr) )
  452. {
  453. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not retrieve user object from DS...");
  454. break;
  455. }
  456. // If we're connected to a dc in a mixed domain we'll need to first get the users
  457. // SAM account name from the user object in the active directory and then treat the
  458. // GetUserSDO() call as if the caller specified DATA_STORE_LOCAL. We also use
  459. // downlevel APIs (SAM) because its a mixed domain.
  460. //
  461. if ( m_dsAD.IsMixedMode() )
  462. {
  463. IASTracePrintf("Machine SDO - GetUserSDO() - Current DC (Server) %ls is in a mixed mode domain...", m_dsAD.GetServerName());
  464. hr = pDSObject->GetValue(IAS_NTDS_SAM_ACCOUNT_NAME, &vtSAMAccountName);
  465. if ( FAILED(hr) )
  466. {
  467. IASTracePrintf("Error in Server SDO - GetUserSDO() - Could not retrieve users SAM account name...");
  468. break;
  469. }
  470. bstrUserName = V_BSTR(&vtSAMAccountName);
  471. fUseDownLevelAPI = true;
  472. pDSObject.Release();
  473. IASTracePrintf("Server SDO - GetUserSDO() - User's SAM account name is: %ls...", (LPWSTR)bstrUserName);
  474. }
  475. else
  476. {
  477. // Use the directory data store object for all subsequent property read/write
  478. // operations on this User SDO.
  479. //
  480. IASTracePrintf("Server SDO - GetUserSDO() - Using active directory for user properties...");
  481. fUseNetAPI = false;
  482. }
  483. }
  484. if ( fUseNetAPI )
  485. {
  486. // Create the net data store and aquire the data store object interfaces
  487. // we'll use to complete the GetUserSDO() operation
  488. //
  489. CComPtr<IDataStore2> pDSNet;
  490. hr = CoCreateInstance(
  491. __uuidof(NetDataStore),
  492. NULL,
  493. CLSCTX_INPROC_SERVER,
  494. IID_IDataStore2,
  495. (void**)&pDSNet
  496. );
  497. if ( FAILED(hr) )
  498. {
  499. IASTracePrintf("Error in Machine SDO - GetUserSDO() - CoCreateInstance(NetDataStore) failed...");
  500. break;
  501. }
  502. hr = pDSNet->Initialize(NULL, NULL, NULL);
  503. if ( FAILED(hr) )
  504. {
  505. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not initialize net data store...");
  506. break;
  507. }
  508. CComPtr<IDataStoreObject> pDSRootObject;
  509. hr = pDSNet->get_Root(&pDSRootObject);
  510. if ( FAILED(hr) )
  511. {
  512. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not get Root object from net data store...");
  513. break;
  514. }
  515. CComPtr<IDataStoreContainer> pDSContainer;
  516. hr = pDSRootObject->QueryInterface(IID_IDataStoreContainer, (void**)&pDSContainer);
  517. if ( FAILED(hr) )
  518. {
  519. IASTracePrintf("Error in Machine SDO - GetUserSDO() - QueryInterface(IID_IDataStoreContainer) failed...");
  520. break;
  521. }
  522. // Get the name of the attached computer and use it to aquire a "Server"
  523. // (machine) object from the data store.
  524. //
  525. CComPtr<IDataStoreObject> pDSObjectMachine;
  526. if ( fUseDownLevelAPI )
  527. {
  528. _bstr_t bstrServerName = m_dsAD.GetServerName();
  529. IASTracePrintf("Machine SDO - GetUserSDO() - Using server %ls with downlevel APIs...", (LPWSTR)bstrServerName);
  530. hr = pDSContainer->Item(bstrServerName, &pDSObjectMachine);
  531. if ( FAILED(hr) )
  532. {
  533. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not obtain server object from net data store...");
  534. break;
  535. }
  536. _bstr_t bstrDownLevel = DOWNLEVEL_NAME;
  537. _variant_t vtDownLevel;
  538. V_BOOL(&vtDownLevel) = VARIANT_TRUE;
  539. V_VT(&vtDownLevel) = VT_BOOL;
  540. hr = pDSObjectMachine->PutValue(bstrDownLevel, &vtDownLevel);
  541. if ( FAILED(hr) )
  542. {
  543. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not set downlevel data store mode...");
  544. break;
  545. }
  546. }
  547. else
  548. {
  549. _bstr_t bstrServerName = m_dsIAS.GetServerName();
  550. IASTracePrintf("Machine SDO - GetUserSDO() - Using server %ls with Net APIs...", (LPWSTR)bstrServerName);
  551. hr = pDSContainer->Item(bstrServerName, &pDSObjectMachine);
  552. if ( FAILED(hr) )
  553. {
  554. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not obtain server object from data store...");
  555. break;
  556. }
  557. }
  558. pDSContainer.Release();
  559. // Get "User" object from the "Server" object. We'll use the "User" object in
  560. // all subsequent read/write operations on the User SDO.
  561. //
  562. hr = pDSObjectMachine->QueryInterface(IID_IDataStoreContainer, (void**)&pDSContainer);
  563. if ( FAILED(hr) )
  564. {
  565. IASTracePrintf("Error in Machine SDO - GetUserSDO() - QueryInterface(IID_IDataStoreContainer) failed...");
  566. break;
  567. }
  568. hr = pDSContainer->Item(bstrUserName, &pDSObject);
  569. if ( FAILED(hr) )
  570. {
  571. IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not obtain user object from data store...");
  572. break;
  573. }
  574. }
  575. // Create and initialize the User SDO
  576. //
  577. pSdoUser = ::MakeSDO(
  578. NULL,
  579. SDO_PROG_ID_USER,
  580. static_cast<ISdoMachine*>(this),
  581. pDSObject,
  582. NULL,
  583. false
  584. );
  585. if ( NULL == pSdoUser )
  586. {
  587. IASTracePrintf("Error in Machine SDO - GetUserSDO() - MakeSDO() failed...");
  588. hr = E_FAIL;
  589. }
  590. else
  591. {
  592. CComPtr<IDispatch> pSdoDispatch;
  593. hr = pSdoUser->QueryInterface(IID_IDispatch, (void**)&pSdoDispatch);
  594. if ( FAILED(hr) )
  595. IASTracePrintf("Error in Machine SDO - GetUserSDO() - QueryInterface(IDispatch) failed...");
  596. else
  597. (*ppUserSdo = pSdoDispatch)->AddRef();
  598. }
  599. }
  600. while ( FALSE);
  601. }
  602. catch(...)
  603. {
  604. IASTracePrintf("Error in Server SDO - GetUserSDO() - Caught unknown exception...");
  605. hr = E_FAIL;
  606. }
  607. if ( pSdoUser )
  608. pSdoUser->Release();
  609. if (ldapPath) { SysFreeString(ldapPath); }
  610. return hr;
  611. }
  612. //////////////////////////////////////////////////////////////////////////////
  613. STDMETHODIMP CSdoMachine::GetOSType(
  614. /*[out]*/ IASOSTYPE* eOSType
  615. )
  616. {
  617. CSdoLock theLock(*this);
  618. _ASSERT( m_fAttached );
  619. if ( ! m_fAttached )
  620. return E_FAIL;
  621. _ASSERT( NULL != eOSType );
  622. if ( NULL == eOSType )
  623. return E_INVALIDARG;
  624. // Get the OS info now
  625. //
  626. HRESULT hr = m_objServerInfo.GetOSInfo (
  627. (LPWSTR)m_dsIAS.GetServerName(),
  628. eOSType
  629. );
  630. if ( FAILED (hr) )
  631. IASTracePrintf("Error in Machine SDO - GetOSType() failed with error: %lx...", hr);
  632. return hr;
  633. }
  634. //////////////////////////////////////////////////////////////////////////////
  635. STDMETHODIMP CSdoMachine::GetDomainType(
  636. /*[out]*/ IASDOMAINTYPE* eDomainType
  637. )
  638. {
  639. CSdoLock theLock(*this);
  640. _ASSERT( m_fAttached );
  641. if ( ! m_fAttached )
  642. return E_FAIL;
  643. _ASSERT( NULL != eDomainType );
  644. if ( NULL == eDomainType )
  645. return E_INVALIDARG;
  646. HRESULT hr = m_objServerInfo.GetDomainInfo (
  647. OBJECT_TYPE_COMPUTER,
  648. (LPWSTR)m_dsIAS.GetServerName(),
  649. eDomainType
  650. );
  651. if (FAILED (hr))
  652. IASTracePrintf("Error in Machine SDO - GetDomainType() - failed with error: %lx...", hr);
  653. return hr;
  654. }
  655. //////////////////////////////////////////////////////////////////////////////
  656. STDMETHODIMP CSdoMachine::IsDirectoryAvailable(
  657. /*[out]*/ VARIANT_BOOL* boolDirectoryAvailable
  658. )
  659. {
  660. CSdoLock theLock(*this);
  661. _ASSERT( m_fAttached );
  662. if ( ! m_fAttached )
  663. return E_FAIL;
  664. _ASSERT( NULL != boolDirectoryAvailable );
  665. if ( NULL == boolDirectoryAvailable )
  666. return E_INVALIDARG;
  667. *boolDirectoryAvailable = VARIANT_FALSE;
  668. return S_OK;
  669. }
  670. //////////////////////////////////////////////////////////////////////////////
  671. STDMETHODIMP CSdoMachine::GetAttachedComputer(
  672. /*[out]*/ BSTR* bstrComputerName
  673. )
  674. {
  675. CSdoLock theLock(*this);
  676. _ASSERT( m_fAttached );
  677. if ( ! m_fAttached )
  678. return E_FAIL;
  679. _ASSERT( NULL != bstrComputerName );
  680. if ( NULL == bstrComputerName )
  681. return E_INVALIDARG;
  682. *bstrComputerName = SysAllocString(m_dsIAS.GetServerName());
  683. if ( NULL != *bstrComputerName )
  684. return S_OK;
  685. else
  686. return E_OUTOFMEMORY;
  687. }
  688. //////////////////////////////////////////////////////////////////////////////
  689. STDMETHODIMP CSdoMachine::GetSDOSchema(
  690. /*[out]*/ IUnknown** ppSDOSchema
  691. )
  692. {
  693. CSdoLock theLock(*this);
  694. _ASSERT( m_fAttached );
  695. if ( ! m_fAttached )
  696. return E_FAIL;
  697. _ASSERT( NULL != ppSDOSchema );
  698. if ( NULL == ppSDOSchema )
  699. return E_INVALIDARG;
  700. (*ppSDOSchema = m_pSdoSchema)->AddRef();
  701. return S_OK;
  702. }
  703. STDMETHODIMP CSdoMachine::get_Limits(IAS_PRODUCT_LIMITS* pVal)
  704. {
  705. if (pVal == 0)
  706. {
  707. return E_POINTER;
  708. }
  709. *pVal = m_Limits;
  710. return S_OK;
  711. }
  712. ///////////////////////////////////////////////////////////////////////////////
  713. // Private member functions
  714. ///////////////////////////////////////////////////////////////////////////////
  715. HRESULT CSdoMachine::CreateSDOSchema()
  716. {
  717. auto_ptr<SDO_SCHEMA_OBJ> pSchema (new SDO_SCHEMA_OBJ);
  718. HRESULT hr = pSchema->Initialize(NULL);
  719. if ( SUCCEEDED(hr) )
  720. m_pSdoSchema = dynamic_cast<ISdoSchema*>(pSchema.release());
  721. return hr;
  722. }
  723. ///////////////////////////////////////////////////////////////////////////////
  724. HRESULT CSdoMachine::InitializeSDOSchema()
  725. {
  726. HRESULT hr = S_OK;
  727. if ( ! m_fSchemaInitialized )
  728. {
  729. // First initialize the IAS data store
  730. //
  731. hr = m_dsIAS.InitializeDS();
  732. if ( SUCCEEDED(hr) )
  733. {
  734. // Get the root data store object for the SDO schema
  735. //
  736. CComPtr<IDataStoreContainer> pDSRootContainer = m_dsIAS.GetDSRootContainer();
  737. _bstr_t bstrSchemaName = SDO_SCHEMA_ROOT_OBJECT;
  738. CComPtr<IDataStoreObject> pSchemaDataStore;
  739. hr = pDSRootContainer->Item(bstrSchemaName, &pSchemaDataStore);
  740. if ( SUCCEEDED(hr) )
  741. {
  742. // Initialize the SDO schema from the SDO schema data store
  743. //
  744. PSDO_SCHEMA_OBJ pSchema = dynamic_cast<PSDO_SCHEMA_OBJ>(m_pSdoSchema);
  745. hr = pSchema->Initialize(pSchemaDataStore);
  746. if ( SUCCEEDED(hr) )
  747. m_fSchemaInitialized = true;
  748. }
  749. else
  750. {
  751. IASTracePrintf("Error in Machine SDO - InitializeSDOSchema() - Could not locate schema data store...");
  752. }
  753. }
  754. else
  755. {
  756. IASTracePrintf("Error in Machine SDO - InitializeSDOSchema() - Could not initialize the IAS data store...");
  757. }
  758. }
  759. return hr;
  760. }
  761. // Returns TRUE if the attached machine has a DS.
  762. BOOL CSdoMachine::hasDirectory() throw ()
  763. {
  764. if (dsType == Directory_Unknown)
  765. {
  766. PDSROLE_PRIMARY_DOMAIN_INFO_BASIC info;
  767. DWORD error = DsRoleGetPrimaryDomainInformation(
  768. m_dsIAS.GetServerName(),
  769. DsRolePrimaryDomainInfoBasic,
  770. (PBYTE*)&info
  771. );
  772. if (error == NO_ERROR)
  773. {
  774. if (info->Flags & DSROLE_PRIMARY_DS_RUNNING)
  775. {
  776. dsType = Directory_Available;
  777. }
  778. else
  779. {
  780. dsType = Directory_None;
  781. }
  782. NetApiBufferFree(info);
  783. }
  784. }
  785. return dsType == Directory_Available;
  786. }