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:   Directory header for Mstream project
9 //
10 //  Classes:    CDirEntry - Information on a single stream
11 //              CDirSect - Sector sized array of DirEntry
12 //              CDirVector - Resizable array of CDirSect
13 //              CDirectory - Grouping of DirSectors
14 //
15 //  Notes:      Properties and storage elements are kept in the same
16 //              child list so the *ChildProp functions are unused.  1/18/93
17 //
18 //--------------------------------------------------------------------
19 
20 
21 
22 
23 #include "msf.hxx"
24 #include "owchar.h"
25 #include "vect.hxx"
26 
27 
28 #ifndef __DIR_HXX__
29 #define __DIR_HXX__
30 
31 
32 #define DIR_HIT 0x01
33 
34 
35 struct SPreDirEntry
36 {
37 protected:
38     CDfName _dfn;   //  Name (word-aligned)
39     BYTE  _mse;   //  STGTY_...
40     BYTE  _bflags;
41 
42     SID   _sidLeftSib;  //  Siblings
43     SID   _sidRightSib; //  Siblings
44 
45     SID   _sidChild;  //  Storage - Child list
46     GUID  _clsId;   //  Storage - Class id
47     DWORD _dwUserFlags; //  Storage - User flags
48     TIME_T  _time[2]; //  Storage - time stamps
49 
50     SECT  _sectStart; //  Stream - start
51     ULONG _ulSize;  //  Stream - size
52 
53     //DFPROPTYPE  _dptPropType; //  Property - type
54 };
55 
56 
57 #define STGTY_INVALID 0
58 #define STGTY_ROOT 5
59 
60 // Macros which tell whether a direntry has stream fields,
61 // storage fields or property fields
62 #define STREAMLIKE(mse) \
63     (((mse) & STGTY_REAL) == STGTY_STREAM || (mse) == STGTY_ROOT)
64 #define STORAGELIKE(mse) \
65     (((mse) & STGTY_REAL) == STGTY_STORAGE || (mse) == STGTY_ROOT)
66 
67 //+----------------------------------------------------------------------
68 //
69 //      Class:      CDirEntry (de)
70 //
71 //      Purpose:    Holds information on one stream
72 //
73 //      Interface:  GetName - returns name of stream
74 //                  GetStart - return first sector for stream
75 //                  GetSize - returns size of stream
76 //                  GetFlags - returns flag byte
77 //
78 //                  SetName - sets name
79 //                  SetStart - sets first sector
80 //                  SetSize - sets size
81 //                  SetFlags - sets flag byte
82 //
83 //                  IsFree - returns 1 if element is not in use
84 //                  IsEntry - returns 1 is element name matches argument
85 //
86 //      Notes:      B-flat,C-sharp
87 //
88 //-----------------------------------------------------------------------
89 const unsigned int CBDIRPAD = (unsigned int)DIRENTRYSIZE - (unsigned int)sizeof(SPreDirEntry);
90 
91 //  DirEntry bit flags are used for the following private state
92 
93 //  Usage   Bit
94 
95 #define DECOLORBIT  0x01
96 #define DERESERVED  0xfe
97 
98 typedef enum
99 {
100     DE_RED = 0,
101     DE_BLACK = 1
102 } DECOLOR;
103 
104 class CDirEntry: private SPreDirEntry
105 {
106 
107 public:
108      CDirEntry();
109 
110     inline void  Init(MSENTRYFLAGS mse);
111 
112     inline CDfName const *  GetName() const;
113     inline SECT  GetStart() const;
114     inline ULONG  GetSize() const;
115     inline SID  GetLeftSib() const;
116     inline SID  GetRightSib() const;
117     inline SID  GetChild() const;
118     inline MSENTRYFLAGS  GetFlags() const;
119     inline DECOLOR  GetColor() const;
120     inline TIME_T  GetTime(WHICHTIME tt) const;
121     inline GUID  GetClassId() const;
122     inline DWORD  GetUserFlags() const;
123 
124     inline void  SetName(const CDfName *pdfn);
125     inline void  SetStart(const SECT);
126     inline void  SetSize(const ULONG);
127     inline void  SetLeftSib(const SID);
128     inline void  SetRightSib(const SID);
129     inline void  SetChild(const SID);
130     inline void  SetFlags(const MSENTRYFLAGS mse);
131     inline void  SetColor(DECOLOR);
132     inline void  SetTime(WHICHTIME tt, TIME_T nt);
133     inline void  SetClassId(GUID cls);
134     inline void  SetUserFlags(DWORD dwUserFlags, DWORD dwMask);
135 
136     inline BOOL  IsFree() const;
137     inline BOOL  IsEntry(CDfName const *pdfn) const;
138     inline void  ByteSwap(void);
139 
140 private:
141     inline BYTE  GetBitFlags() const;
142     inline void  SetBitFlags(BYTE bValue, BYTE bMask);
143 
144     BYTE  _bpad[CBDIRPAD]	// do not remove, bad things will happen!
145 #ifdef __clang__
146 	__unused
147 #endif
148 	;
149 };
150 
151 //+-------------------------------------------------------------------------
152 //
153 //  Class:      CDirSect (ds)
154 //
155 //  Purpose:    Provide sector sized block of DirEntries
156 //
157 //  Interface:
158 //
159 //  Notes:
160 //
161 //--------------------------------------------------------------------------
162 
163 
164 class CDirSect
165 {
166 public:
167     SCODE  Init(USHORT cbSector);
168 
169     inline CDirEntry*  GetEntry(DIROFFSET iEntry);
170     inline void ByteSwap(USHORT cbSector);
171 
172 private:
173      // GetEntries() relies on the fact, there are no data
174      // fields in the class...
175      inline CDirEntry* GetEntries(void) const;
176 };
177 
GetEntries(void) const178 inline CDirEntry * CDirSect::GetEntries(void) const
179 {
180 	return (CDirEntry *)this;
181 }
182 
183 //+-------------------------------------------------------------------------
184 //
185 //  Class:      CDirVector (dv)
186 //
187 //  Purpose:    Provide resizable array of DirSectors.
188 //
189 //  Interface:
190 //
191 //  Notes:
192 //
193 //--------------------------------------------------------------------------
194 
195 class CDirVector: public CPagedVector
196 {
197 public:
198     inline  CDirVector(USHORT cbSector);
~CDirVector()199     inline  ~CDirVector() {}
200 
201     inline SCODE  GetTable(
202             const DIRINDEX iTable,
203             const DWORD dwFlags,
204             CDirSect **ppds);
GetSectorSize(void) const205     inline USHORT  GetSectorSize(void) const
206     { return _cbSector; }
207 
208 private:
209     const USHORT _cbSector;
210 #ifdef _MSC_VER
211 #pragma warning(disable:4512)
212 // since there is a const member, there should be no assignment operator
213 #endif // _MSC_VER
214 };
215 #ifdef _MSC_VER
216 #pragma warning(default:4512)
217 // since there is a const member, there should be no assignment operator
218 #endif // _MSC_VER
219 
220 //+----------------------------------------------------------------------
221 //
222 //      Class:      CDirectory (dir)
223 //
224 //      Purpose:    Main interface for directory functionality
225 //
226 //      Interface:  GetFree - returns an SID for a free DirEntry
227 //                  Find - finds its argument in the directory list
228 //                  SetEntry - sets up a DirEntry and writes out its sector
229 //                  GetName - returns the name of a DirEntry
230 //                  GetStart - returns the start sector of a DirEntry
231 //                  GetSize - returns the size of a DirEntry
232 //                  GetFlags - returns the flag byte of a DirEntry
233 //
234 //
235 //      Notes:
236 //
237 //-----------------------------------------------------------------------
238 
239 typedef enum DIRENTRYOP
240 {
241   DEOP_FIND = 0,
242         DEOP_REMOVE = 1
243 } DIRENTRYOP;
244 
245 class CDirectory
246 {
247 public:
248     CDirectory(USHORT cbSector);
~CDirectory()249     ~CDirectory() {}
250 
251     VOID  Empty();
252 
253 
254     SCODE  Init(CMStream *pmsParent, DIRINDEX cSect);
255 
256 
257     SCODE  InitNew(CMStream *pmsParent);
258 
259     SCODE  FindGreaterEntry(
260       SID sidChildRoot,
261             CDfName const *pdfn,
262             SID *psidResult);
263 
264     SCODE  SetStart(const SID sid, const SECT sect);
265     SCODE  SetTime(const SID sid, WHICHTIME tt, TIME_T nt);
266     SCODE  SetChild(const SID sid, const SID sidChild);
267     SCODE  SetSize(const SID sid, const ULONG cbSize);
268     SCODE  SetClassId(const SID sid, const GUID cls);
269     SCODE  SetFlags(const SID sid, const MSENTRYFLAGS mse);
270     SCODE  SetUserFlags(const SID sid,
271                                 DWORD dwUserFlags,
272                                 DWORD dwMask);
273 
274     inline SCODE  GetName(const SID sid, CDfName *pdfn);
275     inline SCODE  GetStart(const SID sid, SECT * psect);
276     inline SCODE  GetSize(const SID sid, ULONG *pulSize);
277 
278     SCODE  GetChild(const SID sid, SID *psid);
279     inline SCODE  GetFlags(const SID sid, MSENTRYFLAGS *pmse);
280     inline SCODE  GetClassId(const SID sid, GUID *pcls);
281     inline SCODE  GetTime(const SID sid, WHICHTIME tt, TIME_T *ptime);
282     inline SCODE  GetUserFlags(const SID sid, DWORD *pdwUserFlags);
283 
284     SCODE  GetDirEntry(
285             const SID sid,
286             const DWORD dwFlags,
287             CDirEntry **ppde);
288 
289     void  ReleaseEntry(SID sid);
290 
291     SCODE  CreateEntry(
292             SID sidParent,
293             CDfName const *pdfn,
294             MSENTRYFLAGS mef,
295             SID *psidNew);
296 
297     SCODE  RenameEntry(
298             SID const sidParent,
299             CDfName const *pdfn,
300             CDfName const *pdfnNew);
301 
302     inline SCODE  IsEntry(
303             SID const sidParent,
304             CDfName const *pdfn,
305             SEntryBuffer *peb);
306 
307     SCODE  DestroyAllChildren(
308       SID const sidParent);
309 
310     SCODE  DestroyChild(
311       SID const sidParent,
312             CDfName const *pdfn);
313 
314     SCODE  StatEntry(SID const sid,
315                              CDfName *pNextKey,
316                              STATSTGW *pstatstg);
317 
318     inline SCODE  Flush();
319 
320     inline void  SetParent(CMStream * pmsParent);
321 
322 private:
323 
324     CDirVector _dv;
325     DIRINDEX _cdsTable;
326     CMStream * _pmsParent;
327     DIROFFSET _cdeEntries;
328 
329     SID _sidFirstFree;
330 
331     SCODE  Resize(DIRINDEX);
332     inline DIRINDEX  SidToTable(SID sid) const;
333     inline SID  PairToSid(
334             DIRINDEX iTable,
335             DIROFFSET iEntry) const;
336 
337     inline SCODE  SidToPair(
338             SID sid,
339             DIRINDEX* pipds,
340             DIROFFSET* pide) const;
341 
342 
343     SCODE  GetFree(SID * psid);
344 
345     SCODE  InsertEntry(
346       SID sidParent,
347             SID sidInsert,
348             CDfName const *pdfnInsert);
349 
350     SCODE  FindEntry(
351       SID sidParent,
352             CDfName const *pdfnFind,
353             DIRENTRYOP deop,
354             SEntryBuffer *peb);
355 
356     static int  NameCompare(
357       CDfName const *pdfn1,
358             CDfName const *pdfn2);
359 
360     SCODE SplitEntry(
361   CDfName const *pdfn,
362         SID sidTree,
363         SID sidGreat,
364         SID sidGrand,
365         SID sidParent,
366         SID sidChild,
367         SID *psid);
368 
369     SCODE RotateEntry(
370   CDfName const *pdfn,
371         SID sidTree,
372         SID sidParent,
373         SID *psid);
374 
375     SCODE  SetColorBlack(const SID sid);
376 #ifdef _MSC_VER
377 #pragma warning(disable:4512)
378 // since there is a const member, there should be no assignment operator
379 #endif // _MSC_VER
380 };
381 #ifdef _MSC_VER
382 #pragma warning(default:4512)
383 #endif // _MSC_VER
384 
385 #endif //__DIR_HXX__
386