428 lines
12 KiB
C++
428 lines
12 KiB
C++
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// File: crecover.cxx
|
|||
|
//
|
|||
|
// Contents: Implementation for the CRecover support class.
|
|||
|
//
|
|||
|
// History: 09-Mar-93 SudK Created
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
|
|||
|
#include "headers.hxx"
|
|||
|
#pragma hdrstop
|
|||
|
|
|||
|
#include "crecover.hxx"
|
|||
|
|
|||
|
//+------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Method: CRecover::CRecover
|
|||
|
//
|
|||
|
// Synopsis: The Constructor for this Class. This constructor sets the
|
|||
|
// Operation Stage and Operation in its private section to 0.
|
|||
|
// No persistent storage operations are done here.
|
|||
|
//
|
|||
|
// Arguments: [iprop] -- The IProperty instance. Without this it does not
|
|||
|
// make sense to instantiate this class.
|
|||
|
//
|
|||
|
// Returns: Nothing.
|
|||
|
//
|
|||
|
// History: 09-Mar-1993 SudK Created.
|
|||
|
//
|
|||
|
//-------------------------------------------------------------------------
|
|||
|
CRecover::CRecover(void)
|
|||
|
{
|
|||
|
IDfsVolInlineDebOut((
|
|||
|
DEB_TRACE, "CRecover::+CRecover(0x%x)\n",
|
|||
|
this));
|
|||
|
|
|||
|
_Operation = 0;
|
|||
|
_OperStage = 0;
|
|||
|
_RecoveryState = 0;
|
|||
|
_RecoveryBuffer = _ulongBuffer;
|
|||
|
_pPSStg = NULL;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//+------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Method: CRecover::~CRecover
|
|||
|
//
|
|||
|
// Synopsis: The Destructor.
|
|||
|
//
|
|||
|
// Arguments: None
|
|||
|
//
|
|||
|
// Returns: It does nothing actually except to deallocate any memory.
|
|||
|
//
|
|||
|
// History: 09-Mar-1993 SudK Created.
|
|||
|
//
|
|||
|
//-------------------------------------------------------------------------
|
|||
|
CRecover::~CRecover(void)
|
|||
|
{
|
|||
|
IDfsVolInlineDebOut((
|
|||
|
DEB_TRACE, "CRecover::~CRecover(0x%x)\n",
|
|||
|
this));
|
|||
|
|
|||
|
if (_RecoveryBuffer != _ulongBuffer)
|
|||
|
delete [] _RecoveryBuffer;
|
|||
|
|
|||
|
if (_pPSStg != NULL)
|
|||
|
_pPSStg->Release();
|
|||
|
}
|
|||
|
|
|||
|
//+------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Method: CRecover::Initialise
|
|||
|
//
|
|||
|
// Synopsis: Set the IProperty interface. This should not be called twice!!
|
|||
|
//
|
|||
|
// Arguments: [pPSStg] -- The IPropertySetStg from here we get to Props
|
|||
|
//
|
|||
|
// Returns: Nothing.
|
|||
|
//
|
|||
|
// History: 09-Mar-1993 SudK Created.
|
|||
|
//
|
|||
|
//-------------------------------------------------------------------------
|
|||
|
VOID
|
|||
|
CRecover::Initialize(
|
|||
|
CStorage *pPSStg)
|
|||
|
{
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CRecover::Initialize()\n"));
|
|||
|
|
|||
|
ASSERT(_pPSStg == NULL);
|
|||
|
|
|||
|
if (_pPSStg != NULL)
|
|||
|
_pPSStg->Release();
|
|||
|
|
|||
|
_pPSStg = pPSStg;
|
|||
|
_pPSStg->AddRef();
|
|||
|
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CRecover::Initialize() exit\n"));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//+------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Method: CRecover::SetOperationStart
|
|||
|
//
|
|||
|
// Synopsis: Used when one is about to start an operation. Takes Operation
|
|||
|
// Code and any recovery arg if necessary.
|
|||
|
//
|
|||
|
// Arguments: [Operation] -- The operation code for which this class is
|
|||
|
// being instantiated.
|
|||
|
// [RecoverySvc]-- The Recovery Svc if any associated with this
|
|||
|
// Operation.
|
|||
|
//
|
|||
|
// Returns: Nothing. If it cant set properties it will throw an exception.
|
|||
|
//
|
|||
|
// Notes: Caller should take care of freeing the Service passed in.
|
|||
|
//
|
|||
|
// History: 09-Mar-1993 SudK Created.
|
|||
|
//
|
|||
|
//-------------------------------------------------------------------------
|
|||
|
DWORD
|
|||
|
CRecover::SetOperationStart(ULONG fOperation, CDfsService *pRecoverySvc)
|
|||
|
{
|
|||
|
ULONG size;
|
|||
|
DWORD dwErr = ERROR_SUCCESS;
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetOperationStart()\n"));
|
|||
|
|
|||
|
//
|
|||
|
// There could be a recovery buffer from a previous different operation.
|
|||
|
// So we need to get rid of it and create an appropriate sized one again.
|
|||
|
//
|
|||
|
if (_RecoveryBuffer != _ulongBuffer) {
|
|||
|
delete [] _RecoveryBuffer;
|
|||
|
_RecoveryBuffer = _ulongBuffer;
|
|||
|
}
|
|||
|
//
|
|||
|
// Set the private section variables first.
|
|||
|
//
|
|||
|
_Operation = fOperation;
|
|||
|
_OperStage = DFS_OPER_STAGE_START;
|
|||
|
|
|||
|
//
|
|||
|
// Create the RecoverState and the RecoverySvc in private section.
|
|||
|
//
|
|||
|
_RecoveryState = DFS_COMPOSE_RECOVERY_STATE(_Operation, _OperStage);
|
|||
|
|
|||
|
//
|
|||
|
// Let us figure out the marshalled buffer for the Service and create it.
|
|||
|
//
|
|||
|
if (pRecoverySvc != NULL) {
|
|||
|
size = pRecoverySvc->GetMarshalSize();
|
|||
|
|
|||
|
_RecoveryBuffer = new BYTE[size + sizeof(ULONG)];
|
|||
|
if (_RecoveryBuffer == NULL) {
|
|||
|
dwErr = ERROR_OUTOFMEMORY;
|
|||
|
return dwErr;
|
|||
|
}
|
|||
|
|
|||
|
_PutULong(_RecoveryBuffer, size);
|
|||
|
|
|||
|
pRecoverySvc->Serialize(_RecoveryBuffer + sizeof(ULONG), size);
|
|||
|
}
|
|||
|
else {
|
|||
|
//
|
|||
|
// In this case also we add a BLOB but however, this is only an Empty
|
|||
|
// BLOB. So this is easy to handle.
|
|||
|
//
|
|||
|
_PutULong(_RecoveryBuffer, 0);
|
|||
|
}
|
|||
|
|
|||
|
SetRecoveryProps(_RecoveryState, _RecoveryBuffer, FALSE);
|
|||
|
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetOperationStart() exit\n"));
|
|||
|
|
|||
|
return dwErr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//+------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Method: CRecover::SetDefaultProps
|
|||
|
//
|
|||
|
// Synopsis: This method sets null recovery props to start.
|
|||
|
//
|
|||
|
// Arguments: None
|
|||
|
//
|
|||
|
// Returns: Nothing.
|
|||
|
//
|
|||
|
// Notes: This may throw an exception. Failure of this is truly an
|
|||
|
// appropriate time to throw an exception.
|
|||
|
//
|
|||
|
// History: 12-21-1993 SudK Created.
|
|||
|
//
|
|||
|
//-------------------------------------------------------------------------
|
|||
|
VOID
|
|||
|
CRecover::SetDefaultProps(void)
|
|||
|
{
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetDefaultProps()\n"));
|
|||
|
|
|||
|
_RecoveryState = DFS_RECOVERY_STATE_NONE;
|
|||
|
_Operation = 0;
|
|||
|
_OperStage = 0;
|
|||
|
|
|||
|
_PutULong(_RecoveryBuffer, 0);
|
|||
|
SetRecoveryProps(_RecoveryState, _RecoveryBuffer, TRUE);
|
|||
|
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetDefaultProps() exit\n"));
|
|||
|
}
|
|||
|
|
|||
|
//+------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Method: CRecover::SetOperationDone
|
|||
|
//
|
|||
|
// Synopsis: This method deletes all recovery properties to signify end of
|
|||
|
// the Operation that was in progress.
|
|||
|
//
|
|||
|
// Arguments: [Operation] -- The Operation Code.
|
|||
|
//
|
|||
|
// Returns: Nothing.
|
|||
|
//
|
|||
|
// Notes: This may throw an exception. Failure of this is truly an
|
|||
|
// appropriate time to throw an exception.
|
|||
|
//
|
|||
|
// History: 09-Mar-1993 SudK Created.
|
|||
|
//
|
|||
|
//-------------------------------------------------------------------------
|
|||
|
VOID
|
|||
|
CRecover::SetOperationDone(void)
|
|||
|
{
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetOperationDone()\n"));
|
|||
|
|
|||
|
_RecoveryState = DFS_RECOVERY_STATE_NONE;
|
|||
|
_Operation = 0;
|
|||
|
_OperStage = 0;
|
|||
|
|
|||
|
_PutULong(_RecoveryBuffer, 0);
|
|||
|
SetRecoveryProps(_RecoveryState, _RecoveryBuffer, FALSE);
|
|||
|
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetOperationDone() exit\n"));
|
|||
|
}
|
|||
|
|
|||
|
//+------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Method: CRecover::SetOperStage
|
|||
|
//
|
|||
|
// Synopsis: This methods sets the operation stage in its private section
|
|||
|
// and at the same time updates the VolumeObject.
|
|||
|
//
|
|||
|
// Arguments: [OperStage] -- Operation Stage.
|
|||
|
//
|
|||
|
// Returns: Nothing. It throws an exception if it has any problems.
|
|||
|
//
|
|||
|
// History: 09-Mar-1993 SudK Created.
|
|||
|
//
|
|||
|
//-------------------------------------------------------------------------
|
|||
|
VOID
|
|||
|
CRecover::SetOperStage(ULONG OperStage)
|
|||
|
{
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetOperStage()\n"));
|
|||
|
|
|||
|
_OperStage = OperStage;
|
|||
|
_RecoveryState = DFS_COMPOSE_RECOVERY_STATE(_Operation, _OperStage);
|
|||
|
|
|||
|
SetRecoveryProps(_RecoveryState, _RecoveryBuffer, FALSE);
|
|||
|
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetOperStage() exit\n"));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//+------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Method: CRecover::SetRecoveryProps
|
|||
|
//
|
|||
|
// Synopsis: This method interacts with the actual property interface
|
|||
|
// to set the recovery properties.
|
|||
|
//
|
|||
|
// Arguments: [RecoveryState] -- Recovery State.
|
|||
|
// [RecoveryBuffer] -- Recovery Argument if any.
|
|||
|
// [bCreate] -- Whether to create Propset or not.
|
|||
|
//
|
|||
|
// Returns: Nothing. Will throw exception if anything goes wrong.
|
|||
|
//
|
|||
|
// Notes: Caller must free the buffer that he passed in.
|
|||
|
//
|
|||
|
// History: 09-Mar-1993 SudK Created.
|
|||
|
//
|
|||
|
//-------------------------------------------------------------------------
|
|||
|
VOID
|
|||
|
CRecover::SetRecoveryProps(
|
|||
|
ULONG RecoveryState,
|
|||
|
PBYTE RecoveryBuffer,
|
|||
|
BOOLEAN bCreate
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwErr;
|
|||
|
DWORD cbSize;
|
|||
|
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetRecoveryProps()\n"));
|
|||
|
|
|||
|
_GetULong(RecoveryBuffer, cbSize);
|
|||
|
_PutULong(RecoveryBuffer, RecoveryState);
|
|||
|
|
|||
|
dwErr = _pPSStg->SetRecoveryProps(RecoveryBuffer, cbSize+sizeof(ULONG));
|
|||
|
|
|||
|
_PutULong(RecoveryBuffer, cbSize);
|
|||
|
|
|||
|
if (dwErr != ERROR_SUCCESS) {
|
|||
|
IDfsVolInlineDebOut((
|
|||
|
DEB_ERROR, "Unable to Set RecoveryProperties %08lx\n",dwErr));
|
|||
|
|
|||
|
RaiseException ( dwErr, 0, 0, 0 );
|
|||
|
}
|
|||
|
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetRecoveryProps() exit\n"));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Method: CRecover::GetRecoveryProps, private
|
|||
|
//
|
|||
|
// Synopsis: Get the recovery related properties off the volume object.
|
|||
|
//
|
|||
|
// Arguments:[RecoveryState] -- The RecoveryState is returned here.
|
|||
|
// [ppRecoverySvc] -- If there is a recovery Svc it is returned here.
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
// History: 09-Feb-1993 SudK Created.
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
DWORD
|
|||
|
CRecover :: GetRecoveryProps(
|
|||
|
ULONG *RecoveryState,
|
|||
|
CDfsService **ppRecoverySvc
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwErr = ERROR_SUCCESS;
|
|||
|
PBYTE buffer, svcBuffer;
|
|||
|
ULONG size;
|
|||
|
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CDfsVolume::GetRecoveryProps()\n"));
|
|||
|
|
|||
|
//
|
|||
|
// Initialize all the arguments to NULL
|
|||
|
//
|
|||
|
|
|||
|
*RecoveryState = 0;
|
|||
|
*ppRecoverySvc = NULL;
|
|||
|
|
|||
|
dwErr = _pPSStg->GetRecoveryProps( &buffer, &size );
|
|||
|
|
|||
|
if (dwErr != ERROR_SUCCESS) {
|
|||
|
IDfsVolInlineDebOut((
|
|||
|
DEB_ERROR, "Unable to read recovery Props %08lx\n", dwErr));
|
|||
|
SetOperationDone();
|
|||
|
return(dwErr);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// First let us extract the RecoveryState property.
|
|||
|
//
|
|||
|
_GetULong(buffer, (*RecoveryState));
|
|||
|
|
|||
|
//
|
|||
|
// Next let us extract the RecoveryArg property.
|
|||
|
//
|
|||
|
|
|||
|
svcBuffer = buffer + sizeof(ULONG);
|
|||
|
size -= sizeof(ULONG);
|
|||
|
|
|||
|
//
|
|||
|
// Now that we have a buffer we have to create a service out of this.
|
|||
|
// If the buffer is of size Zero we will just return back a NULL ptr.
|
|||
|
//
|
|||
|
if (size != 0) {
|
|||
|
dwErr = CDfsService::DeSerialize(svcBuffer, size, ppRecoverySvc);
|
|||
|
if (dwErr != ERROR_SUCCESS) {
|
|||
|
IDfsVolInlineDebOut((
|
|||
|
DEB_ERROR, "Failed %d to unmarshall RecoverySvc\n", dwErr));
|
|||
|
*ppRecoverySvc = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
delete [] buffer;
|
|||
|
|
|||
|
IDfsVolInlineDebOut((DEB_TRACE, "CDfsVolume::GetRecoveryProps() exit\n"));
|
|||
|
|
|||
|
return dwErr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#if (DBG == 1) || (_CT_TEST_HOOK == 1)
|
|||
|
INIT_RECOVERY_BREAK_INFO()
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsSetRecoveryBreakPoint
|
|||
|
//
|
|||
|
// Synopsis: Sets the globals that determine when a recovery break point
|
|||
|
// is activated
|
|||
|
//
|
|||
|
// Arguments:[pBuffer] -- Marshalled buffer
|
|||
|
// [cbSize] -- Size of the marhalled buffer
|
|||
|
//
|
|||
|
// Returns: STATUS_SUCCESS -- Success
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
NTSTATUS DfsSetRecoveryBreakPoint(PBYTE pBuffer,
|
|||
|
ULONG cbSize)
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
MARSHAL_BUFFER marshalBuffer;
|
|||
|
|
|||
|
MarshalBufferFree(gRecoveryBkptInfo.pwszApiBreak);
|
|||
|
|
|||
|
MarshalBufferInitialize(&marshalBuffer, cbSize, pBuffer);
|
|||
|
|
|||
|
Status = DfsRtlGet(&marshalBuffer, &MiRecoveryBkpt, &gRecoveryBkptInfo);
|
|||
|
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|