Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

488 lines
12 KiB

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