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.

176 lines
5.9 KiB

  1. /***
  2. *a_loc.c - A versions of GetLocaleInfo.
  3. *
  4. * Copyright (c) 1993-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Use either GetLocaleInfoA or GetLocaleInfoW depending on which is
  8. * available
  9. *
  10. *Revision History:
  11. * 09-14-93 CFW Module created.
  12. * 09-17-93 CFW Use unsigned chars.
  13. * 09-23-93 CFW Correct NLS API params and comments about same.
  14. * 10-07-93 CFW Optimize WideCharToMultiByte, use NULL default char.
  15. * 11-09-93 CFW Allow user to pass in code page.
  16. * 11-18-93 CFW Test for entry point function stubs.
  17. * 03-31-94 CFW Include awint.h.
  18. * 12-27-94 CFW Call direct, all OS's have stubs.
  19. * 01-10-95 CFW Debug CRT allocs.
  20. * 02-15-97 RDK For narrow locale info, try W version first so
  21. * Windows NT can process nonANSI codepage correctly.
  22. * 05-16-97 GJF Moved W version into a separate file and renamed this
  23. * one to a_loc.c. Replaced use of _malloc_crt/_free_crt
  24. * with _alloca. Also, detab-ed and cleaned up the code.
  25. * 08-20-98 GJF Use _malloc_crt if _alloca fails.
  26. * 04-28-99 GJF Changed dwFlags arg value to 0 in WideCharToMultiByte
  27. * calls to avoid problems with codepage 1258 on NT 5.0.
  28. * 12-10-99 GB Added support for recovery from stack overflow around
  29. * _alloca().
  30. * 05-17-00 GB Use ERROR_CALL_NOT_IMPLEMENTED for existance of W API
  31. *
  32. *******************************************************************************/
  33. #include <cruntime.h>
  34. #include <internal.h>
  35. #include <stdlib.h>
  36. #include <setlocal.h>
  37. #include <awint.h>
  38. #include <dbgint.h>
  39. #include <malloc.h>
  40. #define USE_W 1
  41. #define USE_A 2
  42. /***
  43. *int __cdecl __crtGetLocaleInfoA - Get locale info and return it as an ASCII
  44. * string
  45. *
  46. *Purpose:
  47. * Internal support function. Assumes info in ANSI string format. Tries
  48. * to use NLS API call GetLocaleInfoA if available (Chicago) and uses
  49. * GetLocaleInfoA if it must (NT). If neither are available it fails and
  50. * returns 0.
  51. *
  52. *Entry:
  53. * LCID Locale - locale context for the comparison.
  54. * LCTYPE LCType - see NT\Chicago docs
  55. * LPSTR lpLCData - pointer to memory to return data
  56. * int cchData - char (byte) count of buffer (including NULL)
  57. * (if 0, lpLCData is not referenced, size needed
  58. * is returned)
  59. * int code_page - for MB/WC conversion. If 0, use __lc_codepage
  60. *
  61. *Exit:
  62. * Success: the number of characters copied (including NULL).
  63. * Failure: 0
  64. *
  65. *Exceptions:
  66. *
  67. *******************************************************************************/
  68. int __cdecl __crtGetLocaleInfoA(
  69. LCID Locale,
  70. LCTYPE LCType,
  71. LPSTR lpLCData,
  72. int cchData,
  73. int code_page
  74. )
  75. {
  76. static int f_use = 0;
  77. /*
  78. * Look for unstubbed 'preferred' flavor. Otherwise use available flavor.
  79. * Must actually call the function to ensure it's not a stub.
  80. */
  81. if (0 == f_use)
  82. {
  83. if (0 != GetLocaleInfoW(0, LOCALE_ILANGUAGE, NULL, 0))
  84. f_use = USE_W;
  85. else if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
  86. f_use = USE_A;
  87. }
  88. /* Use "A" version */
  89. if (USE_A == f_use || f_use == 0)
  90. {
  91. return GetLocaleInfoA(Locale, LCType, lpLCData, cchData);
  92. }
  93. /* Use "W" version */
  94. if (USE_W == f_use)
  95. {
  96. int retval = 0;
  97. int buff_size;
  98. wchar_t *wbuffer;
  99. int malloc_flag = 0;
  100. /*
  101. * Use __lc_codepage for conversion if code_page not specified
  102. */
  103. if (0 == code_page)
  104. code_page = __lc_codepage;
  105. /* find out how big buffer needs to be */
  106. if (0 == (buff_size = GetLocaleInfoW(Locale, LCType, NULL, 0)))
  107. return 0;
  108. /* allocate buffer */
  109. __try {
  110. wbuffer = (wchar_t *)_alloca( buff_size * sizeof(wchar_t) );
  111. }
  112. __except( EXCEPTION_EXECUTE_HANDLER ) {
  113. _resetstkoflw();
  114. wbuffer = NULL;
  115. }
  116. if ( wbuffer == NULL ) {
  117. if ( (wbuffer = (wchar_t *)_malloc_crt(buff_size * sizeof(wchar_t)))
  118. == NULL )
  119. return 0;
  120. malloc_flag++;
  121. }
  122. /* get the info in wide format */
  123. if (0 == GetLocaleInfoW(Locale, LCType, wbuffer, buff_size))
  124. goto error_cleanup;
  125. /* convert from Wide Char to ANSI */
  126. if (0 == cchData)
  127. {
  128. /* convert into local buffer */
  129. retval = WideCharToMultiByte( code_page,
  130. 0,
  131. wbuffer,
  132. -1,
  133. NULL,
  134. 0,
  135. NULL,
  136. NULL );
  137. }
  138. else {
  139. /* convert into user buffer */
  140. retval = WideCharToMultiByte( code_page,
  141. 0,
  142. wbuffer,
  143. -1,
  144. lpLCData,
  145. cchData,
  146. NULL,
  147. NULL );
  148. }
  149. error_cleanup:
  150. if ( malloc_flag )
  151. _free_crt(wbuffer);
  152. return retval;
  153. }
  154. else /* f_use is neither USE_A nor USE_W */
  155. return 0;
  156. }