1 //+-------------------------------------------------------------------------
2 //
3 // For conditions of distribution and use, see copyright notice
4 // in Flashpix.h
5 //
6 // Copyright (c) 1999 Digital Imaging Group, Inc.
7 //
8 // Contents: Header for MSF for external use
9 //
10 // Classes: CMStream - Main multi-stream object
11 //
12 //--------------------------------------------------------------------------
13
14 #ifndef __MSF_HXX__
15 #define __MSF_HXX__
16
17 #include "ref.hxx"
18 #include "error.hxx"
19
20 #define SECURE
21
22 #define msfErr(l, e) ErrJmp(msf, l, e, sc)
23 #define msfChkTo(l, e) do if (FAILED(sc = (e))) msfErr(l, sc) while(0)
24 #define msfHChkTo(l, e) do if (FAILED(sc = GetScode(e))) msfErr(l, sc) while(0)
25 #define msfChk(e) msfChkTo(Err, e)
26 #define msfHChk(e) msfHChkTo(Err, e)
27 #define msfMemTo(l, e) do if (!(e)) msfErr(l, STG_E_INSUFFICIENTMEMORY) while(0)
28 #define msfMem(e) msfMemTo(Err, e)
29
30 #if DEVL == 1
31
32 DECLARE_DEBUG(msf);
33
34 #endif
35
36 #if DBG == 1
37
38 #define msfDebugOut(x) msfInlineDebugOut x
39 #include <assert.h>
40 #define msfAssert(e) assert(e)
41 #define msfVerify(e) assert(e)
42
43 #else
44
45 #define msfDebugOut(x)
46 #define msfAssert(e)
47 #define msfVerify(e) (e)
48
49 #endif
50
51
52 // MSF entry flags type
53 typedef DWORD MSENTRYFLAGS;
54
55 // MEF_ANY refers to all entries regardless of type
56 const MSENTRYFLAGS MEF_ANY = 255;
57
58 //CWCSTREAMNAME is the maximum length (in wide characters) of
59 // a stream name.
60 const USHORT CWCSTREAMNAME = 32;
61
62 //OFFSET and SECT are used to determine positions within
63 //a file.
64 typedef SHORT OFFSET;
65 typedef ULONG SECT;
66
67 #define MAXINDEXTYPE ULONG
68
69 //FSINDEX and FSOFFSET are used to determine the position of a sector
70 //within the Fat.
71 typedef ULONG FSINDEX;
72 typedef USHORT FSOFFSET;
73
74 // DIRINDEX and DIROFFSET and used to index directory tables
75 typedef ULONG DIRINDEX;
76 typedef USHORT DIROFFSET;
77
78 //Size of a mini sector in bytes.
79 const USHORT MINISECTORSHIFT = 6;
80 const USHORT MINISECTORSIZE = 1 << MINISECTORSHIFT; //64
81
82 //Maximum size of a ministream.
83 const USHORT MINISTREAMSIZE=4096;
84
85 //Size of a single sector in bytes.
86 const USHORT SECTORSHIFT = 9;
87 const USHORT SECTORSIZE = 1 << SECTORSHIFT; //512
88 const USHORT MAXSECTORSHIFT = 16;
89
90 //Size of header.
91 const USHORT HEADERSIZE = SECTORSIZE;
92
93 //Size of single DirEntry
94 const USHORT DIRENTRYSIZE = SECTORSIZE / 4;
95
96 //
97 // Predefined Sector Indices
98 //
99
100 const SECT MAXREGSECT = 0xFFFFFFFB;
101 const SECT DIFSECT=0xFFFFFFFC;
102 const SECT FATSECT=0xFFFFFFFD;
103 const SECT ENDOFCHAIN=0xFFFFFFFE;
104 const SECT FREESECT=0xFFFFFFFF;
105
106
107 //Start of Fat chain
108 const SECT SECTFAT = 0;
109
110 //Start of directory chain
111 const SECT SECTDIR = 1;
112
113 class CDirectStream;
114 class CMSFIterator;
115 class CMSFPageTable;
116
117 class CStreamCache;
118
119 #define FLUSH_ILB TRUE
120
121 // ----------------------
122 // Byte swapping routines
123 // ----------------------
124 #include "../byteordr.hxx"
125
126 #include "dfmsp.hxx"
127 class CMStream;
128
129 #include "header.hxx"
130 #include "fat.hxx"
131 #include "dir.hxx"
132 #include "difat.hxx"
133
134 //
135 // Predefined Stream ID's
136 //
137
138 //Return code for Directory
139 //Used to signal a 'Stream Not Found' condition
140 const SID NOSTREAM=0xFFFFFFFF;
141
142 //Stream ID of FAT chain
143 const SID SIDFAT=0xFFFFFFFE;
144
145 //Stream ID of Directory chain
146 const SID SIDDIR=0xFFFFFFFD;
147
148 //SID for root level object
149 const SID SIDROOT = 0;
150
151 //SID of MiniFat
152 const SID SIDMINIFAT = 0xFFFFFFFC;
153
154 //SID of Double-indirect Fat
155 const SID SIDDIF = 0xFFFFFFFB;
156
157 //Stream ID for MiniStream chain
158 const SID SIDMINISTREAM = SIDROOT;
159
160 //SID of the largest regular (non-control) SID
161 const SID MAXREGSID = 0xFFFFFFFA;
162
163 extern "C" WCHAR const wcsContents[];
164
165 //+----------------------------------------------------------------------
166 //
167 // Class: CMStream (ms)
168 //
169 // Purpose: Main interface to multi-streams
170 //
171 // Interface: See below
172 //
173 // Notes:
174 //
175 //-----------------------------------------------------------------------
176
177 class CMStream
178 {
179 public:
180
181 CMStream( ILockBytes **pplstParent,
182 USHORT uSectorShift);
183
184 ~CMStream();
185
186 SCODE Init();
187
188 SCODE InitNew();
189
190 SCODE InitConvert();
191
192
193 void Empty(void);
194
195 inline SCODE CreateEntry( SID const sidParent,
196 CDfName const *pdfn,
197 MSENTRYFLAGS const mefFlags,
198 SID *psid);
199
200 // No implementation, currently unused, placeholder
201 void ReleaseEntry(SID const sid);
202
203 inline SCODE DestroyEntry( SID const sidParent,
204 CDfName const *pdfn);
205
206 inline SCODE KillStream( SECT sectStart, ULONG ulSize);
207
208 inline SCODE RenameEntry( SID const sidParent,
209 CDfName const *pdfn,
210 CDfName const *pdfnNew);
211
212 inline SCODE IsEntry( SID const sidParent,
213 CDfName const *pdfn,
214 SEntryBuffer *peb);
215
216 inline SCODE StatEntry( SID const sid,
217 CDfName *pName,
218 STATSTGW *pstatstg);
219
220 inline SCODE GetChild( SID const sid,
221 SID *psid);
222
223 inline SCODE FindGreaterEntry( SID sidParent,
224 CDfName const *pdfnKey,
225 SID *psid);
226
227 inline SCODE GetTime( SID const sid,
228 WHICHTIME const tt,
229 TIME_T *pnt);
230
231 inline SCODE SetTime( SID const sid,
232 WHICHTIME const tt,
233 TIME_T nt);
234
235 inline SCODE GetClass( SID const sid, CLSID *pclsid);
236
237 inline SCODE SetClass(SID const sid, REFCLSID clsid);
238
239 inline SCODE GetStateBits(SID const sd, DWORD *pgrfStateBits);
240
241 inline SCODE SetStateBits(SID const sid, DWORD grfStateBits,
242 DWORD grfMask);
243
244 inline SCODE GetEntrySize( SID const sid, ULONG *pcbSize);
245
246 SCODE GetIterator( SID const sidParent, CMSFIterator **pit);
247
248 inline SCODE SetSize();
249 inline SCODE SetMiniSize();
250
251
252 SCODE MWrite( SID sid,
253 BOOL fIsMiniStream,
254 ULONG ulOffset,
255 VOID const HUGEP *pBuffer,
256 ULONG ulCount,
257 CStreamCache *pstmc,
258 ULONG *pulRetVal);
259
260
261 SCODE GetName(SID const sid, CDfName *pdfn);
262
263 inline CMSFHeader * GetHeader() const;
264 inline CFat * GetFat() const;
265 inline CFat * GetMiniFat() const;
266 inline CDIFat * GetDIFat() const;
267 inline CDirectory * GetDir() const;
268 inline CMSFPageTable * GetPageTable() const;
269
270 inline USHORT GetSectorSize() const;
271 inline USHORT GetSectorShift() const;
272 inline USHORT GetSectorMask() const;
273
274 SCODE Flush(BOOL fFlushILB);
275
276 SCODE FlushHeader(USHORT uForce);
277
278
279 inline CDirectStream * GetMiniStream() const;
280 inline ILockBytes * GetILB() const;
281
282 inline SCODE GetSect(SID sid, SECT sect, SECT *psect);
283 SCODE GetESect(SID sid, SECT sect, SECT *psect);
284
285 SCODE SecureSect(
286 const SECT sect,
287 const ULONG ulSize,
288 const BOOL fIsMini);
289
290 private:
291
292 ILockBytes **_pplstParent;
293 CMSFHeader _hdr;
294
295 CMSFPageTable *_pmpt;
296
297 CDirectory _dir;
298 CFat _fat;
299 CDIFat _fatDif;
300 CFat _fatMini;
301
302 CDirectStream* _pdsministream;
303
304 USHORT _uSectorSize;
305 USHORT _uSectorShift;
306 USHORT _uSectorMask;
307
308 SCODE InitCommon();
309
310 SECT GetStart(SID sid) const;
311
312
313 SCODE ConvertILB(SECT sectMax);
314
315 friend SCODE DllGetScratchMultiStream( CMStream **ppms,
316 ILockBytes **pplstStream,
317 CMStream *pmsMaster);
318
319 #ifdef _MSC_VER
320 #pragma warning(disable:4512)
321 // default assignment operator could not be generated, which is fine
322 // since we are not using it.
323 #endif // _MSC_VER
324
325 };
326
327 #ifdef _MSC_VER
328 #pragma warning(default:4512)
329 #endif // _MSC_VER
330
331 //+-------------------------------------------------------------------------
332 //
333 // Method: CMStream::GetSectorSize, public
334 //
335 // Synopsis: Returns the current sector size
336 //
337 //--------------------------------------------------------------------------
338
GetSectorSize() const339 inline USHORT CMStream::GetSectorSize() const
340 {
341 return _uSectorSize;
342 }
343
344
345
346 //+-------------------------------------------------------------------------
347 //
348 // Method: CMStream::GetSectorShift, public
349 //
350 // Synopsis: Returns the current shift for sector math
351 //
352 //--------------------------------------------------------------------------
353
GetSectorShift() const354 inline USHORT CMStream::GetSectorShift() const
355 {
356 return _uSectorShift;
357 }
358
359
360 //+-------------------------------------------------------------------------
361 //
362 // Method: CMStream::GetSectorMask, public
363 //
364 // Synopsis: Returns the current mask for sector math
365 //
366 //--------------------------------------------------------------------------
367
GetSectorMask() const368 inline USHORT CMStream::GetSectorMask() const
369 {
370 return _uSectorMask;
371 }
372
373
374 //+-------------------------------------------------------------------------
375 //
376 // Method: CMStream::GetHeader, public
377 //
378 // Synopsis: Returns a pointer to the current header.
379 //
380 //--------------------------------------------------------------------------
381
GetHeader() const382 inline CMSFHeader * CMStream::GetHeader() const
383 {
384 return (CMSFHeader *)(&_hdr);
385 }
386
387
388 //+-------------------------------------------------------------------------
389 //
390 // Method: CMStream::GetFat, public
391 //
392 // Synopsis: Returns a pointer to the current Fat
393 //
394 //--------------------------------------------------------------------------
395
GetFat() const396 inline CFat * CMStream::GetFat() const
397 {
398 return (CFat *)&_fat;
399 }
400
401 //+-------------------------------------------------------------------------
402 //
403 // Member: CMStream::GetMiniFat
404 //
405 // Synopsis: Returns a pointer to the current minifat
406 //
407 //--------------------------------------------------------------------------
408
GetMiniFat() const409 inline CFat * CMStream::GetMiniFat() const
410 {
411 return (CFat *)&_fatMini;
412 }
413
414 //+-------------------------------------------------------------------------
415 //
416 // Method: CMStream::GetDIFat, public
417 //
418 // Synopsis: Returns pointer to the current Double Indirect Fat
419 //
420 //--------------------------------------------------------------------------
421
GetDIFat() const422 inline CDIFat * CMStream::GetDIFat() const
423 {
424 return (CDIFat *)&_fatDif;
425 }
426
427 //+-------------------------------------------------------------------------
428 //
429 // Member: CMStream::GetDir
430 //
431 // Synopsis: Returns a pointer to the current directory
432 //
433 //--------------------------------------------------------------------------
434
GetDir() const435 inline CDirectory * CMStream::GetDir() const
436 {
437 return (CDirectory *)&_dir;
438 }
439
440
441 //+-------------------------------------------------------------------------
442 //
443 // Member: CMStream::GetMiniStream
444 //
445 // Synopsis: Returns pointer to the current ministream
446 //
447 //--------------------------------------------------------------------------
448
GetMiniStream() const449 inline CDirectStream * CMStream::GetMiniStream() const
450 {
451 return(_pdsministream);
452 }
453
454 //+-------------------------------------------------------------------------
455 //
456 // Member: CMStream::GetILB
457 //
458 // Synopsis: Returns a pointer to the current parent ILockBytes
459 //
460 //--------------------------------------------------------------------------
461
GetILB() const462 inline ILockBytes * CMStream::GetILB() const
463 {
464 return(*_pplstParent);
465 }
466
467
468 //+-------------------------------------------------------------------------
469 //
470 // Member: CMStream::GetPageTable
471 //
472 // Synopsis: Returns a pointer to the current page table
473 //
474 //--------------------------------------------------------------------------
475
GetPageTable() const476 inline CMSFPageTable * CMStream::GetPageTable() const
477 {
478 return _pmpt;
479 }
480
481 //+-------------------------------------------------------------------------
482 //
483 // Method: CMStream::StatEntry
484 //
485 // Synopsis: For a given handle, fill in the Multistream specific
486 // information of a STATSTG.
487 //
488 // Arguments: [sid] -- SID that information is requested on.
489 // [pName] -- Name of entry to fill in (if not null)
490 // [pstatstg] -- STATSTG to fill in (if not null)
491 //
492 // Returns: S_OK
493 //
494 //--------------------------------------------------------------------------
495
StatEntry(SID const sid,CDfName * pName,STATSTGW * pstatstg)496 inline SCODE CMStream::StatEntry(SID const sid,
497 CDfName *pName,
498 STATSTGW *pstatstg)
499 {
500 return _dir.StatEntry(sid, pName, pstatstg);
501 }
502
503
504 //+-------------------------------------------------------------------------
505 //
506 // Member: CMStream::GetChild, public
507 //
508 // Synposis: Return the child SID for a directory entry
509 //
510 // Arguments: [sid] - Parent
511 // [psid] - Child SID return
512 //
513 // Returns: Appropriate status code
514 //
515 //---------------------------------------------------------------------------
516
GetChild(SID const sid,SID * psid)517 inline SCODE CMStream::GetChild(
518 SID const sid,
519 SID *psid)
520 {
521 return _dir.GetChild(sid, psid);
522 }
523
524 //+---------------------------------------------------------------------------
525 //
526 // Member: CMStream::FindGreaterEntry, public
527 //
528 // Synopsis: Returns the next greater entry for the given parent SID
529 //
530 // Arguments: [sidParent] - SID of parent storage
531 // [CDfName *pdfnKey] - Previous key
532 // [psid] - Result
533 //
534 // Returns: Appropriate status code
535 //
536 // Modifies: [psid]
537 //
538 //----------------------------------------------------------------------------
539
FindGreaterEntry(SID sidParent,CDfName const * pdfnKey,SID * psid)540 inline SCODE CMStream::FindGreaterEntry(SID sidParent,
541 CDfName const *pdfnKey,
542 SID *psid)
543 {
544 return _dir.FindGreaterEntry(sidParent, pdfnKey, psid);
545 }
546
547
548 extern SCODE DllMultiStreamFromStream(
549 CMStream **ppms,
550 ILockBytes **pplstStream,
551 DWORD dwFlags);
552
553 extern SCODE DllMultiStreamFromCorruptedStream(
554 CMStream **ppms,
555 ILockBytes **pplstStream,
556 DWORD dwFlags);
557
558 extern void DllReleaseMultiStream(CMStream *pms);
559
560
561 extern SCODE DllIsMultiStream(ILockBytes *plstStream);
562
563 extern SCODE DllGetCommitSig(ILockBytes *plst, DFSIGNATURE *psig);
564
565 extern SCODE DllSetCommitSig(ILockBytes *plst, DFSIGNATURE sig);
566
567 #if DEVL == 1
568 extern VOID SetInfoLevel(ULONG x);
569 #endif
570
571 #endif //__MSF_HXX__
572