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.

283 lines
7.7 KiB

  1. /*
  2. * C N V T . H
  3. *
  4. * Data conversion routines
  5. *
  6. * Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
  7. */
  8. #ifndef _CNVT_H_
  9. #define _CNVT_H_
  10. #include <ex\sz.h>
  11. #include <crc.h>
  12. #include <limits.h>
  13. #define INT64_MIN 0x8000000000000000
  14. // Error return value for CchFindChar()
  15. //
  16. #define INVALID_INDEX ((UINT)(-1))
  17. // Conversion functions ------------------------------------------------------
  18. //
  19. UINT __fastcall CchFindChar(WCHAR, LPCWSTR, UINT);
  20. UINT __fastcall CchSkipWhitespace(LPCWSTR, UINT);
  21. LONG __fastcall LNumberFromParam(LPCWSTR, UINT);
  22. HRESULT __fastcall HrHTTPDateToFileTime(LPCWSTR, FILETIME *);
  23. HRESULT __fastcall GetFileTimeFromParam(LPCWSTR, UINT, SYSTEMTIME *);
  24. HRESULT __fastcall GetFileDateFromParam(LPCWSTR, UINT, SYSTEMTIME *);
  25. BOOL __fastcall FGetSystimeFromDateIso8601(LPCWSTR, SYSTEMTIME *);
  26. BOOL __fastcall FGetDateIso8601FromSystime(SYSTEMTIME *, LPWSTR, UINT);
  27. BOOL __fastcall FGetDateRfc1123FromSystime(SYSTEMTIME *, LPWSTR, UINT);
  28. VOID EncodeBase64 (LPBYTE pbIn, UINT cbIn, WCHAR* pwszOut, UINT cchOut);
  29. VOID EncodeBase64A (LPBYTE pbIn, UINT cbIn, LPBYTE pbOut, UINT cbOut, BOOL fTerminate = TRUE);
  30. SCODE ScDecodeBase64 (WCHAR* pwszIn, UINT cchIn, LPBYTE pbOut, UINT* pcbOut);
  31. // ------------------------------------------------------------------------
  32. // CchNeededEncodeBase64
  33. //
  34. // Figure the size of the string buffer needed to encode binary data of the
  35. // given size into a Base64 string.
  36. // Base64 uses 4 chars out for each 3 bytes in, AND if there is ANY
  37. // "remainder", it needs another 4 chars to encode the remainder.
  38. // ("+2" BEFORE "/3" ensures that we count any remainder as a whole
  39. // set of 3 bytes that need 4 chars to hold the encoding.)
  40. //
  41. // NOTE: This function does NOT count space for the terminating NULL.
  42. // The caller must add one for the terminating NULL, if desired.
  43. //
  44. inline
  45. UINT
  46. CchNeededEncodeBase64 (UINT cb)
  47. {
  48. return (((cb + 2) / 3) * 4);
  49. }
  50. // ------------------------------------------------------------------------
  51. // CbNeededDecodeBase64
  52. //
  53. // Figure the number of bytes of space needed to decode a Base64 string
  54. // of length cch (NOT counting terminal NULL -- pure strlen cch here).
  55. // This is the easy direction -- the padding is already in the cch!
  56. //
  57. inline
  58. UINT
  59. CbNeededDecodeBase64 (UINT cch)
  60. {
  61. return ((cch / 4) * 3);
  62. }
  63. // ------------------------------------------------------------------------
  64. // CopyToWideBase64
  65. //
  66. // Copy skinny base64 encoded string into the wide base64 encoded string
  67. // of length equal to cb. Function assumes that there is a '\0' termination
  68. // straight at the end that is to be copied too
  69. //
  70. inline
  71. VOID CopyToWideBase64(LPCSTR psz, LPWSTR pwsz, UINT cb)
  72. {
  73. // Include '\0' termination
  74. //
  75. cb++;
  76. // Copy all the stuff to the wide string
  77. //
  78. while (cb--)
  79. {
  80. pwsz[cb] = psz[cb];
  81. }
  82. }
  83. //$REVIEW: The following three do not really does not belong to any common libraries
  84. //$REVIEW: that are shared by davex, exdav, exoledb and exprox.
  85. //$REVIEW: On the other hand, we definitely don't want add a new lib for this. so just
  86. //$REVIEW: add it here. Feel free to move them to a better location if you find one
  87. //
  88. // Routines to fetch and manipulate security IDs (SIDs)
  89. //
  90. SCODE
  91. ScDupPsid (PSID psidSrc,
  92. DWORD dwcbSID,
  93. PSID * ppsidDst);
  94. SCODE
  95. ScGetTokenInfo (HANDLE hTokenUser,
  96. DWORD * pdwcbSIDUser,
  97. PSID * ppsidUser);
  98. // CRCSid: A SID based key.
  99. //
  100. class CRCSid
  101. {
  102. public:
  103. DWORD m_dwCRC;
  104. DWORD m_dwLength;
  105. PSID m_psid;
  106. CRCSid (PSID psid)
  107. : m_psid(psid)
  108. {
  109. UCHAR* puch;
  110. Assert (psid);
  111. // "Right way" -- since MSDN says not to touch the SID directly.
  112. puch = GetSidSubAuthorityCount (psid);
  113. m_dwLength = GetSidLengthRequired (*puch); // "cannot fail" -- MSDN
  114. Assert (m_dwLength); // MSDN said this call "cannot fail".
  115. m_dwCRC = DwComputeCRC (0,
  116. psid,
  117. m_dwLength);
  118. }
  119. // operators for use with the hash cache
  120. //
  121. int hash (const int rhs) const
  122. {
  123. return (m_dwCRC % rhs);
  124. }
  125. bool isequal (const CRCSid& rhs) const
  126. {
  127. return ((m_dwCRC == rhs.m_dwCRC) &&
  128. (m_dwLength == rhs.m_dwLength) &&
  129. !memcmp (m_psid, rhs.m_psid, m_dwLength));
  130. }
  131. };
  132. //$REVIEW: These functions are needed by _storext, exdav and davex. They have
  133. // moved quite a bit, going from calcprops.cpp to exprops.cpp and now to
  134. // cnvt.cpp. cnvt.cpp seems to be a better destination for them than
  135. // exprops.cpp. I bet these functions look awfully similar to some of
  136. // the ones already in this file:-)
  137. //
  138. SCODE ScUnstringizeData (
  139. IN LPCSTR pchData,
  140. IN UINT cchData,
  141. IN OUT BYTE * pb,
  142. IN OUT UINT * pcb);
  143. SCODE
  144. ScStringizeData (IN const BYTE * pb,
  145. IN const UINT cb,
  146. OUT LPSTR psz,
  147. IN OUT UINT * pcch);
  148. SCODE
  149. ScStringizeDataW ( IN const BYTE * pb,
  150. IN const UINT cb,
  151. OUT LPWSTR pwsz,
  152. IN OUT UINT * pcch);
  153. inline
  154. BOOL
  155. FCharInHexRange (char ch)
  156. {
  157. return ((ch >= '0' && ch <= '9') ||
  158. (ch >= 'A' && ch <= 'F') ||
  159. (ch >= 'a' && ch <= 'f'));
  160. }
  161. // Our own version of WideCharToMultiByte(CP_UTF8, ...)
  162. //
  163. // It returns similarly to the system call WideCharToMultiByte:
  164. //
  165. // If the function succeeds, and cbMulti is nonzero, the return value is
  166. // the number of bytes written to the buffer pointed to by psz.
  167. //
  168. // If the function succeeds, and cbMulti is zero, the return value is
  169. // the required size, in bytes, for a buffer that can receive the translated
  170. // string.
  171. //
  172. // If the function fails, the return value is zero. To get extended error
  173. // information, call GetLastError. GetLastError may return one of the
  174. // following error codes:
  175. //
  176. // ERROR_INSUFFICIENT_BUFFER
  177. // ERROR_INVALID_FLAGS
  178. // ERROR_INVALID_PARAMETER
  179. //
  180. // See the WideCharToMultiByte MSDN pages to find out more about
  181. // this function and its use. The only difference is that INVALID_INDEX
  182. // should be used instead of -1.
  183. //
  184. UINT WideCharToUTF8(/* [in] */ LPCWSTR pwsz,
  185. /* [in] */ UINT cchWide,
  186. /* [out] */ LPSTR psz,
  187. /* [in] */ UINT cbMulti);
  188. //$ REVIEW: negative values of _int64 seem to have problems in
  189. // the __i64toa() API. Handle those cases ourselves by using the wrapper
  190. // function Int64ToPsz.
  191. //
  192. inline
  193. VOID
  194. Int64ToPsz (UNALIGNED __int64 * pI64, LPSTR pszBuf, UINT cbBuf)
  195. {
  196. Assert(pI64);
  197. Assert(pszBuf);
  198. Assert(cbBuf >= 64);
  199. BOOL fNegative = (*pI64 < 0);
  200. // Note: this workaround works for all cases except the
  201. // most negative _int64 value (because it can't be inverted).
  202. // Luckily __i64toa works for this case...
  203. //
  204. if (INT64_MIN == *pI64)
  205. fNegative = FALSE;
  206. if (fNegative)
  207. {
  208. // Stuff a negative sign into the buffer and
  209. // then fix the value.
  210. //
  211. pszBuf[0] = '-';
  212. *pI64 = 0 - *pI64;
  213. }
  214. Assert ((0 == fNegative) || (1 == fNegative));
  215. _i64toa (*pI64, pszBuf + fNegative, 10);
  216. }
  217. //$ REVIEW: negative values of _int64 seem to have problems in
  218. // the __i64tow() API. Handle those cases ourselves by using the wrapper
  219. // function Int64ToPwsz.
  220. //
  221. inline
  222. VOID
  223. Int64ToPwsz (UNALIGNED __int64 * pI64, LPWSTR pwszBuf, UINT cbBuf)
  224. {
  225. Assert(pI64);
  226. Assert(pwszBuf);
  227. Assert(cbBuf >= 64 * sizeof(WCHAR));
  228. BOOL fNegative = (*pI64 < 0);
  229. // Note: this workaround works for all cases except the
  230. // most negative _int64 value (because it can't be inverted).
  231. // Luckily __i64tow works for this case...
  232. //
  233. if (INT64_MIN == *pI64)
  234. fNegative = FALSE;
  235. if (fNegative)
  236. {
  237. // Stuff a negative sign into the buffer and
  238. // then fix the value.
  239. //
  240. pwszBuf[0] = L'-';
  241. *pI64 = 0 - *pI64;
  242. }
  243. Assert ((0 == fNegative) || (1 == fNegative));
  244. _i64tow (*pI64, pwszBuf + fNegative, 10);
  245. }
  246. #endif // _CNVT_H_