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.
 
 
 
 
 
 

344 lines
9.5 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 2000.
//
// File: CIRCSTOB.CXX
//
// Contents: Down-Level Recoverable Storage Object
//
// Classes: CiRcovStorageObj
//
// History: 04-Feb-1994 SrikantS Created
//
//----------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include <circstob.hxx>
#include <eventlog.hxx>
//+---------------------------------------------------------------------------
//
// Function: CiRcovStorageObj::CiRcovStorageObj
//
// Synopsis: Constructor for CiRcovStorageObj.
//
// Effects: Results in the initialization of the header information
// of the recoverable storage object.
//
// Arguments: [storage] -- Storage object for content index.
// [wcsHdr] -- Full path name of the header file.
// [wcsCopy1] -- Full path name of the copy 1.
// [wcsCopy2] -- Full path name of the copy 2.
// [cbDiskSpaceToLeave] -- Megabytes to leave on disk
// [fReadOnly] -- Read only?
//
// Modifies:
//
// Algorithm:
//
// History: 2-05-94 srikants Created
// 11-30-94 srikants Modified to deal with version
// initialization.
// 02-12-98 kitmanh Adding a readOnly parameter to the
// constructor and changes to deal with
// read-only catalogs
// 03-18-98 kitmanh Init the embedded CMmStream with
// value of _fIsReadOnly
// 27-Oct-98 KLam Added cbDiskSpaceToLeave
//
//
// Notes: The constructor initializes the header information but
// does not open the copy 1 or copy 2. That is does in the
// QueryMmStream() method.
//
//----------------------------------------------------------------------------
CiRcovStorageObj::CiRcovStorageObj( CiStorage & storage,
WCHAR * wcsHdr,
WCHAR * wcsCopy1,
WCHAR * wcsCopy2,
ULONG cbDiskSpaceToLeave,
BOOL fReadOnly)
: PRcovStorageObj( storage ),
_storage(storage),
_wcsCopy1(NULL),
_wcsCopy2(NULL),
_cbDiskSpaceToLeave(cbDiskSpaceToLeave),
_hdrStrm(cbDiskSpaceToLeave),
_fIsReadOnly(fReadOnly)
{
Win4Assert( wcsHdr );
Win4Assert( wcsCopy1 );
Win4Assert( wcsCopy2 );
_apMmStrm[0] = _apMmStrm[1] = NULL;
//
// Initialize the header stream (to reset value of CMmStrem::_fIsReadOnly)
//
InithdrStrm();
//
// Open the header stream.
//
_hdrStrm.OpenExclusive( wcsHdr, _fIsReadOnly );
if ( !_hdrStrm.Ok() )
{
THROW( CException() );
}
//
// Check if this is the first time the recoverable object is being
// constructed.
//
BOOL fVirgin = _hdrStrm.SizeLow() == 0 && _hdrStrm.SizeHigh() == 0;
if ( fVirgin )
{
if ( !fReadOnly )
{
//
// There is no data on disk.
//
_hdrStrm.SetSize( _storage, sizeof(CRcovStorageHdr), 0 );
_hdrStrm.MapAll( _hdrSbuf );
//
// Make sure the new header makes it to disk.
//
WriteHeader();
}
}
else
{
//
// By default, the size of the mm stream is always set to the large
// page. Here, we don't need it to be that big.
//
_hdrStrm.MapAll( _hdrSbuf );
const BYTE * pbuf = (const BYTE *)_hdrSbuf.Get();
_hdr.Init( (const void *) pbuf, sizeof(CRcovStorageHdr) );
if ( _hdr.GetVersion() != _storage.GetStorageVersion() )
{
ciDebugOut(( DEB_ERROR,
"Ci Version Mismatch - OnDisk 0x%X Binaries 0x%X\n",
_hdr.GetVersion(), _storage.GetStorageVersion() ));
#if 0
//
// Disabled because general NT user does not want to be bothered by
// the version change assert.
//
Win4Assert( !"The on disk catalog version and that of the binaries"
" are different\n. Catalog will be reindexed. Hit OK." );
#endif
_storage.ReportCorruptComponent( L"CI-RcovStorageObj1" );
THROW( CException( CI_INCORRECT_VERSION ) );
}
}
Win4Assert( _hdr.GetVersion() == _storage.GetStorageVersion() );
TRY
{
_wcsCopy1 = new WCHAR [wcslen(wcsCopy1)+1];
_wcsCopy2 = new WCHAR [wcslen(wcsCopy2)+1];
wcscpy( _wcsCopy1, wcsCopy1 );
wcscpy( _wcsCopy2, wcsCopy2 );
VerifyConsistency();
}
CATCH( CException, e )
{
delete [] _wcsCopy1;
delete [] _wcsCopy2;
RETHROW();
}
END_CATCH
}
CiRcovStorageObj::~CiRcovStorageObj()
{
//
// If the header stream is still mapped, then unmap it.
//
if ( _hdrSbuf.Get() ) {
_hdrStrm.Unmap( _hdrSbuf );
}
_hdrStrm.Close();
delete [] _wcsCopy1;
delete [] _wcsCopy2;
Close( CRcovStorageHdr::idxOne );
Close( CRcovStorageHdr::idxTwo );
}
//+---------------------------------------------------------------------------
//
// Function: Open
//
// Synopsis: Opens the specified stream with the specified access.
//
// Arguments: [n] -- Stream copy to open.
// [fWrite] -- Flag indicating if open in write mode.
//
// History: 2-05-94 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
void CiRcovStorageObj::Open( CRcovStorageHdr::DataCopyNum n, BOOL fWrite )
{
AssertValidIndex(n);
Win4Assert( !IsOpen(n) );
//
// Create the memory mapped stream with the specified open mode.
//
_apMmStrm[n] = QueryMmStream( n, fWrite );
}
//+---------------------------------------------------------------------------
//
// Function: Close
//
// Synopsis: Closes the specified stream if it is open. Also, if the
// stream buffer associated with this stream is mapped, it
// will be unmapped before closing.
//
// Arguments: [n] -- the stream copy to close.
//
// History: 2-05-94 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
void CiRcovStorageObj::Close( CRcovStorageHdr::DataCopyNum n )
{
AssertValidIndex(n);
if ( IsOpen(n) )
{
//
// If the stream is still mapped, then it must be
// unmapped first.
//
if ( IsMapped(n) )
{
_apMmStrm[n]->Unmap( GetMmStreamBuf( n ) );
}
//
// Closing the stream automatically flushes the contents.
//
_apMmStrm[n]->Close();
delete _apMmStrm[n];
_apMmStrm[n] = NULL;
}
}
void CiRcovStorageObj::ReadHeader()
{
const BYTE * pbHdr;
Win4Assert( _hdrStrm.SizeLow() >= sizeof(CRcovStorageHdr) );
pbHdr = (const BYTE *) _hdrSbuf.Get();
Win4Assert( pbHdr );
memcpy( &_hdr, pbHdr, sizeof(CRcovStorageHdr) );
}
void CiRcovStorageObj::WriteHeader()
{
BYTE * pbHdr;
Win4Assert( _hdrStrm.SizeLow() >= sizeof(CRcovStorageHdr) );
Win4Assert( _hdrStrm.isWritable() );
pbHdr = (BYTE *) _hdrSbuf.Get();
Win4Assert( pbHdr );
memcpy( pbHdr, &_hdr , sizeof(CRcovStorageHdr) );
_hdrStrm.Flush( _hdrSbuf, sizeof(CRcovStorageHdr) );
}
//+---------------------------------------------------------------------------
//
// Function: QueryMmStream
//
// Synopsis: Creates a Memory Mapped Stream for the specified copy.
// If one doesn't exist already, a new one will be created.
//
// Arguments: [n] -- Copy number of the stream.
// [fWritable] -- Set to TRUE if the stream is writable.
//
// Returns: Pointer to the memory mapped stream.
//
// History: 2-05-94 srikants Created
// 3-03-98 kitmanh Added code to deal with read-only catalogs
// 27-Oct-98 KLam Pass _cbDiskSpaceToLeave to CMmStream
//
// Notes: It is upto the caller to free up the object created.
//
//----------------------------------------------------------------------------
PMmStream *
CiRcovStorageObj::QueryMmStream( CRcovStorageHdr::DataCopyNum n,
BOOL fWritable )
{
WCHAR * wcsName = ( n == CRcovStorageHdr::idxOne ) ? _wcsCopy1 :
_wcsCopy2;
CMmStream * pMmStrm = new CMmStream( _cbDiskSpaceToLeave, _fIsReadOnly );
ULONG modeShare = 0; // No sharing
ULONG modeCreate = _fIsReadOnly ? OPEN_EXISTING : OPEN_ALWAYS;
ULONG modeAccess = GENERIC_READ;
if ( fWritable && !_fIsReadOnly )
{
modeAccess |= GENERIC_WRITE;
}
//
// A Safe Pointer is needed because the open can fail.
//
XPtr<PMmStream> sMmStrm( pMmStrm );
pMmStrm->Open( wcsName,
modeAccess,
modeShare,
modeCreate,
FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED );
if ( !pMmStrm->Ok() )
{
ciDebugOut(( DEB_ERROR, "querymmstrm failed due to %#x\n",
pMmStrm->GetStatus() ));
THROW( CException(STATUS_OBJECT_PATH_INVALID) );
}
sMmStrm.Acquire();
return pMmStrm;
}