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.

2035 lines
50 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ConfigurationConnection.cpp
  7. //
  8. // Description:
  9. // CConfigurationConnection implementation.
  10. //
  11. // Maintained By:
  12. // Galen Barbee (GalenB) 02-FEB-2000
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. #include "Pch.h"
  16. #include "TaskPollingCallback.h"
  17. #include "ConfigConnection.h"
  18. #include <ClusCfgPrivate.h>
  19. #include <nameutil.h>
  20. DEFINE_THISCLASS("CConfigurationConnection");
  21. //////////////////////////////////////////////////////////////////////////////
  22. //++
  23. //
  24. // HrCreateServerObject
  25. //
  26. // Description:
  27. // Create a ClusCfgServer object and get three interfaces from it
  28. // for use by CConfigurationConnection::ConnectTo().
  29. //
  30. // Arguments:
  31. // pcwszMachineNameIn
  32. // The machine on which to create the object. Can be NULL, which
  33. // creates the object on the local machine.
  34. // ppccsOut
  35. // The IClusCfgServer interface on the newly created object.
  36. // ppccvOut
  37. // The IClusCfgVerify interface on the newly created object.
  38. // ppcciOut
  39. // The IClusCfgInitialize interface on the newly created object.
  40. //
  41. // Return Values:
  42. // S_OK - Creation succeeded and all returned interfaces are valid.
  43. //
  44. // Possible failure codes from CoCreateInstanceEx or QueryInterface.
  45. //
  46. // Remarks:
  47. // This function consolidates code that was duplicated in two parts of
  48. // CConfigurationConnection::ConnectTo().
  49. //
  50. // On failure, all returned pointers are NULL.
  51. //
  52. //--
  53. //////////////////////////////////////////////////////////////////////////////
  54. static
  55. HRESULT
  56. HrCreateServerObject(
  57. LPCWSTR pcwszMachineNameIn
  58. , IClusCfgServer ** ppccsOut
  59. , IClusCfgVerify ** ppccvOut
  60. , IClusCfgInitialize ** ppcciOut
  61. )
  62. {
  63. TraceFunc( "" );
  64. Assert( ppccsOut != NULL );
  65. Assert( ppccvOut != NULL );
  66. Assert( ppcciOut != NULL );
  67. HRESULT hr = S_OK;
  68. COSERVERINFO serverinfo;
  69. COSERVERINFO * pserverinfo = NULL;
  70. MULTI_QI rgmqi[ 3 ];
  71. CLSCTX ctx = CLSCTX_INPROC_SERVER;
  72. size_t idx;
  73. ZeroMemory( rgmqi, sizeof( rgmqi ) );
  74. if ( ( ppccsOut == NULL ) || ( ppccvOut == NULL ) || ( ppcciOut == NULL ) )
  75. {
  76. hr = THR( E_POINTER );
  77. goto Cleanup;
  78. }
  79. *ppccsOut = NULL;
  80. *ppccvOut = NULL;
  81. *ppcciOut = NULL;
  82. rgmqi[ 0 ].pIID = &IID_IClusCfgVerify;
  83. rgmqi[ 1 ].pIID = &IID_IClusCfgServer;
  84. rgmqi[ 2 ].pIID = &IID_IClusCfgInitialize;
  85. if ( pcwszMachineNameIn != NULL )
  86. {
  87. ZeroMemory( &serverinfo, sizeof( serverinfo ) );
  88. serverinfo.pwszName = const_cast< LPWSTR >( pcwszMachineNameIn );
  89. pserverinfo = &serverinfo;
  90. ctx = CLSCTX_REMOTE_SERVER;
  91. }
  92. hr = CoCreateInstanceEx(
  93. CLSID_ClusCfgServer
  94. , NULL
  95. , ctx
  96. , pserverinfo
  97. , ARRAYSIZE( rgmqi )
  98. , rgmqi
  99. );
  100. if ( FAILED( hr ) )
  101. {
  102. goto Cleanup;
  103. }
  104. for ( idx = 0; idx < ARRAYSIZE( rgmqi ); ++idx )
  105. {
  106. if ( FAILED( rgmqi[ idx ].hr ) )
  107. {
  108. hr = THR( rgmqi[ idx ].hr );
  109. goto Cleanup;
  110. } // if: qi failed
  111. }
  112. *ppccvOut = TraceInterface( L"ClusCfgServer!Proxy", IClusCfgVerify, reinterpret_cast< IClusCfgVerify * >( rgmqi[ 0 ].pItf ), 1 );
  113. *ppccsOut = TraceInterface( L"ClusCfgServer!Proxy", IClusCfgServer, reinterpret_cast< IClusCfgServer * >( rgmqi[ 1 ].pItf ), 1 );
  114. *ppcciOut = TraceInterface( L"ClusCfgServer!Proxy", IClusCfgInitialize, reinterpret_cast< IClusCfgInitialize * >( rgmqi[ 2 ].pItf ), 1 );
  115. ZeroMemory( rgmqi, sizeof( rgmqi ) ); // Done with these; don't clean them up.
  116. Cleanup:
  117. for ( idx = 0; idx < ARRAYSIZE( rgmqi ); ++idx )
  118. {
  119. if ( rgmqi[ idx ].pItf != NULL )
  120. {
  121. rgmqi[ idx ].pItf->Release();
  122. }
  123. }
  124. HRETURN( hr );
  125. } //*** HrCreateServerObject
  126. // ************************************************************************
  127. //
  128. // Constructor / Destructor
  129. //
  130. // ************************************************************************
  131. //////////////////////////////////////////////////////////////////////////////
  132. //++
  133. //
  134. // HRESULT
  135. // CConfigurationConnection::S_HrCreateInstance(
  136. // IUnknown ** ppunkOut
  137. // )
  138. //
  139. //--
  140. //////////////////////////////////////////////////////////////////////////////
  141. HRESULT
  142. CConfigurationConnection::S_HrCreateInstance(
  143. IUnknown ** ppunkOut
  144. )
  145. {
  146. TraceFunc( "" );
  147. HRESULT hr = S_OK;
  148. CConfigurationConnection * pcc = NULL;
  149. Assert( ppunkOut != NULL );
  150. if ( ppunkOut == NULL )
  151. {
  152. hr = THR( E_POINTER );
  153. goto Cleanup;
  154. }
  155. pcc = new CConfigurationConnection;
  156. if ( pcc == NULL )
  157. {
  158. hr = THR( E_OUTOFMEMORY );
  159. goto Cleanup;
  160. }
  161. hr = THR( pcc->HrInit() );
  162. if ( FAILED( hr ) )
  163. {
  164. goto Cleanup;
  165. }
  166. hr = THR( pcc->TypeSafeQI( IUnknown, ppunkOut ) );
  167. if ( FAILED( hr ) )
  168. {
  169. goto Cleanup;
  170. }
  171. Cleanup:
  172. if ( pcc != NULL )
  173. {
  174. pcc->Release();
  175. }
  176. HRETURN( hr );
  177. } //*** CConfigurationConnection::S_HrCreateInstance
  178. //////////////////////////////////////////////////////////////////////////////
  179. //++
  180. //
  181. // CConfigurationConnection::CConfigurationConnection
  182. //
  183. //--
  184. //////////////////////////////////////////////////////////////////////////////
  185. CConfigurationConnection::CConfigurationConnection( void )
  186. : m_cRef( 1 )
  187. {
  188. TraceFunc( "" );
  189. InterlockedIncrement( &g_cObjects );
  190. TraceFuncExit();
  191. } //*** CConfigurationConnection::CConfigurationConnection
  192. //////////////////////////////////////////////////////////////////////////////
  193. //++
  194. //
  195. // CConfigurationConnection::HrInit
  196. //
  197. // Description:
  198. // Initialize the object.
  199. //
  200. // Arguments:
  201. // None.
  202. //
  203. // Return Values:
  204. // S_OK - Success.
  205. // Other HRESULTs.
  206. //
  207. //--
  208. //////////////////////////////////////////////////////////////////////////////
  209. STDMETHODIMP
  210. CConfigurationConnection::HrInit( void )
  211. {
  212. TraceFunc( "" );
  213. HRESULT hr = S_OK;
  214. // IUnknown stuff
  215. Assert( m_cRef == 1 );
  216. // IConfigurationConnection
  217. Assert( m_cookieGITServer == 0 );
  218. Assert( m_cookieGITVerify == 0 );
  219. Assert( m_cookieGITCallbackTask == 0 );
  220. Assert( m_pcccb == NULL );
  221. Assert( m_bstrLocalComputerName == NULL );
  222. Assert( m_bstrLocalHostname == NULL );
  223. Assert( m_hrLastStatus == S_OK );
  224. Assert( m_bstrBindingString == NULL );
  225. //
  226. // Figure out the local computer name.
  227. //
  228. hr = THR( HrGetComputerName(
  229. ComputerNameDnsFullyQualified
  230. , &m_bstrLocalComputerName
  231. , TRUE // fBestEffortIn
  232. ) );
  233. if ( FAILED( hr ) )
  234. {
  235. goto Cleanup;
  236. }
  237. hr = THR( HrGetComputerName(
  238. ComputerNameDnsHostname
  239. , &m_bstrLocalHostname
  240. , TRUE // fBestEffortIn
  241. ) );
  242. if ( FAILED( hr ) )
  243. {
  244. goto Cleanup;
  245. }
  246. Cleanup:
  247. HRETURN( hr );
  248. } //*** CConfigurationConnection::HrInit
  249. //////////////////////////////////////////////////////////////////////////////
  250. //++
  251. //
  252. // CConfigurationConnection::~CConfigurationConnection
  253. //
  254. //--
  255. //////////////////////////////////////////////////////////////////////////////
  256. CConfigurationConnection::~CConfigurationConnection( void )
  257. {
  258. TraceFunc( "" );
  259. TraceSysFreeString( m_bstrLocalComputerName );
  260. if ( m_pcccb != NULL )
  261. {
  262. m_pcccb->Release();
  263. }
  264. if ( m_pgit != NULL )
  265. {
  266. if ( m_cookieGITServer != 0 )
  267. {
  268. THR( m_pgit->RevokeInterfaceFromGlobal( m_cookieGITServer ) );
  269. }
  270. if ( m_cookieGITVerify != 0 )
  271. {
  272. THR( m_pgit->RevokeInterfaceFromGlobal( m_cookieGITVerify ) );
  273. }
  274. if ( m_cookieGITCallbackTask != 0 )
  275. {
  276. THR( HrStopPolling() );
  277. } // if:
  278. m_pgit->Release();
  279. }
  280. TraceSysFreeString( m_bstrBindingString );
  281. InterlockedDecrement( &g_cObjects );
  282. TraceFuncExit();
  283. } //*** CConfigurationConnection::~CConfigurationConnection
  284. // ************************************************************************
  285. //
  286. // IUnknown
  287. //
  288. // ************************************************************************
  289. //////////////////////////////////////////////////////////////////////////////
  290. //++
  291. //
  292. // CConfigurationConnection::QueryInterface
  293. //
  294. // Description:
  295. // Query this object for the passed in interface.
  296. //
  297. // Arguments:
  298. // riidIn
  299. // Id of interface requested.
  300. //
  301. // ppvOut
  302. // Pointer to the requested interface.
  303. //
  304. // Return Value:
  305. // S_OK
  306. // If the interface is available on this object.
  307. //
  308. // E_NOINTERFACE
  309. // If the interface is not available.
  310. //
  311. // E_POINTER
  312. // ppvOut was NULL.
  313. //
  314. // Remarks:
  315. // None.
  316. //
  317. //--
  318. //////////////////////////////////////////////////////////////////////////////
  319. STDMETHODIMP
  320. CConfigurationConnection::QueryInterface(
  321. REFIID riidIn
  322. , LPVOID * ppvOut
  323. )
  324. {
  325. TraceQIFunc( riidIn, ppvOut );
  326. HRESULT hr = S_OK;
  327. //
  328. // Validate arguments.
  329. //
  330. Assert( ppvOut != NULL );
  331. if ( ppvOut == NULL )
  332. {
  333. hr = THR( E_POINTER );
  334. goto Cleanup;
  335. }
  336. //
  337. // Handle known interfaces.
  338. //
  339. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  340. {
  341. *ppvOut = static_cast< IConfigurationConnection * >( this );
  342. } // if: IUnknown
  343. else if ( IsEqualIID( riidIn, IID_IConfigurationConnection ) )
  344. {
  345. *ppvOut = TraceInterface( __THISCLASS__, IConfigurationConnection, this, 0 );
  346. } // else if: IConfigurationConnection
  347. else if ( IsEqualIID( riidIn, IID_IClusCfgServer ) )
  348. {
  349. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgServer, this, 0 );
  350. } // else if: IClusCfgServer
  351. else if ( IsEqualIID( riidIn, IID_IClusCfgCallback ) )
  352. {
  353. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgCallback, this, 0 );
  354. } // else if: IClusCfgCallback
  355. else if ( IsEqualIID( riidIn, IID_IClusCfgCapabilities ) )
  356. {
  357. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgCapabilities, this, 0 );
  358. } // else if: IClusCfgCapabilities
  359. else if ( IsEqualIID( riidIn, IID_IClusCfgVerify ) )
  360. {
  361. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgVerify, this, 0 );
  362. } // else if: IClusCfgVerify
  363. else
  364. {
  365. *ppvOut = NULL;
  366. hr = E_NOINTERFACE;
  367. } // else
  368. //
  369. // Add a reference to the interface if successful.
  370. //
  371. if ( SUCCEEDED( hr ) )
  372. {
  373. ((IUnknown *) *ppvOut)->AddRef();
  374. } // if: success
  375. Cleanup:
  376. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  377. } //*** CConfigurationConnection::QueryInterface
  378. //////////////////////////////////////////////////////////////////////////////
  379. //++
  380. //
  381. // STDMETHODIMP_( ULONG )
  382. // CConfigurationConnection::AddRef
  383. //
  384. //--
  385. //////////////////////////////////////////////////////////////////////////////
  386. STDMETHODIMP_( ULONG )
  387. CConfigurationConnection::AddRef( void )
  388. {
  389. TraceFunc( "[IUnknown]" );
  390. InterlockedIncrement( &m_cRef );
  391. CRETURN( m_cRef );
  392. } //*** CConfigurationConnection::AddRef
  393. //////////////////////////////////////////////////////////////////////////////
  394. //++
  395. //
  396. // STDMETHODIMP_( ULONG )
  397. // CConfigurationConnection::Release
  398. //
  399. //--
  400. //////////////////////////////////////////////////////////////////////////////
  401. STDMETHODIMP_( ULONG )
  402. CConfigurationConnection::Release( void )
  403. {
  404. TraceFunc( "[IUnknown]" );
  405. LONG cRef;
  406. cRef = InterlockedDecrement( &m_cRef );
  407. if ( cRef == 0 )
  408. {
  409. TraceDo( delete this );
  410. }
  411. CRETURN( cRef );
  412. } //*** CConfigurationConnection::Release
  413. //****************************************************************************
  414. //
  415. // IConfigurationConnection
  416. //
  417. //****************************************************************************
  418. //////////////////////////////////////////////////////////////////////////////
  419. //++
  420. //
  421. // STDMETHODIMP
  422. // CConfigurationConnection::ConnectTo(
  423. // OBJECTCOOKIE cookieIn
  424. // )
  425. //
  426. //--
  427. //////////////////////////////////////////////////////////////////////////////
  428. STDMETHODIMP
  429. CConfigurationConnection::ConnectTo(
  430. OBJECTCOOKIE cookieIn
  431. )
  432. {
  433. TraceFunc( "[IConfigurationConnection]" );
  434. //
  435. // VARIABLES
  436. //
  437. HRESULT hr;
  438. LCID lcid;
  439. bool fConnectingToNode;
  440. CLSID clsidType;
  441. CLSID clsidMinorId;
  442. const CLSID * pclsidMajor;
  443. const CLSID * pclsidMinor;
  444. IServiceProvider * psp;
  445. IClusCfgCallback * pcccb; // don't free!
  446. ITaskManager * ptm = NULL;
  447. BSTR bstrName = NULL;
  448. BSTR bstrDescription = NULL;
  449. BSTR bstrMappedHostname = NULL;
  450. BSTR bstrDisplayName = NULL;
  451. size_t idxTargetDomain = 0;
  452. IUnknown * punk = NULL;
  453. IObjectManager * pom = NULL;
  454. IStandardInfo * psi = NULL;
  455. IClusCfgInitialize * pcci = NULL;
  456. IClusCfgServer * pccs = NULL;
  457. IClusCfgPollingCallbackInfo * pccpcbi = NULL;
  458. IClusCfgVerify * pccv = NULL;
  459. IClusCfgNodeInfo * pccni = NULL;
  460. IClusCfgClusterInfo * pccci = NULL;
  461. TraceFlow1( "[MT] CConfigurationConnection::ConnectTo() Thread id %d", GetCurrentThreadId() );
  462. //
  463. // Retrieve the managers needs for the task ahead.
  464. //
  465. hr = THR( CoCreateInstance( CLSID_StdGlobalInterfaceTable,
  466. NULL,
  467. CLSCTX_INPROC_SERVER,
  468. IID_IGlobalInterfaceTable,
  469. reinterpret_cast< void ** >( &m_pgit )
  470. ) );
  471. if ( FAILED( hr ) )
  472. {
  473. goto Cleanup;
  474. }
  475. hr = THR( CoCreateInstance( CLSID_ServiceManager,
  476. NULL,
  477. CLSCTX_SERVER,
  478. TypeSafeParams( IServiceProvider, &psp )
  479. ) );
  480. if ( FAILED( hr ) )
  481. {
  482. goto Cleanup;
  483. }
  484. hr = THR( psp->TypeSafeQS( CLSID_TaskManager, ITaskManager, &ptm ) );
  485. if ( FAILED( hr ) )
  486. {
  487. psp->Release(); // release promptly
  488. goto Cleanup;
  489. }
  490. hr = THR( psp->TypeSafeQS( CLSID_ObjectManager, IObjectManager, &pom ) );
  491. psp->Release(); // release promptly
  492. if ( FAILED( hr ) )
  493. {
  494. goto Cleanup;
  495. }
  496. //
  497. // Figure out our locale.
  498. //
  499. lcid = GetUserDefaultLCID();
  500. Assert( lcid != 0 ); // What do we do if it is zero?
  501. //
  502. // Get the name of the node to contact.
  503. //
  504. hr = THR( pom->GetObject( DFGUID_StandardInfo, cookieIn, &punk ) );
  505. if ( FAILED( hr ) )
  506. {
  507. goto Cleanup;
  508. }
  509. hr = THR( punk->TypeSafeQI( IStandardInfo, &psi ) );
  510. if ( FAILED( hr ) )
  511. {
  512. goto Cleanup;
  513. }
  514. psi = TraceInterface( L"ConfigConnection!IStandardInfo", IStandardInfo, psi, 1 );
  515. hr = THR( psi->GetName( &bstrName ) );
  516. if ( FAILED( hr ) )
  517. {
  518. goto Cleanup;
  519. } // if:
  520. TraceMemoryAddBSTR( bstrName );
  521. hr = STHR( HrGetFQNDisplayName( bstrName, &bstrDisplayName ) );
  522. if ( FAILED( hr ) )
  523. {
  524. goto Cleanup;
  525. } // if:
  526. LogMsg( L"[MT] The name to connect to is '%ws'.", bstrDisplayName );
  527. hr = THR( HrFindDomainInFQN( bstrName, &idxTargetDomain ) );
  528. if ( FAILED( hr ) )
  529. {
  530. goto Cleanup;
  531. } // if:
  532. hr = THR( psi->GetType( &clsidType ) );
  533. if ( FAILED( hr ) )
  534. {
  535. goto Cleanup;
  536. } // if:
  537. //
  538. // Figure out where to logging information in the UI.
  539. //
  540. if ( IsEqualIID( clsidType, CLSID_NodeType ) )
  541. {
  542. fConnectingToNode = true;
  543. pclsidMajor = &TASKID_Major_Establish_Connection;
  544. }
  545. else if ( IsEqualIID( clsidType, CLSID_ClusterConfigurationType ) )
  546. {
  547. fConnectingToNode = false;
  548. pclsidMajor = &TASKID_Major_Checking_For_Existing_Cluster;
  549. }
  550. else
  551. {
  552. hr = THR( E_INVALIDARG );
  553. goto Cleanup;
  554. }
  555. //
  556. // If the connection is to the local machine, then invoke the server INPROC
  557. //
  558. hr = STHR( HrIsLocalComputer( bstrName, SysStringLen( bstrName ) ) );
  559. if ( hr == S_OK )
  560. {
  561. LogMsg( L"[MT] Requesting a local connection to '%ws'.", bstrDisplayName );
  562. //
  563. // Requesting connection to local computer.
  564. //
  565. hr = THR( HrCreateServerObject( NULL, &pccs, &pccv, &pcci ) );
  566. if ( FAILED( hr ) )
  567. {
  568. goto Cleanup;
  569. }
  570. //
  571. // Save it away to be used next time. Do this using the GlobalInterfaceTable.
  572. //
  573. hr = THR( m_pgit->RegisterInterfaceInGlobal( pccs, IID_IClusCfgServer, &m_cookieGITServer ) );
  574. if ( FAILED( hr ) )
  575. {
  576. goto Cleanup;
  577. }
  578. //
  579. // Save it away to be used next time. Do this using the GlobalInterfaceTable.
  580. //
  581. hr = THR( m_pgit->RegisterInterfaceInGlobal( pccv, IID_IClusCfgVerify, &m_cookieGITVerify ) );
  582. if ( FAILED( hr ) )
  583. {
  584. goto Cleanup;
  585. }
  586. pcccb = static_cast< IClusCfgCallback * >( this );
  587. TraceSysFreeString( m_bstrBindingString );
  588. m_bstrBindingString = NULL;
  589. }
  590. else
  591. {
  592. LogMsg( L"[MT] Requesting a remote connection to '%ws'.", bstrDisplayName );
  593. //
  594. // Create a binding context for the remote server.
  595. //
  596. TraceSysFreeString( m_bstrBindingString );
  597. m_bstrBindingString = NULL;
  598. hr = STHR( HrFQNToBindingString( this, pclsidMajor, bstrName, &m_bstrBindingString ) );
  599. if ( FAILED( hr ) )
  600. {
  601. hr = HR_S_RPC_S_SERVER_UNAVAILABLE;
  602. goto Cleanup;
  603. }
  604. //
  605. // Report this connection request.
  606. //
  607. if ( fConnectingToNode )
  608. {
  609. //
  610. // Add in the major task in case it hasn't been added yet.
  611. //
  612. hr = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_REMOTE_CONNECTION_REQUESTS, &bstrDescription ) );
  613. if ( FAILED( hr ) )
  614. {
  615. goto Cleanup;
  616. }
  617. hr = THR( SendStatusReport(
  618. m_bstrLocalHostname
  619. , TASKID_Major_Establish_Connection
  620. , TASKID_Minor_Remote_Node_Connection_Requests
  621. , 1
  622. , 1
  623. , 1
  624. , S_OK
  625. , bstrDescription
  626. , NULL
  627. , NULL
  628. ) );
  629. //
  630. // Add the specific minor task instance.
  631. // Generate a new GUID for this report so that it won't wipe out
  632. // any other reports like this.
  633. //
  634. hr = THR( CoCreateGuid( &clsidMinorId ) );
  635. if ( FAILED( hr ) )
  636. {
  637. goto Cleanup;
  638. }
  639. pclsidMajor = &TASKID_Minor_Remote_Node_Connection_Requests;
  640. pclsidMinor = &clsidMinorId;
  641. } // if: connecting to a node
  642. else
  643. {
  644. pclsidMajor = &TASKID_Major_Checking_For_Existing_Cluster;
  645. pclsidMinor = &TASKID_Minor_Requesting_Remote_Connection;
  646. } // else: connecting to a cluster
  647. hr = THR( HrFormatStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_REQUESTING_REMOTE_CONNECTION, &bstrDescription, bstrDisplayName, bstrName + idxTargetDomain, m_bstrBindingString ) );
  648. if ( FAILED( hr ) )
  649. {
  650. goto Cleanup;
  651. }
  652. hr = THR( SendStatusReport(
  653. m_bstrLocalHostname
  654. , *pclsidMajor
  655. , *pclsidMinor
  656. , 1
  657. , 1
  658. , 1
  659. , S_OK
  660. , bstrDescription
  661. , NULL
  662. , NULL
  663. ) );
  664. //
  665. // Create the connection to the node.
  666. //
  667. hr = HrCreateServerObject( m_bstrBindingString, &pccs, &pccv, &pcci );
  668. if ( hr == HRESULT_FROM_WIN32( RPC_S_SERVER_UNAVAILABLE ) )
  669. {
  670. LogMsg( L"[MT] Connection to '%ws' with binding string '%ws' failed because the RPC is not available.", bstrDisplayName, m_bstrBindingString );
  671. //
  672. // Make the error into a success and update the status.
  673. //
  674. hr = HR_S_RPC_S_SERVER_UNAVAILABLE;
  675. goto Cleanup;
  676. }
  677. else if( hr == HRESULT_FROM_WIN32( REGDB_E_CLASSNOTREG ) )
  678. {
  679. LogMsg( L"[MT] Connection to '%ws' with binding string '%ws' failed because one or more classes are not registered.", bstrDisplayName, m_bstrBindingString );
  680. // Known error. It must be a downlevel node.
  681. goto Cleanup;
  682. }
  683. else if ( FAILED( hr ) )
  684. {
  685. LogMsg( L"[MT] Connection to '%ws' with binding string '%ws' failed. (hr=%#08x)", bstrDisplayName, m_bstrBindingString, hr );
  686. THR( hr );
  687. goto Cleanup;
  688. }
  689. //
  690. // Save interfaces away to be used next time. Do this using the GlobalInterfaceTable.
  691. //
  692. hr = THR( m_pgit->RegisterInterfaceInGlobal( pccv, IID_IClusCfgVerify, &m_cookieGITVerify ) );
  693. if ( FAILED( hr ) )
  694. {
  695. goto Cleanup;
  696. }
  697. hr = THR( pccs->SetBindingString( m_bstrBindingString ) );
  698. if ( FAILED( hr ) )
  699. {
  700. goto Cleanup;
  701. }
  702. hr = THR( m_pgit->RegisterInterfaceInGlobal( pccs, IID_IClusCfgServer, &m_cookieGITServer ) );
  703. if ( FAILED( hr ) )
  704. {
  705. goto Cleanup;
  706. }
  707. // commented out by GalenB since this is investigative code.
  708. // hr = THR( HrSetSecurityBlanket( pccs ) );
  709. // if ( FAILED( hr ) )
  710. // goto Cleanup;
  711. //
  712. // Since VerifyConnection below may send a status report to the UI then we
  713. // need to start polling now so that they will indeed show up in the UI...
  714. //
  715. pcccb = NULL; // we're polling.
  716. hr = THR( pccs->TypeSafeQI( IClusCfgPollingCallbackInfo, &pccpcbi ) );
  717. if ( FAILED( hr ) )
  718. {
  719. goto Cleanup;
  720. }
  721. hr = THR( pccpcbi->SetPollingMode( true ) );
  722. if ( FAILED( hr ) )
  723. {
  724. goto Cleanup;
  725. }
  726. hr = THR( HrStartPolling( cookieIn ) );
  727. if ( FAILED( hr ) )
  728. {
  729. goto Cleanup;
  730. }
  731. //
  732. // Verify our connection.
  733. //
  734. if ( fConnectingToNode )
  735. {
  736. hr = STHR( pccv->VerifyConnectionToNode( bstrName ) );
  737. if ( FAILED( hr ) )
  738. {
  739. goto Cleanup;
  740. }
  741. }
  742. else
  743. {
  744. hr = STHR( pccv->VerifyConnectionToCluster( bstrName ) );
  745. if ( FAILED( hr ) )
  746. {
  747. goto Cleanup;
  748. }
  749. }
  750. /*
  751. 3-SEPT-2002 GalenB
  752. Temporarily commented out until a better solution is available...
  753. if ( hr == S_FALSE )
  754. {
  755. hr = THR( HRESULT_FROM_WIN32( ERROR_CONNECTION_REFUSED ) );
  756. goto Cleanup;
  757. }
  758. */
  759. } // else: run server remotely
  760. //
  761. // Initialize the server.
  762. //
  763. hr = pcci->Initialize( pcccb, lcid );
  764. if ( FAILED( hr ) )
  765. {
  766. THR( hr );
  767. goto Cleanup;
  768. }
  769. else if ( hr == HR_S_RPC_S_CLUSTER_NODE_DOWN )
  770. {
  771. LogMsg( L"[MT] The cluster service on node '%ws' is down.", bstrDisplayName );
  772. } // else if:
  773. else
  774. {
  775. THR( hr );
  776. }
  777. {
  778. //
  779. // KB: 15-AUG-2001 jfranco bug 413056
  780. //
  781. // Map the FQN back to a hostname and reset the standard info object's
  782. // name to the hostname, so that later lookups in the object manager
  783. // find the right instance.
  784. //
  785. // Save result from server initialization to propagate back to caller.
  786. HRESULT hrServerInit = hr;
  787. hr = THR( pccs->GetClusterNodeInfo( &pccni ) );
  788. if ( FAILED( hr ) )
  789. {
  790. goto Cleanup;
  791. }
  792. if ( fConnectingToNode )
  793. {
  794. hr = THR( pccni->GetName( &bstrMappedHostname ) );
  795. if ( FAILED( hr ) )
  796. {
  797. goto Cleanup;
  798. }
  799. TraceMemoryAddBSTR( bstrMappedHostname );
  800. } // Connecting to node
  801. else // Connecting to cluster
  802. {
  803. hr = THR( pccni->GetClusterConfigInfo( &pccci ) );
  804. if ( FAILED( hr ) )
  805. {
  806. goto Cleanup;
  807. }
  808. hr = THR( pccci->GetName( &bstrMappedHostname ) );
  809. if ( FAILED( hr ) )
  810. {
  811. goto Cleanup;
  812. }
  813. TraceMemoryAddBSTR( bstrMappedHostname );
  814. }
  815. hr = THR( psi->SetName( bstrMappedHostname ) );
  816. if ( FAILED( hr ) )
  817. {
  818. goto Cleanup;
  819. }
  820. // Restore result from server initialization to propagate back to caller.
  821. hr = hrServerInit;
  822. }
  823. Cleanup:
  824. if ( punk != NULL )
  825. {
  826. punk->Release();
  827. }
  828. if ( pccpcbi != NULL )
  829. {
  830. pccpcbi->Release();
  831. } // if: pccpcbi
  832. if ( pom != NULL )
  833. {
  834. pom->Release();
  835. } // if: pom
  836. if ( ptm != NULL )
  837. {
  838. ptm->Release();
  839. } //if: ptm
  840. if ( psi != NULL )
  841. {
  842. psi->Release();
  843. } // if: psi
  844. if ( pcci != NULL )
  845. {
  846. pcci->Release();
  847. } // if: pcci
  848. TraceSysFreeString( bstrName );
  849. TraceSysFreeString( bstrDescription );
  850. TraceSysFreeString( bstrMappedHostname );
  851. TraceSysFreeString( bstrDisplayName );
  852. if ( pccs != NULL )
  853. {
  854. pccs->Release();
  855. }
  856. if ( pccv != NULL )
  857. {
  858. pccv->Release();
  859. }
  860. if ( pccni != NULL )
  861. {
  862. pccni->Release();
  863. }
  864. if ( pccci != NULL )
  865. {
  866. pccci->Release();
  867. }
  868. m_hrLastStatus = hr;
  869. HRETURN( hr );
  870. } //*** CConfigurationConnection::ConnectTo
  871. //////////////////////////////////////////////////////////////////////////////
  872. //++
  873. //
  874. // STDMETHODIMP
  875. // CConfigurationConnection::ConnectToObject(
  876. // OBJECTCOOKIE cookieIn,
  877. // REFIID riidIn,
  878. // LPUNKNOWN * ppunkOut
  879. // )
  880. //
  881. //--
  882. //////////////////////////////////////////////////////////////////////////////
  883. STDMETHODIMP
  884. CConfigurationConnection::ConnectToObject(
  885. OBJECTCOOKIE cookieIn,
  886. REFIID riidIn,
  887. LPUNKNOWN * ppunkOut
  888. )
  889. {
  890. TraceFunc( "[IConfigurationConnection]" );
  891. HRESULT hr;
  892. CLSID clsid;
  893. IServiceProvider * psp;
  894. IUnknown * punk = NULL;
  895. IObjectManager * pom = NULL;
  896. IStandardInfo * psi = NULL;
  897. TraceFlow1( "[MT] CConfigurationConnection::ConnectToObject() Thread id %d", GetCurrentThreadId() );
  898. //
  899. // Retrieve the managers needs for the task ahead.
  900. //
  901. hr = THR( CoCreateInstance( CLSID_ServiceManager,
  902. NULL,
  903. CLSCTX_INPROC_SERVER,
  904. TypeSafeParams( IServiceProvider, &psp )
  905. ) );
  906. if ( FAILED( hr ) )
  907. {
  908. goto Cleanup;
  909. }
  910. hr = THR( psp->QueryService( CLSID_ObjectManager,
  911. TypeSafeParams( IObjectManager, &pom )
  912. ) );
  913. psp->Release(); // release promptly
  914. if ( FAILED( hr ) )
  915. {
  916. goto Cleanup;
  917. }
  918. //
  919. // Retrieve the type of the object.
  920. //
  921. hr = THR( pom->GetObject( DFGUID_StandardInfo,
  922. cookieIn,
  923. &punk
  924. ) );
  925. if ( FAILED( hr ) )
  926. {
  927. goto Cleanup;
  928. }
  929. hr = THR( punk->TypeSafeQI( IStandardInfo, &psi ) );
  930. if ( FAILED( hr ) )
  931. {
  932. goto Cleanup;
  933. }
  934. psi = TraceInterface( L"ConfigConnection!IStandardInfo", IStandardInfo, psi, 1 );
  935. hr = THR( psi->GetType( &clsid ) );
  936. if ( FAILED( hr ) )
  937. {
  938. goto Cleanup;
  939. }
  940. if ( !IsEqualIID( clsid, CLSID_NodeType ) )
  941. {
  942. hr = THR( E_INVALIDARG );
  943. goto Cleanup;
  944. }
  945. //
  946. // Return the requested interface.
  947. //
  948. hr = THR( QueryInterface( riidIn, reinterpret_cast< void ** > ( ppunkOut ) ) );
  949. if ( FAILED( hr ) )
  950. {
  951. goto Cleanup;
  952. }
  953. Cleanup:
  954. if ( punk != NULL )
  955. {
  956. punk->Release();
  957. }
  958. if ( pom != NULL )
  959. {
  960. pom->Release();
  961. } // if: pom
  962. if ( psi != NULL )
  963. {
  964. psi->Release();
  965. } // if: psi
  966. HRETURN( hr );
  967. } //*** CConfigurationConnection::ConnectToObject
  968. //****************************************************************************
  969. //
  970. // IClusCfgServer
  971. //
  972. //****************************************************************************
  973. //////////////////////////////////////////////////////////////////////////////
  974. //++
  975. //
  976. // STDMETHODIMP
  977. // CConfigurationConnection::GetClusterNodeInfo(
  978. // IClusCfgNodeInfo ** ppClusterNodeInfoOut
  979. // )
  980. //
  981. //--
  982. //////////////////////////////////////////////////////////////////////////////
  983. STDMETHODIMP
  984. CConfigurationConnection::GetClusterNodeInfo(
  985. IClusCfgNodeInfo ** ppClusterNodeInfoOut
  986. )
  987. {
  988. TraceFunc( "[IClusCfgServer]" );
  989. HRESULT hr;
  990. IClusCfgServer * pccs = NULL;
  991. TraceFlow1( "[MT] CConfigurationConnection::GetClusterNodeInfo() Thread id %d", GetCurrentThreadId() );
  992. if ( m_pgit == NULL )
  993. {
  994. hr = THR( m_hrLastStatus );
  995. goto Cleanup;
  996. }
  997. hr = THR( m_pgit->GetInterfaceFromGlobal( m_cookieGITServer, TypeSafeParams( IClusCfgServer, &pccs ) ) );
  998. if ( FAILED( hr ) )
  999. {
  1000. goto Cleanup;
  1001. }
  1002. hr = THR( pccs->GetClusterNodeInfo( ppClusterNodeInfoOut ) );
  1003. Cleanup:
  1004. if ( pccs != NULL )
  1005. {
  1006. pccs->Release();
  1007. }
  1008. HRETURN( hr );
  1009. } //*** CConfigurationConnection::GetClusterNodeInfo
  1010. //////////////////////////////////////////////////////////////////////////////
  1011. //++
  1012. //
  1013. // STDMETHODIMP
  1014. // CConfigurationConnection::GetManagedResourcesEnum(
  1015. // IEnumClusCfgManagedResources ** ppEnumManagedResourcesOut
  1016. // )
  1017. //
  1018. //--
  1019. //////////////////////////////////////////////////////////////////////////////
  1020. STDMETHODIMP
  1021. CConfigurationConnection::GetManagedResourcesEnum(
  1022. IEnumClusCfgManagedResources ** ppEnumManagedResourcesOut
  1023. )
  1024. {
  1025. TraceFunc( "[IClusCfgServer]" );
  1026. HRESULT hr;
  1027. IClusCfgServer * pccs = NULL;
  1028. if ( m_pgit == NULL )
  1029. {
  1030. hr = THR( m_hrLastStatus );
  1031. goto Cleanup;
  1032. }
  1033. hr = THR( m_pgit->GetInterfaceFromGlobal( m_cookieGITServer, TypeSafeParams( IClusCfgServer, &pccs ) ) );
  1034. if ( FAILED( hr ) )
  1035. {
  1036. goto Cleanup;
  1037. }
  1038. hr = THR( pccs->GetManagedResourcesEnum( ppEnumManagedResourcesOut ) );
  1039. Cleanup:
  1040. if ( pccs != NULL )
  1041. {
  1042. pccs->Release();
  1043. }
  1044. HRETURN( hr );
  1045. } //*** CConfigurationConnection::GetManagedResourcesEnum
  1046. //////////////////////////////////////////////////////////////////////////////
  1047. //++
  1048. //
  1049. // STDMETHODIMP
  1050. // CConfigurationConnection::GetNetworksEnum(
  1051. // IEnumClusCfgNetworks ** ppEnumNetworksOut
  1052. // )
  1053. //
  1054. //--
  1055. //////////////////////////////////////////////////////////////////////////////
  1056. STDMETHODIMP
  1057. CConfigurationConnection::GetNetworksEnum(
  1058. IEnumClusCfgNetworks ** ppEnumNetworksOut
  1059. )
  1060. {
  1061. TraceFunc( "[IClusCfgServer]" );
  1062. HRESULT hr;
  1063. IClusCfgServer * pccs = NULL;
  1064. if ( m_pgit == NULL )
  1065. {
  1066. hr = THR( m_hrLastStatus );
  1067. goto Cleanup;
  1068. }
  1069. hr = THR( m_pgit->GetInterfaceFromGlobal( m_cookieGITServer, TypeSafeParams( IClusCfgServer, &pccs ) ) );
  1070. if ( FAILED( hr ) )
  1071. {
  1072. goto Cleanup;
  1073. }
  1074. hr = THR( pccs->GetNetworksEnum( ppEnumNetworksOut ) );
  1075. Cleanup:
  1076. if ( pccs != NULL )
  1077. {
  1078. pccs->Release();
  1079. }
  1080. HRETURN( hr );
  1081. } //*** CConfigurationConnection::GetNetworksEnum
  1082. //////////////////////////////////////////////////////////////////////////////
  1083. //++
  1084. //
  1085. // STDMETHODIMP
  1086. // CConfigurationConnection::CommitChanges( void )
  1087. //
  1088. //--
  1089. //////////////////////////////////////////////////////////////////////////////
  1090. STDMETHODIMP
  1091. CConfigurationConnection::CommitChanges( void )
  1092. {
  1093. TraceFunc( "[IClusCfgServer]" );
  1094. HRESULT hr;
  1095. IClusCfgServer * pccs = NULL;
  1096. TraceFlow1( "[MT] CConfigurationConnection::CommitChanges() Thread id %d", GetCurrentThreadId() );
  1097. if ( m_pgit == NULL )
  1098. {
  1099. hr = THR( m_hrLastStatus );
  1100. goto Cleanup;
  1101. }
  1102. hr = THR( m_pgit->GetInterfaceFromGlobal( m_cookieGITServer, TypeSafeParams( IClusCfgServer, &pccs ) ) );
  1103. if ( FAILED( hr ) )
  1104. {
  1105. goto Cleanup;
  1106. }
  1107. hr = THR( pccs->CommitChanges( ) );
  1108. Cleanup:
  1109. if ( pccs != NULL )
  1110. {
  1111. pccs->Release();
  1112. }
  1113. HRETURN( hr );
  1114. } //*** CConfigurationConnection::CommitChanges
  1115. //////////////////////////////////////////////////////////////////////////////
  1116. //
  1117. // STDMETHODIMP
  1118. // CConfigurationConnection::GetBindingString(
  1119. // BSTR * pbstrBindingOut
  1120. // )
  1121. //
  1122. //////////////////////////////////////////////////////////////////////////////
  1123. STDMETHODIMP
  1124. CConfigurationConnection::GetBindingString(
  1125. BSTR * pbstrBindingStringOut
  1126. )
  1127. {
  1128. TraceFunc1( "[IClusCfgServer] pbstrBindingStringOut = %p", pbstrBindingStringOut );
  1129. HRESULT hr = S_FALSE;
  1130. if ( pbstrBindingStringOut == NULL )
  1131. {
  1132. hr = THR( E_POINTER );
  1133. goto Cleanup;
  1134. }
  1135. // If local server, then there isn't a binding context.
  1136. if ( m_bstrBindingString == NULL )
  1137. {
  1138. Assert( hr == S_FALSE );
  1139. goto Cleanup;
  1140. }
  1141. *pbstrBindingStringOut = SysAllocString( m_bstrBindingString );
  1142. if ( *pbstrBindingStringOut == NULL )
  1143. {
  1144. hr = THR( E_OUTOFMEMORY );
  1145. goto Cleanup;
  1146. }
  1147. hr = S_OK;
  1148. Cleanup:
  1149. HRETURN( hr );
  1150. } // CConfigurationConnection::GetBinding
  1151. //////////////////////////////////////////////////////////////////////////////
  1152. //++
  1153. //
  1154. // STDMETHODIMP
  1155. // CConfigurationConnection::SetBindingString(
  1156. // LPCWSTR pcszBindingStringIn
  1157. // )
  1158. //
  1159. //--
  1160. //////////////////////////////////////////////////////////////////////////////
  1161. STDMETHODIMP
  1162. CConfigurationConnection::SetBindingString(
  1163. LPCWSTR pcszBindingStringIn
  1164. )
  1165. {
  1166. TraceFunc( "[IClusCfgServer]" );
  1167. HRESULT hr = S_OK;
  1168. BSTR bstr = NULL;
  1169. if ( pcszBindingStringIn == NULL )
  1170. {
  1171. hr = THR( E_INVALIDARG );
  1172. goto Cleanup;
  1173. } // if:
  1174. bstr = TraceSysAllocString( pcszBindingStringIn );
  1175. if ( bstr == NULL )
  1176. {
  1177. hr = THR( E_OUTOFMEMORY );
  1178. goto Cleanup;
  1179. } // if:
  1180. TraceSysFreeString( m_bstrBindingString );
  1181. m_bstrBindingString = bstr;
  1182. Cleanup:
  1183. HRETURN( hr );
  1184. } //*** CConfigurationConnection::SetBindingString
  1185. //****************************************************************************
  1186. //
  1187. // IClusCfgVerify
  1188. //
  1189. //****************************************************************************
  1190. //////////////////////////////////////////////////////////////////////////////
  1191. //++
  1192. //
  1193. // STDMETHODIMP
  1194. // CConfigurationConnection::VerifyCredentials(
  1195. // LPCWSTR pcszUserIn,
  1196. // LPCWSTR pcszDomainIn,
  1197. // LPCWSTR pcszPasswordIn
  1198. // )
  1199. //
  1200. //--
  1201. //////////////////////////////////////////////////////////////////////////////
  1202. STDMETHODIMP
  1203. CConfigurationConnection::VerifyCredentials(
  1204. LPCWSTR pcszUserIn,
  1205. LPCWSTR pcszDomainIn,
  1206. LPCWSTR pcszPasswordIn
  1207. )
  1208. {
  1209. TraceFunc( "[IClusCfgVerify]" );
  1210. HRESULT hr;
  1211. IClusCfgVerify * pccv = NULL;
  1212. if ( m_pgit == NULL )
  1213. {
  1214. hr = THR( m_hrLastStatus );
  1215. goto Cleanup;
  1216. }
  1217. hr = THR( m_pgit->GetInterfaceFromGlobal( m_cookieGITVerify, TypeSafeParams( IClusCfgVerify, &pccv ) ) );
  1218. if ( FAILED( hr ) )
  1219. {
  1220. goto Cleanup;
  1221. }
  1222. hr = THR( pccv->VerifyCredentials( pcszUserIn, pcszDomainIn, pcszPasswordIn ) );
  1223. Cleanup:
  1224. if ( pccv != NULL )
  1225. {
  1226. pccv->Release();
  1227. }
  1228. HRETURN( hr );
  1229. } //*** CConfigurationConnection::VerifyCredentials
  1230. //////////////////////////////////////////////////////////////////////////////
  1231. //++
  1232. //
  1233. // STDMETHODIMP
  1234. // CConfigurationConnection::VerifyConnectionToCluster(
  1235. // LPCWSTR pcszClusterNameIn
  1236. // )
  1237. //
  1238. //--
  1239. //////////////////////////////////////////////////////////////////////////////
  1240. STDMETHODIMP
  1241. CConfigurationConnection::VerifyConnectionToCluster(
  1242. LPCWSTR pcszClusterNameIn
  1243. )
  1244. {
  1245. TraceFunc1( "[IClusCfgVerify] pcszClusterNameIn = '%ws'", pcszClusterNameIn );
  1246. HRESULT hr;
  1247. IClusCfgVerify * pccv = NULL;
  1248. if ( m_pgit == NULL )
  1249. {
  1250. hr = THR( m_hrLastStatus );
  1251. goto Cleanup;
  1252. }
  1253. hr = THR( m_pgit->GetInterfaceFromGlobal( m_cookieGITVerify, TypeSafeParams( IClusCfgVerify, &pccv ) ) );
  1254. if ( FAILED( hr ) )
  1255. {
  1256. goto Cleanup;
  1257. }
  1258. hr = THR( pccv->VerifyConnectionToCluster( pcszClusterNameIn ) );
  1259. Cleanup:
  1260. if ( pccv != NULL )
  1261. {
  1262. pccv->Release();
  1263. }
  1264. HRETURN( hr );
  1265. } //*** CConfigurationConnection::VerifyConnection
  1266. //////////////////////////////////////////////////////////////////////////////
  1267. //++
  1268. //
  1269. // STDMETHODIMP
  1270. // CConfigurationConnection::VerifyConnectionToNode(
  1271. // LPCWSTR pcszNodeNameIn
  1272. // )
  1273. //
  1274. //--
  1275. //////////////////////////////////////////////////////////////////////////////
  1276. STDMETHODIMP
  1277. CConfigurationConnection::VerifyConnectionToNode(
  1278. LPCWSTR pcszNodeNameIn
  1279. )
  1280. {
  1281. TraceFunc1( "[IClusCfgVerify] pcszNodeNameIn = '%ws'", pcszNodeNameIn );
  1282. HRESULT hr;
  1283. IClusCfgVerify * pccv = NULL;
  1284. if ( m_pgit == NULL )
  1285. {
  1286. hr = THR( m_hrLastStatus );
  1287. goto Cleanup;
  1288. }
  1289. hr = THR( m_pgit->GetInterfaceFromGlobal( m_cookieGITVerify, TypeSafeParams( IClusCfgVerify, &pccv ) ) );
  1290. if ( FAILED( hr ) )
  1291. {
  1292. goto Cleanup;
  1293. }
  1294. hr = STHR( pccv->VerifyConnectionToNode( pcszNodeNameIn ) );
  1295. Cleanup:
  1296. if ( pccv != NULL )
  1297. {
  1298. pccv->Release();
  1299. }
  1300. HRETURN( hr );
  1301. } //*** CConfigurationConnection::VerifyConnection
  1302. //****************************************************************************
  1303. //
  1304. // IClusCfgCallback
  1305. //
  1306. //****************************************************************************
  1307. //////////////////////////////////////////////////////////////////////////////
  1308. //++
  1309. //
  1310. // STDMETHODIMP
  1311. // CConfigurationConnection::SendStatusReport(
  1312. // LPCWSTR pcszNodeNameIn
  1313. // , CLSID clsidTaskMajorIn
  1314. // , CLSID clsidTaskMinorIn
  1315. // , ULONG ulMinIn
  1316. // , ULONG ulMaxIn
  1317. // , ULONG ulCurrentIn
  1318. // , HRESULT hrStatusIn
  1319. // , LPCWSTR ocszDescriptionIn
  1320. // , FILETIME * pftTimeIn
  1321. // , LPCWSTR pcszReferenceIn
  1322. // )
  1323. //
  1324. //--
  1325. //////////////////////////////////////////////////////////////////////////////
  1326. STDMETHODIMP
  1327. CConfigurationConnection::SendStatusReport(
  1328. LPCWSTR pcszNodeNameIn
  1329. , CLSID clsidTaskMajorIn
  1330. , CLSID clsidTaskMinorIn
  1331. , ULONG ulMinIn
  1332. , ULONG ulMaxIn
  1333. , ULONG ulCurrentIn
  1334. , HRESULT hrStatusIn
  1335. , LPCWSTR ocszDescriptionIn
  1336. , FILETIME * pftTimeIn
  1337. , LPCWSTR pcszReferenceIn
  1338. )
  1339. {
  1340. TraceFunc( "[IClusCfgCallback]" );
  1341. Assert( pcszNodeNameIn != NULL );
  1342. HRESULT hr = S_OK;
  1343. IServiceProvider * psp = NULL;
  1344. IConnectionPointContainer * pcpc = NULL;
  1345. IConnectionPoint * pcp = NULL;
  1346. FILETIME ft;
  1347. if ( m_pcccb == NULL )
  1348. {
  1349. //
  1350. // Collect the manager we need to complete this task.
  1351. //
  1352. hr = THR( CoCreateInstance( CLSID_ServiceManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( IServiceProvider, &psp ) ) );
  1353. if ( FAILED( hr ) )
  1354. {
  1355. goto Cleanup;
  1356. }
  1357. hr = THR( psp->TypeSafeQS( CLSID_NotificationManager, IConnectionPointContainer, &pcpc ) );
  1358. if ( FAILED( hr ) )
  1359. {
  1360. goto Cleanup;
  1361. }
  1362. hr = THR( pcpc->FindConnectionPoint( IID_IClusCfgCallback, &pcp ) );
  1363. if ( FAILED( hr ) )
  1364. {
  1365. goto Cleanup;
  1366. }
  1367. pcp = TraceInterface( L"CConfigurationConnection!IConnectionPoint", IConnectionPoint, pcp, 1 );
  1368. hr = THR( pcp->TypeSafeQI( IClusCfgCallback, &m_pcccb ) );
  1369. if ( FAILED( hr ) )
  1370. {
  1371. goto Cleanup;
  1372. }
  1373. // m_pcccb = TraceInterface( L"CConfigurationConnection!IClusCfgCallback", IClusCfgCallback, m_pcccb, 1 );
  1374. psp->Release();
  1375. psp = NULL;
  1376. }
  1377. if ( pftTimeIn == NULL )
  1378. {
  1379. GetSystemTimeAsFileTime( &ft );
  1380. pftTimeIn = &ft;
  1381. } // if:
  1382. //
  1383. // Send the message!
  1384. //
  1385. hr = THR( m_pcccb->SendStatusReport(
  1386. pcszNodeNameIn != NULL ? pcszNodeNameIn : m_bstrLocalHostname
  1387. , clsidTaskMajorIn
  1388. , clsidTaskMinorIn
  1389. , ulMinIn
  1390. , ulMaxIn
  1391. , ulCurrentIn
  1392. , hrStatusIn
  1393. , ocszDescriptionIn
  1394. , pftTimeIn
  1395. , pcszReferenceIn
  1396. ) );
  1397. Cleanup:
  1398. if ( psp != NULL )
  1399. {
  1400. psp->Release();
  1401. }
  1402. if ( pcpc != NULL )
  1403. {
  1404. pcpc->Release();
  1405. }
  1406. if ( pcp != NULL )
  1407. {
  1408. pcp->Release();
  1409. }
  1410. HRETURN( hr );
  1411. } //*** CConfigurationConnection::SendStatusReport
  1412. //****************************************************************************
  1413. //
  1414. // IClusCfgCapabilities
  1415. //
  1416. //****************************************************************************
  1417. //////////////////////////////////////////////////////////////////////////////
  1418. //++
  1419. //
  1420. // STDMETHODIMP
  1421. // CConfigurationConnection::CanNodeBeClustered( void )
  1422. //
  1423. //--
  1424. //////////////////////////////////////////////////////////////////////////////
  1425. STDMETHODIMP
  1426. CConfigurationConnection::CanNodeBeClustered( void )
  1427. {
  1428. TraceFunc( "[IClusCfgCapabilities]" );
  1429. HRESULT hr;
  1430. IClusCfgServer * pccs = NULL;
  1431. IClusCfgCapabilities * pccc = NULL;
  1432. TraceFlow1( "[MT] CConfigurationConnection::CanNodeBeClustered() Thread id %d", GetCurrentThreadId() );
  1433. if ( m_pgit == NULL )
  1434. {
  1435. hr = THR( m_hrLastStatus );
  1436. goto Cleanup;
  1437. }
  1438. hr = THR( m_pgit->GetInterfaceFromGlobal( m_cookieGITServer, TypeSafeParams( IClusCfgServer, &pccs ) ) );
  1439. if ( FAILED( hr ) )
  1440. {
  1441. goto Cleanup;
  1442. }
  1443. hr = THR( pccs->TypeSafeQI( IClusCfgCapabilities, &pccc ) );
  1444. if ( FAILED( hr ) )
  1445. {
  1446. goto Cleanup;
  1447. }
  1448. hr = STHR( pccc->CanNodeBeClustered( ) );
  1449. Cleanup:
  1450. if ( pccc != NULL )
  1451. {
  1452. pccc->Release();
  1453. }
  1454. if ( pccs != NULL )
  1455. {
  1456. pccs->Release();
  1457. }
  1458. HRETURN( hr );
  1459. } //*** CConfigurationConnection::CanNodeBeClustered
  1460. //////////////////////////////////////////////////////////////////////////////
  1461. //++
  1462. //
  1463. // HRESULT
  1464. // CConfigurationConnection::HrStartPolling(
  1465. // OBJECTCOOKIE cookieIn
  1466. // )
  1467. //
  1468. //--
  1469. //////////////////////////////////////////////////////////////////////////////
  1470. HRESULT
  1471. CConfigurationConnection::HrStartPolling(
  1472. OBJECTCOOKIE cookieIn
  1473. )
  1474. {
  1475. TraceFunc( "" );
  1476. HRESULT hr;
  1477. IServiceProvider * psp = NULL;
  1478. IUnknown * punk = NULL;
  1479. ITaskManager * ptm = NULL;
  1480. ITaskPollingCallback * ptpcb = NULL;
  1481. TraceFlow1( "[MT] CConfigurationConnection::HrStartPolling() Thread id %d", GetCurrentThreadId() );
  1482. hr = THR( CoCreateInstance( CLSID_ServiceManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( IServiceProvider, &psp ) ) );
  1483. if ( FAILED( hr ) )
  1484. {
  1485. goto Cleanup;
  1486. }
  1487. hr = THR( psp->TypeSafeQS( CLSID_TaskManager, ITaskManager, &ptm ) );
  1488. if ( FAILED( hr ) )
  1489. {
  1490. psp->Release(); // release promptly
  1491. goto Cleanup;
  1492. }
  1493. //
  1494. // Create the task object.
  1495. //
  1496. hr = THR( ptm->CreateTask( TASK_PollingCallback, &punk ) );
  1497. if ( FAILED( hr ) )
  1498. {
  1499. goto Cleanup;
  1500. }
  1501. hr = THR( punk->TypeSafeQI( ITaskPollingCallback, &ptpcb ) );
  1502. if ( FAILED( hr ) )
  1503. {
  1504. goto Cleanup;
  1505. }
  1506. //
  1507. // Save it away to be used next time. Do this using the GlobalInterfaceTable.
  1508. //
  1509. hr = THR( m_pgit->RegisterInterfaceInGlobal( ptpcb, IID_ITaskPollingCallback, &m_cookieGITCallbackTask ) );
  1510. if ( FAILED( hr ) )
  1511. {
  1512. goto Cleanup;
  1513. }
  1514. hr = THR( ptpcb->SetServerInfo( m_cookieGITServer, cookieIn ) );
  1515. if ( FAILED( hr ) )
  1516. {
  1517. goto Cleanup;
  1518. }
  1519. hr = THR( ptm->SubmitTask( ptpcb ) );
  1520. Cleanup:
  1521. if ( punk != NULL )
  1522. {
  1523. punk->Release();
  1524. }
  1525. if ( psp != NULL )
  1526. {
  1527. psp->Release();
  1528. } // if:
  1529. if ( ptm != NULL )
  1530. {
  1531. ptm->Release();
  1532. } // if:
  1533. if ( ptpcb != NULL )
  1534. {
  1535. ptpcb->Release();
  1536. } // if:
  1537. HRETURN( hr );
  1538. } //*** CConfigurationConnection::HrStartPolling
  1539. //////////////////////////////////////////////////////////////////////////////
  1540. //++
  1541. //
  1542. // HRESULT
  1543. // CConfigurationConnection::HrStopPolling( void )
  1544. //
  1545. //--
  1546. //////////////////////////////////////////////////////////////////////////////
  1547. HRESULT
  1548. CConfigurationConnection::HrStopPolling( void )
  1549. {
  1550. TraceFunc( "" );
  1551. HRESULT hr = S_OK;
  1552. ITaskPollingCallback * ptpcb = NULL;
  1553. TraceFlow1( "[MT] CConfigurationConnection::HrStopPolling() Thread id %d", GetCurrentThreadId() );
  1554. hr = THR( m_pgit->GetInterfaceFromGlobal( m_cookieGITCallbackTask, TypeSafeParams( ITaskPollingCallback, &ptpcb ) ) );
  1555. if ( FAILED( hr ) )
  1556. {
  1557. goto Cleanup;
  1558. }
  1559. hr = THR( ptpcb->StopTask() );
  1560. if ( FAILED( hr ) )
  1561. {
  1562. goto Cleanup;
  1563. }
  1564. hr = THR( m_pgit->RevokeInterfaceFromGlobal( m_cookieGITCallbackTask ) );
  1565. Cleanup:
  1566. if ( ptpcb != NULL )
  1567. {
  1568. ptpcb->Release();
  1569. } // if:
  1570. HRETURN( hr );
  1571. } //*** CConfigurationConnection::HrStopPolling
  1572. //////////////////////////////////////////////////////////////////////////////
  1573. //++
  1574. //
  1575. // HRESULT
  1576. // CConfigurationConnection::HrSetSecurityBlanket( IClusCfgServer * pccsIn )
  1577. //
  1578. //--
  1579. //////////////////////////////////////////////////////////////////////////////
  1580. HRESULT
  1581. CConfigurationConnection::HrSetSecurityBlanket( IClusCfgServer * pccsIn )
  1582. {
  1583. TraceFunc( "" );
  1584. Assert( pccsIn != NULL );
  1585. HRESULT hr = S_FALSE;
  1586. IClientSecurity * pCliSec;
  1587. hr = THR( pccsIn->TypeSafeQI( IClientSecurity, &pCliSec ) );
  1588. if ( SUCCEEDED( hr ) )
  1589. {
  1590. hr = THR( pCliSec->SetBlanket(
  1591. pccsIn,
  1592. RPC_C_AUTHN_WINNT,
  1593. RPC_C_AUTHZ_NONE,
  1594. NULL,
  1595. RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
  1596. RPC_C_IMP_LEVEL_IMPERSONATE,
  1597. NULL,
  1598. EOAC_NONE
  1599. ) );
  1600. pCliSec->Release();
  1601. if ( FAILED( hr ) )
  1602. {
  1603. LogMsg( L"[MT] Failed to set the security blanket on the server object. (hr = %#08x)", hr );
  1604. } // if:
  1605. } // if:
  1606. HRETURN( hr );
  1607. } //*** CConfigurationConnection::HrSetSecurityBlanket
  1608. //////////////////////////////////////////////////////////////////////////////
  1609. //
  1610. // HRESULT
  1611. // CConfigurationConnection::HrIsLocalComputer(
  1612. // LPCWSTR pcszNameIn
  1613. // , size_t cchNameIn
  1614. // )
  1615. //
  1616. // Parameters:
  1617. // pcszNameIn
  1618. // FQDN or Hostname name to match against local computer name.
  1619. //
  1620. // cchNameIn
  1621. // Length, in characters, of pcszNameIn, NOT including terminating null.
  1622. //
  1623. // Return Values:
  1624. // S_OK
  1625. // Succeeded. Name matches local computer name.
  1626. //
  1627. // S_FALSE
  1628. // Succeeded. Name does not match local computer name.
  1629. //
  1630. // E_INVALIDARG
  1631. // pcszNameIn was NULL.
  1632. //
  1633. //////////////////////////////////////////////////////////////////////////////
  1634. HRESULT
  1635. CConfigurationConnection::HrIsLocalComputer(
  1636. LPCWSTR pcszNameIn
  1637. , size_t cchNameIn
  1638. )
  1639. {
  1640. TraceFunc1( "pcszNameIn = '%s'", pcszNameIn );
  1641. HRESULT hr = S_OK; // assume success!
  1642. if ( pcszNameIn == NULL )
  1643. {
  1644. hr = THR( E_INVALIDARG );
  1645. goto Cleanup;
  1646. }
  1647. if ( NStringCchCompareNoCase( pcszNameIn, cchNameIn + 1, m_bstrLocalComputerName, SysStringLen( m_bstrLocalComputerName ) + 1 ) == 0 )
  1648. {
  1649. // Found a match.
  1650. goto Cleanup;
  1651. }
  1652. if ( NStringCchCompareNoCase( pcszNameIn, cchNameIn + 1, m_bstrLocalHostname, SysStringLen( m_bstrLocalHostname ) + 1 ) == 0 )
  1653. {
  1654. // Found a match
  1655. goto Cleanup;
  1656. }
  1657. if ( ( pcszNameIn[ 0 ] == L'.' ) && ( pcszNameIn[ 1 ] == L'\0' ) )
  1658. {
  1659. goto Cleanup;
  1660. }
  1661. hr = S_FALSE; // didn't match
  1662. Cleanup:
  1663. HRETURN( hr );
  1664. } //*** CConfigurationConnection::HrIsLocalComputer