//+--------------------------------------------------------------------------- // // 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 #include //+--------------------------------------------------------------------------- // // 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 _xDriveInfo; #if CIDBG == 1 XGrowable _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; };