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.

445 lines
11 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: utils.hxx
  7. //
  8. // Contents: Useful classes in implementing properties.
  9. //
  10. // Classes: CPropSetName - Buffer which converts fmtids->names
  11. // CSubPropertyName - Buffer which converts VT_STREAM etc -> name
  12. //
  13. // Functions: DfpStatusToHResult - map NTSTATUS to HRESULT
  14. // Probe - probe memory range to generate GP fault.
  15. //
  16. // History: 1-Mar-95 BillMo Created.
  17. // 31-Mar-97 Danl Removed VerifyCommitFlags. Use definition
  18. // in stg\h\docfilep.hxx
  19. // 10-Mar-98 MikeHill Added IsOriginalPropVariantType.
  20. // 06-May-98 MikeHill Use CoTaskMem rather than new/delete.
  21. // 5/18/98 MikeHill
  22. // - Moved IsOriginalPropVariantType to utils.cxx.
  23. // 6/11/98 MikeHill
  24. // - Add default constructor for CPropSetName.
  25. // - Add CStringize (used for dbg outs).
  26. //
  27. // Notes:
  28. //
  29. // Codework:
  30. //
  31. //--------------------------------------------------------------------------
  32. #include "prophdr.hxx"
  33. #include "stdio.h" // _snprintf
  34. //+-------------------------------------------------------------------------
  35. //
  36. // Misc functions and defines
  37. //
  38. //--------------------------------------------------------------------------
  39. #ifndef _UTILS_HXX_
  40. #define _UTILS_HXX_
  41. #include "prophdr.hxx"
  42. #include <olechar.h> // ocs* routines
  43. #if DBG
  44. #define STACKELEMS 3
  45. #else
  46. #define STACKELEMS 64
  47. #endif
  48. // These are defined in h\docfilep.hxx as STGM_DENY and STGM_RDWR
  49. // But props doesn't include that file and we like these names better.
  50. //
  51. #define STGM_SHARE_MASK ( STGM_SHARE_DENY_NONE \
  52. | STGM_SHARE_DENY_READ \
  53. | STGM_SHARE_DENY_WRITE \
  54. | STGM_SHARE_EXCLUSIVE )
  55. #define STGM_RDWR_MASK (STGM_READ | STGM_WRITE | STGM_READWRITE)
  56. // This function is functionally equivalent to the macro in Inside OLE,
  57. // except that it it also returns the resulting ref count, which is
  58. // useful in Asserts.
  59. // This needs to be template to compile. Can't up cast to a reference.
  60. //
  61. template< class T_IUnknown >
  62. RELEASE_INTERFACE( T_IUnknown *(&punk) )
  63. {
  64. ULONG ul = 0;
  65. if( NULL != punk )
  66. ul = punk->Release();
  67. punk = NULL;
  68. return( ul );
  69. }
  70. extern HRESULT NtStatusToScode(NTSTATUS);
  71. inline HRESULT DfpNtStatusToHResult(NTSTATUS nts)
  72. {
  73. if (NT_SUCCESS(nts))
  74. return S_OK;
  75. if ((nts & 0xF0000000) == 0x80000000)
  76. return nts;
  77. else
  78. return(NtStatusToScode(nts));
  79. }
  80. //+-------------------------------------------------------------------------
  81. //
  82. // Class: CPropSetName
  83. //
  84. // Purpose: Wrap buffer to convert
  85. //
  86. // Interface:
  87. //
  88. //
  89. //
  90. //
  91. //
  92. // Notes:
  93. //
  94. //--------------------------------------------------------------------------
  95. class CPropSetName
  96. {
  97. public:
  98. CPropSetName(REFFMTID rfmtid);
  99. inline CPropSetName();
  100. inline const OLECHAR * GetPropSetName()
  101. {
  102. return(_oszName);
  103. }
  104. private:
  105. OLECHAR _oszName[CWCSTORAGENAME];
  106. };
  107. inline CPropSetName::CPropSetName()
  108. {
  109. _oszName[0] = OLESTR('\0');
  110. }
  111. class CStackBuffer
  112. {
  113. public:
  114. CStackBuffer(BYTE *pbStackBuf,
  115. ULONG ulElementSize,
  116. ULONG cStackElements);
  117. ~CStackBuffer();
  118. HRESULT Init(ULONG cElements);
  119. protected:
  120. BYTE * _pbHeapBuf;
  121. ULONG _cElements;
  122. private:
  123. BYTE * _pbStackBuf;
  124. ULONG _cbElement;
  125. };
  126. inline CStackBuffer::CStackBuffer( BYTE *pbStackBuf,
  127. ULONG cbElement,
  128. ULONG cElements)
  129. : _pbStackBuf(pbStackBuf),
  130. _pbHeapBuf(pbStackBuf),
  131. _cbElement(cbElement),
  132. _cElements(cElements)
  133. {
  134. }
  135. inline CStackBuffer::~CStackBuffer()
  136. {
  137. if (_pbHeapBuf != _pbStackBuf)
  138. {
  139. CoTaskMemFree( _pbHeapBuf );
  140. }
  141. }
  142. template < class t_ElementType, int t_cElements = STACKELEMS >
  143. class TStackBuffer : public CStackBuffer
  144. {
  145. public:
  146. inline TStackBuffer() : CStackBuffer( (BYTE*)_rg, sizeof(_rg[0]), sizeof(_rg)/sizeof(_rg[0]) )
  147. {}
  148. inline t_ElementType * GetBuf()
  149. {
  150. return((t_ElementType*)_pbHeapBuf);
  151. }
  152. inline t_ElementType& operator[]( ULONG i )
  153. {
  154. DfpAssert( i < _cElements );
  155. return( GetBuf()[ i ] );
  156. }
  157. inline operator t_ElementType*()
  158. {
  159. return( GetBuf() );
  160. }
  161. inline ULONG Count() const
  162. {
  163. return( _cElements );
  164. }
  165. private:
  166. t_ElementType _rg[ t_cElements ];
  167. }; // template TStackBuffer
  168. typedef TStackBuffer<PROPID> CStackPropIdArray;
  169. typedef TStackBuffer<OLECHAR*> CStackOSZArray;
  170. typedef TStackBuffer<PROPVARIANT> CStackPropVarArray;
  171. HRESULT ValidateInRGPROPVARIANT( ULONG cpspec, const PROPVARIANT rgpropvar[] );
  172. HRESULT ValidateOutRGPROPVARIANT( ULONG cpspec, PROPVARIANT rgpropvar[] );
  173. HRESULT ValidateInRGLPOLESTR( ULONG cpropid, const OLECHAR* const rglpwstrName[] );
  174. HRESULT ValidateOutRGLPOLESTR( ULONG cpropid, LPOLESTR rglpwstrName[] );
  175. void * AllocAndCopy(ULONG cb, void * pvData, HRESULT *phr = NULL);
  176. inline BOOL
  177. GrfModeIsWriteable( DWORD grfMode )
  178. {
  179. return( (STGM_WRITE & grfMode) || (STGM_READWRITE & grfMode) );
  180. }
  181. inline BOOL
  182. GrfModeIsReadable( DWORD grfMode )
  183. {
  184. return( !(STGM_WRITE & grfMode) );
  185. }
  186. BOOL IsOriginalPropVariantType( VARTYPE vt );
  187. BOOL IsVariantType( VARTYPE vt );
  188. inline BOOL
  189. IsSupportedVarType( VARTYPE vt )
  190. {
  191. // Check for unsupported combinations of the high nibble
  192. if( VT_RESERVED & vt )
  193. return( FALSE );
  194. if( (VT_ARRAY & vt) && (VT_VECTOR & vt) )
  195. return( FALSE );
  196. // Check the type
  197. return( IsOriginalPropVariantType( vt ) // NT4 PROPVARIANT
  198. ||
  199. IsVariantType( vt ) // Supported VARIANT
  200. /*
  201. || // Allow arrays of (U)LONGLONGs
  202. (VT_ARRAY|VT_I8) == vt || (VT_ARRAY|VT_UI8) == vt
  203. */
  204. ||
  205. VT_VERSIONED_STREAM == vt // New to NT5
  206. ||
  207. (VT_VECTOR|VT_I1) == vt ); // New to NT5
  208. }
  209. // Debug routine to get the ref-count of an interface.
  210. // *** Not thread accurate ***
  211. #if DBG
  212. inline ULONG
  213. GetRefCount( IUnknown *punk )
  214. {
  215. punk->AddRef();
  216. return( punk->Release() );
  217. }
  218. #endif
  219. //+----------------------------------------------------------------------------
  220. //
  221. // CStringize
  222. //
  223. // Convert from various data types into an Ansi string in _sz.
  224. //
  225. // E.g. CStringize(rfmtid).
  226. //
  227. // For types that are used in multiple ways (e.g. grfMode & grfFlags are
  228. // both DWORDs), a structure is used to allow for overloading.
  229. //
  230. // E.g. CStringize(SGrfMode(grfMode))
  231. //
  232. //+----------------------------------------------------------------------------
  233. #if DBG
  234. struct SGrfMode
  235. {
  236. DWORD grfMode;
  237. SGrfMode( DWORD grf )
  238. {
  239. grfMode = grf;
  240. }
  241. };
  242. struct SGrfFlags
  243. {
  244. DWORD grfFlags;
  245. SGrfFlags( DWORD grf )
  246. {
  247. grfFlags = grf;
  248. }
  249. };
  250. class CStringize
  251. {
  252. private:
  253. CHAR _sz[ MAX_PATH ];
  254. public:
  255. inline operator const char*() const;
  256. public:
  257. inline CStringize( const GUID &guid );
  258. inline CStringize( const SGrfMode &sgrfMode );
  259. inline CStringize( const SGrfFlags &sgrfFlags );
  260. }; // CStringize
  261. inline
  262. CStringize::operator const char*() const
  263. {
  264. return( _sz );
  265. }
  266. inline
  267. CStringize::CStringize( const GUID &guid )
  268. {
  269. if( NULL == &guid )
  270. {
  271. StringCbCopyA( _sz, sizeof(_sz), "<NULL>" );
  272. }
  273. else
  274. {
  275. StringCbPrintfA( _sz, sizeof(_sz),
  276. "{%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X}",
  277. guid.Data1, guid.Data2, guid.Data3,
  278. guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
  279. guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7] );
  280. }
  281. }
  282. inline
  283. CStringize::CStringize( const SGrfMode &sgrfMode )
  284. {
  285. _sz[0] = '\0';
  286. DWORD grfMode = sgrfMode.grfMode;
  287. if (grfMode & STGM_TRANSACTED)
  288. StringCbCatA(_sz, sizeof(_sz), "STGM_TRANSACTED | ");
  289. else
  290. StringCbCatA(_sz, sizeof(_sz), "STGM_DIRECT | ");
  291. if (grfMode & STGM_SIMPLE)
  292. StringCbCatA(_sz, sizeof(_sz), "STGM_SIMPLE | ");
  293. switch (grfMode & 3)
  294. {
  295. case STGM_READ:
  296. StringCbCatA(_sz, sizeof(_sz), "STGM_READ |");
  297. break;
  298. case STGM_WRITE:
  299. StringCbCatA(_sz, sizeof(_sz), "STGM_WRITE |");
  300. break;
  301. case STGM_READWRITE:
  302. StringCbCatA(_sz, sizeof(_sz), "STGM_READWRITE |");
  303. break;
  304. default:
  305. StringCbCatA(_sz, sizeof(_sz), "BAD grfMode |");
  306. break;
  307. }
  308. switch (grfMode & 0x70)
  309. {
  310. case STGM_SHARE_DENY_NONE:
  311. StringCbCatA(_sz, sizeof(_sz), "STGM_SHARE_DENY_NONE |");
  312. break;
  313. case STGM_SHARE_DENY_READ:
  314. StringCbCatA(_sz, sizeof(_sz), "STGM_SHARE_DENY_READ |");
  315. break;
  316. case STGM_SHARE_DENY_WRITE:
  317. StringCbCatA(_sz, sizeof(_sz), "STGM_SHARE_DENY_WRITE |");
  318. break;
  319. case STGM_SHARE_EXCLUSIVE:
  320. StringCbCatA(_sz, sizeof(_sz), "STGM_SHARE_EXCLUSIVE |");
  321. break;
  322. default:
  323. StringCbCatA(_sz, sizeof(_sz), "BAD grfMode | ");
  324. break;
  325. }
  326. if (grfMode & STGM_PRIORITY)
  327. StringCbCatA(_sz, sizeof(_sz), "STGM_PRIORITY | ");
  328. if (grfMode & STGM_DELETEONRELEASE)
  329. StringCbCatA(_sz, sizeof(_sz), "STGM_DELETEONRELEASE | ");
  330. if (grfMode & STGM_NOSCRATCH)
  331. StringCbCatA(_sz, sizeof(_sz), "STGM_NOSCRATCH | ");
  332. if (grfMode & STGM_CREATE)
  333. StringCbCatA(_sz, sizeof(_sz), "STGM_CREATE | ");
  334. if (grfMode & STGM_CONVERT)
  335. StringCbCatA(_sz, sizeof(_sz), "STGM_CONVERT | ");
  336. if (grfMode & STGM_FAILIFTHERE)
  337. StringCbCatA(_sz, sizeof(_sz), "STGM_FAILIFTHERE | ");
  338. }
  339. inline
  340. CStringize::CStringize( const SGrfFlags &sgrfFlags )
  341. {
  342. StringCbCopyA(_sz, sizeof(_sz), "PROPSETFLAG_DEFAULT |");
  343. if (sgrfFlags.grfFlags & PROPSETFLAG_NONSIMPLE)
  344. StringCbCatA(_sz, sizeof(_sz), "PROPSETFLAG_NONSIMPLE |");
  345. if (sgrfFlags.grfFlags & PROPSETFLAG_ANSI)
  346. StringCbCatA(_sz, sizeof(_sz), "PROPSETFLAG_ANSI |");
  347. }
  348. #endif // #if DBG
  349. #endif // _UTILS_HXX_