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.

280 lines
5.7 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. charset.c
  5. Abstract:
  6. Contains some functions to do Unicode <-> Ansi/MBCS convertsions.
  7. Author:
  8. Danilo Almeida (t-danal) 06-17-96
  9. Revision History:
  10. --*/
  11. //
  12. // INCLUDES
  13. //
  14. #include <string.h>
  15. #include "charset.h"
  16. /*
  17. * AnsiBytesFromUnicode
  18. *
  19. * Description:
  20. * Given a Unicode string, returns number of bytes needed for Ansi version
  21. *
  22. * In:
  23. * pwszUnicode - pointer to Unicode string
  24. */
  25. int
  26. AnsiBytesFromUnicode(
  27. LPCWSTR pwszUnicode
  28. )
  29. {
  30. return WideCharToMultiByte(CP_ACP,
  31. 0,
  32. pwszUnicode,
  33. -1,
  34. NULL,
  35. 0,
  36. NULL,
  37. NULL);
  38. }
  39. /*
  40. * AllocAnsi
  41. *
  42. * Description:
  43. * Given a Unicode string, allocate a new Ansi translation of that string
  44. *
  45. * In:
  46. * pwszUnicode - pointer to original Unicode string
  47. * ppszAnsi - pointer to cell to hold new MCBS string addr
  48. *
  49. * Out:
  50. * ppszAnsi - contains new MBCS string
  51. *
  52. * Returns:
  53. * Error code or 0 if successful.
  54. *
  55. * Notes:
  56. * The client must free the allocated string with FreeAnsi.
  57. */
  58. UINT
  59. AllocAnsi(
  60. LPCWSTR pwszUnicode,
  61. LPSTR* ppszAnsi
  62. )
  63. {
  64. UINT err;
  65. BYTE * pbAlloc;
  66. INT cbUnicode;
  67. INT cbAnsi;
  68. if (pwszUnicode == NULL)
  69. {
  70. *ppszAnsi = NULL;
  71. return 0;
  72. }
  73. cbAnsi = AnsiBytesFromUnicode(pwszUnicode);
  74. err = AllocMem(cbAnsi, &pbAlloc);
  75. if (err)
  76. return err;
  77. cbUnicode = wcslen(pwszUnicode)+1;
  78. *ppszAnsi = (LPSTR)pbAlloc;
  79. err = (UINT) !WideCharToMultiByte(CP_ACP,
  80. 0,
  81. pwszUnicode,
  82. cbUnicode,
  83. *ppszAnsi,
  84. cbAnsi,
  85. NULL,
  86. NULL);
  87. if (err)
  88. {
  89. *ppszAnsi = NULL;
  90. FreeMem(pbAlloc);
  91. return ( (UINT)GetLastError() );
  92. }
  93. return 0;
  94. }
  95. /*
  96. * FreeAnsi
  97. *
  98. * Description:
  99. * Deallocates an Ansi string allocated by AllocAnsi
  100. *
  101. * In:
  102. * pszAnsi - pointer to the Ansi string
  103. *
  104. * Out:
  105. * pszAnsi - invalid pointer - string has been freed
  106. */
  107. VOID
  108. FreeAnsi(LPSTR pszAnsi)
  109. {
  110. if (pszAnsi != NULL)
  111. FreeMem((LPBYTE)pszAnsi);
  112. }
  113. /*
  114. * AllocUnicode
  115. *
  116. * Description:
  117. * Given an Ansi string, allocates an Unicode version of that string
  118. *
  119. * In:
  120. * pszAnsi - pointer to original MBCS string
  121. * ppwszUnicode - pointer to new Unicode string address
  122. *
  123. * Out:
  124. * ppwszUnicode - points to new Unicode string
  125. *
  126. * Returns:
  127. * Error code or 0 if successful.
  128. *
  129. * Notes:
  130. * The client must free the allocated string with FreeUnicode.
  131. */
  132. UINT
  133. AllocUnicode(
  134. LPCSTR pszAnsi,
  135. LPWSTR * ppwszUnicode )
  136. {
  137. UINT err;
  138. BYTE * pbAlloc;
  139. INT cbAnsi;
  140. if (pszAnsi == NULL)
  141. {
  142. *ppwszUnicode = NULL;
  143. return 0;
  144. }
  145. // Allocate space for Unicode string (may be a little extra if MBCS)
  146. cbAnsi = strlen(pszAnsi)+1;
  147. err = AllocMem(sizeof(WCHAR) * cbAnsi, &pbAlloc);
  148. if (err)
  149. return err;
  150. *ppwszUnicode = (LPWSTR)pbAlloc;
  151. err = (UINT) !MultiByteToWideChar(CP_ACP,
  152. MB_PRECOMPOSED,
  153. pszAnsi,
  154. cbAnsi,
  155. *ppwszUnicode,
  156. cbAnsi);
  157. if (err)
  158. {
  159. *ppwszUnicode = NULL;
  160. FreeMem(pbAlloc);
  161. return ( (UINT)GetLastError() );
  162. }
  163. return 0;
  164. }
  165. /*
  166. * AllocUnicode2
  167. *
  168. * Description:
  169. * Given a MBCS string, allocates a new Unicode version of that string
  170. *
  171. * In:
  172. * pszAnsi - pointer to original MBCS string
  173. * cbAnsi - number of bytes to convert
  174. * ppwszUnicode - pointer to where to return new Unicode string address
  175. *
  176. * Out:
  177. * ppwszUnicode - contains new Unicode string
  178. *
  179. * Returns:
  180. * Returns number of characters written.
  181. *
  182. * Notes:
  183. * The client must free the allocated string with FreeUnicode.
  184. */
  185. int
  186. AllocUnicode2(
  187. LPCSTR pszAnsi,
  188. int cbAnsi,
  189. LPWSTR * ppwszUnicode)
  190. {
  191. UINT err;
  192. BYTE * pbAlloc;
  193. INT cwch;
  194. *ppwszUnicode = NULL;
  195. SetLastError(ERROR_SUCCESS);
  196. if (cbAnsi == 0)
  197. return 0;
  198. err = AllocMem(sizeof(WCHAR) * cbAnsi, &pbAlloc);
  199. if (err)
  200. {
  201. SetLastError(err);
  202. return 0;
  203. }
  204. *ppwszUnicode = (LPWSTR)pbAlloc;
  205. cwch = MultiByteToWideChar(CP_ACP,
  206. MB_PRECOMPOSED,
  207. pszAnsi,
  208. cbAnsi,
  209. *ppwszUnicode,
  210. cbAnsi);
  211. if (cwch == 0)
  212. {
  213. *ppwszUnicode = NULL;
  214. FreeMem(pbAlloc);
  215. }
  216. return cwch;
  217. }
  218. /*
  219. * FreeUnicode
  220. *
  221. * Description:
  222. * Deallocates a Unicode string allocatedd by AllocUnicode/AllocUnicode2
  223. *
  224. * In:
  225. * pwszUnicode - pointer to the Unicode string
  226. *
  227. * Out:
  228. * pwszUnicode - invalid pointer - string has been freed
  229. */
  230. VOID
  231. FreeUnicode( LPWSTR pwszUnicode )
  232. {
  233. if (pwszUnicode != NULL)
  234. FreeMem((LPBYTE)pwszUnicode);
  235. }