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:   DocFile and MultiStream shared private definitions
9 //
10 //---------------------------------------------------------------
11 
12 #ifndef __DFMSP_HXX__
13 #define __DFMSP_HXX__
14 
15 #include "ref.hxx"
16 #include "ole.hxx"
17 #include "msf.hxx"
18 #include "owchar.h"
19 #include <memory.h>
20 #include <string.h>
21 #include "../time.hxx"
22 
23 // Target-dependent things
24 
25 //
26 //      x86 16-bit build optimizations
27 //
28 //      Some function parameters are always stack based pointers,
29 //      so we can let the compiler use near addressing via ss by
30 //      declaring the parameter stack based.
31 //
32 
33 #define STACKBASED
34 
35 //
36 //      x86 16-bit retail build optimizations
37 //
38 //      For the retail build, we group the code segments,
39 //      allowing us to make many calls near.
40 //
41 
42 // Segmented memory model definitions
43 #define HUGEP
44 
45 #ifndef LISet32
46 #define LISet32(li, v) \
47     ((li).HighPart = ((LONG)(v)) < 0 ? -1 : 0, (li).LowPart = (v))
48 #endif
49 #ifndef ULISet32
50 #define ULISet32(li, v) ((li).HighPart = 0, (li).LowPart = (v))
51 #endif
52 #define LISetLow(li, v) ((li).LowPart = (v))
53 #define LISetHigh(li, v) ((li).HighPart = (v))
54 #define ULISetLow(li, v) ((li).LowPart = (v))
55 #define ULISetHigh(li, v) ((li).HighPart = (v))
56 #define LIGetLow(li) ((li).LowPart)
57 #define LIGetHigh(li) ((li).HighPart)
58 #define ULIGetLow(li) ((li).LowPart)
59 #define ULIGetHigh(li) ((li).HighPart)
60 
61 // Fast safe increment/decrement
62 #define AtomicInc(lp) (++*(lp))
63 #define AtomicDec(lp) (--*(lp))
64 
65 
66 // Switchable ANSI/Unicode support
67 // Conversion routines assume null termination before max characters
68 
69 //----------------------------------------------------------------------------
70 
71 // The name of this function might change, so encapsulate it
72 #define DfGetScode(hr) GetScode(hr)
73 
74 //
75 // These function now just check for NULL values or are disabled
76 // -- system dependent
77 //
78 // We leave these functions in so that it is a good place to verify memory,
79 // if they can be implemented.
80 //
81 #define ValidateNotNull(x)  \
82     ((x) ? S_OK : STG_E_INVALIDPOINTER)
83 
84 #define ValidateBuffer(pv, n) \
85     ValidateNotNull(pv)
86 
87 #define ValidatePtrBuffer(pv) \
88     ValidateNotNull(pv)
89 
90 #define ValidateHugeBuffer(pv, n) \
91     ValidateNotNull(pv)
92 
93 #define ValidateOutBuffer(pv, n) \
94     ValidateNotNull(pv)
95 
96 #define ValidateOutPtrBuffer(pv) \
97     ValidateNotNull(pv)
98 
99 #define ValidateHugeOutBuffer(pv, n) \
100     ValidateNotNull(pv)
101 
102 #define ValidateIid(riid) S_OK   // disabled
103 
104 #define ValidateInterface(punk,riid) \
105     ValidateNotNull(punk)
106 
107 #define ValidateWcs(pwcs, cwcMax) \
108     ValdateNotNull(pwcs)
109 
110 #define ValidateSz(psz, cchMax) S_OK \
111     ValidateNotNull(psz)
112 
113 #define ValidateNameW(pwcs, cchMax) \
114     ((pwcs)?(S_OK):(STG_E_INVALIDNAME))
115 
116 #define ValidateNameA(psz, cchMax) \
117     ((psz)?(S_OK):(STG_E_INVALIDNAME))
118 
119 // Enumeration for Get/SetTime
120 enum WHICHTIME
121 {
122     WT_CREATION=0,
123     WT_MODIFICATION,
124     WT_ACCESS
125 };
126 
127 // Signature for transactioning
128 typedef DWORD DFSIGNATURE;
129 #define DF_INVALIDSIGNATURE ((DFSIGNATURE)-1)
130 
131 // Convenience macros for signature creation
132 #define LONGSIG(c1, c2, c3, c4) \
133 (((ULONG) (BYTE) (c1)) | \
134  (((ULONG) (BYTE) (c2)) << 8) | \
135  (((ULONG) (BYTE) (c3)) << 16) | \
136  (((ULONG) (BYTE) (c4)) << 24))
137 
138 #define DfAllocWC(cwc, ppwcs) (*ppwcs = new WCHAR[cwc], \
139         (*ppwcs != NULL) ? S_OK: STG_E_INSUFFICIENTMEMORY)
140 
141 #define DfAllocWCS(pwcs, ppwcs) DfAllocWC(wcslen(pwcs)+1, ppwcs)
142 
143 // Docfile locally unique identity
144 // Every entry in a multistream has a LUID generated and stored for it
145 typedef DWORD DFLUID;
146 #define DF_NOLUID 0
147 
148 typedef WCHAR **SNBW;
149 
150 #ifndef _UNICODE
151 typedef struct
152 {
153     WCHAR *pwcsName;
154     DWORD type;
155     ULARGE_INTEGER cbSize;
156     FILETIME mtime;
157     FILETIME ctime;
158     FILETIME atime;
159     DWORD grfMode;
160     DWORD grfLocksSupported;
161     CLSID clsid;
162     DWORD grfStateBits;
163     DWORD reserved;
164 } STATSTGW;
165 #else  // if _UNICODE
166 typedef STATSTG STATSTGW;
167 #endif // ! _UNICODE
168 
169 #define TSTDMETHODIMP SCODE
170 #define TSTDAPI(name) SCODE name##W
171 
172 #define CBSTORAGENAME (CWCSTORAGENAME*sizeof(WCHAR))
173 
174 // A Unicode case-insensitive compare
175 // No such thing really exists so we use our own
176 #define dfwcsnicmp(wcsa, wcsb, len) wcsnicmp(wcsa, wcsb, len)
177 
178 
179 // A name for a docfile element
180 class CDfName
181 {
182 private:
183     BYTE _ab[CBSTORAGENAME];
184     WORD _cb;
185 
186 public:
CDfName(void)187     CDfName(void)               { _cb = 0; }
188 
Set(WORD const cb,BYTE const * pb)189     void Set(WORD const cb, BYTE const *pb)
190     {
191   _cb = cb;
192   if (pb)
193       memcpy(_ab, pb, cb);
194     }
Set(WCHAR const * pwcs)195     void Set(WCHAR const *pwcs)
196     {
197         Set( (WORD) ((wcslen(pwcs)+1)*sizeof(WCHAR)), (BYTE const *)pwcs);
198     }
199 
200     // Special method for names with prepended character
Set(WCHAR const wcLead,WCHAR const * pwcs)201     void Set(WCHAR const wcLead, WCHAR const *pwcs)
202     {
203         olAssert((wcslen(pwcs)+2)*sizeof(WCHAR) < CBSTORAGENAME);
204         _cb = (USHORT) ((wcslen(pwcs)+2)*sizeof(WCHAR));
205         *(WCHAR *)_ab = wcLead;
206         wcscpy((WCHAR *)_ab+1, pwcs);
207     }
208 
209     inline void Set(CDfName const *pdfn);
210 
CDfName(WORD const cb,BYTE const * pb)211     CDfName(WORD const cb, BYTE const *pb)      { Set(cb, pb); }
CDfName(WCHAR const * pwcs)212     CDfName(WCHAR const *pwcs)  { Set(pwcs); }
213 //    CDfName(char const *psz)    { Set(psz); }
214 
GetLength(void) const215     WORD GetLength(void) const  { return _cb; }
GetBuffer(void) const216     BYTE *GetBuffer(void) const { return (BYTE *) _ab; }
217 
IsEqual(CDfName const * dfn) const218     BOOL IsEqual(CDfName const *dfn) const
219     {
220   // This assumes that all DfNames are actually Unicode strings
221   return _cb == dfn->_cb &&
222       dfwcsnicmp((WCHAR *)_ab, (WCHAR *)dfn->GetBuffer(), _cb) == 0;
223     }
224 
225     inline void ByteSwap(void);
226 };
227 
Set(CDfName const * pdfn)228 inline void CDfName::Set(CDfName const *pdfn)
229 {
230     Set(pdfn->GetLength(), pdfn->GetBuffer());
231 }
232 
ByteSwap(void)233 inline void CDfName::ByteSwap(void)
234 {
235     // assume all names are wide characters, we swap each word
236     WCHAR *awName = (WCHAR*) _ab;
237     ::ByteSwap(&_cb);
238     for (unsigned int i=0; i<CBSTORAGENAME/sizeof(WCHAR); i++)
239     {
240         ::ByteSwap(awName);
241         awName++;
242     }
243 }
244 
245 // Fast, fixed space iterator structure
246 struct SIterBuffer
247 {
248     CDfName dfnName;
249     DWORD type;
250 };
251 
252 //SID is a Stream Identifier
253 typedef ULONG SID;
254 
255 // IsEntry entry information
256 struct SEntryBuffer
257 {
258     DFLUID luid;
259     DWORD  dwType;
260     SID    sid;
261 };
262 
263 // Destroy flags
264 #define DESTROY_FROM_HANDLE     0
265 #define DESTROY_FROM_ENTRY      1
266 #define DESTROY_FROM            0x01
267 #define DESTROY_SELF            0x40
268 #define DESTROY_RECURSIVE       0x80
269 
270 #define DESTROY_HANDLE          (DESTROY_FROM_HANDLE | DESTROY_SELF)
271 #define DESTROY_ENTRY           (DESTROY_FROM_ENTRY | DESTROY_SELF)
272 
273 // Root startup flags
274 #define RSF_OPEN                0x00
275 #define RSF_CONVERT             0x01
276 #define RSF_TRUNCATE            0x02
277 #define RSF_CREATE              0x04
278 #define RSF_DELAY               0x08
279 #define RSF_DELETEONRELEASE     0x10
280 #define RSF_OPENCREATE          0x20
281 #define RSF_RESERVE_HANDLE      0x40
282 
283 #define RSF_CREATEFLAGS (RSF_CREATE | RSF_TRUNCATE | RSF_OPENCREATE)
284 
285 // Stream copy buffer size
286 ULONG const STREAMBUFFERSIZE = 8192;
287 
288 // ILockBytes copy buffer size
289 ULONG const LOCKBYTESBUFFERSIZE = 16384;
290 
291 // Docfile flags for permissions and other information kept
292 // on streams and docfiles
293 typedef WORD DFLAGS;
294 
295 #define DF_TRANSACTEDSELF       0x0001
296 
297 #define DF_TRANSACTED           0x0002
298 #define DF_DIRECT               0x0000
299 
300 #define DF_INDEPENDENT          0x0004
301 #define DF_DEPENDENT            0x0000
302 
303 #define DF_COMMIT               0x0008
304 #define DF_ABORT                0x0000
305 
306 #define DF_INVALID              0x0010
307 
308 #define DF_REVERTED             0x0020
309 #define DF_NOTREVERTED          0x0000
310 
311 #define DF_READ                 0x0040
312 #define DF_WRITE                0x0080
313 #define DF_READWRITE            (DF_READ | DF_WRITE)
314 
315 #define DF_DENYREAD             0x0100
316 #define DF_DENYWRITE            0x0200
317 #define DF_DENYALL              (DF_DENYREAD | DF_DENYWRITE)
318 
319 #define DF_PRIORITY             0x0400
320 #define DF_CREATE               0x0800
321 #define DF_CACHE                0x1000
322 #define DF_NOUPDATE             0x2000
323 
324 // Shift required to translate from DF_READWRITE to DF_DENYALL
325 #define DF_DENIALSHIFT          2
326 
327 // Permission abstraction macros
328 // These only work with DF_* flags
329 #define P_READ(f)       ((f) & DF_READ)
330 #define P_WRITE(f)      ((f) & DF_WRITE)
331 #define P_READWRITE(f)  (((f) & (DF_READ | DF_WRITE)) == (DF_READ | DF_WRITE))
332 #define P_DENYREAD(f)   ((f) & DF_DENYREAD)
333 #define P_DENYWRITE(f)  ((f) & DF_DENYWRITE)
334 #define P_DENYALL(f)    (((f) & (DF_DENYREAD | DF_DENYWRITE)) == \
335        (DF_DENYREAD | DF_DENYWRITE))
336 #define P_PRIORITY(f)   ((f) & DF_PRIORITY)
337 #define P_TRANSACTED(f) ((f) & DF_TRANSACTED)
338 #define P_DIRECT(f)     (!P_TRANSACTED(f))
339 #define P_INDEPENDENT(f) ((f) & DF_INDEPENDENT)
340 #define P_DEPENDENT(f)  (!P_INDEPENDENT(f))
341 #define P_TSELF(f)      ((f) & DF_TRANSACTEDSELF)
342 #define P_INVALID(f)    ((f) & DF_INVALID)
343 #define P_REVERTED(f)   ((f) & DF_REVERTED)
344 #define P_COMMIT(f)     ((f) & DF_COMMIT)
345 #define P_ABORT(f)      (!P_COMMIT(f))
346 #define P_CREATE(f)     ((f) & DF_CREATE)
347 #define P_CACHE(f)      ((f) & DF_CACHE)
348 #define P_NOUPDATE(f)   ((f) & DF_NOUPDATE)
349 
350 // Translation functions
351 DFLAGS ModeToDFlags(DWORD const dwModeFlags);
352 DWORD DFlagsToMode(DFLAGS const df);
353 
354 // Flags for what state has been dirtied
355 #define DIRTY_CREATETIME  0x0001
356 #define DIRTY_MODIFYTIME  0x0002
357 #define DIRTY_ACCESSTIME  0x0004
358 #define DIRTY_CLASS       0x0008
359 #define DIRTY_STATEBITS   0x0010
360 
361 // Allow text in asserts
362 #define aMsg(s) (s)
363 
364 #define STGTY_REAL (STGTY_STORAGE | STGTY_STREAM | STGTY_LOCKBYTES)
365 
366 #define REAL_STGTY(f) (f)
367 
368 extern void *DfMemAlloc(DWORD dwFlags, size_t size);
369 extern void DfMemFree(void *mem);
370 
371 extern void *TaskMemAlloc(size_t size);
372 extern void TaskMemFree(void *mem);
373 
374 // Buffer management
375 #define CB_LARGEBUFFER 32768
376 #define CB_PAGEBUFFER 4096
377 #define CB_SMALLBUFFER 512
378 
379 extern SCODE GetBuffer(USHORT cbMin, USHORT cbMax, BYTE **ppb,
380                        USHORT *pcbActual);
381 extern void GetSafeBuffer(USHORT cbMin, USHORT cbMax, BYTE **ppb,
382                           USHORT *pcbActual);
383 extern void FreeBuffer(BYTE *pb);
384 
385 #endif // #ifndef __DFMSP_HXX__
386