1 //+--------------------------------------------------------------------------
2 //
3 //  For conditions of distribution and use, see copyright notice
4 //  in Flashpix.h
5 //
6 //  Copyright (c) 1999 Digital Imaging Group
7 //
8 // Contents:    various macros used in property set code
9 //
10 //---------------------------------------------------------------------------
11 
12 #ifndef _PROPMAC_HXX_
13 #define _PROPMAC_HXX_
14 
15 #include "../../byteordr.hxx"
16 
17 #define Prop_wcslen wcslen
18 #define Prop_wcsnicmp _wcsnicmp
19 #define Prop_wcscmp wcscmp
20 #define Prop_wcscpy wcscpy
21 
22 //+---------------------------------------------------------------------------
23 // Function:    Add2Ptr
24 //
25 // Synopsis:    Add an unscaled increment to a ptr regardless of type.
26 //
27 // Arguments:   [pv]    -- Initial ptr.
28 //              [cb]    -- Increment
29 //
30 // Returns:     Incremented ptr.
31 //
32 //----------------------------------------------------------------------------
33 
34 inline VOID *
Add2Ptr(VOID const * pv,ULONG cb)35 Add2Ptr(VOID const *pv, ULONG cb)
36 {
37     return((BYTE *) pv + cb);
38 }
39 
40 
41 //+---------------------------------------------------------------------------
42 // Function:    Add2ConstPtr
43 //
44 // Synopsis:    Add an unscaled increment to a ptr regardless of type.
45 //
46 // Arguments:   [pv]    -- Initial ptr.
47 //              [cb]    -- Increment
48 //
49 // Returns:     Incremented ptr.
50 //
51 //----------------------------------------------------------------------------
52 
53 inline
54 const VOID *
Add2ConstPtr(const VOID * pv,ULONG cb)55 Add2ConstPtr(const VOID *pv, ULONG cb)
56 {
57     return((const BYTE *) pv + cb);
58 }
59 
60 
61 //+--------------------------------------------------------------------------
62 // Function:    CopyFileTime, private
63 //
64 // Synopsis:    Copy LARGE_INTEGER time to FILETIME structure
65 //
66 // Arguments:   [pft] -- pointer to FILETIME
67 //              [pli] -- pointer to LARGE_INTEGER
68 //
69 // Returns:     Nothing
70 //---------------------------------------------------------------------------
71 
72 __inline VOID
CopyFileTime(OUT FILETIME * pft,IN LARGE_INTEGER * pli)73 CopyFileTime(OUT FILETIME *pft, IN LARGE_INTEGER *pli)
74 {
75     pft->dwLowDateTime = pli->LowPart;
76     pft->dwHighDateTime = pli->HighPart;
77 }
78 
79 
80 //+--------------------------------------------------------------------------
81 // Function:    ZeroFileTime, private
82 //
83 // Synopsis:    Zero FILETIME structure
84 //
85 // Arguments:   [pft] -- pointer to FILETIME
86 //
87 // Returns:     Nothing
88 //---------------------------------------------------------------------------
89 
90 __inline VOID
ZeroFileTime(OUT FILETIME * pft)91 ZeroFileTime(OUT FILETIME *pft)
92 {
93     pft->dwLowDateTime = pft->dwHighDateTime = 0;
94 }
95 
96 
97 #define DwordAlign(n)     (((n) + sizeof(ULONG) - 1) & ~(sizeof(ULONG) - 1))
98 #define DwordRemain(cb)   ((sizeof(ULONG) - ((cb) % sizeof(ULONG))) % sizeof(ULONG))
99 
100 #define QuadAlign(n)  (((n) + sizeof(LONGLONG) - 1) & ~(sizeof(LONGLONG) - 1))
101 
102 #include "propapi.h"
103 
104 #if DBG
105 extern "C" LONG ExceptionFilter(struct _EXCEPTION_POINTERS *pep);
106 #else // DBG
107 #define ExceptionFilter(pep)    EXCEPTION_EXECUTE_HANDLER
108 #endif // DBG
109 
110 extern "C" UNICODECALLOUTS UnicodeCallouts;
111 
112 
113 // The CMemSerStream and CDeMemSerStream have different requirements for
114 // handling buffer overflow conditions. In the case of the driver this
115 // is indicative of a corrupted stream and we would like to raise an
116 // exception. On the other hand in Query implementation we deal with
117 // streams whose sizes are precomputed in the user mode. Therefore we
118 // do not wish to incur any additional penalty in handling such situations.
119 // In debug builds this condition is asserted while in retail builds it is
120 // ignored. The CMemSerStream and CMemDeSerStream implementation are
121 // implemented using a macro HANDLE_OVERFLOW(fOverflow) which take the
122 // appropriate action.
123 
124 #define HANDLE_OVERFLOW(fOverflow)                      \
125     if (fOverflow) {                                    \
126         PropRaiseException(STATUS_BUFFER_OVERFLOW);     \
127     }
128 
129 #define newk(Tag, pCounter)     new
130 
131 #if DBG
132 extern "C" ULONG DebugLevel;
133 extern "C" ULONG DebugIndent;
134 
135 #define DEBTRACE_ERROR          (ULONG) 0x00000001
136 #define DEBTRACE_WARN           (ULONG) 0x00000002
137 #define DEBTRACE_CREATESTREAM   (ULONG) 0x00000004
138 #define DEBTRACE_NTPROP         (ULONG) 0x00000008
139 #define DEBTRACE_MAPSTM         (ULONG) 0x00000010
140 #define DEBTRACE_PROPERTY       (ULONG) 0x00000020
141 #define DEBTRACE_SUMCAT         (ULONG) 0x00000040
142 #define DEBTRACE_PROPVALIDATE (ULONG) 0x00010000  // awfully noisy
143 #define DEBTRACE_PROPPATCH  (ULONG) 0x00020000  // awfully noisy
144 
145 extern ULONG DbgPrint(PCHAR Format, ...);
146 
147 #define DebugTrace(indent, flag, args)                   \
148         if ((flag) == 0 || (DebugLevel & (flag)))        \
149         {                                                \
150             DebugIndent += (ULONG) (indent);             \
151             DbgPrint("NTDLL: %*s", DebugIndent, "");     \
152             DbgPrint args;                               \
153         }                                                \
154         else
155 
156 #ifdef _MSC_VER
157 #pragma warning(disable:4512)
158 #endif
159 
160 class CDebugTrace {
161 public:
162     inline CDebugTrace(CHAR *psz);
163     inline ~CDebugTrace();
164 private:
165    CHAR const *const _psz;
166 };
167 
168 #ifdef _MSC_VER
169 #pragma warning(default:4512)
170 #endif
171 
CDebugTrace(CHAR * psz)172 inline CDebugTrace::CDebugTrace(CHAR *psz): _psz(psz)
173 {
174     DebugTrace(+1, 0, ("Entering -- %s\n", _psz));
175 }
176 
~CDebugTrace()177 inline CDebugTrace::~CDebugTrace()
178 {
179     DebugTrace(-1, 0, ("Exiting -- %s\n", _psz));
180 }
181 
182 #define DEBUG_TRACE(ProcName) CDebugTrace _trace_(#ProcName);
183 #else
184 #define DebugTrace(indent, flag, args)
185 #define DEBUG_TRACE(ProcName)
186 #endif
187 
188 
189 //+-----------------------------------------------------------------------
190 //+-----------------------------------------------------------------------
191 //
192 // Byte-swapping functions
193 //
194 //+-----------------------------------------------------------------------
195 //+-----------------------------------------------------------------------
196 
197 // FmtID Byte-Swapped Comparisson.  I.e, does rfmtid1 equal
198 // a byte-swapped rfmtid2?
199 
IsEqualFMTIDByteSwap(REFFMTID rfmtid1,REFFMTID rfmtid2)200 inline BOOL IsEqualFMTIDByteSwap( REFFMTID rfmtid1, REFFMTID rfmtid2 )
201 {
202 
203     return( rfmtid1.Data1 == ByteSwap(rfmtid2.Data1)
204             &&
205             rfmtid1.Data2 == ByteSwap(rfmtid2.Data2)
206             &&
207             rfmtid1.Data3 == ByteSwap(rfmtid2.Data3)
208             &&
209             !memcmp(&rfmtid1.Data4, &rfmtid2.Data4, sizeof(rfmtid1.Data4))
210           );
211 }
212 
213 
214 // This define is for a special-case value of cbByteSwap in
215 // PBSBuffer
216 
217 #define CBBYTESWAP_UID        ((ULONG) -1)
218 
219 // The following byte-swapping functions mostly forward the call
220 // to the ByteSwap overloads when compiled in a big-endian
221 // system, and NOOP when compiled in a little-endian
222 // system (because property sets are always little-endian).
223 
224 #ifdef BIGENDIAN
225 
226 // This is a big-endian build, property byte-swapping is enabled.
227 
228 //  -----------
229 //  Swap a Byte
230 //  -----------
231 
232  // This exists primarily so that PropByteSwap(OLECHAR) will work
233  // whether OLECHAR is Unicode or Ansi.
234 
PropByteSwap(char b)235 inline BYTE PropByteSwap( char b )
236 {
237     return ByteSwap(b);
238 }
PropByteSwap(char * pb)239 inline VOID PropByteSwap( char *pb )
240 {
241     ByteSwap(pb);
242 }
243 
244 //  -----------
245 //  Swap a Word
246 //  -----------
247 
PropByteSwap(WORD w)248 inline WORD PropByteSwap( WORD w )
249 {
250     return ByteSwap(w);
251 }
PropByteSwap(WORD * pw)252 inline VOID PropByteSwap( WORD *pw )
253 {
254     ByteSwap(pw);
255 }
PropByteSwap(SHORT s)256 inline SHORT PropByteSwap( SHORT s )
257 {
258     PROPASSERT( sizeof(WORD) == sizeof(SHORT) );
259     return ByteSwap( (WORD) s );
260 }
PropByteSwap(SHORT * ps)261 inline VOID PropByteSwap( SHORT *ps )
262 {
263     PROPASSERT( sizeof(WORD) == sizeof(SHORT) );
264     ByteSwap( (WORD*) ps );
265 }
266 
267 //  ------------
268 //  Swap a DWORD
269 //  ------------
270 
PropByteSwap(DWORD dw)271 inline DWORD PropByteSwap( DWORD dw )
272 {
273     return ByteSwap(dw);
274 }
PropByteSwap(DWORD * pdw)275 inline VOID PropByteSwap( DWORD *pdw )
276 {
277     ByteSwap(pdw);
278 }
PropByteSwap(LONG l)279 inline LONG PropByteSwap( LONG l )
280 {
281     PROPASSERT( sizeof(DWORD) == sizeof(LONG) );
282     return ByteSwap( (DWORD) l );
283 }
PropByteSwap(LONG * pl)284 inline VOID PropByteSwap( LONG *pl )
285 {
286     PROPASSERT( sizeof(DWORD) == sizeof(LONG) );
287     ByteSwap( (DWORD*) pl );
288 }
289 
290 //  -------------------------
291 //  Swap a LONGLONG (64 bits)
292 //  -------------------------
293 
PropByteSwap(LONGLONG ll)294 inline LONGLONG PropByteSwap( LONGLONG ll )
295 {
296     return( ByteSwap(ll) );
297 }
298 
PropByteSwap(LONGLONG * pll)299 inline VOID PropByteSwap( LONGLONG *pll )
300 {
301     // we have to deal with two DWORDs instead of one LONG LONG
302     // because the pointer might not be 8 word aligned.
303     // (it is DWORD (4 bytes) aligned though)
304     PROPASSERT( sizeof(LONGLONG) == 2 * sizeof (DWORD));
305     DWORD *pdw = (DWORD*)pll;
306     DWORD dwTemp = ByteSwap( *pdw ); // temp = swapped(dw1)
307     ByteSwap( pdw+1 );               // swap dw2
308     *pdw = *(pdw+1);                 // dw1 = dw2(swapped)
309     *(pdw+1) = dwTemp;               // dw2 = temp
310     return;
311 }
312 
313 //  -----------
314 //  Swap a GUID
315 //  -----------
316 
PropByteSwap(GUID * pguid)317 inline VOID PropByteSwap( GUID *pguid )
318 {
319     ByteSwap(pguid);
320     return;
321 }
322 
323 
324 #else // Little Endian
325 
326 // This is a little-endian build, property byte-swapping is disabled.
327 
328 
PropByteSwap(BYTE b)329 inline BYTE PropByteSwap( BYTE b )
330 {
331     return (b);
332 }
PropByteSwap(BYTE * pb)333 inline VOID PropByteSwap( BYTE *pb )
334 {
335     UNREFERENCED_PARM(pb);
336 }
337 
338 
PropByteSwap(WORD w)339 inline WORD PropByteSwap( WORD w )
340 {
341     return (w);
342 }
PropByteSwap(WORD * pw)343 inline VOID PropByteSwap( WORD *pw )
344 {
345     UNREFERENCED_PARM(pw);
346 }
PropByteSwap(SHORT s)347 inline SHORT PropByteSwap( SHORT s )
348 {
349     return (s);
350 }
PropByteSwap(SHORT * ps)351 inline VOID PropByteSwap( SHORT *ps )
352 {
353     UNREFERENCED_PARM(ps);
354 }
355 
PropByteSwap(DWORD dw)356 inline DWORD PropByteSwap( DWORD dw )
357 {
358     return (dw);
359 }
PropByteSwap(DWORD * pdw)360 inline VOID PropByteSwap( DWORD *pdw )
361 {
362     UNREFERENCED_PARM(pdw);
363 }
PropByteSwap(LONG l)364 inline LONG PropByteSwap( LONG l )
365 {
366     return (l);
367 }
PropByteSwap(LONG * pl)368 inline VOID PropByteSwap( LONG *pl )
369 {
370     UNREFERENCED_PARM(pl);
371 }
372 
PropByteSwap(LONGLONG ll)373 inline LONGLONG PropByteSwap( LONGLONG ll )
374 {
375     return(ll);
376 }
PropByteSwap(LONGLONG * pll)377 inline VOID PropByteSwap( LONGLONG *pll )
378 {
379     UNREFERENCED_PARM(pll);
380 }
381 
382 //  -----------
383 //  Swap a GUID
384 //  -----------
385 
PropByteSwap(GUID * pguid)386 inline VOID PropByteSwap( GUID *pguid )
387 {
388     UNREFERENCED_PARM(pguid);
389 }
390 
391 #endif // #else // Little Endian
392 
393 
394 #endif// _PROPMAC_HXX_
395