ReactOS  0.4.14-dev-52-g6116262
win_iconv.c
Go to the documentation of this file.
1 /*
2  * iconv implementation using Win32 API to convert.
3  *
4  * This file is placed in the public domain.
5  */
6 
7 /* for WC_NO_BEST_FIT_CHARS */
8 #ifndef WINVER
9 # define WINVER 0x0500
10 #endif
11 
12 #define STRICT
13 #include <windows.h>
14 #include <errno.h>
15 #include <string.h>
16 #include <stdlib.h>
17 
18 #ifdef __GNUC__
19 #define UNUSED __attribute__((unused))
20 #else
21 #define UNUSED
22 #endif
23 
24 /* WORKAROUND: */
25 #ifndef UNDER_CE
26 #define GetProcAddressA GetProcAddress
27 #endif
28 
29 #if 0
30 # define MAKE_EXE
31 # define MAKE_DLL
32 # define USE_LIBICONV_DLL
33 #endif
34 
35 #if !defined(DEFAULT_LIBICONV_DLL)
36 # define DEFAULT_LIBICONV_DLL ""
37 #endif
38 
39 #define MB_CHAR_MAX 16
40 
41 #define UNICODE_MODE_BOM_DONE 1
42 #define UNICODE_MODE_SWAPPED 2
43 
44 #define FLAG_USE_BOM 1
45 #define FLAG_TRANSLIT 2 /* //TRANSLIT */
46 #define FLAG_IGNORE 4 /* //IGNORE */
47 
48 typedef unsigned char uchar;
49 typedef unsigned short ushort;
50 typedef unsigned int uint;
51 
52 typedef void* iconv_t;
53 
54 iconv_t iconv_open(const char *tocode, const char *fromcode);
56 size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
57 
58 /* libiconv interface for vim */
59 #if defined(MAKE_DLL)
60 int
61 iconvctl (iconv_t cd, int request, void* argument)
62 {
63  /* not supported */
64  return 0;
65 }
66 #endif
67 
68 typedef struct compat_t compat_t;
69 typedef struct csconv_t csconv_t;
70 typedef struct rec_iconv_t rec_iconv_t;
71 
72 typedef iconv_t (*f_iconv_open)(const char *tocode, const char *fromcode);
74 typedef size_t (*f_iconv)(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
75 typedef int* (*f_errno)(void);
76 typedef int (*f_mbtowc)(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
77 typedef int (*f_wctomb)(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
78 typedef int (*f_mblen)(csconv_t *cv, const uchar *buf, int bufsize);
79 typedef int (*f_flush)(csconv_t *cv, uchar *buf, int bufsize);
80 
81 #define COMPAT_IN 1
82 #define COMPAT_OUT 2
83 
84 /* unicode mapping for compatibility with other conversion table. */
85 struct compat_t {
89 };
90 
91 struct csconv_t {
92  int codepage;
93  int flags;
100 };
101 
102 struct rec_iconv_t {
109 #if defined(USE_LIBICONV_DLL)
110  HMODULE hlibiconv;
111 #endif
112 };
113 
114 static int win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode);
115 static int win_iconv_close(iconv_t cd);
116 static size_t win_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
117 
118 static int load_mlang(void);
119 static int make_csconv(const char *name, csconv_t *cv);
120 static int name_to_codepage(const char *name);
121 static uint utf16_to_ucs4(const ushort *wbuf);
122 static void ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize);
123 static int mbtowc_flags(int codepage);
125 static char *strrstr(const char *str, const char *token);
126 static char *xstrndup(const char *s, size_t n);
127 static int seterror(int err);
128 
129 #if defined(USE_LIBICONV_DLL)
130 static int libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode);
131 static PVOID MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size);
132 static FARPROC find_imported_function(HMODULE hModule, const char *funcname);
133 
134 static HMODULE hwiniconv;
135 #endif
136 
137 static int sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);
138 static int dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);
139 static int mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);
140 static int utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize);
141 static int eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize);
142 
143 static int kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
144 static int kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
145 static int mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
146 static int mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
147 static int utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
148 static int utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
149 static int utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
150 static int utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
151 static int iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
152 static int iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
153 static int iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize);
154 
155 static struct {
156  int codepage;
157  const char *name;
158 } codepage_alias[] = {
159  {65001, "CP65001"},
160  {65001, "UTF8"},
161  {65001, "UTF-8"},
162 
163  {1200, "CP1200"},
164  {1200, "UTF16LE"},
165  {1200, "UTF-16LE"},
166  {1200, "UCS2LE"},
167  {1200, "UCS-2LE"},
168 
169  {1201, "CP1201"},
170  {1201, "UTF16BE"},
171  {1201, "UTF-16BE"},
172  {1201, "UCS2BE"},
173  {1201, "UCS-2BE"},
174  {1201, "unicodeFFFE"},
175 
176  {12000, "CP12000"},
177  {12000, "UTF32LE"},
178  {12000, "UTF-32LE"},
179  {12000, "UCS4LE"},
180  {12000, "UCS-4LE"},
181 
182  {12001, "CP12001"},
183  {12001, "UTF32BE"},
184  {12001, "UTF-32BE"},
185  {12001, "UCS4BE"},
186  {12001, "UCS-4BE"},
187 
188 #ifndef GLIB_COMPILATION
189  /*
190  * Default is big endian.
191  * See rfc2781 4.3 Interpreting text labelled as UTF-16.
192  */
193  {1201, "UTF16"},
194  {1201, "UTF-16"},
195  {1201, "UCS2"},
196  {1201, "UCS-2"},
197  {12001, "UTF32"},
198  {12001, "UTF-32"},
199  {12001, "UCS-4"},
200  {12001, "UCS4"},
201 #else
202  /* Default is little endian, because the platform is */
203  {1200, "UTF16"},
204  {1200, "UTF-16"},
205  {1200, "UCS2"},
206  {1200, "UCS-2"},
207  {12000, "UTF32"},
208  {12000, "UTF-32"},
209  {12000, "UCS4"},
210  {12000, "UCS-4"},
211 #endif
212 
213  /* copy from libiconv `iconv -l` */
214  /* !IsValidCodePage(367) */
215  {20127, "ANSI_X3.4-1968"},
216  {20127, "ANSI_X3.4-1986"},
217  {20127, "ASCII"},
218  {20127, "CP367"},
219  {20127, "IBM367"},
220  {20127, "ISO-IR-6"},
221  {20127, "ISO646-US"},
222  {20127, "ISO_646.IRV:1991"},
223  {20127, "US"},
224  {20127, "US-ASCII"},
225  {20127, "CSASCII"},
226 
227  /* !IsValidCodePage(819) */
228  {1252, "CP819"},
229  {1252, "IBM819"},
230  {28591, "ISO-8859-1"},
231  {28591, "ISO-IR-100"},
232  {28591, "ISO8859-1"},
233  {28591, "ISO_8859-1"},
234  {28591, "ISO_8859-1:1987"},
235  {28591, "L1"},
236  {28591, "LATIN1"},
237  {28591, "CSISOLATIN1"},
238 
239  {1250, "CP1250"},
240  {1250, "MS-EE"},
241  {1250, "WINDOWS-1250"},
242 
243  {1251, "CP1251"},
244  {1251, "MS-CYRL"},
245  {1251, "WINDOWS-1251"},
246 
247  {1252, "CP1252"},
248  {1252, "MS-ANSI"},
249  {1252, "WINDOWS-1252"},
250 
251  {1253, "CP1253"},
252  {1253, "MS-GREEK"},
253  {1253, "WINDOWS-1253"},
254 
255  {1254, "CP1254"},
256  {1254, "MS-TURK"},
257  {1254, "WINDOWS-1254"},
258 
259  {1255, "CP1255"},
260  {1255, "MS-HEBR"},
261  {1255, "WINDOWS-1255"},
262 
263  {1256, "CP1256"},
264  {1256, "MS-ARAB"},
265  {1256, "WINDOWS-1256"},
266 
267  {1257, "CP1257"},
268  {1257, "WINBALTRIM"},
269  {1257, "WINDOWS-1257"},
270 
271  {1258, "CP1258"},
272  {1258, "WINDOWS-1258"},
273 
274  {850, "850"},
275  {850, "CP850"},
276  {850, "IBM850"},
277  {850, "CSPC850MULTILINGUAL"},
278 
279  /* !IsValidCodePage(862) */
280  {862, "862"},
281  {862, "CP862"},
282  {862, "IBM862"},
283  {862, "CSPC862LATINHEBREW"},
284 
285  {866, "866"},
286  {866, "CP866"},
287  {866, "IBM866"},
288  {866, "CSIBM866"},
289 
290  /* !IsValidCodePage(154) */
291  {154, "CP154"},
292  {154, "CYRILLIC-ASIAN"},
293  {154, "PT154"},
294  {154, "PTCP154"},
295  {154, "CSPTCP154"},
296 
297  /* !IsValidCodePage(1133) */
298  {1133, "CP1133"},
299  {1133, "IBM-CP1133"},
300 
301  {874, "CP874"},
302  {874, "WINDOWS-874"},
303 
304  /* !IsValidCodePage(51932) */
305  {51932, "CP51932"},
306  {51932, "MS51932"},
307  {51932, "WINDOWS-51932"},
308  {51932, "EUC-JP"},
309 
310  {932, "CP932"},
311  {932, "MS932"},
312  {932, "SHIFFT_JIS"},
313  {932, "SHIFFT_JIS-MS"},
314  {932, "SJIS"},
315  {932, "SJIS-MS"},
316  {932, "SJIS-OPEN"},
317  {932, "SJIS-WIN"},
318  {932, "WINDOWS-31J"},
319  {932, "WINDOWS-932"},
320  {932, "CSWINDOWS31J"},
321 
322  {50221, "CP50221"},
323  {50221, "ISO-2022-JP"},
324  {50221, "ISO-2022-JP-MS"},
325  {50221, "ISO2022-JP"},
326  {50221, "ISO2022-JP-MS"},
327  {50221, "MS50221"},
328  {50221, "WINDOWS-50221"},
329 
330  {936, "CP936"},
331  {936, "GBK"},
332  {936, "MS936"},
333  {936, "WINDOWS-936"},
334 
335  {950, "CP950"},
336  {950, "BIG5"},
337  {950, "BIG5HKSCS"},
338  {950, "BIG5-HKSCS"},
339 
340  {949, "CP949"},
341  {949, "UHC"},
342  {949, "EUC-KR"},
343 
344  {1361, "CP1361"},
345  {1361, "JOHAB"},
346 
347  {437, "437"},
348  {437, "CP437"},
349  {437, "IBM437"},
350  {437, "CSPC8CODEPAGE437"},
351 
352  {737, "CP737"},
353 
354  {775, "CP775"},
355  {775, "IBM775"},
356  {775, "CSPC775BALTIC"},
357 
358  {852, "852"},
359  {852, "CP852"},
360  {852, "IBM852"},
361  {852, "CSPCP852"},
362 
363  /* !IsValidCodePage(853) */
364  {853, "CP853"},
365 
366  {855, "855"},
367  {855, "CP855"},
368  {855, "IBM855"},
369  {855, "CSIBM855"},
370 
371  {857, "857"},
372  {857, "CP857"},
373  {857, "IBM857"},
374  {857, "CSIBM857"},
375 
376  /* !IsValidCodePage(858) */
377  {858, "CP858"},
378 
379  {860, "860"},
380  {860, "CP860"},
381  {860, "IBM860"},
382  {860, "CSIBM860"},
383 
384  {861, "861"},
385  {861, "CP-IS"},
386  {861, "CP861"},
387  {861, "IBM861"},
388  {861, "CSIBM861"},
389 
390  {863, "863"},
391  {863, "CP863"},
392  {863, "IBM863"},
393  {863, "CSIBM863"},
394 
395  {864, "CP864"},
396  {864, "IBM864"},
397  {864, "CSIBM864"},
398 
399  {865, "865"},
400  {865, "CP865"},
401  {865, "IBM865"},
402  {865, "CSIBM865"},
403 
404  {869, "869"},
405  {869, "CP-GR"},
406  {869, "CP869"},
407  {869, "IBM869"},
408  {869, "CSIBM869"},
409 
410  /* !IsValidCodePage(1152) */
411  {1125, "CP1125"},
412 
413  /*
414  * Code Page Identifiers
415  * http://msdn2.microsoft.com/en-us/library/ms776446.aspx
416  */
417  {37, "IBM037"}, /* IBM EBCDIC US-Canada */
418  {437, "IBM437"}, /* OEM United States */
419  {500, "IBM500"}, /* IBM EBCDIC International */
420  {708, "ASMO-708"}, /* Arabic (ASMO 708) */
421  /* 709 Arabic (ASMO-449+, BCON V4) */
422  /* 710 Arabic - Transparent Arabic */
423  {720, "DOS-720"}, /* Arabic (Transparent ASMO); Arabic (DOS) */
424  {737, "ibm737"}, /* OEM Greek (formerly 437G); Greek (DOS) */
425  {775, "ibm775"}, /* OEM Baltic; Baltic (DOS) */
426  {850, "ibm850"}, /* OEM Multilingual Latin 1; Western European (DOS) */
427  {852, "ibm852"}, /* OEM Latin 2; Central European (DOS) */
428  {855, "IBM855"}, /* OEM Cyrillic (primarily Russian) */
429  {857, "ibm857"}, /* OEM Turkish; Turkish (DOS) */
430  {858, "IBM00858"}, /* OEM Multilingual Latin 1 + Euro symbol */
431  {860, "IBM860"}, /* OEM Portuguese; Portuguese (DOS) */
432  {861, "ibm861"}, /* OEM Icelandic; Icelandic (DOS) */
433  {862, "DOS-862"}, /* OEM Hebrew; Hebrew (DOS) */
434  {863, "IBM863"}, /* OEM French Canadian; French Canadian (DOS) */
435  {864, "IBM864"}, /* OEM Arabic; Arabic (864) */
436  {865, "IBM865"}, /* OEM Nordic; Nordic (DOS) */
437  {866, "cp866"}, /* OEM Russian; Cyrillic (DOS) */
438  {869, "ibm869"}, /* OEM Modern Greek; Greek, Modern (DOS) */
439  {870, "IBM870"}, /* IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2 */
440  {874, "windows-874"}, /* ANSI/OEM Thai (same as 28605, ISO 8859-15); Thai (Windows) */
441  {875, "cp875"}, /* IBM EBCDIC Greek Modern */
442  {932, "shift_jis"}, /* ANSI/OEM Japanese; Japanese (Shift-JIS) */
443  {932, "shift-jis"}, /* alternative name for it */
444  {936, "gb2312"}, /* ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) */
445  {949, "ks_c_5601-1987"}, /* ANSI/OEM Korean (Unified Hangul Code) */
446  {950, "big5"}, /* ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) */
447  {950, "big5hkscs"}, /* ANSI/OEM Traditional Chinese (Hong Kong SAR); Chinese Traditional (Big5-HKSCS) */
448  {950, "big5-hkscs"}, /* alternative name for it */
449  {1026, "IBM1026"}, /* IBM EBCDIC Turkish (Latin 5) */
450  {1047, "IBM01047"}, /* IBM EBCDIC Latin 1/Open System */
451  {1140, "IBM01140"}, /* IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro) */
452  {1141, "IBM01141"}, /* IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro) */
453  {1142, "IBM01142"}, /* IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro) */
454  {1143, "IBM01143"}, /* IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro) */
455  {1144, "IBM01144"}, /* IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro) */
456  {1145, "IBM01145"}, /* IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro) */
457  {1146, "IBM01146"}, /* IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro) */
458  {1147, "IBM01147"}, /* IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro) */
459  {1148, "IBM01148"}, /* IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro) */
460  {1149, "IBM01149"}, /* IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro) */
461  {1250, "windows-1250"}, /* ANSI Central European; Central European (Windows) */
462  {1251, "windows-1251"}, /* ANSI Cyrillic; Cyrillic (Windows) */
463  {1252, "windows-1252"}, /* ANSI Latin 1; Western European (Windows) */
464  {1253, "windows-1253"}, /* ANSI Greek; Greek (Windows) */
465  {1254, "windows-1254"}, /* ANSI Turkish; Turkish (Windows) */
466  {1255, "windows-1255"}, /* ANSI Hebrew; Hebrew (Windows) */
467  {1256, "windows-1256"}, /* ANSI Arabic; Arabic (Windows) */
468  {1257, "windows-1257"}, /* ANSI Baltic; Baltic (Windows) */
469  {1258, "windows-1258"}, /* ANSI/OEM Vietnamese; Vietnamese (Windows) */
470  {1361, "Johab"}, /* Korean (Johab) */
471  {10000, "macintosh"}, /* MAC Roman; Western European (Mac) */
472  {10001, "x-mac-japanese"}, /* Japanese (Mac) */
473  {10002, "x-mac-chinesetrad"}, /* MAC Traditional Chinese (Big5); Chinese Traditional (Mac) */
474  {10003, "x-mac-korean"}, /* Korean (Mac) */
475  {10004, "x-mac-arabic"}, /* Arabic (Mac) */
476  {10005, "x-mac-hebrew"}, /* Hebrew (Mac) */
477  {10006, "x-mac-greek"}, /* Greek (Mac) */
478  {10007, "x-mac-cyrillic"}, /* Cyrillic (Mac) */
479  {10008, "x-mac-chinesesimp"}, /* MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac) */
480  {10010, "x-mac-romanian"}, /* Romanian (Mac) */
481  {10017, "x-mac-ukrainian"}, /* Ukrainian (Mac) */
482  {10021, "x-mac-thai"}, /* Thai (Mac) */
483  {10029, "x-mac-ce"}, /* MAC Latin 2; Central European (Mac) */
484  {10079, "x-mac-icelandic"}, /* Icelandic (Mac) */
485  {10081, "x-mac-turkish"}, /* Turkish (Mac) */
486  {10082, "x-mac-croatian"}, /* Croatian (Mac) */
487  {20000, "x-Chinese_CNS"}, /* CNS Taiwan; Chinese Traditional (CNS) */
488  {20001, "x-cp20001"}, /* TCA Taiwan */
489  {20002, "x_Chinese-Eten"}, /* Eten Taiwan; Chinese Traditional (Eten) */
490  {20003, "x-cp20003"}, /* IBM5550 Taiwan */
491  {20004, "x-cp20004"}, /* TeleText Taiwan */
492  {20005, "x-cp20005"}, /* Wang Taiwan */
493  {20105, "x-IA5"}, /* IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5) */
494  {20106, "x-IA5-German"}, /* IA5 German (7-bit) */
495  {20107, "x-IA5-Swedish"}, /* IA5 Swedish (7-bit) */
496  {20108, "x-IA5-Norwegian"}, /* IA5 Norwegian (7-bit) */
497  {20127, "us-ascii"}, /* US-ASCII (7-bit) */
498  {20261, "x-cp20261"}, /* T.61 */
499  {20269, "x-cp20269"}, /* ISO 6937 Non-Spacing Accent */
500  {20273, "IBM273"}, /* IBM EBCDIC Germany */
501  {20277, "IBM277"}, /* IBM EBCDIC Denmark-Norway */
502  {20278, "IBM278"}, /* IBM EBCDIC Finland-Sweden */
503  {20280, "IBM280"}, /* IBM EBCDIC Italy */
504  {20284, "IBM284"}, /* IBM EBCDIC Latin America-Spain */
505  {20285, "IBM285"}, /* IBM EBCDIC United Kingdom */
506  {20290, "IBM290"}, /* IBM EBCDIC Japanese Katakana Extended */
507  {20297, "IBM297"}, /* IBM EBCDIC France */
508  {20420, "IBM420"}, /* IBM EBCDIC Arabic */
509  {20423, "IBM423"}, /* IBM EBCDIC Greek */
510  {20424, "IBM424"}, /* IBM EBCDIC Hebrew */
511  {20833, "x-EBCDIC-KoreanExtended"}, /* IBM EBCDIC Korean Extended */
512  {20838, "IBM-Thai"}, /* IBM EBCDIC Thai */
513  {20866, "koi8-r"}, /* Russian (KOI8-R); Cyrillic (KOI8-R) */
514  {20871, "IBM871"}, /* IBM EBCDIC Icelandic */
515  {20880, "IBM880"}, /* IBM EBCDIC Cyrillic Russian */
516  {20905, "IBM905"}, /* IBM EBCDIC Turkish */
517  {20924, "IBM00924"}, /* IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) */
518  {20932, "EUC-JP"}, /* Japanese (JIS 0208-1990 and 0121-1990) */
519  {20936, "x-cp20936"}, /* Simplified Chinese (GB2312); Chinese Simplified (GB2312-80) */
520  {20949, "x-cp20949"}, /* Korean Wansung */
521  {21025, "cp1025"}, /* IBM EBCDIC Cyrillic Serbian-Bulgarian */
522  /* 21027 (deprecated) */
523  {21866, "koi8-u"}, /* Ukrainian (KOI8-U); Cyrillic (KOI8-U) */
524  {28591, "iso-8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */
525  {28591, "iso8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */
526  {28591, "iso_8859-1"},
527  {28591, "iso_8859_1"},
528  {28592, "iso-8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */
529  {28592, "iso8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */
530  {28592, "iso_8859-2"},
531  {28592, "iso_8859_2"},
532  {28593, "iso-8859-3"}, /* ISO 8859-3 Latin 3 */
533  {28593, "iso8859-3"}, /* ISO 8859-3 Latin 3 */
534  {28593, "iso_8859-3"},
535  {28593, "iso_8859_3"},
536  {28594, "iso-8859-4"}, /* ISO 8859-4 Baltic */
537  {28594, "iso8859-4"}, /* ISO 8859-4 Baltic */
538  {28594, "iso_8859-4"},
539  {28594, "iso_8859_4"},
540  {28595, "iso-8859-5"}, /* ISO 8859-5 Cyrillic */
541  {28595, "iso8859-5"}, /* ISO 8859-5 Cyrillic */
542  {28595, "iso_8859-5"},
543  {28595, "iso_8859_5"},
544  {28596, "iso-8859-6"}, /* ISO 8859-6 Arabic */
545  {28596, "iso8859-6"}, /* ISO 8859-6 Arabic */
546  {28596, "iso_8859-6"},
547  {28596, "iso_8859_6"},
548  {28597, "iso-8859-7"}, /* ISO 8859-7 Greek */
549  {28597, "iso8859-7"}, /* ISO 8859-7 Greek */
550  {28597, "iso_8859-7"},
551  {28597, "iso_8859_7"},
552  {28598, "iso-8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */
553  {28598, "iso8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */
554  {28598, "iso_8859-8"},
555  {28598, "iso_8859_8"},
556  {28599, "iso-8859-9"}, /* ISO 8859-9 Turkish */
557  {28599, "iso8859-9"}, /* ISO 8859-9 Turkish */
558  {28599, "iso_8859-9"},
559  {28599, "iso_8859_9"},
560  {28603, "iso-8859-13"}, /* ISO 8859-13 Estonian */
561  {28603, "iso8859-13"}, /* ISO 8859-13 Estonian */
562  {28603, "iso_8859-13"},
563  {28603, "iso_8859_13"},
564  {28605, "iso-8859-15"}, /* ISO 8859-15 Latin 9 */
565  {28605, "iso8859-15"}, /* ISO 8859-15 Latin 9 */
566  {28605, "iso_8859-15"},
567  {28605, "iso_8859_15"},
568  {29001, "x-Europa"}, /* Europa 3 */
569  {38598, "iso-8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */
570  {38598, "iso8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */
571  {38598, "iso_8859-8-i"},
572  {38598, "iso_8859_8-i"},
573  {50220, "iso-2022-jp"}, /* ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) */
574  {50221, "csISO2022JP"}, /* ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) */
575  {50222, "iso-2022-jp"}, /* ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) */
576  {50225, "iso-2022-kr"}, /* ISO 2022 Korean */
577  {50225, "iso2022-kr"}, /* ISO 2022 Korean */
578  {50227, "x-cp50227"}, /* ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022) */
579  /* 50229 ISO 2022 Traditional Chinese */
580  /* 50930 EBCDIC Japanese (Katakana) Extended */
581  /* 50931 EBCDIC US-Canada and Japanese */
582  /* 50933 EBCDIC Korean Extended and Korean */
583  /* 50935 EBCDIC Simplified Chinese Extended and Simplified Chinese */
584  /* 50936 EBCDIC Simplified Chinese */
585  /* 50937 EBCDIC US-Canada and Traditional Chinese */
586  /* 50939 EBCDIC Japanese (Latin) Extended and Japanese */
587  {51932, "euc-jp"}, /* EUC Japanese */
588  {51936, "EUC-CN"}, /* EUC Simplified Chinese; Chinese Simplified (EUC) */
589  {51949, "euc-kr"}, /* EUC Korean */
590  /* 51950 EUC Traditional Chinese */
591  {52936, "hz-gb-2312"}, /* HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ) */
592  {54936, "GB18030"}, /* Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030) */
593  {57002, "x-iscii-de"}, /* ISCII Devanagari */
594  {57003, "x-iscii-be"}, /* ISCII Bengali */
595  {57004, "x-iscii-ta"}, /* ISCII Tamil */
596  {57005, "x-iscii-te"}, /* ISCII Telugu */
597  {57006, "x-iscii-as"}, /* ISCII Assamese */
598  {57007, "x-iscii-or"}, /* ISCII Oriya */
599  {57008, "x-iscii-ka"}, /* ISCII Kannada */
600  {57009, "x-iscii-ma"}, /* ISCII Malayalam */
601  {57010, "x-iscii-gu"}, /* ISCII Gujarati */
602  {57011, "x-iscii-pa"}, /* ISCII Punjabi */
603 
604  {0, NULL}
605 };
606 
607 /*
608  * SJIS SHIFTJIS table CP932 table
609  * ---- --------------------------- --------------------------------
610  * 5C U+00A5 YEN SIGN U+005C REVERSE SOLIDUS
611  * 7E U+203E OVERLINE U+007E TILDE
612  * 815C U+2014 EM DASH U+2015 HORIZONTAL BAR
613  * 815F U+005C REVERSE SOLIDUS U+FF3C FULLWIDTH REVERSE SOLIDUS
614  * 8160 U+301C WAVE DASH U+FF5E FULLWIDTH TILDE
615  * 8161 U+2016 DOUBLE VERTICAL LINE U+2225 PARALLEL TO
616  * 817C U+2212 MINUS SIGN U+FF0D FULLWIDTH HYPHEN-MINUS
617  * 8191 U+00A2 CENT SIGN U+FFE0 FULLWIDTH CENT SIGN
618  * 8192 U+00A3 POUND SIGN U+FFE1 FULLWIDTH POUND SIGN
619  * 81CA U+00AC NOT SIGN U+FFE2 FULLWIDTH NOT SIGN
620  *
621  * EUC-JP and ISO-2022-JP should be compatible with CP932.
622  *
623  * Kernel and MLang have different Unicode mapping table. Make sure
624  * which API is used.
625  */
626 static compat_t cp932_compat[] = {
627  {0x00A5, 0x005C, COMPAT_OUT},
628  {0x203E, 0x007E, COMPAT_OUT},
629  {0x2014, 0x2015, COMPAT_OUT},
630  {0x301C, 0xFF5E, COMPAT_OUT},
631  {0x2016, 0x2225, COMPAT_OUT},
632  {0x2212, 0xFF0D, COMPAT_OUT},
633  {0x00A2, 0xFFE0, COMPAT_OUT},
634  {0x00A3, 0xFFE1, COMPAT_OUT},
635  {0x00AC, 0xFFE2, COMPAT_OUT},
636  {0, 0, 0}
637 };
638 
640  {0x00A5, 0x005C, COMPAT_OUT},
641  {0x203E, 0x007E, COMPAT_OUT},
642  {0x2014, 0x2015, COMPAT_OUT},
643  {0xFF5E, 0x301C, COMPAT_OUT|COMPAT_IN},
644  {0x2225, 0x2016, COMPAT_OUT|COMPAT_IN},
645  {0xFF0D, 0x2212, COMPAT_OUT|COMPAT_IN},
646  {0xFFE0, 0x00A2, COMPAT_OUT|COMPAT_IN},
647  {0xFFE1, 0x00A3, COMPAT_OUT|COMPAT_IN},
648  {0xFFE2, 0x00AC, COMPAT_OUT|COMPAT_IN},
649  {0, 0, 0}
650 };
651 
653 
654 /* cp20932_compat for kernel. cp932_compat for mlang. */
656 
658  LPDWORD lpdwMode,
659  DWORD dwSrcEncoding,
660  DWORD dwDstEncoding,
661  LPCSTR lpSrcStr,
662  LPINT lpnSrcSize,
663  LPBYTE lpDstStr,
664  LPINT lpnDstSize
665 );
667  LPDWORD lpdwMode,
668  DWORD dwSrcEncoding,
669  LPCSTR lpSrcStr,
670  LPINT lpnMultiCharCount,
671  LPWSTR lpDstStr,
672  LPINT lpnWideCharCount
673 );
675  LPDWORD lpdwMode,
676  DWORD dwEncoding,
677  LPCWSTR lpSrcStr,
678  LPINT lpnWideCharCount,
679  LPSTR lpDstStr,
680  LPINT lpnMultiCharCount
681 );
683  DWORD dwSrcEncoding,
684  DWORD dwDstEncoding
685 );
687  LCID Locale,
688  LPSTR pszRfc1766,
689  int nChar
690 );
692  LCID Locale,
693  LPWSTR pszRfc1766,
694  int nChar
695 );
697  LCID *pLocale,
698  LPSTR pszRfc1766
699 );
701  LCID *pLocale,
702  LPWSTR pszRfc1766
703 );
710 
711 static int
713 {
714  HMODULE h;
715  if (ConvertINetString != NULL)
716  return TRUE;
717  h = LoadLibrary(TEXT("mlang.dll"));
718  if (!h)
719  return FALSE;
720  ConvertINetString = (CONVERTINETSTRING)GetProcAddressA(h, "ConvertINetString");
724  LcidToRfc1766A = (LCIDTORFC1766A)GetProcAddressA(h, "LcidToRfc1766A");
725  Rfc1766ToLcidA = (RFC1766TOLCIDA)GetProcAddressA(h, "Rfc1766ToLcidA");
726  return TRUE;
727 }
728 
729 iconv_t
730 iconv_open(const char *tocode, const char *fromcode)
731 {
732  rec_iconv_t *cd;
733 
734  cd = (rec_iconv_t *)calloc(1, sizeof(rec_iconv_t));
735  if (cd == NULL)
736  return (iconv_t)(-1);
737 
738 #if defined(USE_LIBICONV_DLL)
739  errno = 0;
740  if (libiconv_iconv_open(cd, tocode, fromcode))
741  return (iconv_t)cd;
742 #endif
743 
744  /* reset the errno to prevent reporting wrong error code.
745  * 0 for unsorted error. */
746  errno = 0;
747  if (win_iconv_open(cd, tocode, fromcode))
748  return (iconv_t)cd;
749 
750  free(cd);
751 
752  return (iconv_t)(-1);
753 }
754 
755 int
757 {
758  rec_iconv_t *cd = (rec_iconv_t *)_cd;
759  int r = cd->iconv_close(cd->cd);
760  int e = *(cd->_errno());
761 #if defined(USE_LIBICONV_DLL)
762  if (cd->hlibiconv != NULL)
763  FreeLibrary(cd->hlibiconv);
764 #endif
765  free(cd);
766  errno = e;
767  return r;
768 }
769 
770 size_t
771 iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
772 {
773  rec_iconv_t *cd = (rec_iconv_t *)_cd;
774  size_t r = cd->iconv(cd->cd, inbuf, inbytesleft, outbuf, outbytesleft);
775  errno = *(cd->_errno());
776  return r;
777 }
778 
779 static int
780 win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode)
781 {
782  if (!make_csconv(fromcode, &cd->from) || !make_csconv(tocode, &cd->to))
783  return FALSE;
784  cd->iconv_close = win_iconv_close;
785  cd->iconv = win_iconv;
786  cd->_errno = _errno;
787  cd->cd = (iconv_t)cd;
788  return TRUE;
789 }
790 
791 static int
793 {
794  return 0;
795 }
796 
797 static size_t
798 win_iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
799 {
800  rec_iconv_t *cd = (rec_iconv_t *)_cd;
801  ushort wbuf[MB_CHAR_MAX]; /* enough room for one character */
802  int insize;
803  int outsize;
804  int wsize;
805  DWORD frommode;
806  DWORD tomode;
807  uint wc;
808  compat_t *cp;
809  int i;
810 
811  if (inbuf == NULL || *inbuf == NULL)
812  {
813  if (outbuf != NULL && *outbuf != NULL && cd->to.flush != NULL)
814  {
815  tomode = cd->to.mode;
816  outsize = cd->to.flush(&cd->to, (uchar *)*outbuf, *outbytesleft);
817  if (outsize == -1)
818  {
819  if ((cd->to.flags & FLAG_IGNORE) && errno != E2BIG)
820  {
821  outsize = 0;
822  }
823  else
824  {
825  cd->to.mode = tomode;
826  return (size_t)(-1);
827  }
828  }
829  *outbuf += outsize;
830  *outbytesleft -= outsize;
831  }
832  cd->from.mode = 0;
833  cd->to.mode = 0;
834  return 0;
835  }
836 
837  while (*inbytesleft != 0)
838  {
839  frommode = cd->from.mode;
840  tomode = cd->to.mode;
841  wsize = MB_CHAR_MAX;
842 
843  insize = cd->from.mbtowc(&cd->from, (const uchar *)*inbuf, *inbytesleft, wbuf, &wsize);
844  if (insize == -1)
845  {
846  if (cd->to.flags & FLAG_IGNORE)
847  {
848  cd->from.mode = frommode;
849  insize = 1;
850  wsize = 0;
851  }
852  else
853  {
854  cd->from.mode = frommode;
855  return (size_t)(-1);
856  }
857  }
858 
859  if (wsize == 0)
860  {
861  *inbuf += insize;
862  *inbytesleft -= insize;
863  continue;
864  }
865 
866  if (cd->from.compat != NULL)
867  {
868  wc = utf16_to_ucs4(wbuf);
869  cp = cd->from.compat;
870  for (i = 0; cp[i].in != 0; ++i)
871  {
872  if ((cp[i].flag & COMPAT_IN) && cp[i].out == wc)
873  {
874  ucs4_to_utf16(cp[i].in, wbuf, &wsize);
875  break;
876  }
877  }
878  }
879 
880  if (cd->to.compat != NULL)
881  {
882  wc = utf16_to_ucs4(wbuf);
883  cp = cd->to.compat;
884  for (i = 0; cp[i].in != 0; ++i)
885  {
886  if ((cp[i].flag & COMPAT_OUT) && cp[i].in == wc)
887  {
888  ucs4_to_utf16(cp[i].out, wbuf, &wsize);
889  break;
890  }
891  }
892  }
893 
894  outsize = cd->to.wctomb(&cd->to, wbuf, wsize, (uchar *)*outbuf, *outbytesleft);
895  if (outsize == -1)
896  {
897  if ((cd->to.flags & FLAG_IGNORE) && errno != E2BIG)
898  {
899  cd->to.mode = tomode;
900  outsize = 0;
901  }
902  else
903  {
904  cd->from.mode = frommode;
905  cd->to.mode = tomode;
906  return (size_t)(-1);
907  }
908  }
909 
910  *inbuf += insize;
911  *outbuf += outsize;
912  *inbytesleft -= insize;
913  *outbytesleft -= outsize;
914  }
915 
916  return 0;
917 }
918 
919 static int
920 make_csconv(const char *_name, csconv_t *cv)
921 {
922  CPINFO cpinfo;
923  int use_compat = TRUE;
924  int flag = 0;
925  char *name;
926  char *p;
927 
928  name = xstrndup(_name, strlen(_name));
929  if (name == NULL)
930  return FALSE;
931 
932  /* check for option "enc_name//opt1//opt2" */
933  while ((p = strrstr(name, "//")) != NULL)
934  {
935  if (_stricmp(p + 2, "nocompat") == 0)
936  use_compat = FALSE;
937  else if (_stricmp(p + 2, "translit") == 0)
938  flag |= FLAG_TRANSLIT;
939  else if (_stricmp(p + 2, "ignore") == 0)
940  flag |= FLAG_IGNORE;
941  *p = 0;
942  }
943 
944  cv->mode = 0;
945  cv->flags = flag;
946  cv->mblen = NULL;
947  cv->flush = NULL;
948  cv->compat = NULL;
950  if (cv->codepage == 1200 || cv->codepage == 1201)
951  {
952  cv->mbtowc = utf16_mbtowc;
953  cv->wctomb = utf16_wctomb;
954  if (_stricmp(name, "UTF-16") == 0 || _stricmp(name, "UTF16") == 0 ||
955  _stricmp(name, "UCS-2") == 0 || _stricmp(name, "UCS2") == 0)
956  cv->flags |= FLAG_USE_BOM;
957  }
958  else if (cv->codepage == 12000 || cv->codepage == 12001)
959  {
960  cv->mbtowc = utf32_mbtowc;
961  cv->wctomb = utf32_wctomb;
962  if (_stricmp(name, "UTF-32") == 0 || _stricmp(name, "UTF32") == 0 ||
963  _stricmp(name, "UCS-4") == 0 || _stricmp(name, "UCS4") == 0)
964  cv->flags |= FLAG_USE_BOM;
965  }
966  else if (cv->codepage == 65001)
967  {
968  cv->mbtowc = kernel_mbtowc;
969  cv->wctomb = kernel_wctomb;
970  cv->mblen = utf8_mblen;
971  }
972  else if ((cv->codepage == 50220 || cv->codepage == 50221 || cv->codepage == 50222) && load_mlang())
973  {
974  cv->mbtowc = iso2022jp_mbtowc;
975  cv->wctomb = iso2022jp_wctomb;
976  cv->flush = iso2022jp_flush;
977  }
978  else if (cv->codepage == 51932 && load_mlang())
979  {
980  cv->mbtowc = mlang_mbtowc;
981  cv->wctomb = mlang_wctomb;
982  cv->mblen = eucjp_mblen;
983  }
984  else if (IsValidCodePage(cv->codepage)
985  && GetCPInfo(cv->codepage, &cpinfo) != 0)
986  {
987  cv->mbtowc = kernel_mbtowc;
988  cv->wctomb = kernel_wctomb;
989  if (cpinfo.MaxCharSize == 1)
990  cv->mblen = sbcs_mblen;
991  else if (cpinfo.MaxCharSize == 2)
992  cv->mblen = dbcs_mblen;
993  else
994  cv->mblen = mbcs_mblen;
995  }
996  else
997  {
998  /* not supported */
999  free(name);
1000  errno = EINVAL;
1001  return FALSE;
1002  }
1003 
1004  if (use_compat)
1005  {
1006  switch (cv->codepage)
1007  {
1008  case 932: cv->compat = cp932_compat; break;
1009  case 20932: cv->compat = cp20932_compat; break;
1010  case 51932: cv->compat = cp51932_compat; break;
1011  case 50220: case 50221: case 50222: cv->compat = cp5022x_compat; break;
1012  }
1013  }
1014 
1015  free(name);
1016 
1017  return TRUE;
1018 }
1019 
1020 static int
1022 {
1023  int i;
1024 
1025  if (*name == '\0' ||
1026  strcmp(name, "char") == 0)
1027  return GetACP();
1028  else if (strcmp(name, "wchar_t") == 0)
1029  return 1200;
1030  else if (_strnicmp(name, "cp", 2) == 0)
1031  return atoi(name + 2); /* CP123 */
1032  else if ('0' <= name[0] && name[0] <= '9')
1033  return atoi(name); /* 123 */
1034  else if (_strnicmp(name, "xx", 2) == 0)
1035  return atoi(name + 2); /* XX123 for debug */
1036 
1037  for (i = 0; codepage_alias[i].name != NULL; ++i)
1038  if (_stricmp(name, codepage_alias[i].name) == 0)
1039  return codepage_alias[i].codepage;
1040  return -1;
1041 }
1042 
1043 /*
1044  * http://www.faqs.org/rfcs/rfc2781.html
1045  */
1046 static uint
1047 utf16_to_ucs4(const ushort *wbuf)
1048 {
1049  uint wc = wbuf[0];
1050  if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)
1051  wc = ((wbuf[0] & 0x3FF) << 10) + (wbuf[1] & 0x3FF) + 0x10000;
1052  return wc;
1053 }
1054 
1055 static void
1056 ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize)
1057 {
1058  if (wc < 0x10000)
1059  {
1060  wbuf[0] = wc;
1061  *wbufsize = 1;
1062  }
1063  else
1064  {
1065  wc -= 0x10000;
1066  wbuf[0] = 0xD800 | ((wc >> 10) & 0x3FF);
1067  wbuf[1] = 0xDC00 | (wc & 0x3FF);
1068  *wbufsize = 2;
1069  }
1070 }
1071 
1072 /*
1073  * Check if codepage is one of those for which the dwFlags parameter
1074  * to MultiByteToWideChar() must be zero. Return zero or
1075  * MB_ERR_INVALID_CHARS. The docs in Platform SDK for for Windows
1076  * Server 2003 R2 claims that also codepage 65001 is one of these, but
1077  * that doesn't seem to be the case. The MSDN docs for MSVS2008 leave
1078  * out 65001 (UTF-8), and that indeed seems to be the case on XP, it
1079  * works fine to pass MB_ERR_INVALID_CHARS in dwFlags when converting
1080  * from UTF-8.
1081  */
1082 static int
1084 {
1085  return (codepage == 50220 || codepage == 50221 ||
1086  codepage == 50222 || codepage == 50225 ||
1087  codepage == 50227 || codepage == 50229 ||
1088  codepage == 52936 || codepage == 54936 ||
1089  (codepage >= 57002 && codepage <= 57011) ||
1090  codepage == 65000 || codepage == 42) ? 0 : MB_ERR_INVALID_CHARS;
1091 }
1092 
1093 /*
1094  * Check if codepage is one those for which the lpUsedDefaultChar
1095  * parameter to WideCharToMultiByte() must be NULL. The docs in
1096  * Platform SDK for Windows Server 2003 R2 claims that this is the
1097  * list below, while the MSDN docs for MSVS2008 claim that it is only
1098  * for 65000 (UTF-7) and 65001 (UTF-8). This time the earlier Platform
1099  * SDK seems to be correct, at least for XP.
1100  */
1101 static int
1103 {
1104  return (codepage == 65000 || codepage == 65001 ||
1105  codepage == 50220 || codepage == 50221 ||
1106  codepage == 50222 || codepage == 50225 ||
1107  codepage == 50227 || codepage == 50229 ||
1108  codepage == 52936 || codepage == 54936 ||
1109  (codepage >= 57002 && codepage <= 57011) ||
1110  codepage == 42);
1111 }
1112 
1113 static char *
1114 strrstr(const char *str, const char *token)
1115 {
1116  int len = strlen(token);
1117  const char *p = str + strlen(str);
1118 
1119  while (str <= --p)
1120  if (p[0] == token[0] && strncmp(p, token, len) == 0)
1121  return (char *)p;
1122  return NULL;
1123 }
1124 
1125 static char *
1126 xstrndup(const char *s, size_t n)
1127 {
1128  char *p;
1129 
1130  p = (char *)malloc(n + 1);
1131  if (p == NULL)
1132  return NULL;
1133  memcpy(p, s, n);
1134  p[n] = '\0';
1135  return p;
1136 }
1137 
1138 static int
1140 {
1141  errno = err;
1142  return -1;
1143 }
1144 
1145 #if defined(USE_LIBICONV_DLL)
1146 static int
1147 libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode)
1148 {
1149  HMODULE hlibiconv = NULL;
1150  char *dllname;
1151  const char *p;
1152  const char *e;
1153  f_iconv_open _iconv_open;
1154 
1155  /*
1156  * always try to load dll, so that we can switch dll in runtime.
1157  */
1158 
1159  /* XXX: getenv() can't get variable set by SetEnvironmentVariable() */
1160  p = getenv("WINICONV_LIBICONV_DLL");
1161  if (p == NULL)
1163  /* parse comma separated value */
1164  for ( ; *p != 0; p = (*e == ',') ? e + 1 : e)
1165  {
1166  e = strchr(p, ',');
1167  if (p == e)
1168  continue;
1169  else if (e == NULL)
1170  e = p + strlen(p);
1171  dllname = xstrndup(p, e - p);
1172  if (dllname == NULL)
1173  return FALSE;
1174  hlibiconv = LoadLibraryA(dllname);
1175  free(dllname);
1176  if (hlibiconv != NULL)
1177  {
1178  if (hlibiconv == hwiniconv)
1179  {
1180  FreeLibrary(hlibiconv);
1181  hlibiconv = NULL;
1182  continue;
1183  }
1184  break;
1185  }
1186  }
1187 
1188  if (hlibiconv == NULL)
1189  goto failed;
1190 
1191  _iconv_open = (f_iconv_open)GetProcAddressA(hlibiconv, "libiconv_open");
1192  if (_iconv_open == NULL)
1193  _iconv_open = (f_iconv_open)GetProcAddressA(hlibiconv, "iconv_open");
1194  cd->iconv_close = (f_iconv_close)GetProcAddressA(hlibiconv, "libiconv_close");
1195  if (cd->iconv_close == NULL)
1196  cd->iconv_close = (f_iconv_close)GetProcAddressA(hlibiconv, "iconv_close");
1197  cd->iconv = (f_iconv)GetProcAddressA(hlibiconv, "libiconv");
1198  if (cd->iconv == NULL)
1199  cd->iconv = (f_iconv)GetProcAddressA(hlibiconv, "iconv");
1200  cd->_errno = (f_errno)find_imported_function(hlibiconv, "_errno");
1201  if (_iconv_open == NULL || cd->iconv_close == NULL
1202  || cd->iconv == NULL || cd->_errno == NULL)
1203  goto failed;
1204 
1205  cd->cd = _iconv_open(tocode, fromcode);
1206  if (cd->cd == (iconv_t)(-1))
1207  goto failed;
1208 
1209  cd->hlibiconv = hlibiconv;
1210  return TRUE;
1211 
1212 failed:
1213  if (hlibiconv != NULL)
1214  FreeLibrary(hlibiconv);
1215  return FALSE;
1216 }
1217 
1218 /*
1219  * Reference:
1220  * http://forums.belution.com/ja/vc/000/234/78s.shtml
1221  * http://nienie.com/~masapico/api_ImageDirectoryEntryToData.html
1222  *
1223  * The formal way is
1224  * imagehlp.h or dbghelp.h
1225  * imagehlp.lib or dbghelp.lib
1226  * ImageDirectoryEntryToData()
1227  */
1228 #define TO_DOS_HEADER(base) ((PIMAGE_DOS_HEADER)(base))
1229 #define TO_NT_HEADERS(base) ((PIMAGE_NT_HEADERS)((LPBYTE)(base) + TO_DOS_HEADER(base)->e_lfanew))
1230 static PVOID
1231 MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size)
1232 {
1233  /* TODO: MappedAsImage? */
1235  p = TO_NT_HEADERS(Base)->OptionalHeader.DataDirectory + DirectoryEntry;
1236  if (p->VirtualAddress == 0) {
1237  *Size = 0;
1238  return NULL;
1239  }
1240  *Size = p->Size;
1241  return (PVOID)((LPBYTE)Base + p->VirtualAddress);
1242 }
1243 
1244 static FARPROC
1245 find_imported_function(HMODULE hModule, const char *funcname)
1246 {
1247  DWORD_PTR Base;
1248  ULONG Size;
1250  PIMAGE_THUNK_DATA Address; /* Import Address Table */
1251  PIMAGE_THUNK_DATA Name; /* Import Name Table */
1252  PIMAGE_IMPORT_BY_NAME ImpName;
1253 
1254  Base = (DWORD_PTR)hModule;
1255  Imp = (PIMAGE_IMPORT_DESCRIPTOR)MyImageDirectoryEntryToData(
1256  (LPVOID)Base,
1257  TRUE,
1259  &Size);
1260  if (Imp == NULL)
1261  return NULL;
1262  for ( ; Imp->OriginalFirstThunk != 0; ++Imp)
1263  {
1266  for ( ; Name->u1.Ordinal != 0; ++Name, ++Address)
1267  {
1268  if (!IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal))
1269  {
1270  ImpName = (PIMAGE_IMPORT_BY_NAME)
1271  (Base + (DWORD_PTR)Name->u1.AddressOfData);
1272  if (strcmp((char *)ImpName->Name, funcname) == 0)
1273  return (FARPROC)Address->u1.Function;
1274  }
1275  }
1276  }
1277  return NULL;
1278 }
1279 #endif
1280 
1281 static int
1283 {
1284  return 1;
1285 }
1286 
1287 static int
1289 {
1290  int len = IsDBCSLeadByteEx(cv->codepage, buf[0]) ? 2 : 1;
1291  if (bufsize < len)
1292  return seterror(EINVAL);
1293  return len;
1294 }
1295 
1296 static int
1298 {
1299  int len = 0;
1300 
1301  if (cv->codepage == 54936) {
1302  if (buf[0] <= 0x7F) len = 1;
1303  else if (buf[0] >= 0x81 && buf[0] <= 0xFE &&
1304  bufsize >= 2 &&
1305  ((buf[1] >= 0x40 && buf[1] <= 0x7E) ||
1306  (buf[1] >= 0x80 && buf[1] <= 0xFE))) len = 2;
1307  else if (buf[0] >= 0x81 && buf[0] <= 0xFE &&
1308  bufsize >= 4 &&
1309  buf[1] >= 0x30 && buf[1] <= 0x39) len = 4;
1310  else
1311  return seterror(EINVAL);
1312  return len;
1313  }
1314  else
1315  return seterror(EINVAL);
1316 }
1317 
1318 static int
1320 {
1321  int len = 0;
1322 
1323  if (buf[0] < 0x80) len = 1;
1324  else if ((buf[0] & 0xE0) == 0xC0) len = 2;
1325  else if ((buf[0] & 0xF0) == 0xE0) len = 3;
1326  else if ((buf[0] & 0xF8) == 0xF0) len = 4;
1327  else if ((buf[0] & 0xFC) == 0xF8) len = 5;
1328  else if ((buf[0] & 0xFE) == 0xFC) len = 6;
1329 
1330  if (len == 0)
1331  return seterror(EILSEQ);
1332  else if (bufsize < len)
1333  return seterror(EINVAL);
1334  return len;
1335 }
1336 
1337 static int
1339 {
1340  if (buf[0] < 0x80) /* ASCII */
1341  return 1;
1342  else if (buf[0] == 0x8E) /* JIS X 0201 */
1343  {
1344  if (bufsize < 2)
1345  return seterror(EINVAL);
1346  else if (!(0xA1 <= buf[1] && buf[1] <= 0xDF))
1347  return seterror(EILSEQ);
1348  return 2;
1349  }
1350  else if (buf[0] == 0x8F) /* JIS X 0212 */
1351  {
1352  if (bufsize < 3)
1353  return seterror(EINVAL);
1354  else if (!(0xA1 <= buf[1] && buf[1] <= 0xFE)
1355  || !(0xA1 <= buf[2] && buf[2] <= 0xFE))
1356  return seterror(EILSEQ);
1357  return 3;
1358  }
1359  else /* JIS X 0208 */
1360  {
1361  if (bufsize < 2)
1362  return seterror(EINVAL);
1363  else if (!(0xA1 <= buf[0] && buf[0] <= 0xFE)
1364  || !(0xA1 <= buf[1] && buf[1] <= 0xFE))
1365  return seterror(EILSEQ);
1366  return 2;
1367  }
1368 }
1369 
1370 static int
1371 kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
1372 {
1373  int len;
1374 
1375  len = cv->mblen(cv, buf, bufsize);
1376  if (len == -1)
1377  return -1;
1378  *wbufsize = MultiByteToWideChar(cv->codepage, mbtowc_flags (cv->codepage),
1379  (const char *)buf, len, (wchar_t *)wbuf, *wbufsize);
1380  if (*wbufsize == 0)
1381  return seterror(EILSEQ);
1382  return len;
1383 }
1384 
1385 static int
1386 kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
1387 {
1388  BOOL usedDefaultChar = 0;
1389  BOOL *p = NULL;
1390  int flags = 0;
1391  int len;
1392 
1393  if (bufsize == 0)
1394  return seterror(E2BIG);
1396  {
1397  p = &usedDefaultChar;
1398 #ifdef WC_NO_BEST_FIT_CHARS
1399  if (!(cv->flags & FLAG_TRANSLIT))
1401 #endif
1402  }
1404  (const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL, p);
1405  if (len == 0)
1406  {
1408  return seterror(E2BIG);
1409  return seterror(EILSEQ);
1410  }
1411  else if (usedDefaultChar && !(cv->flags & FLAG_TRANSLIT))
1412  return seterror(EILSEQ);
1413  else if (cv->mblen(cv, buf, len) != len) /* validate result */
1414  return seterror(EILSEQ);
1415  return len;
1416 }
1417 
1418 /*
1419  * It seems that the mode (cv->mode) is fixnum.
1420  * For example, when converting iso-2022-jp(cp50221) to unicode:
1421  * in ascii sequence: mode=0xC42C0000
1422  * in jisx0208 sequence: mode=0xC42C0001
1423  * "C42C" is same for each convert session.
1424  * It should be: ((codepage-1)<<16)|state
1425  */
1426 static int
1427 mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
1428 {
1429  int len;
1430  int insize;
1431  HRESULT hr;
1432 
1433  len = cv->mblen(cv, buf, bufsize);
1434  if (len == -1)
1435  return -1;
1436  insize = len;
1438  (const char *)buf, &insize, (wchar_t *)wbuf, wbufsize);
1439  if (hr != S_OK || insize != len)
1440  return seterror(EILSEQ);
1441  return len;
1442 }
1443 
1444 static int
1445 mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
1446 {
1447  char tmpbuf[MB_CHAR_MAX]; /* enough room for one character */
1448  int tmpsize = MB_CHAR_MAX;
1449  int insize = wbufsize;
1450  HRESULT hr;
1451 
1453  (const wchar_t *)wbuf, &wbufsize, tmpbuf, &tmpsize);
1454  if (hr != S_OK || insize != wbufsize)
1455  return seterror(EILSEQ);
1456  else if (bufsize < tmpsize)
1457  return seterror(E2BIG);
1458  else if (cv->mblen(cv, (uchar *)tmpbuf, tmpsize) != tmpsize)
1459  return seterror(EILSEQ);
1460  memcpy(buf, tmpbuf, tmpsize);
1461  return tmpsize;
1462 }
1463 
1464 static int
1465 utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
1466 {
1467  int codepage = cv->codepage;
1468 
1469  /* swap endian: 1200 <-> 1201 */
1470  if (cv->mode & UNICODE_MODE_SWAPPED)
1471  codepage ^= 1;
1472 
1473  if (bufsize < 2)
1474  return seterror(EINVAL);
1475  if (codepage == 1200) /* little endian */
1476  wbuf[0] = (buf[1] << 8) | buf[0];
1477  else if (codepage == 1201) /* big endian */
1478  wbuf[0] = (buf[0] << 8) | buf[1];
1479 
1480  if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))
1481  {
1482  cv->mode |= UNICODE_MODE_BOM_DONE;
1483  if (wbuf[0] == 0xFFFE)
1484  {
1485  cv->mode |= UNICODE_MODE_SWAPPED;
1486  *wbufsize = 0;
1487  return 2;
1488  }
1489  else if (wbuf[0] == 0xFEFF)
1490  {
1491  *wbufsize = 0;
1492  return 2;
1493  }
1494  }
1495 
1496  if (0xDC00 <= wbuf[0] && wbuf[0] <= 0xDFFF)
1497  return seterror(EILSEQ);
1498  if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)
1499  {
1500  if (bufsize < 4)
1501  return seterror(EINVAL);
1502  if (codepage == 1200) /* little endian */
1503  wbuf[1] = (buf[3] << 8) | buf[2];
1504  else if (codepage == 1201) /* big endian */
1505  wbuf[1] = (buf[2] << 8) | buf[3];
1506  if (!(0xDC00 <= wbuf[1] && wbuf[1] <= 0xDFFF))
1507  return seterror(EILSEQ);
1508  *wbufsize = 2;
1509  return 4;
1510  }
1511  *wbufsize = 1;
1512  return 2;
1513 }
1514 
1515 static int
1516 utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
1517 {
1518  if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))
1519  {
1520  int r;
1521 
1522  cv->mode |= UNICODE_MODE_BOM_DONE;
1523  if (bufsize < 2)
1524  return seterror(E2BIG);
1525  if (cv->codepage == 1200) /* little endian */
1526  memcpy(buf, "\xFF\xFE", 2);
1527  else if (cv->codepage == 1201) /* big endian */
1528  memcpy(buf, "\xFE\xFF", 2);
1529 
1530  r = utf16_wctomb(cv, wbuf, wbufsize, buf + 2, bufsize - 2);
1531  if (r == -1)
1532  return -1;
1533  return r + 2;
1534  }
1535 
1536  if (bufsize < 2)
1537  return seterror(E2BIG);
1538  if (cv->codepage == 1200) /* little endian */
1539  {
1540  buf[0] = (wbuf[0] & 0x00FF);
1541  buf[1] = (wbuf[0] & 0xFF00) >> 8;
1542  }
1543  else if (cv->codepage == 1201) /* big endian */
1544  {
1545  buf[0] = (wbuf[0] & 0xFF00) >> 8;
1546  buf[1] = (wbuf[0] & 0x00FF);
1547  }
1548  if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)
1549  {
1550  if (bufsize < 4)
1551  return seterror(E2BIG);
1552  if (cv->codepage == 1200) /* little endian */
1553  {
1554  buf[2] = (wbuf[1] & 0x00FF);
1555  buf[3] = (wbuf[1] & 0xFF00) >> 8;
1556  }
1557  else if (cv->codepage == 1201) /* big endian */
1558  {
1559  buf[2] = (wbuf[1] & 0xFF00) >> 8;
1560  buf[3] = (wbuf[1] & 0x00FF);
1561  }
1562  return 4;
1563  }
1564  return 2;
1565 }
1566 
1567 static int
1568 utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
1569 {
1570  int codepage = cv->codepage;
1571  uint wc;
1572 
1573  /* swap endian: 12000 <-> 12001 */
1574  if (cv->mode & UNICODE_MODE_SWAPPED)
1575  codepage ^= 1;
1576 
1577  if (bufsize < 4)
1578  return seterror(EINVAL);
1579  if (codepage == 12000) /* little endian */
1580  wc = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
1581  else if (codepage == 12001) /* big endian */
1582  wc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1583 
1584  if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))
1585  {
1586  cv->mode |= UNICODE_MODE_BOM_DONE;
1587  if (wc == 0xFFFE0000)
1588  {
1589  cv->mode |= UNICODE_MODE_SWAPPED;
1590  *wbufsize = 0;
1591  return 4;
1592  }
1593  else if (wc == 0x0000FEFF)
1594  {
1595  *wbufsize = 0;
1596  return 4;
1597  }
1598  }
1599 
1600  if ((0xD800 <= wc && wc <= 0xDFFF) || 0x10FFFF < wc)
1601  return seterror(EILSEQ);
1602  ucs4_to_utf16(wc, wbuf, wbufsize);
1603  return 4;
1604 }
1605 
1606 static int
1607 utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
1608 {
1609  uint wc;
1610 
1611  if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))
1612  {
1613  int r;
1614 
1615  cv->mode |= UNICODE_MODE_BOM_DONE;
1616  if (bufsize < 4)
1617  return seterror(E2BIG);
1618  if (cv->codepage == 12000) /* little endian */
1619  memcpy(buf, "\xFF\xFE\x00\x00", 4);
1620  else if (cv->codepage == 12001) /* big endian */
1621  memcpy(buf, "\x00\x00\xFE\xFF", 4);
1622 
1623  r = utf32_wctomb(cv, wbuf, wbufsize, buf + 4, bufsize - 4);
1624  if (r == -1)
1625  return -1;
1626  return r + 4;
1627  }
1628 
1629  if (bufsize < 4)
1630  return seterror(E2BIG);
1631  wc = utf16_to_ucs4(wbuf);
1632  if (cv->codepage == 12000) /* little endian */
1633  {
1634  buf[0] = wc & 0x000000FF;
1635  buf[1] = (wc & 0x0000FF00) >> 8;
1636  buf[2] = (wc & 0x00FF0000) >> 16;
1637  buf[3] = (wc & 0xFF000000) >> 24;
1638  }
1639  else if (cv->codepage == 12001) /* big endian */
1640  {
1641  buf[0] = (wc & 0xFF000000) >> 24;
1642  buf[1] = (wc & 0x00FF0000) >> 16;
1643  buf[2] = (wc & 0x0000FF00) >> 8;
1644  buf[3] = wc & 0x000000FF;
1645  }
1646  return 4;
1647 }
1648 
1649 /*
1650  * 50220: ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS)
1651  * 50221: ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow
1652  * 1 byte Kana)
1653  * 50222: ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte
1654  * Kana - SO/SI)
1655  *
1656  * MultiByteToWideChar() and WideCharToMultiByte() behave differently
1657  * depending on Windows version. On XP, WideCharToMultiByte() doesn't
1658  * terminate result sequence with ascii escape. But Vista does.
1659  * Use MLang instead.
1660  */
1661 
1662 #define ISO2022_MODE(cs, shift) (((cs) << 8) | (shift))
1663 #define ISO2022_MODE_CS(mode) (((mode) >> 8) & 0xFF)
1664 #define ISO2022_MODE_SHIFT(mode) ((mode) & 0xFF)
1665 
1666 #define ISO2022_SI 0
1667 #define ISO2022_SO 1
1668 
1669 /* shift in */
1670 static const char iso2022_SI_seq[] = "\x0F";
1671 /* shift out */
1672 static const char iso2022_SO_seq[] = "\x0E";
1673 
1676  const char *esc;
1677  int esc_len;
1678  int len;
1679  int cs;
1680 };
1681 
1682 #define ISO2022JP_CS_ASCII 0
1683 #define ISO2022JP_CS_JISX0201_ROMAN 1
1684 #define ISO2022JP_CS_JISX0201_KANA 2
1685 #define ISO2022JP_CS_JISX0208_1978 3
1686 #define ISO2022JP_CS_JISX0208_1983 4
1687 #define ISO2022JP_CS_JISX0212 5
1688 
1690  {"\x1B\x28\x42", 3, 1, ISO2022JP_CS_ASCII},
1691  {"\x1B\x28\x4A", 3, 1, ISO2022JP_CS_JISX0201_ROMAN},
1692  {"\x1B\x28\x49", 3, 1, ISO2022JP_CS_JISX0201_KANA},
1693  {"\x1B\x24\x40", 3, 2, ISO2022JP_CS_JISX0208_1983}, /* unify 1978 with 1983 */
1694  {"\x1B\x24\x42", 3, 2, ISO2022JP_CS_JISX0208_1983},
1695  {"\x1B\x24\x28\x44", 4, 2, ISO2022JP_CS_JISX0212},
1696  {NULL, 0, 0, 0}
1697 };
1698 
1699 static int
1700 iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
1701 {
1702  iso2022_esc_t *iesc = iso2022jp_esc;
1703  char tmp[MB_CHAR_MAX];
1704  int insize;
1705  HRESULT hr;
1706  DWORD dummy = 0;
1707  int len;
1708  int esc_len;
1709  int cs;
1710  int shift;
1711  int i;
1712 
1713  if (buf[0] == 0x1B)
1714  {
1715  for (i = 0; iesc[i].esc != NULL; ++i)
1716  {
1717  esc_len = iesc[i].esc_len;
1718  if (bufsize < esc_len)
1719  {
1720  if (strncmp((char *)buf, iesc[i].esc, bufsize) == 0)
1721  return seterror(EINVAL);
1722  }
1723  else
1724  {
1725  if (strncmp((char *)buf, iesc[i].esc, esc_len) == 0)
1726  {
1727  cv->mode = ISO2022_MODE(iesc[i].cs, ISO2022_SI);
1728  *wbufsize = 0;
1729  return esc_len;
1730  }
1731  }
1732  }
1733  /* not supported escape sequence */
1734  return seterror(EILSEQ);
1735  }
1736  else if (buf[0] == iso2022_SO_seq[0])
1737  {
1739  *wbufsize = 0;
1740  return 1;
1741  }
1742  else if (buf[0] == iso2022_SI_seq[0])
1743  {
1745  *wbufsize = 0;
1746  return 1;
1747  }
1748 
1749  cs = ISO2022_MODE_CS(cv->mode);
1750  shift = ISO2022_MODE_SHIFT(cv->mode);
1751 
1752  /* reset the mode for informal sequence */
1753  if (buf[0] < 0x20)
1754  {
1756  shift = ISO2022_SI;
1757  }
1758 
1759  len = iesc[cs].len;
1760  if (bufsize < len)
1761  return seterror(EINVAL);
1762  for (i = 0; i < len; ++i)
1763  if (!(buf[i] < 0x80))
1764  return seterror(EILSEQ);
1765  esc_len = iesc[cs].esc_len;
1766  memcpy(tmp, iesc[cs].esc, esc_len);
1767  if (shift == ISO2022_SO)
1768  {
1769  memcpy(tmp + esc_len, iso2022_SO_seq, 1);
1770  esc_len += 1;
1771  }
1772  memcpy(tmp + esc_len, buf, len);
1773 
1774  if ((cv->codepage == 50220 || cv->codepage == 50221
1775  || cv->codepage == 50222) && shift == ISO2022_SO)
1776  {
1777  /* XXX: shift-out cannot be used for mbtowc (both kernel and
1778  * mlang) */
1779  esc_len = iesc[ISO2022JP_CS_JISX0201_KANA].esc_len;
1780  memcpy(tmp, iesc[ISO2022JP_CS_JISX0201_KANA].esc, esc_len);
1781  memcpy(tmp + esc_len, buf, len);
1782  }
1783 
1784  insize = len + esc_len;
1786  (const char *)tmp, &insize, (wchar_t *)wbuf, wbufsize);
1787  if (hr != S_OK || insize != len + esc_len)
1788  return seterror(EILSEQ);
1789 
1790  /* Check for conversion error. Assuming defaultChar is 0x3F. */
1791  /* ascii should be converted from ascii */
1792  if (wbuf[0] == buf[0]
1794  return seterror(EILSEQ);
1795 
1796  /* reset the mode for informal sequence */
1797  if (cv->mode != ISO2022_MODE(cs, shift))
1798  cv->mode = ISO2022_MODE(cs, shift);
1799 
1800  return len;
1801 }
1802 
1803 static int
1804 iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
1805 {
1806  iso2022_esc_t *iesc = iso2022jp_esc;
1807  char tmp[MB_CHAR_MAX];
1808  int tmpsize = MB_CHAR_MAX;
1809  int insize = wbufsize;
1810  HRESULT hr;
1811  DWORD dummy = 0;
1812  int len;
1813  int esc_len;
1814  int cs;
1815  int shift;
1816  int i;
1817 
1818  /*
1819  * MultiByte = [escape sequence] + character + [escape sequence]
1820  *
1821  * Whether trailing escape sequence is added depends on which API is
1822  * used (kernel or MLang, and its version).
1823  */
1825  (const wchar_t *)wbuf, &wbufsize, tmp, &tmpsize);
1826  if (hr != S_OK || insize != wbufsize)
1827  return seterror(EILSEQ);
1828  else if (bufsize < tmpsize)
1829  return seterror(E2BIG);
1830 
1831  if (tmpsize == 1)
1832  {
1834  esc_len = 0;
1835  }
1836  else
1837  {
1838  for (i = 1; iesc[i].esc != NULL; ++i)
1839  {
1840  esc_len = iesc[i].esc_len;
1841  if (strncmp(tmp, iesc[i].esc, esc_len) == 0)
1842  {
1843  cs = iesc[i].cs;
1844  break;
1845  }
1846  }
1847  if (iesc[i].esc == NULL)
1848  /* not supported escape sequence */
1849  return seterror(EILSEQ);
1850  }
1851 
1852  shift = ISO2022_SI;
1853  if (tmp[esc_len] == iso2022_SO_seq[0])
1854  {
1855  shift = ISO2022_SO;
1856  esc_len += 1;
1857  }
1858 
1859  len = iesc[cs].len;
1860 
1861  /* Check for converting error. Assuming defaultChar is 0x3F. */
1862  /* ascii should be converted from ascii */
1863  if (cs == ISO2022JP_CS_ASCII && !(wbuf[0] < 0x80))
1864  return seterror(EILSEQ);
1865  else if (tmpsize < esc_len + len)
1866  return seterror(EILSEQ);
1867 
1868  if (cv->mode == ISO2022_MODE(cs, shift))
1869  {
1870  /* remove escape sequence */
1871  if (esc_len != 0)
1872  memmove(tmp, tmp + esc_len, len);
1873  esc_len = 0;
1874  }
1875  else
1876  {
1877  if (cs == ISO2022JP_CS_ASCII)
1878  {
1879  esc_len = iesc[ISO2022JP_CS_ASCII].esc_len;
1880  memmove(tmp + esc_len, tmp, len);
1881  memcpy(tmp, iesc[ISO2022JP_CS_ASCII].esc, esc_len);
1882  }
1883  if (ISO2022_MODE_SHIFT(cv->mode) == ISO2022_SO)
1884  {
1885  /* shift-in before changing to other mode */
1886  memmove(tmp + 1, tmp, len + esc_len);
1887  memcpy(tmp, iso2022_SI_seq, 1);
1888  esc_len += 1;
1889  }
1890  }
1891 
1892  if (bufsize < len + esc_len)
1893  return seterror(E2BIG);
1894  memcpy(buf, tmp, len + esc_len);
1895  cv->mode = ISO2022_MODE(cs, shift);
1896  return len + esc_len;
1897 }
1898 
1899 static int
1901 {
1902  iso2022_esc_t *iesc = iso2022jp_esc;
1903  int esc_len;
1904 
1906  {
1907  esc_len = 0;
1908  if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI)
1909  esc_len += 1;
1911  esc_len += iesc[ISO2022JP_CS_ASCII].esc_len;
1912  if (bufsize < esc_len)
1913  return seterror(E2BIG);
1914 
1915  esc_len = 0;
1916  if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI)
1917  {
1918  memcpy(buf, iso2022_SI_seq, 1);
1919  esc_len += 1;
1920  }
1922  {
1923  memcpy(buf + esc_len, iesc[ISO2022JP_CS_ASCII].esc,
1924  iesc[ISO2022JP_CS_ASCII].esc_len);
1925  esc_len += iesc[ISO2022JP_CS_ASCII].esc_len;
1926  }
1927  return esc_len;
1928  }
1929  return 0;
1930 }
1931 
1932 #if defined(MAKE_DLL) && defined(USE_LIBICONV_DLL)
1933 BOOL WINAPI
1934 DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
1935 {
1936  switch( fdwReason )
1937  {
1938  case DLL_PROCESS_ATTACH:
1939  hwiniconv = (HMODULE)hinstDLL;
1940  break;
1941  case DLL_THREAD_ATTACH:
1942  case DLL_THREAD_DETACH:
1943  case DLL_PROCESS_DETACH:
1944  break;
1945  }
1946  return TRUE;
1947 }
1948 #endif
1949 
1950 #if defined(MAKE_EXE)
1951 #include <stdio.h>
1952 #include <fcntl.h>
1953 #include <io.h>
1954 int
1955 main(int argc, char **argv)
1956 {
1957  char *fromcode = NULL;
1958  char *tocode = NULL;
1959  int i;
1960  char inbuf[BUFSIZ];
1961  char outbuf[BUFSIZ];
1962  const char *pin;
1963  char *pout;
1964  size_t inbytesleft;
1965  size_t outbytesleft;
1966  size_t rest = 0;
1967  iconv_t cd;
1968  size_t r;
1969  FILE *in = stdin;
1970  FILE *out = stdout;
1971  int ignore = 0;
1972  char *p;
1973 
1976 
1977  for (i = 1; i < argc; ++i)
1978  {
1979  if (strcmp(argv[i], "-l") == 0)
1980  {
1981  for (i = 0; codepage_alias[i].name != NULL; ++i)
1982  printf("%s\n", codepage_alias[i].name);
1983  return 0;
1984  }
1985 
1986  if (strcmp(argv[i], "-f") == 0)
1987  fromcode = argv[++i];
1988  else if (strcmp(argv[i], "-t") == 0)
1989  tocode = argv[++i];
1990  else if (strcmp(argv[i], "-c") == 0)
1991  ignore = 1;
1992  else if (strcmp(argv[i], "--output") == 0)
1993  {
1994  out = fopen(argv[++i], "wb");
1995  if(out == NULL)
1996  {
1997  fprintf(stderr, "cannot open %s\n", argv[i]);
1998  return 1;
1999  }
2000  }
2001  else
2002  {
2003  in = fopen(argv[i], "rb");
2004  if (in == NULL)
2005  {
2006  fprintf(stderr, "cannot open %s\n", argv[i]);
2007  return 1;
2008  }
2009  break;
2010  }
2011  }
2012 
2013  if (fromcode == NULL || tocode == NULL)
2014  {
2015  printf("usage: %s [-c] -f from-enc -t to-enc [file]\n", argv[0]);
2016  return 0;
2017  }
2018 
2019  if (ignore)
2020  {
2021  p = tocode;
2022  tocode = (char *)malloc(strlen(p) + strlen("//IGNORE") + 1);
2023  if (tocode == NULL)
2024  {
2025  perror("fatal error");
2026  return 1;
2027  }
2028  strcpy(tocode, p);
2029  strcat(tocode, "//IGNORE");
2030  }
2031 
2032  cd = iconv_open(tocode, fromcode);
2033  if (cd == (iconv_t)(-1))
2034  {
2035  perror("iconv_open error");
2036  return 1;
2037  }
2038 
2039  while ((inbytesleft = fread(inbuf + rest, 1, sizeof(inbuf) - rest, in)) != 0
2040  || rest != 0)
2041  {
2042  inbytesleft += rest;
2043  pin = inbuf;
2044  pout = outbuf;
2045  outbytesleft = sizeof(outbuf);
2046  r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft);
2047  fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, out);
2048  if (r == (size_t)(-1) && errno != E2BIG && (errno != EINVAL || feof(in)))
2049  {
2050  perror("conversion error");
2051  return 1;
2052  }
2053  memmove(inbuf, pin, inbytesleft);
2054  rest = inbytesleft;
2055  }
2056  pout = outbuf;
2057  outbytesleft = sizeof(outbuf);
2058  r = iconv(cd, NULL, NULL, &pout, &outbytesleft);
2059  fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, out);
2060  if (r == (size_t)(-1))
2061  {
2062  perror("conversion error");
2063  return 1;
2064  }
2065 
2066  iconv_close(cd);
2067 
2068  return 0;
2069 }
2070 #endif
2071 
static LCIDTORFC1766A LcidToRfc1766A
Definition: win_iconv.c:708
size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: win_iconv.c:771
compat_t * compat
Definition: win_iconv.c:99
#define HRESULT
Definition: msvc.h:9
static int argc
Definition: ServiceArgs.c:12
HRESULT(WINAPI * ISCONVERTINETSTRINGAVAILABLE)(DWORD dwSrcEncoding, DWORD dwDstEncoding)
Definition: win_iconv.c:682
BOOL WINAPI GetCPInfo(UINT CodePage, LPCPINFO CodePageInfo)
Definition: nls.c:1904
#define EILSEQ
Definition: errno.h:97
static uint utf16_to_ucs4(const ushort *wbuf)
Definition: win_iconv.c:1047
f_iconv_close iconv_close
Definition: win_iconv.c:104
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define _setmode(fd, mode)
Definition: cat.c:21
Definition: arc.h:33
uint in
Definition: win_iconv.c:86
#define TRUE
Definition: types.h:120
static int kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:1371
#define shift
Definition: input.c:1668
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
iconv_t iconv_open(const char *tocode, const char *fromcode)
Definition: win_iconv.c:730
static void ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:1056
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
static int mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
Definition: win_iconv.c:1445
#define DWORD_PTR
Definition: treelist.c:76
#define WideCharToMultiByte
Definition: compat.h:101
static CONVERTINETMULTIBYTETOUNICODE ConvertINetMultiByteToUnicode
Definition: win_iconv.c:705
#define LoadLibrary
Definition: winbase.h:3679
HRESULT hr
Definition: shlfolder.c:183
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char uchar
Definition: Unfrag.h:59
HRESULT(WINAPI * CONVERTINETMULTIBYTETOUNICODE)(LPDWORD lpdwMode, DWORD dwSrcEncoding, LPCSTR lpSrcStr, LPINT lpnMultiCharCount, LPWSTR lpDstStr, LPINT lpnWideCharCount)
Definition: win_iconv.c:666
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static int win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode)
Definition: win_iconv.c:780
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static size_t win_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: win_iconv.c:798
#define DLL_THREAD_ATTACH
Definition: compat.h:121
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
int main(int argc, char *argv[])
Definition: atactl.cpp:1685
Definition: arc.h:39
static struct cd_image cd
Definition: cdmake.c:182
int ignore(int trapCode, ppc_trap_frame_t *trap)
Definition: mmuobject.c:296
f_iconv iconv
Definition: win_iconv.c:105
#define free
Definition: debug_ros.c:5
#define ISO2022JP_CS_JISX0212
Definition: win_iconv.c:1687
HRESULT(WINAPI * LCIDTORFC1766W)(LCID Locale, LPWSTR pszRfc1766, int nChar)
Definition: win_iconv.c:691
#define MB_CHAR_MAX
Definition: win_iconv.c:39
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
f_mbtowc mbtowc
Definition: win_iconv.c:94
GLdouble n
Definition: glext.h:7729
unsigned int uint
Definition: win_iconv.c:50
struct _IMAGE_IMPORT_DESCRIPTOR * PIMAGE_IMPORT_DESCRIPTOR
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
FILE * stdin
static int utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
Definition: win_iconv.c:1516
#define BUFSIZ
Definition: nsplookup.c:26
#define DLL_PROCESS_ATTACH
Definition: compat.h:120
UINT MaxCharSize
Definition: winnls.h:578
DWORD LCID
Definition: nls.h:13
static int utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:1465
#define ISO2022JP_CS_JISX0208_1983
Definition: win_iconv.c:1686
int errno
static compat_t cp932_compat[]
Definition: win_iconv.c:626
static CONVERTINETSTRING ConvertINetString
Definition: win_iconv.c:704
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
#define argv
Definition: mplay32.c:18
char * LPSTR
Definition: xmlstorage.h:182
int(* f_flush)(csconv_t *cv, uchar *buf, int bufsize)
Definition: win_iconv.c:79
#define _stricmp
Definition: cat.c:22
static int utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize)
static int mbtowc_flags(int codepage)
Definition: win_iconv.c:1083
#define DLL_THREAD_DETACH
Definition: compat.h:122
FILE * stdout
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
unsigned char uchar
Definition: win_iconv.c:48
static iso2022_esc_t iso2022jp_esc[]
Definition: win_iconv.c:1689
static int iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:1700
Definition: regsvr.c:103
const char * esc
Definition: win_iconv.c:1676
BOOL WINAPI IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
Definition: nls.c:2199
uint32_t cs
Definition: isohybrid.c:75
#define UNICODE_MODE_BOM_DONE
Definition: win_iconv.c:41
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned char * LPBYTE
Definition: typedefs.h:52
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
DWORD mode
Definition: win_iconv.c:98
static ISCONVERTINETSTRINGAVAILABLE IsConvertINetStringAvailable
Definition: win_iconv.c:707
static char * strrstr(const char *str, const char *token)
Definition: win_iconv.c:1114
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
unsigned int BOOL
Definition: ntddk_ex.h:94
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define e
Definition: ke_i.h:82
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
HRESULT(WINAPI * LCIDTORFC1766A)(LCID Locale, LPSTR pszRfc1766, int nChar)
Definition: win_iconv.c:686
_Check_return_ _CRTIMP int __cdecl _strnicmp(_In_reads_or_z_(_MaxCount) const char *_Str1, _In_reads_or_z_(_MaxCount) const char *_Str2, _In_ size_t _MaxCount)
static int eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize)
struct NameRec_ * Name
Definition: cdprocs.h:464
int codepage
Definition: win_iconv.c:156
unsigned short ushort
Definition: win_iconv.c:49
_In_ BOOLEAN MappedAsImage
Definition: rtlfuncs.h:3734
csconv_t from
Definition: win_iconv.c:107
const WCHAR * str
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static int dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)
Definition: win_iconv.c:1288
static WCHAR Address[46]
Definition: ping.c:68
BOOL WINAPI DllMain(IN HINSTANCE hinstDLL, IN DWORD dwReason, IN LPVOID lpvReserved)
Definition: kbsdll.c:83
static int mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:1427
UINT WINAPI GetACP(VOID)
Definition: nls.c:2169
int(* f_iconv_close)(iconv_t cd)
Definition: win_iconv.c:73
uint out
Definition: win_iconv.c:87
const char * LPCSTR
Definition: xmlstorage.h:183
unsigned short ushort
Definition: linux.h:273
#define DLL_PROCESS_DETACH
Definition: compat.h:119
static int load_mlang(void)
Definition: win_iconv.c:712
f_mblen mblen
Definition: win_iconv.c:96
__kernel_size_t size_t
Definition: linux.h:237
_Check_return_ _CRTIMP int __cdecl feof(_In_ FILE *_File)
static compat_t * cp51932_compat
Definition: win_iconv.c:652
#define FreeLibrary(x)
Definition: compat.h:405
static int utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
Definition: win_iconv.c:1607
static compat_t * cp5022x_compat
Definition: win_iconv.c:655
#define COMPAT_IN
Definition: win_iconv.c:81
LONG HRESULT
Definition: typedefs.h:77
#define funcname
Definition: shellext.h:91
#define UNICODE_MODE_SWAPPED
Definition: win_iconv.c:42
static int utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:1568
static compat_t cp20932_compat[]
Definition: win_iconv.c:639
#define WINAPI
Definition: msvc.h:8
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static FILE * out
Definition: regtests2xml.c:44
static int win_iconv_close(iconv_t cd)
Definition: win_iconv.c:792
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ISO2022_MODE_SHIFT(mode)
Definition: win_iconv.c:1664
unsigned char unsigned long * outsize
Definition: jpeglib.h:979
GLbitfield flags
Definition: glext.h:7161
#define WC_NO_BEST_FIT_CHARS
Definition: unicode.h:46
#define ISO2022_SI
Definition: win_iconv.c:1666
_CRTIMP int *__cdecl _errno(void)
Definition: errno.c:19
uchar inbuf[M_BLOCK]
Definition: unzcrash.c:40
f_errno _errno
Definition: win_iconv.c:106
#define _O_BINARY
Definition: cabinet.h:51
#define ISO2022_MODE(cs, shift)
Definition: win_iconv.c:1662
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
HRESULT(WINAPI * RFC1766TOLCIDA)(LCID *pLocale, LPSTR pszRfc1766)
Definition: win_iconv.c:696
static int iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
Definition: win_iconv.c:1804
#define ISO2022_MODE_CS(mode)
Definition: win_iconv.c:1663
HRESULT(WINAPI * CONVERTINETUNICODETOMULTIBYTE)(LPDWORD lpdwMode, DWORD dwEncoding, LPCWSTR lpSrcStr, LPINT lpnWideCharCount, LPSTR lpDstStr, LPINT lpnMultiCharCount)
Definition: win_iconv.c:674
const unsigned char unsigned long insize
Definition: jpeglib.h:982
int(* f_wctomb)(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
Definition: win_iconv.c:77
uint flag
Definition: win_iconv.c:88
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
int(* f_mbtowc)(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:76
#define FLAG_TRANSLIT
Definition: win_iconv.c:45
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
#define err(...)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define ISO2022JP_CS_JISX0201_KANA
Definition: win_iconv.c:1684
static int iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize)
Definition: win_iconv.c:1900
#define COMPAT_OUT
Definition: win_iconv.c:82
static RFC1766TOLCIDA Rfc1766ToLcidA
Definition: win_iconv.c:709
#define UNUSED
Definition: win_iconv.c:21
HANDLE HMODULE
Definition: typedefs.h:75
iconv_t(* f_iconv_open)(const char *tocode, const char *fromcode)
Definition: win_iconv.c:72
iconv_t cd
Definition: win_iconv.c:103
#define S_OK
Definition: intsafe.h:59
#define ISO2022JP_CS_ASCII
Definition: win_iconv.c:1682
#define ISO2022JP_CS_JISX0201_ROMAN
Definition: win_iconv.c:1683
#define TEXT(s)
Definition: k32.h:26
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1468
static int must_use_null_useddefaultchar(int codepage)
Definition: win_iconv.c:1102
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
static int make_csconv(const char *name, csconv_t *cv)
Definition: win_iconv.c:920
static const char iso2022_SI_seq[]
Definition: win_iconv.c:1670
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
GLuint in
Definition: glext.h:9616
static const char iso2022_SO_seq[]
Definition: win_iconv.c:1672
unsigned short USHORT
Definition: pedump.c:61
size_t(* f_iconv)(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: win_iconv.c:74
int iconv_close(iconv_t cd)
Definition: win_iconv.c:756
static struct @3869 codepage_alias[]
int *(* f_errno)(void)
Definition: win_iconv.c:75
f_flush flush
Definition: win_iconv.c:97
int codepage
Definition: win_iconv.c:92
static int sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)
static int mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)
Definition: win_iconv.c:1297
static char * xstrndup(const char *s, size_t n)
Definition: win_iconv.c:1126
unsigned int * PULONG
Definition: retypes.h:1
#define MultiByteToWideChar
Definition: compat.h:100
Definition: tftpd.h:85
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define FLAG_IGNORE
Definition: win_iconv.c:46
static int seterror(int err)
Definition: win_iconv.c:1139
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
void * iconv_t
Definition: win_iconv.c:52
static CONVERTINETUNICODETOMULTIBYTE ConvertINetUnicodeToMultiByte
Definition: win_iconv.c:706
POINT cp
Definition: magnifier.c:59
Definition: name.c:36
#define calloc
Definition: rosglue.h:14
csconv_t to
Definition: win_iconv.c:108
uint32_t * LPDWORD
Definition: typedefs.h:57
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define DEFAULT_LIBICONV_DLL
Definition: win_iconv.c:36
#define malloc
Definition: debug_ros.c:4
int flags
Definition: win_iconv.c:93
#define GetProcAddressA
Definition: win_iconv.c:26
UINT32 uint
Definition: types.h:83
#define FLAG_USE_BOM
Definition: win_iconv.c:44
int(* f_mblen)(csconv_t *cv, const uchar *buf, int bufsize)
Definition: win_iconv.c:78
#define ISO2022_SO
Definition: win_iconv.c:1667
_Check_return_ _CRTIMP int __cdecl _fileno(_In_ FILE *_File)
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
HRESULT(WINAPI * RFC1766TOLCIDW)(LCID *pLocale, LPWSTR pszRfc1766)
Definition: win_iconv.c:700
f_wctomb wctomb
Definition: win_iconv.c:95
static int kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
Definition: win_iconv.c:1386
int(* FARPROC)()
Definition: compat.h:28
PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA
Definition: ntimage.h:566
HMODULE hModule
Definition: animate.c:44
#define printf
Definition: config.h:203
const char * name
Definition: win_iconv.c:157
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
int * LPINT
Definition: windef.h:178
uchar outbuf[M_BLOCK_OUT]
Definition: unzcrash.c:41
static int name_to_codepage(const char *name)
Definition: win_iconv.c:1021
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
HRESULT(WINAPI * CONVERTINETSTRING)(LPDWORD lpdwMode, DWORD dwSrcEncoding, DWORD dwDstEncoding, LPCSTR lpSrcStr, LPINT lpnSrcSize, LPBYTE lpDstStr, LPINT lpnDstSize)
Definition: win_iconv.c:657