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.

1249 lines
32 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CClusCfgCallback.cpp
  7. //
  8. // Description:
  9. // This file contains the definition of the CClusCfgCallback
  10. // class.
  11. //
  12. // The class CClusCfgCallback inplements the callback
  13. // interface between this server and its clients. It implements the
  14. // IClusCfgCallback interface.
  15. //
  16. // Maintained By:
  17. // Galen Barbee (GalenB) 22-FEB-2000
  18. //
  19. //////////////////////////////////////////////////////////////////////////////
  20. //////////////////////////////////////////////////////////////////////////////
  21. // Include Files
  22. //////////////////////////////////////////////////////////////////////////////
  23. #include "Pch.h"
  24. #include "CClusCfgCallback.h"
  25. // For CClCfgSrvLogger
  26. #include <Logger.h>
  27. //////////////////////////////////////////////////////////////////////////////
  28. // Constant Definitions
  29. //////////////////////////////////////////////////////////////////////////////
  30. DEFINE_THISCLASS( "CClusCfgCallback" );
  31. //*************************************************************************//
  32. /////////////////////////////////////////////////////////////////////////////
  33. // CClusCfgCallback class
  34. /////////////////////////////////////////////////////////////////////////////
  35. //////////////////////////////////////////////////////////////////////////////
  36. //++
  37. //
  38. // CClusCfgCallback::S_HrCreateInstance
  39. //
  40. // Description:
  41. // Create a CClusCfgCallback instance.
  42. //
  43. // Arguments:
  44. // ppunkOut
  45. // The IUnknown interface of the newly created object.
  46. //
  47. // Return Values:
  48. // S_OK
  49. // Success.
  50. //
  51. // E_OUTOFMEMORY
  52. // Out of memory.
  53. //
  54. // other HRESULTs
  55. // Object initialization failed.
  56. //
  57. //--
  58. //////////////////////////////////////////////////////////////////////////////
  59. HRESULT
  60. CClusCfgCallback::S_HrCreateInstance( IUnknown ** ppunkOut )
  61. {
  62. TraceFunc( "" );
  63. HRESULT hr = S_OK;
  64. CClusCfgCallback * pccs = NULL;
  65. if ( ppunkOut == NULL )
  66. {
  67. hr = THR( E_POINTER );
  68. goto Cleanup;
  69. } // if:
  70. pccs = new CClusCfgCallback();
  71. if ( pccs == NULL )
  72. {
  73. hr = THR( E_OUTOFMEMORY );
  74. goto Cleanup;
  75. } // if: error allocating object
  76. hr = THR( pccs->HrInit() );
  77. if ( FAILED( hr ) )
  78. {
  79. goto Cleanup;
  80. } // if: HrInit() succeeded
  81. hr = THR( pccs->TypeSafeQI( IUnknown, ppunkOut ) );
  82. if ( FAILED( hr ) )
  83. {
  84. goto Cleanup;
  85. } // if: QI failed
  86. Cleanup:
  87. if ( pccs != NULL )
  88. {
  89. pccs->Release();
  90. } // if:
  91. if ( FAILED( hr ) )
  92. {
  93. LogMsg( L"[SRV] CClusCfgCallback::S_HrCreateInstance() failed. (hr = %#08x)", hr );
  94. } // if:
  95. HRETURN( hr );
  96. } //*** CClusCfgCallback::S_HrCreateInstance
  97. //////////////////////////////////////////////////////////////////////////////
  98. //++
  99. //
  100. // CClusCfgCallback::CClusCfgCallback
  101. //
  102. // Description:
  103. // Constructor of the CClusCfgCallback class. This initializes
  104. // the m_cRef variable to 1 instead of 0 to account of possible
  105. // QueryInterface failure in DllGetClassObject.
  106. //
  107. // Arguments:
  108. // None.
  109. //
  110. // Return Value:
  111. // None.
  112. //
  113. // Remarks:
  114. // None.
  115. //
  116. //--
  117. //////////////////////////////////////////////////////////////////////////////
  118. CClusCfgCallback::CClusCfgCallback( void )
  119. : m_cRef( 1 )
  120. {
  121. TraceFunc( "" );
  122. // Increment the count of components in memory so the DLL hosting this
  123. // object cannot be unloaded.
  124. InterlockedIncrement( &g_cObjects );
  125. Assert( m_pccc == NULL );
  126. Assert( m_hEvent == NULL );
  127. Assert( m_pcszNodeName == NULL );
  128. Assert( m_pclsidTaskMajor == NULL );
  129. Assert( m_pclsidTaskMinor == NULL );
  130. Assert( m_pulMin == NULL );
  131. Assert( m_pulMax == NULL );
  132. Assert( m_pulCurrent == NULL );
  133. Assert( m_phrStatus == NULL );
  134. Assert( m_pcszDescription == NULL );
  135. Assert( m_pftTime == NULL );
  136. Assert( m_pcszReference == NULL );
  137. Assert( !m_fPollingMode );
  138. Assert( m_bstrNodeName == NULL );
  139. Assert( m_plLogger == NULL );
  140. //
  141. // Assert the simulated RPC failure variables are in the correct state.
  142. //
  143. #if defined( DEBUG ) && defined( CCS_SIMULATE_RPC_FAILURE )
  144. Assert( m_cMessages == 0 );
  145. Assert( m_fDoFailure == false );
  146. #endif
  147. TraceFuncExit();
  148. } //*** CClusCfgCallback::CClusCfgCallback
  149. //////////////////////////////////////////////////////////////////////////////
  150. //++
  151. //
  152. // CClusCfgCallback::~CClusCfgCallback
  153. //
  154. // Description:
  155. // Desstructor of the CClusCfgCallback class.
  156. //
  157. // Arguments:
  158. // None.
  159. //
  160. // Return Value:
  161. // None.
  162. //
  163. // Remarks:
  164. // None.
  165. //
  166. //--
  167. //////////////////////////////////////////////////////////////////////////////
  168. CClusCfgCallback::~CClusCfgCallback( void )
  169. {
  170. TraceFunc( "" );
  171. if ( m_hEvent != NULL )
  172. {
  173. if ( CloseHandle( m_hEvent ) == false )
  174. {
  175. TW32( GetLastError() );
  176. LogMsg( L"[SRV] Cannot close event handle. (sc = %#08x)", GetLastError() );
  177. }
  178. } // if:
  179. TraceSysFreeString( m_bstrNodeName );
  180. if ( m_pccc != NULL )
  181. {
  182. m_pccc->Release();
  183. } // if:
  184. if ( m_plLogger != NULL )
  185. {
  186. m_plLogger->Release();
  187. } // if:
  188. // There's going to be one less component in memory. Decrement component count.
  189. InterlockedDecrement( &g_cObjects );
  190. TraceFuncExit();
  191. } //*** CClusCfgCallback::~CClusCfgCallback
  192. //////////////////////////////////////////////////////////////////////////////
  193. //++
  194. //
  195. // CClusterConfigurationInfo::SendStatusReport
  196. //
  197. // Description:
  198. //
  199. // Arguments:
  200. //
  201. // Return Value:
  202. //
  203. // Remarks:
  204. // None.
  205. //
  206. //--
  207. //////////////////////////////////////////////////////////////////////////////
  208. STDMETHODIMP
  209. CClusCfgCallback::SendStatusReport(
  210. CLSID clsidTaskMajorIn,
  211. CLSID clsidTaskMinorIn,
  212. ULONG ulMinIn,
  213. ULONG ulMaxIn,
  214. ULONG ulCurrentIn,
  215. HRESULT hrStatusIn,
  216. const WCHAR * pcszDescriptionIn
  217. )
  218. {
  219. TraceFunc1( "pcszDescriptionIn = '%ls'", pcszDescriptionIn == NULL ? L"<null>" : pcszDescriptionIn );
  220. HRESULT hr = S_OK;
  221. BSTR bstrDescription = NULL;
  222. FILETIME ft;
  223. bstrDescription = TraceSysAllocString( pcszDescriptionIn );
  224. if ( bstrDescription == NULL )
  225. {
  226. hr = THR( E_OUTOFMEMORY );
  227. goto Cleanup;
  228. } // if:
  229. GetSystemTimeAsFileTime( &ft );
  230. hr = THR( SendStatusReport(
  231. NULL,
  232. clsidTaskMajorIn,
  233. clsidTaskMinorIn,
  234. ulMinIn,
  235. ulMaxIn,
  236. ulCurrentIn,
  237. hrStatusIn,
  238. bstrDescription,
  239. &ft,
  240. NULL
  241. ) );
  242. Cleanup:
  243. TraceSysFreeString( bstrDescription );
  244. HRETURN( hr );
  245. } //*** CClusCfgCallback::SendStatusReport
  246. //////////////////////////////////////////////////////////////////////////////
  247. //++
  248. //
  249. // CClusterConfigurationInfo::SendStatusReport
  250. //
  251. // Description:
  252. //
  253. // Arguments:
  254. //
  255. // Return Value:
  256. //
  257. // Remarks:
  258. // None.
  259. //
  260. //--
  261. //////////////////////////////////////////////////////////////////////////////
  262. STDMETHODIMP
  263. CClusCfgCallback::SendStatusReport(
  264. CLSID clsidTaskMajorIn,
  265. CLSID clsidTaskMinorIn,
  266. ULONG ulMinIn,
  267. ULONG ulMaxIn,
  268. ULONG ulCurrentIn,
  269. HRESULT hrStatusIn,
  270. DWORD dwDescriptionIn
  271. )
  272. {
  273. TraceFunc1( "dwDescriptionIn = %d", dwDescriptionIn );
  274. HRESULT hr = S_OK;
  275. BSTR bstrDescription = NULL;
  276. FILETIME ft;
  277. hr = THR( HrLoadStringIntoBSTR( g_hInstance, dwDescriptionIn, &bstrDescription ) );
  278. if ( FAILED( hr ) )
  279. {
  280. goto Cleanup;
  281. } // if:
  282. GetSystemTimeAsFileTime( &ft );
  283. hr = THR( SendStatusReport(
  284. NULL,
  285. clsidTaskMajorIn,
  286. clsidTaskMinorIn,
  287. ulMinIn,
  288. ulMaxIn,
  289. ulCurrentIn,
  290. hrStatusIn,
  291. bstrDescription,
  292. &ft,
  293. NULL
  294. ) );
  295. Cleanup:
  296. TraceSysFreeString( bstrDescription );
  297. HRETURN( hr );
  298. } //*** CClusCfgCallback::SendStatusReport
  299. //*************************************************************************//
  300. /////////////////////////////////////////////////////////////////////////////
  301. // CClusCfgCallback -- IUnknown interface.
  302. /////////////////////////////////////////////////////////////////////////////
  303. //////////////////////////////////////////////////////////////////////////////
  304. //++
  305. //
  306. // CClusCfgCallback::AddRef
  307. //
  308. // Description:
  309. // Increment the reference count of this object by one.
  310. //
  311. // Arguments:
  312. // None.
  313. //
  314. // Return Value:
  315. // The new reference count.
  316. //
  317. // Remarks:
  318. // None.
  319. //
  320. //--
  321. //////////////////////////////////////////////////////////////////////////////
  322. STDMETHODIMP_( ULONG )
  323. CClusCfgCallback::AddRef( void )
  324. {
  325. TraceFunc( "[IUnknown]" );
  326. InterlockedIncrement( & m_cRef );
  327. CRETURN( m_cRef );
  328. } //*** CClusCfgCallback::AddRef
  329. //////////////////////////////////////////////////////////////////////////////
  330. //++
  331. //
  332. // CClusCfgCallback::Release
  333. //
  334. // Description:
  335. // Decrement the reference count of this object by one.
  336. //
  337. // Arguments:
  338. // None.
  339. //
  340. // Return Value:
  341. // The new reference count.
  342. //
  343. // Remarks:
  344. // None.
  345. //
  346. //--
  347. //////////////////////////////////////////////////////////////////////////////
  348. STDMETHODIMP_( ULONG )
  349. CClusCfgCallback::Release( void )
  350. {
  351. TraceFunc( "[IUnknown]" );
  352. LONG cRef;
  353. cRef = InterlockedDecrement( &m_cRef );
  354. if ( cRef == 0 )
  355. {
  356. TraceDo( delete this );
  357. } // if: reference count equal to zero
  358. CRETURN( cRef );
  359. } //*** CClusCfgCallback::Release
  360. //////////////////////////////////////////////////////////////////////////////
  361. //++
  362. //
  363. // CClusCfgCallback::QueryInterface
  364. //
  365. // Description:
  366. // Query this object for the passed in interface.
  367. //
  368. // Arguments:
  369. // riidIn
  370. // Id of interface requested.
  371. //
  372. // ppvOut
  373. // Pointer to the requested interface.
  374. //
  375. // Return Value:
  376. // S_OK
  377. // If the interface is available on this object.
  378. //
  379. // E_NOINTERFACE
  380. // If the interface is not available.
  381. //
  382. // Remarks:
  383. // None.
  384. //
  385. //--
  386. //////////////////////////////////////////////////////////////////////////////
  387. STDMETHODIMP
  388. CClusCfgCallback::QueryInterface(
  389. REFIID riidIn
  390. , void ** ppvOut
  391. )
  392. {
  393. TraceQIFunc( riidIn, ppvOut );
  394. HRESULT hr = S_OK;
  395. //
  396. // Validate arguments.
  397. //
  398. Assert( ppvOut != NULL );
  399. if ( ppvOut == NULL )
  400. {
  401. hr = THR( E_POINTER );
  402. goto Cleanup;
  403. }
  404. //
  405. // Handle known interfaces.
  406. //
  407. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  408. {
  409. *ppvOut = static_cast< IClusCfgCallback * >( this );
  410. } // if: IUnknown
  411. else if ( IsEqualIID( riidIn, IID_IClusCfgCallback ) )
  412. {
  413. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgCallback, this, 0 );
  414. } // else if: IClusCfgCallback
  415. else if ( IsEqualIID( riidIn, IID_IClusCfgInitialize ) )
  416. {
  417. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 );
  418. } // else if: IClusCfgInitialize
  419. else if ( IsEqualIID( riidIn, IID_IClusCfgPollingCallback ) )
  420. {
  421. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgPollingCallback, this, 0 );
  422. } // else if: IClusCfgPollingCallback
  423. else if ( IsEqualIID( riidIn, IID_IClusCfgSetPollingCallback ) )
  424. {
  425. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgSetPollingCallback, this, 0 );
  426. } // else if: IClusCfgSetPollingCallback
  427. else
  428. {
  429. *ppvOut = NULL;
  430. hr = E_NOINTERFACE;
  431. }
  432. //
  433. // Add a reference to the interface if successful.
  434. //
  435. if ( SUCCEEDED( hr ) )
  436. {
  437. ((IUnknown *) *ppvOut)->AddRef();
  438. } // if: success
  439. Cleanup:
  440. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  441. } //*** CClusCfgCallback::QueryInterface
  442. //*************************************************************************//
  443. /////////////////////////////////////////////////////////////////////////////
  444. // CClusCfgCallback -- IClusCfgCallback interface.
  445. /////////////////////////////////////////////////////////////////////////////
  446. //////////////////////////////////////////////////////////////////////////////
  447. //++
  448. //
  449. // CClusterConfigurationInfo::SendStatusReport
  450. //
  451. // Description:
  452. //
  453. // Arguments:
  454. //
  455. // Return Value:
  456. //
  457. // Remarks:
  458. // None.
  459. //
  460. //--
  461. //////////////////////////////////////////////////////////////////////////////
  462. STDMETHODIMP
  463. CClusCfgCallback::SendStatusReport(
  464. LPCWSTR pcszNodeNameIn,
  465. CLSID clsidTaskMajorIn,
  466. CLSID clsidTaskMinorIn,
  467. ULONG ulMinIn,
  468. ULONG ulMaxIn,
  469. ULONG ulCurrentIn,
  470. HRESULT hrStatusIn,
  471. LPCWSTR pcszDescriptionIn,
  472. FILETIME * pftTimeIn,
  473. LPCWSTR pcszReferenceIn
  474. )
  475. {
  476. TraceFunc1( "[IClusCfgCallback] pcszDescriptionIn = '%s'", pcszDescriptionIn == NULL ? TEXT("<null>") : pcszDescriptionIn );
  477. HRESULT hr = S_OK;
  478. FILETIME ft;
  479. FILETIME ftLocal;
  480. SYSTEMTIME stLocal;
  481. BOOL fRet;
  482. BSTR bstrReferenceString = NULL;
  483. LPCWSTR pcszReference = NULL;
  484. if ( pcszNodeNameIn == NULL )
  485. {
  486. pcszNodeNameIn = m_bstrNodeName;
  487. } // if:
  488. if ( pftTimeIn == NULL )
  489. {
  490. GetSystemTimeAsFileTime( &ft );
  491. pftTimeIn = &ft;
  492. } // if:
  493. Assert( pcszNodeNameIn != NULL );
  494. Assert( pftTimeIn != NULL );
  495. TraceMsg( mtfFUNC, L"pcszNodeNameIn = %s", pcszNodeNameIn );
  496. TraceMsgGUID( mtfFUNC, "clsidTaskMajorIn ", clsidTaskMajorIn );
  497. TraceMsgGUID( mtfFUNC, "clsidTaskMinorIn ", clsidTaskMinorIn );
  498. TraceMsg( mtfFUNC, L"ulMinIn = %u", ulMinIn );
  499. TraceMsg( mtfFUNC, L"ulMaxIn = %u", ulMaxIn );
  500. TraceMsg( mtfFUNC, L"ulCurrentIn = %u", ulCurrentIn );
  501. TraceMsg( mtfFUNC, L"hrStatusIn = %#08x", hrStatusIn );
  502. TraceMsg( mtfFUNC, L"pcszDescriptionIn = '%ws'", ( pcszDescriptionIn ? pcszDescriptionIn : L"<null>" ) );
  503. fRet = FileTimeToLocalFileTime( pftTimeIn, &ftLocal );
  504. Assert( fRet == TRUE );
  505. fRet = FileTimeToSystemTime( &ftLocal, &stLocal );
  506. Assert( fRet == TRUE );
  507. TraceMsg(
  508. mtfFUNC
  509. , L"pftTimeIn = \"%04u-%02u-%02u %02u:%02u:%02u.%03u\""
  510. , stLocal.wYear
  511. , stLocal.wMonth
  512. , stLocal.wDay
  513. , stLocal.wHour
  514. , stLocal.wMinute
  515. , stLocal.wSecond
  516. , stLocal.wMilliseconds
  517. );
  518. if ( ( pcszReferenceIn == NULL )
  519. && ( hrStatusIn != S_OK )
  520. && ( hrStatusIn != S_FALSE )
  521. )
  522. {
  523. hr = STHR( HrGetReferenceStringFromHResult( hrStatusIn, &bstrReferenceString ) );
  524. if ( hr == S_OK )
  525. {
  526. pcszReference = bstrReferenceString;
  527. }
  528. } // if: no reference string was specified
  529. else
  530. {
  531. pcszReference = pcszReferenceIn;
  532. }
  533. TraceMsg( mtfFUNC, L"pcszReferenceIn = '%ws'", ( pcszReference ? pcszReference : L"<null>" ) );
  534. hr = THR( CClCfgSrvLogger::S_HrLogStatusReport(
  535. m_plLogger
  536. , pcszNodeNameIn
  537. , clsidTaskMajorIn
  538. , clsidTaskMinorIn
  539. , ulMinIn
  540. , ulMaxIn
  541. , ulCurrentIn
  542. , hrStatusIn
  543. , pcszDescriptionIn
  544. , pftTimeIn
  545. , pcszReference
  546. ) );
  547. // Local logging - don't send up
  548. if ( IsEqualIID( clsidTaskMajorIn, TASKID_Major_Server_Log ) )
  549. {
  550. goto Cleanup;
  551. } // if:
  552. if ( m_fPollingMode )
  553. {
  554. Assert( m_pccc == NULL );
  555. TraceMsg( mtfFUNC, L"[SRV] Sending the status message with polling." );
  556. hr = THR( HrQueueStatusReport(
  557. pcszNodeNameIn,
  558. clsidTaskMajorIn,
  559. clsidTaskMinorIn,
  560. ulMinIn,
  561. ulMaxIn,
  562. ulCurrentIn,
  563. hrStatusIn,
  564. pcszDescriptionIn,
  565. pftTimeIn,
  566. pcszReference
  567. ) );
  568. } // if:
  569. else if ( m_pccc != NULL )
  570. {
  571. TraceMsg( mtfFUNC, L"[SRV] Sending the status message without polling." );
  572. hr = THR( m_pccc->SendStatusReport(
  573. pcszNodeNameIn,
  574. clsidTaskMajorIn,
  575. clsidTaskMinorIn,
  576. ulMinIn,
  577. ulMaxIn,
  578. ulCurrentIn,
  579. hrStatusIn,
  580. pcszDescriptionIn,
  581. pftTimeIn,
  582. pcszReference
  583. ) );
  584. if ( hr == E_ABORT )
  585. {
  586. LogMsg( L"[SRV] E_ABORT returned from the client." );
  587. } // if:
  588. } // else if:
  589. else
  590. {
  591. LogMsg( L"[SRV] Neither a polling callback or a regular callback were found. No messages are being sent to anyone!" );
  592. } // else:
  593. Cleanup:
  594. TraceSysFreeString( bstrReferenceString );
  595. HRETURN( hr );
  596. } //*** CClusCfgCallback::SendStatusReport
  597. //*************************************************************************//
  598. /////////////////////////////////////////////////////////////////////////////
  599. // CClusCfgCallback -- IClusCfgPollingCallback interface.
  600. /////////////////////////////////////////////////////////////////////////////
  601. //////////////////////////////////////////////////////////////////////////////
  602. //++
  603. //
  604. // CClusterConfigurationInfo::GetStatusReport
  605. //
  606. // Description:
  607. //
  608. // Arguments:
  609. //
  610. // Return Value:
  611. //
  612. // Remarks:
  613. // None.
  614. //
  615. //--
  616. //////////////////////////////////////////////////////////////////////////////
  617. STDMETHODIMP
  618. CClusCfgCallback::GetStatusReport(
  619. BSTR * pbstrNodeNameOut,
  620. CLSID * pclsidTaskMajorOut,
  621. CLSID * pclsidTaskMinorOut,
  622. ULONG * pulMinOut,
  623. ULONG * pulMaxOut,
  624. ULONG * pulCurrentOut,
  625. HRESULT * phrStatusOut,
  626. BSTR * pbstrDescriptionOut,
  627. FILETIME * pftTimeOut,
  628. BSTR * pbstrReferenceOut
  629. )
  630. {
  631. TraceFunc( "[IClusCfgPollingCallback]" );
  632. HRESULT hr;
  633. DWORD sc;
  634. //
  635. // If we are simulating RPC errors then force this function to always fail.
  636. //
  637. #if defined( DEBUG ) && defined( CCS_SIMULATE_RPC_FAILURE )
  638. if ( m_fDoFailure )
  639. {
  640. hr = THR( RPC_E_CALL_REJECTED );
  641. goto Cleanup;
  642. } // if:
  643. #endif
  644. sc = WaitForSingleObject( m_hEvent, 0 );
  645. if ( sc == WAIT_FAILED )
  646. {
  647. sc = TW32( GetLastError() );
  648. hr = HRESULT_FROM_WIN32( sc );
  649. goto Cleanup;
  650. } // if:
  651. //
  652. // If sc is WAIT_TIMEOUT then the event is not signaled and there is an SSR
  653. // for the client to pick up.
  654. //
  655. if ( sc == WAIT_TIMEOUT )
  656. {
  657. Assert( *m_pcszNodeName != NULL );
  658. *pbstrNodeNameOut = SysAllocString( m_pcszNodeName );
  659. if ( *pbstrNodeNameOut == NULL )
  660. {
  661. hr = THR( E_OUTOFMEMORY );
  662. goto Cleanup;
  663. } // if:
  664. *pclsidTaskMajorOut = *m_pclsidTaskMajor;
  665. *pclsidTaskMinorOut = *m_pclsidTaskMinor;
  666. *pulMinOut = *m_pulMin;
  667. *pulMaxOut = *m_pulMax;
  668. *pulCurrentOut = *m_pulCurrent;
  669. *phrStatusOut = *m_phrStatus;
  670. *pftTimeOut = *m_pftTime;
  671. if ( m_pcszDescription != NULL )
  672. {
  673. *pbstrDescriptionOut = SysAllocString( m_pcszDescription );
  674. if ( *pbstrDescriptionOut == NULL )
  675. {
  676. hr = THR( E_OUTOFMEMORY );
  677. goto Cleanup;
  678. } // if:
  679. } // if:
  680. else
  681. {
  682. *pbstrDescriptionOut = NULL;
  683. } // else:
  684. if ( m_pcszReference != NULL )
  685. {
  686. *pbstrReferenceOut = SysAllocString( m_pcszReference );
  687. if ( *pbstrReferenceOut == NULL )
  688. {
  689. hr = THR( E_OUTOFMEMORY );
  690. goto Cleanup;
  691. } // if:
  692. } // if:
  693. else
  694. {
  695. *pbstrReferenceOut = NULL;
  696. } // else:
  697. hr = S_OK;
  698. } // if: event was not signaled
  699. else
  700. {
  701. hr = S_FALSE;
  702. } // else: WAIT_OBJECT_0 event was signaled
  703. goto Cleanup;
  704. Cleanup:
  705. HRETURN( hr );
  706. } //*** CClusCfgCallback::GetStatusReport
  707. //////////////////////////////////////////////////////////////////////////////
  708. //++
  709. //
  710. // CClusterConfigurationInfo::SetHResult
  711. //
  712. // Description:
  713. //
  714. // Arguments:
  715. //
  716. // Return Value:
  717. //
  718. // Remarks:
  719. // None.
  720. //
  721. //--
  722. //////////////////////////////////////////////////////////////////////////////
  723. STDMETHODIMP
  724. CClusCfgCallback::SetHResult( HRESULT hrIn )
  725. {
  726. TraceFunc( "[IClusCfgPollingCallback]" );
  727. HRESULT hr = S_OK;
  728. DWORD sc;
  729. m_hr = hrIn;
  730. if ( hrIn != S_OK )
  731. {
  732. if ( hrIn == E_ABORT )
  733. {
  734. LogMsg( L"[SRV] E_ABORT returned from the client." );
  735. } // if:
  736. else
  737. {
  738. LogMsg( L"[SRV] SetHResult(). (hrIn = %#08x)", hrIn );
  739. } // else:
  740. } // if:
  741. if ( !SetEvent( m_hEvent ) )
  742. {
  743. sc = TW32( GetLastError() );
  744. hr = HRESULT_FROM_WIN32( sc );
  745. LogMsg( L"[SRV] Could not signal event. (hr = %#08x)", hr );
  746. } // if:
  747. HRETURN( hr );
  748. } //*** CClusCfgCallback::SetHResult
  749. //*************************************************************************//
  750. /////////////////////////////////////////////////////////////////////////////
  751. // CClusCfgCallback -- IClusCfgInitialize interface.
  752. /////////////////////////////////////////////////////////////////////////////
  753. //////////////////////////////////////////////////////////////////////////////
  754. //++
  755. //
  756. // CClusterConfigurationInfo::Initialize
  757. //
  758. // Description:
  759. //
  760. // Arguments:
  761. //
  762. // Return Value:
  763. //
  764. // Remarks:
  765. // None.
  766. //
  767. //--
  768. //////////////////////////////////////////////////////////////////////////////
  769. STDMETHODIMP
  770. CClusCfgCallback::Initialize( IUnknown * punkCallbackIn, LCID lcidIn )
  771. {
  772. TraceFunc( "[IClusCfgInitialize]" );
  773. Assert( m_pccc == NULL );
  774. HRESULT hr = S_OK;
  775. m_lcid = lcidIn;
  776. //
  777. // KB: 13 DEC 2000 GalenB
  778. //
  779. // If the passed in callback object is NULL then we had better be doing a polling
  780. // callback!
  781. //
  782. if ( punkCallbackIn != NULL )
  783. {
  784. Assert( !m_fPollingMode );
  785. hr = THR( punkCallbackIn->TypeSafeQI( IClusCfgCallback, &m_pccc ) );
  786. } // if:
  787. else
  788. {
  789. Assert( m_fPollingMode );
  790. } // else:
  791. HRETURN( hr );
  792. } //*** CClusCfgCallback::Initialize
  793. //*************************************************************************//
  794. /////////////////////////////////////////////////////////////////////////////
  795. // CClusCfgCallback -- IClusCfgSetPollingCallback interface.
  796. /////////////////////////////////////////////////////////////////////////////
  797. //////////////////////////////////////////////////////////////////////////////
  798. //++
  799. //
  800. // CClusCfgCallback::SetPollingMode
  801. //
  802. // Description:
  803. //
  804. // Arguments:
  805. //
  806. // Return Value:
  807. //
  808. // Remarks:
  809. // None.
  810. //
  811. //--
  812. //////////////////////////////////////////////////////////////////////////////
  813. STDMETHODIMP
  814. CClusCfgCallback::SetPollingMode( BOOL fUsePollingModeIn )
  815. {
  816. TraceFunc( "[IClusCfgPollingCallback]" );
  817. HRESULT hr = S_OK;
  818. m_fPollingMode = fUsePollingModeIn;
  819. HRETURN( hr );
  820. } //*** CClusCfgCallback::SetPollingMode
  821. //*************************************************************************//
  822. /////////////////////////////////////////////////////////////////////////////
  823. // CClusCfgCallback class -- Private Methods.
  824. /////////////////////////////////////////////////////////////////////////////
  825. //////////////////////////////////////////////////////////////////////////////
  826. //++
  827. //
  828. // CClusCfgCallback::HrInit
  829. //
  830. // Description:
  831. // Initialize this component.
  832. //
  833. // Arguments:
  834. // None.
  835. //
  836. // Return Value:
  837. //
  838. //
  839. // Remarks:
  840. // None.
  841. //
  842. //--
  843. //////////////////////////////////////////////////////////////////////////////
  844. HRESULT
  845. CClusCfgCallback::HrInit( void )
  846. {
  847. TraceFunc( "" );
  848. HRESULT hr = S_OK;
  849. IServiceProvider * psp = NULL;
  850. ILogManager * plm = NULL;
  851. // IUnknown
  852. Assert( m_cRef == 1 );
  853. //
  854. // Get a ClCfgSrv ILogger instance.
  855. // We can't do logging (e.g. LogMsg) until this is succesful.
  856. //
  857. hr = THR( CoCreateInstance(
  858. CLSID_ServiceManager
  859. , NULL
  860. , CLSCTX_INPROC_SERVER
  861. , IID_IServiceProvider
  862. , reinterpret_cast< void ** >( &psp )
  863. ) );
  864. if ( FAILED( hr ) )
  865. {
  866. goto Cleanup;
  867. }
  868. hr = THR( psp->TypeSafeQS( CLSID_LogManager, ILogManager, &plm ) );
  869. if ( FAILED( hr ) )
  870. {
  871. goto Cleanup;
  872. }
  873. hr = THR( plm->GetLogger( &m_plLogger ) );
  874. if ( FAILED( hr ) )
  875. {
  876. goto Cleanup;
  877. }
  878. //
  879. // Create the event in a signaled state. To prevent MT polling task from grabbing
  880. // bad/empty data.
  881. //
  882. m_hEvent = CreateEvent( NULL, TRUE, TRUE, NULL );
  883. if ( m_hEvent == NULL )
  884. {
  885. DWORD sc = TW32( GetLastError() );
  886. hr = HRESULT_FROM_WIN32( sc );
  887. LogMsg( L"[SRV] Could not create event. (hr = %#08x)", hr );
  888. goto Cleanup;
  889. } // if:
  890. //
  891. // Save off the local computer name.
  892. //
  893. hr = THR( HrGetComputerName(
  894. ComputerNameDnsFullyQualified
  895. , &m_bstrNodeName
  896. , TRUE // fBestEffortIn
  897. ) );
  898. if ( FAILED( hr ) )
  899. {
  900. goto Cleanup;
  901. }
  902. Cleanup:
  903. if ( psp != NULL )
  904. {
  905. psp->Release();
  906. }
  907. if ( plm != NULL )
  908. {
  909. plm->Release();
  910. }
  911. HRETURN( hr );
  912. } //*** CClusCfgCallback::HrInit
  913. //////////////////////////////////////////////////////////////////////////////
  914. //++
  915. //
  916. // CClusterConfigurationInfo::HrQueueStatusReport
  917. //
  918. // Description:
  919. //
  920. // Arguments:
  921. //
  922. // Return Value:
  923. //
  924. // Remarks:
  925. // None.
  926. //
  927. //--
  928. //////////////////////////////////////////////////////////////////////////////
  929. HRESULT
  930. CClusCfgCallback::HrQueueStatusReport(
  931. LPCWSTR pcszNodeNameIn,
  932. CLSID clsidTaskMajorIn,
  933. CLSID clsidTaskMinorIn,
  934. ULONG ulMinIn,
  935. ULONG ulMaxIn,
  936. ULONG ulCurrentIn,
  937. HRESULT hrStatusIn,
  938. LPCWSTR pcszDescriptionIn,
  939. FILETIME * pftTimeIn,
  940. LPCWSTR pcszReferenceIn
  941. )
  942. {
  943. TraceFunc( "" );
  944. HRESULT hr = S_OK;
  945. DWORD sc;
  946. MSG msg;
  947. m_pcszNodeName = pcszNodeNameIn;
  948. m_pclsidTaskMajor = &clsidTaskMajorIn;
  949. m_pclsidTaskMinor = &clsidTaskMinorIn;
  950. m_pulMin = &ulMinIn;
  951. m_pulMax = &ulMaxIn;
  952. m_pulCurrent = &ulCurrentIn;
  953. m_phrStatus = &hrStatusIn;
  954. m_pcszDescription = pcszDescriptionIn;
  955. m_pftTime = pftTimeIn,
  956. m_pcszReference = pcszReferenceIn;
  957. //
  958. // This code simulates the RPC failure that causes a deadlock between the
  959. // client and the server. This deadlock occurs when this object is waiting
  960. // for the client's TaskPollingCallback to pick up the queued SSR and an RPC
  961. // failure prevents that from happening. Since the client task has made a
  962. // DCOM call into the server side the Wizard appears to hang since that thread
  963. // is waiting for the remote object to return and that object inturn is
  964. // waiting in this object for the client to pick up the queued status report.
  965. //
  966. #if defined( DEBUG ) && defined( CCS_SIMULATE_RPC_FAILURE )
  967. m_cMessages++;
  968. //
  969. // Arbitrary number to cause the simulated RPC failure to occur after some
  970. // normal status report traffic has gone by. This really only works when
  971. // doing analysis. More thought will be needed to make this simulated
  972. // failure code work for commit.
  973. //
  974. if ( m_cMessages > 10 )
  975. {
  976. HANDLE hEvent = NULL;
  977. m_fDoFailure = true;
  978. hEvent = CreateEvent( NULL, TRUE, TRUE, NULL );
  979. if ( hEvent != NULL )
  980. {
  981. for ( sc = (DWORD) -1; sc != WAIT_OBJECT_0; )
  982. {
  983. while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
  984. {
  985. TranslateMessage( &msg );
  986. DispatchMessage( &msg );
  987. } // while: PeekMessage
  988. //
  989. // Wait for up to twice the normal default timeout...
  990. //
  991. sc = MsgWaitForMultipleObjects( 1, &hEvent, FALSE, 2 * CCC_WAIT_TIMEOUT, QS_ALLINPUT );
  992. if ( ( sc == -1 ) || ( sc == WAIT_FAILED ) )
  993. {
  994. sc = TW32( GetLastError() );
  995. hr = HRESULT_FROM_WIN32( sc );
  996. LogMsg( L"[SRV] MsgWaitForMultipleObjects failed. (hr = %#08x)", hr );
  997. goto Cleanup;
  998. } // if:
  999. else if ( sc == WAIT_TIMEOUT )
  1000. {
  1001. LogMsg( L"[SRV] MsgWaitForMultipleObjects timed out. Returning E_ABORT to the caller (hr = %#08x)", hr );
  1002. hr = THR( E_ABORT );
  1003. goto Cleanup;
  1004. } // else if:
  1005. } // for:
  1006. } // if:
  1007. } // if:
  1008. #endif
  1009. if ( ResetEvent( m_hEvent ) == FALSE )
  1010. {
  1011. sc = TW32( GetLastError() );
  1012. hr = HRESULT_FROM_WIN32( sc );
  1013. LogMsg( L"[SRV] Could not reset event. (hr = %#08x)", hr );
  1014. goto Cleanup;
  1015. } // if:
  1016. for ( sc = (DWORD) -1; sc != WAIT_OBJECT_0; )
  1017. {
  1018. while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
  1019. {
  1020. TranslateMessage( &msg );
  1021. DispatchMessage( &msg );
  1022. } // while: PeekMessage
  1023. //
  1024. // Wait for up to 5 minutes...
  1025. //
  1026. sc = MsgWaitForMultipleObjects( 1, &m_hEvent, FALSE, CCC_WAIT_TIMEOUT, QS_ALLINPUT );
  1027. if ( ( sc == -1 ) || ( sc == WAIT_FAILED ) )
  1028. {
  1029. sc = TW32( GetLastError() );
  1030. hr = HRESULT_FROM_WIN32( sc );
  1031. LogMsg( L"[SRV] MsgWaitForMultipleObjects failed. (hr = %#08x)", hr );
  1032. goto Cleanup;
  1033. } // if:
  1034. else if ( sc == WAIT_TIMEOUT )
  1035. {
  1036. LogMsg( L"[SRV] MsgWaitForMultipleObjects timed out. Returning E_ABORT to the caller (hr = %#08x)", hr );
  1037. hr = THR( E_ABORT );
  1038. goto Cleanup;
  1039. } // else if:
  1040. } // for:
  1041. //
  1042. // If we end up here then we want to return the status from the client that is
  1043. // in m_hr...
  1044. //
  1045. hr = m_hr;
  1046. Cleanup:
  1047. HRETURN( hr );
  1048. } //*** CClusCfgCallback::HrQueueStatusReport