Fixed some traces to use the right printf format and avoid typecasts.
[wine] / dlls / ole32 / storage32.h
1 /*
2  * Compound Storage (32 bit version)
3  *
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>)
7  *
8  * This include file contains definitions of types and function
9  * prototypes that are used in the many files implementing the
10  * storage functionality
11  *
12  * Copyright 1998,1999 Francis Beaudet
13  * Copyright 1998,1999 Thuy Nguyen
14  *
15  * This library is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU Lesser General Public
17  * License as published by the Free Software Foundation; either
18  * version 2.1 of the License, or (at your option) any later version.
19  *
20  * This library is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  * Lesser General Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser General Public
26  * License along with this library; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29 #ifndef __STORAGE32_H__
30 #define __STORAGE32_H__
31
32 #include <stdarg.h>
33
34 #include "windef.h"
35 #include "winbase.h"
36 #include "winnt.h"
37 #include "objbase.h"
38 #include "winreg.h"
39 #include "winternl.h"
40
41 /*
42  * Definitions for the file format offsets.
43  */
44 static const ULONG OFFSET_BIGBLOCKSIZEBITS   = 0x0000001e;
45 static const ULONG OFFSET_SMALLBLOCKSIZEBITS = 0x00000020;
46 static const ULONG OFFSET_BBDEPOTCOUNT       = 0x0000002C;
47 static const ULONG OFFSET_ROOTSTARTBLOCK     = 0x00000030;
48 static const ULONG OFFSET_SBDEPOTSTART       = 0x0000003C;
49 static const ULONG OFFSET_SBDEPOTCOUNT       = 0x00000040;
50 static const ULONG OFFSET_EXTBBDEPOTSTART    = 0x00000044;
51 static const ULONG OFFSET_EXTBBDEPOTCOUNT    = 0x00000048;
52 static const ULONG OFFSET_BBDEPOTSTART       = 0x0000004C;
53 static const ULONG OFFSET_PS_NAME            = 0x00000000;
54 static const ULONG OFFSET_PS_NAMELENGTH      = 0x00000040;
55 static const ULONG OFFSET_PS_PROPERTYTYPE    = 0x00000042;
56 static const ULONG OFFSET_PS_PREVIOUSPROP    = 0x00000044;
57 static const ULONG OFFSET_PS_NEXTPROP        = 0x00000048;
58 static const ULONG OFFSET_PS_DIRPROP         = 0x0000004C;
59 static const ULONG OFFSET_PS_GUID            = 0x00000050;
60 static const ULONG OFFSET_PS_TSS1            = 0x00000064;
61 static const ULONG OFFSET_PS_TSD1            = 0x00000068;
62 static const ULONG OFFSET_PS_TSS2            = 0x0000006C;
63 static const ULONG OFFSET_PS_TSD2            = 0x00000070;
64 static const ULONG OFFSET_PS_STARTBLOCK      = 0x00000074;
65 static const ULONG OFFSET_PS_SIZE            = 0x00000078;
66 static const WORD  DEF_BIG_BLOCK_SIZE_BITS   = 0x0009;
67 static const WORD  DEF_SMALL_BLOCK_SIZE_BITS = 0x0006;
68 static const WORD  DEF_BIG_BLOCK_SIZE        = 0x0200;
69 static const WORD  DEF_SMALL_BLOCK_SIZE      = 0x0040;
70 static const ULONG BLOCK_EXTBBDEPOT          = 0xFFFFFFFC;
71 static const ULONG BLOCK_SPECIAL             = 0xFFFFFFFD;
72 static const ULONG BLOCK_END_OF_CHAIN        = 0xFFFFFFFE;
73 static const ULONG BLOCK_UNUSED              = 0xFFFFFFFF;
74 static const ULONG PROPERTY_NULL             = 0xFFFFFFFF;
75
76 #define PROPERTY_NAME_MAX_LEN    0x20
77 #define PROPERTY_NAME_BUFFER_LEN 0x40
78
79 #define PROPSET_BLOCK_SIZE 0x00000080
80
81 /*
82  * Property type of relation
83  */
84 #define PROPERTY_RELATION_PREVIOUS 0
85 #define PROPERTY_RELATION_NEXT     1
86 #define PROPERTY_RELATION_DIR      2
87
88 /*
89  * Property type constants
90  */
91 #define PROPTYPE_STORAGE 0x01
92 #define PROPTYPE_STREAM  0x02
93 #define PROPTYPE_ROOT    0x05
94
95 /*
96  * These defines assume a hardcoded blocksize. The code will assert
97  * if the blocksize is different. Some changes will have to be done if it
98  * becomes the case.
99  */
100 #define BIG_BLOCK_SIZE           0x200
101 #define COUNT_BBDEPOTINHEADER    109
102 #define LIMIT_TO_USE_SMALL_BLOCK 0x1000
103 #define NUM_BLOCKS_PER_DEPOT_BLOCK 128
104
105 #define STGM_ACCESS_MODE(stgm)   ((stgm)&0x0000f)
106 #define STGM_SHARE_MODE(stgm)    ((stgm)&0x000f0)
107 #define STGM_CREATE_MODE(stgm)   ((stgm)&0x0f000)
108
109 #define STGM_KNOWN_FLAGS (0xf0ff | \
110      STGM_TRANSACTED | STGM_CONVERT | STGM_PRIORITY | STGM_NOSCRATCH | \
111      STGM_NOSNAPSHOT | STGM_DIRECT_SWMR | STGM_DELETEONRELEASE | STGM_SIMPLE)
112
113 /*
114  * These are signatures to detect the type of Document file.
115  */
116 static const BYTE STORAGE_magic[8]    ={0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1};
117 static const BYTE STORAGE_oldmagic[8] ={0xd0,0xcf,0x11,0xe0,0x0e,0x11,0xfc,0x0d};
118
119 /*
120  * Forward declarations of all the structures used by the storage
121  * module.
122  */
123 typedef struct StorageBaseImpl     StorageBaseImpl;
124 typedef struct StorageImpl         StorageImpl;
125 typedef struct StorageInternalImpl StorageInternalImpl;
126 typedef struct BlockChainStream      BlockChainStream;
127 typedef struct SmallBlockChainStream SmallBlockChainStream;
128 typedef struct IEnumSTATSTGImpl      IEnumSTATSTGImpl;
129 typedef struct StgProperty           StgProperty;
130 typedef struct StgStreamImpl         StgStreamImpl;
131
132 /*
133  * This utility structure is used to read/write the information in a storage
134  * property.
135  */
136 struct StgProperty
137 {
138   WCHAR          name[PROPERTY_NAME_MAX_LEN];
139   WORD           sizeOfNameString;
140   BYTE           propertyType;
141   ULONG          previousProperty;
142   ULONG          nextProperty;
143   ULONG          dirProperty;
144   GUID           propertyUniqueID;
145   ULONG          timeStampS1;
146   ULONG          timeStampD1;
147   ULONG          timeStampS2;
148   ULONG          timeStampD2;
149   ULONG          startingBlock;
150   ULARGE_INTEGER size;
151 };
152
153 /*************************************************************************
154  * Big Block File support
155  *
156  * The big block file is an abstraction of a flat file separated in
157  * same sized blocks. The implementation for the methods described in
158  * this section appear in stg_bigblockfile.c
159  */
160
161 /*
162  * Declaration of the data structures
163  */
164 typedef struct BigBlockFile BigBlockFile,*LPBIGBLOCKFILE;
165 typedef struct MappedPage   MappedPage,*LPMAPPEDPAGE;
166
167 struct BigBlockFile
168 {
169   BOOL fileBased;
170   ULARGE_INTEGER filesize;
171   ULONG blocksize;
172   HANDLE hfile;
173   HANDLE hfilemap;
174   DWORD flProtect;
175   MappedPage *maplist;
176   MappedPage *victimhead, *victimtail;
177   ULONG num_victim_pages;
178   ILockBytes *pLkbyt;
179   HGLOBAL hbytearray;
180   LPVOID pbytearray;
181 };
182
183 /*
184  * Declaration of the functions used to manipulate the BigBlockFile
185  * data structure.
186  */
187 BigBlockFile*  BIGBLOCKFILE_Construct(HANDLE hFile,
188                                       ILockBytes* pLkByt,
189                                       DWORD openFlags,
190                                       ULONG blocksize,
191                                       BOOL fileBased);
192 void           BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This);
193 void*          BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index);
194 void*          BIGBLOCKFILE_GetROBigBlock(LPBIGBLOCKFILE This, ULONG index);
195 void           BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock);
196 void           BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize);
197 ULARGE_INTEGER BIGBLOCKFILE_GetSize(LPBIGBLOCKFILE This);
198
199 /*************************************************************************
200  * Ole Convert support
201  */
202
203 void OLECONVERT_CreateOleStream(LPSTORAGE pStorage);
204 HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName);
205
206 /****************************************************************************
207  * Storage32BaseImpl definitions.
208  *
209  * This structure defines the base information contained in all implementations
210  * of IStorage32 contained in this file storage implementation.
211  *
212  * In OOP terms, this is the base class for all the IStorage32 implementations
213  * contained in this file.
214  */
215 struct StorageBaseImpl
216 {
217   const IStorageVtbl *lpVtbl;    /* Needs to be the first item in the struct
218                             * since we want to cast this in a Storage32 pointer */
219
220   const IPropertySetStorageVtbl *pssVtbl; /* interface for adding a properties stream */
221
222   /*
223    * Reference count of this object
224    */
225   LONG ref;
226
227   /*
228    * Ancestor storage (top level)
229    */
230   StorageImpl* ancestorStorage;
231
232   /*
233    * Index of the property for the root of
234    * this storage
235    */
236   ULONG rootPropertySetIndex;
237
238   /*
239    * virtual Destructor method.
240    */
241   void (*v_destructor)(StorageBaseImpl*);
242
243   /*
244    * flags that this storage was opened or created with
245    */
246   DWORD openFlags;
247 };
248
249
250 /****************************************************************************
251  * Storage32Impl definitions.
252  *
253  * This implementation of the IStorage32 interface represents a root
254  * storage. Basically, a document file.
255  */
256 struct StorageImpl
257 {
258   struct StorageBaseImpl base;
259
260   /*
261    * The following data members are specific to the Storage32Impl
262    * class
263    */
264   HANDLE           hFile;      /* Physical support for the Docfile */
265   LPOLESTR         pwcsName;   /* Full path of the document file */
266
267   /* FIXME: should this be in Storage32BaseImpl ? */
268   WCHAR            filename[PROPERTY_NAME_BUFFER_LEN];
269
270   /*
271    * File header
272    */
273   WORD  bigBlockSizeBits;
274   WORD  smallBlockSizeBits;
275   ULONG bigBlockSize;
276   ULONG smallBlockSize;
277   ULONG bigBlockDepotCount;
278   ULONG rootStartBlock;
279   ULONG smallBlockDepotStart;
280   ULONG extBigBlockDepotStart;
281   ULONG extBigBlockDepotCount;
282   ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER];
283
284   ULONG blockDepotCached[NUM_BLOCKS_PER_DEPOT_BLOCK];
285   ULONG indexBlockDepotCached;
286   ULONG prevFreeBlock;
287
288   /*
289    * Abstraction of the big block chains for the chains of the header.
290    */
291   BlockChainStream* rootBlockChain;
292   BlockChainStream* smallBlockDepotChain;
293   BlockChainStream* smallBlockRootChain;
294
295   /*
296    * Pointer to the big block file abstraction
297    */
298   BigBlockFile* bigBlockFile;
299 };
300
301 void StorageImpl_Destroy(
302             StorageBaseImpl* This);
303
304 HRESULT StorageImpl_Construct(
305             StorageImpl* This,
306             HANDLE       hFile,
307             LPCOLESTR    pwcsName,
308             ILockBytes*  pLkbyt,
309             DWORD        openFlags,
310             BOOL         fileBased,
311             BOOL         fileCreate);
312
313 BOOL StorageImpl_ReadBigBlock(
314             StorageImpl* This,
315             ULONG          blockIndex,
316             void*          buffer);
317
318 BOOL StorageImpl_WriteBigBlock(
319             StorageImpl* This,
320             ULONG          blockIndex,
321             void*          buffer);
322
323 void* StorageImpl_GetROBigBlock(
324             StorageImpl* This,
325             ULONG          blockIndex);
326
327 void* StorageImpl_GetBigBlock(
328             StorageImpl* This,
329             ULONG          blockIndex);
330
331 void StorageImpl_ReleaseBigBlock(
332             StorageImpl* This,
333             void*          pBigBlock);
334
335 ULONG StorageImpl_GetNextFreeBigBlock(
336             StorageImpl* This);
337
338 void StorageImpl_FreeBigBlock(
339             StorageImpl* This,
340             ULONG blockIndex);
341
342 HRESULT StorageImpl_GetNextBlockInChain(
343             StorageImpl* This,
344             ULONG blockIndex,
345             ULONG* nextBlockIndex);
346
347 void StorageImpl_SetNextBlockInChain(
348             StorageImpl* This,
349             ULONG blockIndex,
350             ULONG nextBlock);
351
352 HRESULT StorageImpl_LoadFileHeader(
353             StorageImpl* This);
354
355 void StorageImpl_SaveFileHeader(
356             StorageImpl* This);
357
358 BOOL StorageImpl_ReadProperty(
359             StorageImpl* This,
360             ULONG          index,
361             StgProperty*    buffer);
362
363 BOOL StorageImpl_WriteProperty(
364             StorageImpl* This,
365             ULONG          index,
366             StgProperty*   buffer);
367
368 BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
369                       StorageImpl* This,
370                       SmallBlockChainStream** ppsbChain);
371
372 ULONG Storage32Impl_GetNextExtendedBlock(StorageImpl* This,
373                                          ULONG blockIndex);
374
375 void Storage32Impl_AddBlockDepot(StorageImpl* This,
376                                  ULONG blockIndex);
377
378 ULONG Storage32Impl_AddExtBlockDepot(StorageImpl* This);
379
380 ULONG Storage32Impl_GetExtDepotBlock(StorageImpl* This,
381                                      ULONG depotIndex);
382
383 void Storage32Impl_SetExtDepotBlock(StorageImpl* This,
384                                     ULONG depotIndex,
385                                     ULONG blockIndex);
386 /****************************************************************************
387  * Storage32InternalImpl definitions.
388  *
389  * Definition of the implementation structure for the IStorage32 interface.
390  * This one implements the IStorage32 interface for storage that are
391  * inside another storage.
392  */
393 struct StorageInternalImpl
394 {
395   struct StorageBaseImpl base;
396
397   /*
398    * There is no specific data for this class.
399    */
400 };
401
402 /*
403  * Method definitions for the Storage32InternalImpl class.
404  */
405 StorageInternalImpl* StorageInternalImpl_Construct(
406             StorageImpl* ancestorStorage,
407             DWORD          openFlags,
408             ULONG          rootTropertyIndex);
409
410 void StorageInternalImpl_Destroy(
411             StorageBaseImpl* This);
412
413 HRESULT WINAPI StorageInternalImpl_Commit(
414             IStorage*            iface,
415             DWORD                  grfCommitFlags); /* [in] */
416
417 HRESULT WINAPI StorageInternalImpl_Revert(
418             IStorage*            iface);
419
420
421 /****************************************************************************
422  * IEnumSTATSTGImpl definitions.
423  *
424  * Definition of the implementation structure for the IEnumSTATSTGImpl interface.
425  * This class allows iterating through the content of a storage and to find
426  * specific items inside it.
427  */
428 struct IEnumSTATSTGImpl
429 {
430   const IEnumSTATSTGVtbl *lpVtbl;    /* Needs to be the first item in the struct
431                                 * since we want to cast this in an IEnumSTATSTG pointer */
432
433   LONG           ref;                   /* Reference count */
434   StorageImpl* parentStorage;         /* Reference to the parent storage */
435   ULONG          firstPropertyNode;     /* Index of the root of the storage to enumerate */
436
437   /*
438    * The current implementation of the IEnumSTATSTGImpl class uses a stack
439    * to walk the property sets to get the content of a storage. This stack
440    * is implemented by the following 3 data members
441    */
442   ULONG          stackSize;
443   ULONG          stackMaxSize;
444   ULONG*         stackToVisit;
445
446 #define ENUMSTATSGT_SIZE_INCREMENT 10
447 };
448
449 IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(
450             StorageImpl* This,
451             ULONG          firstPropertyNode);
452
453 void IEnumSTATSTGImpl_Destroy(
454             IEnumSTATSTGImpl* This);
455
456 void IEnumSTATSTGImpl_PushSearchNode(
457             IEnumSTATSTGImpl* This,
458             ULONG             nodeToPush);
459
460 ULONG IEnumSTATSTGImpl_PopSearchNode(
461             IEnumSTATSTGImpl* This,
462             BOOL            remove);
463
464 ULONG IEnumSTATSTGImpl_FindProperty(
465             IEnumSTATSTGImpl* This,
466             const OLECHAR*  lpszPropName,
467             StgProperty*      buffer);
468
469 INT IEnumSTATSTGImpl_FindParentProperty(
470   IEnumSTATSTGImpl *This,
471   ULONG             childProperty,
472   StgProperty      *currentProperty,
473   ULONG            *propertyId);
474
475
476 /****************************************************************************
477  * StgStreamImpl definitions.
478  *
479  * This class imlements the IStream32 inteface and represents a stream
480  * located inside a storage object.
481  */
482 struct StgStreamImpl
483 {
484   const IStreamVtbl *lpVtbl;  /* Needs to be the first item in the struct
485                          * since we want to cast this to an IStream pointer */
486
487   /*
488    * Reference count
489    */
490   LONG               ref;
491
492   /*
493    * Storage that is the parent(owner) of the stream
494    */
495   StorageBaseImpl* parentStorage;
496
497   /*
498    * Access mode of this stream.
499    */
500   DWORD grfMode;
501
502   /*
503    * Index of the property that owns (points to) this stream.
504    */
505   ULONG              ownerProperty;
506
507   /*
508    * Helper variable that contains the size of the stream
509    */
510   ULARGE_INTEGER     streamSize;
511
512   /*
513    * This is the current position of the cursor in the stream
514    */
515   ULARGE_INTEGER     currentPosition;
516
517   /*
518    * The information in the stream is represented by a chain of small blocks
519    * or a chain of large blocks. Depending on the case, one of the two
520    * following variabled points to that information.
521    */
522   BlockChainStream*      bigBlockChain;
523   SmallBlockChainStream* smallBlockChain;
524 };
525
526 /*
527  * Method definition for the StgStreamImpl class.
528  */
529 StgStreamImpl* StgStreamImpl_Construct(
530                 StorageBaseImpl* parentStorage,
531     DWORD            grfMode,
532     ULONG            ownerProperty);
533
534
535 /******************************************************************************
536  * Endian conversion macros
537  */
538 #ifdef WORDS_BIGENDIAN
539
540 #define htole32(x) RtlUlongByteSwap(x)
541 #define htole16(x) RtlUshortByteSwap(x)
542 #define le32toh(x) RtlUlongByteSwap(x)
543 #define le16toh(x) RtlUshortByteSwap(x)
544
545 #else
546
547 #define htole32(x) (x)
548 #define htole16(x) (x)
549 #define le32toh(x) (x)
550 #define le16toh(x) (x)
551
552 #endif
553
554 /******************************************************************************
555  * The StorageUtl_ functions are miscellaneous utility functions. Most of which
556  * are abstractions used to read values from file buffers without having to
557  * worry about bit order
558  */
559 void StorageUtl_ReadWord(const BYTE* buffer, ULONG offset, WORD* value);
560 void StorageUtl_WriteWord(BYTE* buffer, ULONG offset, WORD value);
561 void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value);
562 void StorageUtl_WriteDWord(BYTE* buffer, ULONG offset, DWORD value);
563 void StorageUtl_ReadULargeInteger(const BYTE* buffer, ULONG offset,
564  ULARGE_INTEGER* value);
565 void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
566  const ULARGE_INTEGER *value);
567 void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value);
568 void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value);
569 void StorageUtl_CopyPropertyToSTATSTG(STATSTG*     destination,
570                                              StgProperty* source,
571                                              int          statFlags);
572
573 /****************************************************************************
574  * BlockChainStream definitions.
575  *
576  * The BlockChainStream class is a utility class that is used to create an
577  * abstraction of the big block chains in the storage file.
578  */
579 struct BlockChainStream
580 {
581   StorageImpl* parentStorage;
582   ULONG*       headOfStreamPlaceHolder;
583   ULONG        ownerPropertyIndex;
584   ULONG        lastBlockNoInSequence;
585   ULONG        lastBlockNoInSequenceIndex;
586   ULONG        tailIndex;
587   ULONG        numBlocks;
588 };
589
590 /*
591  * Methods for the BlockChainStream class.
592  */
593 BlockChainStream* BlockChainStream_Construct(
594                 StorageImpl* parentStorage,
595                 ULONG*         headOfStreamPlaceHolder,
596                 ULONG          propertyIndex);
597
598 void BlockChainStream_Destroy(
599                 BlockChainStream* This);
600
601 ULONG BlockChainStream_GetHeadOfChain(
602                 BlockChainStream* This);
603
604 BOOL BlockChainStream_ReadAt(
605                 BlockChainStream* This,
606                 ULARGE_INTEGER offset,
607                 ULONG          size,
608                 void*          buffer,
609                 ULONG*         bytesRead);
610
611 BOOL BlockChainStream_WriteAt(
612                 BlockChainStream* This,
613                 ULARGE_INTEGER offset,
614                 ULONG          size,
615                 const void*    buffer,
616                 ULONG*         bytesWritten);
617
618 BOOL BlockChainStream_SetSize(
619                 BlockChainStream* This,
620                 ULARGE_INTEGER    newSize);
621
622 ULARGE_INTEGER BlockChainStream_GetSize(
623     BlockChainStream* This);
624
625 ULONG BlockChainStream_GetCount(
626     BlockChainStream* This);
627
628 /****************************************************************************
629  * SmallBlockChainStream definitions.
630  *
631  * The SmallBlockChainStream class is a utility class that is used to create an
632  * abstraction of the small block chains in the storage file.
633  */
634 struct SmallBlockChainStream
635 {
636   StorageImpl* parentStorage;
637   ULONG          ownerPropertyIndex;
638 };
639
640 /*
641  * Methods of the SmallBlockChainStream class.
642  */
643 SmallBlockChainStream* SmallBlockChainStream_Construct(
644                StorageImpl* parentStorage,
645                ULONG          propertyIndex);
646
647 void SmallBlockChainStream_Destroy(
648                SmallBlockChainStream* This);
649
650 ULONG SmallBlockChainStream_GetHeadOfChain(
651                SmallBlockChainStream* This);
652
653 HRESULT SmallBlockChainStream_GetNextBlockInChain(
654                SmallBlockChainStream* This,
655                ULONG                  blockIndex,
656                ULONG*                 nextBlockIndex);
657
658 void SmallBlockChainStream_SetNextBlockInChain(
659          SmallBlockChainStream* This,
660          ULONG                  blockIndex,
661          ULONG                  nextBlock);
662
663 void SmallBlockChainStream_FreeBlock(
664          SmallBlockChainStream* This,
665          ULONG                  blockIndex);
666
667 ULONG SmallBlockChainStream_GetNextFreeBlock(
668          SmallBlockChainStream* This);
669
670 BOOL SmallBlockChainStream_ReadAt(
671                SmallBlockChainStream* This,
672                ULARGE_INTEGER offset,
673                ULONG          size,
674                void*          buffer,
675                ULONG*         bytesRead);
676
677 BOOL SmallBlockChainStream_WriteAt(
678                SmallBlockChainStream* This,
679                ULARGE_INTEGER offset,
680                ULONG          size,
681                const void*    buffer,
682                ULONG*         bytesWritten);
683
684 BOOL SmallBlockChainStream_SetSize(
685                SmallBlockChainStream* This,
686                ULARGE_INTEGER          newSize);
687
688 ULARGE_INTEGER SmallBlockChainStream_GetSize(
689          SmallBlockChainStream* This);
690
691 ULONG SmallBlockChainStream_GetCount(
692          SmallBlockChainStream* This);
693
694
695 #endif /* __STORAGE32_H__ */