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.
 
 
 
 
 
 

325 lines
11 KiB

//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2001 Microsoft Corporation
//
// Module Name:
// CStatusReport.h
//
// Description:
// Header file for CStatusReport class.
//
// CStatusReport is a class the provides the functionality sending a
// status report.
//
// Implementation File:
// CStatusReport.cpp
//
// Maintained By:
// David Potter (DavidP) 30-MAR-2001
// Vij Vasu (Vvasu) 05-JUN-2000
//
//////////////////////////////////////////////////////////////////////////////
// Make sure that this file is included only once per compile path.
#pragma once
//////////////////////////////////////////////////////////////////////////////
// Include files
//////////////////////////////////////////////////////////////////////////////
// A few common declarations
#include "CommonDefs.h"
// For the exceptions thrown by this class.
#include "Exceptions.h"
// For the CBCAInterface class
#include "CBCAInterface.h"
//////////////////////////////////////////////////////////////////////////////
//++
//
// class CStatusReport
//
// Description:
// CStatusReport is a class the provides the functionality sending a
// status report. Each status report can have a number of steps. For
// example, the task of creating the cluster service could have 4 steps,
//
// The user interface is so designed that if the first step of a report is
// sent, the last one has to be sent as well, even if an error occurs after
// sending the first one. This class queues the last status report for
// sending in case and exception occurs and the last report has not been
// sent yet.
//
// It is not possible to send the last, outstanding status report from the
// destructor of this class since the error code contained in the exception
// that is causing this object to be destroyed is not known. So, this last
// status report is queued with the CBCAInterface object which will send this
// report once the exception has been caught.
//
//--
//////////////////////////////////////////////////////////////////////////////
class CStatusReport
{
public:
//////////////////////////////////////////////////////////////////////////
// Constructors and destructors
//////////////////////////////////////////////////////////////////////////
// Constructor.
CStatusReport(
CBCAInterface * pbcaiInterfaceIn
, const CLSID & clsidTaskMajorIn
, const CLSID & clsidTaskMinorIn
, ULONG ulMinIn
, ULONG ulMaxIn
, UINT idsDescriptionStringIdIn
)
: m_pbcaiInterface( pbcaiInterfaceIn )
, m_clsidTaskMajor( clsidTaskMajorIn )
, m_clsidTaskMinor( clsidTaskMinorIn )
, m_ulMin( ulMinIn )
, m_ulMax( ulMaxIn )
, m_ulNext( ulMinIn )
, m_idsDescriptionStringId( idsDescriptionStringIdIn )
, m_idsReferenceStringId( 0 )
, m_fLastStepSent( false )
{
TraceFunc( "" );
// Validate the parameters.
if ( ( pbcaiInterfaceIn == NULL )
|| ( ulMinIn > ulMaxIn )
)
{
THR( E_INVALIDARG );
THROW_ASSERT( E_INVALIDARG, "The parameters for this status report are invalid." );
} // if: the parameters are invalid
TraceFuncExit();
} //*** CStatusReport::CStatusReport
// Constructor.
CStatusReport(
CBCAInterface * pbcaiInterfaceIn
, const CLSID & clsidTaskMajorIn
, const CLSID & clsidTaskMinorIn
, ULONG ulMinIn
, ULONG ulMaxIn
, UINT idsDescriptionStringIdIn
, UINT idsReferenceStringIdIn
)
: m_pbcaiInterface( pbcaiInterfaceIn )
, m_clsidTaskMajor( clsidTaskMajorIn )
, m_clsidTaskMinor( clsidTaskMinorIn )
, m_ulMin( ulMinIn )
, m_ulMax( ulMaxIn )
, m_ulNext( ulMinIn )
, m_idsDescriptionStringId( idsDescriptionStringIdIn )
, m_idsReferenceStringId( idsReferenceStringIdIn )
, m_fLastStepSent( false )
{
TraceFunc( "" );
// Validate the parameters.
if ( ( pbcaiInterfaceIn == NULL )
|| ( ulMinIn > ulMaxIn )
)
{
THR( E_INVALIDARG );
THROW_ASSERT( E_INVALIDARG, "The parameters for this status report are invalid." );
} // if: the parameters are invalid
TraceFuncExit();
} //*** CStatusReport::CStatusReport
// Default destructor.
~CStatusReport( void )
{
TraceFunc( "" );
// If the last step has not been sent, queue it for sending. This is most probably because
// an exception has occurred (if no exception has occurred and the last step has not been
// sent, then it is a programming error).
if ( ! m_fLastStepSent )
{
// The last step has not been sent.
// Don't throw exceptions from destructor. An unwind may already be in progress.
try
{
// Queue the last step for sending. The CBCAInterface object will fill in the
// error code from the current exception and send this report.
m_pbcaiInterface->QueueStatusReportCompletion(
m_clsidTaskMajor
, m_clsidTaskMinor
, m_ulMin
, m_ulMax
, m_idsDescriptionStringId
, m_idsReferenceStringId
);
}
catch( ... )
{
// Catch all errors. Do not rethrow this exception - the app may be terminated due to
// a collided unwind - so log the error.
THR( E_UNEXPECTED );
LogMsg( "[BC] Caught an exception while trying to send the last step of a status report during cleanup." );
}
}
TraceFuncExit();
} //*** CStatusReport::~CStatusReport
//////////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////////
// Send the next step of this report.
void SendNextStep( HRESULT hrStatusIn, UINT idsDescriptionStringIdIn = 0, UINT idsReferenceStringIdIn = 0 )
{
TraceFunc( "" );
if ( m_fLastStepSent )
{
LogMsg( "[BC] The last step for this status report has already been sent! Throwing an exception." );
THR( E_INVALIDARG );
THROW_ASSERT( E_INVALIDARG, "The last step for this status report has already been sent." );
} // if: the last step has already been sent
else
{
if ( idsDescriptionStringIdIn == 0 )
{
idsDescriptionStringIdIn = m_idsDescriptionStringId;
}
if ( idsReferenceStringIdIn == 0 )
{
idsReferenceStringIdIn = m_idsReferenceStringId;
}
m_pbcaiInterface->SendStatusReport(
m_clsidTaskMajor
, m_clsidTaskMinor
, m_ulMin
, m_ulMax
, m_ulNext
, hrStatusIn
, idsDescriptionStringIdIn
, idsReferenceStringIdIn
);
++m_ulNext;
m_fLastStepSent = ( m_ulNext > m_ulMax );
} // else: the last step has not been sent
TraceFuncExit();
} //*** CStatusReport::SendNextStep
// Send the last step of this report, if it hasn't been sent already.
void SendLastStep( HRESULT hrStatusIn, UINT idsDescriptionStringIdIn = 0, UINT idsReferenceStringIdIn = 0 )
{
TraceFunc( "" );
if ( m_fLastStepSent )
{
LogMsg( "[BC] The last step for this status report has already been sent! Throwing an exception." );
THR( E_INVALIDARG );
THROW_ASSERT( E_INVALIDARG, "The last step for this status report has already been sent." );
} // if: the last step has already been sent
else
{
if ( idsDescriptionStringIdIn == 0 )
{
idsDescriptionStringIdIn = m_idsDescriptionStringId;
}
if ( idsReferenceStringIdIn == 0 )
{
idsReferenceStringIdIn = m_idsReferenceStringId;
}
m_pbcaiInterface->SendStatusReport(
m_clsidTaskMajor
, m_clsidTaskMinor
, m_ulMin
, m_ulMax
, m_ulMax
, hrStatusIn
, idsDescriptionStringIdIn
, idsReferenceStringIdIn
);
m_fLastStepSent = true;
} // else: the last step has not been sent
TraceFuncExit();
} //*** CStatusReport::SendLastStep
// Get the description string ID.
UINT IdsGetDescriptionStringId( void )
{
return m_idsDescriptionStringId;
}
// Set the description string ID.
void SetDescriptionStringId( UINT idsDescriptionStringIdIn )
{
m_idsDescriptionStringId = idsDescriptionStringIdIn;
}
// Get the reference string ID.
UINT IdsGetReferenceStringId( void )
{
return m_idsReferenceStringId;
}
// Set the reference string ID.
void SetReferenceStringId( UINT idsReferenceStringIdIn )
{
m_idsReferenceStringId = idsReferenceStringIdIn;
}
private:
//////////////////////////////////////////////////////////////////////////
// Private data
//////////////////////////////////////////////////////////////////////////
// Pointer to the interface class.
CBCAInterface * m_pbcaiInterface;
// The major and minor class id to be sent with this status report.
CLSID m_clsidTaskMajor;
CLSID m_clsidTaskMinor;
// The range for this status report
ULONG m_ulMin;
ULONG m_ulMax;
ULONG m_ulNext;
// The string id of the description to be sent with this status report
UINT m_idsDescriptionStringId;
// The REF string id of the description to be sent with this status report
UINT m_idsReferenceStringId;
// Flag to indicate if the last step has been sent.
bool m_fLastStepSent;
}; //*** class CStatusReport