DWORD at offset 0x40 in the header is the number of big blocks in the
[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 "wtypes.h"
33 #include "winnt.h"
34 #include "wine/obj_base.h"
35 #include "wine/obj_storage.h"
36
37 /*
38  * Definitions for the file format offsets.
39  */
40 static const ULONG OFFSET_BIGBLOCKSIZEBITS   = 0x0000001e;
41 static const ULONG OFFSET_SMALLBLOCKSIZEBITS = 0x00000020;
42 static const ULONG OFFSET_BBDEPOTCOUNT       = 0x0000002C;
43 static const ULONG OFFSET_ROOTSTARTBLOCK     = 0x00000030;
44 static const ULONG OFFSET_SBDEPOTSTART       = 0x0000003C;
45 static const ULONG OFFSET_SBDEPOTCOUNT       = 0x00000040;
46 static const ULONG OFFSET_EXTBBDEPOTSTART    = 0x00000044;
47 static const ULONG OFFSET_EXTBBDEPOTCOUNT    = 0x00000048;
48 static const ULONG OFFSET_BBDEPOTSTART       = 0x0000004C;
49 static const ULONG OFFSET_PS_NAME            = 0x00000000;
50 static const ULONG OFFSET_PS_NAMELENGTH      = 0x00000040;
51 static const ULONG OFFSET_PS_PROPERTYTYPE    = 0x00000042;
52 static const ULONG OFFSET_PS_PREVIOUSPROP    = 0x00000044;
53 static const ULONG OFFSET_PS_NEXTPROP        = 0x00000048;
54 static const ULONG OFFSET_PS_DIRPROP         = 0x0000004C;
55 static const ULONG OFFSET_PS_GUID            = 0x00000050;
56 static const ULONG OFFSET_PS_TSS1            = 0x00000064;
57 static const ULONG OFFSET_PS_TSD1            = 0x00000068;
58 static const ULONG OFFSET_PS_TSS2            = 0x0000006C;
59 static const ULONG OFFSET_PS_TSD2            = 0x00000070;
60 static const ULONG OFFSET_PS_STARTBLOCK      = 0x00000074;
61 static const ULONG OFFSET_PS_SIZE            = 0x00000078;
62 static const WORD  DEF_BIG_BLOCK_SIZE_BITS   = 0x0009;
63 static const WORD  DEF_SMALL_BLOCK_SIZE_BITS = 0x0006;
64 static const WORD  DEF_BIG_BLOCK_SIZE        = 0x0200;
65 static const WORD  DEF_SMALL_BLOCK_SIZE      = 0x0040;
66 static const ULONG BLOCK_EXTBBDEPOT          = 0xFFFFFFFC;
67 static const ULONG BLOCK_SPECIAL             = 0xFFFFFFFD;
68 static const ULONG BLOCK_END_OF_CHAIN        = 0xFFFFFFFE;
69 static const ULONG BLOCK_UNUSED              = 0xFFFFFFFF;
70 static const ULONG PROPERTY_NULL             = 0xFFFFFFFF;
71
72 #define PROPERTY_NAME_MAX_LEN    0x20
73 #define PROPERTY_NAME_BUFFER_LEN 0x40
74
75 #define PROPSET_BLOCK_SIZE 0x00000080
76
77 /*
78  * Property type of relation
79  */
80 #define PROPERTY_RELATION_PREVIOUS 0
81 #define PROPERTY_RELATION_NEXT     1
82 #define PROPERTY_RELATION_DIR      2
83
84 /*
85  * Property type constants
86  */
87 #define PROPTYPE_STORAGE 0x01
88 #define PROPTYPE_STREAM  0x02
89 #define PROPTYPE_ROOT    0x05
90
91 /*
92  * These defines assume a hardcoded blocksize. The code will assert
93  * if the blocksize is different. Some changes will have to be done if it
94  * becomes the case.
95  */
96 #define BIG_BLOCK_SIZE           0x200
97 #define COUNT_BBDEPOTINHEADER    109
98 #define LIMIT_TO_USE_SMALL_BLOCK 0x1000
99 #define NUM_BLOCKS_PER_DEPOT_BLOCK 128
100
101 /*
102  * These are signatures to detect the type of Document file.
103  */
104 static const BYTE STORAGE_magic[8]    ={0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1};
105 static const BYTE STORAGE_oldmagic[8] ={0xd0,0xcf,0x11,0xe0,0x0e,0x11,0xfc,0x0d};
106
107 /*
108  * Forward declarations of all the structures used by the storage
109  * module.
110  */
111 typedef struct StorageBaseImpl     StorageBaseImpl;
112 typedef struct StorageImpl         StorageImpl;
113 typedef struct StorageInternalImpl StorageInternalImpl;
114 typedef struct BlockChainStream      BlockChainStream;
115 typedef struct SmallBlockChainStream SmallBlockChainStream;
116 typedef struct IEnumSTATSTGImpl      IEnumSTATSTGImpl;
117 typedef struct StgProperty           StgProperty;
118 typedef struct StgStreamImpl         StgStreamImpl;
119
120 /*
121  * This utility structure is used to read/write the information in a storage
122  * property.
123  */
124 struct StgProperty
125 {
126   WCHAR          name[PROPERTY_NAME_MAX_LEN];
127   WORD           sizeOfNameString;
128   BYTE           propertyType;
129   ULONG          previousProperty;
130   ULONG          nextProperty;
131   ULONG          dirProperty;
132   GUID           propertyUniqueID;
133   ULONG          timeStampS1;
134   ULONG          timeStampD1;
135   ULONG          timeStampS2;
136   ULONG          timeStampD2;
137   ULONG          startingBlock;
138   ULARGE_INTEGER size;
139 };
140
141 /*************************************************************************
142  * Big Block File support
143  *
144  * The big block file is an abstraction of a flat file separated in
145  * same sized blocks. The implementation for the methods described in
146  * this section appear in stg_bigblockfile.c
147  */
148
149 /*
150  * Declaration of the data structures
151  */
152 typedef struct BigBlockFile BigBlockFile,*LPBIGBLOCKFILE;
153 typedef struct MappedPage   MappedPage,*LPMAPPEDPAGE;
154
155 struct BigBlockFile
156 {
157   BOOL fileBased;
158   ULARGE_INTEGER filesize;
159   ULONG blocksize;
160   HANDLE hfile;
161   HANDLE hfilemap;
162   DWORD flProtect;
163   MappedPage *maplist;
164   MappedPage *victimhead, *victimtail;
165   ULONG num_victim_pages;
166   ILockBytes *pLkbyt;
167   HGLOBAL hbytearray;
168   LPVOID pbytearray;
169 };
170
171 /*
172  * Declaration of the functions used to manipulate the BigBlockFile
173  * data structure.
174  */
175 BigBlockFile*  BIGBLOCKFILE_Construct(HANDLE hFile,
176                                       ILockBytes* pLkByt,
177                                       DWORD openFlags,
178                                       ULONG blocksize,
179                                       BOOL fileBased);
180 void           BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This);
181 void*          BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index);
182 void*          BIGBLOCKFILE_GetROBigBlock(LPBIGBLOCKFILE This, ULONG index);
183 void           BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock);
184 void           BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize);
185 ULARGE_INTEGER BIGBLOCKFILE_GetSize(LPBIGBLOCKFILE This);
186
187 /*************************************************************************
188  * Ole Convert support
189  */
190
191 void OLECONVERT_CreateOleStream(LPSTORAGE pStorage);
192 HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName);
193
194 /****************************************************************************
195  * Storage32BaseImpl definitions.
196  *
197  * This structure defines the base information contained in all implementations
198  * of IStorage32 contained in this file storage implementation.
199  *
200  * In OOP terms, this is the base class for all the IStorage32 implementations
201  * contained in this file.
202  */
203 struct StorageBaseImpl
204 {
205   ICOM_VFIELD(IStorage);   /* Needs to be the first item in the struct
206                             * since we want to cast this in a Storage32 pointer */
207
208   /*
209    * Reference count of this object
210    */
211   ULONG ref;
212
213   /*
214    * Ancestor storage (top level)
215    */
216   StorageImpl* ancestorStorage;
217
218   /*
219    * Index of the property for the root of
220    * this storage
221    */
222   ULONG rootPropertySetIndex;
223
224   /*
225    * virtual Destructor method.
226    */
227   void (*v_destructor)(StorageBaseImpl*);
228 };
229
230
231 /*
232  * Prototypes for the methods of the Storage32BaseImpl class.
233  */
234 HRESULT WINAPI StorageBaseImpl_QueryInterface(
235             IStorage*        iface,
236             REFIID             riid,
237             void**             ppvObject);
238
239 ULONG WINAPI StorageBaseImpl_AddRef(
240             IStorage*        iface);
241
242 ULONG WINAPI StorageBaseImpl_Release(
243             IStorage*        iface);
244
245 HRESULT WINAPI StorageBaseImpl_OpenStream(
246             IStorage*        iface,
247             const OLECHAR*   pwcsName,  /* [string][in] */
248             void*              reserved1, /* [unique][in] */
249             DWORD              grfMode,   /* [in] */
250             DWORD              reserved2, /* [in] */
251             IStream**        ppstm);    /* [out] */
252
253 HRESULT WINAPI StorageBaseImpl_OpenStorage(
254             IStorage*        iface,
255             const OLECHAR*   pwcsName,      /* [string][unique][in] */
256             IStorage*        pstgPriority,  /* [unique][in] */
257             DWORD              grfMode,       /* [in] */
258             SNB              snbExclude,    /* [unique][in] */
259             DWORD              reserved,      /* [in] */
260             IStorage**       ppstg);        /* [out] */
261
262 HRESULT WINAPI StorageBaseImpl_EnumElements(
263             IStorage*        iface,
264             DWORD              reserved1, /* [in] */
265             void*              reserved2, /* [size_is][unique][in] */
266             DWORD              reserved3, /* [in] */
267             IEnumSTATSTG**     ppenum);   /* [out] */
268
269 HRESULT WINAPI StorageBaseImpl_Stat(
270             IStorage*        iface,
271             STATSTG*           pstatstg,     /* [out] */
272             DWORD              grfStatFlag); /* [in] */
273
274 HRESULT WINAPI StorageBaseImpl_RenameElement(
275             IStorage*        iface,
276             const OLECHAR*   pwcsOldName,  /* [string][in] */
277             const OLECHAR*   pwcsNewName); /* [string][in] */
278
279 HRESULT WINAPI StorageBaseImpl_CreateStream(
280             IStorage*        iface,
281             const OLECHAR*   pwcsName,  /* [string][in] */
282             DWORD              grfMode,   /* [in] */
283             DWORD              reserved1, /* [in] */
284             DWORD              reserved2, /* [in] */
285             IStream**        ppstm);    /* [out] */
286
287 HRESULT WINAPI StorageBaseImpl_SetClass(
288             IStorage*        iface,
289             REFCLSID           clsid);  /* [in] */
290
291 /****************************************************************************
292  * Storage32Impl definitions.
293  *
294  * This implementation of the IStorage32 interface represents a root
295  * storage. Basically, a document file.
296  */
297 struct StorageImpl
298 {
299   ICOM_VFIELD(IStorage); /* Needs to be the first item in the struct
300                           * since we want to cast this in a Storage32 pointer */
301
302   /*
303    * Declare the member of the Storage32BaseImpl class to allow
304    * casting as a Storage32BaseImpl
305    */
306   ULONG                 ref;
307   struct StorageImpl* ancestorStorage;
308   ULONG                 rootPropertySetIndex;
309   void (*v_destructor)(struct StorageImpl*);
310
311   /*
312    * The following data members are specific to the Storage32Impl
313    * class
314    */
315   HANDLE           hFile;      /* Physical support for the Docfile */
316   LPOLESTR         pwcsName;   /* Full path of the document file */
317
318   /* FIXME: should this be in Storage32BaseImpl ? */
319   WCHAR            filename[PROPERTY_NAME_BUFFER_LEN];
320
321   /*
322    * File header
323    */
324   WORD  bigBlockSizeBits;
325   WORD  smallBlockSizeBits;
326   ULONG bigBlockSize;
327   ULONG smallBlockSize;
328   ULONG bigBlockDepotCount;
329   ULONG rootStartBlock;
330   ULONG smallBlockDepotStart;
331   ULONG extBigBlockDepotStart;
332   ULONG extBigBlockDepotCount;
333   ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER];
334
335   ULONG blockDepotCached[NUM_BLOCKS_PER_DEPOT_BLOCK];
336   ULONG indexBlockDepotCached;
337   ULONG prevFreeBlock;
338
339   /*
340    * Abstraction of the big block chains for the chains of the header.
341    */
342   BlockChainStream* rootBlockChain;
343   BlockChainStream* smallBlockDepotChain;
344   BlockChainStream* smallBlockRootChain;
345
346   /*
347    * Pointer to the big block file abstraction
348    */
349   BigBlockFile* bigBlockFile;
350 };
351
352 /*
353  * Method declaration for the Storage32Impl class
354  */
355
356 HRESULT WINAPI StorageImpl_CreateStorage(
357             IStorage*      iface,
358             const OLECHAR* pwcsName,  /* [string][in] */
359             DWORD            grfMode,   /* [in] */
360             DWORD            dwStgFmt,  /* [in] */
361             DWORD            reserved2, /* [in] */
362             IStorage**     ppstg);    /* [out] */
363
364 HRESULT WINAPI StorageImpl_CopyTo(
365             IStorage*      iface,
366             DWORD          ciidExclude,  /* [in] */
367             const IID*     rgiidExclude, /* [size_is][unique][in] */
368             SNB            snbExclude, /* [unique][in] */
369             IStorage*    pstgDest);    /* [unique][in] */
370
371 HRESULT WINAPI StorageImpl_MoveElementTo(
372             IStorage*      iface,
373             const OLECHAR* pwcsName,    /* [string][in] */
374             IStorage*      pstgDest,    /* [unique][in] */
375             const OLECHAR* pwcsNewName, /* [string][in] */
376             DWORD            grfFlags);   /* [in] */
377
378 HRESULT WINAPI StorageImpl_Commit(
379             IStorage*      iface,
380             DWORD          grfCommitFlags); /* [in] */
381
382 HRESULT WINAPI StorageImpl_Revert(
383             IStorage*      iface);
384
385 HRESULT WINAPI StorageImpl_DestroyElement(
386             IStorage*      iface,
387             const OLECHAR* pwcsName); /* [string][in] */
388
389 HRESULT WINAPI StorageImpl_SetElementTimes(
390             IStorage*      iface,
391             const OLECHAR* pwcsName, /* [string][in] */
392             const FILETIME*  pctime,   /* [in] */
393             const FILETIME*  patime,   /* [in] */
394             const FILETIME*  pmtime);  /* [in] */
395
396 HRESULT WINAPI StorageImpl_SetStateBits(
397             IStorage*      iface,
398             DWORD          grfStateBits, /* [in] */
399             DWORD          grfMask);     /* [in] */
400
401 HRESULT WINAPI StorageImpl_Stat(IStorage* iface,
402                                 STATSTG*  pstatstg,     /* [out] */
403                                 DWORD     grfStatFlag); /* [in] */
404
405 void StorageImpl_Destroy(
406             StorageImpl* This);
407
408 HRESULT StorageImpl_Construct(
409             StorageImpl* This,
410             HANDLE       hFile,
411             LPCOLESTR    pwcsName,
412             ILockBytes*  pLkbyt,
413             DWORD        openFlags,
414             BOOL         fileBased,
415             BOOL         fileCreate);
416
417 BOOL StorageImpl_ReadBigBlock(
418             StorageImpl* This,
419             ULONG          blockIndex,
420             void*          buffer);
421
422 BOOL StorageImpl_WriteBigBlock(
423             StorageImpl* This,
424             ULONG          blockIndex,
425             void*          buffer);
426
427 void* StorageImpl_GetROBigBlock(
428             StorageImpl* This,
429             ULONG          blockIndex);
430
431 void* StorageImpl_GetBigBlock(
432             StorageImpl* This,
433             ULONG          blockIndex);
434
435 void StorageImpl_ReleaseBigBlock(
436             StorageImpl* This,
437             void*          pBigBlock);
438
439 ULONG StorageImpl_GetNextFreeBigBlock(
440             StorageImpl* This);
441
442 void StorageImpl_FreeBigBlock(
443             StorageImpl* This,
444             ULONG blockIndex);
445
446 HRESULT StorageImpl_GetNextBlockInChain(
447             StorageImpl* This,
448             ULONG blockIndex,
449             ULONG* nextBlockIndex);
450
451 void StorageImpl_SetNextBlockInChain(
452             StorageImpl* This,
453             ULONG blockIndex,
454             ULONG nextBlock);
455
456 HRESULT StorageImpl_LoadFileHeader(
457             StorageImpl* This);
458
459 void StorageImpl_SaveFileHeader(
460             StorageImpl* This);
461
462 BOOL StorageImpl_ReadProperty(
463             StorageImpl* This,
464             ULONG          index,
465             StgProperty*    buffer);
466
467 BOOL StorageImpl_WriteProperty(
468             StorageImpl* This,
469             ULONG          index,
470             StgProperty*   buffer);
471
472 BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
473                       StorageImpl* This,
474                       SmallBlockChainStream** ppsbChain);
475
476 ULONG Storage32Impl_GetNextExtendedBlock(StorageImpl* This,
477                                          ULONG blockIndex);
478
479 void Storage32Impl_AddBlockDepot(StorageImpl* This,
480                                  ULONG blockIndex);
481
482 ULONG Storage32Impl_AddExtBlockDepot(StorageImpl* This);
483
484 ULONG Storage32Impl_GetExtDepotBlock(StorageImpl* This,
485                                      ULONG depotIndex);
486
487 void Storage32Impl_SetExtDepotBlock(StorageImpl* This,
488                                     ULONG depotIndex,
489                                     ULONG blockIndex);
490 /****************************************************************************
491  * Storage32InternalImpl definitions.
492  *
493  * Definition of the implementation structure for the IStorage32 interface.
494  * This one implements the IStorage32 interface for storage that are
495  * inside another storage.
496  */
497 struct StorageInternalImpl
498 {
499   ICOM_VFIELD(IStorage);        /* Needs to be the first item in the struct
500                                  * since we want to cast this in a Storage32 pointer */
501
502   /*
503    * Declare the member of the Storage32BaseImpl class to allow
504    * casting as a Storage32BaseImpl
505    */
506   ULONG                      ref;
507   struct StorageImpl* ancestorStorage;
508   ULONG                    rootPropertySetIndex;
509   void (*v_destructor)(struct StorageInternalImpl*);
510
511   /*
512    * There is no specific data for this class.
513    */
514 };
515
516 /*
517  * Method definitions for the Storage32InternalImpl class.
518  */
519 StorageInternalImpl* StorageInternalImpl_Construct(
520             StorageImpl* ancestorStorage,
521             ULONG          rootTropertyIndex);
522
523 void StorageInternalImpl_Destroy(
524             StorageInternalImpl* This);
525
526 HRESULT WINAPI StorageInternalImpl_Commit(
527             IStorage*            iface,
528             DWORD                  grfCommitFlags); /* [in] */
529
530 HRESULT WINAPI StorageInternalImpl_Revert(
531             IStorage*            iface);
532
533
534 /****************************************************************************
535  * IEnumSTATSTGImpl definitions.
536  *
537  * Definition of the implementation structure for the IEnumSTATSTGImpl interface.
538  * This class allows iterating through the content of a storage and to find
539  * specific items inside it.
540  */
541 struct IEnumSTATSTGImpl
542 {
543   ICOM_VFIELD(IEnumSTATSTG);    /* Needs to be the first item in the struct
544                                          * since we want to cast this in a IEnumSTATSTG pointer */
545
546   ULONG          ref;                   /* Reference count */
547   StorageImpl* parentStorage;         /* Reference to the parent storage */
548   ULONG          firstPropertyNode;     /* Index of the root of the storage to enumerate */
549
550   /*
551    * The current implementation of the IEnumSTATSTGImpl class uses a stack
552    * to walk the property sets to get the content of a storage. This stack
553    * is implemented by the following 3 data members
554    */
555   ULONG          stackSize;
556   ULONG          stackMaxSize;
557   ULONG*         stackToVisit;
558
559 #define ENUMSTATSGT_SIZE_INCREMENT 10
560 };
561
562 /*
563  * Method definitions for the IEnumSTATSTGImpl class.
564  */
565 HRESULT WINAPI IEnumSTATSTGImpl_QueryInterface(
566             IEnumSTATSTG*     iface,
567             REFIID            riid,
568             void**            ppvObject);
569
570 ULONG WINAPI IEnumSTATSTGImpl_AddRef(
571             IEnumSTATSTG*     iface);
572
573 ULONG WINAPI IEnumSTATSTGImpl_Release(
574             IEnumSTATSTG*     iface);
575
576 HRESULT WINAPI IEnumSTATSTGImpl_Next(
577             IEnumSTATSTG*     iface,
578             ULONG             celt,
579             STATSTG*          rgelt,
580             ULONG*            pceltFetched);
581
582 HRESULT WINAPI IEnumSTATSTGImpl_Skip(
583             IEnumSTATSTG*     iface,
584             ULONG             celt);
585
586 HRESULT WINAPI IEnumSTATSTGImpl_Reset(
587             IEnumSTATSTG* iface);
588
589 HRESULT WINAPI IEnumSTATSTGImpl_Clone(
590             IEnumSTATSTG*     iface,
591             IEnumSTATSTG**    ppenum);
592
593 IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(
594             StorageImpl* This,
595             ULONG          firstPropertyNode);
596
597 void IEnumSTATSTGImpl_Destroy(
598             IEnumSTATSTGImpl* This);
599
600 void IEnumSTATSTGImpl_PushSearchNode(
601             IEnumSTATSTGImpl* This,
602             ULONG             nodeToPush);
603
604 ULONG IEnumSTATSTGImpl_PopSearchNode(
605             IEnumSTATSTGImpl* This,
606             BOOL            remove);
607
608 ULONG IEnumSTATSTGImpl_FindProperty(
609             IEnumSTATSTGImpl* This,
610             const OLECHAR*  lpszPropName,
611             StgProperty*      buffer);
612
613 INT IEnumSTATSTGImpl_FindParentProperty(
614   IEnumSTATSTGImpl *This,
615   ULONG             childProperty,
616   StgProperty      *currentProperty,
617   ULONG            *propertyId);
618
619
620 /****************************************************************************
621  * StgStreamImpl definitions.
622  *
623  * This class imlements the IStream32 inteface and represents a stream
624  * located inside a storage object.
625  */
626 struct StgStreamImpl
627 {
628   ICOM_VFIELD(IStream);  /* Needs to be the first item in the struct
629                                     * since we want to cast this in a IStream pointer */
630
631   /*
632    * Reference count
633    */
634   ULONG              ref;
635
636   /*
637    * Storage that is the parent(owner) of the stream
638    */
639   StorageBaseImpl* parentStorage;
640
641   /*
642    * Access mode of this stream.
643    */
644   DWORD grfMode;
645
646   /*
647    * Index of the property that owns (points to) this stream.
648    */
649   ULONG              ownerProperty;
650
651   /*
652    * Helper variable that contains the size of the stream
653    */
654   ULARGE_INTEGER     streamSize;
655
656   /*
657    * This is the current position of the cursor in the stream
658    */
659   ULARGE_INTEGER     currentPosition;
660
661   /*
662    * The information in the stream is represented by a chain of small blocks
663    * or a chain of large blocks. Depending on the case, one of the two
664    * following variabled points to that information.
665    */
666   BlockChainStream*      bigBlockChain;
667   SmallBlockChainStream* smallBlockChain;
668 };
669
670 /*
671  * Method definition for the StgStreamImpl class.
672  */
673 StgStreamImpl* StgStreamImpl_Construct(
674                 StorageBaseImpl* parentStorage,
675     DWORD            grfMode,
676     ULONG            ownerProperty);
677
678 void StgStreamImpl_Destroy(
679                 StgStreamImpl* This);
680
681 void StgStreamImpl_OpenBlockChain(
682                 StgStreamImpl* This);
683
684 HRESULT WINAPI StgStreamImpl_QueryInterface(
685                 IStream*      iface,
686                 REFIID         riid,            /* [in] */
687                 void**         ppvObject);  /* [iid_is][out] */
688
689 ULONG WINAPI StgStreamImpl_AddRef(
690                 IStream*      iface);
691
692 ULONG WINAPI StgStreamImpl_Release(
693                 IStream*      iface);
694
695 HRESULT WINAPI StgStreamImpl_Read(
696                 IStream*      iface,
697                 void*          pv,        /* [length_is][size_is][out] */
698                 ULONG          cb,        /* [in] */
699                 ULONG*         pcbRead);  /* [out] */
700
701 HRESULT WINAPI StgStreamImpl_Write(
702                 IStream*      iface,
703                 const void*    pv,          /* [size_is][in] */
704                 ULONG          cb,          /* [in] */
705                 ULONG*         pcbWritten); /* [out] */
706
707 HRESULT WINAPI StgStreamImpl_Seek(
708                 IStream*      iface,
709                 LARGE_INTEGER   dlibMove,         /* [in] */
710                 DWORD           dwOrigin,         /* [in] */
711                 ULARGE_INTEGER* plibNewPosition); /* [out] */
712
713 HRESULT WINAPI StgStreamImpl_SetSize(
714                 IStream*      iface,
715                 ULARGE_INTEGER  libNewSize);  /* [in] */
716
717 HRESULT WINAPI StgStreamImpl_CopyTo(
718                 IStream*      iface,
719                 IStream*      pstm,         /* [unique][in] */
720                 ULARGE_INTEGER  cb,           /* [in] */
721                 ULARGE_INTEGER* pcbRead,      /* [out] */
722                 ULARGE_INTEGER* pcbWritten);  /* [out] */
723
724 HRESULT WINAPI StgStreamImpl_Commit(
725                 IStream*      iface,
726                 DWORD           grfCommitFlags); /* [in] */
727
728 HRESULT WINAPI StgStreamImpl_Revert(
729                 IStream*  iface);
730
731 HRESULT WINAPI StgStreamImpl_LockRegion(
732                 IStream*     iface,
733                 ULARGE_INTEGER libOffset,   /* [in] */
734                 ULARGE_INTEGER cb,          /* [in] */
735                 DWORD          dwLockType); /* [in] */
736
737 HRESULT WINAPI StgStreamImpl_UnlockRegion(
738                 IStream*     iface,
739                 ULARGE_INTEGER libOffset,   /* [in] */
740                 ULARGE_INTEGER cb,          /* [in] */
741                 DWORD          dwLockType); /* [in] */
742
743 HRESULT WINAPI StgStreamImpl_Stat(
744                 IStream*     iface,
745                 STATSTG*       pstatstg,     /* [out] */
746                 DWORD          grfStatFlag); /* [in] */
747
748 HRESULT WINAPI StgStreamImpl_Clone(
749                 IStream*     iface,
750                 IStream**    ppstm);       /* [out] */
751
752
753 /********************************************************************************
754  * The StorageUtl_ functions are miscelaneous utility functions. Most of which are
755  * abstractions used to read values from file buffers without having to worry
756  * about bit order
757  */
758 void StorageUtl_ReadWord(void* buffer, ULONG offset, WORD* value);
759 void StorageUtl_WriteWord(void* buffer, ULONG offset, WORD value);
760 void StorageUtl_ReadDWord(void* buffer, ULONG offset, DWORD* value);
761 void StorageUtl_WriteDWord(void* buffer, ULONG offset, DWORD value);
762 void StorageUtl_ReadGUID(void* buffer, ULONG offset, GUID* value);
763 void StorageUtl_WriteGUID(void* buffer, ULONG offset, GUID* value);
764 void StorageUtl_CopyPropertyToSTATSTG(STATSTG*     destination,
765                                              StgProperty* source,
766                                              int          statFlags);
767
768 /****************************************************************************
769  * BlockChainStream definitions.
770  *
771  * The BlockChainStream class is a utility class that is used to create an
772  * abstraction of the big block chains in the storage file.
773  */
774 struct BlockChainStream
775 {
776   StorageImpl* parentStorage;
777   ULONG*       headOfStreamPlaceHolder;
778   ULONG        ownerPropertyIndex;
779   ULONG        lastBlockNoInSequence;
780   ULONG        lastBlockNoInSequenceIndex;
781   ULONG        tailIndex;
782   ULONG        numBlocks;
783 };
784
785 /*
786  * Methods for the BlockChainStream class.
787  */
788 BlockChainStream* BlockChainStream_Construct(
789                 StorageImpl* parentStorage,
790                 ULONG*         headOfStreamPlaceHolder,
791                 ULONG          propertyIndex);
792
793 void BlockChainStream_Destroy(
794                 BlockChainStream* This);
795
796 ULONG BlockChainStream_GetHeadOfChain(
797                 BlockChainStream* This);
798
799 BOOL BlockChainStream_ReadAt(
800                 BlockChainStream* This,
801                 ULARGE_INTEGER offset,
802                 ULONG          size,
803                 void*          buffer,
804                 ULONG*         bytesRead);
805
806 BOOL BlockChainStream_WriteAt(
807                 BlockChainStream* This,
808                 ULARGE_INTEGER offset,
809                 ULONG          size,
810                 const void*    buffer,
811                 ULONG*         bytesWritten);
812
813 BOOL BlockChainStream_SetSize(
814                 BlockChainStream* This,
815                 ULARGE_INTEGER    newSize);
816
817 ULARGE_INTEGER BlockChainStream_GetSize(
818     BlockChainStream* This);
819
820 ULONG BlockChainStream_GetCount(
821     BlockChainStream* This);
822
823 /****************************************************************************
824  * SmallBlockChainStream definitions.
825  *
826  * The SmallBlockChainStream class is a utility class that is used to create an
827  * abstraction of the small block chains in the storage file.
828  */
829 struct SmallBlockChainStream
830 {
831   StorageImpl* parentStorage;
832   ULONG          ownerPropertyIndex;
833 };
834
835 /*
836  * Methods of the SmallBlockChainStream class.
837  */
838 SmallBlockChainStream* SmallBlockChainStream_Construct(
839                StorageImpl* parentStorage,
840                ULONG          propertyIndex);
841
842 void SmallBlockChainStream_Destroy(
843                SmallBlockChainStream* This);
844
845 ULONG SmallBlockChainStream_GetHeadOfChain(
846                SmallBlockChainStream* This);
847
848 HRESULT SmallBlockChainStream_GetNextBlockInChain(
849                SmallBlockChainStream* This,
850                ULONG                  blockIndex,
851                ULONG*                 nextBlockIndex);
852
853 void SmallBlockChainStream_SetNextBlockInChain(
854          SmallBlockChainStream* This,
855          ULONG                  blockIndex,
856          ULONG                  nextBlock);
857
858 void SmallBlockChainStream_FreeBlock(
859          SmallBlockChainStream* This,
860          ULONG                  blockIndex);
861
862 ULONG SmallBlockChainStream_GetNextFreeBlock(
863          SmallBlockChainStream* This);
864
865 BOOL SmallBlockChainStream_ReadAt(
866                SmallBlockChainStream* This,
867                ULARGE_INTEGER offset,
868                ULONG          size,
869                void*          buffer,
870                ULONG*         bytesRead);
871
872 BOOL SmallBlockChainStream_WriteAt(
873                SmallBlockChainStream* This,
874                ULARGE_INTEGER offset,
875                ULONG          size,
876                const void*    buffer,
877                ULONG*         bytesWritten);
878
879 BOOL SmallBlockChainStream_SetSize(
880                SmallBlockChainStream* This,
881                ULARGE_INTEGER          newSize);
882
883 ULARGE_INTEGER SmallBlockChainStream_GetSize(
884          SmallBlockChainStream* This);
885
886 ULONG SmallBlockChainStream_GetCount(
887          SmallBlockChainStream* This);
888
889
890 #endif /* __STORAGE32_H__ */