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.

316 lines
8.1 KiB

  1. /*++
  2. Copyright (c) 1997-2000, Microsoft Corporation All rights reserved.
  3. Module Name:
  4. getuname.c
  5. Abstract:
  6. The CharMap accessory uses this DLL to obtain the Unicode name
  7. associated with each 16-bit code value. The names are Win32 string
  8. resources and are localized for some languages. The precomposed
  9. Korean syllables (Hangul) get special treatment to reduce the size
  10. of the string table.
  11. The module contains two external entry points:
  12. GetUName - Called by CharMap to get a name
  13. DLLMain - Invoked by the system when the DLL is loaded and unloaded.
  14. BUGBUGS:
  15. (1) This module does not support UTF-16 (Unicode surrogate) names.
  16. To fix this would require changes to CharMap to pass pairs of code
  17. values.
  18. (2) The HangulName code assumes that the name parts are in the same order
  19. as in English instead of:
  20. "HANGUL SYLLABLE"+leading consonant+medial vowel+trailing consonant
  21. This is a localization sin since it does not work for all languages.
  22. Revision History:
  23. 15-Sep-2000 JohnMcCo Added support for Unicode 3.0
  24. 17-Oct-2000 JulieB Code cleanup
  25. --*/
  26. //
  27. // Include Files.
  28. //
  29. #include <windows.h>
  30. #include <uceshare.h>
  31. #include "getuname.h"
  32. //
  33. // Global Variables.
  34. //
  35. static HINSTANCE g_hInstance = NULL;
  36. ////////////////////////////////////////////////////////////////////////////
  37. //
  38. // CopyUName
  39. //
  40. // Copies the Unicode name of a code value into the buffer.
  41. //
  42. ////////////////////////////////////////////////////////////////////////////
  43. static int CopyUName(
  44. WCHAR wcCodeValue, // Unicode code value
  45. LPWSTR lpBuffer) // pointer to the caller's buffer
  46. {
  47. //
  48. // Attempt to load the string resource with the ID equal to the code
  49. // value.
  50. //
  51. int nLen = LoadString(g_hInstance, wcCodeValue, lpBuffer, MAX_NAME_LEN);
  52. //
  53. // If no such string, return the undefined code value string.
  54. //
  55. if (nLen == 0)
  56. {
  57. nLen = LoadString(g_hInstance, IDS_UNDEFINED, lpBuffer, MAX_NAME_LEN);
  58. }
  59. //
  60. // Return the length of the string copied to the buffer.
  61. //
  62. return (nLen);
  63. }
  64. ////////////////////////////////////////////////////////////////////////////
  65. //
  66. // MakeHangulName
  67. //
  68. // Copy the Unicode name of the Hangul syllable code value into the buffer.
  69. // The Hangul syllable names are composed from the code value. Each name
  70. // consists of three parts:
  71. // leading consonant
  72. // medial vowel
  73. // trailing consonant (which may be null)
  74. // The algorithm is explained in Unicode 3.0 Chapter 3.11
  75. // "Conjoining Jamo Behavior".
  76. //
  77. ////////////////////////////////////////////////////////////////////////////
  78. static int MakeHangulName(
  79. WCHAR wcCodeValue, // Unicode code value
  80. LPWSTR lpBuffer) // pointer to the caller's buffer
  81. {
  82. const int nVowels = 21; // number of medial vowel jamos
  83. const int nTrailing = 28; // number of trailing consonant jamos
  84. //
  85. // Copy the constant part of the name into the buffer.
  86. //
  87. int nLen = LoadString( g_hInstance,
  88. IDS_HANGUL_SYLLABLE,
  89. lpBuffer,
  90. MAX_NAME_LEN );
  91. //
  92. // Turn the code value into an index into the Hangul syllable block.
  93. //
  94. wcCodeValue -= FIRST_HANGUL;
  95. //
  96. // Append the name of the leading consonant.
  97. //
  98. nLen += LoadString( g_hInstance,
  99. IDS_HANGUL_LEADING + wcCodeValue / (nVowels * nTrailing),
  100. &lpBuffer[nLen],
  101. MAX_NAME_LEN );
  102. wcCodeValue %= (nVowels * nTrailing);
  103. //
  104. // Append the name of the medial vowel.
  105. //
  106. nLen += LoadString( g_hInstance,
  107. IDS_HANGUL_MEDIAL + wcCodeValue / nTrailing,
  108. &lpBuffer[nLen],
  109. MAX_NAME_LEN );
  110. wcCodeValue %= nTrailing;
  111. //
  112. // Append the name of the trailing consonant.
  113. //
  114. nLen += LoadString( g_hInstance,
  115. IDS_HANGUL_TRAILING + wcCodeValue,
  116. &lpBuffer[nLen],
  117. MAX_NAME_LEN );
  118. //
  119. // Return the total length.
  120. //
  121. return (nLen);
  122. }
  123. ////////////////////////////////////////////////////////////////////////////
  124. //
  125. // DllMain
  126. //
  127. // This is the DLL init routine.
  128. //
  129. ////////////////////////////////////////////////////////////////////////////
  130. BOOL WINAPI DllMain(
  131. HINSTANCE hInstance, // handle of this DLL
  132. DWORD fdwReason, // reason we are here
  133. LPVOID lpReserved) // reserved and unused
  134. {
  135. //
  136. // If the DLL has just been loaded into memory, save the instance
  137. // handle.
  138. //
  139. if (fdwReason == DLL_PROCESS_ATTACH)
  140. {
  141. g_hInstance = hInstance;
  142. }
  143. return (TRUE);
  144. UNREFERENCED_PARAMETER(lpReserved);
  145. }
  146. ////////////////////////////////////////////////////////////////////////////
  147. //
  148. // GetUName
  149. //
  150. // Copies the name of the Unicode character code value into the caller's
  151. // buffer. The function value is the length of the name if it was found
  152. // and zero if not.
  153. //
  154. ////////////////////////////////////////////////////////////////////////////
  155. int APIENTRY GetUName(
  156. WCHAR wcCodeValue, // Unicode code value
  157. LPWSTR lpBuffer) // pointer to the caller's buffer
  158. {
  159. //
  160. // Perform a series of comparisons to determine in which range the code
  161. // value lies. If there were more ranges, it would be efficient to use
  162. // a binary search. However, with just a few ranges, the overhead is
  163. // greater than the savings, especially since the first comparison
  164. // usually succeeds.
  165. //
  166. //
  167. // MOST SCRIPTS.
  168. //
  169. if (wcCodeValue < FIRST_EXTENSION_A)
  170. {
  171. return (CopyUName(wcCodeValue, lpBuffer));
  172. }
  173. //
  174. // CJK EXTENSION A.
  175. //
  176. else if (wcCodeValue <= LAST_EXTENSION_A)
  177. {
  178. return (LoadString(g_hInstance, IDS_CJK_EXTA, lpBuffer, MAX_NAME_LEN));
  179. }
  180. //
  181. // UNDEFINED.
  182. //
  183. else if (wcCodeValue < FIRST_CJK)
  184. {
  185. return (LoadString(g_hInstance, IDS_UNDEFINED, lpBuffer, MAX_NAME_LEN));
  186. }
  187. //
  188. // CJK.
  189. //
  190. else if (wcCodeValue <= LAST_CJK)
  191. {
  192. return (LoadString(g_hInstance, IDS_CJK, lpBuffer, MAX_NAME_LEN));
  193. }
  194. //
  195. // UNDEFINED.
  196. //
  197. else if (wcCodeValue < FIRST_YI)
  198. {
  199. return (LoadString(g_hInstance, IDS_UNDEFINED, lpBuffer, MAX_NAME_LEN));
  200. }
  201. //
  202. // YI.
  203. //
  204. else if (wcCodeValue < FIRST_HANGUL)
  205. {
  206. return (CopyUName(wcCodeValue, lpBuffer));
  207. }
  208. //
  209. // HANGUL SYLLABLE.
  210. //
  211. else if (wcCodeValue <= LAST_HANGUL)
  212. {
  213. return (MakeHangulName(wcCodeValue, lpBuffer));
  214. }
  215. //
  216. // UNDEFINED.
  217. //
  218. else if (wcCodeValue < FIRST_HIGH_SURROGATE)
  219. {
  220. return (LoadString(g_hInstance, IDS_UNDEFINED, lpBuffer, MAX_NAME_LEN));
  221. }
  222. //
  223. // NON PRIVATE USE HIGH SURROGATE.
  224. //
  225. else if (wcCodeValue < FIRST_PRIVATE_SURROGATE)
  226. {
  227. return (LoadString(g_hInstance, IDS_HIGH_SURROGATE, lpBuffer, MAX_NAME_LEN));
  228. }
  229. //
  230. // PRIVATE USE HIGH SURROGATE.
  231. //
  232. else if (wcCodeValue < FIRST_LOW_SURROGATE)
  233. {
  234. return (LoadString(g_hInstance, IDS_PRIVATE_SURROGATE, lpBuffer, MAX_NAME_LEN));
  235. }
  236. //
  237. // LOW SURROGATE.
  238. //
  239. else if (wcCodeValue < FIRST_PRIVATE_USE)
  240. {
  241. return (LoadString(g_hInstance, IDS_LOW_SURROGATE, lpBuffer, MAX_NAME_LEN));
  242. }
  243. //
  244. // PRIVATE USE.
  245. //
  246. else if (wcCodeValue < FIRST_COMPATIBILITY)
  247. {
  248. return (LoadString(g_hInstance, IDS_PRIVATE_USE, lpBuffer, MAX_NAME_LEN));
  249. }
  250. //
  251. // COMPATIBILITY REGION.
  252. //
  253. else
  254. {
  255. return (CopyUName(wcCodeValue, lpBuffer));
  256. }
  257. }