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