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.

177 lines
5.8 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: nlsconv.c *
  3. * *
  4. * NLS conversion routines. *
  5. * *
  6. * Created: 08-Sep-1991 15:56:30 *
  7. * Author: Bodin Dresevic [BodinD] *
  8. * *
  9. * Copyright (c) 1991-1999 Microsoft Corporation *
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. /******************************Public*Routine******************************\
  14. * bGetANSISetMap *
  15. * *
  16. * Tries to get a simple translation table from ANSI to UNICODE. Returns *
  17. * TRUE on success. Sets the gbDBCSCodePage flag if it thinks the char set *
  18. * MIGHT be DBCS. *
  19. * *
  20. * *
  21. * Mon 11-Jan-1993 14:13:34 -by- Charles Whitmer [chuckwh] *
  22. * Wrote it. I'm clearly assuming that by the time this is called, the *
  23. * char set is well defined, and will not change. *
  24. \**************************************************************************/
  25. WCHAR *gpwcANSICharSet = NULL;
  26. WCHAR *gpwcDBCSCharSet = NULL;
  27. BOOL bGetANSISetMap()
  28. {
  29. CHAR ch[256];
  30. ULONG *pul;
  31. ULONG ii,jj;
  32. NTSTATUS st;
  33. ULONG cjResult;
  34. WCHAR *pwc;
  35. WCHAR *pwcSBC;
  36. // See if we know the answers already. (The client should not have called!)
  37. if (gpwcANSICharSet != (WCHAR *) NULL)
  38. return(TRUE);
  39. // Create a mapping.
  40. // Make an ANSI source char set. This funny way of initialization takes
  41. // about 180 instructions to execute rather than over 1000.
  42. pul = (ULONG *) ch;
  43. for (ii=0x03020100L,jj=0; jj<64; jj+=4)
  44. {
  45. pul[jj+0] = ii;
  46. ii += 0x04040404L;
  47. pul[jj+1] = ii;
  48. ii += 0x04040404L;
  49. pul[jj+2] = ii;
  50. ii += 0x04040404L;
  51. pul[jj+3] = ii;
  52. ii += 0x04040404L;
  53. }
  54. // Allocate the UNICODE buffer but don't write the pointer in until the
  55. // table is valid, in case we're racing another thread.
  56. pwc = LOCALALLOC(512 * sizeof(WCHAR));
  57. pwcSBC = &pwc[256];
  58. if (pwc == (WCHAR *) NULL)
  59. return(FALSE);
  60. // Convert the characters.
  61. pwc[0] = 0;
  62. st = RtlMultiByteToUnicodeN
  63. (
  64. &pwc[1], // OUT PWCH UnicodeString
  65. 255 * sizeof(WCHAR), // IN ULONG MaxBytesInUnicodeString
  66. &cjResult, // OUT PULONG BytesInUnicodeString
  67. &ch[1], // IN PCH MultiByteString
  68. 255 // IN ULONG BytesInMultiByteString
  69. );
  70. if( !NT_SUCCESS(st) )
  71. {
  72. // Clean up and forget about accelerations.
  73. WARNING("GDI32: RtlMultiByteToUnicodeN error.");
  74. LOCALFREE(pwc);
  75. return(FALSE);
  76. }
  77. if( cjResult != 255 * sizeof(WCHAR) )
  78. {
  79. // There must be a DBCS code page so gpwcANSIMap takes on new meaning.
  80. // It is used for fonts with ANSI,OEM, and SYMBOL charsets. Also,
  81. // another table, gpwcDBCS is constructed that is used to map the SBCS
  82. // of SHIFT-JIS fonts.
  83. WARNING("GDI32:Assuming DBCS code page.\n");
  84. st = MultiByteToWideChar
  85. (
  86. 1252, // code page to use
  87. 0, // flags
  88. &ch[1], // characters to translate
  89. 255, // number of multibyte characters
  90. &pwc[1], // unicode values of characters
  91. 255 // number of wide characters
  92. );
  93. if( !NT_SUCCESS(st) )
  94. {
  95. // Clean up and forget about accelerations.
  96. WARNING("GDI32: MultiByteToWideChar error.");
  97. LOCALFREE(pwc);
  98. return(FALSE);
  99. }
  100. // Okay now make a table for SBC bytes. Mark DBCS lead bytes
  101. // with 0xFFFF.
  102. for( jj = 0; jj < 256; jj++ )
  103. {
  104. if( IsDBCSLeadByte( (UCHAR)jj ))
  105. {
  106. pwcSBC[jj] = (WCHAR) 0xFFFF;
  107. }
  108. else
  109. {
  110. st = RtlMultiByteToUnicodeN
  111. (
  112. &pwcSBC[jj],
  113. sizeof(WCHAR),
  114. &cjResult,
  115. &ch[jj],
  116. 1
  117. );
  118. if( !NT_SUCCESS(st) )
  119. {
  120. WARNING("GDI32: RtlMultByteToUnicodeN error.");
  121. LOCALFREE(pwc);
  122. return(FALSE);
  123. }
  124. }
  125. }
  126. }
  127. // The table is good, jam it in. Watch out for another thread running this
  128. // routine simultaneously.
  129. ENTERCRITICALSECTION(&semLocal);
  130. {
  131. if (gpwcANSICharSet == (WCHAR *) NULL)
  132. {
  133. gpwcANSICharSet = pwc;
  134. gpwcDBCSCharSet = pwcSBC;
  135. pwc = (WCHAR *) NULL;
  136. }
  137. }
  138. LEAVECRITICALSECTION(&semLocal);
  139. // If we collided with another thread, clean up our extra space.
  140. if (pwc != (WCHAR *) NULL)
  141. LOCALFREE(pwc);
  142. // At this point we have a valid mapping.
  143. return(TRUE);
  144. }