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