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
7.7 KiB

  1. /**************************************************/
  2. /* */
  3. /* */
  4. /* Setting code range */
  5. /* */
  6. /* */
  7. /* Copyright (c) 1997-1999 Microsoft Corporation. */
  8. /**************************************************/
  9. #include "stdafx.h"
  10. #include "eudcedit.h"
  11. #include "registry.h"
  12. #ifdef BUILD_ON_WINNT
  13. #include "extfunc.h"
  14. #endif // BUILD_ON_WINNT
  15. #include "util.h"
  16. #define STRSAFE_LIB
  17. #include <strsafe.h>
  18. #define S_UNICODE 0xE000
  19. #define E_UNICODE 0xE0ff
  20. BOOL SetCountryInfo( UINT LocalCP);
  21. int SetLeadByteRange(TCHAR * CodeRange,int nCode);
  22. void SetTrailByteRange();
  23. #ifdef BUILD_ON_WINNT
  24. void CorrectTrailByteRange(int nIndex);
  25. #endif // BUILD_ON_WINNT
  26. /****************************************/
  27. /* */
  28. /* Set Country Infomation */
  29. /* */
  30. /****************************************/
  31. BOOL
  32. SetCountryInfo(
  33. UINT LocalCP)
  34. {
  35. TCHAR CodePage[10], szUnicode[] = TEXT("Unicode");
  36. TCHAR Coderange[50];
  37. int nCode = 0;
  38. HRESULT hresult;
  39. SetTrailByteRange(LocalCP);
  40. if (!CountryInfo.bOnlyUnicode){
  41. /* Read EUDC Coderange from Registry */
  42. #ifndef NEWREG
  43. /* Old Version */
  44. TCHAR CodeTmp[10];
  45. //*STRSAFE* wsprintf( CodeTmp, TEXT("%d"), LocalCP);
  46. hresult = StringCchPrintf(CodeTmp , ARRAYLEN(CodeTmp), TEXT("%d"), LocalCP);
  47. if (!SUCCEEDED(hresult))
  48. {
  49. return FALSE;
  50. }
  51. if( lstrlen( CodeTmp) == 3){
  52. //*STRSAFE* lstrcpy(CodePage, TEXT("CP00"));
  53. hresult = StringCchCopy(CodePage , ARRAYLEN(CodePage), TEXT("CP00"));
  54. if (!SUCCEEDED(hresult))
  55. {
  56. return FALSE;
  57. }
  58. }else{
  59. //*STRSAFE* lstrcpy(CodePage, TEXT("CP0"));
  60. hresult = StringCchCopy(CodePage , ARRAYLEN(CodePage), TEXT("CP0"));
  61. if (!SUCCEEDED(hresult))
  62. {
  63. return FALSE;
  64. }
  65. }
  66. //*STRSAFE* lstrcat(CodePage, CodeTmp);
  67. hresult = StringCchCat(CodePage , ARRAYLEN(CodePage), CodeTmp);
  68. if (!SUCCEEDED(hresult))
  69. {
  70. return FALSE;
  71. }
  72. #else
  73. /* New Version */
  74. //*STRSAFE* wsprintf( CodePage, TEXT("%d"), LocalCP);
  75. hresult = StringCchPrintf(CodePage , ARRAYLEN(CodePage), TEXT("%d"), LocalCP);
  76. if (!SUCCEEDED(hresult))
  77. {
  78. return FALSE;
  79. }
  80. #endif
  81. if( !InqCodeRange(CodePage, (BYTE *)Coderange, 50))
  82. return FALSE;
  83. if ((nCode = SetLeadByteRange ( Coderange, 0)) == -1)
  84. return FALSE;
  85. } //!CountryInfo.bOnlyUnicode
  86. #ifdef UNICODE
  87. // unicode range will always be the last one.
  88. //*STRSAFE* lstrcpy(CodePage, szUnicode);
  89. hresult = StringCchCopy(CodePage , ARRAYLEN(CodePage), szUnicode);
  90. if (!SUCCEEDED(hresult))
  91. {
  92. return FALSE;
  93. }
  94. if( !InqCodeRange(CodePage, (BYTE *)Coderange, 50))
  95. return FALSE;
  96. if (SetLeadByteRange (Coderange, nCode) == -1)
  97. return FALSE;
  98. #else
  99. //
  100. // Ansi version, we have to set end Unicode
  101. // code point to the last ansi range.
  102. //
  103. WCHAR RangeTmp[2];
  104. CHAR AnsiRange[2];
  105. CountryInfo.nRange = nCode+1;
  106. CountryInfo.nLeadByte = nCode+1;
  107. CountryInfo.sRange[nCode] = S_UNICODE;
  108. AnsiRange[0] = HIBYTE(CountryInfo.eRange[nCode-1]);
  109. AnsiRange[1] = LOBYTE(CountryInfo.eRange[nCode-1]);
  110. MultiByteToWideChar(CP_ACP, 0, AnsiRange,2,RangeTmp, 1);
  111. CountryInfo.eRange[nCode] = RangeTmp[0];
  112. CountryInfo.sLeadByte[nCode] = HIBYTE(CountryInfo.sRange[nCode]);
  113. CountryInfo.eLeadByte[nCode] = HIBYTE(CountryInfo.eRange[nCode]);
  114. #endif
  115. return TRUE;
  116. }
  117. void
  118. SetTrailByteRange(
  119. UINT LocalCP)
  120. {
  121. WORD UCode[MAX_CODE];
  122. BYTE SCode[MAX_CODE], sTral, cTral;
  123. int nTral = 0;
  124. if (!CountryInfo.bUnicodeMode){
  125. // calculate trailbyte range.
  126. UCode[0] = S_UNICODE;
  127. UCode[1] = '\0';
  128. WideCharToMultiByte( LocalCP, 0L, (const unsigned short *)UCode,
  129. -1, (char *)SCode, sizeof(SCode), NULL, NULL);
  130. sTral = cTral = SCode[1];
  131. CountryInfo.sTralByte[nTral] = sTral;
  132. for( WORD Cnt = S_UNICODE + 1; Cnt <= E_UNICODE; Cnt++){
  133. UCode[0] = Cnt;
  134. UCode[1] = '\0';
  135. WideCharToMultiByte( LocalCP, 0L, (const unsigned short *)UCode,
  136. -1, (char *)SCode, sizeof(SCode), NULL, NULL);
  137. if( cTral + 1 != SCode[1]){
  138. CountryInfo.eTralByte[nTral] = cTral;
  139. nTral++;
  140. if( sTral != SCode[1]){
  141. CountryInfo.sTralByte[nTral] = SCode[1];
  142. }
  143. }
  144. cTral = SCode[1];
  145. if( sTral == cTral)
  146. break;
  147. }
  148. CountryInfo.nTralByte = nTral;
  149. /* For Extend Wansung (test) */
  150. if( CountryInfo.LangID == EUDC_KRW){
  151. CountryInfo.nTralByte = 3;
  152. CountryInfo.sTralByte[0] = 0x41;
  153. CountryInfo.eTralByte[0] = 0x5a;
  154. CountryInfo.sTralByte[1] = 0x61;
  155. CountryInfo.eTralByte[1] = 0x7a;
  156. CountryInfo.sTralByte[2] = 0x81;
  157. CountryInfo.eTralByte[2] = 0xfe;
  158. }
  159. /* For CHS we have to remember the original trail byte range and calculate
  160. trail byte range dynamically
  161. */
  162. if( CountryInfo.LangID == EUDC_CHS){
  163. CountryInfo.nOrigTralByte = 2;
  164. CountryInfo.sOrigTralByte[0] = 0x40;
  165. CountryInfo.eOrigTralByte[0] = 0x7e;
  166. CountryInfo.sOrigTralByte[1] = 0x80;
  167. CountryInfo.eOrigTralByte[1] = 0xfe;
  168. //To start with, calculate trailbyte range for the default EUDC selection range.
  169. CorrectTrailByteRange(0);
  170. }else{
  171. CountryInfo.nOrigTralByte = 0;
  172. }
  173. }else { //!CountryInfo.bUnicodeMode
  174. CountryInfo.nTralByte = 1;
  175. CountryInfo.sTralByte[0] = 0x00;
  176. CountryInfo.eTralByte[0] = 0xff;
  177. } //!CountryInfo.bUnicodeMode
  178. }
  179. int
  180. SetLeadByteRange(
  181. TCHAR * Coderange,
  182. int nCode)
  183. {
  184. // Calculate LeadByte Range
  185. TCHAR *pStr1, *pStr2;
  186. WORD wLow, wHigh;
  187. if (!Coderange)
  188. {
  189. return -1;
  190. }
  191. pStr1 = pStr2 = Coderange;
  192. while(1){
  193. if(( pStr2 = Mytcschr( pStr1, '-')) != NULL){
  194. *pStr2 = '\0';
  195. wLow = (WORD)Mytcstol( pStr1, (TCHAR **)0, 16);
  196. CountryInfo.sRange[nCode] = wLow;
  197. CountryInfo.sLeadByte[nCode] = HIBYTE( wLow);
  198. pStr2++;
  199. pStr1 = pStr2;
  200. }else return -1;
  201. if(( pStr2 = Mytcschr( pStr1, ',')) != NULL){
  202. *pStr2 = '\0';
  203. wHigh = (WORD)Mytcstol( pStr1, (TCHAR **)0, 16);
  204. CountryInfo.eRange[nCode] = (unsigned short)wHigh;
  205. CountryInfo.eLeadByte[nCode] = HIBYTE( wHigh);
  206. pStr2++;
  207. pStr1 = pStr2;
  208. }else{
  209. wHigh = (WORD)Mytcstol( pStr1, (TCHAR **)0, 16);
  210. CountryInfo.eRange[nCode] = (unsigned short)wHigh;
  211. CountryInfo.eLeadByte[nCode] = HIBYTE( wHigh);
  212. break;
  213. }
  214. nCode++;
  215. }
  216. CountryInfo.nLeadByte = ++nCode;
  217. CountryInfo.nRange = nCode;
  218. return nCode;
  219. }
  220. #ifdef BUILD_ON_WINNT
  221. /**************************************************************************\
  222. * CorrectTralByteRange *
  223. * Correct trailbyte range of EUDC range with each of original trail byte *
  224. * ranges. It is used by countries where EUDC trail byte range changes *
  225. * with selection of different EUDC range, for example CHS. *
  226. \**************************************************************************/
  227. void
  228. CorrectTrailByteRange(
  229. int nIndex)
  230. {
  231. COUNTRYINFO *Info;
  232. int i, Unique=0;
  233. if (CountryInfo.bUnicodeMode)
  234. return;
  235. Info=&CountryInfo;
  236. for (i=0; i< Info->nOrigTralByte; i++){
  237. //take the smaller of the two ranges.
  238. Info->sTralByte[Unique] = max(LOBYTE(Info->sRange[nIndex]),
  239. Info->sOrigTralByte[i]);
  240. Info->eTralByte[Unique] = min(LOBYTE(Info->eRange[nIndex]),
  241. Info->eOrigTralByte[i]);
  242. //we keep valid ranges and overwrite invalid one with next loop
  243. if (Info->eTralByte[Unique] >= Info->sTralByte[Unique])
  244. Unique +=1;
  245. }
  246. Info->nTralByte=Unique;
  247. }
  248. #endif // BUILD_ON_WINNT