Release 1.7.27.
[wine.git] / dlls / ole32 / storage32.h
blob36cbc9d5239b759c386df96ab822ed9a14f89148
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_EXTBBDEPOT = 0xFFFFFFFC;
82 static const ULONG BLOCK_SPECIAL = 0xFFFFFFFD;
83 static const ULONG BLOCK_END_OF_CHAIN = 0xFFFFFFFE;
84 static const ULONG BLOCK_UNUSED = 0xFFFFFFFF;
85 static const ULONG DIRENTRY_NULL = 0xFFFFFFFF;
87 #define DIRENTRY_NAME_MAX_LEN 0x20
88 #define DIRENTRY_NAME_BUFFER_LEN 0x40
90 #define RAW_DIRENTRY_SIZE 0x00000080
92 #define HEADER_SIZE 512
94 #define MIN_BIG_BLOCK_SIZE 0x200
95 #define MAX_BIG_BLOCK_SIZE 0x1000
98 * Type of child entry link
100 #define DIRENTRY_RELATION_PREVIOUS 0
101 #define DIRENTRY_RELATION_NEXT 1
102 #define DIRENTRY_RELATION_DIR 2
105 * type constant used in files for the root storage
107 #define STGTY_ROOT 0x05
109 #define COUNT_BBDEPOTINHEADER 109
111 /* FIXME: This value is stored in the header, but we hard-code it to 0x1000. */
112 #define LIMIT_TO_USE_SMALL_BLOCK 0x1000
114 #define STGM_ACCESS_MODE(stgm) ((stgm)&0x0000f)
115 #define STGM_SHARE_MODE(stgm) ((stgm)&0x000f0)
116 #define STGM_CREATE_MODE(stgm) ((stgm)&0x0f000)
118 #define STGM_KNOWN_FLAGS (0xf0ff | \
119 STGM_TRANSACTED | STGM_CONVERT | STGM_PRIORITY | STGM_NOSCRATCH | \
120 STGM_NOSNAPSHOT | STGM_DIRECT_SWMR | STGM_DELETEONRELEASE | STGM_SIMPLE)
123 * Forward declarations of all the structures used by the storage
124 * module.
126 typedef struct StorageBaseImpl StorageBaseImpl;
127 typedef struct StorageBaseImplVtbl StorageBaseImplVtbl;
128 typedef struct StorageImpl StorageImpl;
129 typedef struct BlockChainStream BlockChainStream;
130 typedef struct SmallBlockChainStream SmallBlockChainStream;
131 typedef struct IEnumSTATSTGImpl IEnumSTATSTGImpl;
132 typedef struct DirEntry DirEntry;
133 typedef struct StgStreamImpl StgStreamImpl;
136 * A reference to a directory entry in the file or a transacted cache.
138 typedef ULONG DirRef;
141 * This utility structure is used to read/write the information in a directory
142 * entry.
144 struct DirEntry
146 WCHAR name[DIRENTRY_NAME_MAX_LEN];
147 WORD sizeOfNameString;
148 BYTE stgType;
149 DirRef leftChild;
150 DirRef rightChild;
151 DirRef dirRootEntry;
152 GUID clsid;
153 FILETIME ctime;
154 FILETIME mtime;
155 ULONG startingBlock;
156 ULARGE_INTEGER size;
159 HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, LPCWSTR pwcsName, ILockBytes **pLockBytes) DECLSPEC_HIDDEN;
161 HRESULT FileLockBytesImpl_LockRegionSync(ILockBytes* iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb) DECLSPEC_HIDDEN;
163 /*************************************************************************
164 * Ole Convert support
167 HRESULT STORAGE_CreateOleStream(IStorage*, DWORD) DECLSPEC_HIDDEN;
168 HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName) DECLSPEC_HIDDEN;
170 enum swmr_mode
172 SWMR_None,
173 SWMR_Writer,
174 SWMR_Reader
177 /****************************************************************************
178 * StorageBaseImpl definitions.
180 * This structure defines the base information contained in all implementations
181 * of IStorage contained in this file storage implementation.
183 * In OOP terms, this is the base class for all the IStorage implementations
184 * contained in this file.
186 struct StorageBaseImpl
188 IStorage IStorage_iface;
189 IPropertySetStorage IPropertySetStorage_iface; /* interface for adding a properties stream */
190 IDirectWriterLock IDirectWriterLock_iface;
191 LONG ref;
194 * Stream tracking list
197 struct list strmHead;
200 * Storage tracking list
202 struct list storageHead;
205 * TRUE if this object has been invalidated
207 BOOL reverted;
210 * Index of the directory entry of this storage
212 DirRef storageDirEntry;
215 * virtual methods.
217 const StorageBaseImplVtbl *baseVtbl;
220 * flags that this storage was opened or created with
222 DWORD openFlags;
225 * State bits appear to only be preserved while running. No in the stream
227 DWORD stateBits;
229 BOOL create; /* Was the storage created or opened.
230 The behaviour of STGM_SIMPLE depends on this */
232 * If this storage was opened in transacted mode, the object that implements
233 * the transacted snapshot or cache.
235 StorageBaseImpl *transactedChild;
236 enum swmr_mode lockingrole;
239 /* virtual methods for StorageBaseImpl objects */
240 struct StorageBaseImplVtbl {
241 void (*Destroy)(StorageBaseImpl*);
242 void (*Invalidate)(StorageBaseImpl*);
243 HRESULT (*Flush)(StorageBaseImpl*);
244 HRESULT (*GetFilename)(StorageBaseImpl*,LPWSTR*);
245 HRESULT (*CreateDirEntry)(StorageBaseImpl*,const DirEntry*,DirRef*);
246 HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*);
247 HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*);
248 HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef);
249 HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*);
250 HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*);
251 HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER);
252 HRESULT (*StreamLink)(StorageBaseImpl*,DirRef,DirRef);
253 HRESULT (*GetTransactionSig)(StorageBaseImpl*,ULONG*,BOOL);
254 HRESULT (*SetTransactionSig)(StorageBaseImpl*,ULONG);
255 HRESULT (*LockTransaction)(StorageBaseImpl*,BOOL);
256 HRESULT (*UnlockTransaction)(StorageBaseImpl*,BOOL);
259 static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This)
261 This->baseVtbl->Destroy(This);
264 static inline void StorageBaseImpl_Invalidate(StorageBaseImpl *This)
266 This->baseVtbl->Invalidate(This);
269 static inline HRESULT StorageBaseImpl_Flush(StorageBaseImpl *This)
271 return This->baseVtbl->Flush(This);
274 static inline HRESULT StorageBaseImpl_GetFilename(StorageBaseImpl *This, LPWSTR *result)
276 return This->baseVtbl->GetFilename(This, result);
279 static inline HRESULT StorageBaseImpl_CreateDirEntry(StorageBaseImpl *This,
280 const DirEntry *newData, DirRef *index)
282 return This->baseVtbl->CreateDirEntry(This, newData, index);
285 static inline HRESULT StorageBaseImpl_WriteDirEntry(StorageBaseImpl *This,
286 DirRef index, const DirEntry *data)
288 return This->baseVtbl->WriteDirEntry(This, index, data);
291 static inline HRESULT StorageBaseImpl_ReadDirEntry(StorageBaseImpl *This,
292 DirRef index, DirEntry *data)
294 return This->baseVtbl->ReadDirEntry(This, index, data);
297 static inline HRESULT StorageBaseImpl_DestroyDirEntry(StorageBaseImpl *This,
298 DirRef index)
300 return This->baseVtbl->DestroyDirEntry(This, index);
303 /* Read up to size bytes from this directory entry's stream at the given offset. */
304 static inline HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This,
305 DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead)
307 return This->baseVtbl->StreamReadAt(This, index, offset, size, buffer, bytesRead);
310 /* Write size bytes to this directory entry's stream at the given offset,
311 * growing the stream if necessary. */
312 static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This,
313 DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
315 return This->baseVtbl->StreamWriteAt(This, index, offset, size, buffer, bytesWritten);
318 static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This,
319 DirRef index, ULARGE_INTEGER newsize)
321 return This->baseVtbl->StreamSetSize(This, index, newsize);
324 /* Make dst point to the same stream that src points to. Other stream operations
325 * will not work properly for entries that point to the same stream, so this
326 * must be a very temporary state, and only one entry pointing to a given stream
327 * may be reachable at any given time. */
328 static inline HRESULT StorageBaseImpl_StreamLink(StorageBaseImpl *This,
329 DirRef dst, DirRef src)
331 return This->baseVtbl->StreamLink(This, dst, src);
334 static inline HRESULT StorageBaseImpl_GetTransactionSig(StorageBaseImpl *This,
335 ULONG* result, BOOL refresh)
337 return This->baseVtbl->GetTransactionSig(This, result, refresh);
340 static inline HRESULT StorageBaseImpl_SetTransactionSig(StorageBaseImpl *This,
341 ULONG value)
343 return This->baseVtbl->SetTransactionSig(This, value);
346 static inline HRESULT StorageBaseImpl_LockTransaction(StorageBaseImpl *This, BOOL write)
348 return This->baseVtbl->LockTransaction(This, write);
351 static inline HRESULT StorageBaseImpl_UnlockTransaction(StorageBaseImpl *This, BOOL write)
353 return This->baseVtbl->UnlockTransaction(This, write);
356 /****************************************************************************
357 * StorageBaseImpl stream list handlers
360 void StorageBaseImpl_AddStream(StorageBaseImpl * stg, StgStreamImpl * strm) DECLSPEC_HIDDEN;
361 void StorageBaseImpl_RemoveStream(StorageBaseImpl * stg, StgStreamImpl * strm) DECLSPEC_HIDDEN;
363 /* Number of BlockChainStream objects to cache in a StorageImpl */
364 #define BLOCKCHAIN_CACHE_SIZE 4
366 /****************************************************************************
367 * Storage32Impl definitions.
369 * This implementation of the IStorage32 interface represents a root
370 * storage. Basically, a document file.
372 struct StorageImpl
374 struct StorageBaseImpl base;
377 * File header
379 WORD bigBlockSizeBits;
380 WORD smallBlockSizeBits;
381 ULONG bigBlockSize;
382 ULONG smallBlockSize;
383 ULONG bigBlockDepotCount;
384 ULONG rootStartBlock;
385 ULONG smallBlockLimit;
386 ULONG smallBlockDepotStart;
387 ULONG extBigBlockDepotStart;
388 ULONG *extBigBlockDepotLocations;
389 ULONG extBigBlockDepotLocationsSize;
390 ULONG extBigBlockDepotCount;
391 ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER];
392 ULONG transactionSig;
394 ULONG extBlockDepotCached[MAX_BIG_BLOCK_SIZE / 4];
395 ULONG indexExtBlockDepotCached;
397 ULONG blockDepotCached[MAX_BIG_BLOCK_SIZE / 4];
398 ULONG indexBlockDepotCached;
399 ULONG prevFreeBlock;
401 /* All small blocks before this one are known to be in use. */
402 ULONG firstFreeSmallBlock;
405 * Abstraction of the big block chains for the chains of the header.
407 BlockChainStream* rootBlockChain;
408 BlockChainStream* smallBlockDepotChain;
409 BlockChainStream* smallBlockRootChain;
411 /* Cache of block chain streams objects for directory entries */
412 BlockChainStream* blockChainCache[BLOCKCHAIN_CACHE_SIZE];
413 UINT blockChainToEvict;
415 ILockBytes* lockBytes;
417 ULONG locked_bytes[8];
420 HRESULT StorageImpl_ReadRawDirEntry(
421 StorageImpl *This,
422 ULONG index,
423 BYTE *buffer) DECLSPEC_HIDDEN;
425 void UpdateRawDirEntry(
426 BYTE *buffer,
427 const DirEntry *newData) DECLSPEC_HIDDEN;
429 HRESULT StorageImpl_WriteRawDirEntry(
430 StorageImpl *This,
431 ULONG index,
432 const BYTE *buffer) DECLSPEC_HIDDEN;
434 HRESULT StorageImpl_ReadDirEntry(
435 StorageImpl* This,
436 DirRef index,
437 DirEntry* buffer) DECLSPEC_HIDDEN;
439 HRESULT StorageImpl_WriteDirEntry(
440 StorageImpl* This,
441 DirRef index,
442 const DirEntry* buffer) DECLSPEC_HIDDEN;
444 BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
445 StorageImpl* This,
446 SmallBlockChainStream** ppsbChain) DECLSPEC_HIDDEN;
448 SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks(
449 StorageImpl* This,
450 BlockChainStream** ppbbChain,
451 ULARGE_INTEGER newSize) DECLSPEC_HIDDEN;
453 /****************************************************************************
454 * StgStreamImpl definitions.
456 * This class implements the IStream interface and represents a stream
457 * located inside a storage object.
459 struct StgStreamImpl
461 IStream IStream_iface;
462 LONG ref;
465 * We are an entry in the storage object's stream handler list
467 struct list StrmListEntry;
470 * Storage that is the parent(owner) of the stream
472 StorageBaseImpl* parentStorage;
475 * Access mode of this stream.
477 DWORD grfMode;
480 * Index of the directory entry that owns (points to) this stream.
482 DirRef dirEntry;
485 * This is the current position of the cursor in the stream
487 ULARGE_INTEGER currentPosition;
490 static inline StgStreamImpl *impl_from_IStream( IStream *iface )
492 return CONTAINING_RECORD(iface, StgStreamImpl, IStream_iface);
496 * Method definition for the StgStreamImpl class.
498 StgStreamImpl* StgStreamImpl_Construct(
499 StorageBaseImpl* parentStorage,
500 DWORD grfMode,
501 DirRef dirEntry) DECLSPEC_HIDDEN;
504 /* Range lock constants.
506 * The storage format reserves the region from 0x7fffff00-0x7fffffff for
507 * locking and synchronization. Unfortunately, the spec doesn't say which bytes
508 * within that range are used, and for what. These are guesses based on testing.
509 * In particular, ends of ranges may be wrong.
511 0x0 through 0x57: Unknown. Causes read-only exclusive opens to fail.
512 0x58 through 0x6b: Priority mode.
513 0x6c through 0x7f: No snapshot mode.
514 0x80: Commit lock.
515 0x81 through 0x91: Priority mode, again. Not sure why it uses two regions.
516 0x92: Lock-checking lock. Held while opening so ranges can be tested without
517 causing spurious failures if others try to grab or test those ranges at the
518 same time.
519 0x93 through 0xa6: Read mode.
520 0xa7 through 0xba: Write mode.
521 0xbb through 0xce: Deny read.
522 0xcf through 0xe2: Deny write.
523 0xe2 through 0xff: Unknown. Causes read-only exclusive opens to fail.
526 #define RANGELOCK_UNK1_FIRST 0x7fffff00
527 #define RANGELOCK_UNK1_LAST 0x7fffff57
528 #define RANGELOCK_PRIORITY1_FIRST 0x7fffff58
529 #define RANGELOCK_PRIORITY1_LAST 0x7fffff6b
530 #define RANGELOCK_NOSNAPSHOT_FIRST 0x7fffff6c
531 #define RANGELOCK_NOSNAPSHOT_LAST 0x7fffff7f
532 #define RANGELOCK_COMMIT 0x7fffff80
533 #define RANGELOCK_PRIORITY2_FIRST 0x7fffff81
534 #define RANGELOCK_PRIORITY2_LAST 0x7fffff91
535 #define RANGELOCK_CHECKLOCKS 0x7fffff92
536 #define RANGELOCK_READ_FIRST 0x7fffff93
537 #define RANGELOCK_READ_LAST 0x7fffffa6
538 #define RANGELOCK_WRITE_FIRST 0x7fffffa7
539 #define RANGELOCK_WRITE_LAST 0x7fffffba
540 #define RANGELOCK_DENY_READ_FIRST 0x7fffffbb
541 #define RANGELOCK_DENY_READ_LAST 0x7fffffce
542 #define RANGELOCK_DENY_WRITE_FIRST 0x7fffffcf
543 #define RANGELOCK_DENY_WRITE_LAST 0x7fffffe2
544 #define RANGELOCK_UNK2_FIRST 0x7fffffe3
545 #define RANGELOCK_UNK2_LAST 0x7fffffff
546 #define RANGELOCK_TRANSACTION_FIRST RANGELOCK_COMMIT
547 #define RANGELOCK_TRANSACTION_LAST RANGELOCK_CHECKLOCKS
548 #define RANGELOCK_FIRST RANGELOCK_UNK1_FIRST
549 #define RANGELOCK_LAST RANGELOCK_UNK2_LAST
552 /******************************************************************************
553 * Endian conversion macros
555 #ifdef WORDS_BIGENDIAN
557 #define htole32(x) RtlUlongByteSwap(x)
558 #define htole16(x) RtlUshortByteSwap(x)
559 #define lendian32toh(x) RtlUlongByteSwap(x)
560 #define lendian16toh(x) RtlUshortByteSwap(x)
562 #else
564 #define htole32(x) (x)
565 #define htole16(x) (x)
566 #define lendian32toh(x) (x)
567 #define lendian16toh(x) (x)
569 #endif
571 /******************************************************************************
572 * The StorageUtl_ functions are miscellaneous utility functions. Most of which
573 * are abstractions used to read values from file buffers without having to
574 * worry about bit order
576 void StorageUtl_ReadWord(const BYTE* buffer, ULONG offset, WORD* value) DECLSPEC_HIDDEN;
577 void StorageUtl_WriteWord(BYTE* buffer, ULONG offset, WORD value) DECLSPEC_HIDDEN;
578 void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value) DECLSPEC_HIDDEN;
579 void StorageUtl_WriteDWord(BYTE* buffer, ULONG offset, DWORD value) DECLSPEC_HIDDEN;
580 void StorageUtl_ReadULargeInteger(const BYTE* buffer, ULONG offset,
581 ULARGE_INTEGER* value) DECLSPEC_HIDDEN;
582 void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
583 const ULARGE_INTEGER *value) DECLSPEC_HIDDEN;
584 void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value) DECLSPEC_HIDDEN;
585 void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value) DECLSPEC_HIDDEN;
586 void StorageUtl_CopyDirEntryToSTATSTG(StorageBaseImpl *storage,STATSTG* destination,
587 const DirEntry* source, int statFlags) DECLSPEC_HIDDEN;
589 /****************************************************************************
590 * BlockChainStream definitions.
592 * The BlockChainStream class is a utility class that is used to create an
593 * abstraction of the big block chains in the storage file.
595 struct BlockChainRun
597 /* This represents a range of blocks that happen reside in consecutive sectors. */
598 ULONG firstSector;
599 ULONG firstOffset;
600 ULONG lastOffset;
603 typedef struct BlockChainBlock
605 ULONG index;
606 ULONG sector;
607 BOOL read;
608 BOOL dirty;
609 BYTE data[MAX_BIG_BLOCK_SIZE];
610 } BlockChainBlock;
612 struct BlockChainStream
614 StorageImpl* parentStorage;
615 ULONG* headOfStreamPlaceHolder;
616 DirRef ownerDirEntry;
617 struct BlockChainRun* indexCache;
618 ULONG indexCacheLen;
619 ULONG indexCacheSize;
620 BlockChainBlock cachedBlocks[2];
621 ULONG blockToEvict;
622 ULONG tailIndex;
623 ULONG numBlocks;
627 * Methods for the BlockChainStream class.
629 BlockChainStream* BlockChainStream_Construct(
630 StorageImpl* parentStorage,
631 ULONG* headOfStreamPlaceHolder,
632 DirRef dirEntry) DECLSPEC_HIDDEN;
634 void BlockChainStream_Destroy(
635 BlockChainStream* This) DECLSPEC_HIDDEN;
637 HRESULT BlockChainStream_ReadAt(
638 BlockChainStream* This,
639 ULARGE_INTEGER offset,
640 ULONG size,
641 void* buffer,
642 ULONG* bytesRead) DECLSPEC_HIDDEN;
644 HRESULT BlockChainStream_WriteAt(
645 BlockChainStream* This,
646 ULARGE_INTEGER offset,
647 ULONG size,
648 const void* buffer,
649 ULONG* bytesWritten) DECLSPEC_HIDDEN;
651 BOOL BlockChainStream_SetSize(
652 BlockChainStream* This,
653 ULARGE_INTEGER newSize) DECLSPEC_HIDDEN;
655 HRESULT BlockChainStream_Flush(
656 BlockChainStream* This) DECLSPEC_HIDDEN;
658 /****************************************************************************
659 * SmallBlockChainStream definitions.
661 * The SmallBlockChainStream class is a utility class that is used to create an
662 * abstraction of the small block chains in the storage file.
664 struct SmallBlockChainStream
666 StorageImpl* parentStorage;
667 DirRef ownerDirEntry;
668 ULONG* headOfStreamPlaceHolder;
672 * Methods of the SmallBlockChainStream class.
674 SmallBlockChainStream* SmallBlockChainStream_Construct(
675 StorageImpl* parentStorage,
676 ULONG* headOfStreamPlaceHolder,
677 DirRef dirEntry) DECLSPEC_HIDDEN;
679 void SmallBlockChainStream_Destroy(
680 SmallBlockChainStream* This) DECLSPEC_HIDDEN;
682 HRESULT SmallBlockChainStream_ReadAt(
683 SmallBlockChainStream* This,
684 ULARGE_INTEGER offset,
685 ULONG size,
686 void* buffer,
687 ULONG* bytesRead) DECLSPEC_HIDDEN;
689 HRESULT SmallBlockChainStream_WriteAt(
690 SmallBlockChainStream* This,
691 ULARGE_INTEGER offset,
692 ULONG size,
693 const void* buffer,
694 ULONG* bytesWritten) DECLSPEC_HIDDEN;
696 BOOL SmallBlockChainStream_SetSize(
697 SmallBlockChainStream* This,
698 ULARGE_INTEGER newSize) DECLSPEC_HIDDEN;
701 #endif /* __STORAGE32_H__ */