ole32: Use a snapshot file when sharing storages for writing.
[wine/multimedia.git] / dlls / ole32 / storage32.h
blobcc5b9707c10521eb667830d058562abec04dd555
1 /*
2 * Compound Storage (32 bit version)
4 * Implemented using the documentation of the LAOLA project at
5 * <URL:http://wwwwbs.cs.tu-berlin.de/~schwartz/pmh/index.html>
6 * (Thanks to Martin Schwartz <schwartz@cs.tu-berlin.de>)
8 * This include file contains definitions of types and function
9 * prototypes that are used in the many files implementing the
10 * storage functionality
12 * Copyright 1998,1999 Francis Beaudet
13 * Copyright 1998,1999 Thuy Nguyen
14 * Copyright 2010 Vincent Povirk for CodeWeavers
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #ifndef __STORAGE32_H__
31 #define __STORAGE32_H__
33 #include <stdarg.h>
35 #include "windef.h"
36 #include "winbase.h"
37 #include "winnt.h"
38 #include "objbase.h"
39 #include "winreg.h"
40 #include "winternl.h"
41 #include "wine/list.h"
44 * Definitions for the file format offsets.
46 static const ULONG OFFSET_MINORVERSION = 0x00000018;
47 static const ULONG OFFSET_MAJORVERSION = 0x0000001a;
48 static const ULONG OFFSET_BYTEORDERMARKER = 0x0000001c;
49 static const ULONG OFFSET_BIGBLOCKSIZEBITS = 0x0000001e;
50 static const ULONG OFFSET_SMALLBLOCKSIZEBITS = 0x00000020;
51 static const ULONG OFFSET_DIRSECTORCOUNT = 0x00000028;
52 static const ULONG OFFSET_BBDEPOTCOUNT = 0x0000002C;
53 static const ULONG OFFSET_ROOTSTARTBLOCK = 0x00000030;
54 static const ULONG OFFSET_TRANSACTIONSIG = 0x00000034;
55 static const ULONG OFFSET_SMALLBLOCKLIMIT = 0x00000038;
56 static const ULONG OFFSET_SBDEPOTSTART = 0x0000003C;
57 static const ULONG OFFSET_SBDEPOTCOUNT = 0x00000040;
58 static const ULONG OFFSET_EXTBBDEPOTSTART = 0x00000044;
59 static const ULONG OFFSET_EXTBBDEPOTCOUNT = 0x00000048;
60 static const ULONG OFFSET_BBDEPOTSTART = 0x0000004C;
61 static const ULONG OFFSET_PS_NAME = 0x00000000;
62 static const ULONG OFFSET_PS_NAMELENGTH = 0x00000040;
63 static const ULONG OFFSET_PS_STGTYPE = 0x00000042;
64 static const ULONG OFFSET_PS_LEFTCHILD = 0x00000044;
65 static const ULONG OFFSET_PS_RIGHTCHILD = 0x00000048;
66 static const ULONG OFFSET_PS_DIRROOT = 0x0000004C;
67 static const ULONG OFFSET_PS_GUID = 0x00000050;
68 static const ULONG OFFSET_PS_CTIMELOW = 0x00000064;
69 static const ULONG OFFSET_PS_CTIMEHIGH = 0x00000068;
70 static const ULONG OFFSET_PS_MTIMELOW = 0x0000006C;
71 static const ULONG OFFSET_PS_MTIMEHIGH = 0x00000070;
72 static const ULONG OFFSET_PS_STARTBLOCK = 0x00000074;
73 static const ULONG OFFSET_PS_SIZE = 0x00000078;
74 static const WORD DEF_BIG_BLOCK_SIZE_BITS = 0x0009;
75 static const WORD MIN_BIG_BLOCK_SIZE_BITS = 0x0009;
76 static const WORD MAX_BIG_BLOCK_SIZE_BITS = 0x000c;
77 static const WORD DEF_SMALL_BLOCK_SIZE_BITS = 0x0006;
78 static const WORD DEF_BIG_BLOCK_SIZE = 0x0200;
79 static const WORD DEF_SMALL_BLOCK_SIZE = 0x0040;
80 static const ULONG BLOCK_EXTBBDEPOT = 0xFFFFFFFC;
81 static const ULONG BLOCK_SPECIAL = 0xFFFFFFFD;
82 static const ULONG BLOCK_END_OF_CHAIN = 0xFFFFFFFE;
83 static const ULONG BLOCK_UNUSED = 0xFFFFFFFF;
84 static const ULONG DIRENTRY_NULL = 0xFFFFFFFF;
86 #define DIRENTRY_NAME_MAX_LEN 0x20
87 #define DIRENTRY_NAME_BUFFER_LEN 0x40
89 #define RAW_DIRENTRY_SIZE 0x00000080
91 #define HEADER_SIZE 512
93 #define MIN_BIG_BLOCK_SIZE 0x200
94 #define MAX_BIG_BLOCK_SIZE 0x1000
97 * Type of child entry link
99 #define DIRENTRY_RELATION_PREVIOUS 0
100 #define DIRENTRY_RELATION_NEXT 1
101 #define DIRENTRY_RELATION_DIR 2
104 * type constant used in files for the root storage
106 #define STGTY_ROOT 0x05
108 #define COUNT_BBDEPOTINHEADER 109
110 /* FIXME: This value is stored in the header, but we hard-code it to 0x1000. */
111 #define LIMIT_TO_USE_SMALL_BLOCK 0x1000
113 #define STGM_ACCESS_MODE(stgm) ((stgm)&0x0000f)
114 #define STGM_SHARE_MODE(stgm) ((stgm)&0x000f0)
115 #define STGM_CREATE_MODE(stgm) ((stgm)&0x0f000)
117 #define STGM_KNOWN_FLAGS (0xf0ff | \
118 STGM_TRANSACTED | STGM_CONVERT | STGM_PRIORITY | STGM_NOSCRATCH | \
119 STGM_NOSNAPSHOT | STGM_DIRECT_SWMR | STGM_DELETEONRELEASE | STGM_SIMPLE)
122 * Forward declarations of all the structures used by the storage
123 * module.
125 typedef struct StorageBaseImpl StorageBaseImpl;
126 typedef struct StorageBaseImplVtbl StorageBaseImplVtbl;
127 typedef struct StorageImpl StorageImpl;
128 typedef struct BlockChainStream BlockChainStream;
129 typedef struct SmallBlockChainStream SmallBlockChainStream;
130 typedef struct IEnumSTATSTGImpl IEnumSTATSTGImpl;
131 typedef struct DirEntry DirEntry;
132 typedef struct StgStreamImpl StgStreamImpl;
135 * A reference to a directory entry in the file or a transacted cache.
137 typedef ULONG DirRef;
140 * This utility structure is used to read/write the information in a directory
141 * entry.
143 struct DirEntry
145 WCHAR name[DIRENTRY_NAME_MAX_LEN];
146 WORD sizeOfNameString;
147 BYTE stgType;
148 DirRef leftChild;
149 DirRef rightChild;
150 DirRef dirRootEntry;
151 GUID clsid;
152 FILETIME ctime;
153 FILETIME mtime;
154 ULONG startingBlock;
155 ULARGE_INTEGER size;
158 HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, LPCWSTR pwcsName, ILockBytes **pLockBytes) DECLSPEC_HIDDEN;
160 HRESULT FileLockBytesImpl_LockRegionSync(ILockBytes* iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb) DECLSPEC_HIDDEN;
162 /*************************************************************************
163 * Ole Convert support
166 HRESULT STORAGE_CreateOleStream(IStorage*, DWORD) DECLSPEC_HIDDEN;
167 HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName) DECLSPEC_HIDDEN;
169 enum swmr_mode
171 SWMR_None,
172 SWMR_Writer,
173 SWMR_Reader
176 /****************************************************************************
177 * StorageBaseImpl definitions.
179 * This structure defines the base information contained in all implementations
180 * of IStorage contained in this file storage implementation.
182 * In OOP terms, this is the base class for all the IStorage implementations
183 * contained in this file.
185 struct StorageBaseImpl
187 IStorage IStorage_iface;
188 IPropertySetStorage IPropertySetStorage_iface; /* interface for adding a properties stream */
189 IDirectWriterLock IDirectWriterLock_iface;
190 LONG ref;
193 * Stream tracking list
196 struct list strmHead;
199 * Storage tracking list
201 struct list storageHead;
204 * TRUE if this object has been invalidated
206 BOOL reverted;
209 * Index of the directory entry of this storage
211 DirRef storageDirEntry;
214 * virtual methods.
216 const StorageBaseImplVtbl *baseVtbl;
219 * flags that this storage was opened or created with
221 DWORD openFlags;
224 * State bits appear to only be preserved while running. No in the stream
226 DWORD stateBits;
228 BOOL create; /* Was the storage created or opened.
229 The behaviour of STGM_SIMPLE depends on this */
231 * If this storage was opened in transacted mode, the object that implements
232 * the transacted snapshot or cache.
234 StorageBaseImpl *transactedChild;
235 enum swmr_mode lockingrole;
238 /* virtual methods for StorageBaseImpl objects */
239 struct StorageBaseImplVtbl {
240 void (*Destroy)(StorageBaseImpl*);
241 void (*Invalidate)(StorageBaseImpl*);
242 HRESULT (*Flush)(StorageBaseImpl*);
243 HRESULT (*GetFilename)(StorageBaseImpl*,LPWSTR*);
244 HRESULT (*CreateDirEntry)(StorageBaseImpl*,const DirEntry*,DirRef*);
245 HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*);
246 HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*);
247 HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef);
248 HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*);
249 HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*);
250 HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER);
251 HRESULT (*StreamLink)(StorageBaseImpl*,DirRef,DirRef);
252 HRESULT (*GetTransactionSig)(StorageBaseImpl*,ULONG*,BOOL);
253 HRESULT (*SetTransactionSig)(StorageBaseImpl*,ULONG);
254 HRESULT (*LockTransaction)(StorageBaseImpl*,BOOL);
255 HRESULT (*UnlockTransaction)(StorageBaseImpl*,BOOL);
258 static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This)
260 This->baseVtbl->Destroy(This);
263 static inline void StorageBaseImpl_Invalidate(StorageBaseImpl *This)
265 This->baseVtbl->Invalidate(This);
268 static inline HRESULT StorageBaseImpl_Flush(StorageBaseImpl *This)
270 return This->baseVtbl->Flush(This);
273 static inline HRESULT StorageBaseImpl_GetFilename(StorageBaseImpl *This, LPWSTR *result)
275 return This->baseVtbl->GetFilename(This, result);
278 static inline HRESULT StorageBaseImpl_CreateDirEntry(StorageBaseImpl *This,
279 const DirEntry *newData, DirRef *index)
281 return This->baseVtbl->CreateDirEntry(This, newData, index);
284 static inline HRESULT StorageBaseImpl_WriteDirEntry(StorageBaseImpl *This,
285 DirRef index, const DirEntry *data)
287 return This->baseVtbl->WriteDirEntry(This, index, data);
290 static inline HRESULT StorageBaseImpl_ReadDirEntry(StorageBaseImpl *This,
291 DirRef index, DirEntry *data)
293 return This->baseVtbl->ReadDirEntry(This, index, data);
296 static inline HRESULT StorageBaseImpl_DestroyDirEntry(StorageBaseImpl *This,
297 DirRef index)
299 return This->baseVtbl->DestroyDirEntry(This, index);
302 /* Read up to size bytes from this directory entry's stream at the given offset. */
303 static inline HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This,
304 DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead)
306 return This->baseVtbl->StreamReadAt(This, index, offset, size, buffer, bytesRead);
309 /* Write size bytes to this directory entry's stream at the given offset,
310 * growing the stream if necessary. */
311 static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This,
312 DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
314 return This->baseVtbl->StreamWriteAt(This, index, offset, size, buffer, bytesWritten);
317 static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This,
318 DirRef index, ULARGE_INTEGER newsize)
320 return This->baseVtbl->StreamSetSize(This, index, newsize);
323 /* Make dst point to the same stream that src points to. Other stream operations
324 * will not work properly for entries that point to the same stream, so this
325 * must be a very temporary state, and only one entry pointing to a given stream
326 * may be reachable at any given time. */
327 static inline HRESULT StorageBaseImpl_StreamLink(StorageBaseImpl *This,
328 DirRef dst, DirRef src)
330 return This->baseVtbl->StreamLink(This, dst, src);
333 static inline HRESULT StorageBaseImpl_GetTransactionSig(StorageBaseImpl *This,
334 ULONG* result, BOOL refresh)
336 return This->baseVtbl->GetTransactionSig(This, result, refresh);
339 static inline HRESULT StorageBaseImpl_SetTransactionSig(StorageBaseImpl *This,
340 ULONG value)
342 return This->baseVtbl->SetTransactionSig(This, value);
345 static inline HRESULT StorageBaseImpl_LockTransaction(StorageBaseImpl *This, BOOL write)
347 return This->baseVtbl->LockTransaction(This, write);
350 static inline HRESULT StorageBaseImpl_UnlockTransaction(StorageBaseImpl *This, BOOL write)
352 return This->baseVtbl->UnlockTransaction(This, write);
355 /****************************************************************************
356 * StorageBaseImpl stream list handlers
359 void StorageBaseImpl_AddStream(StorageBaseImpl * stg, StgStreamImpl * strm) DECLSPEC_HIDDEN;
360 void StorageBaseImpl_RemoveStream(StorageBaseImpl * stg, StgStreamImpl * strm) DECLSPEC_HIDDEN;
362 /* Number of BlockChainStream objects to cache in a StorageImpl */
363 #define BLOCKCHAIN_CACHE_SIZE 4
365 /****************************************************************************
366 * Storage32Impl definitions.
368 * This implementation of the IStorage32 interface represents a root
369 * storage. Basically, a document file.
371 struct StorageImpl
373 struct StorageBaseImpl base;
376 * File header
378 WORD bigBlockSizeBits;
379 WORD smallBlockSizeBits;
380 ULONG bigBlockSize;
381 ULONG smallBlockSize;
382 ULONG bigBlockDepotCount;
383 ULONG rootStartBlock;
384 ULONG smallBlockLimit;
385 ULONG smallBlockDepotStart;
386 ULONG extBigBlockDepotStart;
387 ULONG *extBigBlockDepotLocations;
388 ULONG extBigBlockDepotLocationsSize;
389 ULONG extBigBlockDepotCount;
390 ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER];
391 ULONG transactionSig;
393 ULONG extBlockDepotCached[MAX_BIG_BLOCK_SIZE / 4];
394 ULONG indexExtBlockDepotCached;
396 ULONG blockDepotCached[MAX_BIG_BLOCK_SIZE / 4];
397 ULONG indexBlockDepotCached;
398 ULONG prevFreeBlock;
400 /* All small blocks before this one are known to be in use. */
401 ULONG firstFreeSmallBlock;
404 * Abstraction of the big block chains for the chains of the header.
406 BlockChainStream* rootBlockChain;
407 BlockChainStream* smallBlockDepotChain;
408 BlockChainStream* smallBlockRootChain;
410 /* Cache of block chain streams objects for directory entries */
411 BlockChainStream* blockChainCache[BLOCKCHAIN_CACHE_SIZE];
412 UINT blockChainToEvict;
414 ILockBytes* lockBytes;
416 ULONG locked_bytes[8];
419 HRESULT StorageImpl_ReadRawDirEntry(
420 StorageImpl *This,
421 ULONG index,
422 BYTE *buffer) DECLSPEC_HIDDEN;
424 void UpdateRawDirEntry(
425 BYTE *buffer,
426 const DirEntry *newData) DECLSPEC_HIDDEN;
428 HRESULT StorageImpl_WriteRawDirEntry(
429 StorageImpl *This,
430 ULONG index,
431 const BYTE *buffer) DECLSPEC_HIDDEN;
433 HRESULT StorageImpl_ReadDirEntry(
434 StorageImpl* This,
435 DirRef index,
436 DirEntry* buffer) DECLSPEC_HIDDEN;
438 HRESULT StorageImpl_WriteDirEntry(
439 StorageImpl* This,
440 DirRef index,
441 const DirEntry* buffer) DECLSPEC_HIDDEN;
443 BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
444 StorageImpl* This,
445 SmallBlockChainStream** ppsbChain) DECLSPEC_HIDDEN;
447 SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks(
448 StorageImpl* This,
449 BlockChainStream** ppbbChain,
450 ULARGE_INTEGER newSize) DECLSPEC_HIDDEN;
452 /****************************************************************************
453 * StgStreamImpl definitions.
455 * This class implements the IStream interface and represents a stream
456 * located inside a storage object.
458 struct StgStreamImpl
460 IStream IStream_iface;
461 LONG ref;
464 * We are an entry in the storage object's stream handler list
466 struct list StrmListEntry;
469 * Storage that is the parent(owner) of the stream
471 StorageBaseImpl* parentStorage;
474 * Access mode of this stream.
476 DWORD grfMode;
479 * Index of the directory entry that owns (points to) this stream.
481 DirRef dirEntry;
484 * This is the current position of the cursor in the stream
486 ULARGE_INTEGER currentPosition;
489 static inline StgStreamImpl *impl_from_IStream( IStream *iface )
491 return CONTAINING_RECORD(iface, StgStreamImpl, IStream_iface);
495 * Method definition for the StgStreamImpl class.
497 StgStreamImpl* StgStreamImpl_Construct(
498 StorageBaseImpl* parentStorage,
499 DWORD grfMode,
500 DirRef dirEntry) DECLSPEC_HIDDEN;
503 /* Range lock constants.
505 * The storage format reserves the region from 0x7fffff00-0x7fffffff for
506 * locking and synchronization. Unfortuantely, the spec doesn't say which bytes
507 * within that range are used, and for what. These are guesses based on testing.
508 * In particular, ends of ranges may be wrong.
510 0x0 through 0x57: Unknown. Causes read-only exclusive opens to fail.
511 0x58 through 0x6b: Priority mode.
512 0x6c through 0x7f: No snapshot mode.
513 0x80: Commit lock.
514 0x81 through 0x91: Priority mode, again. Not sure why it uses two regions.
515 0x92: Lock-checking lock. Held while opening so ranges can be tested without
516 causing spurious failures if others try to grab or test those ranges at the
517 same time.
518 0x93 through 0xa6: Read mode.
519 0xa7 through 0xba: Write mode.
520 0xbb through 0xce: Deny read.
521 0xcf through 0xe2: Deny write.
522 0xe2 through 0xff: Unknown. Causes read-only exclusive opens to fail.
525 #define RANGELOCK_UNK1_FIRST 0x7fffff00
526 #define RANGELOCK_UNK1_LAST 0x7fffff57
527 #define RANGELOCK_PRIORITY1_FIRST 0x7fffff58
528 #define RANGELOCK_PRIORITY1_LAST 0x7fffff6b
529 #define RANGELOCK_NOSNAPSHOT_FIRST 0x7fffff6c
530 #define RANGELOCK_NOSNAPSHOT_LAST 0x7fffff7f
531 #define RANGELOCK_COMMIT 0x7fffff80
532 #define RANGELOCK_PRIORITY2_FIRST 0x7fffff81
533 #define RANGELOCK_PRIORITY2_LAST 0x7fffff91
534 #define RANGELOCK_CHECKLOCKS 0x7fffff92
535 #define RANGELOCK_READ_FIRST 0x7fffff93
536 #define RANGELOCK_READ_LAST 0x7fffffa6
537 #define RANGELOCK_WRITE_FIRST 0x7fffffa7
538 #define RANGELOCK_WRITE_LAST 0x7fffffba
539 #define RANGELOCK_DENY_READ_FIRST 0x7fffffbb
540 #define RANGELOCK_DENY_READ_LAST 0x7fffffce
541 #define RANGELOCK_DENY_WRITE_FIRST 0x7fffffcf
542 #define RANGELOCK_DENY_WRITE_LAST 0x7fffffe2
543 #define RANGELOCK_UNK2_FIRST 0x7fffffe3
544 #define RANGELOCK_UNK2_LAST 0x7fffffff
545 #define RANGELOCK_TRANSACTION_FIRST RANGELOCK_COMMIT
546 #define RANGELOCK_TRANSACTION_LAST RANGELOCK_CHECKLOCKS
547 #define RANGELOCK_FIRST RANGELOCK_UNK1_FIRST
548 #define RANGELOCK_LAST RANGELOCK_UNK2_LAST
551 /******************************************************************************
552 * Endian conversion macros
554 #ifdef WORDS_BIGENDIAN
556 #define htole32(x) RtlUlongByteSwap(x)
557 #define htole16(x) RtlUshortByteSwap(x)
558 #define lendian32toh(x) RtlUlongByteSwap(x)
559 #define lendian16toh(x) RtlUshortByteSwap(x)
561 #else
563 #define htole32(x) (x)
564 #define htole16(x) (x)
565 #define lendian32toh(x) (x)
566 #define lendian16toh(x) (x)
568 #endif
570 /******************************************************************************
571 * The StorageUtl_ functions are miscellaneous utility functions. Most of which
572 * are abstractions used to read values from file buffers without having to
573 * worry about bit order
575 void StorageUtl_ReadWord(const BYTE* buffer, ULONG offset, WORD* value) DECLSPEC_HIDDEN;
576 void StorageUtl_WriteWord(BYTE* buffer, ULONG offset, WORD value) DECLSPEC_HIDDEN;
577 void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value) DECLSPEC_HIDDEN;
578 void StorageUtl_WriteDWord(BYTE* buffer, ULONG offset, DWORD value) DECLSPEC_HIDDEN;
579 void StorageUtl_ReadULargeInteger(const BYTE* buffer, ULONG offset,
580 ULARGE_INTEGER* value) DECLSPEC_HIDDEN;
581 void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
582 const ULARGE_INTEGER *value) DECLSPEC_HIDDEN;
583 void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value) DECLSPEC_HIDDEN;
584 void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value) DECLSPEC_HIDDEN;
585 void StorageUtl_CopyDirEntryToSTATSTG(StorageBaseImpl *storage,STATSTG* destination,
586 const DirEntry* source, int statFlags) DECLSPEC_HIDDEN;
588 /****************************************************************************
589 * BlockChainStream definitions.
591 * The BlockChainStream class is a utility class that is used to create an
592 * abstraction of the big block chains in the storage file.
594 struct BlockChainRun
596 /* This represents a range of blocks that happen reside in consecutive sectors. */
597 ULONG firstSector;
598 ULONG firstOffset;
599 ULONG lastOffset;
602 typedef struct BlockChainBlock
604 ULONG index;
605 ULONG sector;
606 BOOL read;
607 BOOL dirty;
608 BYTE data[MAX_BIG_BLOCK_SIZE];
609 } BlockChainBlock;
611 struct BlockChainStream
613 StorageImpl* parentStorage;
614 ULONG* headOfStreamPlaceHolder;
615 DirRef ownerDirEntry;
616 struct BlockChainRun* indexCache;
617 ULONG indexCacheLen;
618 ULONG indexCacheSize;
619 BlockChainBlock cachedBlocks[2];
620 ULONG blockToEvict;
621 ULONG tailIndex;
622 ULONG numBlocks;
626 * Methods for the BlockChainStream class.
628 BlockChainStream* BlockChainStream_Construct(
629 StorageImpl* parentStorage,
630 ULONG* headOfStreamPlaceHolder,
631 DirRef dirEntry) DECLSPEC_HIDDEN;
633 void BlockChainStream_Destroy(
634 BlockChainStream* This) DECLSPEC_HIDDEN;
636 HRESULT BlockChainStream_ReadAt(
637 BlockChainStream* This,
638 ULARGE_INTEGER offset,
639 ULONG size,
640 void* buffer,
641 ULONG* bytesRead) DECLSPEC_HIDDEN;
643 HRESULT BlockChainStream_WriteAt(
644 BlockChainStream* This,
645 ULARGE_INTEGER offset,
646 ULONG size,
647 const void* buffer,
648 ULONG* bytesWritten) DECLSPEC_HIDDEN;
650 BOOL BlockChainStream_SetSize(
651 BlockChainStream* This,
652 ULARGE_INTEGER newSize) DECLSPEC_HIDDEN;
654 HRESULT BlockChainStream_Flush(
655 BlockChainStream* This) DECLSPEC_HIDDEN;
657 /****************************************************************************
658 * SmallBlockChainStream definitions.
660 * The SmallBlockChainStream class is a utility class that is used to create an
661 * abstraction of the small block chains in the storage file.
663 struct SmallBlockChainStream
665 StorageImpl* parentStorage;
666 DirRef ownerDirEntry;
667 ULONG* headOfStreamPlaceHolder;
671 * Methods of the SmallBlockChainStream class.
673 SmallBlockChainStream* SmallBlockChainStream_Construct(
674 StorageImpl* parentStorage,
675 ULONG* headOfStreamPlaceHolder,
676 DirRef dirEntry) DECLSPEC_HIDDEN;
678 void SmallBlockChainStream_Destroy(
679 SmallBlockChainStream* This) DECLSPEC_HIDDEN;
681 HRESULT SmallBlockChainStream_ReadAt(
682 SmallBlockChainStream* This,
683 ULARGE_INTEGER offset,
684 ULONG size,
685 void* buffer,
686 ULONG* bytesRead) DECLSPEC_HIDDEN;
688 HRESULT SmallBlockChainStream_WriteAt(
689 SmallBlockChainStream* This,
690 ULARGE_INTEGER offset,
691 ULONG size,
692 const void* buffer,
693 ULONG* bytesWritten) DECLSPEC_HIDDEN;
695 BOOL SmallBlockChainStream_SetSize(
696 SmallBlockChainStream* This,
697 ULARGE_INTEGER newSize) DECLSPEC_HIDDEN;
700 #endif /* __STORAGE32_H__ */