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.

170 lines
5.5 KiB

  1. /***
  2. *w_loc.c - W version 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 Split off W version into this file (w_loc.c). Replaced
  23. * use of _malloc_crt/_free_crt with _alloca. Also,
  24. * detab-ed and cleaned up the code.
  25. * 08-19-98 GJF Use _malloc_crt if _alloca fails.
  26. * 12-10-99 GB Added support for recovery from stack overflow around
  27. * _alloca().
  28. * 05-17-00 GB Use ERROR_CALL_NOT_IMPLEMENTED for existance of W API
  29. *
  30. *******************************************************************************/
  31. #include <cruntime.h>
  32. #include <internal.h>
  33. #include <stdlib.h>
  34. #include <setlocal.h>
  35. #include <awint.h>
  36. #include <dbgint.h>
  37. #include <malloc.h>
  38. #define USE_W 1
  39. #define USE_A 2
  40. /***
  41. *int __cdecl __crtGetLocaleInfoW - Get locale info and return it as a wide
  42. * string
  43. *
  44. *Purpose:
  45. * Internal support function. Assumes info in wide string format. Tries
  46. * to use NLS API call GetLocaleInfoW if available (NT) and uses
  47. * GetLocaleInfoA if it must (Chicago). If neither are available it fails
  48. * and returns 0.
  49. *
  50. *Entry:
  51. * LCID Locale - locale context for the comparison.
  52. * LCTYPE LCType - see NT\Chicago docs
  53. * LPWSTR lpLCData - pointer to memory to return data
  54. * int cchData - wide char (word) count of buffer (including
  55. * NULL) (if 0, lpLCData is not referenced, size
  56. * needed is returned)
  57. * int code_page - for MB/WC conversion. If 0, use __lc_codepage
  58. *
  59. *Exit:
  60. * Success: the number of characters copied (including NULL).
  61. * Failure: 0
  62. *
  63. *Exceptions:
  64. *
  65. *******************************************************************************/
  66. int __cdecl __crtGetLocaleInfoW(
  67. LCID Locale,
  68. LCTYPE LCType,
  69. LPWSTR lpLCData,
  70. int cchData,
  71. int code_page
  72. )
  73. {
  74. static int f_use = 0;
  75. /*
  76. * Look for unstubbed 'preferred' flavor. Otherwise use available flavor.
  77. * Must actually call the function to ensure it's not a stub.
  78. */
  79. if (0 == f_use)
  80. {
  81. if (0 != GetLocaleInfoW(0, LOCALE_ILANGUAGE, NULL, 0))
  82. f_use = USE_W;
  83. else if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
  84. f_use = USE_A;
  85. }
  86. /* Use "W" version */
  87. if (USE_W == f_use)
  88. {
  89. return GetLocaleInfoW(Locale, LCType, lpLCData, cchData);
  90. }
  91. /* Use "A" version */
  92. if (USE_A == f_use || f_use == 0)
  93. {
  94. int retval = 0;
  95. int buff_size;
  96. unsigned char *buffer;
  97. int malloc_flag = 0;
  98. /*
  99. * Use __lc_codepage for conversion if code_page not specified
  100. */
  101. if (0 == code_page)
  102. code_page = __lc_codepage;
  103. /* find out how big buffer needs to be */
  104. if (0 == (buff_size = GetLocaleInfoA(Locale, LCType, NULL, 0)))
  105. return 0;
  106. /* allocate buffer */
  107. __try {
  108. buffer = (unsigned char *)_alloca( buff_size * sizeof(char) );
  109. }
  110. __except( EXCEPTION_EXECUTE_HANDLER ) {
  111. _resetstkoflw();
  112. buffer = NULL;
  113. }
  114. if ( buffer == NULL ) {
  115. if ( (buffer = (unsigned char *)_malloc_crt(buff_size * sizeof(char)))
  116. == NULL )
  117. return 0;
  118. malloc_flag++;
  119. }
  120. /* get the info in ANSI format */
  121. if (0 == GetLocaleInfoA(Locale, LCType, buffer, buff_size))
  122. goto error_cleanup;
  123. if (0 == cchData)
  124. {
  125. /* find out how much space needed */
  126. retval = MultiByteToWideChar( code_page,
  127. MB_PRECOMPOSED,
  128. buffer,
  129. -1,
  130. NULL,
  131. 0 );
  132. }
  133. else {
  134. /* convert into user buffer */
  135. retval = MultiByteToWideChar( code_page,
  136. MB_PRECOMPOSED,
  137. buffer,
  138. -1,
  139. lpLCData,
  140. cchData );
  141. }
  142. error_cleanup:
  143. if ( malloc_flag )
  144. _free_crt(buffer);
  145. return retval;
  146. }
  147. else /* f_use is neither USE_A nor USE_W */
  148. return 0;
  149. }