dwrite: Cleanup layout instance creation, handle memory allocation failures.
[wine.git] / dlls / ole32 / storage32.h
blob9831a2782b180d7e28b9883370f5ad86794d8acc
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 ULONG OFFSET_PS_SIZE_HIGH = 0x0000007C;
75 static const WORD DEF_BIG_BLOCK_SIZE_BITS = 0x0009;
76 static const WORD MIN_BIG_BLOCK_SIZE_BITS = 0x0009;
77 static const WORD MAX_BIG_BLOCK_SIZE_BITS = 0x000c;
78 static const WORD DEF_SMALL_BLOCK_SIZE_BITS = 0x0006;
79 static const WORD DEF_BIG_BLOCK_SIZE = 0x0200;
80 static const WORD DEF_SMALL_BLOCK_SIZE = 0x0040;
81 static const ULONG BLOCK_FIRST_SPECIAL = 0xFFFFFFFB;
82 static const ULONG BLOCK_EXTBBDEPOT = 0xFFFFFFFC;
83 static const ULONG BLOCK_SPECIAL = 0xFFFFFFFD;
84 static const ULONG BLOCK_END_OF_CHAIN = 0xFFFFFFFE;
85 static const ULONG BLOCK_UNUSED = 0xFFFFFFFF;
86 static const ULONG DIRENTRY_NULL = 0xFFFFFFFF;
88 #define DIRENTRY_NAME_MAX_LEN 0x20
89 #define DIRENTRY_NAME_BUFFER_LEN 0x40
91 #define RAW_DIRENTRY_SIZE 0x00000080
93 #define HEADER_SIZE 512
95 #define MIN_BIG_BLOCK_SIZE 0x200
96 #define MAX_BIG_BLOCK_SIZE 0x1000
99 * Type of child entry link
101 #define DIRENTRY_RELATION_PREVIOUS 0
102 #define DIRENTRY_RELATION_NEXT 1
103 #define DIRENTRY_RELATION_DIR 2
106 * type constant used in files for the root storage
108 #define STGTY_ROOT 0x05
110 #define COUNT_BBDEPOTINHEADER 109
112 /* FIXME: This value is stored in the header, but we hard-code it to 0x1000. */
113 #define LIMIT_TO_USE_SMALL_BLOCK 0x1000
115 #define STGM_ACCESS_MODE(stgm) ((stgm)&0x0000f)
116 #define STGM_SHARE_MODE(stgm) ((stgm)&0x000f0)
117 #define STGM_CREATE_MODE(stgm) ((stgm)&0x0f000)
119 #define STGM_KNOWN_FLAGS (0xf0ff | \
120 STGM_TRANSACTED | STGM_CONVERT | STGM_PRIORITY | STGM_NOSCRATCH | \
121 STGM_NOSNAPSHOT | STGM_DIRECT_SWMR | STGM_DELETEONRELEASE | STGM_SIMPLE)
124 * Forward declarations of all the structures used by the storage
125 * module.
127 typedef struct StorageBaseImpl StorageBaseImpl;
128 typedef struct StorageBaseImplVtbl StorageBaseImplVtbl;
129 typedef struct StorageImpl StorageImpl;
130 typedef struct BlockChainStream BlockChainStream;
131 typedef struct SmallBlockChainStream SmallBlockChainStream;
132 typedef struct IEnumSTATSTGImpl IEnumSTATSTGImpl;
133 typedef struct DirEntry DirEntry;
134 typedef struct StgStreamImpl StgStreamImpl;
137 * A reference to a directory entry in the file or a transacted cache.
139 typedef ULONG DirRef;
142 * This utility structure is used to read/write the information in a directory
143 * entry.
145 struct DirEntry
147 WCHAR name[DIRENTRY_NAME_MAX_LEN];
148 WORD sizeOfNameString;
149 BYTE stgType;
150 DirRef leftChild;
151 DirRef rightChild;
152 DirRef dirRootEntry;
153 GUID clsid;
154 FILETIME ctime;
155 FILETIME mtime;
156 ULONG startingBlock;
157 ULARGE_INTEGER size;
160 HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, LPCWSTR pwcsName, ILockBytes **pLockBytes) DECLSPEC_HIDDEN;
162 HRESULT FileLockBytesImpl_LockRegionSync(ILockBytes* iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb) DECLSPEC_HIDDEN;
164 /*************************************************************************
165 * Ole Convert support
168 HRESULT STORAGE_CreateOleStream(IStorage*, DWORD) DECLSPEC_HIDDEN;
169 HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName) DECLSPEC_HIDDEN;
171 enum swmr_mode
173 SWMR_None,
174 SWMR_Writer,
175 SWMR_Reader
178 /****************************************************************************
179 * StorageBaseImpl definitions.
181 * This structure defines the base information contained in all implementations
182 * of IStorage contained in this file storage implementation.
184 * In OOP terms, this is the base class for all the IStorage implementations
185 * contained in this file.
187 struct StorageBaseImpl
189 IStorage IStorage_iface;
190 IPropertySetStorage IPropertySetStorage_iface; /* interface for adding a properties stream */
191 IDirectWriterLock IDirectWriterLock_iface;
192 LONG ref;
195 * Stream tracking list
198 struct list strmHead;
201 * Storage tracking list
203 struct list storageHead;
206 * TRUE if this object has been invalidated
208 BOOL reverted;
211 * Index of the directory entry of this storage
213 DirRef storageDirEntry;
216 * virtual methods.
218 const StorageBaseImplVtbl *baseVtbl;
221 * flags that this storage was opened or created with
223 DWORD openFlags;
226 * State bits appear to only be preserved while running. No in the stream
228 DWORD stateBits;
230 BOOL create; /* Was the storage created or opened.
231 The behaviour of STGM_SIMPLE depends on this */
233 * If this storage was opened in transacted mode, the object that implements
234 * the transacted snapshot or cache.
236 StorageBaseImpl *transactedChild;
237 enum swmr_mode lockingrole;
240 /* virtual methods for StorageBaseImpl objects */
241 struct StorageBaseImplVtbl {
242 void (*Destroy)(StorageBaseImpl*);
243 void (*Invalidate)(StorageBaseImpl*);
244 HRESULT (*Flush)(StorageBaseImpl*);
245 HRESULT (*GetFilename)(StorageBaseImpl*,LPWSTR*);
246 HRESULT (*CreateDirEntry)(StorageBaseImpl*,const DirEntry*,DirRef*);
247 HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*);
248 HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*);
249 HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef);
250 HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*);
251 HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*);
252 HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER);
253 HRESULT (*StreamLink)(StorageBaseImpl*,DirRef,DirRef);
254 HRESULT (*GetTransactionSig)(StorageBaseImpl*,ULONG*,BOOL);
255 HRESULT (*SetTransactionSig)(StorageBaseImpl*,ULONG);
256 HRESULT (*LockTransaction)(StorageBaseImpl*,BOOL);
257 HRESULT (*UnlockTransaction)(StorageBaseImpl*,BOOL);
260 static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This)
262 This->baseVtbl->Destroy(This);
265 static inline void StorageBaseImpl_Invalidate(StorageBaseImpl *This)
267 This->baseVtbl->Invalidate(This);
270 static inline HRESULT StorageBaseImpl_Flush(StorageBaseImpl *This)
272 return This->baseVtbl->Flush(This);
275 static inline HRESULT StorageBaseImpl_GetFilename(StorageBaseImpl *This, LPWSTR *result)
277 return This->baseVtbl->GetFilename(This, result);
280 static inline HRESULT StorageBaseImpl_CreateDirEntry(StorageBaseImpl *This,
281 const DirEntry *newData, DirRef *index)
283 return This->baseVtbl->CreateDirEntry(This, newData, index);
286 static inline HRESULT StorageBaseImpl_WriteDirEntry(StorageBaseImpl *This,
287 DirRef index, const DirEntry *data)
289 return This->baseVtbl->WriteDirEntry(This, index, data);
292 static inline HRESULT StorageBaseImpl_ReadDirEntry(StorageBaseImpl *This,
293 DirRef index, DirEntry *data)
295 return This->baseVtbl->ReadDirEntry(This, index, data);
298 static inline HRESULT StorageBaseImpl_DestroyDirEntry(StorageBaseImpl *This,
299 DirRef index)
301 return This->baseVtbl->DestroyDirEntry(This, index);
304 /* Read up to size bytes from this directory entry's stream at the given offset. */
305 static inline HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This,
306 DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead)
308 return This->baseVtbl->StreamReadAt(This, index, offset, size, buffer, bytesRead);
311 /* Write size bytes to this directory entry's stream at the given offset,
312 * growing the stream if necessary. */
313 static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This,
314 DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
316 return This->baseVtbl->StreamWriteAt(This, index, offset, size, buffer, bytesWritten);
319 static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This,
320 DirRef index, ULARGE_INTEGER newsize)
322 return This->baseVtbl->StreamSetSize(This, index, newsize);
325 /* Make dst point to the same stream that src points to. Other stream operations
326 * will not work properly for entries that point to the same stream, so this
327 * must be a very temporary state, and only one entry pointing to a given stream
328 * may be reachable at any given time. */
329 static inline HRESULT StorageBaseImpl_StreamLink(StorageBaseImpl *This,
330 DirRef dst, DirRef src)
332 return This->baseVtbl->StreamLink(This, dst, src);
335 static inline HRESULT StorageBaseImpl_GetTransactionSig(StorageBaseImpl *This,
336 ULONG* result, BOOL refresh)
338 return This->baseVtbl->GetTransactionSig(This, result, refresh);
341 static inline HRESULT StorageBaseImpl_SetTransactionSig(StorageBaseImpl *This,
342 ULONG value)
344 return This->baseVtbl->SetTransactionSig(This, value);
347 static inline HRESULT StorageBaseImpl_LockTransaction(StorageBaseImpl *This, BOOL write)
349 return This->baseVtbl->LockTransaction(This, write);
352 static inline HRESULT StorageBaseImpl_UnlockTransaction(StorageBaseImpl *This, BOOL write)
354 return This->baseVtbl->UnlockTransaction(This, write);
357 /****************************************************************************
358 * StorageBaseImpl stream list handlers
361 void StorageBaseImpl_AddStream(StorageBaseImpl * stg, StgStreamImpl * strm) DECLSPEC_HIDDEN;
362 void StorageBaseImpl_RemoveStream(StorageBaseImpl * stg, StgStreamImpl * strm) DECLSPEC_HIDDEN;
364 /* Number of BlockChainStream objects to cache in a StorageImpl */
365 #define BLOCKCHAIN_CACHE_SIZE 4
367 /****************************************************************************
368 * Storage32Impl definitions.
370 * This implementation of the IStorage32 interface represents a root
371 * storage. Basically, a document file.
373 struct StorageImpl
375 struct StorageBaseImpl base;
378 * File header
380 WORD bigBlockSizeBits;
381 WORD smallBlockSizeBits;
382 ULONG bigBlockSize;
383 ULONG smallBlockSize;
384 ULONG bigBlockDepotCount;
385 ULONG rootStartBlock;
386 ULONG smallBlockLimit;
387 ULONG smallBlockDepotStart;
388 ULONG extBigBlockDepotStart;
389 ULONG *extBigBlockDepotLocations;
390 ULONG extBigBlockDepotLocationsSize;
391 ULONG extBigBlockDepotCount;
392 ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER];
393 ULONG transactionSig;
395 ULONG extBlockDepotCached[MAX_BIG_BLOCK_SIZE / 4];
396 ULONG indexExtBlockDepotCached;
398 ULONG blockDepotCached[MAX_BIG_BLOCK_SIZE / 4];
399 ULONG indexBlockDepotCached;
400 ULONG prevFreeBlock;
402 /* All small blocks before this one are known to be in use. */
403 ULONG firstFreeSmallBlock;
406 * Abstraction of the big block chains for the chains of the header.
408 BlockChainStream* rootBlockChain;
409 BlockChainStream* smallBlockDepotChain;
410 BlockChainStream* smallBlockRootChain;
412 /* Cache of block chain streams objects for directory entries */
413 BlockChainStream* blockChainCache[BLOCKCHAIN_CACHE_SIZE];
414 UINT blockChainToEvict;
416 ILockBytes* lockBytes;
418 ULONG locked_bytes[8];
421 HRESULT StorageImpl_ReadRawDirEntry(
422 StorageImpl *This,
423 ULONG index,
424 BYTE *buffer) DECLSPEC_HIDDEN;
426 void UpdateRawDirEntry(
427 BYTE *buffer,
428 const DirEntry *newData) DECLSPEC_HIDDEN;
430 HRESULT StorageImpl_WriteRawDirEntry(
431 StorageImpl *This,
432 ULONG index,
433 const BYTE *buffer) DECLSPEC_HIDDEN;
435 HRESULT StorageImpl_ReadDirEntry(
436 StorageImpl* This,
437 DirRef index,
438 DirEntry* buffer) DECLSPEC_HIDDEN;
440 HRESULT StorageImpl_WriteDirEntry(
441 StorageImpl* This,
442 DirRef index,
443 const DirEntry* buffer) DECLSPEC_HIDDEN;
445 BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
446 StorageImpl* This,
447 SmallBlockChainStream** ppsbChain) DECLSPEC_HIDDEN;
449 SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks(
450 StorageImpl* This,
451 BlockChainStream** ppbbChain,
452 ULARGE_INTEGER newSize) DECLSPEC_HIDDEN;
454 /****************************************************************************
455 * StgStreamImpl definitions.
457 * This class implements the IStream interface and represents a stream
458 * located inside a storage object.
460 struct StgStreamImpl
462 IStream IStream_iface;
463 LONG ref;
466 * We are an entry in the storage object's stream handler list
468 struct list StrmListEntry;
471 * Storage that is the parent(owner) of the stream
473 StorageBaseImpl* parentStorage;
476 * Access mode of this stream.
478 DWORD grfMode;
481 * Index of the directory entry that owns (points to) this stream.
483 DirRef dirEntry;
486 * This is the current position of the cursor in the stream
488 ULARGE_INTEGER currentPosition;
491 static inline StgStreamImpl *impl_from_IStream( IStream *iface )
493 return CONTAINING_RECORD(iface, StgStreamImpl, IStream_iface);
497 * Method definition for the StgStreamImpl class.
499 StgStreamImpl* StgStreamImpl_Construct(
500 StorageBaseImpl* parentStorage,
501 DWORD grfMode,
502 DirRef dirEntry) DECLSPEC_HIDDEN;
505 /* Range lock constants.
507 * The storage format reserves the region from 0x7fffff00-0x7fffffff for
508 * locking and synchronization. Unfortunately, the spec doesn't say which bytes
509 * within that range are used, and for what. These are guesses based on testing.
510 * In particular, ends of ranges may be wrong.
512 0x0 through 0x57: Unknown. Causes read-only exclusive opens to fail.
513 0x58 through 0x6b: Priority mode.
514 0x6c through 0x7f: No snapshot mode.
515 0x80: Commit lock.
516 0x81 through 0x91: Priority mode, again. Not sure why it uses two regions.
517 0x92: Lock-checking lock. Held while opening so ranges can be tested without
518 causing spurious failures if others try to grab or test those ranges at the
519 same time.
520 0x93 through 0xa6: Read mode.
521 0xa7 through 0xba: Write mode.
522 0xbb through 0xce: Deny read.
523 0xcf through 0xe2: Deny write.
524 0xe2 through 0xff: Unknown. Causes read-only exclusive opens to fail.
527 #define RANGELOCK_UNK1_FIRST 0x7fffff00
528 #define RANGELOCK_UNK1_LAST 0x7fffff57
529 #define RANGELOCK_PRIORITY1_FIRST 0x7fffff58
530 #define RANGELOCK_PRIORITY1_LAST 0x7fffff6b
531 #define RANGELOCK_NOSNAPSHOT_FIRST 0x7fffff6c
532 #define RANGELOCK_NOSNAPSHOT_LAST 0x7fffff7f
533 #define RANGELOCK_COMMIT 0x7fffff80
534 #define RANGELOCK_PRIORITY2_FIRST 0x7fffff81
535 #define RANGELOCK_PRIORITY2_LAST 0x7fffff91
536 #define RANGELOCK_CHECKLOCKS 0x7fffff92
537 #define RANGELOCK_READ_FIRST 0x7fffff93
538 #define RANGELOCK_READ_LAST 0x7fffffa6
539 #define RANGELOCK_WRITE_FIRST 0x7fffffa7
540 #define RANGELOCK_WRITE_LAST 0x7fffffba
541 #define RANGELOCK_DENY_READ_FIRST 0x7fffffbb
542 #define RANGELOCK_DENY_READ_LAST 0x7fffffce
543 #define RANGELOCK_DENY_WRITE_FIRST 0x7fffffcf
544 #define RANGELOCK_DENY_WRITE_LAST 0x7fffffe2
545 #define RANGELOCK_UNK2_FIRST 0x7fffffe3
546 #define RANGELOCK_UNK2_LAST 0x7fffffff
547 #define RANGELOCK_TRANSACTION_FIRST RANGELOCK_COMMIT
548 #define RANGELOCK_TRANSACTION_LAST RANGELOCK_CHECKLOCKS
549 #define RANGELOCK_FIRST RANGELOCK_UNK1_FIRST
550 #define RANGELOCK_LAST RANGELOCK_UNK2_LAST
553 /******************************************************************************
554 * Endian conversion macros
556 #ifdef WORDS_BIGENDIAN
558 #define htole32(x) RtlUlongByteSwap(x)
559 #define htole16(x) RtlUshortByteSwap(x)
560 #define lendian32toh(x) RtlUlongByteSwap(x)
561 #define lendian16toh(x) RtlUshortByteSwap(x)
563 #else
565 #define htole32(x) (x)
566 #define htole16(x) (x)
567 #define lendian32toh(x) (x)
568 #define lendian16toh(x) (x)
570 #endif
572 /******************************************************************************
573 * The StorageUtl_ functions are miscellaneous utility functions. Most of which
574 * are abstractions used to read values from file buffers without having to
575 * worry about bit order
577 void StorageUtl_ReadWord(const BYTE* buffer, ULONG offset, WORD* value) DECLSPEC_HIDDEN;
578 void StorageUtl_WriteWord(BYTE* buffer, ULONG offset, WORD value) DECLSPEC_HIDDEN;
579 void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value) DECLSPEC_HIDDEN;
580 void StorageUtl_WriteDWord(BYTE* buffer, ULONG offset, DWORD value) DECLSPEC_HIDDEN;
581 void StorageUtl_ReadULargeInteger(const BYTE* buffer, ULONG offset,
582 ULARGE_INTEGER* value) DECLSPEC_HIDDEN;
583 void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
584 const ULARGE_INTEGER *value) DECLSPEC_HIDDEN;
585 void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value) DECLSPEC_HIDDEN;
586 void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value) DECLSPEC_HIDDEN;
587 void StorageUtl_CopyDirEntryToSTATSTG(StorageBaseImpl *storage,STATSTG* destination,
588 const DirEntry* source, int statFlags) DECLSPEC_HIDDEN;
590 /****************************************************************************
591 * BlockChainStream definitions.
593 * The BlockChainStream class is a utility class that is used to create an
594 * abstraction of the big block chains in the storage file.
596 struct BlockChainRun
598 /* This represents a range of blocks that happen reside in consecutive sectors. */
599 ULONG firstSector;
600 ULONG firstOffset;
601 ULONG lastOffset;
604 typedef struct BlockChainBlock
606 ULONG index;
607 ULONG sector;
608 BOOL read;
609 BOOL dirty;
610 BYTE data[MAX_BIG_BLOCK_SIZE];
611 } BlockChainBlock;
613 struct BlockChainStream
615 StorageImpl* parentStorage;
616 ULONG* headOfStreamPlaceHolder;
617 DirRef ownerDirEntry;
618 struct BlockChainRun* indexCache;
619 ULONG indexCacheLen;
620 ULONG indexCacheSize;
621 BlockChainBlock cachedBlocks[2];
622 ULONG blockToEvict;
623 ULONG tailIndex;
624 ULONG numBlocks;
628 * Methods for the BlockChainStream class.
630 BlockChainStream* BlockChainStream_Construct(
631 StorageImpl* parentStorage,
632 ULONG* headOfStreamPlaceHolder,
633 DirRef dirEntry) DECLSPEC_HIDDEN;
635 void BlockChainStream_Destroy(
636 BlockChainStream* This) DECLSPEC_HIDDEN;
638 HRESULT BlockChainStream_ReadAt(
639 BlockChainStream* This,
640 ULARGE_INTEGER offset,
641 ULONG size,
642 void* buffer,
643 ULONG* bytesRead) DECLSPEC_HIDDEN;
645 HRESULT BlockChainStream_WriteAt(
646 BlockChainStream* This,
647 ULARGE_INTEGER offset,
648 ULONG size,
649 const void* buffer,
650 ULONG* bytesWritten) DECLSPEC_HIDDEN;
652 BOOL BlockChainStream_SetSize(
653 BlockChainStream* This,
654 ULARGE_INTEGER newSize) DECLSPEC_HIDDEN;
656 HRESULT BlockChainStream_Flush(
657 BlockChainStream* This) DECLSPEC_HIDDEN;
659 /****************************************************************************
660 * SmallBlockChainStream definitions.
662 * The SmallBlockChainStream class is a utility class that is used to create an
663 * abstraction of the small block chains in the storage file.
665 struct SmallBlockChainStream
667 StorageImpl* parentStorage;
668 DirRef ownerDirEntry;
669 ULONG* headOfStreamPlaceHolder;
673 * Methods of the SmallBlockChainStream class.
675 SmallBlockChainStream* SmallBlockChainStream_Construct(
676 StorageImpl* parentStorage,
677 ULONG* headOfStreamPlaceHolder,
678 DirRef dirEntry) DECLSPEC_HIDDEN;
680 void SmallBlockChainStream_Destroy(
681 SmallBlockChainStream* This) DECLSPEC_HIDDEN;
683 HRESULT SmallBlockChainStream_ReadAt(
684 SmallBlockChainStream* This,
685 ULARGE_INTEGER offset,
686 ULONG size,
687 void* buffer,
688 ULONG* bytesRead) DECLSPEC_HIDDEN;
690 HRESULT SmallBlockChainStream_WriteAt(
691 SmallBlockChainStream* This,
692 ULARGE_INTEGER offset,
693 ULONG size,
694 const void* buffer,
695 ULONG* bytesWritten) DECLSPEC_HIDDEN;
697 BOOL SmallBlockChainStream_SetSize(
698 SmallBlockChainStream* This,
699 ULARGE_INTEGER newSize) DECLSPEC_HIDDEN;
702 #endif /* __STORAGE32_H__ */