408 lines
9.8 KiB
C++
408 lines
9.8 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1998.
|
|
//
|
|
// File: mmstrm.hxx
|
|
//
|
|
// Contents: Memory Mapped Stream
|
|
//
|
|
// Classes: CMmStream, CMmStreamBuf
|
|
//
|
|
// History: 10-Mar-93 BartoszM Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#include <pmmstrm.hxx>
|
|
#include <driveinf.hxx>
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CMmStream
|
|
//
|
|
// Purpose: Memory Mapped Stream
|
|
//
|
|
// History: 10-Mar-93 BartoszM Created
|
|
// 18-Mar-98 KitmanH Added a protected member
|
|
// _fIsReadOnly
|
|
// 26-Oct-98 KLam Added _cMegToLeaveOnDisk
|
|
// Added CDriveInfo smart pointer
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CMmStream: public PMmStream
|
|
{
|
|
friend class CMmStreamBuf;
|
|
friend class CDupStream;
|
|
|
|
public:
|
|
|
|
CMmStream( ULONG cbDiskSpaceToLeave = CI_MIN_DISK_SPACE_TO_LEAVE_DEFAULT,
|
|
BOOL fIsReadOnly = FALSE );
|
|
|
|
BOOL Ok() { return _hFile != INVALID_HANDLE_VALUE; }
|
|
|
|
virtual ~CMmStream();
|
|
|
|
void OpenExclusive ( WCHAR* wcsPath, BOOL fReadOnly);
|
|
|
|
void Open ( const WCHAR* wcsPath,
|
|
ULONG modeAccess,
|
|
ULONG modeShare,
|
|
ULONG modeCreate,
|
|
ULONG modeAttribute = FILE_ATTRIBUTE_NORMAL,
|
|
BOOL fSparse = FALSE );
|
|
|
|
void Close();
|
|
|
|
void SetSize ( PStorage& storage,
|
|
ULONG newSizeLow,
|
|
ULONG newSizeHigh=0 );
|
|
|
|
BOOL isEmpty() { return _sizeHigh == 0 && _sizeLow == 0; }
|
|
|
|
ULONG SizeLow() { return _sizeLow; }
|
|
|
|
ULONG SizeHigh() { return _sizeHigh; }
|
|
|
|
LONGLONG Size()
|
|
{
|
|
return llfromuls( _sizeLow, _sizeHigh );
|
|
}
|
|
|
|
BOOL isWritable() { return _fWrite; }
|
|
|
|
void MapAll ( CMmStreamBuf& sbuf );
|
|
|
|
void Map ( CMmStreamBuf& sbuf,
|
|
ULONG cb = 0,
|
|
ULONG offLow = 0,
|
|
ULONG offHigh = 0,
|
|
BOOL fMapForWrite = FALSE );
|
|
|
|
void Unmap ( CMmStreamBuf& sbuf );
|
|
|
|
void Flush ( CMmStreamBuf& sbuf, ULONG cb, BOOL fThrowOnFailure = TRUE );
|
|
|
|
void FlushMetaData( BOOL fThrowOnFailure = TRUE );
|
|
|
|
BOOL FStatusFileNotFound()
|
|
{
|
|
return _status == STATUS_OBJECT_NAME_NOT_FOUND
|
|
|| _status == STATUS_OBJECT_PATH_NOT_FOUND;
|
|
}
|
|
|
|
NTSTATUS GetStatus() const { return _status; }
|
|
|
|
ULONG ShrinkFromFront( ULONG firstPage, ULONG numPages );
|
|
|
|
#if CIDBG == 1
|
|
WCHAR const * GetPath() { return _xwcPath.Get(); }
|
|
#endif
|
|
|
|
void InitFIsReadOnly( BOOL fIsReadOnly ) { _fIsReadOnly = fIsReadOnly; }
|
|
|
|
void Read( void * pvBuffer, ULONGLONG oStart, DWORD cbToRead, DWORD & cbRead );
|
|
|
|
void Write( void * pvBuffer, ULONGLONG oStart, DWORD cbToWrite );
|
|
|
|
protected:
|
|
|
|
HANDLE _hFile;
|
|
HANDLE _hMap;
|
|
ULONG _sizeLow;
|
|
ULONG _sizeHigh;
|
|
|
|
BOOL _fWrite;
|
|
BOOL _fSparse;
|
|
NTSTATUS _status;
|
|
unsigned _cMap;
|
|
BOOL _fIsReadOnly;
|
|
ULONG _cMegToLeaveOnDisk;
|
|
XPtr<CDriveInfo> _xDriveInfo;
|
|
|
|
#if CIDBG == 1
|
|
XGrowable<WCHAR> _xwcPath;
|
|
#endif // CIDBG == 1
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CLockingMmStream
|
|
//
|
|
// Purpose: Memory Mapped Stream with reader/writer locking
|
|
//
|
|
// History: 13-Nov-97 dlee Created
|
|
// 27-Oct-98 KLam Added cbDiskSpaceToLeave
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CLockingMmStream: public PMmStream
|
|
{
|
|
public:
|
|
|
|
CLockingMmStream( ULONG cbDiskSpaceToLeave )
|
|
: _cRef( 0 ),
|
|
_mmStream( cbDiskSpaceToLeave )
|
|
{}
|
|
|
|
~CLockingMmStream()
|
|
{
|
|
Win4Assert( 0 == _cRef );
|
|
|
|
CWriteAccess lock( _rwLock );
|
|
}
|
|
|
|
void Open ( const WCHAR* wcsPath,
|
|
ULONG modeAccess,
|
|
ULONG modeShare,
|
|
ULONG modeCreate,
|
|
ULONG modeAttribute = FILE_ATTRIBUTE_NORMAL,
|
|
BOOL fSparse = FALSE )
|
|
{
|
|
CWriteAccess lock( _rwLock );
|
|
_mmStream.Open( wcsPath, modeAccess, modeShare, modeCreate,
|
|
modeAttribute, fSparse );
|
|
}
|
|
|
|
BOOL Ok() { return _mmStream.Ok(); }
|
|
|
|
void Close()
|
|
{
|
|
CWriteAccess lock( _rwLock );
|
|
Win4Assert( 0 == _cRef );
|
|
_mmStream.Close();
|
|
}
|
|
|
|
void SetSize ( PStorage & storage,
|
|
ULONG newSizeLow,
|
|
ULONG newSizeHigh=0 )
|
|
{
|
|
CWriteAccess lock( _rwLock );
|
|
_mmStream.SetSize( storage, newSizeLow, newSizeHigh );
|
|
}
|
|
|
|
BOOL isEmpty()
|
|
{
|
|
CReadAccess lock( _rwLock );
|
|
return _mmStream.isEmpty();
|
|
}
|
|
|
|
ULONG SizeLow()
|
|
{
|
|
CReadAccess lock( _rwLock );
|
|
return _mmStream.SizeLow();
|
|
}
|
|
|
|
ULONG SizeHigh()
|
|
{
|
|
CReadAccess lock( _rwLock );
|
|
return _mmStream.SizeHigh();
|
|
}
|
|
|
|
LONGLONG Size()
|
|
{
|
|
return _mmStream.Size();
|
|
}
|
|
|
|
BOOL isWritable()
|
|
{
|
|
CReadAccess lock( _rwLock );
|
|
return _mmStream.isWritable();
|
|
}
|
|
|
|
void MapAll ( CMmStreamBuf& sbuf )
|
|
{
|
|
CWriteAccess lock( _rwLock );
|
|
_mmStream.MapAll( sbuf );
|
|
}
|
|
|
|
void Map ( CMmStreamBuf& sbuf,
|
|
ULONG cb = 0,
|
|
ULONG offLow = 0,
|
|
ULONG offHigh = 0,
|
|
BOOL fMapForWrite = FALSE )
|
|
{
|
|
CWriteAccess lock( _rwLock );
|
|
_mmStream.Map( sbuf, cb, offLow, offHigh, fMapForWrite );
|
|
}
|
|
|
|
void Unmap ( CMmStreamBuf& sbuf )
|
|
{
|
|
CReadAccess lock( _rwLock );
|
|
_mmStream.Unmap( sbuf );
|
|
}
|
|
|
|
void Flush ( CMmStreamBuf& sbuf, ULONG cb, BOOL fThrowOnFailure = TRUE )
|
|
{
|
|
CReadAccess lock( _rwLock );
|
|
_mmStream.Flush( sbuf, cb, fThrowOnFailure );
|
|
}
|
|
|
|
void FlushMetaData( BOOL fThrowOnFailure = TRUE )
|
|
{
|
|
CReadAccess lock( _rwLock );
|
|
_mmStream.FlushMetaData( fThrowOnFailure );
|
|
}
|
|
|
|
ULONG ShrinkFromFront( ULONG firstPage, ULONG numPages )
|
|
{
|
|
CWriteAccess lock( _rwLock );
|
|
return _mmStream.ShrinkFromFront( firstPage, numPages );
|
|
}
|
|
|
|
#if CIDBG == 1
|
|
WCHAR const * GetPath() { return _mmStream.GetPath(); }
|
|
#endif
|
|
|
|
void RefCount( CDupStream * p ) { _cRef++; }
|
|
void UnRefCount( CDupStream * p ) { _cRef--; }
|
|
|
|
void Read( void * pvBuffer, ULONGLONG oStart, DWORD cbToRead, DWORD & cbRead )
|
|
{
|
|
CWriteAccess lock( _rwLock );
|
|
|
|
_mmStream.Read( pvBuffer, oStart, cbToRead, cbRead );
|
|
}
|
|
|
|
void Write( void * pvBuffer, ULONGLONG oStart, DWORD cbToWrite )
|
|
{
|
|
CWriteAccess lock( _rwLock );
|
|
|
|
_mmStream.Write( pvBuffer, oStart, cbToWrite );
|
|
}
|
|
|
|
private:
|
|
|
|
unsigned _cRef;
|
|
CReadWriteAccess _rwLock;
|
|
CMmStream _mmStream;
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CDupMmStream
|
|
//
|
|
// Purpose: Duplicates an existing stream, so multiple storages can
|
|
// share 1 stream.
|
|
//
|
|
// History: 13-Nov-97 dlee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CDupStream: public PMmStream
|
|
{
|
|
public:
|
|
|
|
CDupStream( CLockingMmStream & mmStream ) : _mmStream(mmStream)
|
|
{
|
|
_mmStream.RefCount( this );
|
|
}
|
|
|
|
~CDupStream()
|
|
{
|
|
_mmStream.UnRefCount( this );
|
|
}
|
|
|
|
BOOL Ok() { return _mmStream.Ok(); }
|
|
|
|
void Close()
|
|
{
|
|
Win4Assert( !"Must Not Be Called" );
|
|
}
|
|
|
|
void SetSize ( PStorage& storage,
|
|
ULONG newSizeLow,
|
|
ULONG newSizeHigh=0 )
|
|
{
|
|
_mmStream.SetSize( storage, newSizeLow, newSizeHigh );
|
|
}
|
|
|
|
BOOL isEmpty()
|
|
{
|
|
return _mmStream.isEmpty();
|
|
}
|
|
|
|
ULONG SizeLow()
|
|
{
|
|
return _mmStream.SizeLow();
|
|
}
|
|
|
|
ULONG SizeHigh()
|
|
{
|
|
return _mmStream.SizeHigh();
|
|
}
|
|
|
|
LONGLONG Size()
|
|
{
|
|
return llfromuls( _mmStream.SizeLow(), _mmStream.SizeHigh() );
|
|
}
|
|
|
|
BOOL isWritable()
|
|
{
|
|
return _mmStream.isWritable();
|
|
}
|
|
|
|
void MapAll ( CMmStreamBuf& sbuf )
|
|
{
|
|
_mmStream.MapAll( sbuf );
|
|
}
|
|
|
|
void Map ( CMmStreamBuf& sbuf,
|
|
ULONG cb = 0,
|
|
ULONG offLow = 0,
|
|
ULONG offHigh = 0,
|
|
BOOL fMapForWrite = FALSE )
|
|
{
|
|
_mmStream.Map( sbuf, cb, offLow, offHigh, fMapForWrite );
|
|
}
|
|
|
|
void Unmap ( CMmStreamBuf& sbuf )
|
|
{
|
|
_mmStream.Unmap( sbuf );
|
|
}
|
|
|
|
void Flush ( CMmStreamBuf& sbuf, ULONG cb, BOOL fThrowOnFailure = TRUE )
|
|
{
|
|
_mmStream.Flush( sbuf, cb, fThrowOnFailure );
|
|
}
|
|
|
|
void FlushMetaData ( BOOL fThrowOnFailure = TRUE )
|
|
{
|
|
_mmStream.FlushMetaData( fThrowOnFailure );
|
|
}
|
|
|
|
ULONG ShrinkFromFront( ULONG firstPage, ULONG numPages )
|
|
{
|
|
Win4Assert( "!Must not be called" );
|
|
return(0);
|
|
}
|
|
|
|
PMmStream * DupStream()
|
|
{
|
|
Win4Assert( !"Must not be called" );
|
|
return(0);
|
|
}
|
|
|
|
void Read( void * pvBuffer, ULONGLONG oStart, DWORD cbToRead, DWORD & cbRead )
|
|
{
|
|
_mmStream.Read( pvBuffer, oStart, cbToRead, cbRead );
|
|
}
|
|
|
|
void Write( void * pvBuffer, ULONGLONG oStart, DWORD cbToWrite )
|
|
{
|
|
_mmStream.Write( pvBuffer, oStart, cbToWrite );
|
|
}
|
|
|
|
#if CIDBG == 1
|
|
WCHAR const * GetPath() { return _mmStream.GetPath(); }
|
|
#endif
|
|
|
|
private:
|
|
|
|
CLockingMmStream & _mmStream;
|
|
};
|
|
|