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.

359 lines
11 KiB

  1. /*++
  2. Copyright (c) 1991-1999, Microsoft Corporation All rights reserved.
  3. Module Name:
  4. c_eucdb.c
  5. Abstract:
  6. This file contains the main functions for this module.
  7. External Routines in this file:
  8. DllEntry
  9. NlsDllCodePageTranslation
  10. Revision History:
  11. 10-30-96 JulieB Created.
  12. --*/
  13. ////////////////////////////////////////////////////////////////////////////
  14. //
  15. // EUC DBCS<->Unicode conversions :
  16. //
  17. // 51932 (Japanese) ............................. calls c_20932.nls
  18. // 51949 (Korean) ............................... calls c_20949.nls
  19. // 51950 (Taiwanese Traditional Chinese) ........ calls c_20950.nls
  20. // 51936 (Chinese Simplified Chinese) ........ calls c_20936.nls
  21. //
  22. ////////////////////////////////////////////////////////////////////////////
  23. //
  24. // Include Files.
  25. //
  26. #include <share.h>
  27. //
  28. // Constant Declarations.
  29. //
  30. #define EUC_J 51932
  31. #define INTERNAL_CODEPAGE(cp) ((cp) - 31000)
  32. //-------------------------------------------------------------------------//
  33. // DLL ENTRY POINT //
  34. //-------------------------------------------------------------------------//
  35. ////////////////////////////////////////////////////////////////////////////
  36. //
  37. // DllEntry
  38. //
  39. // DLL Entry initialization procedure.
  40. //
  41. // 10-30-96 JulieB Created.
  42. ////////////////////////////////////////////////////////////////////////////
  43. BOOL DllEntry(
  44. HANDLE hModule,
  45. DWORD dwReason,
  46. LPVOID lpRes)
  47. {
  48. switch (dwReason)
  49. {
  50. case ( DLL_THREAD_ATTACH ) :
  51. {
  52. return (TRUE);
  53. }
  54. case ( DLL_THREAD_DETACH ) :
  55. {
  56. return (TRUE);
  57. }
  58. case ( DLL_PROCESS_ATTACH ) :
  59. {
  60. return (TRUE);
  61. }
  62. case ( DLL_PROCESS_DETACH ) :
  63. {
  64. return (TRUE);
  65. }
  66. }
  67. return (FALSE);
  68. hModule;
  69. lpRes;
  70. }
  71. //-------------------------------------------------------------------------//
  72. // EXTERNAL ROUTINES //
  73. //-------------------------------------------------------------------------//
  74. ////////////////////////////////////////////////////////////////////////////
  75. //
  76. // NlsDllCodePageTranslation
  77. //
  78. // This routine is the main exported procedure for the functionality in
  79. // this DLL. All calls to this DLL must go through this function.
  80. //
  81. // 10-30-96 JulieB Created.
  82. ////////////////////////////////////////////////////////////////////////////
  83. DWORD NlsDllCodePageTranslation(
  84. DWORD CodePage,
  85. DWORD dwFlags,
  86. LPSTR lpMultiByteStr,
  87. int cchMultiByte,
  88. LPWSTR lpWideCharStr,
  89. int cchWideChar,
  90. LPCPINFO lpCPInfo)
  91. {
  92. int ctr;
  93. int cchMBTemp, cchMBCount;
  94. LPSTR lpMBTempStr;
  95. //
  96. // Error out if internally needed c_*.nls file is not installed.
  97. //
  98. if (!IsValidCodePage(INTERNAL_CODEPAGE(CodePage)))
  99. {
  100. SetLastError(ERROR_INVALID_PARAMETER);
  101. return (0);
  102. }
  103. switch (dwFlags)
  104. {
  105. case ( NLS_CP_CPINFO ) :
  106. {
  107. GetCPInfo(CodePage, lpCPInfo);
  108. if (CodePage == EUC_J)
  109. {
  110. lpCPInfo->MaxCharSize = 3;
  111. }
  112. return (TRUE);
  113. }
  114. case ( NLS_CP_MBTOWC ) :
  115. {
  116. if (CodePage != EUC_J)
  117. {
  118. return (MultiByteToWideChar( INTERNAL_CODEPAGE(CodePage),
  119. 0,
  120. lpMultiByteStr,
  121. cchMultiByte,
  122. lpWideCharStr,
  123. cchWideChar ));
  124. }
  125. //
  126. // CodePage == EUC_J
  127. //
  128. // JIS X 0212-1990
  129. // 0x8F is the first-byte of a 3-byte char :
  130. // Remove 0x8F
  131. // If there is no third byte
  132. // remove the second byte as well,
  133. // else
  134. // leave the second byte unchanged.
  135. // Mask off MSB of the third byte (Byte3 & 0x7F).
  136. // Example : 0x8FA2EF -> 0xA26F
  137. //
  138. if (cchMultiByte == -1)
  139. {
  140. cchMultiByte = strlen(lpMultiByteStr) + 1;
  141. }
  142. lpMBTempStr = (LPSTR)NLS_ALLOC_MEM(cchMultiByte);
  143. if (lpMBTempStr == NULL)
  144. {
  145. SetLastError(ERROR_OUTOFMEMORY);
  146. return (0);
  147. }
  148. for (ctr = 0, cchMBTemp = 0; ctr < cchMultiByte; ctr++, cchMBTemp++)
  149. {
  150. if (lpMultiByteStr[ctr] == (char)0x8F)
  151. {
  152. ctr++;
  153. if (ctr >= (cchMultiByte - 1))
  154. {
  155. //
  156. // Missing second or third byte.
  157. //
  158. break;
  159. }
  160. lpMBTempStr[cchMBTemp++] = lpMultiByteStr[ctr++];
  161. lpMBTempStr[cchMBTemp] = (lpMultiByteStr[ctr] & 0x7F);
  162. }
  163. else
  164. {
  165. lpMBTempStr[cchMBTemp] = lpMultiByteStr[ctr];
  166. }
  167. }
  168. cchMBCount = MultiByteToWideChar( INTERNAL_CODEPAGE(CodePage),
  169. 0,
  170. lpMBTempStr,
  171. cchMBTemp,
  172. lpWideCharStr,
  173. cchWideChar );
  174. NLS_FREE_MEM(lpMBTempStr);
  175. return (cchMBCount);
  176. }
  177. case ( NLS_CP_WCTOMB ) :
  178. {
  179. if (CodePage != EUC_J)
  180. {
  181. return (WideCharToMultiByte( INTERNAL_CODEPAGE(CodePage),
  182. WC_NO_BEST_FIT_CHARS,
  183. lpWideCharStr,
  184. cchWideChar,
  185. lpMultiByteStr,
  186. cchMultiByte,
  187. NULL,
  188. NULL ));
  189. }
  190. //
  191. // CodePage == EUC_J
  192. //
  193. // Check char for JIS X 0212-1990
  194. // if a lead-byte (>= 0x80) followed by a trail-byte (< 0x80)
  195. // then
  196. // insert 0x8F which is the first byte of a 3-byte char
  197. // lead-byte becomes the second byte
  198. // turns on MSB of trail-byte which becomes the third byte
  199. // Example : 0xA26F -> 0x8FA2EF
  200. //
  201. if (cchWideChar == -1)
  202. {
  203. cchWideChar = wcslen(lpWideCharStr);
  204. }
  205. cchMBTemp = cchWideChar * (sizeof(WCHAR) + 1) + 1;
  206. lpMBTempStr = (LPSTR)NLS_ALLOC_MEM(cchMBTemp);
  207. if (lpMBTempStr == NULL)
  208. {
  209. SetLastError(ERROR_OUTOFMEMORY);
  210. return (0);
  211. }
  212. cchMBCount = WideCharToMultiByte( INTERNAL_CODEPAGE(CodePage),
  213. WC_NO_BEST_FIT_CHARS,
  214. lpWideCharStr,
  215. cchWideChar,
  216. lpMBTempStr,
  217. cchMBTemp,
  218. NULL,
  219. NULL );
  220. for (ctr = 0, cchMBTemp = 0;
  221. ctr < cchMBCount, cchMBTemp < cchMultiByte;
  222. ctr++, cchMBTemp++)
  223. {
  224. if (lpMBTempStr[ctr] & 0x80)
  225. {
  226. //
  227. // It's a lead byte.
  228. //
  229. if (lpMBTempStr[ctr + 1] & 0x80)
  230. {
  231. //
  232. // It's a non JIS X 0212-1990 char.
  233. //
  234. if (cchMultiByte)
  235. {
  236. if (cchMBTemp < (cchMultiByte - 1))
  237. {
  238. lpMultiByteStr[cchMBTemp] = lpMBTempStr[ctr];
  239. lpMultiByteStr[cchMBTemp + 1] = lpMBTempStr[ctr + 1];
  240. }
  241. else
  242. {
  243. //
  244. // No room for trail byte.
  245. //
  246. lpMultiByteStr[cchMBTemp++] = '?';
  247. break;
  248. }
  249. }
  250. }
  251. else
  252. {
  253. //
  254. // It's a JIS X 0212-1990 char.
  255. //
  256. if (cchMultiByte)
  257. {
  258. if (cchMBTemp < (cchMultiByte - 2))
  259. {
  260. lpMultiByteStr[cchMBTemp] = (char) 0x8F;
  261. lpMultiByteStr[cchMBTemp + 1] = lpMBTempStr[ctr];
  262. lpMultiByteStr[cchMBTemp + 2] = (lpMBTempStr[ctr + 1] | 0x80);
  263. }
  264. else
  265. {
  266. //
  267. // No room for two trail bytes.
  268. //
  269. lpMultiByteStr[cchMBTemp++] = '?';
  270. break;
  271. }
  272. }
  273. cchMBTemp++;
  274. }
  275. cchMBTemp++;
  276. ctr++;
  277. }
  278. else
  279. {
  280. if (cchMultiByte && (cchMBTemp < cchMultiByte))
  281. {
  282. lpMultiByteStr[cchMBTemp] = lpMBTempStr[ctr];
  283. }
  284. }
  285. }
  286. //
  287. // See if the output buffer is too small.
  288. //
  289. if (cchMultiByte && (cchMBTemp >= cchMultiByte))
  290. {
  291. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  292. return (0);
  293. }
  294. NLS_FREE_MEM (lpMBTempStr);
  295. return (cchMBTemp);
  296. }
  297. }
  298. //
  299. // This shouldn't happen since this gets called by the NLS APIs.
  300. //
  301. SetLastError(ERROR_INVALID_PARAMETER);
  302. return (0);
  303. }