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