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.

189 lines
6.5 KiB

  1. /***
  2. *convrtcp.c - support routines for Ansi WinAPIs.
  3. *
  4. * Copyright (c) 1993-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Implementation of routines to convert multibyte string from one code
  8. * page to another.
  9. *
  10. *Revision History:
  11. * 08-18-00 GB Module created.
  12. *
  13. *******************************************************************************/
  14. #include <cruntime.h>
  15. #include <internal.h>
  16. #include <setlocal.h>
  17. #include <locale.h>
  18. #include <awint.h>
  19. #include <dbgint.h>
  20. #include <malloc.h>
  21. #include <stdlib.h>
  22. #include <wchar.h>
  23. /***
  24. *int __cdecl __ansicp - count characters in a string, up to n.
  25. *
  26. *Purpose:
  27. * return ansi codepage for given Locale
  28. *
  29. *Entry:
  30. * int lcid - Locale ID
  31. *
  32. *Exit:
  33. * returns ansi codepage corrosponding to the locale.
  34. *
  35. *Exceptions:
  36. * return -1
  37. *
  38. *******************************************************************************/
  39. int __cdecl __ansicp(int lcid)
  40. {
  41. char ch[7];
  42. int ret;
  43. ch[6] = 0;
  44. if (!GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, ch, 6))
  45. ret = -1;
  46. else
  47. ret = atol(ch);
  48. return ret;
  49. }
  50. /***
  51. *int __cdecl __convertcp - converts string from one code page to other.
  52. *
  53. *Purpose:
  54. * Convert string from one code page to other.
  55. *
  56. *Entry:
  57. * int fromCP - Codepage to convert from
  58. * int toCP - Codepage to convert to
  59. * const char *lpSrcStr - String to be converted
  60. * int *pcchSrc - Length of lpSrcStr.
  61. * char *lpDestSrc - Destenation string. If NULL, create new string.
  62. * char cchDest - Destenation string length. No use if lpDestStr = NULL
  63. *
  64. *Exit:
  65. * returns pointer to new string (or Destination string)
  66. *
  67. *Exceptions:
  68. * return NULL
  69. *
  70. *******************************************************************************/
  71. char * __cdecl __convertcp(int fromCP,
  72. int toCP,
  73. const char *lpSrcStr,
  74. int *pcchSrc,
  75. char *lpDestStr,
  76. int cchDest
  77. )
  78. {
  79. wchar_t *wbuffer;
  80. char *cbuffer = NULL;
  81. int malloc_flag = 0 ;
  82. int buff_size;
  83. int cchSrc = *pcchSrc;
  84. int sb = FALSE;
  85. if (fromCP != toCP)
  86. {
  87. CPINFO cpi;
  88. // Find if both the codepages have no MBCS
  89. if ( GetCPInfo(fromCP, &cpi))
  90. {
  91. if ( cpi.MaxCharSize == 1 && GetCPInfo(toCP, &cpi))
  92. if (cpi.MaxCharSize == 1)
  93. sb = TRUE;
  94. }
  95. // If no MBCS in both then set buff_size and use if for all allocation
  96. if (sb)
  97. {
  98. if ( cchSrc != -1)
  99. buff_size = cchSrc;
  100. else
  101. //NULL character included
  102. buff_size = (int)strlen(lpSrcStr) + 1;
  103. }
  104. // If sb then no need to find buff_size
  105. if ( !sb && !(buff_size = MultiByteToWideChar( fromCP,
  106. MB_PRECOMPOSED,
  107. lpSrcStr,
  108. cchSrc,
  109. NULL,
  110. 0 )) )
  111. return NULL;
  112. /* allocate enough space for wide chars */
  113. __try {
  114. wbuffer = (wchar_t *)_alloca( sizeof(wchar_t) * buff_size);
  115. (void)memset( wbuffer, 0, sizeof(wchar_t) * buff_size);
  116. }
  117. __except( EXCEPTION_EXECUTE_HANDLER ) {
  118. _resetstkoflw();
  119. wbuffer = NULL;
  120. }
  121. if ( wbuffer == NULL ) {
  122. if ( (wbuffer = (wchar_t *)_calloc_crt(sizeof(wchar_t), buff_size)) == NULL)
  123. return NULL;
  124. malloc_flag++;
  125. }
  126. /* do the conversion to WideChar */
  127. if ( 0 != MultiByteToWideChar( fromCP,
  128. MB_PRECOMPOSED,
  129. lpSrcStr,
  130. cchSrc,
  131. wbuffer,
  132. buff_size ))
  133. {
  134. if ( lpDestStr != NULL)
  135. {
  136. if (WideCharToMultiByte(toCP,
  137. 0,
  138. wbuffer,
  139. buff_size,
  140. lpDestStr,
  141. cchDest,
  142. NULL,
  143. NULL))
  144. cbuffer = lpDestStr;
  145. } else {
  146. /* do the conversion back to MultiByte using ANSI_CP */
  147. if ( sb || (buff_size = WideCharToMultiByte( toCP,
  148. 0,
  149. wbuffer,
  150. buff_size,
  151. 0,
  152. 0,
  153. NULL,
  154. NULL)))
  155. {
  156. if ( (cbuffer = (char *)_calloc_crt(sizeof(char),buff_size)) != NULL)
  157. {
  158. if ( 0 == (buff_size = WideCharToMultiByte( toCP,
  159. 0,
  160. wbuffer,
  161. buff_size,
  162. cbuffer,
  163. buff_size,
  164. NULL,
  165. NULL)))
  166. {
  167. _free_crt(cbuffer);
  168. cbuffer = NULL;
  169. } else {
  170. if ( cchSrc != -1)
  171. *pcchSrc = buff_size;
  172. }
  173. }
  174. }
  175. }
  176. }
  177. }
  178. if (malloc_flag)
  179. _free_crt(wbuffer);
  180. return cbuffer;
  181. }