Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1633 lines
47 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CBCAInterface.cpp
  7. //
  8. // Description:
  9. // This file contains the implementation of the CBCAInterface
  10. // class.
  11. //
  12. // Documentation:
  13. // TODO: fill in pointer to external documentation
  14. //
  15. // Header File:
  16. // CBCAInterface.h
  17. //
  18. // Maintained By:
  19. // Vij Vasu (VVasu) 07-MAR-2000
  20. //
  21. //////////////////////////////////////////////////////////////////////////////
  22. //////////////////////////////////////////////////////////////////////////////
  23. // Include Files
  24. //////////////////////////////////////////////////////////////////////////////
  25. // The precompiled header for this library
  26. #include "pch.h"
  27. // The header file for this class
  28. #include "CBCAInterface.h"
  29. // For TraceInterface
  30. #include "CITracker.h"
  31. // Needed by Dll.h
  32. #include "CFactory.h"
  33. // For g_cObjects
  34. #include "Dll.h"
  35. // For the CBaseClusterForm class
  36. #include "CBaseClusterForm.h"
  37. // For the CBaseClusterJoin class
  38. #include "CBaseClusterJoin.h"
  39. // For the CBaseClusterCleanup class
  40. #include "CBaseClusterCleanup.h"
  41. // For the exception classes
  42. #include "Exceptions.h"
  43. //////////////////////////////////////////////////////////////////////////////
  44. // Macro Definitions
  45. //////////////////////////////////////////////////////////////////////////////
  46. //////////////////////////////////////////////////////////////////////////////
  47. // Constant Definitions
  48. //////////////////////////////////////////////////////////////////////////////
  49. DEFINE_THISCLASS( "CBCAInterface" );
  50. //////////////////////////////////////////////////////////////////////////////
  51. //++
  52. //
  53. // CBCAInterface::CBCAInterface( void )
  54. //
  55. // Description:
  56. // Constructor of the CBCAInterface class. This initializes
  57. // the m_cRef variable to 1 instead of 0 to account of possible
  58. // QueryInterface failure in DllGetClassObject.
  59. //
  60. // Arguments:
  61. // None.
  62. //
  63. // Return Value:
  64. // None.
  65. //
  66. // Remarks:
  67. // None.
  68. //
  69. //--
  70. //////////////////////////////////////////////////////////////////////////////
  71. CBCAInterface::CBCAInterface( void )
  72. : m_cRef( 1 )
  73. , m_fCommitComplete( false )
  74. , m_fRollbackPossible( false )
  75. , m_lcid( LOCALE_SYSTEM_DEFAULT )
  76. , m_fCallbackSupported( false )
  77. {
  78. BCATraceScope( "" );
  79. // Increment the count of components in memory so the DLL hosting this
  80. // object cannot be unloaded.
  81. InterlockedIncrement( &g_cObjects );
  82. BCATraceMsg1( "Component count = %d.", g_cObjects );
  83. } //*** CBCAInterface::CBCAInterface
  84. //////////////////////////////////////////////////////////////////////////////
  85. //++
  86. //
  87. // CBCAInterface::~CBCAInterface( void)
  88. //
  89. // Description:
  90. // Destructor of the CBCAInterface class.
  91. //
  92. // Arguments:
  93. // None.
  94. //
  95. // Return Value:
  96. // None.
  97. //
  98. // Remarks:
  99. // None.
  100. //
  101. //--
  102. //////////////////////////////////////////////////////////////////////////////
  103. CBCAInterface::~CBCAInterface( void )
  104. {
  105. BCATraceScope( "" );
  106. // There's going to be one less component in memory. Decrement component count.
  107. InterlockedDecrement( &g_cObjects );
  108. BCATraceMsg1( "Component count = %d.", g_cObjects );
  109. } //*** CBCAInterface::~CBCAInterface
  110. //////////////////////////////////////////////////////////////////////////////
  111. //++
  112. //
  113. // HRESULT
  114. // CBCAInterface::S_HrCreateInstance(
  115. // IUnknown ** ppunkOut
  116. // )
  117. //
  118. // Description:
  119. // Creates a CBCAInterface instance.
  120. //
  121. // Arguments:
  122. // ppunkOut
  123. // The IUnknown interface of the new object.
  124. //
  125. // Return Values:
  126. // S_OK
  127. // Success.
  128. //
  129. // E_OUTOFMEMORY
  130. // Not enough memory to create the object.
  131. //
  132. // other HRESULTs
  133. // Object initialization failed.
  134. //
  135. //--
  136. //////////////////////////////////////////////////////////////////////////////
  137. HRESULT
  138. CBCAInterface::S_HrCreateInstance(
  139. IUnknown ** ppunkOut
  140. )
  141. {
  142. BCATraceScope( "" );
  143. HRESULT hr = E_INVALIDARG;
  144. CBCAInterface * pbcaInterface;
  145. pbcaInterface = new CBCAInterface();
  146. if ( pbcaInterface != NULL )
  147. {
  148. hr = THR(
  149. pbcaInterface->QueryInterface(
  150. IID_IUnknown
  151. , reinterpret_cast< void ** >( ppunkOut )
  152. )
  153. );
  154. pbcaInterface->Release( );
  155. } // if: error allocating object
  156. else
  157. {
  158. hr = THR( E_OUTOFMEMORY );
  159. } // else: out of memory
  160. BCATraceMsg1( "*ppunkOut = %p.", *ppunkOut );
  161. BCATraceMsg1( "hr = %#08x", hr );
  162. return hr;
  163. } //*** CBCAInterface::S_HrCreateInstance()
  164. //////////////////////////////////////////////////////////////////////////////
  165. //++
  166. //
  167. // STDMETHODIMP_( ULONG )
  168. // CBCAInterface::AddRef()
  169. //
  170. // Description:
  171. // Increment the reference count of this object by one.
  172. //
  173. // Arguments:
  174. // None.
  175. //
  176. // Return Value:
  177. // The new reference count.
  178. //
  179. // Remarks:
  180. // None.
  181. //
  182. //--
  183. //////////////////////////////////////////////////////////////////////////////
  184. STDMETHODIMP_( ULONG )
  185. CBCAInterface::AddRef( void )
  186. {
  187. BCATraceScope( "[IUnknown]" );
  188. InterlockedIncrement( &m_cRef );
  189. BCATraceMsg1( "m_cRef = %d", m_cRef );
  190. return m_cRef;
  191. } //*** CBCAInterface::AddRef()
  192. //////////////////////////////////////////////////////////////////////////////
  193. //++
  194. //
  195. // STDMETHODIMP_( ULONG )
  196. // CBCAInterface::Release()
  197. //
  198. // Description:
  199. // Decrement the reference count of this object by one.
  200. //
  201. // Arguments:
  202. // None.
  203. //
  204. // Return Value:
  205. // The new reference count.
  206. //
  207. // Remarks:
  208. // None.
  209. //
  210. //--
  211. //////////////////////////////////////////////////////////////////////////////
  212. STDMETHODIMP_( ULONG )
  213. CBCAInterface::Release( void )
  214. {
  215. BCATraceScope( "[IUnknown]" );
  216. InterlockedDecrement( &m_cRef );
  217. BCATraceMsg1( "m_cRef = %d", m_cRef );
  218. if ( m_cRef == 0 )
  219. {
  220. TraceDo( delete this );
  221. return 0;
  222. } // if: reference count decremented to zero
  223. return m_cRef;
  224. } //*** CBCAInterface::Release()
  225. //////////////////////////////////////////////////////////////////////////////
  226. //++
  227. //
  228. // STDMETHODIMP
  229. // CBCAInterface::QueryInterface()
  230. //
  231. // Description:
  232. // Decrement the reference count of this object by one.
  233. //
  234. // Arguments:
  235. // IN REFIID riidIn,
  236. // Id of interface requested.
  237. //
  238. // OUT void ** ppvOut
  239. // Pointer to the requested interface.
  240. //
  241. // Return Value:
  242. // S_OK
  243. // If the interface is available on this object.
  244. //
  245. // E_NOINTERFACE
  246. // If the interface is not available.
  247. //
  248. // Remarks:
  249. // None.
  250. //
  251. //--
  252. //////////////////////////////////////////////////////////////////////////////
  253. STDMETHODIMP
  254. CBCAInterface::QueryInterface( REFIID riidIn, void ** ppvOut )
  255. {
  256. BCATraceQIScope( riidIn, ppvOut );
  257. HRESULT hr = S_OK;
  258. if ( ppvOut != NULL )
  259. {
  260. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  261. {
  262. *ppvOut = static_cast< IClusCfgBaseCluster * >( this );
  263. } // if: IUnknown
  264. else if ( IsEqualIID( riidIn, IID_IClusCfgBaseCluster ) )
  265. {
  266. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgBaseCluster, this, 0 );
  267. } // else if:
  268. else if ( IsEqualIID( riidIn, IID_IClusCfgInitialize ) )
  269. {
  270. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 );
  271. } // else if:
  272. else
  273. {
  274. hr = THR( E_NOINTERFACE );
  275. } // else
  276. if ( SUCCEEDED( hr ) )
  277. {
  278. ((IUnknown *) *ppvOut)->AddRef( );
  279. } // if: success
  280. else
  281. {
  282. *ppvOut = NULL;
  283. } // else: something failed
  284. } // if: the output pointer was valid
  285. else
  286. {
  287. hr = THR( E_INVALIDARG );
  288. } // else: the output pointer is invalid
  289. return hr;
  290. } //*** CBCAInterface::QueryInterface()
  291. //////////////////////////////////////////////////////////////////////////////
  292. //++
  293. //
  294. // CBCAInterface::Initialize()
  295. //
  296. // Description:
  297. // Initialize this component.
  298. //
  299. // Arguments:
  300. // punkCallbackIn
  301. // Pointer to the IUnknown interface of a component that implements
  302. // the IClusCfgCallback interface.
  303. //
  304. // lcidIn
  305. // Locale id for this component.
  306. //
  307. // Return Value:
  308. // S_OK
  309. // If the call succeeded
  310. //
  311. // Other HRESULTs
  312. // If the call failed.
  313. //
  314. //--
  315. //////////////////////////////////////////////////////////////////////////////
  316. STDMETHODIMP
  317. CBCAInterface::Initialize(
  318. IUnknown * punkCallbackIn,
  319. LCID lcidIn
  320. )
  321. {
  322. BCATraceScope( "[IClusCfgInitialize]" );
  323. HRESULT hrRetVal = S_OK;
  324. // Store the locale id in the member variable.
  325. m_lcid = lcidIn;
  326. do
  327. {
  328. // Indicate that SendStatusReports will not be supported unless a non-
  329. // NULL callback interface pointer was specified. This is done in
  330. // the constructor as well, but is also done here since this method
  331. // could be called multiple times.
  332. SetCallbackSupported( false );
  333. if ( punkCallbackIn == NULL )
  334. {
  335. BCATraceMsg( "Callback pointer is NULL. No notifications will be sent." );
  336. LogMsg( "No notifications will be sent." );
  337. break;
  338. }
  339. BCATraceMsg( "The callback pointer is not NULL." );
  340. // Try and get the "normal" callback interface.
  341. hrRetVal = THR( m_spcbCallback.HrQueryAndAssign( punkCallbackIn ) );
  342. if ( FAILED( hrRetVal ) )
  343. {
  344. BCATraceMsg( "Could not get pointer to the callback interface. No notifications will be sent." );
  345. LogMsg( "An error occurred trying to get a pointer to the callback interface. No notifications will be sent." );
  346. break;
  347. } // if: we could not get the callback interface
  348. SetCallbackSupported( true );
  349. BCATraceMsg( "Progress messages will be sent." );
  350. LogMsg( "Progress messages will be sent." );
  351. }
  352. while( false ); // Dummy do-while loop to avoid gotos
  353. BCATraceMsg1( "hrRetVal = %#08x", hrRetVal );
  354. return hrRetVal;
  355. } //*** CBCAInterface::Initialize()
  356. //////////////////////////////////////////////////////////////////////////////
  357. //++
  358. //
  359. // STDMETHODIMP
  360. // CBCAInterface::SetForm()
  361. //
  362. // Description:
  363. // Indicate that a cluster is to be formed with this computer as the first node.
  364. //
  365. // Arguments:
  366. // const WCHAR * pcszClusterNameIn
  367. // Name of the cluster to be formed.
  368. //
  369. // const WCHAR * pcszClusterAccountNameIn
  370. // const WCHAR * pcszClusterAccountPwdIn
  371. // const WCHAR * pcszClusterAccountDomainIn
  372. // Information about the cluster service account.
  373. //
  374. // const DWORD dwClusterIPAddressIn
  375. // const DWORD dwClusterIPSubnetMaskIn
  376. // const WCHAR * pcszClusterIPNetworkIn
  377. // Information about the cluster IP address
  378. //
  379. // Return Value:
  380. // S_OK
  381. // If the call succeeded
  382. //
  383. // Other HRESULTs
  384. // If the call failed.
  385. //
  386. //--
  387. //////////////////////////////////////////////////////////////////////////////
  388. STDMETHODIMP
  389. CBCAInterface::SetForm(
  390. const WCHAR * pcszClusterNameIn
  391. , const WCHAR * pcszClusterBindingStringIn
  392. , const WCHAR * pcszClusterAccountNameIn
  393. , const WCHAR * pcszClusterAccountPwdIn
  394. , const WCHAR * pcszClusterAccountDomainIn
  395. , const DWORD dwClusterIPAddressIn
  396. , const DWORD dwClusterIPSubnetMaskIn
  397. , const WCHAR * pcszClusterIPNetworkIn
  398. )
  399. {
  400. BCATraceScope( "[IClusCfgBaseCluster]" );
  401. HRESULT hrRetVal = S_OK;
  402. // Set the thread locale.
  403. if ( SetThreadLocale( m_lcid ) == FALSE )
  404. {
  405. DWORD dwError = TW32( GetLastError() );
  406. // If SetThreadLocale() fails, do not abort. Just log the error.
  407. BCATraceMsg1( "Error %#08x occurred trying to set the thread locale.", dwError );
  408. LogMsg( "Error %#08x occurred trying to set the thread locale.", dwError );
  409. } // if: SetThreadLocale() failed
  410. try
  411. {
  412. BCATraceMsg( "Initializing cluster formation." );
  413. LogMsg( "Initializing cluster formation." );
  414. // Reset these state variables, to account for exceptions.
  415. SetRollbackPossible( false );
  416. // Setting this to true prevents Commit from being called while we are
  417. // in this routine or if this routine doesn't complete successfully.
  418. SetCommitCompleted( true );
  419. {
  420. // Create a CBaseClusterForm object and assign it to a smart pointer.
  421. SmartBCAPointer spbcaTemp(
  422. new CBaseClusterForm(
  423. this
  424. , pcszClusterNameIn
  425. , pcszClusterBindingStringIn
  426. , pcszClusterAccountNameIn
  427. , pcszClusterAccountPwdIn
  428. , pcszClusterAccountDomainIn
  429. , dwClusterIPAddressIn
  430. , dwClusterIPSubnetMaskIn
  431. , pcszClusterIPNetworkIn
  432. )
  433. );
  434. if ( spbcaTemp.FIsEmpty() )
  435. {
  436. BCATraceMsg( "Could not allocate memory for the CBaseClusterForm() object. Throwing an exception." );
  437. LogMsg( "Could not initialize cluster formation. A memory allocation failure occurred." );
  438. THROW_RUNTIME_ERROR( E_OUTOFMEMORY, IDS_ERROR_CLUSTER_FORM_INIT );
  439. } // if: the memory allocation failed.
  440. //
  441. // If the creation succeeded store the pointer in a member variable for
  442. // use during commit.
  443. //
  444. m_spbcaCurrentAction = spbcaTemp;
  445. }
  446. LogMsg( "Initialization completed. A cluster will be formed on commit." );
  447. // Indicate if rollback is possible.
  448. SetRollbackPossible( m_spbcaCurrentAction->FIsRollbackPossible() );
  449. // Indicate that this action has not been committed.
  450. SetCommitCompleted( false );
  451. } // try: to initialize cluster formation
  452. catch( CAssert & raExceptionObject )
  453. {
  454. // Process the exception.
  455. hrRetVal = THR( HrProcessException( raExceptionObject ) );
  456. } // catch( CAssert & )
  457. catch( CExceptionWithString & resExceptionObject )
  458. {
  459. // Process the exception.
  460. hrRetVal = THR( HrProcessException( resExceptionObject ) );
  461. } // catch( CExceptionWithString & )
  462. catch( CException & reExceptionObject )
  463. {
  464. // Process the exception.
  465. hrRetVal = THR( HrProcessException( reExceptionObject ) );
  466. } // catch( CException & )
  467. catch( ... )
  468. {
  469. // Catch everything. Do not let any exceptions pass out of this function.
  470. hrRetVal = THR( HrProcessException() );
  471. } // catch all
  472. BCATraceMsg1( "hrRetVal = %#08x", hrRetVal );
  473. return hrRetVal;
  474. } //*** CBCAInterface::SetForm()
  475. //////////////////////////////////////////////////////////////////////////////
  476. //++
  477. //
  478. // STDMETHODIMP
  479. // CBCAInterface::SetJoin()
  480. //
  481. // Description:
  482. // Indicate that this computer should be added to a cluster.
  483. //
  484. // Arguments:
  485. // const WCHAR * pcszClusterNameIn
  486. // Name of the cluster to be joined.
  487. //
  488. // const WCHAR * pcszClusterAccountNameIn
  489. // const WCHAR * pcszClusterAccountPwdIn
  490. // const WCHAR * pcszClusterAccountDomainIn
  491. // Information about the cluster service account.
  492. //
  493. // Return Value:
  494. // S_OK
  495. // If the call succeeded
  496. //
  497. // Other HRESULTs
  498. // If the call failed.
  499. //
  500. //--
  501. //////////////////////////////////////////////////////////////////////////////
  502. STDMETHODIMP
  503. CBCAInterface::SetJoin(
  504. const WCHAR * pcszClusterNameIn
  505. , const WCHAR * pcszClusterBindingStringIn
  506. , const WCHAR * pcszClusterAccountNameIn
  507. , const WCHAR * pcszClusterAccountPwdIn
  508. , const WCHAR * pcszClusterAccountDomainIn
  509. )
  510. {
  511. BCATraceScope( "[IClusCfgBaseCluster]" );
  512. HRESULT hrRetVal = S_OK;
  513. // Set the thread locale.
  514. if ( SetThreadLocale( m_lcid ) == FALSE )
  515. {
  516. DWORD dwError = TW32( GetLastError() );
  517. // If SetThreadLocale() fails, do not abort. Just log the error.
  518. BCATraceMsg1( "Error %#08x occurred trying to set the thread locale.", dwError );
  519. LogMsg( "Error %#08x occurred trying to set the thread locale.", dwError );
  520. } // if: SetThreadLocale() failed
  521. try
  522. {
  523. BCATraceMsg( "Initializing cluster join." );
  524. LogMsg( "Initializing cluster join." );
  525. // Reset these state variables, to account for exceptions.
  526. SetRollbackPossible( false );
  527. // Setting this to true prevents Commit from being called while we are
  528. // in this routine or if this routine doesn't complete successfully.
  529. SetCommitCompleted( true );
  530. {
  531. // Create a CBaseClusterJoin object and assign it to a smart pointer.
  532. SmartBCAPointer spbcaTemp(
  533. new CBaseClusterJoin(
  534. this
  535. , pcszClusterNameIn
  536. , pcszClusterBindingStringIn
  537. , pcszClusterAccountNameIn
  538. , pcszClusterAccountPwdIn
  539. , pcszClusterAccountDomainIn
  540. )
  541. );
  542. if ( spbcaTemp.FIsEmpty() )
  543. {
  544. BCATraceMsg( "Could not allocate memory for the CBaseClusterJoin() object. Throwing an exception." );
  545. LogMsg( "Could not initialize cluster join. A memory allocation failure occurred." );
  546. THROW_RUNTIME_ERROR( E_OUTOFMEMORY, IDS_ERROR_CLUSTER_JOIN_INIT );
  547. } // if: the memory allocation failed.
  548. //
  549. // If the creation succeeded store the pointer in a member variable for
  550. // use during commit.
  551. //
  552. m_spbcaCurrentAction = spbcaTemp;
  553. }
  554. LogMsg( "Initialization completed. This computer will join a cluster on commit." );
  555. // Indicate if rollback is possible.
  556. SetRollbackPossible( m_spbcaCurrentAction->FIsRollbackPossible() );
  557. // Indicate that this action has not been committed.
  558. SetCommitCompleted( false );
  559. } // try: to initialize cluster join
  560. catch( CAssert & raExceptionObject )
  561. {
  562. // Process the exception.
  563. hrRetVal = THR( HrProcessException( raExceptionObject ) );
  564. } // catch( CAssert & )
  565. catch( CExceptionWithString & resExceptionObject )
  566. {
  567. // Process the exception.
  568. hrRetVal = THR( HrProcessException( resExceptionObject ) );
  569. } // catch( CExceptionWithString & )
  570. catch( CException & reExceptionObject )
  571. {
  572. // Process the exception.
  573. hrRetVal = THR( HrProcessException( reExceptionObject ) );
  574. } // catch( CException & )
  575. catch( ... )
  576. {
  577. // Catch everything. Do not let any exceptions pass out of this function.
  578. hrRetVal = THR( HrProcessException() );
  579. } // catch all
  580. BCATraceMsg1( "hrRetVal = %#08x", hrRetVal );
  581. return hrRetVal;
  582. } //*** CBCAInterface::SetJoin()
  583. //////////////////////////////////////////////////////////////////////////////
  584. //++
  585. //
  586. // STDMETHODIMP
  587. // CBCAInterface::SetCleanup()
  588. //
  589. // Description:
  590. // Indicate that this node needs to be cleaned up. The ClusSvc service
  591. // should not be running when this action is committed.
  592. //
  593. // Arguments:
  594. // None.
  595. //
  596. // Return Value:
  597. // S_OK
  598. // If the call succeeded
  599. //
  600. // Other HRESULTs
  601. // If the call failed.
  602. //
  603. //--
  604. //////////////////////////////////////////////////////////////////////////////
  605. STDMETHODIMP
  606. CBCAInterface::SetCleanup()
  607. {
  608. BCATraceScope( "[IClusCfgBaseCluster]" );
  609. HRESULT hrRetVal = S_OK;
  610. // Set the thread locale.
  611. if ( SetThreadLocale( m_lcid ) == FALSE )
  612. {
  613. DWORD dwError = TW32( GetLastError() );
  614. // If SetThreadLocale() fails, do not abort. Just log the error.
  615. BCATraceMsg1( "Error %#08x occurred trying to set the thread locale.", dwError );
  616. LogMsg( "Error %#08x occurred trying to set the thread locale.", dwError );
  617. } // if: SetThreadLocale() failed
  618. try
  619. {
  620. BCATraceMsg( "Initializing node clean up." );
  621. LogMsg( "Initializing node clean up." );
  622. // Reset these state variables, to account for exceptions.
  623. SetRollbackPossible( false );
  624. // Setting this to true prevents Commit from being called while we are
  625. // in this routine or if this routine doesn't complete successfully.
  626. SetCommitCompleted( true );
  627. {
  628. // Create a CBaseClusterCleanup object and assign it to a smart pointer.
  629. SmartBCAPointer spbcaTemp( new CBaseClusterCleanup( this ) );
  630. if ( spbcaTemp.FIsEmpty() )
  631. {
  632. BCATraceMsg( "Could not allocate memory for the CBaseClusterCleanup() object. Throwing an exception." );
  633. LogMsg( "Could not initialize node clean up. A memory allocation failure occurred." );
  634. THROW_RUNTIME_ERROR( E_OUTOFMEMORY, IDS_ERROR_CLUSTER_CLEANUP_INIT );
  635. } // if: the memory allocation failed.
  636. //
  637. // If the creation succeeded store the pointer in a member variable for
  638. // use during commit.
  639. //
  640. m_spbcaCurrentAction = spbcaTemp;
  641. }
  642. LogMsg( "Initialization completed. This node will be cleaned up on commit." );
  643. // Indicate if rollback is possible.
  644. SetRollbackPossible( m_spbcaCurrentAction->FIsRollbackPossible() );
  645. // Indicate that this action has not been committed.
  646. SetCommitCompleted( false );
  647. } // try: to initialize node clean up
  648. catch( CAssert & raExceptionObject )
  649. {
  650. // Process the exception.
  651. hrRetVal = THR( HrProcessException( raExceptionObject ) );
  652. } // catch( CAssert & )
  653. catch( CExceptionWithString & resExceptionObject )
  654. {
  655. // Process the exception.
  656. hrRetVal = THR( HrProcessException( resExceptionObject ) );
  657. } // catch( CExceptionWithString & )
  658. catch( CException & reExceptionObject )
  659. {
  660. // Process the exception.
  661. hrRetVal = THR( HrProcessException( reExceptionObject ) );
  662. } // catch( CException & )
  663. catch( ... )
  664. {
  665. // Catch everything. Do not let any exceptions pass out of this function.
  666. hrRetVal = THR( HrProcessException() );
  667. } // catch all
  668. BCATraceMsg1( "hrRetVal = %#08x", hrRetVal );
  669. return hrRetVal;
  670. } //*** CBCAInterface::SetCleanup()
  671. //////////////////////////////////////////////////////////////////////////////
  672. //++
  673. //
  674. // STDMETHODIMP
  675. // CBCAInterface::Commit( void )
  676. //
  677. // Description:
  678. // Perform the action indicated by a previous call to one of the SetXXX
  679. // routines.
  680. //
  681. // Arguments:
  682. // None.
  683. //
  684. // Return Value:
  685. // S_OK
  686. // If the call succeeded
  687. //
  688. // E_FAIL
  689. // If this commit has already been performed.
  690. //
  691. // E_INVALIDARG
  692. // If no action has been set using a SetXXX call.
  693. //
  694. // Other HRESULTs
  695. // If the call failed.
  696. //
  697. // Remarks:
  698. // None.
  699. //
  700. //--
  701. //////////////////////////////////////////////////////////////////////////////
  702. STDMETHODIMP
  703. CBCAInterface::Commit( void )
  704. {
  705. BCATraceScope( "[IClusCfgBaseCluster]" );
  706. HRESULT hrRetVal = S_OK;
  707. // Set the thread locale.
  708. if ( SetThreadLocale( m_lcid ) == FALSE )
  709. {
  710. DWORD dwError = TW32( GetLastError() );
  711. // If SetThreadLocale() fails, do not abort. Just log the error.
  712. BCATraceMsg1( "Error %#08x occurred trying to set the thread locale.", dwError );
  713. LogMsg( "Error %#08x occurred trying to set the thread locale.", dwError );
  714. } // if: SetThreadLocale() failed
  715. do
  716. {
  717. // Has this action already been committed?
  718. if ( FIsCommitComplete() )
  719. {
  720. BCATraceMsg( "The desired cluster configuration has already been performed." );
  721. LogMsg( "The desired cluster configuration has already been performed." );
  722. hrRetVal = THR( E_FAIL ); // BUGBUG: 29-JAN-2001 DavidP Replace E_FAIL
  723. break;
  724. } // if: already committed
  725. // Check if the arguments to commit have been set.
  726. if ( m_spbcaCurrentAction.FIsEmpty() )
  727. {
  728. BCATraceMsg( "Commit was called when an operation has not been specified." );
  729. LogMsg( "Commit was called when an operation has not been specified." );
  730. hrRetVal = THR( E_INVALIDARG ); // BUGBUG: 29-JAN-2001 DavidP Replace E_INVALIDARG
  731. break;
  732. } // if: the pointer to the action to be committed is NULL
  733. LogMsg( "About to perform the desired cluster configuration." );
  734. // Commit the desired action.
  735. try
  736. {
  737. m_spbcaCurrentAction->Commit();
  738. LogMsg( "Cluster configuration completed successfully." );
  739. // If we are here, then everything has gone well.
  740. SetCommitCompleted( true );
  741. } // try: to commit the desired action.
  742. catch( CAssert & raExceptionObject )
  743. {
  744. // Process the exception.
  745. hrRetVal = THR( HrProcessException( raExceptionObject ) );
  746. } // catch( CAssert & )
  747. catch( CExceptionWithString & resExceptionObject )
  748. {
  749. // Process the exception.
  750. hrRetVal = THR( HrProcessException( resExceptionObject ) );
  751. } // catch( CExceptionWithString & )
  752. catch( CException & reExceptionObject )
  753. {
  754. // Process the exception.
  755. hrRetVal = THR( HrProcessException( reExceptionObject ) );
  756. } // catch( CException & )
  757. catch( ... )
  758. {
  759. // Catch everything. Do not let any exceptions pass out of this function.
  760. hrRetVal = THR( HrProcessException() );
  761. } // catch all
  762. }
  763. while( false ); // dummy do-while loop to avoid gotos
  764. BCATraceMsg1( "hrRetVal = %#08x", hrRetVal );
  765. return hrRetVal;
  766. } //*** CBCAInterface::Commit()
  767. //////////////////////////////////////////////////////////////////////////////
  768. //++
  769. //
  770. // STDMETHODIMP
  771. // CBCAInterface::Rollback( void )
  772. //
  773. // Description:
  774. // Rollback a committed configuration.
  775. //
  776. // Arguments:
  777. // None.
  778. //
  779. // Return Value:
  780. // S_OK
  781. // If the call succeeded
  782. //
  783. // E_FAIL
  784. // If this action cannot be rolled back or if it has not yet been
  785. // committed successfully.
  786. //
  787. // E_INVALIDARG
  788. // If no action has been set using a SetXXX call.
  789. //
  790. // Other HRESULTs
  791. // If the call failed.
  792. //
  793. // Remarks:
  794. // None.
  795. //
  796. //--
  797. //////////////////////////////////////////////////////////////////////////////
  798. STDMETHODIMP
  799. CBCAInterface::Rollback( void )
  800. {
  801. BCATraceScope( "[IClusCfgCallback]" );
  802. HRESULT hrRetVal = S_OK;
  803. do
  804. {
  805. // Check if this action list has completed successfully.
  806. if ( !FIsCommitComplete() )
  807. {
  808. // Cannot rollback an incomplete action.
  809. BCATraceMsg( "Cannot rollback - action not yet committed." );
  810. LogMsg( "Cannot rollback - action not yet committed." );
  811. hrRetVal = THR( E_FAIL ); // BUGBUG: 29-JAN-2001 DavidP Replace E_FAIL
  812. break;
  813. } // if: this action was not completed successfully
  814. // Check if this action can be rolled back.
  815. if ( !FIsRollbackPossible() )
  816. {
  817. // Cannot rollback an incompleted action.
  818. BCATraceMsg( "This action cannot be rolled back." );
  819. LogMsg( "This action cannot be rolled back." ); // BUGBUG: 29-JAN-2001 DavidP Why?
  820. hrRetVal = THR( E_FAIL ); // BUGBUG: 29-JAN-2001 DavidP Replace E_FAIL
  821. break;
  822. } // if: this action was not completed successfully
  823. // Check if the arguments to rollback have been set.
  824. if ( m_spbcaCurrentAction.FIsEmpty() )
  825. {
  826. BCATraceMsg( "Rollback was called when an operation has not been specified." );
  827. LogMsg( "Rollback was called when an operation has not been specified." );
  828. hrRetVal = THR( E_INVALIDARG ); // BUGBUG: 29-JAN-2001 DavidP Replace E_INVALIDARG
  829. break;
  830. } // if: the pointer to the action to be committed is NULL
  831. LogMsg( "About to rollback the cluster configuration just committed." );
  832. // Commit the desired action.
  833. try
  834. {
  835. m_spbcaCurrentAction->Rollback();
  836. LogMsg( "Cluster configuration rolled back." );
  837. // If we are here, then everything has gone well.
  838. SetCommitCompleted( false );
  839. } // try: to rollback the desired action.
  840. catch( CAssert & raExceptionObject )
  841. {
  842. // Process the exception.
  843. hrRetVal = THR( HrProcessException( raExceptionObject ) );
  844. } // catch( CAssert & )
  845. catch( CExceptionWithString & resExceptionObject )
  846. {
  847. // Process the exception.
  848. hrRetVal = THR( HrProcessException( resExceptionObject ) );
  849. } // catch( CExceptionWithString & )
  850. catch( CException & reExceptionObject )
  851. {
  852. // Process the exception.
  853. hrRetVal = THR( HrProcessException( reExceptionObject ) );
  854. } // catch( CException & )
  855. catch( ... )
  856. {
  857. // Catch everything. Do not let any exceptions pass out of this function.
  858. hrRetVal = THR( HrProcessException() );
  859. } // catch all
  860. }
  861. while( false ); // dummy do-while loop to avoid gotos
  862. BCATraceMsg1( "hrRetVal = %#08x", hrRetVal );
  863. return hrRetVal;
  864. } //*** CBCAInterface::Rollback()
  865. //////////////////////////////////////////////////////////////////////////////
  866. //++
  867. //
  868. // void
  869. // CBCAInterface::SendStatusReport
  870. //
  871. // Description:
  872. // Send a progress notification [ string id overload ].
  873. //
  874. // Arguments:
  875. // clsidTaskMajorIn
  876. // clsidTaskMinorIn
  877. // GUIDs identifying the notification.
  878. //
  879. // ulMinIn
  880. // ulMaxIn
  881. // ulCurrentIn
  882. // Values that indicate the percentage of this task that is
  883. // completed.
  884. //
  885. // hrStatusIn
  886. // Error code.
  887. //
  888. // uiDescriptionStringIdIn
  889. // String ID of the description of the notification.
  890. //
  891. // Return Value:
  892. // None.
  893. //
  894. // Exceptions Thrown:
  895. // CRuntimeError
  896. // If any of the APIs fail.
  897. //
  898. // CAbortException
  899. // If the configuration was aborted.
  900. //
  901. // Remarks:
  902. // In the current implementation, IClusCfgCallback::SendStatusReport
  903. // returns E_ABORT to indicate that the user wants to abort
  904. // the cluster configuration.
  905. //--
  906. //////////////////////////////////////////////////////////////////////////////
  907. void
  908. CBCAInterface::SendStatusReport(
  909. const CLSID & clsidTaskMajorIn
  910. , const CLSID & clsidTaskMinorIn
  911. , ULONG ulMinIn
  912. , ULONG ulMaxIn
  913. , ULONG ulCurrentIn
  914. , HRESULT hrStatusIn
  915. , UINT uiDescriptionStringIdIn
  916. , bool fIsAbortAllowedIn // = true
  917. )
  918. {
  919. BCATraceScope( "uiDescriptionStringIdIn" );
  920. HRESULT hrRetVal = S_OK;
  921. if ( FIsCallbackSupported() )
  922. {
  923. CStr strDescription;
  924. // Lookup the string using the string Id.
  925. strDescription.LoadString( g_hInstance, uiDescriptionStringIdIn );
  926. // Send progress notification ( call the overloaded function )
  927. SendStatusReport(
  928. clsidTaskMajorIn
  929. , clsidTaskMinorIn
  930. , ulMinIn
  931. , ulMaxIn
  932. , ulCurrentIn
  933. , hrStatusIn
  934. , strDescription.PszData()
  935. , fIsAbortAllowedIn
  936. );
  937. } // if: callbacks are supported
  938. else
  939. {
  940. BCATraceMsg( "Callbacks are not supported. Doing nothing." );
  941. } // else: callbacks are not supported
  942. } //*** CBCAInterface::SendStatusReport()
  943. //////////////////////////////////////////////////////////////////////////////
  944. //++
  945. //
  946. // void
  947. // CBCAInterface::SendStatusReport
  948. //
  949. // Description:
  950. // Send a progress notification [ string overload ].
  951. //
  952. // Arguments:
  953. // clsidTaskMajorIn
  954. // clsidTaskMinorIn
  955. // GUIDs identifying the notification.
  956. //
  957. // ulMinIn
  958. // ulMaxIn
  959. // ulCurrentIn
  960. // Values that indicate the percentage of this task that is
  961. // completed.
  962. //
  963. // hrStatusIn
  964. // Error code.
  965. //
  966. // pcszDescriptionStringIn
  967. // String ID of the description of the notification.
  968. //
  969. // fIsAbortAllowedIn
  970. // An optional parameter indicating if this configuration step can
  971. // be aborted or not. Default value is true.
  972. //
  973. // Return Value:
  974. // None.
  975. //
  976. // Exceptions Thrown:
  977. // CRuntimeError
  978. // If any of the APIs fail.
  979. //
  980. // CAbortException
  981. // If the configuration was aborted.
  982. //
  983. // Remarks:
  984. // In the current implementation, IClusCfgCallback::SendStatusReport
  985. // returns E_ABORT to indicate that the user wants to abort
  986. // the cluster configuration.
  987. //--
  988. //////////////////////////////////////////////////////////////////////////////
  989. void
  990. CBCAInterface::SendStatusReport(
  991. const CLSID & clsidTaskMajorIn
  992. , const CLSID & clsidTaskMinorIn
  993. , ULONG ulMinIn
  994. , ULONG ulMaxIn
  995. , ULONG ulCurrentIn
  996. , HRESULT hrStatusIn
  997. , const WCHAR * pcszDescriptionStringIn
  998. , bool fIsAbortAllowedIn // = true
  999. )
  1000. {
  1001. BCATraceScope1( "pcszDescriptionStringIn = '%ls'", pcszDescriptionStringIn );
  1002. HRESULT hrRetVal = S_OK;
  1003. FILETIME ft;
  1004. do
  1005. {
  1006. CSmartResource<
  1007. CHandleTrait<
  1008. BSTR
  1009. , void
  1010. , SysFreeString
  1011. , reinterpret_cast< LPOLESTR >( NULL )
  1012. >
  1013. > sbstrDescription;
  1014. if ( !FIsCallbackSupported() )
  1015. {
  1016. // Nothing needs to be done.
  1017. break;
  1018. } // if: callbacks are not supported
  1019. if ( pcszDescriptionStringIn != NULL )
  1020. {
  1021. // Convert the string to a BSTR.
  1022. sbstrDescription.Assign( SysAllocString( pcszDescriptionStringIn ) );
  1023. // Did the conversion succeed?
  1024. if ( sbstrDescription.FIsInvalid() )
  1025. {
  1026. BCATraceMsg( "Could not convert description string to BSTR." );
  1027. LogMsg( "Could not convert description string to BSTR." );
  1028. hrRetVal = E_OUTOFMEMORY;
  1029. break;
  1030. } // if: the string lookup failed.
  1031. } // if: the description string is not NULL
  1032. GetSystemTimeAsFileTime( &ft );
  1033. //
  1034. // TODO: 21 NOV 2000 GalenB
  1035. //
  1036. // I don't know why the two new args cannot be NULL?
  1037. // When they are NULL something throws and exception from
  1038. // somewhere...
  1039. // Send progress notification
  1040. hrRetVal = THR(
  1041. m_spcbCallback->SendStatusReport(
  1042. NULL
  1043. , clsidTaskMajorIn
  1044. , clsidTaskMinorIn
  1045. , ulMinIn
  1046. , ulMaxIn
  1047. , ulCurrentIn
  1048. , hrStatusIn
  1049. , sbstrDescription.HHandle()
  1050. , &ft
  1051. , L""
  1052. )
  1053. );
  1054. // Has the user requested an abort?
  1055. if ( hrRetVal == E_ABORT )
  1056. {
  1057. LogMsg( "A request to abort the configuration has been recieved." );
  1058. if ( fIsAbortAllowedIn )
  1059. {
  1060. LogMsg( "Configuration will be aborted." );
  1061. BCATraceMsg( "Aborting configuration." );
  1062. THROW_ABORT( E_ABORT, IDS_USER_ABORT );
  1063. } // if: this operation can be aborted
  1064. else
  1065. {
  1066. LogMsg( "This configuration operation cannot be aborted. Request will be ignored." );
  1067. BCATraceMsg( "This configuration operation cannot be aborted. Request will be ignored." );
  1068. } // else: this operation cannot be aborted
  1069. } // if: the user has indicated that that configuration should be aborted
  1070. else
  1071. {
  1072. if ( FAILED( hrRetVal ) )
  1073. {
  1074. LogMsg( "Error %#08x has occurred - no more status messages will be sent.", hrRetVal );
  1075. BCATraceMsg1( "Error %#08x occurred - no more status messages will be sent.", hrRetVal );
  1076. // Disable all further callbacks.
  1077. SetCallbackSupported( false );
  1078. } // if: something went wrong trying to send a status report
  1079. } // else: abort was not requested
  1080. }
  1081. while( false ); // dummy do-while loop to avoid gotos
  1082. if ( FAILED( hrRetVal ) )
  1083. {
  1084. LogMsg( "Error %#08x occurred trying send a status message.", hrRetVal );
  1085. BCATraceMsg1( "Error %#08x occurred trying send a status message. Throwing exception.", hrRetVal );
  1086. THROW_RUNTIME_ERROR( hrRetVal, IDS_ERROR_SENDING_REPORT );
  1087. } // if: an error occurred
  1088. } //*** CBCAInterface::SendStatusReport()
  1089. //////////////////////////////////////////////////////////////////////////////
  1090. //++
  1091. //
  1092. // void
  1093. // CBCAInterface::QueueStatusReportCompletion
  1094. //
  1095. // Description:
  1096. // Queue a status report for sending when an exception is caught.
  1097. //
  1098. // Arguments:
  1099. // clsidTaskMajorIn
  1100. // clsidTaskMinorIn
  1101. // GUIDs identifying the notification.
  1102. //
  1103. // ulMinIn
  1104. // ulMaxIn
  1105. // Values that indicate the range of steps for this report.
  1106. //
  1107. // uiDescriptionStringIdIn
  1108. // String ID of the description of the notification.
  1109. //
  1110. // Return Value:
  1111. // None.
  1112. //
  1113. // Exceptions Thrown:
  1114. // Any thrown by CList::Append()
  1115. //--
  1116. //////////////////////////////////////////////////////////////////////////////
  1117. void
  1118. CBCAInterface::QueueStatusReportCompletion(
  1119. const CLSID & clsidTaskMajorIn
  1120. , const CLSID & clsidTaskMinorIn
  1121. , ULONG ulMinIn
  1122. , ULONG ulMaxIn
  1123. , UINT uiDescriptionStringIdIn
  1124. )
  1125. {
  1126. BCATraceScope( "" );
  1127. // Queue the status report only if callbacks are supported.
  1128. if ( m_fCallbackSupported )
  1129. {
  1130. // Append this status report to the end of the pending list.
  1131. m_prlPendingReportList.Append(
  1132. SPendingStatusReport(
  1133. clsidTaskMajorIn
  1134. , clsidTaskMinorIn
  1135. , ulMinIn
  1136. , ulMaxIn
  1137. , uiDescriptionStringIdIn
  1138. )
  1139. );
  1140. }
  1141. } //*** CBCAInterface::QueueStatusReportCompletion()
  1142. //////////////////////////////////////////////////////////////////////////////
  1143. //++
  1144. //
  1145. // void
  1146. // CBCAInterface::CompletePendingStatusReports
  1147. //
  1148. // Description:
  1149. // Send all the status reports that were queued for sending when an
  1150. // exception occurred. This function is meant to be called from an exception
  1151. // handler when an exception is caught.
  1152. //
  1153. // Arguments:
  1154. // hrStatusIn
  1155. // The error code to be sent with the pending status reports.
  1156. //
  1157. // Return Value:
  1158. // None.
  1159. //
  1160. // Exceptions Thrown:
  1161. // None, since this function is usually called in an exception handler.
  1162. //
  1163. //--
  1164. //////////////////////////////////////////////////////////////////////////////
  1165. void
  1166. CBCAInterface::CompletePendingStatusReports( HRESULT hrStatusIn ) throw()
  1167. {
  1168. BCATraceScope( "" );
  1169. if ( m_fCallbackSupported )
  1170. {
  1171. try
  1172. {
  1173. PendingReportList::CIterator ciCurrent = m_prlPendingReportList.CiBegin();
  1174. PendingReportList::CIterator ciLast = m_prlPendingReportList.CiEnd();
  1175. // Iterate through the list of pending status reports and send each pending report.
  1176. while ( ciCurrent != ciLast )
  1177. {
  1178. // Send the current status report.
  1179. SendStatusReport(
  1180. ciCurrent->m_clsidTaskMajor
  1181. , ciCurrent->m_clsidTaskMinor
  1182. , ciCurrent->m_ulMin
  1183. , ciCurrent->m_ulMax
  1184. , ciCurrent->m_ulMax
  1185. , hrStatusIn
  1186. , ciCurrent->m_uiDescriptionStringId
  1187. , false
  1188. );
  1189. // Move to the next one.
  1190. m_prlPendingReportList.DeleteAndMoveToNext( ciCurrent );
  1191. } // while: the pending status report list is not empty
  1192. } // try: to send status report
  1193. catch( ... )
  1194. {
  1195. THR( E_UNEXPECTED );
  1196. // Nothing can be done here if the sending of the status report fails.
  1197. BCATraceMsg( "An exception has occurred trying to complete pending status messages. It will not be propagated." );
  1198. LogMsg( "An unexpected error has occurred trying to complete pending status messages. It will not be propagated." );
  1199. } // catch: all exceptions
  1200. } // if: callbacks are supported
  1201. // Empty the pending status report list.
  1202. m_prlPendingReportList.Empty();
  1203. } //*** CBCAInterface::CompletePendingStatusReports()
  1204. //////////////////////////////////////////////////////////////////////////////
  1205. //++
  1206. //
  1207. // HRESULT
  1208. // CBCAInterface::HrProcessException
  1209. //
  1210. // Description:
  1211. // Process an exception that should be shown to the user.
  1212. //
  1213. // Arguments:
  1214. // CExceptionWithString & resExceptionObjectInOut
  1215. // The exception object that has been caught.
  1216. //
  1217. // Return Value:
  1218. // The error code stored in the exception object.
  1219. //
  1220. // Exceptions Thrown:
  1221. // None.
  1222. //
  1223. //--
  1224. //////////////////////////////////////////////////////////////////////////////
  1225. HRESULT
  1226. CBCAInterface::HrProcessException(
  1227. CExceptionWithString & resExceptionObjectInOut
  1228. ) throw()
  1229. {
  1230. BCATraceScope( "resExceptionObjectInOut" );
  1231. LogMsg(
  1232. TEXT("A runtime error has occurred in file '%s', line %d. Error code is %#08x.") SZ_NEWLINE
  1233. TEXT(" The error string is '%s'.")
  1234. , resExceptionObjectInOut.PszGetThrowingFile()
  1235. , resExceptionObjectInOut.UiGetThrowingLine()
  1236. , resExceptionObjectInOut.HrGetErrorCode()
  1237. , resExceptionObjectInOut.StrGetErrorString().PszData()
  1238. );
  1239. BCATraceMsg3(
  1240. "A runtime error has occurred in file '%s', line %d. Error code is %#08x."
  1241. , resExceptionObjectInOut.PszGetThrowingFile()
  1242. , resExceptionObjectInOut.UiGetThrowingLine()
  1243. , resExceptionObjectInOut.HrGetErrorCode()
  1244. );
  1245. BCATraceMsg1(
  1246. " The error string is '%s'."
  1247. , resExceptionObjectInOut.StrGetErrorString().PszData()
  1248. );
  1249. // If the user has not been notified
  1250. if ( !resExceptionObjectInOut.FHasUserBeenNotified() )
  1251. {
  1252. try
  1253. {
  1254. SendStatusReport(
  1255. TASKID_Major_Configure_Cluster_Services
  1256. , TASKID_Minor_Rolling_Back_Cluster_Configuration
  1257. , 1, 1, 1
  1258. , resExceptionObjectInOut.HrGetErrorCode()
  1259. , resExceptionObjectInOut.StrGetErrorString().PszData()
  1260. , false // fIsAbortAllowedIn
  1261. );
  1262. resExceptionObjectInOut.SetUserNotified();
  1263. } // try: to send status report
  1264. catch( ... )
  1265. {
  1266. THR( E_UNEXPECTED );
  1267. // Nothing can be done here if the sending of the status report fails.
  1268. BCATraceMsg( "An exception has occurred trying to send a progress notification. It will not be propagated." );
  1269. LogMsg( "An unexpected error has occurred trying to send a progress notification. It will not be propagated." );
  1270. } // catch: all exceptions
  1271. } // if: the user has not been notified of this exception
  1272. // Complete sending pending status reports.
  1273. CompletePendingStatusReports( resExceptionObjectInOut.HrGetErrorCode() );
  1274. return resExceptionObjectInOut.HrGetErrorCode();
  1275. } //*** CBCAInterface::HrProcessException()
  1276. //////////////////////////////////////////////////////////////////////////////
  1277. //++
  1278. //
  1279. // HRESULT
  1280. // CBCAInterface::HrProcessException
  1281. //
  1282. // Description:
  1283. // Process an assert exception.
  1284. //
  1285. // Arguments:
  1286. // const CAssert & rcaExceptionObjectIn
  1287. // The exception object that has been caught.
  1288. //
  1289. // Return Value:
  1290. // The error code stored in the exception object.
  1291. //
  1292. // Exceptions Thrown:
  1293. // None.
  1294. //
  1295. //--
  1296. //////////////////////////////////////////////////////////////////////////////
  1297. HRESULT
  1298. CBCAInterface::HrProcessException(
  1299. const CAssert & rcaExceptionObjectIn
  1300. ) throw()
  1301. {
  1302. BCATraceScope( "rcaExceptionObjectIn" );
  1303. LogMsg(
  1304. TEXT("An assertion has failed in file '%s', line %d. Error code is %#08x.") SZ_NEWLINE
  1305. TEXT(" The error string is '%s'.")
  1306. , rcaExceptionObjectIn.PszGetThrowingFile()
  1307. , rcaExceptionObjectIn.UiGetThrowingLine()
  1308. , rcaExceptionObjectIn.HrGetErrorCode()
  1309. , rcaExceptionObjectIn.StrGetErrorString().PszData()
  1310. );
  1311. BCATraceMsg3(
  1312. "An assertion has failed in file '%s', line %d. Error code is %#08x."
  1313. , rcaExceptionObjectIn.PszGetThrowingFile()
  1314. , rcaExceptionObjectIn.UiGetThrowingLine()
  1315. , rcaExceptionObjectIn.HrGetErrorCode()
  1316. );
  1317. BCATraceMsg1(
  1318. " The error string is '%s'."
  1319. , rcaExceptionObjectIn.StrGetErrorString().PszData()
  1320. );
  1321. // Complete sending pending status reports.
  1322. CompletePendingStatusReports( rcaExceptionObjectIn.HrGetErrorCode() );
  1323. return rcaExceptionObjectIn.HrGetErrorCode();
  1324. } //*** CBCAInterface::HrProcessException()
  1325. //////////////////////////////////////////////////////////////////////////////
  1326. //++
  1327. //
  1328. // HRESULT
  1329. // CBCAInterface::HrProcessException
  1330. //
  1331. // Description:
  1332. // Process a general exception.
  1333. //
  1334. // Arguments:
  1335. // const CException & rceExceptionObjectIn
  1336. // The exception object that has been caught.
  1337. //
  1338. // Return Value:
  1339. // The error code stored in the exception object.
  1340. //
  1341. // Exceptions Thrown:
  1342. // None.
  1343. //
  1344. //--
  1345. //////////////////////////////////////////////////////////////////////////////
  1346. HRESULT
  1347. CBCAInterface::HrProcessException(
  1348. const CException & rceExceptionObjectIn
  1349. ) throw()
  1350. {
  1351. BCATraceScope( "roeExceptionObjectIn" );
  1352. LogMsg(
  1353. "An exception has occurred in file '%s', line %d. Error code is %#08x."
  1354. , rceExceptionObjectIn.PszGetThrowingFile()
  1355. , rceExceptionObjectIn.UiGetThrowingLine()
  1356. , rceExceptionObjectIn.HrGetErrorCode()
  1357. );
  1358. BCATraceMsg3(
  1359. "An exception has occurred in file '%s', line %d. Error code is %#08x."
  1360. , rceExceptionObjectIn.PszGetThrowingFile()
  1361. , rceExceptionObjectIn.UiGetThrowingLine()
  1362. , rceExceptionObjectIn.HrGetErrorCode()
  1363. );
  1364. // Complete sending pending status reports.
  1365. CompletePendingStatusReports( rceExceptionObjectIn.HrGetErrorCode() );
  1366. return rceExceptionObjectIn.HrGetErrorCode();
  1367. } //*** CBCAInterface::HrProcessException()
  1368. //////////////////////////////////////////////////////////////////////////////
  1369. //++
  1370. //
  1371. // HRESULT
  1372. // CBCAInterface::HrProcessException
  1373. //
  1374. // Description:
  1375. // Process an unknown exception.
  1376. //
  1377. // Arguments:
  1378. // None.
  1379. // Return Value:
  1380. // E_UNEXPECTED
  1381. //
  1382. // Exceptions Thrown:
  1383. // None.
  1384. //
  1385. //--
  1386. //////////////////////////////////////////////////////////////////////////////
  1387. HRESULT
  1388. CBCAInterface::HrProcessException( void ) throw()
  1389. {
  1390. BCATraceScope( "void" );
  1391. LogMsg( "An unknown exception (for example, an access violation) has occurred." );
  1392. BCATraceMsg( "An unknown exception (for example, an access violation) has occurred." );
  1393. // Complete sending pending status reports.
  1394. CompletePendingStatusReports( E_UNEXPECTED );
  1395. return E_UNEXPECTED;
  1396. } //*** CBCAInterface::HrProcessException()