| /* |
| * Compound Storage (32 bit version) |
| * |
| * Implemented using the documentation of the LAOLA project at |
| * <URL:http://wwwwbs.cs.tu-berlin.de/~schwartz/pmh/index.html> |
| * (Thanks to Martin Schwartz <schwartz@cs.tu-berlin.de>) |
| * |
| * This include file contains definitions of types and function |
| * prototypes that are used in the many files implementing the |
| * storage functionality |
| * |
| * Copyright 1998,1999 Francis Beaudet |
| * Copyright 1998,1999 Thuy Nguyen |
| * Copyright 2010 Vincent Povirk for CodeWeavers |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| #ifndef __STORAGE32_H__ |
| #define __STORAGE32_H__ |
| |
| #include <stdarg.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winnt.h" |
| #include "objbase.h" |
| #include "winreg.h" |
| #include "winternl.h" |
| #include "wine/list.h" |
| |
| /* |
| * Definitions for the file format offsets. |
| */ |
| static const ULONG OFFSET_MINORVERSION = 0x00000018; |
| static const ULONG OFFSET_MAJORVERSION = 0x0000001a; |
| static const ULONG OFFSET_BYTEORDERMARKER = 0x0000001c; |
| static const ULONG OFFSET_BIGBLOCKSIZEBITS = 0x0000001e; |
| static const ULONG OFFSET_SMALLBLOCKSIZEBITS = 0x00000020; |
| static const ULONG OFFSET_DIRSECTORCOUNT = 0x00000028; |
| static const ULONG OFFSET_BBDEPOTCOUNT = 0x0000002C; |
| static const ULONG OFFSET_ROOTSTARTBLOCK = 0x00000030; |
| static const ULONG OFFSET_SMALLBLOCKLIMIT = 0x00000038; |
| static const ULONG OFFSET_SBDEPOTSTART = 0x0000003C; |
| static const ULONG OFFSET_SBDEPOTCOUNT = 0x00000040; |
| static const ULONG OFFSET_EXTBBDEPOTSTART = 0x00000044; |
| static const ULONG OFFSET_EXTBBDEPOTCOUNT = 0x00000048; |
| static const ULONG OFFSET_BBDEPOTSTART = 0x0000004C; |
| static const ULONG OFFSET_PS_NAME = 0x00000000; |
| static const ULONG OFFSET_PS_NAMELENGTH = 0x00000040; |
| static const ULONG OFFSET_PS_STGTYPE = 0x00000042; |
| static const ULONG OFFSET_PS_LEFTCHILD = 0x00000044; |
| static const ULONG OFFSET_PS_RIGHTCHILD = 0x00000048; |
| static const ULONG OFFSET_PS_DIRROOT = 0x0000004C; |
| static const ULONG OFFSET_PS_GUID = 0x00000050; |
| static const ULONG OFFSET_PS_CTIMELOW = 0x00000064; |
| static const ULONG OFFSET_PS_CTIMEHIGH = 0x00000068; |
| static const ULONG OFFSET_PS_MTIMELOW = 0x0000006C; |
| static const ULONG OFFSET_PS_MTIMEHIGH = 0x00000070; |
| static const ULONG OFFSET_PS_STARTBLOCK = 0x00000074; |
| static const ULONG OFFSET_PS_SIZE = 0x00000078; |
| static const WORD DEF_BIG_BLOCK_SIZE_BITS = 0x0009; |
| static const WORD MIN_BIG_BLOCK_SIZE_BITS = 0x0009; |
| static const WORD MAX_BIG_BLOCK_SIZE_BITS = 0x000c; |
| static const WORD DEF_SMALL_BLOCK_SIZE_BITS = 0x0006; |
| static const WORD DEF_BIG_BLOCK_SIZE = 0x0200; |
| static const WORD DEF_SMALL_BLOCK_SIZE = 0x0040; |
| static const ULONG BLOCK_EXTBBDEPOT = 0xFFFFFFFC; |
| static const ULONG BLOCK_SPECIAL = 0xFFFFFFFD; |
| static const ULONG BLOCK_END_OF_CHAIN = 0xFFFFFFFE; |
| static const ULONG BLOCK_UNUSED = 0xFFFFFFFF; |
| static const ULONG DIRENTRY_NULL = 0xFFFFFFFF; |
| |
| #define DIRENTRY_NAME_MAX_LEN 0x20 |
| #define DIRENTRY_NAME_BUFFER_LEN 0x40 |
| |
| #define RAW_DIRENTRY_SIZE 0x00000080 |
| |
| #define HEADER_SIZE 512 |
| |
| #define MIN_BIG_BLOCK_SIZE 0x200 |
| #define MAX_BIG_BLOCK_SIZE 0x1000 |
| |
| /* |
| * Type of child entry link |
| */ |
| #define DIRENTRY_RELATION_PREVIOUS 0 |
| #define DIRENTRY_RELATION_NEXT 1 |
| #define DIRENTRY_RELATION_DIR 2 |
| |
| /* |
| * type constant used in files for the root storage |
| */ |
| #define STGTY_ROOT 0x05 |
| |
| #define COUNT_BBDEPOTINHEADER 109 |
| |
| /* FIXME: This value is stored in the header, but we hard-code it to 0x1000. */ |
| #define LIMIT_TO_USE_SMALL_BLOCK 0x1000 |
| |
| #define STGM_ACCESS_MODE(stgm) ((stgm)&0x0000f) |
| #define STGM_SHARE_MODE(stgm) ((stgm)&0x000f0) |
| #define STGM_CREATE_MODE(stgm) ((stgm)&0x0f000) |
| |
| #define STGM_KNOWN_FLAGS (0xf0ff | \ |
| STGM_TRANSACTED | STGM_CONVERT | STGM_PRIORITY | STGM_NOSCRATCH | \ |
| STGM_NOSNAPSHOT | STGM_DIRECT_SWMR | STGM_DELETEONRELEASE | STGM_SIMPLE) |
| |
| /* |
| * Forward declarations of all the structures used by the storage |
| * module. |
| */ |
| typedef struct StorageBaseImpl StorageBaseImpl; |
| typedef struct StorageBaseImplVtbl StorageBaseImplVtbl; |
| typedef struct StorageImpl StorageImpl; |
| typedef struct BlockChainStream BlockChainStream; |
| typedef struct SmallBlockChainStream SmallBlockChainStream; |
| typedef struct IEnumSTATSTGImpl IEnumSTATSTGImpl; |
| typedef struct DirEntry DirEntry; |
| typedef struct StgStreamImpl StgStreamImpl; |
| |
| /* |
| * A reference to a directory entry in the file or a transacted cache. |
| */ |
| typedef ULONG DirRef; |
| |
| /* |
| * This utility structure is used to read/write the information in a directory |
| * entry. |
| */ |
| struct DirEntry |
| { |
| WCHAR name[DIRENTRY_NAME_MAX_LEN]; |
| WORD sizeOfNameString; |
| BYTE stgType; |
| DirRef leftChild; |
| DirRef rightChild; |
| DirRef dirRootEntry; |
| GUID clsid; |
| FILETIME ctime; |
| FILETIME mtime; |
| ULONG startingBlock; |
| ULARGE_INTEGER size; |
| }; |
| |
| HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, LPCWSTR pwcsName, ILockBytes **pLockBytes) DECLSPEC_HIDDEN; |
| |
| /************************************************************************* |
| * Ole Convert support |
| */ |
| |
| void OLECONVERT_CreateOleStream(LPSTORAGE pStorage) DECLSPEC_HIDDEN; |
| HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName) DECLSPEC_HIDDEN; |
| |
| |
| /**************************************************************************** |
| * StorageBaseImpl definitions. |
| * |
| * This structure defines the base information contained in all implementations |
| * of IStorage contained in this file storage implementation. |
| * |
| * In OOP terms, this is the base class for all the IStorage implementations |
| * contained in this file. |
| */ |
| struct StorageBaseImpl |
| { |
| IStorage IStorage_iface; |
| IPropertySetStorage IPropertySetStorage_iface; /* interface for adding a properties stream */ |
| LONG ref; |
| |
| /* |
| * Stream tracking list |
| */ |
| |
| struct list strmHead; |
| |
| /* |
| * Storage tracking list |
| */ |
| struct list storageHead; |
| |
| /* |
| * TRUE if this object has been invalidated |
| */ |
| int reverted; |
| |
| /* |
| * Index of the directory entry of this storage |
| */ |
| DirRef storageDirEntry; |
| |
| /* |
| * virtual methods. |
| */ |
| const StorageBaseImplVtbl *baseVtbl; |
| |
| /* |
| * flags that this storage was opened or created with |
| */ |
| DWORD openFlags; |
| |
| /* |
| * State bits appear to only be preserved while running. No in the stream |
| */ |
| DWORD stateBits; |
| |
| BOOL create; /* Was the storage created or opened. |
| The behaviour of STGM_SIMPLE depends on this */ |
| /* |
| * If this storage was opened in transacted mode, the object that implements |
| * the transacted snapshot or cache. |
| */ |
| StorageBaseImpl *transactedChild; |
| }; |
| |
| /* virtual methods for StorageBaseImpl objects */ |
| struct StorageBaseImplVtbl { |
| void (*Destroy)(StorageBaseImpl*); |
| void (*Invalidate)(StorageBaseImpl*); |
| HRESULT (*Flush)(StorageBaseImpl*); |
| HRESULT (*GetFilename)(StorageBaseImpl*,LPWSTR*); |
| HRESULT (*CreateDirEntry)(StorageBaseImpl*,const DirEntry*,DirRef*); |
| HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*); |
| HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*); |
| HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef); |
| HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*); |
| HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*); |
| HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER); |
| HRESULT (*StreamLink)(StorageBaseImpl*,DirRef,DirRef); |
| }; |
| |
| static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This) |
| { |
| This->baseVtbl->Destroy(This); |
| } |
| |
| static inline void StorageBaseImpl_Invalidate(StorageBaseImpl *This) |
| { |
| This->baseVtbl->Invalidate(This); |
| } |
| |
| static inline HRESULT StorageBaseImpl_Flush(StorageBaseImpl *This) |
| { |
| return This->baseVtbl->Flush(This); |
| } |
| |
| static inline HRESULT StorageBaseImpl_GetFilename(StorageBaseImpl *This, LPWSTR *result) |
| { |
| return This->baseVtbl->GetFilename(This, result); |
| } |
| |
| static inline HRESULT StorageBaseImpl_CreateDirEntry(StorageBaseImpl *This, |
| const DirEntry *newData, DirRef *index) |
| { |
| return This->baseVtbl->CreateDirEntry(This, newData, index); |
| } |
| |
| static inline HRESULT StorageBaseImpl_WriteDirEntry(StorageBaseImpl *This, |
| DirRef index, const DirEntry *data) |
| { |
| return This->baseVtbl->WriteDirEntry(This, index, data); |
| } |
| |
| static inline HRESULT StorageBaseImpl_ReadDirEntry(StorageBaseImpl *This, |
| DirRef index, DirEntry *data) |
| { |
| return This->baseVtbl->ReadDirEntry(This, index, data); |
| } |
| |
| static inline HRESULT StorageBaseImpl_DestroyDirEntry(StorageBaseImpl *This, |
| DirRef index) |
| { |
| return This->baseVtbl->DestroyDirEntry(This, index); |
| } |
| |
| /* Read up to size bytes from this directory entry's stream at the given offset. */ |
| static inline HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This, |
| DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) |
| { |
| return This->baseVtbl->StreamReadAt(This, index, offset, size, buffer, bytesRead); |
| } |
| |
| /* Write size bytes to this directory entry's stream at the given offset, |
| * growing the stream if necessary. */ |
| static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This, |
| DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) |
| { |
| return This->baseVtbl->StreamWriteAt(This, index, offset, size, buffer, bytesWritten); |
| } |
| |
| static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This, |
| DirRef index, ULARGE_INTEGER newsize) |
| { |
| return This->baseVtbl->StreamSetSize(This, index, newsize); |
| } |
| |
| /* Make dst point to the same stream that src points to. Other stream operations |
| * will not work properly for entries that point to the same stream, so this |
| * must be a very temporary state, and only one entry pointing to a given stream |
| * may be reachable at any given time. */ |
| static inline HRESULT StorageBaseImpl_StreamLink(StorageBaseImpl *This, |
| DirRef dst, DirRef src) |
| { |
| return This->baseVtbl->StreamLink(This, dst, src); |
| } |
| |
| /**************************************************************************** |
| * StorageBaseImpl stream list handlers |
| */ |
| |
| void StorageBaseImpl_AddStream(StorageBaseImpl * stg, StgStreamImpl * strm) DECLSPEC_HIDDEN; |
| void StorageBaseImpl_RemoveStream(StorageBaseImpl * stg, StgStreamImpl * strm) DECLSPEC_HIDDEN; |
| |
| /* Number of BlockChainStream objects to cache in a StorageImpl */ |
| #define BLOCKCHAIN_CACHE_SIZE 4 |
| |
| /**************************************************************************** |
| * Storage32Impl definitions. |
| * |
| * This implementation of the IStorage32 interface represents a root |
| * storage. Basically, a document file. |
| */ |
| struct StorageImpl |
| { |
| struct StorageBaseImpl base; |
| |
| /* |
| * File header |
| */ |
| WORD bigBlockSizeBits; |
| WORD smallBlockSizeBits; |
| ULONG bigBlockSize; |
| ULONG smallBlockSize; |
| ULONG bigBlockDepotCount; |
| ULONG rootStartBlock; |
| ULONG smallBlockLimit; |
| ULONG smallBlockDepotStart; |
| ULONG extBigBlockDepotStart; |
| ULONG *extBigBlockDepotLocations; |
| ULONG extBigBlockDepotLocationsSize; |
| ULONG extBigBlockDepotCount; |
| ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER]; |
| |
| ULONG extBlockDepotCached[MAX_BIG_BLOCK_SIZE / 4]; |
| ULONG indexExtBlockDepotCached; |
| |
| ULONG blockDepotCached[MAX_BIG_BLOCK_SIZE / 4]; |
| ULONG indexBlockDepotCached; |
| ULONG prevFreeBlock; |
| |
| /* All small blocks before this one are known to be in use. */ |
| ULONG firstFreeSmallBlock; |
| |
| /* |
| * Abstraction of the big block chains for the chains of the header. |
| */ |
| BlockChainStream* rootBlockChain; |
| BlockChainStream* smallBlockDepotChain; |
| BlockChainStream* smallBlockRootChain; |
| |
| /* Cache of block chain streams objects for directory entries */ |
| BlockChainStream* blockChainCache[BLOCKCHAIN_CACHE_SIZE]; |
| UINT blockChainToEvict; |
| |
| ILockBytes* lockBytes; |
| }; |
| |
| HRESULT StorageImpl_ReadRawDirEntry( |
| StorageImpl *This, |
| ULONG index, |
| BYTE *buffer) DECLSPEC_HIDDEN; |
| |
| void UpdateRawDirEntry( |
| BYTE *buffer, |
| const DirEntry *newData) DECLSPEC_HIDDEN; |
| |
| HRESULT StorageImpl_WriteRawDirEntry( |
| StorageImpl *This, |
| ULONG index, |
| const BYTE *buffer) DECLSPEC_HIDDEN; |
| |
| HRESULT StorageImpl_ReadDirEntry( |
| StorageImpl* This, |
| DirRef index, |
| DirEntry* buffer) DECLSPEC_HIDDEN; |
| |
| HRESULT StorageImpl_WriteDirEntry( |
| StorageImpl* This, |
| DirRef index, |
| const DirEntry* buffer) DECLSPEC_HIDDEN; |
| |
| BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks( |
| StorageImpl* This, |
| SmallBlockChainStream** ppsbChain) DECLSPEC_HIDDEN; |
| |
| SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks( |
| StorageImpl* This, |
| BlockChainStream** ppbbChain, |
| ULARGE_INTEGER newSize) DECLSPEC_HIDDEN; |
| |
| /**************************************************************************** |
| * StgStreamImpl definitions. |
| * |
| * This class implements the IStream interface and represents a stream |
| * located inside a storage object. |
| */ |
| struct StgStreamImpl |
| { |
| IStream IStream_iface; |
| LONG ref; |
| |
| /* |
| * We are an entry in the storage object's stream handler list |
| */ |
| struct list StrmListEntry; |
| |
| /* |
| * Storage that is the parent(owner) of the stream |
| */ |
| StorageBaseImpl* parentStorage; |
| |
| /* |
| * Access mode of this stream. |
| */ |
| DWORD grfMode; |
| |
| /* |
| * Index of the directory entry that owns (points to) this stream. |
| */ |
| DirRef dirEntry; |
| |
| /* |
| * This is the current position of the cursor in the stream |
| */ |
| ULARGE_INTEGER currentPosition; |
| }; |
| |
| static inline StgStreamImpl *impl_from_IStream( IStream *iface ) |
| { |
| return CONTAINING_RECORD(iface, StgStreamImpl, IStream_iface); |
| } |
| |
| /* |
| * Method definition for the StgStreamImpl class. |
| */ |
| StgStreamImpl* StgStreamImpl_Construct( |
| StorageBaseImpl* parentStorage, |
| DWORD grfMode, |
| DirRef dirEntry) DECLSPEC_HIDDEN; |
| |
| |
| /****************************************************************************** |
| * Endian conversion macros |
| */ |
| #ifdef WORDS_BIGENDIAN |
| |
| #define htole32(x) RtlUlongByteSwap(x) |
| #define htole16(x) RtlUshortByteSwap(x) |
| #define lendian32toh(x) RtlUlongByteSwap(x) |
| #define lendian16toh(x) RtlUshortByteSwap(x) |
| |
| #else |
| |
| #define htole32(x) (x) |
| #define htole16(x) (x) |
| #define lendian32toh(x) (x) |
| #define lendian16toh(x) (x) |
| |
| #endif |
| |
| /****************************************************************************** |
| * The StorageUtl_ functions are miscellaneous utility functions. Most of which |
| * are abstractions used to read values from file buffers without having to |
| * worry about bit order |
| */ |
| void StorageUtl_ReadWord(const BYTE* buffer, ULONG offset, WORD* value) DECLSPEC_HIDDEN; |
| void StorageUtl_WriteWord(BYTE* buffer, ULONG offset, WORD value) DECLSPEC_HIDDEN; |
| void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value) DECLSPEC_HIDDEN; |
| void StorageUtl_WriteDWord(BYTE* buffer, ULONG offset, DWORD value) DECLSPEC_HIDDEN; |
| void StorageUtl_ReadULargeInteger(const BYTE* buffer, ULONG offset, |
| ULARGE_INTEGER* value) DECLSPEC_HIDDEN; |
| void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset, |
| const ULARGE_INTEGER *value) DECLSPEC_HIDDEN; |
| void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value) DECLSPEC_HIDDEN; |
| void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value) DECLSPEC_HIDDEN; |
| void StorageUtl_CopyDirEntryToSTATSTG(StorageBaseImpl *storage,STATSTG* destination, |
| const DirEntry* source, int statFlags) DECLSPEC_HIDDEN; |
| |
| /**************************************************************************** |
| * BlockChainStream definitions. |
| * |
| * The BlockChainStream class is a utility class that is used to create an |
| * abstraction of the big block chains in the storage file. |
| */ |
| struct BlockChainRun |
| { |
| /* This represents a range of blocks that happen reside in consecutive sectors. */ |
| ULONG firstSector; |
| ULONG firstOffset; |
| ULONG lastOffset; |
| }; |
| |
| typedef struct BlockChainBlock |
| { |
| ULONG index; |
| ULONG sector; |
| int read; |
| int dirty; |
| BYTE data[MAX_BIG_BLOCK_SIZE]; |
| } BlockChainBlock; |
| |
| struct BlockChainStream |
| { |
| StorageImpl* parentStorage; |
| ULONG* headOfStreamPlaceHolder; |
| DirRef ownerDirEntry; |
| struct BlockChainRun* indexCache; |
| ULONG indexCacheLen; |
| ULONG indexCacheSize; |
| BlockChainBlock cachedBlocks[2]; |
| ULONG blockToEvict; |
| ULONG tailIndex; |
| ULONG numBlocks; |
| }; |
| |
| /* |
| * Methods for the BlockChainStream class. |
| */ |
| BlockChainStream* BlockChainStream_Construct( |
| StorageImpl* parentStorage, |
| ULONG* headOfStreamPlaceHolder, |
| DirRef dirEntry) DECLSPEC_HIDDEN; |
| |
| void BlockChainStream_Destroy( |
| BlockChainStream* This) DECLSPEC_HIDDEN; |
| |
| HRESULT BlockChainStream_ReadAt( |
| BlockChainStream* This, |
| ULARGE_INTEGER offset, |
| ULONG size, |
| void* buffer, |
| ULONG* bytesRead) DECLSPEC_HIDDEN; |
| |
| HRESULT BlockChainStream_WriteAt( |
| BlockChainStream* This, |
| ULARGE_INTEGER offset, |
| ULONG size, |
| const void* buffer, |
| ULONG* bytesWritten) DECLSPEC_HIDDEN; |
| |
| BOOL BlockChainStream_SetSize( |
| BlockChainStream* This, |
| ULARGE_INTEGER newSize) DECLSPEC_HIDDEN; |
| |
| HRESULT BlockChainStream_Flush( |
| BlockChainStream* This) DECLSPEC_HIDDEN; |
| |
| /**************************************************************************** |
| * SmallBlockChainStream definitions. |
| * |
| * The SmallBlockChainStream class is a utility class that is used to create an |
| * abstraction of the small block chains in the storage file. |
| */ |
| struct SmallBlockChainStream |
| { |
| StorageImpl* parentStorage; |
| DirRef ownerDirEntry; |
| ULONG* headOfStreamPlaceHolder; |
| }; |
| |
| /* |
| * Methods of the SmallBlockChainStream class. |
| */ |
| SmallBlockChainStream* SmallBlockChainStream_Construct( |
| StorageImpl* parentStorage, |
| ULONG* headOfStreamPlaceHolder, |
| DirRef dirEntry) DECLSPEC_HIDDEN; |
| |
| void SmallBlockChainStream_Destroy( |
| SmallBlockChainStream* This) DECLSPEC_HIDDEN; |
| |
| HRESULT SmallBlockChainStream_ReadAt( |
| SmallBlockChainStream* This, |
| ULARGE_INTEGER offset, |
| ULONG size, |
| void* buffer, |
| ULONG* bytesRead) DECLSPEC_HIDDEN; |
| |
| HRESULT SmallBlockChainStream_WriteAt( |
| SmallBlockChainStream* This, |
| ULARGE_INTEGER offset, |
| ULONG size, |
| const void* buffer, |
| ULONG* bytesWritten) DECLSPEC_HIDDEN; |
| |
| BOOL SmallBlockChainStream_SetSize( |
| SmallBlockChainStream* This, |
| ULARGE_INTEGER newSize) DECLSPEC_HIDDEN; |
| |
| |
| #endif /* __STORAGE32_H__ */ |