Source code of Windows XP (NT5)
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.

449 lines
9.9 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. inline VOID Probe(VOID *pv, ULONG cb)
  81. {
  82. BYTE b = *(BYTE*)pv;
  83. b=((BYTE*)pv)[cb-1];
  84. }
  85. //+-------------------------------------------------------------------------
  86. //
  87. // Class: CPropSetName
  88. //
  89. // Purpose: Wrap buffer to convert
  90. //
  91. // Interface:
  92. //
  93. //
  94. //
  95. //
  96. //
  97. // Notes:
  98. //
  99. //--------------------------------------------------------------------------
  100. class CPropSetName
  101. {
  102. public:
  103. CPropSetName(REFFMTID rfmtid);
  104. inline CPropSetName();
  105. inline const OLECHAR * GetPropSetName()
  106. {
  107. return(_oszName);
  108. }
  109. private:
  110. OLECHAR _oszName[CWCSTORAGENAME];
  111. };
  112. inline CPropSetName::CPropSetName()
  113. {
  114. _oszName[0] = OLESTR('\0');
  115. }
  116. class CStackBuffer
  117. {
  118. public:
  119. CStackBuffer(BYTE *pbStackBuf,
  120. ULONG ulElementSize,
  121. ULONG cStackElements);
  122. ~CStackBuffer();
  123. HRESULT Init(ULONG cElements);
  124. protected:
  125. BYTE * _pbHeapBuf;
  126. ULONG _cElements;
  127. private:
  128. BYTE * _pbStackBuf;
  129. ULONG _cbElement;
  130. };
  131. inline CStackBuffer::CStackBuffer( BYTE *pbStackBuf,
  132. ULONG cbElement,
  133. ULONG cElements)
  134. : _pbStackBuf(pbStackBuf),
  135. _pbHeapBuf(pbStackBuf),
  136. _cbElement(cbElement),
  137. _cElements(cElements)
  138. {
  139. }
  140. inline CStackBuffer::~CStackBuffer()
  141. {
  142. if (_pbHeapBuf != _pbStackBuf)
  143. {
  144. CoTaskMemFree( _pbHeapBuf );
  145. }
  146. }
  147. template < class t_ElementType, int t_cElements = STACKELEMS >
  148. class TStackBuffer : public CStackBuffer
  149. {
  150. public:
  151. inline TStackBuffer() : CStackBuffer( (BYTE*)_rg, sizeof(_rg[0]), sizeof(_rg)/sizeof(_rg[0]) )
  152. {}
  153. inline t_ElementType * GetBuf()
  154. {
  155. return((t_ElementType*)_pbHeapBuf);
  156. }
  157. inline t_ElementType& operator[]( ULONG i )
  158. {
  159. DfpAssert( i < _cElements );
  160. return( GetBuf()[ i ] );
  161. }
  162. inline operator t_ElementType*()
  163. {
  164. return( GetBuf() );
  165. }
  166. inline ULONG Count() const
  167. {
  168. return( _cElements );
  169. }
  170. private:
  171. t_ElementType _rg[ t_cElements ];
  172. }; // template TStackBuffer
  173. typedef TStackBuffer<PROPID> CStackPropIdArray;
  174. typedef TStackBuffer<OLECHAR*> CStackOSZArray;
  175. typedef TStackBuffer<PROPVARIANT> CStackPropVarArray;
  176. #define CCH_MAX_DEFAULT_INDIRECT_PROP_NAMESZ 15 // E.g. "prop0123456789"
  177. HRESULT ValidateInRGPROPVARIANT( ULONG cpspec, const PROPVARIANT rgpropvar[] );
  178. HRESULT ValidateOutRGPROPVARIANT( ULONG cpspec, PROPVARIANT rgpropvar[] );
  179. HRESULT ValidateInRGLPOLESTR( ULONG cpropid, const OLECHAR* const rglpwstrName[] );
  180. HRESULT ValidateOutRGLPOLESTR( ULONG cpropid, LPOLESTR rglpwstrName[] );
  181. void * AllocAndCopy(ULONG cb, void * pvData, HRESULT *phr = NULL);
  182. inline BOOL
  183. GrfModeIsWriteable( DWORD grfMode )
  184. {
  185. return( (STGM_WRITE & grfMode) || (STGM_READWRITE & grfMode) );
  186. }
  187. inline BOOL
  188. GrfModeIsReadable( DWORD grfMode )
  189. {
  190. return( !(STGM_WRITE & grfMode) );
  191. }
  192. BOOL IsOriginalPropVariantType( VARTYPE vt );
  193. BOOL IsVariantType( VARTYPE vt );
  194. inline BOOL
  195. IsSupportedVarType( VARTYPE vt )
  196. {
  197. // Check for unsupported combinations of the high nibble
  198. if( VT_RESERVED & vt )
  199. return( FALSE );
  200. if( (VT_ARRAY & vt) && (VT_VECTOR & vt) )
  201. return( FALSE );
  202. // Check the type
  203. return( IsOriginalPropVariantType( vt ) // NT4 PROPVARIANT
  204. ||
  205. IsVariantType( vt ) // Supported VARIANT
  206. /*
  207. || // Allow arrays of (U)LONGLONGs
  208. (VT_ARRAY|VT_I8) == vt || (VT_ARRAY|VT_UI8) == vt
  209. */
  210. ||
  211. VT_VERSIONED_STREAM == vt // New to NT5
  212. ||
  213. (VT_VECTOR|VT_I1) == vt ); // New to NT5
  214. }
  215. // Debug routine to get the ref-count of an interface.
  216. // *** Not thread accurate ***
  217. inline ULONG
  218. GetRefCount( IUnknown *punk )
  219. {
  220. punk->AddRef();
  221. return( punk->Release() );
  222. }
  223. //+----------------------------------------------------------------------------
  224. //
  225. // CStringize
  226. //
  227. // Convert from various data types into an Ansi string in _sz.
  228. //
  229. // E.g. CStringize(rfmtid).
  230. //
  231. // For types that are used in multiple ways (e.g. grfMode & grfFlags are
  232. // both DWORDs), a structure is used to allow for overloading.
  233. //
  234. // E.g. CStringize(SGrfMode(grfMode))
  235. //
  236. //+----------------------------------------------------------------------------
  237. struct SGrfMode
  238. {
  239. DWORD grfMode;
  240. SGrfMode( DWORD grf )
  241. {
  242. grfMode = grf;
  243. }
  244. };
  245. struct SGrfFlags
  246. {
  247. DWORD grfFlags;
  248. SGrfFlags( DWORD grf )
  249. {
  250. grfFlags = grf;
  251. }
  252. };
  253. class CStringize
  254. {
  255. private:
  256. CHAR _sz[ MAX_PATH ];
  257. public:
  258. inline operator const char*() const;
  259. public:
  260. inline CStringize( const GUID &guid );
  261. inline CStringize( const SGrfMode &sgrfMode );
  262. inline CStringize( const SGrfFlags &sgrfFlags );
  263. }; // CStringize
  264. inline
  265. CStringize::operator const char*() const
  266. {
  267. return( _sz );
  268. }
  269. inline
  270. CStringize::CStringize( const GUID &guid )
  271. {
  272. if( NULL == &guid )
  273. {
  274. sprintf( _sz, "<NULL>" );
  275. }
  276. else
  277. {
  278. _snprintf( _sz, sizeof(_sz),
  279. "{%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X}",
  280. guid.Data1, guid.Data2, guid.Data3,
  281. guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
  282. guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7] );
  283. }
  284. }
  285. inline
  286. CStringize::CStringize( const SGrfMode &sgrfMode )
  287. {
  288. _sz[0] = '\0';
  289. DWORD grfMode = sgrfMode.grfMode;
  290. if (grfMode & STGM_TRANSACTED)
  291. strcat(_sz, "STGM_TRANSACTED | ");
  292. else
  293. strcat(_sz, "STGM_DIRECT | ");
  294. if (grfMode & STGM_SIMPLE)
  295. strcat(_sz, "STGM_SIMPLE | ");
  296. switch (grfMode & 3)
  297. {
  298. case STGM_READ:
  299. strcat(_sz, "STGM_READ |");
  300. break;
  301. case STGM_WRITE:
  302. strcat(_sz, "STGM_WRITE |");
  303. break;
  304. case STGM_READWRITE:
  305. strcat(_sz, "STGM_READWRITE |");
  306. break;
  307. default:
  308. strcat(_sz, "BAD grfMode |");
  309. break;
  310. }
  311. switch (grfMode & 0x70)
  312. {
  313. case STGM_SHARE_DENY_NONE:
  314. strcat(_sz, "STGM_SHARE_DENY_NONE |");
  315. break;
  316. case STGM_SHARE_DENY_READ:
  317. strcat(_sz, "STGM_SHARE_DENY_READ |");
  318. break;
  319. case STGM_SHARE_DENY_WRITE:
  320. strcat(_sz, "STGM_SHARE_DENY_WRITE |");
  321. break;
  322. case STGM_SHARE_EXCLUSIVE:
  323. strcat(_sz, "STGM_SHARE_EXCLUSIVE |");
  324. break;
  325. default:
  326. strcat(_sz, "BAD grfMode | ");
  327. break;
  328. }
  329. if (grfMode & STGM_PRIORITY)
  330. strcat(_sz, "STGM_PRIORITY | ");
  331. if (grfMode & STGM_DELETEONRELEASE)
  332. strcat(_sz, "STGM_DELETEONRELEASE | ");
  333. if (grfMode & STGM_NOSCRATCH)
  334. strcat(_sz, "STGM_NOSCRATCH | ");
  335. if (grfMode & STGM_CREATE)
  336. strcat(_sz, "STGM_CREATE | ");
  337. if (grfMode & STGM_CONVERT)
  338. strcat(_sz, "STGM_CONVERT | ");
  339. if (grfMode & STGM_FAILIFTHERE)
  340. strcat(_sz, "STGM_FAILIFTHERE | ");
  341. }
  342. inline
  343. CStringize::CStringize( const SGrfFlags &sgrfFlags )
  344. {
  345. strcpy(_sz, "PROPSETFLAG_DEFAULT |");
  346. if (sgrfFlags.grfFlags & PROPSETFLAG_NONSIMPLE)
  347. strcat(_sz, "PROPSETFLAG_NONSIMPLE |");
  348. if (sgrfFlags.grfFlags & PROPSETFLAG_ANSI)
  349. strcat(_sz, "PROPSETFLAG_ANSI |");
  350. }
  351. #endif // _UTILS_HXX_