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.

490 lines
12 KiB

  1. /*===================================================================
  2. Microsoft Denali
  3. Microsoft Confidential.
  4. Copyright 1996 Microsoft Corporation. All Rights Reserved.
  5. Component: misc
  6. File: util.h
  7. Owner: AndrewS
  8. This file contains random useful utility macros.
  9. ===================================================================*/
  10. #ifndef _UTIL_H
  11. #define _UTIL_H
  12. #include <dbgutil.h>
  13. // Generally useful
  14. #define PPVOID VOID **
  15. #define BOOLB BYTE
  16. /* S E R V E R _ G E T
  17. *
  18. * Get a server variable from ISAPI. Automatically queries for the buffer
  19. * size and increases the BUFFER object.
  20. *
  21. * Usage:
  22. * DWORD dwLen;
  23. * char *szValue = SERVER_GET(<ecb>, <szKey>, bufferObj, &dwLen)
  24. *
  25. * bufferObj is a STACK_BUFFER object than can be dynamically resized as necessary
  26. *
  27. * On return,
  28. * bufferObj.QueryPtr() points to data. dwLen is the real length of the variable.
  29. */
  30. class CIsapiReqInfo;
  31. BOOL Server_FindKey(CIsapiReqInfo *pIReq, char *szBuffer, DWORD *dwBufLen, const char *szKey);
  32. inline BOOL SERVER_GET(CIsapiReqInfo *pIReq, const char *szKey, BUFFER *pBuffer, DWORD *pdwBufLen) {
  33. DWORD dwBufLen = pBuffer->QuerySize();
  34. if (Server_FindKey(pIReq, (char *)pBuffer->QueryPtr(), &dwBufLen, szKey)) {
  35. *pdwBufLen = dwBufLen;
  36. return TRUE;
  37. }
  38. if (!pBuffer->Resize(dwBufLen)) {
  39. SetLastError(E_OUTOFMEMORY);
  40. return FALSE;
  41. }
  42. *pdwBufLen = dwBufLen;
  43. return Server_FindKey(pIReq, (char *)pBuffer->QueryPtr(), pdwBufLen, szKey);
  44. }
  45. /* V a r i a n t R e s o l v e D i s p a t c h
  46. *
  47. * Convert an IDispatch pointer to a Variant by calling IDispatch::Invoke
  48. * on dispid(0) repeatedly until a non-IDispatch Variant is returned
  49. */
  50. HRESULT VariantResolveDispatch(VARIANT *pVarOut, VARIANT *pVarIn, const GUID &iidObj, int nObjId);
  51. /* V a r i a n t G e t B S T R
  52. *
  53. * Get BSTR from a variant when available
  54. */
  55. BSTR VariantGetBSTR(const VARIANT *pvar);
  56. /* F i n d A p p l i c a t i o n P a t h
  57. *
  58. * Find the application path for this request.
  59. */
  60. HRESULT FindApplicationPath(CIsapiReqInfo *pIReq, TCHAR *szPath, int cbPath);
  61. /* N o r m a l i z e
  62. *
  63. * Convert filenames to a uniform format
  64. */
  65. int Normalize(TCHAR *szSrc);
  66. #ifdef DBG
  67. BOOLB IsNormalized(const TCHAR* sz);
  68. #endif // DBG
  69. /* H T M L E n c o d e L e n
  70. *
  71. * Returns the storage requirements to HTML encode a string.
  72. */
  73. int HTMLEncodeLen(const char *szSrc, UINT uCodePage, BSTR bstrIn, BOOL fEncodeExtCharOnly = FALSE);
  74. /* H T M L E n c o d e
  75. *
  76. * HTML encoeds a string.
  77. */
  78. char *HTMLEncode(char *szDest, const char *szSrc, UINT uCodePage, BSTR bstrIn, BOOL fEncodeExtCharOnly = FALSE);
  79. /* U R L E n c o d e L e n
  80. *
  81. * Returns the storage requirements to URL encode a string
  82. */
  83. int URLEncodeLen(const char *szSrc);
  84. /* U R L E n c o d e
  85. *
  86. * Hex escape non alphanumeric characters and change spaces to '+'.
  87. */
  88. char *URLEncode(char *szDest, const char *szSrc);
  89. /* D B C S E n c o d e L e n
  90. *
  91. * Returns the storage requirements to DBCS encode a string
  92. */
  93. int DBCSEncodeLen(const char *szSrc);
  94. /* D B C S E n c o d e
  95. *
  96. * Hex escape characters with the upper bit set - this will encode DBCS.
  97. */
  98. char *DBCSEncode(char *szDest, const char *szSrc);
  99. /* U R L P a t h E n c o d e L e n
  100. *
  101. * Returns the storage requirements to URL path encode a string
  102. */
  103. int URLPathEncodeLen(const char *szSrc);
  104. /* U R L P a t h E n c o d e
  105. *
  106. * Hex escape non alphanumeric or syntax characters until a ? is reached.
  107. */
  108. char *URLPathEncode(char *szDest, const char *szSrc);
  109. /* s t r c p y E x
  110. *
  111. * Like strcpy() but returns a pointer to the NUL character on return
  112. */
  113. char *strcpyExA(char *szDest, const char *szSrc);
  114. /* w c s c p y E x
  115. *
  116. * strcpyEx for wide strings
  117. */
  118. wchar_t *strcpyExW(wchar_t *szDest, const wchar_t *szSrc);
  119. #if UNICODE
  120. #define strcpyEx strcpyExW
  121. #else
  122. #define strcpyEx strcpyExA
  123. #endif
  124. /* G e t B r a c k e t i n g P a i r
  125. *
  126. * searches an ordered array and returns the bracketing pair of 'n', i.e.
  127. * the largest value <= 'n', and the smallest value >= 'n', or points
  128. * to end() if no bracketing pair exists.
  129. *
  130. * Note: STL is not supported with NT build - when such support is added,
  131. * replace this function with either 'lower_bound' or 'upper_bound'.
  132. */
  133. template<class EleType, class ValType, class Ordering>
  134. void GetBracketingPair(const ValType &value, EleType *pBegin, EleType *pEnd, Ordering FIsLess, EleType **ppLB, EleType **ppUB)
  135. {
  136. EleType *pT1, *pT2;
  137. if (ppLB == NULL) ppLB = &pT1;
  138. if (ppUB == NULL) ppUB = &pT2;
  139. *ppLB = pBegin; // Temporary use to see if we've moved pBegin
  140. *ppUB = pEnd; // Temporary use to see if we've moved pEnd
  141. while (pBegin < pEnd)
  142. {
  143. EleType *pMidpt = &pBegin[(pEnd - pBegin) >> 1];
  144. if (FIsLess(*pMidpt, value))
  145. pBegin = pMidpt + 1;
  146. else if (FIsLess(value, *pMidpt))
  147. pEnd = pMidpt;
  148. else
  149. {
  150. *ppLB = *ppUB = pMidpt;
  151. return;
  152. }
  153. }
  154. if (pBegin == *ppUB) // at end, no upper bound
  155. {
  156. if (pBegin == *ppLB) // low bound was initially equal to upper bound
  157. *ppLB = NULL; // lower bound does not exits
  158. else
  159. *ppLB = pEnd - 1; // lower bound is pEnd - 1
  160. *ppUB = NULL;
  161. }
  162. else if (pBegin != *ppLB) // pBegin was moved; pBegin-1 is the lower bound
  163. {
  164. *ppLB = pBegin - 1;
  165. *ppUB = pBegin;
  166. }
  167. else // pBegin was not moved - no lower bound exists
  168. {
  169. *ppLB = NULL;
  170. *ppUB = pBegin;
  171. }
  172. }
  173. /* V a r i a n t D a t e T o C T i m e
  174. *
  175. * Converts a timestamp stored as a Variant date to the format C && C++ use.
  176. */
  177. HRESULT VariantDateToCTime(DATE dt, time_t *ptResult);
  178. /* C T i m e T o V a r i a n t D a t e
  179. *
  180. * Converts a timestamp stored as a time_t to a Variant Date
  181. */
  182. HRESULT CTimeToVariantDate(const time_t *ptNow, DATE *pdtResult);
  183. /* C T i m e T o S t r i n g G M T
  184. *
  185. * Converts a C language time_t value to a string using the format required for
  186. * the internet
  187. */
  188. const DATE_STRING_SIZE = 30; // date strings will not be larger than this size
  189. HRESULT CTimeToStringGMT(const time_t *ptNow, char szBuffer[DATE_STRING_SIZE], BOOL fFunkyCookieFormat = FALSE);
  190. //DeleteInterfaceImp calls 'delete' and NULLs the pointer
  191. #define DeleteInterfaceImp(p)\
  192. {\
  193. if (NULL!=p)\
  194. {\
  195. delete p;\
  196. p=NULL;\
  197. }\
  198. }
  199. //ReleaseInterface calls 'Release' and NULLs the pointer
  200. #define ReleaseInterface(p)\
  201. {\
  202. if (NULL!=p)\
  203. {\
  204. p->Release();\
  205. p=NULL;\
  206. }\
  207. }
  208. /*
  209. * String handling stuff
  210. */
  211. HRESULT SysAllocStringFromSz(CHAR *sz, DWORD cch, BSTR *pbstrRet, UINT lCodePage = CP_ACP);
  212. /*
  213. * A simple class to convert WideChar to Multibyte. Uses object memory, if sufficient,
  214. * else allocates memory from the heap. Intended to be used on the stack.
  215. */
  216. class CWCharToMBCS
  217. {
  218. private:
  219. LPSTR m_pszResult;
  220. char m_resMemory[256];
  221. INT m_cbResult;
  222. public:
  223. CWCharToMBCS() { m_pszResult = m_resMemory; m_cbResult = 0; }
  224. ~CWCharToMBCS();
  225. // Init(): converts the widechar string at pWSrc to an MBCS string in memory
  226. // managed by CWCharToMBCS
  227. HRESULT Init(LPCWSTR pWSrc, UINT lCodePage = CP_ACP, int cch = -1);
  228. // GetString(): returns a pointer to the converted string. Passing TRUE
  229. // gives the ownership of the memory to the caller. Passing TRUE has the
  230. // side effect of clearing the object's contents with respect to the
  231. // converted string. Subsequent calls to GetString(). after which a TRUE
  232. // value was passed, will result in a pointer to an empty string being
  233. // returned.
  234. LPSTR GetString(BOOL fTakeOwnerShip = FALSE);
  235. // returns the number of bytes in the converted string - NOT including the
  236. // NULL terminating byte. Note that this is the number of bytes in the
  237. // string and not the number of characters.
  238. INT GetStringLen() { return (m_cbResult ? m_cbResult - 1 : 0); }
  239. };
  240. /*
  241. * A simple class to convert Multibyte to Widechar. Uses object memory, if sufficient,
  242. * else allocates memory from the heap. Intended to be used on the stack.
  243. */
  244. class CMBCSToWChar
  245. {
  246. private:
  247. LPWSTR m_pszResult;
  248. WCHAR m_resMemory[256];
  249. INT m_cchResult;
  250. public:
  251. CMBCSToWChar() { m_pszResult = m_resMemory; m_cchResult = 0; }
  252. ~CMBCSToWChar();
  253. // Init(): converts the MBCS string at pSrc to a Wide string in memory
  254. // managed by CMBCSToWChar
  255. HRESULT Init(LPCSTR pSrc, UINT lCodePage = CP_ACP, int cch = -1);
  256. // GetString(): returns a pointer to the converted string. Passing TRUE
  257. // gives the ownership of the memory to the caller. Passing TRUE has the
  258. // side effect of clearing the object's contents with respect to the
  259. // converted string. Subsequent calls to GetString(). after which a TRUE
  260. // value was passed, will result in a pointer to an empty string being
  261. // returned.
  262. LPWSTR GetString(BOOL fTakeOwnerShip = FALSE);
  263. // returns the number of WideChars in the converted string, not bytes.
  264. INT GetStringLen() { return (m_cchResult ? m_cchResult - 1 : 0); }
  265. };
  266. /*
  267. * Output Debug String should occur in Debug only
  268. */
  269. inline void DebugOutputDebugString(LPCSTR x)
  270. {
  271. #ifndef _NO_TRACING_
  272. DBGPRINTF((DBG_CONTEXT, x));
  273. #else
  274. #ifdef DBG
  275. OutputDebugStringA(x);
  276. #endif
  277. #endif
  278. }
  279. inline void __cdecl DebugFilePrintf(LPCSTR fname, LPCSTR fmt, ...)
  280. {
  281. #ifdef DBG
  282. FILE *f = fopen(fname, "a");
  283. if (f)
  284. {
  285. va_list marker;
  286. va_start(marker, fmt);
  287. vfprintf(f, fmt, marker);
  288. va_end(marker);
  289. fclose(f);
  290. }
  291. #endif
  292. }
  293. /*
  294. * Duplicate CHAR String using proper malloc (moved from error.h)
  295. */
  296. CHAR *StringDupA(CHAR *pszStrIn, BOOL fDupEmpty = FALSE);
  297. /*
  298. * Duplicate WCHAR String using proper malloc
  299. */
  300. WCHAR *StringDupW(WCHAR *pwszStrIn, BOOL fDupEmpty = FALSE);
  301. #if UNICODE
  302. #define StringDup StringDupW
  303. #else
  304. #define StringDup StringDupA
  305. #endif
  306. /*
  307. * Duplicate WCHAR String into a UTF-8 string
  308. */
  309. CHAR *StringDupUTF8(WCHAR *pwszStrIn, BOOL fDupEmpty = FALSE);
  310. /*
  311. * The same using macro to allocate memory from stack:
  312. WSTR_STACK_DUP
  313. (
  314. wsz -- string to copy
  315. buf -- user supplied buffer (to use before trying alloca())
  316. pwszDup -- [out] the pointer to copy (could be buffer or alloca())
  317. )
  318. *
  319. */
  320. inline HRESULT WSTR_STACK_DUP(WCHAR *wsz, BUFFER *buf, WCHAR **ppwszDup) {
  321. HRESULT hr = S_OK;
  322. DWORD cbwsz = wsz && *wsz ? (wcslen(wsz)+1)*sizeof(WCHAR) : 0;
  323. *ppwszDup = NULL;
  324. if (cbwsz == 0);
  325. else if (!buf->Resize(cbwsz)) {
  326. hr = E_OUTOFMEMORY;
  327. }
  328. else {
  329. *ppwszDup = (WCHAR *)buf->QueryPtr();
  330. memcpy(*ppwszDup, wsz, cbwsz);
  331. }
  332. return hr;
  333. }
  334. /*
  335. * String length (in bytes) of a WCHAR String
  336. */
  337. DWORD CbWStr(WCHAR *pwszStrIn);
  338. /*
  339. * Parent path support function
  340. */
  341. BOOL DotPathToPath(TCHAR *szDest, const TCHAR *szFileSpec, const TCHAR *szParentDirectory);
  342. /*
  343. * Check if is global.asa
  344. */
  345. BOOL FIsGlobalAsa(const TCHAR *szPath, DWORD cchPath = 0);
  346. /*
  347. * Encode/decode cookie
  348. */
  349. HRESULT EncodeSessionIdCookie(DWORD dw1, DWORD dw2, DWORD dw3, char *pszCookie);
  350. HRESULT DecodeSessionIdCookie(const char *pszCookie, DWORD *pdw1, DWORD *pdw2, DWORD *pdw3);
  351. /*
  352. * Typelibrary name from the registry
  353. */
  354. HRESULT GetTypelibFilenameFromRegistry(const char *szUUID, const char *szVersion,
  355. LCID lcid, char *szName, DWORD cbName);
  356. /*
  357. * Get security descriptor for file
  358. */
  359. DWORD GetSecDescriptor(LPCTSTR lpFileName, PSECURITY_DESCRIPTOR *ppSecurityDescriptor, DWORD *pnLength);
  360. /*
  361. * Get File Attributes (Ex)
  362. */
  363. HRESULT AspGetFileAttributes(LPCTSTR szFileName, WIN32_FILE_ATTRIBUTE_DATA *pfad = NULL);
  364. /*
  365. * Fix for UTF8 CharNext
  366. */
  367. char *AspCharNextA(WORD wCodePage, const char *pchNext);
  368. VOID AspDoRevertHack( HANDLE * phToken );
  369. VOID AspUndoRevertHack( HANDLE * phToken );
  370. #endif // _UTIL_H