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.

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