summaryrefslogtreecommitdiff
path: root/src/md/inc/stgio.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/md/inc/stgio.h')
-rw-r--r--src/md/inc/stgio.h293
1 files changed, 293 insertions, 0 deletions
diff --git a/src/md/inc/stgio.h b/src/md/inc/stgio.h
new file mode 100644
index 0000000000..96a2f1dddb
--- /dev/null
+++ b/src/md/inc/stgio.h
@@ -0,0 +1,293 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//*****************************************************************************
+// StgIO.h
+//
+
+//
+// This module handles disk/memory i/o for a generic set of storage solutions,
+// including:
+// * File system handle (HFILE)
+// * IStream
+// * User supplied memory buffer (non-movable)
+//
+// The Read, Write, Seek, ... functions are all directed to the corresponding
+// method for each type of file, allowing the consumer to use one set of api's.
+//
+// File system data can be paged fully into memory in two scenarios:
+// read: Normal memory mapped file is created to manage paging.
+// write: A custom paging system provides storage for pages as required. This
+// data is invalidated when you call Rewrite on the file.
+//
+// Transactions and backups are handled in the existing file case only. The
+// Rewrite function can make a backup of the current contents, and the Restore
+// function can be used to recover the data into the current scope. The backup
+// file is flushed to disk (which is slower but safer) after the copy. The
+// Restore also flushed the recovered changes to disk. Worst case scenario you
+// get a crash after calling Rewrite but before Restore, in which case you will
+// have a foo.clb.txn file in the same directory as the source file, foo.clb in
+// this example.
+//<TODO>
+// @FUTURE: issues,
+// 1. For reading a .clb in an image, it would be great to memory map
+// only the portion of the file with the .clb in it.
+//</TODO>
+//*****************************************************************************
+#ifndef __STGIO_H_
+#define __STGIO_H_
+
+#define MAXSHMEM 32
+
+#define STGIO_READ 0x1
+#define STGIO_WRITE 0x2
+
+enum DBPROPMODE
+ { DBPROP_TMODEF_READ = 0x1,
+ DBPROP_TMODEF_WRITE = 0x2,
+ DBPROP_TMODEF_EXCLUSIVE = 0x4,
+#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
+ // Shared memory uses ole32.dll - we cannot depend on it in the standalone WinRT Read-Only DLL
+ DBPROP_TMODEF_SHAREDMEM = 0x8,
+#endif
+ DBPROP_TMODEF_CREATE = 0x10,
+ DBPROP_TMODEF_FAILIFTHERE = 0x20,
+ DBPROP_TMODEF_SLOWSAVE = 0x100,
+ // Means it is OK to use LoadLibrary to map the file. Used by code:ofTrustedImage.
+ // We prefer that because it is shared with loader's image loading.
+ DBPROP_TMODEF_TRYLOADLIBRARY = 0x400,
+#if 0 // dead code
+ DBPROP_TMODEF_NOTXNBACKUPFILE = 0x200,
+ DBPROP_TMODEF_COMPLUS = 0x1000,
+ DBPROP_TMODEF_SMEMCREATE = 0x2000,
+ DBPROP_TMODEF_SMEMOPEN = 0x4000,
+ DBPROP_TMODEF_ALIGNBLOBS = 0x10000
+ DBPROP_TMODEF_RESERVED = 0x80000000,
+#endif
+ DBPROP_TMODEF_DFTWRITEMASK = 0x113,
+ DBPROP_TMODEF_DFTREADWRITEMASK = 0x103,
+ };
+
+
+// Types of IO we can handle.
+enum STGIOTYPE
+{
+ STGIO_NODATA = 0, // Currently not open.
+ STGIO_HFILE = 1, // File handle contains data.
+ STGIO_HMODULE = 2, // The file was loaded via LoadLibrary as module.
+ STGIO_STREAM = 3, // Stream pointer has data.
+ STGIO_MEM = 4, // In memory pointer has data.
+#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
+ // Shared memory uses ole32.dll - we cannot depend on it in the standalone WinRT Read-Only DLL
+ STGIO_SHAREDMEM = 5, // Shared memory handle.
+#endif
+ STGIO_HFILEMEM = 6 // Handle open, but memory allocated.
+};
+
+class StgIO
+{
+ friend class CLiteWeightStgdbRW; // for low-level access to data for metainfo and such.
+ friend class TiggerStorage;
+public:
+ StgIO(
+ bool bAutoMap=true); // Memory map for read on open?
+
+ ~StgIO();
+
+//*****************************************************************************
+// Open the base file on top of: (a) file, (b) memory buffer, or (c) stream.
+// If create flag is specified, then this will create a new file with the
+// name supplied. No data is read from an opened file. You must call
+// MapFileToMem before doing direct pointer access to the contents.
+//*****************************************************************************
+ HRESULT Open( // Return code.
+ LPCWSTR szName, // Name of the storage.
+ int fFlags, // How to open the file.
+ const void *pbBuff, // Optional buffer for memory.
+ ULONG cbBuff, // Size of buffer.
+ IStream *pIStream, // Stream for input.
+ LPSECURITY_ATTRIBUTES pAttributes); // Security token.
+
+//*****************************************************************************
+// Shut down the file handles and allocated objects.
+//*****************************************************************************
+ void Close();
+
+//*****************************************************************************
+// Read data from the storage source. This will handle all types of backing
+// storage from mmf, streams, and file handles. No read ahead or MRU
+// caching is done.
+//*****************************************************************************
+ HRESULT Read( // Return code.
+ void *pbBuff, // Write buffer here.
+ ULONG cbBuff, // How much to read.
+ ULONG *pcbRead); // How much read.
+
+//*****************************************************************************
+// Write to disk. This function will cache up to a page of data in a buffer
+// and peridocially flush it on overflow and explicit request. This makes it
+// safe to do lots of small writes without too much performance overhead.
+//*****************************************************************************
+ HRESULT Write( // Return code.
+ const void *pbBuff, // Buffer to write.
+ ULONG cbWrite, // How much.
+ ULONG *pcbWritten); // Return how much written.
+
+//*****************************************************************************
+// Moves the file pointer to the new location. This handles the different
+// types of storage systems.
+//*****************************************************************************
+ HRESULT Seek( // New offset.
+ int lVal, // How much to move.
+ ULONG fMoveType); // Direction, use Win32 FILE_xxxx.
+
+//*****************************************************************************
+// Retrieves the current offset for the storage being used. This value is
+// tracked based on Read, Write, and Seek operations.
+//*****************************************************************************
+ ULONG GetCurrentOffset(); // Current offset.
+
+//*****************************************************************************
+// Map the file contents to a memory mapped file and return a pointer to the
+// data. For read/write with a backing store, map the file using an internal
+// paging system.
+//*****************************************************************************
+ HRESULT MapFileToMem( // Return code.
+ void *&ptr, // Return pointer to file data.
+ ULONG *pcbSize, // Return size of data.
+ LPSECURITY_ATTRIBUTES pAttributes=0); // Security token.
+
+//*****************************************************************************
+// Free the mapping object for shared memory but keep the rest of the internal
+// state intact.
+//*****************************************************************************
+ HRESULT ReleaseMappingObject(); // Return code.
+
+//*****************************************************************************
+// Resets the logical base address and size to the value given. This is for
+// cases like finding a section embedded in another format, like the .clb inside
+// of an image. GetPtrForMem, Read, and Seek will then behave as though only
+// data from pbStart to cbSize is valid.
+//*****************************************************************************
+ HRESULT SetBaseRange( // Return code.
+ void *pbStart, // Start of file data.
+ ULONG cbSize); // How big is the range.
+
+//*****************************************************************************
+// For read/write case, get a pointer to a chunk of the file at cbStart for
+// size cbSize. Return the pointer. This will page in parts of the file from
+// disk if not already loaded.
+//*****************************************************************************
+ HRESULT GetPtrForMem( // Return code.
+ ULONG cbStart, // Offset from beginning to load.
+ ULONG cbSize, // How much, rounded to page.
+ void *&ptr); // Return pointer on success.
+
+//*****************************************************************************
+// For cached writes, flush the cache to the data store.
+//*****************************************************************************
+ HRESULT FlushCache();
+
+//*****************************************************************************
+// Tells the file system to flush any cached data it may have. This is
+// expensive, but if successful guarantees you won't lose writes short of
+// a disk failure.
+//*****************************************************************************
+ HRESULT FlushFileBuffers();
+
+//*****************************************************************************
+// Called after a successful rewrite of an existing file. The in memory
+// backing store is no longer valid because all new data is in memory and
+// on disk. This is essentially the same state as created, so free up some
+// working set and remember this state.
+//*****************************************************************************
+ HRESULT ResetBackingStore(); // Return code.
+
+ FILETYPE GetFileType()
+ { return m_FileType; }
+
+ int IsReadOnly()
+ { return ((m_fFlags & STGIO_WRITE) == 0); }
+
+ ULONG GetFlags()
+ { return (m_fFlags); }
+
+ ULONG SetFlags(ULONG fFlags)
+ { m_fFlags = fFlags;
+ return (m_fFlags); }
+
+ ULONG GetDataSize()
+ { return (m_cbData); }
+
+ LONG AddRef()
+ {
+ return (++m_cRef);
+ }
+
+ LONG Release()
+ {
+ LONG cRef = --m_cRef;
+ if (cRef == 0)
+ delete this;
+ return (cRef);
+ }
+
+ int IsAlignedPtr(ULONG_PTR Value, int iAlignment);
+ MAPPINGTYPE GetMemoryMappedType()
+ { return m_mtMappedType;}
+
+
+//*****************************************************************************
+// Called to read the data into allocated memory and release the backing store.
+// Only available on read-only data.
+//*****************************************************************************
+ HRESULT LoadFileToMemory();
+
+
+private:
+ int IsBackingStore()
+ { return (m_rgPageMap != 0); }
+ int IsMemoryMapped()
+ { return ((m_hMapping != NULL) || (m_hModule != NULL)); }
+
+ void CtorInit();
+ HRESULT WriteToDisk(const void *pbBuff, ULONG cbWrite, ULONG *pcbWritten);
+ HRESULT ReadFromDisk(void *pbBuff, ULONG cbBuff, ULONG *pcbRead);
+ HRESULT CopyFileInternal(LPCWSTR szTo, int bFailIfThere, int bWriteThrough);
+ void FreePageMap();
+
+private:
+
+ // Flags and state data.
+ FILETYPE m_FileType; // Cached type of the file (based on extension).
+ LONG m_cRef; // Ref count on this object.
+ bool m_bWriteThrough : 1; // true for write through mode.
+ bool m_bRewrite : 1; // State check for rewrite mode.
+ bool m_bAutoMap : 1; // true to automatically memory map file.
+ bool m_bFreeMem : 1; // true to free allocated memory.
+
+ // Handles.
+ IStream * m_pIStream; // For save to stream instead of file.
+ HANDLE m_hFile; // The actual file with contents.
+ HANDLE m_hMapping; // Mapping handle.
+ HMODULE m_hModule; // If we load with LoadLibrary, this is the module (otherwise NULL).
+ void * m_pBaseData; // Base address for memory mapped file.
+ void * m_pData; // For memory mapped file read.
+ ULONG m_cbData; // Size of in memory data.
+ int m_fFlags; // Flags for open/create mode.
+ STGIOTYPE m_iType; // Where is the data.
+ MAPPINGTYPE m_mtMappedType; // How the file was memory mapped
+
+ // File cache information.
+ BYTE * m_rgBuff; // Cache buffer for writing.
+ ULONG m_cbBuff; // Current cache size.
+ ULONG m_cbOffset; // Current offset in file.
+
+ // Buffer read management.
+ static int m_iPageSize; // Size of an OS page.
+ static int m_iCacheSize; // How big a write back cache to use.
+ BYTE * m_rgPageMap; // Track loaded pages on read/write.
+
+}; // class StgIO
+
+#endif // __STGIO_H_