ae7a514be010bf2a5ff99ffb526e80ea91483442
[reactos.git] / reactos / lib / 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 #define STGM_ACCESS_MODE(stgm) ((stgm)&0x0000f)
104 #define STGM_SHARE_MODE(stgm) ((stgm)&0x000f0)
105 #define STGM_CREATE_MODE(stgm) ((stgm)&0x0f000)
106
107 #define STGM_KNOWN_FLAGS (0xf0ff | \
108 STGM_TRANSACTED | STGM_CONVERT | STGM_PRIORITY | STGM_NOSCRATCH | \
109 STGM_NOSNAPSHOT | STGM_DIRECT_SWMR | STGM_DELETEONRELEASE | STGM_SIMPLE)
110
111 /*
112 * These are signatures to detect the type of Document file.
113 */
114 static const BYTE STORAGE_magic[8] ={0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1};
115 static const BYTE STORAGE_oldmagic[8] ={0xd0,0xcf,0x11,0xe0,0x0e,0x11,0xfc,0x0d};
116
117 /*
118 * Forward declarations of all the structures used by the storage
119 * module.
120 */
121 typedef struct StorageBaseImpl StorageBaseImpl;
122 typedef struct StorageImpl StorageImpl;
123 typedef struct StorageInternalImpl StorageInternalImpl;
124 typedef struct BlockChainStream BlockChainStream;
125 typedef struct SmallBlockChainStream SmallBlockChainStream;
126 typedef struct IEnumSTATSTGImpl IEnumSTATSTGImpl;
127 typedef struct StgProperty StgProperty;
128 typedef struct StgStreamImpl StgStreamImpl;
129
130 /*
131 * This utility structure is used to read/write the information in a storage
132 * property.
133 */
134 struct StgProperty
135 {
136 WCHAR name[PROPERTY_NAME_MAX_LEN];
137 WORD sizeOfNameString;
138 BYTE propertyType;
139 ULONG previousProperty;
140 ULONG nextProperty;
141 ULONG dirProperty;
142 GUID propertyUniqueID;
143 ULONG timeStampS1;
144 ULONG timeStampD1;
145 ULONG timeStampS2;
146 ULONG timeStampD2;
147 ULONG startingBlock;
148 ULARGE_INTEGER size;
149 };
150
151 /*************************************************************************
152 * Big Block File support
153 *
154 * The big block file is an abstraction of a flat file separated in
155 * same sized blocks. The implementation for the methods described in
156 * this section appear in stg_bigblockfile.c
157 */
158
159 /*
160 * Declaration of the data structures
161 */
162 typedef struct BigBlockFile BigBlockFile,*LPBIGBLOCKFILE;
163 typedef struct MappedPage MappedPage,*LPMAPPEDPAGE;
164
165 struct BigBlockFile
166 {
167 BOOL fileBased;
168 ULARGE_INTEGER filesize;
169 ULONG blocksize;
170 HANDLE hfile;
171 HANDLE hfilemap;
172 DWORD flProtect;
173 MappedPage *maplist;
174 MappedPage *victimhead, *victimtail;
175 ULONG num_victim_pages;
176 ILockBytes *pLkbyt;
177 HGLOBAL hbytearray;
178 LPVOID pbytearray;
179 };
180
181 /*
182 * Declaration of the functions used to manipulate the BigBlockFile
183 * data structure.
184 */
185 BigBlockFile* BIGBLOCKFILE_Construct(HANDLE hFile,
186 ILockBytes* pLkByt,
187 DWORD openFlags,
188 ULONG blocksize,
189 BOOL fileBased);
190 void BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This);
191 void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index);
192 void* BIGBLOCKFILE_GetROBigBlock(LPBIGBLOCKFILE This, ULONG index);
193 void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock);
194 void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize);
195 ULARGE_INTEGER BIGBLOCKFILE_GetSize(LPBIGBLOCKFILE This);
196
197 /*************************************************************************
198 * Ole Convert support
199 */
200
201 void OLECONVERT_CreateOleStream(LPSTORAGE pStorage);
202 HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName);
203
204 /****************************************************************************
205 * Storage32BaseImpl definitions.
206 *
207 * This structure defines the base information contained in all implementations
208 * of IStorage32 contained in this file storage implementation.
209 *
210 * In OOP terms, this is the base class for all the IStorage32 implementations
211 * contained in this file.
212 */
213 struct StorageBaseImpl
214 {
215 IStorageVtbl *lpVtbl; /* Needs to be the first item in the struct
216 * since we want to cast this in a Storage32 pointer */
217
218 IPropertySetStorageVtbl *pssVtbl; /* interface for adding a properties stream */
219
220 /*
221 * Reference count of this object
222 */
223 ULONG ref;
224
225 /*
226 * Ancestor storage (top level)
227 */
228 StorageImpl* ancestorStorage;
229
230 /*
231 * Index of the property for the root of
232 * this storage
233 */
234 ULONG rootPropertySetIndex;
235
236 /*
237 * virtual Destructor method.
238 */
239 void (*v_destructor)(StorageBaseImpl*);
240 };
241
242
243 /****************************************************************************
244 * Storage32Impl definitions.
245 *
246 * This implementation of the IStorage32 interface represents a root
247 * storage. Basically, a document file.
248 */
249 struct StorageImpl
250 {
251 struct StorageBaseImpl base;
252
253 /*
254 * The following data members are specific to the Storage32Impl
255 * class
256 */
257 HANDLE hFile; /* Physical support for the Docfile */
258 LPOLESTR pwcsName; /* Full path of the document file */
259
260 /* FIXME: should this be in Storage32BaseImpl ? */
261 WCHAR filename[PROPERTY_NAME_BUFFER_LEN];
262
263 /*
264 * File header
265 */
266 WORD bigBlockSizeBits;
267 WORD smallBlockSizeBits;
268 ULONG bigBlockSize;
269 ULONG smallBlockSize;
270 ULONG bigBlockDepotCount;
271 ULONG rootStartBlock;
272 ULONG smallBlockDepotStart;
273 ULONG extBigBlockDepotStart;
274 ULONG extBigBlockDepotCount;
275 ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER];
276
277 ULONG blockDepotCached[NUM_BLOCKS_PER_DEPOT_BLOCK];
278 ULONG indexBlockDepotCached;
279 ULONG prevFreeBlock;
280
281 /*
282 * Abstraction of the big block chains for the chains of the header.
283 */
284 BlockChainStream* rootBlockChain;
285 BlockChainStream* smallBlockDepotChain;
286 BlockChainStream* smallBlockRootChain;
287
288 /*
289 * Pointer to the big block file abstraction
290 */
291 BigBlockFile* bigBlockFile;
292 };
293
294 void StorageImpl_Destroy(
295 StorageBaseImpl* This);
296
297 HRESULT StorageImpl_Construct(
298 StorageImpl* This,
299 HANDLE hFile,
300 LPCOLESTR pwcsName,
301 ILockBytes* pLkbyt,
302 DWORD openFlags,
303 BOOL fileBased,
304 BOOL fileCreate);
305
306 BOOL StorageImpl_ReadBigBlock(
307 StorageImpl* This,
308 ULONG blockIndex,
309 void* buffer);
310
311 BOOL StorageImpl_WriteBigBlock(
312 StorageImpl* This,
313 ULONG blockIndex,
314 void* buffer);
315
316 void* StorageImpl_GetROBigBlock(
317 StorageImpl* This,
318 ULONG blockIndex);
319
320 void* StorageImpl_GetBigBlock(
321 StorageImpl* This,
322 ULONG blockIndex);
323
324 void StorageImpl_ReleaseBigBlock(
325 StorageImpl* This,
326 void* pBigBlock);
327
328 ULONG StorageImpl_GetNextFreeBigBlock(
329 StorageImpl* This);
330
331 void StorageImpl_FreeBigBlock(
332 StorageImpl* This,
333 ULONG blockIndex);
334
335 HRESULT StorageImpl_GetNextBlockInChain(
336 StorageImpl* This,
337 ULONG blockIndex,
338 ULONG* nextBlockIndex);
339
340 void StorageImpl_SetNextBlockInChain(
341 StorageImpl* This,
342 ULONG blockIndex,
343 ULONG nextBlock);
344
345 HRESULT StorageImpl_LoadFileHeader(
346 StorageImpl* This);
347
348 void StorageImpl_SaveFileHeader(
349 StorageImpl* This);
350
351 BOOL StorageImpl_ReadProperty(
352 StorageImpl* This,
353 ULONG index,
354 StgProperty* buffer);
355
356 BOOL StorageImpl_WriteProperty(
357 StorageImpl* This,
358 ULONG index,
359 StgProperty* buffer);
360
361 BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
362 StorageImpl* This,
363 SmallBlockChainStream** ppsbChain);
364
365 ULONG Storage32Impl_GetNextExtendedBlock(StorageImpl* This,
366 ULONG blockIndex);
367
368 void Storage32Impl_AddBlockDepot(StorageImpl* This,
369 ULONG blockIndex);
370
371 ULONG Storage32Impl_AddExtBlockDepot(StorageImpl* This);
372
373 ULONG Storage32Impl_GetExtDepotBlock(StorageImpl* This,
374 ULONG depotIndex);
375
376 void Storage32Impl_SetExtDepotBlock(StorageImpl* This,
377 ULONG depotIndex,
378 ULONG blockIndex);
379 /****************************************************************************
380 * Storage32InternalImpl definitions.
381 *
382 * Definition of the implementation structure for the IStorage32 interface.
383 * This one implements the IStorage32 interface for storage that are
384 * inside another storage.
385 */
386 struct StorageInternalImpl
387 {
388 struct StorageBaseImpl base;
389
390 /*
391 * There is no specific data for this class.
392 */
393 };
394
395 /*
396 * Method definitions for the Storage32InternalImpl class.
397 */
398 StorageInternalImpl* StorageInternalImpl_Construct(
399 StorageImpl* ancestorStorage,
400 ULONG rootTropertyIndex);
401
402 void StorageInternalImpl_Destroy(
403 StorageBaseImpl* This);
404
405 HRESULT WINAPI StorageInternalImpl_Commit(
406 IStorage* iface,
407 DWORD grfCommitFlags); /* [in] */
408
409 HRESULT WINAPI StorageInternalImpl_Revert(
410 IStorage* iface);
411
412
413 /****************************************************************************
414 * IEnumSTATSTGImpl definitions.
415 *
416 * Definition of the implementation structure for the IEnumSTATSTGImpl interface.
417 * This class allows iterating through the content of a storage and to find
418 * specific items inside it.
419 */
420 struct IEnumSTATSTGImpl
421 {
422 IEnumSTATSTGVtbl *lpVtbl; /* Needs to be the first item in the struct
423 * since we want to cast this in an IEnumSTATSTG pointer */
424
425 ULONG ref; /* Reference count */
426 StorageImpl* parentStorage; /* Reference to the parent storage */
427 ULONG firstPropertyNode; /* Index of the root of the storage to enumerate */
428
429 /*
430 * The current implementation of the IEnumSTATSTGImpl class uses a stack
431 * to walk the property sets to get the content of a storage. This stack
432 * is implemented by the following 3 data members
433 */
434 ULONG stackSize;
435 ULONG stackMaxSize;
436 ULONG* stackToVisit;
437
438 #define ENUMSTATSGT_SIZE_INCREMENT 10
439 };
440
441 IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(
442 StorageImpl* This,
443 ULONG firstPropertyNode);
444
445 void IEnumSTATSTGImpl_Destroy(
446 IEnumSTATSTGImpl* This);
447
448 void IEnumSTATSTGImpl_PushSearchNode(
449 IEnumSTATSTGImpl* This,
450 ULONG nodeToPush);
451
452 ULONG IEnumSTATSTGImpl_PopSearchNode(
453 IEnumSTATSTGImpl* This,
454 BOOL remove);
455
456 ULONG IEnumSTATSTGImpl_FindProperty(
457 IEnumSTATSTGImpl* This,
458 const OLECHAR* lpszPropName,
459 StgProperty* buffer);
460
461 INT IEnumSTATSTGImpl_FindParentProperty(
462 IEnumSTATSTGImpl *This,
463 ULONG childProperty,
464 StgProperty *currentProperty,
465 ULONG *propertyId);
466
467
468 /****************************************************************************
469 * StgStreamImpl definitions.
470 *
471 * This class imlements the IStream32 inteface and represents a stream
472 * located inside a storage object.
473 */
474 struct StgStreamImpl
475 {
476 IStreamVtbl *lpVtbl; /* Needs to be the first item in the struct
477 * since we want to cast this to an IStream pointer */
478
479 /*
480 * Reference count
481 */
482 ULONG ref;
483
484 /*
485 * Storage that is the parent(owner) of the stream
486 */
487 StorageBaseImpl* parentStorage;
488
489 /*
490 * Access mode of this stream.
491 */
492 DWORD grfMode;
493
494 /*
495 * Index of the property that owns (points to) this stream.
496 */
497 ULONG ownerProperty;
498
499 /*
500 * Helper variable that contains the size of the stream
501 */
502 ULARGE_INTEGER streamSize;
503
504 /*
505 * This is the current position of the cursor in the stream
506 */
507 ULARGE_INTEGER currentPosition;
508
509 /*
510 * The information in the stream is represented by a chain of small blocks
511 * or a chain of large blocks. Depending on the case, one of the two
512 * following variabled points to that information.
513 */
514 BlockChainStream* bigBlockChain;
515 SmallBlockChainStream* smallBlockChain;
516 };
517
518 /*
519 * Method definition for the StgStreamImpl class.
520 */
521 StgStreamImpl* StgStreamImpl_Construct(
522 StorageBaseImpl* parentStorage,
523 DWORD grfMode,
524 ULONG ownerProperty);
525
526
527 /********************************************************************************
528 * The StorageUtl_ functions are miscelaneous utility functions. Most of which are
529 * abstractions used to read values from file buffers without having to worry
530 * about bit order
531 */
532 void StorageUtl_ReadWord(const BYTE* buffer, ULONG offset, WORD* value);
533 void StorageUtl_WriteWord(BYTE* buffer, ULONG offset, WORD value);
534 void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value);
535 void StorageUtl_WriteDWord(BYTE* buffer, ULONG offset, DWORD value);
536 void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value);
537 void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value);
538 void StorageUtl_CopyPropertyToSTATSTG(STATSTG* destination,
539 StgProperty* source,
540 int statFlags);
541
542 /****************************************************************************
543 * BlockChainStream definitions.
544 *
545 * The BlockChainStream class is a utility class that is used to create an
546 * abstraction of the big block chains in the storage file.
547 */
548 struct BlockChainStream
549 {
550 StorageImpl* parentStorage;
551 ULONG* headOfStreamPlaceHolder;
552 ULONG ownerPropertyIndex;
553 ULONG lastBlockNoInSequence;
554 ULONG lastBlockNoInSequenceIndex;
555 ULONG tailIndex;
556 ULONG numBlocks;
557 };
558
559 /*
560 * Methods for the BlockChainStream class.
561 */
562 BlockChainStream* BlockChainStream_Construct(
563 StorageImpl* parentStorage,
564 ULONG* headOfStreamPlaceHolder,
565 ULONG propertyIndex);
566
567 void BlockChainStream_Destroy(
568 BlockChainStream* This);
569
570 ULONG BlockChainStream_GetHeadOfChain(
571 BlockChainStream* This);
572
573 BOOL BlockChainStream_ReadAt(
574 BlockChainStream* This,
575 ULARGE_INTEGER offset,
576 ULONG size,
577 void* buffer,
578 ULONG* bytesRead);
579
580 BOOL BlockChainStream_WriteAt(
581 BlockChainStream* This,
582 ULARGE_INTEGER offset,
583 ULONG size,
584 const void* buffer,
585 ULONG* bytesWritten);
586
587 BOOL BlockChainStream_SetSize(
588 BlockChainStream* This,
589 ULARGE_INTEGER newSize);
590
591 ULARGE_INTEGER BlockChainStream_GetSize(
592 BlockChainStream* This);
593
594 ULONG BlockChainStream_GetCount(
595 BlockChainStream* This);
596
597 /****************************************************************************
598 * SmallBlockChainStream definitions.
599 *
600 * The SmallBlockChainStream class is a utility class that is used to create an
601 * abstraction of the small block chains in the storage file.
602 */
603 struct SmallBlockChainStream
604 {
605 StorageImpl* parentStorage;
606 ULONG ownerPropertyIndex;
607 };
608
609 /*
610 * Methods of the SmallBlockChainStream class.
611 */
612 SmallBlockChainStream* SmallBlockChainStream_Construct(
613 StorageImpl* parentStorage,
614 ULONG propertyIndex);
615
616 void SmallBlockChainStream_Destroy(
617 SmallBlockChainStream* This);
618
619 ULONG SmallBlockChainStream_GetHeadOfChain(
620 SmallBlockChainStream* This);
621
622 HRESULT SmallBlockChainStream_GetNextBlockInChain(
623 SmallBlockChainStream* This,
624 ULONG blockIndex,
625 ULONG* nextBlockIndex);
626
627 void SmallBlockChainStream_SetNextBlockInChain(
628 SmallBlockChainStream* This,
629 ULONG blockIndex,
630 ULONG nextBlock);
631
632 void SmallBlockChainStream_FreeBlock(
633 SmallBlockChainStream* This,
634 ULONG blockIndex);
635
636 ULONG SmallBlockChainStream_GetNextFreeBlock(
637 SmallBlockChainStream* This);
638
639 BOOL SmallBlockChainStream_ReadAt(
640 SmallBlockChainStream* This,
641 ULARGE_INTEGER offset,
642 ULONG size,
643 void* buffer,
644 ULONG* bytesRead);
645
646 BOOL SmallBlockChainStream_WriteAt(
647 SmallBlockChainStream* This,
648 ULARGE_INTEGER offset,
649 ULONG size,
650 const void* buffer,
651 ULONG* bytesWritten);
652
653 BOOL SmallBlockChainStream_SetSize(
654 SmallBlockChainStream* This,
655 ULARGE_INTEGER newSize);
656
657 ULARGE_INTEGER SmallBlockChainStream_GetSize(
658 SmallBlockChainStream* This);
659
660 ULONG SmallBlockChainStream_GetCount(
661 SmallBlockChainStream* This);
662
663
664 #endif /* __STORAGE32_H__ */