Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmlang.c
Go to the documentation of this file.
00001 /* 00002 * MLANG Class Factory 00003 * 00004 * Copyright 2002 Lionel Ulmer 00005 * Copyright 2003,2004 Mike McCormack 00006 * Copyright 2004,2005 Dmitry Timoshkov 00007 * Copyright 2009 Detlef Riekenberg 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 * This library is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00022 */ 00023 00024 #include "config.h" 00025 00026 #include <stdarg.h> 00027 #include <stdio.h> 00028 00029 #define COBJMACROS 00030 00031 #include "windef.h" 00032 #include "winbase.h" 00033 #include "wingdi.h" 00034 #include "winuser.h" 00035 #include "ole2.h" 00036 #include "objbase.h" 00037 #include "rpcproxy.h" 00038 #include "mlang.h" 00039 00040 #include "wine/unicode.h" 00041 #include "wine/debug.h" 00042 00043 WINE_DEFAULT_DEBUG_CHANNEL(mlang); 00044 00045 #include "initguid.h" 00046 00047 #define CP_UNICODE 1200 00048 00049 static HRESULT MultiLanguage_create(IUnknown *pUnkOuter, LPVOID *ppObj); 00050 static HRESULT EnumRfc1766_create(LANGID LangId, IEnumRfc1766 **ppEnum); 00051 00052 static HINSTANCE instance; 00053 static DWORD MLANG_tls_index; /* to store various per thead data */ 00054 00055 /* FIXME: 00056 * Under what circumstances HKEY_CLASSES_ROOT\MIME\Database\Codepage and 00057 * HKEY_CLASSES_ROOT\MIME\Database\Charset are used? 00058 */ 00059 00060 typedef struct 00061 { 00062 const char *description; 00063 UINT cp; 00064 DWORD flags; 00065 const char *web_charset; 00066 const char *header_charset; 00067 const char *body_charset; 00068 } MIME_CP_INFO; 00069 00070 /* These data are based on the codepage info in libs/unicode/cpmap.pl */ 00071 /* FIXME: Add 28604 (Celtic), 28606 (Balkan) */ 00072 00073 static const MIME_CP_INFO arabic_cp[] = 00074 { 00075 { "Arabic (864)", 00076 864, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00077 MIMECONTF_MIME_LATEST, 00078 "ibm864", "ibm864", "ibm864" }, 00079 { "Arabic (1006)", 00080 1006, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00081 MIMECONTF_MIME_LATEST, 00082 "ibm1006", "ibm1006", "ibm1006" }, 00083 { "Arabic (Windows)", 00084 1256, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT | 00085 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER | 00086 MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00087 "windows-1256", "windows-1256", "windows-1256" }, 00088 { "Arabic (ISO)", 00089 28596, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00090 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00091 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | 00092 MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00093 "iso-8859-6", "iso-8859-6", "iso-8859-6" } 00094 }; 00095 static const MIME_CP_INFO baltic_cp[] = 00096 { 00097 { "Baltic (DOS)", 00098 775, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00099 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00100 "ibm775", "ibm775", "ibm775" }, 00101 { "Baltic (Windows)", 00102 1257, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00103 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00104 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID | 00105 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00106 "windows-1257", "windows-1257", "windows-1257" }, 00107 { "Baltic (ISO)", 00108 28594, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT | 00109 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER | 00110 MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS | 00111 MIMECONTF_MIME_LATEST, 00112 "iso-8859-4", "iso-8859-4", "iso-8859-4" }, 00113 { "Estonian (ISO)", 00114 28603, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00115 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00116 "iso-8859-13", "iso-8859-13", "iso-8859-13" } 00117 }; 00118 static const MIME_CP_INFO chinese_simplified_cp[] = 00119 { 00120 { "Chinese Simplified (GB2312)", 00121 936, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00122 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00123 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00124 MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00125 "gb2312", "gb2312", "gb2312" } 00126 }; 00127 static const MIME_CP_INFO chinese_traditional_cp[] = 00128 { 00129 { "Chinese Traditional (Big5)", 00130 950, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00131 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00132 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | 00133 MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00134 "big5", "big5", "big5" } 00135 }; 00136 static const MIME_CP_INFO central_european_cp[] = 00137 { 00138 { "Central European (DOS)", 00139 852, MIMECONTF_BROWSER | MIMECONTF_IMPORT | MIMECONTF_SAVABLE_BROWSER | 00140 MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS | 00141 MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00142 "ibm852", "ibm852", "ibm852" }, 00143 { "Central European (Windows)", 00144 1250, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT | 00145 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER | 00146 MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS | 00147 MIMECONTF_MIME_LATEST, 00148 "windows-1250", "windows-1250", "windows-1250" }, 00149 { "Central European (Mac)", 00150 10029, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00151 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00152 "x-mac-ce", "x-mac-ce", "x-mac-ce" }, 00153 { "Central European (ISO)", 00154 28592, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00155 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00156 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID | 00157 MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00158 "iso-8859-2", "iso-8859-2", "iso-8859-2" } 00159 }; 00160 static const MIME_CP_INFO cyrillic_cp[] = 00161 { 00162 { "OEM Cyrillic", 00163 855, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00164 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00165 "ibm855", "ibm855", "ibm855" }, 00166 { "Cyrillic (DOS)", 00167 866, MIMECONTF_BROWSER | MIMECONTF_IMPORT | MIMECONTF_SAVABLE_BROWSER | 00168 MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | 00169 MIMECONTF_MIME_LATEST, 00170 "cp866", "cp866", "cp866" }, 00171 #if 0 /* Windows has 20866 as an official code page for KOI8-R */ 00172 { "Cyrillic (KOI8-R)", 00173 878, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00174 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00175 "koi8-r", "koi8-r", "koi8-r" }, 00176 #endif 00177 { "Cyrillic (Windows)", 00178 1251, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT | 00179 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER | 00180 MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00181 "windows-1251", "windows-1251", "windows-1251" }, 00182 { "Cyrillic (Mac)", 00183 10007, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00184 MIMECONTF_MIME_LATEST, 00185 "x-mac-cyrillic", "x-mac-cyrillic", "x-mac-cyrillic" }, 00186 { "Cyrillic (KOI8-R)", 00187 20866, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00188 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00189 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | 00190 MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00191 "koi8-r", "koi8-r", "koi8-r" }, 00192 { "Cyrillic (KOI8-U)", 00193 21866, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00194 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00195 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | 00196 MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00197 "koi8-u", "koi8-u", "koi8-u" }, 00198 { "Cyrillic (ISO)", 00199 28595, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00200 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00201 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | 00202 MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00203 "iso-8859-5", "iso-8859-5", "iso-8859-5" } 00204 }; 00205 static const MIME_CP_INFO greek_cp[] = 00206 { 00207 { "Greek (DOS)", 00208 737, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00209 MIMECONTF_MIME_LATEST, 00210 "ibm737", "ibm737", "ibm737" }, 00211 { "Greek, Modern (DOS)", 00212 869, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00213 MIMECONTF_MIME_LATEST, 00214 "ibm869", "ibm869", "ibm869" }, 00215 { "IBM EBCDIC (Greek Modern)", 00216 875, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00217 MIMECONTF_MIME_LATEST, 00218 "cp875", "cp875", "cp875" }, 00219 { "Greek (Windows)", 00220 1253, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT | 00221 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER | 00222 MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00223 "windows-1253", "windows-1253", "windows-1253" }, 00224 { "Greek (Mac)", 00225 10006, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00226 MIMECONTF_MIME_LATEST, 00227 "x-mac-greek", "x-mac-greek", "x-mac-greek" }, 00228 { "Greek (ISO)", 00229 28597, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00230 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00231 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | 00232 MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00233 "iso-8859-7", "iso-8859-7", "iso-8859-7" } 00234 }; 00235 static const MIME_CP_INFO hebrew_cp[] = 00236 { 00237 { "Hebrew (424)", 00238 424, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00239 MIMECONTF_MIME_LATEST, 00240 "ibm424", "ibm424", "ibm424" }, 00241 { "Hebrew (856)", 00242 856, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00243 MIMECONTF_MIME_LATEST, 00244 "cp856", "cp856", "cp856" }, 00245 { "Hebrew (DOS)", 00246 862, MIMECONTF_BROWSER | MIMECONTF_MINIMAL | MIMECONTF_IMPORT | 00247 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00248 MIMECONTF_MIME_LATEST, 00249 "dos-862", "dos-862", "dos-862" }, 00250 { "Hebrew (Windows)", 00251 1255, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT | 00252 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER | 00253 MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00254 "windows-1255", "windows-1255", "windows-1255" }, 00255 { "Hebrew (ISO-Visual)", 00256 28598, MIMECONTF_BROWSER | MIMECONTF_MINIMAL | MIMECONTF_IMPORT | 00257 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | 00258 MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00259 "iso-8859-8", "iso-8859-8", "iso-8859-8" } 00260 }; 00261 static const MIME_CP_INFO japanese_cp[] = 00262 { 00263 { "Japanese (Auto-Select)", 00264 50932, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00265 MIMECONTF_IMPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS | 00266 MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00267 "_autodetect", "_autodetect", "_autodetect" }, 00268 { "Japanese (EUC)", 00269 51932, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00270 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00271 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID | 00272 MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00273 "euc-jp", "euc-jp", "euc-jp" }, 00274 { "Japanese (JIS)", 00275 50220, MIMECONTF_IMPORT | MIMECONTF_MAILNEWS | MIMECONTF_EXPORT | 00276 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_VALID_NLS | 00277 MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST | 00278 MIMECONTF_MIME_IE4, 00279 "iso-2022-jp","iso-2022-jp","iso-2022-jp"}, 00280 { "Japanese (JIS 0208-1990 and 0212-1990)", 00281 20932, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00282 MIMECONTF_VALID | MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST, 00283 "EUC-JP","EUC-JP","EUC-JP"}, 00284 { "Japanese (JIS-Allow 1 byte Kana)", 00285 50221, MIMECONTF_MAILNEWS | MIMECONTF_EXPORT | MIMECONTF_SAVABLE_BROWSER | 00286 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_VALID_NLS | 00287 MIMECONTF_VALID | MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST, 00288 "csISO2022JP","iso-2022-jp","iso-2022-jp"}, 00289 { "Japanese (JIS-Allow 1 byte Kana - SO/SI)", 00290 50222, MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_VALID | 00291 MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST, 00292 "iso-2022-jp","iso-2022-jp","iso-2022-jp"}, 00293 { "Japanese (Mac)", 00294 10001, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00295 MIMECONTF_VALID | MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST, 00296 "x-mac-japanese","x-mac-japanese","x-mac-japanese"}, 00297 { "Japanese (Shift-JIS)", 00298 932, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00299 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00300 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID | 00301 MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00302 "shift_jis", "iso-2022-jp", "iso-2022-jp" } 00303 }; 00304 static const MIME_CP_INFO korean_cp[] = 00305 { 00306 { "Korean", 00307 949, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00308 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00309 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | 00310 MIMECONTF_MIME_LATEST, 00311 "ks_c_5601-1987", "ks_c_5601-1987", "ks_c_5601-1987" } 00312 }; 00313 static const MIME_CP_INFO thai_cp[] = 00314 { 00315 { "Thai (Windows)", 00316 874, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_MIME_LATEST, 00317 "ibm-thai", "ibm-thai", "ibm-thai" } 00318 }; 00319 static const MIME_CP_INFO turkish_cp[] = 00320 { 00321 { "Turkish (DOS)", 00322 857, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00323 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00324 "ibm857", "ibm857", "ibm857" }, 00325 { "IBM EBCDIC (Turkish Latin-5)", 00326 1026, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00327 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00328 "ibm1026", "ibm1026", "ibm1026" }, 00329 { "Turkish (Windows)", 00330 1254, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00331 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00332 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID | 00333 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00334 "windows-1254", "windows-1254", "windows-1254" }, 00335 { "Turkish (Mac)", 00336 10081, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00337 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00338 "x-mac-turkish", "x-mac-turkish", "x-mac-turkish" }, 00339 { "Latin 3 (ISO)", 00340 28593, MIMECONTF_MAILNEWS | MIMECONTF_IMPORT | 00341 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_EXPORT | MIMECONTF_VALID | 00342 MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00343 "iso-8859-3", "iso-8859-3", "iso-8859-3" }, 00344 { "Turkish (ISO)", 00345 28599, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00346 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00347 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID | 00348 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00349 "iso-8859-9", "iso-8859-9", "iso-8859-9" } 00350 }; 00351 static const MIME_CP_INFO vietnamese_cp[] = 00352 { 00353 { "Vietnamese (Windows)", 00354 1258, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT | 00355 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER | 00356 MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | 00357 MIMECONTF_MIME_LATEST, 00358 "windows-1258", "windows-1258", "windows-1258" } 00359 }; 00360 static const MIME_CP_INFO western_cp[] = 00361 { 00362 { "IBM EBCDIC (US-Canada)", 00363 37, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00364 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00365 "ibm037", "ibm037", "ibm037" }, 00366 { "OEM United States", 00367 437, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00368 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00369 "ibm437", "ibm437", "ibm437" }, 00370 { "IBM EBCDIC (International)", 00371 500, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00372 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00373 "ibm500", "ibm500", "ibm500" }, 00374 { "Western European (DOS)", 00375 850, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00376 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00377 "ibm850", "ibm850", "ibm850" }, 00378 { "Portuguese (DOS)", 00379 860, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00380 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00381 "ibm860", "ibm860", "ibm860" }, 00382 { "Icelandic (DOS)", 00383 861, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00384 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00385 "ibm861", "ibm861", "ibm861" }, 00386 { "French Canadian (DOS)", 00387 863, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00388 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00389 "ibm863", "ibm863", "ibm863" }, 00390 { "Nordic (DOS)", 00391 865, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00392 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00393 "ibm865", "ibm865", "ibm865" }, 00394 { "Western European (Windows)", 00395 1252, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | 00396 MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | 00397 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID | 00398 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00399 "windows-1252", "windows-1252", "iso-8859-1" }, 00400 { "Western European (Mac)", 00401 10000, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00402 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00403 "macintosh", "macintosh", "macintosh" }, 00404 { "Icelandic (Mac)", 00405 10079, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID | 00406 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00407 "x-mac-icelandic", "x-mac-icelandic", "x-mac-icelandic" }, 00408 { "US-ASCII", 00409 20127, MIMECONTF_MAILNEWS | MIMECONTF_IMPORT | MIMECONTF_EXPORT | 00410 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_VALID | 00411 MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST, 00412 "us-ascii", "us-ascii", "us-ascii" }, 00413 { "Western European (ISO)", 00414 28591, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT | 00415 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER | 00416 MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS | 00417 MIMECONTF_MIME_LATEST, 00418 "iso-8859-1", "iso-8859-1", "iso-8859-1" }, 00419 { "Latin 9 (ISO)", 00420 28605, MIMECONTF_MAILNEWS | MIMECONTF_IMPORT | 00421 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER | 00422 MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS | 00423 MIMECONTF_MIME_LATEST, 00424 "iso-8859-15", "iso-8859-15", "iso-8859-15" } 00425 }; 00426 static const MIME_CP_INFO unicode_cp[] = 00427 { 00428 { "Unicode", 00429 CP_UNICODE, MIMECONTF_MINIMAL | MIMECONTF_IMPORT | 00430 MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | 00431 MIMECONTF_VALID | MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | 00432 MIMECONTF_MIME_LATEST, 00433 "unicode", "unicode", "unicode" }, 00434 { "Unicode (UTF-7)", 00435 CP_UTF7, MIMECONTF_MAILNEWS | MIMECONTF_IMPORT | 00436 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_EXPORT | MIMECONTF_VALID | 00437 MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00438 "utf-7", "utf-7", "utf-7" }, 00439 { "Unicode (UTF-8)", 00440 CP_UTF8, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT | 00441 MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER | 00442 MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS | 00443 MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, 00444 "utf-8", "utf-8", "utf-8" } 00445 }; 00446 00447 static const struct mlang_data 00448 { 00449 const char *description; 00450 UINT family_codepage; 00451 UINT number_of_cp; 00452 const MIME_CP_INFO *mime_cp_info; 00453 const char *fixed_font; 00454 const char *proportional_font; 00455 SCRIPT_ID sid; 00456 } mlang_data[] = 00457 { 00458 { "Arabic",1256,sizeof(arabic_cp)/sizeof(arabic_cp[0]),arabic_cp, 00459 "Courier","Arial", sidArabic }, /* FIXME */ 00460 { "Baltic",1257,sizeof(baltic_cp)/sizeof(baltic_cp[0]),baltic_cp, 00461 "Courier","Arial", sidAsciiLatin }, /* FIXME */ 00462 { "Chinese Simplified",936,sizeof(chinese_simplified_cp)/sizeof(chinese_simplified_cp[0]),chinese_simplified_cp, 00463 "Courier","Arial", sidHan }, /* FIXME */ 00464 { "Chinese Traditional",950,sizeof(chinese_traditional_cp)/sizeof(chinese_traditional_cp[0]),chinese_traditional_cp, 00465 "Courier","Arial", sidBopomofo }, /* FIXME */ 00466 { "Central European",1250,sizeof(central_european_cp)/sizeof(central_european_cp[0]),central_european_cp, 00467 "Courier","Arial", sidAsciiLatin }, /* FIXME */ 00468 { "Cyrillic",1251,sizeof(cyrillic_cp)/sizeof(cyrillic_cp[0]),cyrillic_cp, 00469 "Courier","Arial", sidCyrillic }, /* FIXME */ 00470 { "Greek",1253,sizeof(greek_cp)/sizeof(greek_cp[0]),greek_cp, 00471 "Courier","Arial", sidGreek }, /* FIXME */ 00472 { "Hebrew",1255,sizeof(hebrew_cp)/sizeof(hebrew_cp[0]),hebrew_cp, 00473 "Courier","Arial", sidHebrew }, /* FIXME */ 00474 { "Japanese",932,sizeof(japanese_cp)/sizeof(japanese_cp[0]),japanese_cp, 00475 "MS Gothic","MS PGothic", sidKana }, 00476 { "Korean",949,sizeof(korean_cp)/sizeof(korean_cp[0]),korean_cp, 00477 "Courier","Arial", sidHangul }, /* FIXME */ 00478 { "Thai",874,sizeof(thai_cp)/sizeof(thai_cp[0]),thai_cp, 00479 "Courier","Arial", sidThai }, /* FIXME */ 00480 { "Turkish",1254,sizeof(turkish_cp)/sizeof(turkish_cp[0]),turkish_cp, 00481 "Courier","Arial", sidAsciiLatin }, /* FIXME */ 00482 { "Vietnamese",1258,sizeof(vietnamese_cp)/sizeof(vietnamese_cp[0]),vietnamese_cp, 00483 "Courier","Arial", sidAsciiLatin }, /* FIXME */ 00484 { "Western European",1252,sizeof(western_cp)/sizeof(western_cp[0]),western_cp, 00485 "Courier","Arial", sidAsciiLatin }, /* FIXME */ 00486 { "Unicode",CP_UNICODE,sizeof(unicode_cp)/sizeof(unicode_cp[0]),unicode_cp, 00487 "Courier","Arial" } /* FIXME */ 00488 }; 00489 00490 static void fill_cp_info(const struct mlang_data *ml_data, UINT index, MIMECPINFO *mime_cp_info); 00491 00492 static LONG dll_count; 00493 00494 /* 00495 * Japanese Detection and Converstion Functions 00496 */ 00497 00498 #define HANKATA(A) ((A >= 161) && (A <= 223)) 00499 #define ISEUC(A) ((A >= 161) && (A <= 254)) 00500 #define NOTEUC(A,B) (((A >= 129) && (A <= 159)) && ((B >= 64) && (B <= 160))) 00501 #define SJIS1(A) (((A >= 129) && (A <= 159)) || ((A >= 224) && (A <= 239))) 00502 #define SJIS2(A) ((A >= 64) && (A <= 252)) 00503 #define ISMARU(A) ((A >= 202) && (A <= 206)) 00504 #define ISNIGORI(A) (((A >= 182) && (A <= 196)) || ((A >= 202) && (A <= 206))) 00505 00506 static UINT DetectJapaneseCode(LPCSTR input, DWORD count) 00507 { 00508 UINT code = 0; 00509 DWORD i = 0; 00510 unsigned char c1,c2; 00511 00512 while ((code == 0 || code == 51932) && i < count) 00513 { 00514 c1 = input[i]; 00515 if (c1 == 0x1b /* ESC */) 00516 { 00517 i++; 00518 if (i >= count) 00519 return code; 00520 c1 = input[i]; 00521 if (c1 == '$') 00522 { 00523 i++; 00524 if (i >= count) 00525 return code; 00526 c1 = input[i]; 00527 if (c1 =='B' || c1 == '@') 00528 code = 50220; 00529 } 00530 if (c1 == 'K') 00531 code = 50220; 00532 } 00533 else if (c1 >= 129) 00534 { 00535 i++; 00536 if (i >= count) 00537 return code; 00538 c2 = input[i]; 00539 if NOTEUC(c1,c2) 00540 code = 932; 00541 else if (ISEUC(c1) && ISEUC(c2)) 00542 code = 51932; 00543 else if (((c1 == 142)) && HANKATA(c2)) 00544 code = 51932; 00545 } 00546 i++; 00547 } 00548 return code; 00549 } 00550 00551 static inline void jis2sjis(unsigned char *p1, unsigned char *p2) 00552 { 00553 unsigned char c1 = *p1; 00554 unsigned char c2 = *p2; 00555 int row = c1 < 95 ? 112 : 176; 00556 int cell = c1 % 2 ? 31 + (c2 > 95) : 126; 00557 00558 *p1 = ((c1 + 1) >> 1) + row; 00559 *p2 = c2 + cell; 00560 } 00561 00562 static inline void sjis2jis(unsigned char *p1, unsigned char *p2) 00563 { 00564 unsigned char c1 = *p1; 00565 unsigned char c2 = *p2; 00566 int shift = c2 < 159; 00567 int row = c1 < 160 ? 112 : 176; 00568 int cell = shift ? (31 + (c2 > 127)): 126; 00569 00570 *p1 = ((c1 - row) << 1) - shift; 00571 *p2 -= cell; 00572 } 00573 00574 static int han2zen(unsigned char *p1, unsigned char *p2) 00575 { 00576 int maru = FALSE; 00577 int nigori = FALSE; 00578 static const unsigned char char1[] = {129,129,129,129,129,131,131,131,131, 00579 131,131,131,131,131,131,129,131,131,131,131,131,131,131,131,131,131, 00580 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, 00581 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, 00582 131,129,129 }; 00583 static const unsigned char char2[] = {66,117,118,65,69,146,64,66,68,70, 00584 72,131,133,135,98,91,65,67,69,71,73,74,76,78,80,82,84,86,88,90,92,94, 00585 96,99,101,103,105,106,107,108,109,110,113,116,119,122,125,126,128, 00586 129,130,132,134,136,137,138,139,140,141,143,147,74,75}; 00587 00588 if (( *p2 == 222) && ((ISNIGORI(*p1) || (*p1 == 179)))) 00589 nigori = TRUE; 00590 else if ((*p2 == 223) && (ISMARU(*p1))) 00591 maru = TRUE; 00592 00593 if (*p1 >= 161 && *p1 <= 223) 00594 { 00595 unsigned char index = *p1 - 161; 00596 *p1 = char1[index]; 00597 *p2 = char2[index]; 00598 } 00599 00600 if (maru || nigori) 00601 { 00602 if (nigori) 00603 { 00604 if (((*p2 >= 74) && (*p2 <= 103)) || ((*p2 >= 110) && (*p2 <= 122))) 00605 (*p2)++; 00606 else if ((*p1 == 131) && (*p2 == 69)) 00607 *p2 = 148; 00608 } 00609 else if ((maru) && ((*p2 >= 110) && (*p2 <= 122))) 00610 *p2+= 2; 00611 00612 return 1; 00613 } 00614 00615 return 0; 00616 } 00617 00618 00619 static UINT ConvertJIS2SJIS(LPCSTR input, DWORD count, LPSTR output) 00620 { 00621 DWORD i = 0; 00622 int j = 0; 00623 unsigned char p2,p; 00624 int shifted = FALSE; 00625 00626 while (i < count) 00627 { 00628 p = input[i]; 00629 if (p == 0x1b /* ESC */) 00630 { 00631 i++; 00632 if (i >= count) 00633 return 0; 00634 p2 = input[i]; 00635 if (p2 == '$' || p2 =='(') 00636 i++; 00637 if (p2 == 'K' || p2 =='$') 00638 shifted = TRUE; 00639 else 00640 shifted = FALSE; 00641 } 00642 else 00643 { 00644 if (shifted) 00645 { 00646 i++; 00647 if (i >= count) 00648 return 0; 00649 p2 = input[i]; 00650 jis2sjis(&p,&p2); 00651 output[j++]=p; 00652 output[j++]=p2; 00653 } 00654 else 00655 { 00656 output[j++] = p; 00657 } 00658 } 00659 i++; 00660 } 00661 return j; 00662 } 00663 00664 static inline int exit_shift(LPSTR out, int c) 00665 { 00666 if (out) 00667 { 00668 out[c] = 0x1b; 00669 out[c+1] = '('; 00670 out[c+2] = 'B'; 00671 } 00672 return 3; 00673 } 00674 00675 static inline int enter_shift(LPSTR out, int c) 00676 { 00677 if (out) 00678 { 00679 out[c] = 0x1b; 00680 out[c+1] = '$'; 00681 out[c+2] = 'B'; 00682 } 00683 return 3; 00684 } 00685 00686 00687 static UINT ConvertSJIS2JIS(LPCSTR input, DWORD count, LPSTR output) 00688 { 00689 DWORD i = 0; 00690 int j = 0; 00691 unsigned char p2,p; 00692 int shifted = FALSE; 00693 00694 while (i < count) 00695 { 00696 p = input[i] & 0xff; 00697 if (p == 10 || p == 13) /* NL and CR */ 00698 { 00699 if (shifted) 00700 { 00701 shifted = FALSE; 00702 j += exit_shift(output,j); 00703 } 00704 if (output) 00705 output[j++] = p; 00706 else 00707 j++; 00708 } 00709 else 00710 { 00711 if (SJIS1(p)) 00712 { 00713 i++; 00714 if (i >= count) 00715 return 0; 00716 p2 = input[i] & 0xff; 00717 if (SJIS2(p2)) 00718 { 00719 sjis2jis(&p,&p2); 00720 if (!shifted) 00721 { 00722 shifted = TRUE; 00723 j+=enter_shift(output,j); 00724 } 00725 } 00726 00727 if (output) 00728 { 00729 output[j++]=p; 00730 output[j++]=p2; 00731 } 00732 else 00733 j+=2; 00734 } 00735 else 00736 { 00737 if (HANKATA(p)) 00738 { 00739 if ((i+1) >= count) 00740 return 0; 00741 p2 = input[i+1] & 0xff; 00742 i+=han2zen(&p,&p2); 00743 sjis2jis(&p,&p2); 00744 if (!shifted) 00745 { 00746 shifted = TRUE; 00747 j+=enter_shift(output,j); 00748 } 00749 if (output) 00750 { 00751 output[j++]=p; 00752 output[j++]=p2; 00753 } 00754 else 00755 j+=2; 00756 } 00757 else 00758 { 00759 if (shifted) 00760 { 00761 shifted = FALSE; 00762 j += exit_shift(output,j); 00763 } 00764 if (output) 00765 output[j++]=p; 00766 else 00767 j++; 00768 } 00769 } 00770 } 00771 i++; 00772 } 00773 if (shifted) 00774 j += exit_shift(output,j); 00775 return j; 00776 } 00777 00778 static UINT ConvertJISJapaneseToUnicode(LPCSTR input, DWORD count, 00779 LPWSTR output, DWORD out_count) 00780 { 00781 CHAR *sjis_string; 00782 UINT rc = 0; 00783 sjis_string = HeapAlloc(GetProcessHeap(),0,count); 00784 rc = ConvertJIS2SJIS(input,count,sjis_string); 00785 if (rc) 00786 { 00787 TRACE("%s\n",debugstr_an(sjis_string,rc)); 00788 if (output) 00789 rc = MultiByteToWideChar(932,0,sjis_string,rc,output,out_count); 00790 else 00791 rc = MultiByteToWideChar(932,0,sjis_string,rc,0,0); 00792 } 00793 HeapFree(GetProcessHeap(),0,sjis_string); 00794 return rc; 00795 00796 } 00797 00798 static UINT ConvertUnknownJapaneseToUnicode(LPCSTR input, DWORD count, 00799 LPWSTR output, DWORD out_count) 00800 { 00801 CHAR *sjis_string; 00802 UINT rc = 0; 00803 int code = DetectJapaneseCode(input,count); 00804 TRACE("Japanese code %i\n",code); 00805 00806 switch (code) 00807 { 00808 case 0: 00809 if (output) 00810 rc = MultiByteToWideChar(CP_ACP,0,input,count,output,out_count); 00811 else 00812 rc = MultiByteToWideChar(CP_ACP,0,input,count,0,0); 00813 break; 00814 00815 case 932: 00816 if (output) 00817 rc = MultiByteToWideChar(932,0,input,count,output,out_count); 00818 else 00819 rc = MultiByteToWideChar(932,0,input,count,0,0); 00820 break; 00821 00822 case 51932: 00823 if (output) 00824 rc = MultiByteToWideChar(20932,0,input,count,output,out_count); 00825 else 00826 rc = MultiByteToWideChar(20932,0,input,count,0,0); 00827 break; 00828 00829 case 50220: 00830 sjis_string = HeapAlloc(GetProcessHeap(),0,count); 00831 rc = ConvertJIS2SJIS(input,count,sjis_string); 00832 if (rc) 00833 { 00834 TRACE("%s\n",debugstr_an(sjis_string,rc)); 00835 if (output) 00836 rc = MultiByteToWideChar(932,0,sjis_string,rc,output,out_count); 00837 else 00838 rc = MultiByteToWideChar(932,0,sjis_string,rc,0,0); 00839 } 00840 HeapFree(GetProcessHeap(),0,sjis_string); 00841 break; 00842 } 00843 return rc; 00844 } 00845 00846 static UINT ConvertJapaneseUnicodeToJIS(LPCWSTR input, DWORD count, 00847 LPSTR output, DWORD out_count) 00848 { 00849 CHAR *sjis_string; 00850 INT len; 00851 UINT rc = 0; 00852 00853 len = WideCharToMultiByte(932,0,input,count,0,0,NULL,NULL); 00854 sjis_string = HeapAlloc(GetProcessHeap(),0,len); 00855 WideCharToMultiByte(932,0,input,count,sjis_string,len,NULL,NULL); 00856 TRACE("%s\n",debugstr_an(sjis_string,len)); 00857 00858 rc = ConvertSJIS2JIS(sjis_string, len, NULL); 00859 if (out_count >= rc) 00860 { 00861 ConvertSJIS2JIS(sjis_string, len, output); 00862 } 00863 HeapFree(GetProcessHeap(),0,sjis_string); 00864 return rc; 00865 00866 } 00867 00868 /* 00869 * Dll lifetime tracking declaration 00870 */ 00871 static void LockModule(void) 00872 { 00873 InterlockedIncrement(&dll_count); 00874 } 00875 00876 static void UnlockModule(void) 00877 { 00878 InterlockedDecrement(&dll_count); 00879 } 00880 00881 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) 00882 { 00883 switch(fdwReason) { 00884 case DLL_PROCESS_ATTACH: 00885 instance = hInstDLL; 00886 MLANG_tls_index = TlsAlloc(); 00887 DisableThreadLibraryCalls(hInstDLL); 00888 break; 00889 case DLL_PROCESS_DETACH: 00890 TlsFree(MLANG_tls_index); 00891 break; 00892 } 00893 return TRUE; 00894 } 00895 00896 HRESULT WINAPI ConvertINetMultiByteToUnicode( 00897 LPDWORD pdwMode, 00898 DWORD dwEncoding, 00899 LPCSTR pSrcStr, 00900 LPINT pcSrcSize, 00901 LPWSTR pDstStr, 00902 LPINT pcDstSize) 00903 { 00904 INT src_len = -1; 00905 00906 TRACE("%p %d %s %p %p %p\n", pdwMode, dwEncoding, 00907 debugstr_a(pSrcStr), pcSrcSize, pDstStr, pcDstSize); 00908 00909 if (!pcDstSize) 00910 return E_FAIL; 00911 00912 if (!pcSrcSize) 00913 pcSrcSize = &src_len; 00914 00915 if (!*pcSrcSize) 00916 { 00917 *pcDstSize = 0; 00918 return S_OK; 00919 } 00920 00921 /* forwarding euc-jp to EUC-JP */ 00922 if (dwEncoding == 51932) 00923 dwEncoding = 20932; 00924 00925 switch (dwEncoding) 00926 { 00927 case CP_UNICODE: 00928 if (*pcSrcSize == -1) 00929 *pcSrcSize = lstrlenW((LPCWSTR)pSrcStr); 00930 *pcDstSize = min(*pcSrcSize, *pcDstSize); 00931 *pcSrcSize *= sizeof(WCHAR); 00932 if (pDstStr) 00933 memmove(pDstStr, pSrcStr, *pcDstSize * sizeof(WCHAR)); 00934 break; 00935 00936 case 50220: 00937 case 50221: 00938 case 50222: 00939 *pcDstSize = ConvertJISJapaneseToUnicode(pSrcStr,*pcSrcSize,pDstStr,*pcDstSize); 00940 break; 00941 case 50932: 00942 *pcDstSize = ConvertUnknownJapaneseToUnicode(pSrcStr,*pcSrcSize,pDstStr,*pcDstSize); 00943 break; 00944 00945 default: 00946 if (*pcSrcSize == -1) 00947 *pcSrcSize = lstrlenA(pSrcStr); 00948 00949 if (pDstStr) 00950 *pcDstSize = MultiByteToWideChar(dwEncoding, 0, pSrcStr, *pcSrcSize, pDstStr, *pcDstSize); 00951 else 00952 *pcDstSize = MultiByteToWideChar(dwEncoding, 0, pSrcStr, *pcSrcSize, NULL, 0); 00953 break; 00954 } 00955 00956 if (!*pcDstSize) 00957 return E_FAIL; 00958 00959 return S_OK; 00960 } 00961 00962 HRESULT WINAPI ConvertINetUnicodeToMultiByte( 00963 LPDWORD pdwMode, 00964 DWORD dwEncoding, 00965 LPCWSTR pSrcStr, 00966 LPINT pcSrcSize, 00967 LPSTR pDstStr, 00968 LPINT pcDstSize) 00969 { 00970 INT destsz, size; 00971 INT src_len = -1; 00972 00973 TRACE("%p %d %s %p %p %p\n", pdwMode, dwEncoding, 00974 debugstr_w(pSrcStr), pcSrcSize, pDstStr, pcDstSize); 00975 00976 if (!pcDstSize) 00977 return S_OK; 00978 00979 if (!pcSrcSize) 00980 pcSrcSize = &src_len; 00981 00982 destsz = (pDstStr) ? *pcDstSize : 0; 00983 *pcDstSize = 0; 00984 00985 if (!pSrcStr || !*pcSrcSize) 00986 return S_OK; 00987 00988 if (*pcSrcSize == -1) 00989 *pcSrcSize = lstrlenW(pSrcStr); 00990 00991 /* forwarding euc-jp to EUC-JP */ 00992 if (dwEncoding == 51932) 00993 dwEncoding = 20932; 00994 00995 if (dwEncoding == CP_UNICODE) 00996 { 00997 if (*pcSrcSize == -1) 00998 *pcSrcSize = lstrlenW(pSrcStr); 00999 01000 size = min(*pcSrcSize, destsz) * sizeof(WCHAR); 01001 if (pDstStr) 01002 memmove(pDstStr, pSrcStr, size); 01003 01004 if (size >= destsz) 01005 goto fail; 01006 } 01007 else if (dwEncoding == 50220 || dwEncoding == 50221 || dwEncoding == 50222) 01008 { 01009 size = ConvertJapaneseUnicodeToJIS(pSrcStr, *pcSrcSize, NULL, 0); 01010 if (!size) 01011 goto fail; 01012 01013 if (pDstStr) 01014 { 01015 size = ConvertJapaneseUnicodeToJIS(pSrcStr, *pcSrcSize, pDstStr, 01016 destsz); 01017 if (!size) 01018 goto fail; 01019 } 01020 01021 } 01022 else 01023 { 01024 size = WideCharToMultiByte(dwEncoding, 0, pSrcStr, *pcSrcSize, 01025 NULL, 0, NULL, NULL); 01026 if (!size) 01027 goto fail; 01028 01029 if (pDstStr) 01030 { 01031 size = WideCharToMultiByte(dwEncoding, 0, pSrcStr, *pcSrcSize, 01032 pDstStr, destsz, NULL, NULL); 01033 if (!size) 01034 goto fail; 01035 } 01036 } 01037 01038 *pcDstSize = size; 01039 return S_OK; 01040 01041 fail: 01042 *pcSrcSize = 0; 01043 *pcDstSize = 0; 01044 return E_FAIL; 01045 } 01046 01047 HRESULT WINAPI ConvertINetString( 01048 LPDWORD pdwMode, 01049 DWORD dwSrcEncoding, 01050 DWORD dwDstEncoding, 01051 LPCSTR pSrcStr, 01052 LPINT pcSrcSize, 01053 LPSTR pDstStr, 01054 LPINT pcDstSize 01055 ) 01056 { 01057 TRACE("%p %d %d %s %p %p %p\n", pdwMode, dwSrcEncoding, dwDstEncoding, 01058 debugstr_a(pSrcStr), pcSrcSize, pDstStr, pcDstSize); 01059 01060 if (dwSrcEncoding == CP_UNICODE) 01061 { 01062 INT cSrcSizeW; 01063 if (pcSrcSize && *pcSrcSize != -1) 01064 { 01065 cSrcSizeW = *pcSrcSize / sizeof(WCHAR); 01066 pcSrcSize = &cSrcSizeW; 01067 } 01068 return ConvertINetUnicodeToMultiByte(pdwMode, dwDstEncoding, (LPCWSTR)pSrcStr, pcSrcSize, pDstStr, pcDstSize); 01069 } 01070 else if (dwDstEncoding == CP_UNICODE) 01071 { 01072 HRESULT hr = ConvertINetMultiByteToUnicode(pdwMode, dwSrcEncoding, pSrcStr, pcSrcSize, (LPWSTR)pDstStr, pcDstSize); 01073 *pcDstSize *= sizeof(WCHAR); 01074 return hr; 01075 } 01076 else 01077 { 01078 INT cDstSizeW; 01079 LPWSTR pDstStrW; 01080 HRESULT hr; 01081 01082 TRACE("convert %s from %d to %d\n", debugstr_a(pSrcStr), dwSrcEncoding, dwDstEncoding); 01083 01084 hr = ConvertINetMultiByteToUnicode(pdwMode, dwSrcEncoding, pSrcStr, pcSrcSize, NULL, &cDstSizeW); 01085 if (hr != S_OK) 01086 return hr; 01087 01088 pDstStrW = HeapAlloc(GetProcessHeap(), 0, cDstSizeW * sizeof(WCHAR)); 01089 hr = ConvertINetMultiByteToUnicode(pdwMode, dwSrcEncoding, pSrcStr, pcSrcSize, pDstStrW, &cDstSizeW); 01090 if (hr == S_OK) 01091 hr = ConvertINetUnicodeToMultiByte(pdwMode, dwDstEncoding, pDstStrW, &cDstSizeW, pDstStr, pcDstSize); 01092 01093 HeapFree(GetProcessHeap(), 0, pDstStrW); 01094 return hr; 01095 } 01096 } 01097 01098 static HRESULT GetFamilyCodePage( 01099 UINT uiCodePage, 01100 UINT* puiFamilyCodePage) 01101 { 01102 UINT i, n; 01103 01104 TRACE("%u %p\n", uiCodePage, puiFamilyCodePage); 01105 01106 if (!puiFamilyCodePage) return S_FALSE; 01107 01108 for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 01109 { 01110 for (n = 0; n < mlang_data[i].number_of_cp; n++) 01111 { 01112 if (mlang_data[i].mime_cp_info[n].cp == uiCodePage) 01113 { 01114 *puiFamilyCodePage = mlang_data[i].family_codepage; 01115 return S_OK; 01116 } 01117 } 01118 } 01119 01120 return S_FALSE; 01121 } 01122 01123 HRESULT WINAPI IsConvertINetStringAvailable( 01124 DWORD dwSrcEncoding, 01125 DWORD dwDstEncoding) 01126 { 01127 UINT src_family, dst_family; 01128 01129 TRACE("%d %d\n", dwSrcEncoding, dwDstEncoding); 01130 01131 if (GetFamilyCodePage(dwSrcEncoding, &src_family) != S_OK || 01132 GetFamilyCodePage(dwDstEncoding, &dst_family) != S_OK) 01133 return S_FALSE; 01134 01135 if (src_family == dst_family) return S_OK; 01136 01137 /* we can convert any codepage to/from unicode */ 01138 if (src_family == CP_UNICODE || dst_family == CP_UNICODE) return S_OK; 01139 01140 return S_FALSE; 01141 } 01142 01143 static inline HRESULT lcid_to_rfc1766A( LCID lcid, LPSTR rfc1766, INT len ) 01144 { 01145 CHAR buffer[MAX_RFC1766_NAME]; 01146 INT n = GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, buffer, MAX_RFC1766_NAME); 01147 INT i; 01148 01149 if (n) 01150 { 01151 i = PRIMARYLANGID(lcid); 01152 if ((((i == LANG_ENGLISH) || (i == LANG_CHINESE) || (i == LANG_ARABIC)) && 01153 (SUBLANGID(lcid) == SUBLANG_DEFAULT)) || 01154 (SUBLANGID(lcid) > SUBLANG_DEFAULT)) { 01155 01156 buffer[n - 1] = '-'; 01157 i = GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, buffer + n, MAX_RFC1766_NAME - n); 01158 if (!i) 01159 buffer[n - 1] = '\0'; 01160 } 01161 else 01162 i = 0; 01163 01164 LCMapStringA( LOCALE_USER_DEFAULT, LCMAP_LOWERCASE, buffer, n + i, rfc1766, len ); 01165 return ((n + i) > len) ? E_INVALIDARG : S_OK; 01166 } 01167 return E_FAIL; 01168 } 01169 01170 static inline HRESULT lcid_to_rfc1766W( LCID lcid, LPWSTR rfc1766, INT len ) 01171 { 01172 WCHAR buffer[MAX_RFC1766_NAME]; 01173 INT n = GetLocaleInfoW(lcid, LOCALE_SISO639LANGNAME, buffer, MAX_RFC1766_NAME); 01174 INT i; 01175 01176 if (n) 01177 { 01178 i = PRIMARYLANGID(lcid); 01179 if ((((i == LANG_ENGLISH) || (i == LANG_CHINESE) || (i == LANG_ARABIC)) && 01180 (SUBLANGID(lcid) == SUBLANG_DEFAULT)) || 01181 (SUBLANGID(lcid) > SUBLANG_DEFAULT)) { 01182 01183 buffer[n - 1] = '-'; 01184 i = GetLocaleInfoW(lcid, LOCALE_SISO3166CTRYNAME, buffer + n, MAX_RFC1766_NAME - n); 01185 if (!i) 01186 buffer[n - 1] = '\0'; 01187 } 01188 else 01189 i = 0; 01190 01191 LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE, buffer, n + i, rfc1766, len); 01192 return ((n + i) > len) ? E_INVALIDARG : S_OK; 01193 } 01194 return E_FAIL; 01195 } 01196 01197 HRESULT WINAPI LcidToRfc1766A( 01198 LCID lcid, 01199 LPSTR pszRfc1766, 01200 INT nChar) 01201 { 01202 TRACE("%04x %p %u\n", lcid, pszRfc1766, nChar); 01203 if (!pszRfc1766) 01204 return E_INVALIDARG; 01205 01206 return lcid_to_rfc1766A(lcid, pszRfc1766, nChar); 01207 } 01208 01209 HRESULT WINAPI LcidToRfc1766W( 01210 LCID lcid, 01211 LPWSTR pszRfc1766, 01212 INT nChar) 01213 { 01214 TRACE("%04x %p %u\n", lcid, pszRfc1766, nChar); 01215 if (!pszRfc1766) 01216 return E_INVALIDARG; 01217 01218 return lcid_to_rfc1766W(lcid, pszRfc1766, nChar); 01219 } 01220 01221 static HRESULT lcid_from_rfc1766(IEnumRfc1766 *iface, LCID *lcid, LPCWSTR rfc1766) 01222 { 01223 RFC1766INFO info; 01224 ULONG num; 01225 01226 while (IEnumRfc1766_Next(iface, 1, &info, &num) == S_OK) 01227 { 01228 if (!strcmpiW(info.wszRfc1766, rfc1766)) 01229 { 01230 *lcid = info.lcid; 01231 return S_OK; 01232 } 01233 if (strlenW(rfc1766) == 2 && !memcmp(info.wszRfc1766, rfc1766, 2 * sizeof(WCHAR))) 01234 { 01235 *lcid = PRIMARYLANGID(info.lcid); 01236 return S_OK; 01237 } 01238 } 01239 01240 return E_FAIL; 01241 } 01242 01243 HRESULT WINAPI Rfc1766ToLcidW(LCID *pLocale, LPCWSTR pszRfc1766) 01244 { 01245 IEnumRfc1766 *enumrfc1766; 01246 HRESULT hr; 01247 01248 TRACE("(%p, %s)\n", pLocale, debugstr_w(pszRfc1766)); 01249 01250 if (!pLocale || !pszRfc1766) 01251 return E_INVALIDARG; 01252 01253 hr = EnumRfc1766_create(0, &enumrfc1766); 01254 if (FAILED(hr)) 01255 return hr; 01256 01257 hr = lcid_from_rfc1766(enumrfc1766, pLocale, pszRfc1766); 01258 IEnumRfc1766_Release(enumrfc1766); 01259 01260 return hr; 01261 } 01262 01263 HRESULT WINAPI Rfc1766ToLcidA(LCID *lcid, LPCSTR rfc1766A) 01264 { 01265 WCHAR rfc1766W[MAX_RFC1766_NAME + 1]; 01266 01267 if (!rfc1766A) 01268 return E_INVALIDARG; 01269 01270 MultiByteToWideChar(CP_ACP, 0, rfc1766A, -1, rfc1766W, MAX_RFC1766_NAME); 01271 rfc1766W[MAX_RFC1766_NAME] = 0; 01272 01273 return Rfc1766ToLcidW(lcid, rfc1766W); 01274 } 01275 01276 /****************************************************************************** 01277 * MLANG ClassFactory 01278 */ 01279 typedef struct { 01280 IClassFactory ITF_IClassFactory; 01281 01282 LONG ref; 01283 HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); 01284 } IClassFactoryImpl; 01285 01286 struct object_creation_info 01287 { 01288 const CLSID *clsid; 01289 LPCSTR szClassName; 01290 HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); 01291 }; 01292 01293 static const struct object_creation_info object_creation[] = 01294 { 01295 { &CLSID_CMultiLanguage, "CLSID_CMultiLanguage", MultiLanguage_create }, 01296 }; 01297 01298 static HRESULT WINAPI 01299 MLANGCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) 01300 { 01301 IClassFactoryImpl *This = (IClassFactoryImpl *)iface; 01302 01303 TRACE("%s\n", debugstr_guid(riid) ); 01304 01305 if (IsEqualGUID(riid, &IID_IUnknown) 01306 || IsEqualGUID(riid, &IID_IClassFactory)) 01307 { 01308 IClassFactory_AddRef(iface); 01309 *ppobj = This; 01310 return S_OK; 01311 } 01312 01313 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); 01314 return E_NOINTERFACE; 01315 } 01316 01317 static ULONG WINAPI MLANGCF_AddRef(LPCLASSFACTORY iface) 01318 { 01319 IClassFactoryImpl *This = (IClassFactoryImpl *)iface; 01320 return InterlockedIncrement(&This->ref); 01321 } 01322 01323 static ULONG WINAPI MLANGCF_Release(LPCLASSFACTORY iface) 01324 { 01325 IClassFactoryImpl *This = (IClassFactoryImpl *)iface; 01326 01327 ULONG ref = InterlockedDecrement(&This->ref); 01328 01329 if (ref == 0) 01330 { 01331 TRACE("Destroying %p\n", This); 01332 HeapFree(GetProcessHeap(), 0, This); 01333 } 01334 01335 return ref; 01336 } 01337 01338 static HRESULT WINAPI MLANGCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, 01339 REFIID riid, LPVOID *ppobj) 01340 { 01341 IClassFactoryImpl *This = (IClassFactoryImpl *)iface; 01342 HRESULT hres; 01343 LPUNKNOWN punk; 01344 01345 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); 01346 01347 *ppobj = NULL; 01348 hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk); 01349 if (SUCCEEDED(hres)) { 01350 hres = IUnknown_QueryInterface(punk, riid, ppobj); 01351 IUnknown_Release(punk); 01352 } 01353 TRACE("returning (%p) -> %x\n", *ppobj, hres); 01354 return hres; 01355 } 01356 01357 static HRESULT WINAPI MLANGCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) 01358 { 01359 if (dolock) 01360 LockModule(); 01361 else 01362 UnlockModule(); 01363 01364 return S_OK; 01365 } 01366 01367 static const IClassFactoryVtbl MLANGCF_Vtbl = 01368 { 01369 MLANGCF_QueryInterface, 01370 MLANGCF_AddRef, 01371 MLANGCF_Release, 01372 MLANGCF_CreateInstance, 01373 MLANGCF_LockServer 01374 }; 01375 01376 /****************************************************************** 01377 * DllGetClassObject (MLANG.@) 01378 */ 01379 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) 01380 { 01381 unsigned int i; 01382 IClassFactoryImpl *factory; 01383 01384 TRACE("%s %s %p\n",debugstr_guid(rclsid), debugstr_guid(iid), ppv); 01385 01386 if ( !IsEqualGUID( &IID_IClassFactory, iid ) 01387 && ! IsEqualGUID( &IID_IUnknown, iid) ) 01388 return E_NOINTERFACE; 01389 01390 for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) 01391 { 01392 if (IsEqualGUID(object_creation[i].clsid, rclsid)) 01393 break; 01394 } 01395 01396 if (i == sizeof(object_creation)/sizeof(object_creation[0])) 01397 { 01398 FIXME("%s: no class found.\n", debugstr_guid(rclsid)); 01399 return CLASS_E_CLASSNOTAVAILABLE; 01400 } 01401 01402 TRACE("Creating a class factory for %s\n",object_creation[i].szClassName); 01403 01404 factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory)); 01405 if (factory == NULL) return E_OUTOFMEMORY; 01406 01407 factory->ITF_IClassFactory.lpVtbl = &MLANGCF_Vtbl; 01408 factory->ref = 1; 01409 01410 factory->pfnCreateInstance = object_creation[i].pfnCreateInstance; 01411 01412 *ppv = &(factory->ITF_IClassFactory); 01413 01414 TRACE("(%p) <- %p\n", ppv, &(factory->ITF_IClassFactory) ); 01415 01416 return S_OK; 01417 } 01418 01419 01420 /******************************************************************************/ 01421 01422 typedef struct tagMLang_impl 01423 { 01424 IMLangFontLink IMLangFontLink_iface; 01425 IMultiLanguage IMultiLanguage_iface; 01426 IMultiLanguage3 IMultiLanguage3_iface; 01427 IMLangFontLink2 IMLangFontLink2_iface; 01428 IMLangLineBreakConsole IMLangLineBreakConsole_iface; 01429 LONG ref; 01430 DWORD total_cp, total_scripts; 01431 } MLang_impl; 01432 01433 static ULONG MLang_AddRef( MLang_impl* This) 01434 { 01435 return InterlockedIncrement(&This->ref); 01436 } 01437 01438 static ULONG MLang_Release( MLang_impl* This ) 01439 { 01440 ULONG ref = InterlockedDecrement(&This->ref); 01441 01442 TRACE("%p ref = %d\n", This, ref); 01443 if (ref == 0) 01444 { 01445 TRACE("Destroying %p\n", This); 01446 HeapFree(GetProcessHeap(), 0, This); 01447 UnlockModule(); 01448 } 01449 01450 return ref; 01451 } 01452 01453 static HRESULT MLang_QueryInterface( 01454 MLang_impl* This, 01455 REFIID riid, 01456 void** ppvObject) 01457 { 01458 TRACE("%p -> %s\n", This, debugstr_guid(riid) ); 01459 01460 if (IsEqualGUID(riid, &IID_IUnknown) 01461 || IsEqualGUID(riid, &IID_IMLangCodePages) 01462 || IsEqualGUID(riid, &IID_IMLangFontLink)) 01463 { 01464 MLang_AddRef(This); 01465 TRACE("Returning IID_IMLangFontLink %p ref = %d\n", This, This->ref); 01466 *ppvObject = &This->IMLangFontLink_iface; 01467 return S_OK; 01468 } 01469 01470 if (IsEqualGUID(riid, &IID_IMLangFontLink2)) 01471 { 01472 MLang_AddRef(This); 01473 TRACE("Returning IID_IMLangFontLink2 %p ref = %d\n", This, This->ref); 01474 *ppvObject = &This->IMLangFontLink2_iface; 01475 return S_OK; 01476 } 01477 01478 if (IsEqualGUID(riid, &IID_IMultiLanguage) ) 01479 { 01480 MLang_AddRef(This); 01481 TRACE("Returning IID_IMultiLanguage %p ref = %d\n", This, This->ref); 01482 *ppvObject = &This->IMultiLanguage_iface; 01483 return S_OK; 01484 } 01485 01486 if (IsEqualGUID(riid, &IID_IMultiLanguage2) ) 01487 { 01488 MLang_AddRef(This); 01489 *ppvObject = &This->IMultiLanguage3_iface; 01490 TRACE("Returning IID_IMultiLanguage2 %p ref = %d\n", This, This->ref); 01491 return S_OK; 01492 } 01493 01494 if (IsEqualGUID(riid, &IID_IMultiLanguage3) ) 01495 { 01496 MLang_AddRef(This); 01497 *ppvObject = &This->IMultiLanguage3_iface; 01498 TRACE("Returning IID_IMultiLanguage3 %p ref = %d\n", This, This->ref); 01499 return S_OK; 01500 } 01501 01502 if (IsEqualGUID(riid, &IID_IMLangLineBreakConsole)) 01503 { 01504 MLang_AddRef(This); 01505 TRACE("Returning IID_IMLangLineBreakConsole %p ref = %d\n", This, This->ref); 01506 *ppvObject = &This->IMLangLineBreakConsole_iface; 01507 return S_OK; 01508 } 01509 01510 01511 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); 01512 return E_NOINTERFACE; 01513 } 01514 01515 /******************************************************************************/ 01516 01517 typedef struct tagEnumCodePage_impl 01518 { 01519 IEnumCodePage IEnumCodePage_iface; 01520 LONG ref; 01521 MIMECPINFO *cpinfo; 01522 DWORD total, pos; 01523 } EnumCodePage_impl; 01524 01525 static inline EnumCodePage_impl *impl_from_IEnumCodePage( IEnumCodePage *iface ) 01526 { 01527 return CONTAINING_RECORD( iface, EnumCodePage_impl, IEnumCodePage_iface ); 01528 } 01529 01530 static HRESULT WINAPI fnIEnumCodePage_QueryInterface( 01531 IEnumCodePage* iface, 01532 REFIID riid, 01533 void** ppvObject) 01534 { 01535 EnumCodePage_impl *This = impl_from_IEnumCodePage( iface ); 01536 01537 TRACE("%p -> %s\n", This, debugstr_guid(riid) ); 01538 01539 if (IsEqualGUID(riid, &IID_IUnknown) 01540 || IsEqualGUID(riid, &IID_IEnumCodePage)) 01541 { 01542 IEnumCodePage_AddRef(iface); 01543 TRACE("Returning IID_IEnumCodePage %p ref = %d\n", This, This->ref); 01544 *ppvObject = &This->IEnumCodePage_iface; 01545 return S_OK; 01546 } 01547 01548 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); 01549 return E_NOINTERFACE; 01550 } 01551 01552 static ULONG WINAPI fnIEnumCodePage_AddRef( 01553 IEnumCodePage* iface) 01554 { 01555 EnumCodePage_impl *This = impl_from_IEnumCodePage( iface ); 01556 return InterlockedIncrement(&This->ref); 01557 } 01558 01559 static ULONG WINAPI fnIEnumCodePage_Release( 01560 IEnumCodePage* iface) 01561 { 01562 EnumCodePage_impl *This = impl_from_IEnumCodePage( iface ); 01563 ULONG ref = InterlockedDecrement(&This->ref); 01564 01565 TRACE("%p ref = %d\n", This, ref); 01566 if (ref == 0) 01567 { 01568 TRACE("Destroying %p\n", This); 01569 HeapFree(GetProcessHeap(), 0, This->cpinfo); 01570 HeapFree(GetProcessHeap(), 0, This); 01571 } 01572 01573 return ref; 01574 } 01575 01576 static HRESULT WINAPI fnIEnumCodePage_Clone( 01577 IEnumCodePage* iface, 01578 IEnumCodePage** ppEnum) 01579 { 01580 EnumCodePage_impl *This = impl_from_IEnumCodePage( iface ); 01581 FIXME("%p %p\n", This, ppEnum); 01582 return E_NOTIMPL; 01583 } 01584 01585 static HRESULT WINAPI fnIEnumCodePage_Next( 01586 IEnumCodePage* iface, 01587 ULONG celt, 01588 PMIMECPINFO rgelt, 01589 ULONG* pceltFetched) 01590 { 01591 ULONG i; 01592 EnumCodePage_impl *This = impl_from_IEnumCodePage( iface ); 01593 01594 TRACE("%p %u %p %p\n", This, celt, rgelt, pceltFetched); 01595 01596 if (!pceltFetched) return S_FALSE; 01597 *pceltFetched = 0; 01598 01599 if (!rgelt) return S_FALSE; 01600 01601 if (This->pos + celt > This->total) 01602 celt = This->total - This->pos; 01603 01604 if (!celt) return S_FALSE; 01605 01606 memcpy(rgelt, This->cpinfo + This->pos, celt * sizeof(MIMECPINFO)); 01607 *pceltFetched = celt; 01608 This->pos += celt; 01609 01610 for (i = 0; i < celt; i++) 01611 { 01612 TRACE("#%u: %08x %u %u %s %s %s %s %s %s %d\n", 01613 i, rgelt[i].dwFlags, rgelt[i].uiCodePage, 01614 rgelt[i].uiFamilyCodePage, 01615 wine_dbgstr_w(rgelt[i].wszDescription), 01616 wine_dbgstr_w(rgelt[i].wszWebCharset), 01617 wine_dbgstr_w(rgelt[i].wszHeaderCharset), 01618 wine_dbgstr_w(rgelt[i].wszBodyCharset), 01619 wine_dbgstr_w(rgelt[i].wszFixedWidthFont), 01620 wine_dbgstr_w(rgelt[i].wszProportionalFont), 01621 rgelt[i].bGDICharset); 01622 } 01623 return S_OK; 01624 } 01625 01626 static HRESULT WINAPI fnIEnumCodePage_Reset( 01627 IEnumCodePage* iface) 01628 { 01629 EnumCodePage_impl *This = impl_from_IEnumCodePage( iface ); 01630 01631 TRACE("%p\n", This); 01632 01633 This->pos = 0; 01634 return S_OK; 01635 } 01636 01637 static HRESULT WINAPI fnIEnumCodePage_Skip( 01638 IEnumCodePage* iface, 01639 ULONG celt) 01640 { 01641 EnumCodePage_impl *This = impl_from_IEnumCodePage( iface ); 01642 01643 TRACE("%p %u\n", This, celt); 01644 01645 if (celt >= This->total) return S_FALSE; 01646 01647 This->pos += celt; 01648 return S_OK; 01649 } 01650 01651 static const IEnumCodePageVtbl IEnumCodePage_vtbl = 01652 { 01653 fnIEnumCodePage_QueryInterface, 01654 fnIEnumCodePage_AddRef, 01655 fnIEnumCodePage_Release, 01656 fnIEnumCodePage_Clone, 01657 fnIEnumCodePage_Next, 01658 fnIEnumCodePage_Reset, 01659 fnIEnumCodePage_Skip 01660 }; 01661 01662 static HRESULT EnumCodePage_create( MLang_impl* mlang, DWORD grfFlags, 01663 LANGID LangId, IEnumCodePage** ppEnumCodePage ) 01664 { 01665 EnumCodePage_impl *ecp; 01666 MIMECPINFO *cpinfo; 01667 UINT i, n; 01668 01669 TRACE("%p, %08x, %04x, %p\n", mlang, grfFlags, LangId, ppEnumCodePage); 01670 01671 if (!grfFlags) /* enumerate internal data base of encodings */ 01672 grfFlags = MIMECONTF_MIME_LATEST; 01673 01674 ecp = HeapAlloc( GetProcessHeap(), 0, sizeof (EnumCodePage_impl) ); 01675 ecp->IEnumCodePage_iface.lpVtbl = &IEnumCodePage_vtbl; 01676 ecp->ref = 1; 01677 ecp->pos = 0; 01678 ecp->total = 0; 01679 for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 01680 { 01681 for (n = 0; n < mlang_data[i].number_of_cp; n++) 01682 { 01683 if (mlang_data[i].mime_cp_info[n].flags & grfFlags) 01684 ecp->total++; 01685 } 01686 } 01687 01688 ecp->cpinfo = HeapAlloc(GetProcessHeap(), 0, 01689 sizeof(MIMECPINFO) * ecp->total); 01690 cpinfo = ecp->cpinfo; 01691 01692 for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 01693 { 01694 for (n = 0; n < mlang_data[i].number_of_cp; n++) 01695 { 01696 if (mlang_data[i].mime_cp_info[n].flags & grfFlags) 01697 fill_cp_info(&mlang_data[i], n, cpinfo++); 01698 } 01699 } 01700 01701 TRACE("enumerated %d codepages with flags %08x\n", ecp->total, grfFlags); 01702 01703 *ppEnumCodePage = &ecp->IEnumCodePage_iface; 01704 01705 return S_OK; 01706 } 01707 01708 /******************************************************************************/ 01709 01710 typedef struct tagEnumScript_impl 01711 { 01712 IEnumScript IEnumScript_iface; 01713 LONG ref; 01714 SCRIPTINFO *script_info; 01715 DWORD total, pos; 01716 } EnumScript_impl; 01717 01718 static inline EnumScript_impl *impl_from_IEnumScript( IEnumScript *iface ) 01719 { 01720 return CONTAINING_RECORD( iface, EnumScript_impl, IEnumScript_iface ); 01721 } 01722 01723 static HRESULT WINAPI fnIEnumScript_QueryInterface( 01724 IEnumScript* iface, 01725 REFIID riid, 01726 void** ppvObject) 01727 { 01728 EnumScript_impl *This = impl_from_IEnumScript( iface ); 01729 01730 TRACE("%p -> %s\n", This, debugstr_guid(riid) ); 01731 01732 if (IsEqualGUID(riid, &IID_IUnknown) 01733 || IsEqualGUID(riid, &IID_IEnumScript)) 01734 { 01735 IEnumScript_AddRef(iface); 01736 TRACE("Returning IID_IEnumScript %p ref = %d\n", This, This->ref); 01737 *ppvObject = &This->IEnumScript_iface; 01738 return S_OK; 01739 } 01740 01741 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); 01742 return E_NOINTERFACE; 01743 } 01744 01745 static ULONG WINAPI fnIEnumScript_AddRef( 01746 IEnumScript* iface) 01747 { 01748 EnumScript_impl *This = impl_from_IEnumScript( iface ); 01749 return InterlockedIncrement(&This->ref); 01750 } 01751 01752 static ULONG WINAPI fnIEnumScript_Release( 01753 IEnumScript* iface) 01754 { 01755 EnumScript_impl *This = impl_from_IEnumScript( iface ); 01756 ULONG ref = InterlockedDecrement(&This->ref); 01757 01758 TRACE("%p ref = %d\n", This, ref); 01759 if (ref == 0) 01760 { 01761 TRACE("Destroying %p\n", This); 01762 HeapFree(GetProcessHeap(), 0, This->script_info); 01763 HeapFree(GetProcessHeap(), 0, This); 01764 } 01765 01766 return ref; 01767 } 01768 01769 static HRESULT WINAPI fnIEnumScript_Clone( 01770 IEnumScript* iface, 01771 IEnumScript** ppEnum) 01772 { 01773 EnumScript_impl *This = impl_from_IEnumScript( iface ); 01774 FIXME("%p %p: stub!\n", This, ppEnum); 01775 return E_NOTIMPL; 01776 } 01777 01778 static HRESULT WINAPI fnIEnumScript_Next( 01779 IEnumScript* iface, 01780 ULONG celt, 01781 PSCRIPTINFO rgelt, 01782 ULONG* pceltFetched) 01783 { 01784 EnumScript_impl *This = impl_from_IEnumScript( iface ); 01785 01786 TRACE("%p %u %p %p\n", This, celt, rgelt, pceltFetched); 01787 01788 if (!pceltFetched || !rgelt) return E_FAIL; 01789 01790 *pceltFetched = 0; 01791 01792 if (This->pos + celt > This->total) 01793 celt = This->total - This->pos; 01794 01795 if (!celt) return S_FALSE; 01796 01797 memcpy(rgelt, This->script_info + This->pos, celt * sizeof(SCRIPTINFO)); 01798 *pceltFetched = celt; 01799 This->pos += celt; 01800 01801 return S_OK; 01802 } 01803 01804 static HRESULT WINAPI fnIEnumScript_Reset( 01805 IEnumScript* iface) 01806 { 01807 EnumScript_impl *This = impl_from_IEnumScript( iface ); 01808 01809 TRACE("%p\n", This); 01810 01811 This->pos = 0; 01812 return S_OK; 01813 } 01814 01815 static HRESULT WINAPI fnIEnumScript_Skip( 01816 IEnumScript* iface, 01817 ULONG celt) 01818 { 01819 EnumScript_impl *This = impl_from_IEnumScript( iface ); 01820 01821 TRACE("%p %u\n", This, celt); 01822 01823 if (celt >= This->total) return S_FALSE; 01824 01825 This->pos += celt; 01826 return S_OK; 01827 } 01828 01829 static const IEnumScriptVtbl IEnumScript_vtbl = 01830 { 01831 fnIEnumScript_QueryInterface, 01832 fnIEnumScript_AddRef, 01833 fnIEnumScript_Release, 01834 fnIEnumScript_Clone, 01835 fnIEnumScript_Next, 01836 fnIEnumScript_Reset, 01837 fnIEnumScript_Skip 01838 }; 01839 01840 static HRESULT EnumScript_create( MLang_impl* mlang, DWORD dwFlags, 01841 LANGID LangId, IEnumScript** ppEnumScript ) 01842 { 01843 EnumScript_impl *es; 01844 UINT i; 01845 01846 TRACE("%p, %08x, %04x, %p: stub!\n", mlang, dwFlags, LangId, ppEnumScript); 01847 01848 if (!dwFlags) /* enumerate all available scripts */ 01849 dwFlags = SCRIPTCONTF_SCRIPT_USER | SCRIPTCONTF_SCRIPT_HIDE | SCRIPTCONTF_SCRIPT_SYSTEM; 01850 01851 es = HeapAlloc( GetProcessHeap(), 0, sizeof (EnumScript_impl) ); 01852 es->IEnumScript_iface.lpVtbl = &IEnumScript_vtbl; 01853 es->ref = 1; 01854 es->pos = 0; 01855 /* do not enumerate unicode flavours */ 01856 es->total = sizeof(mlang_data)/sizeof(mlang_data[0]) - 1; 01857 es->script_info = HeapAlloc(GetProcessHeap(), 0, sizeof(SCRIPTINFO) * es->total); 01858 01859 for (i = 0; i < es->total; i++) 01860 { 01861 es->script_info[i].ScriptId = i; 01862 es->script_info[i].uiCodePage = mlang_data[i].family_codepage; 01863 MultiByteToWideChar(CP_ACP, 0, mlang_data[i].description, -1, 01864 es->script_info[i].wszDescription, MAX_SCRIPT_NAME); 01865 MultiByteToWideChar(CP_ACP, 0, mlang_data[i].fixed_font, -1, 01866 es->script_info[i].wszFixedWidthFont, MAX_MIMEFACE_NAME); 01867 MultiByteToWideChar(CP_ACP, 0, mlang_data[i].proportional_font, -1, 01868 es->script_info[i].wszProportionalFont, MAX_MIMEFACE_NAME); 01869 } 01870 01871 TRACE("enumerated %d scripts with flags %08x\n", es->total, dwFlags); 01872 01873 *ppEnumScript = &es->IEnumScript_iface; 01874 01875 return S_OK; 01876 } 01877 01878 /******************************************************************************/ 01879 01880 static inline MLang_impl *impl_from_IMLangFontLink( IMLangFontLink *iface ) 01881 { 01882 return CONTAINING_RECORD( iface, MLang_impl, IMLangFontLink_iface ); 01883 } 01884 01885 static HRESULT WINAPI fnIMLangFontLink_QueryInterface( 01886 IMLangFontLink* iface, 01887 REFIID riid, 01888 void** ppvObject) 01889 { 01890 MLang_impl *This = impl_from_IMLangFontLink( iface ); 01891 return MLang_QueryInterface( This, riid, ppvObject ); 01892 } 01893 01894 static ULONG WINAPI fnIMLangFontLink_AddRef( 01895 IMLangFontLink* iface) 01896 { 01897 MLang_impl *This = impl_from_IMLangFontLink( iface ); 01898 return MLang_AddRef( This ); 01899 } 01900 01901 static ULONG WINAPI fnIMLangFontLink_Release( 01902 IMLangFontLink* iface) 01903 { 01904 MLang_impl *This = impl_from_IMLangFontLink( iface ); 01905 return MLang_Release( This ); 01906 } 01907 01908 static HRESULT WINAPI fnIMLangFontLink_GetCharCodePages( 01909 IMLangFontLink* iface, 01910 WCHAR chSrc, 01911 DWORD* pdwCodePages) 01912 { 01913 int i; 01914 CHAR buf; 01915 BOOL used_dc; 01916 DWORD codePages; 01917 01918 *pdwCodePages = 0; 01919 01920 for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 01921 { 01922 WideCharToMultiByte(mlang_data[i].family_codepage, WC_NO_BEST_FIT_CHARS, 01923 &chSrc, 1, &buf, 1, NULL, &used_dc); 01924 01925 /* If default char is not used, current codepage include the given symbol */ 01926 if (!used_dc) 01927 { 01928 IMLangFontLink_CodePageToCodePages(iface, 01929 mlang_data[i].family_codepage, &codePages); 01930 *pdwCodePages |= codePages; 01931 } 01932 } 01933 return S_OK; 01934 } 01935 01936 static HRESULT WINAPI fnIMLangFontLink_GetStrCodePages( 01937 IMLangFontLink* iface, 01938 const WCHAR* pszSrc, 01939 LONG cchSrc, 01940 DWORD dwPriorityCodePages, 01941 DWORD* pdwCodePages, 01942 LONG* pcchCodePages) 01943 { 01944 LONG i; 01945 DWORD cps = 0; 01946 01947 TRACE("(%p)->%s %d %x %p %p\n", iface, debugstr_wn(pszSrc, cchSrc), cchSrc, dwPriorityCodePages, pdwCodePages, pcchCodePages); 01948 01949 if (pdwCodePages) *pdwCodePages = 0; 01950 if (pcchCodePages) *pcchCodePages = 0; 01951 01952 if (!pszSrc || !cchSrc || cchSrc < 0) 01953 return E_INVALIDARG; 01954 01955 for (i = 0; i < cchSrc; i++) 01956 { 01957 DWORD cp; 01958 HRESULT ret; 01959 01960 ret = fnIMLangFontLink_GetCharCodePages(iface, pszSrc[i], &cp); 01961 if (ret != S_OK) return E_FAIL; 01962 01963 if (!cps) cps = cp; 01964 else cps &= cp; 01965 01966 /* FIXME: not tested */ 01967 if (dwPriorityCodePages & cps) break; 01968 } 01969 01970 if (pdwCodePages) *pdwCodePages = cps; 01971 if (pcchCodePages) *pcchCodePages = min( i + 1, cchSrc ); 01972 return S_OK; 01973 } 01974 01975 static HRESULT WINAPI fnIMLangFontLink_CodePageToCodePages( 01976 IMLangFontLink* iface, 01977 UINT uCodePage, 01978 DWORD* pdwCodePages) 01979 { 01980 MLang_impl *This = impl_from_IMLangFontLink( iface ); 01981 CHARSETINFO cs; 01982 BOOL rc; 01983 01984 TRACE("(%p) Seeking %u\n",This, uCodePage); 01985 01986 rc = TranslateCharsetInfo((DWORD*)(DWORD_PTR)uCodePage, &cs, TCI_SRCCODEPAGE); 01987 01988 if (rc) 01989 { 01990 *pdwCodePages = cs.fs.fsCsb[0]; 01991 TRACE("resulting CodePages 0x%x\n",*pdwCodePages); 01992 return S_OK; 01993 } 01994 01995 TRACE("CodePage Not Found\n"); 01996 *pdwCodePages = 0; 01997 return E_FAIL; 01998 } 01999 02000 static HRESULT WINAPI fnIMLangFontLink_CodePagesToCodePage( 02001 IMLangFontLink* iface, 02002 DWORD dwCodePages, 02003 UINT uDefaultCodePage, 02004 UINT* puCodePage) 02005 { 02006 MLang_impl *This = impl_from_IMLangFontLink( iface ); 02007 DWORD mask = 0x00000000; 02008 UINT i; 02009 CHARSETINFO cs; 02010 BOOL rc; 02011 02012 TRACE("(%p) scanning 0x%x default page %u\n",This, dwCodePages, 02013 uDefaultCodePage); 02014 02015 *puCodePage = 0x00000000; 02016 02017 rc = TranslateCharsetInfo((DWORD*)(DWORD_PTR)uDefaultCodePage, &cs, 02018 TCI_SRCCODEPAGE); 02019 02020 if (rc && (dwCodePages & cs.fs.fsCsb[0])) 02021 { 02022 TRACE("Found Default Codepage\n"); 02023 *puCodePage = uDefaultCodePage; 02024 return S_OK; 02025 } 02026 02027 02028 for (i = 0; i < 32; i++) 02029 { 02030 02031 mask = 1 << i; 02032 if (dwCodePages & mask) 02033 { 02034 DWORD Csb[2]; 02035 Csb[0] = mask; 02036 Csb[1] = 0x0; 02037 rc = TranslateCharsetInfo(Csb, &cs, TCI_SRCFONTSIG); 02038 if (!rc) 02039 continue; 02040 02041 TRACE("Falling back to least significant found CodePage %u\n", 02042 cs.ciACP); 02043 *puCodePage = cs.ciACP; 02044 return S_OK; 02045 } 02046 } 02047 02048 TRACE("no codepage found\n"); 02049 return E_FAIL; 02050 } 02051 02052 static HRESULT WINAPI fnIMLangFontLink_GetFontCodePages( 02053 IMLangFontLink* iface, 02054 HDC hDC, 02055 HFONT hFont, 02056 DWORD* pdwCodePages) 02057 { 02058 HFONT old_font; 02059 FONTSIGNATURE fontsig; 02060 MLang_impl *This = impl_from_IMLangFontLink( iface ); 02061 02062 TRACE("(%p)\n",This); 02063 02064 old_font = SelectObject(hDC,hFont); 02065 GetTextCharsetInfo(hDC,&fontsig, 0); 02066 SelectObject(hDC,old_font); 02067 02068 *pdwCodePages = fontsig.fsCsb[0]; 02069 TRACE("CodePages is 0x%x\n",fontsig.fsCsb[0]); 02070 02071 return S_OK; 02072 } 02073 02074 static HRESULT WINAPI fnIMLangFontLink_MapFont( 02075 IMLangFontLink* iface, 02076 HDC hDC, 02077 DWORD dwCodePages, 02078 HFONT hSrcFont, 02079 HFONT* phDestFont) 02080 { 02081 FIXME("\n"); 02082 return E_NOTIMPL; 02083 } 02084 02085 static HRESULT WINAPI fnIMLangFontLink_ReleaseFont( 02086 IMLangFontLink* iface, 02087 HFONT hFont) 02088 { 02089 FIXME("\n"); 02090 return E_NOTIMPL; 02091 } 02092 02093 static HRESULT WINAPI fnIMLangFontLink_ResetFontMapping( 02094 IMLangFontLink* iface) 02095 { 02096 FIXME("\n"); 02097 return E_NOTIMPL; 02098 } 02099 02100 02101 static const IMLangFontLinkVtbl IMLangFontLink_vtbl = 02102 { 02103 fnIMLangFontLink_QueryInterface, 02104 fnIMLangFontLink_AddRef, 02105 fnIMLangFontLink_Release, 02106 fnIMLangFontLink_GetCharCodePages, 02107 fnIMLangFontLink_GetStrCodePages, 02108 fnIMLangFontLink_CodePageToCodePages, 02109 fnIMLangFontLink_CodePagesToCodePage, 02110 fnIMLangFontLink_GetFontCodePages, 02111 fnIMLangFontLink_MapFont, 02112 fnIMLangFontLink_ReleaseFont, 02113 fnIMLangFontLink_ResetFontMapping, 02114 }; 02115 02116 /******************************************************************************/ 02117 02118 static inline MLang_impl *impl_from_IMultiLanguage( IMultiLanguage *iface ) 02119 { 02120 return CONTAINING_RECORD( iface, MLang_impl, IMultiLanguage_iface ); 02121 } 02122 02123 static HRESULT WINAPI fnIMultiLanguage_QueryInterface( 02124 IMultiLanguage* iface, 02125 REFIID riid, 02126 void** ppvObject) 02127 { 02128 MLang_impl *This = impl_from_IMultiLanguage( iface ); 02129 return MLang_QueryInterface( This, riid, ppvObject ); 02130 } 02131 02132 static ULONG WINAPI fnIMultiLanguage_AddRef( IMultiLanguage* iface ) 02133 { 02134 MLang_impl *This = impl_from_IMultiLanguage( iface ); 02135 return IMLangFontLink_AddRef( &This->IMLangFontLink_iface ); 02136 } 02137 02138 static ULONG WINAPI fnIMultiLanguage_Release( IMultiLanguage* iface ) 02139 { 02140 MLang_impl *This = impl_from_IMultiLanguage( iface ); 02141 return IMLangFontLink_Release( &This->IMLangFontLink_iface ); 02142 } 02143 02144 static HRESULT WINAPI fnIMultiLanguage_GetNumberOfCodePageInfo( 02145 IMultiLanguage* iface, 02146 UINT* pcCodePage) 02147 { 02148 MLang_impl *This = impl_from_IMultiLanguage( iface ); 02149 02150 TRACE("(%p, %p)\n", This, pcCodePage); 02151 02152 if (!pcCodePage) return E_INVALIDARG; 02153 02154 *pcCodePage = This->total_cp; 02155 return S_OK; 02156 } 02157 02158 static HRESULT WINAPI fnIMultiLanguage_GetCodePageInfo( 02159 IMultiLanguage* iface, 02160 UINT uiCodePage, 02161 PMIMECPINFO pCodePageInfo) 02162 { 02163 UINT i, n; 02164 MLang_impl *This = impl_from_IMultiLanguage( iface ); 02165 02166 TRACE("%p, %u, %p\n", This, uiCodePage, pCodePageInfo); 02167 02168 for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 02169 { 02170 for (n = 0; n < mlang_data[i].number_of_cp; n++) 02171 { 02172 if (mlang_data[i].mime_cp_info[n].cp == uiCodePage) 02173 { 02174 fill_cp_info(&mlang_data[i], n, pCodePageInfo); 02175 return S_OK; 02176 } 02177 } 02178 } 02179 02180 return S_FALSE; 02181 } 02182 02183 static HRESULT WINAPI fnIMultiLanguage_GetFamilyCodePage( 02184 IMultiLanguage* iface, 02185 UINT uiCodePage, 02186 UINT* puiFamilyCodePage) 02187 { 02188 return GetFamilyCodePage(uiCodePage, puiFamilyCodePage); 02189 } 02190 02191 static HRESULT WINAPI fnIMultiLanguage_EnumCodePages( 02192 IMultiLanguage* iface, 02193 DWORD grfFlags, 02194 IEnumCodePage** ppEnumCodePage) 02195 { 02196 MLang_impl *This = impl_from_IMultiLanguage( iface ); 02197 02198 TRACE("%p %08x %p\n", This, grfFlags, ppEnumCodePage); 02199 02200 return EnumCodePage_create( This, grfFlags, 0, ppEnumCodePage ); 02201 } 02202 02203 static HRESULT WINAPI fnIMultiLanguage_GetCharsetInfo( 02204 IMultiLanguage* iface, 02205 BSTR Charset, 02206 PMIMECSETINFO pCharsetInfo) 02207 { 02208 MLang_impl *This = impl_from_IMultiLanguage( iface ); 02209 return IMultiLanguage3_GetCharsetInfo( &This->IMultiLanguage3_iface, Charset, pCharsetInfo ); 02210 } 02211 02212 static HRESULT WINAPI fnIMultiLanguage_IsConvertible( 02213 IMultiLanguage* iface, 02214 DWORD dwSrcEncoding, 02215 DWORD dwDstEncoding) 02216 { 02217 return IsConvertINetStringAvailable(dwSrcEncoding, dwDstEncoding); 02218 } 02219 02220 static HRESULT WINAPI fnIMultiLanguage_ConvertString( 02221 IMultiLanguage* iface, 02222 DWORD* pdwMode, 02223 DWORD dwSrcEncoding, 02224 DWORD dwDstEncoding, 02225 BYTE* pSrcStr, 02226 UINT* pcSrcSize, 02227 BYTE* pDstStr, 02228 UINT* pcDstSize) 02229 { 02230 return ConvertINetString(pdwMode, dwSrcEncoding, dwDstEncoding, 02231 (LPCSTR)pSrcStr, (LPINT)pcSrcSize, (LPSTR)pDstStr, (LPINT)pcDstSize); 02232 } 02233 02234 static HRESULT WINAPI fnIMultiLanguage_ConvertStringToUnicode( 02235 IMultiLanguage* iface, 02236 DWORD* pdwMode, 02237 DWORD dwEncoding, 02238 CHAR* pSrcStr, 02239 UINT* pcSrcSize, 02240 WCHAR* pDstStr, 02241 UINT* pcDstSize) 02242 { 02243 return ConvertINetMultiByteToUnicode(pdwMode, dwEncoding, 02244 (LPCSTR)pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize); 02245 } 02246 02247 static HRESULT WINAPI fnIMultiLanguage_ConvertStringFromUnicode( 02248 IMultiLanguage* iface, 02249 DWORD* pdwMode, 02250 DWORD dwEncoding, 02251 WCHAR* pSrcStr, 02252 UINT* pcSrcSize, 02253 CHAR* pDstStr, 02254 UINT* pcDstSize) 02255 { 02256 return ConvertINetUnicodeToMultiByte(pdwMode, dwEncoding, 02257 pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize); 02258 } 02259 02260 static HRESULT WINAPI fnIMultiLanguage_ConvertStringReset( 02261 IMultiLanguage* iface) 02262 { 02263 FIXME("\n"); 02264 return E_NOTIMPL; 02265 } 02266 02267 static HRESULT WINAPI fnIMultiLanguage_GetRfc1766FromLcid( 02268 IMultiLanguage* iface, 02269 LCID lcid, 02270 BSTR* pbstrRfc1766) 02271 { 02272 WCHAR buf[MAX_RFC1766_NAME]; 02273 02274 TRACE("%p %04x %p\n", iface, lcid, pbstrRfc1766); 02275 if (!pbstrRfc1766) 02276 return E_INVALIDARG; 02277 02278 if (!lcid_to_rfc1766W( lcid, buf, MAX_RFC1766_NAME )) 02279 { 02280 *pbstrRfc1766 = SysAllocString( buf ); 02281 return S_OK; 02282 } 02283 return E_FAIL; 02284 } 02285 02286 static HRESULT WINAPI fnIMultiLanguage_GetLcidFromRfc1766( 02287 IMultiLanguage* iface, 02288 LCID* pLocale, 02289 BSTR bstrRfc1766) 02290 { 02291 HRESULT hr; 02292 IEnumRfc1766 *rfc1766; 02293 02294 TRACE("%p %p %s\n", iface, pLocale, debugstr_w(bstrRfc1766)); 02295 02296 if (!pLocale || !bstrRfc1766) 02297 return E_INVALIDARG; 02298 02299 hr = IMultiLanguage_EnumRfc1766(iface, &rfc1766); 02300 if (FAILED(hr)) 02301 return hr; 02302 02303 hr = lcid_from_rfc1766(rfc1766, pLocale, bstrRfc1766); 02304 02305 IEnumRfc1766_Release(rfc1766); 02306 return hr; 02307 } 02308 02309 /******************************************************************************/ 02310 02311 typedef struct tagEnumRfc1766_impl 02312 { 02313 IEnumRfc1766 IEnumRfc1766_iface; 02314 LONG ref; 02315 RFC1766INFO *info; 02316 DWORD total, pos; 02317 } EnumRfc1766_impl; 02318 02319 static inline EnumRfc1766_impl *impl_from_IEnumRfc1766( IEnumRfc1766 *iface ) 02320 { 02321 return CONTAINING_RECORD( iface, EnumRfc1766_impl, IEnumRfc1766_iface ); 02322 } 02323 02324 static HRESULT WINAPI fnIEnumRfc1766_QueryInterface( 02325 IEnumRfc1766 *iface, 02326 REFIID riid, 02327 void** ppvObject) 02328 { 02329 EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface ); 02330 02331 TRACE("%p -> %s\n", This, debugstr_guid(riid) ); 02332 02333 if (IsEqualGUID(riid, &IID_IUnknown) 02334 || IsEqualGUID(riid, &IID_IEnumRfc1766)) 02335 { 02336 IEnumRfc1766_AddRef(iface); 02337 TRACE("Returning IID_IEnumRfc1766 %p ref = %d\n", This, This->ref); 02338 *ppvObject = &This->IEnumRfc1766_iface; 02339 return S_OK; 02340 } 02341 02342 WARN("(%p) -> (%s,%p), not found\n",This,debugstr_guid(riid),ppvObject); 02343 return E_NOINTERFACE; 02344 } 02345 02346 static ULONG WINAPI fnIEnumRfc1766_AddRef( 02347 IEnumRfc1766 *iface) 02348 { 02349 EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface ); 02350 return InterlockedIncrement(&This->ref); 02351 } 02352 02353 static ULONG WINAPI fnIEnumRfc1766_Release( 02354 IEnumRfc1766 *iface) 02355 { 02356 EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface ); 02357 ULONG ref = InterlockedDecrement(&This->ref); 02358 02359 TRACE("%p ref = %d\n", This, ref); 02360 if (ref == 0) 02361 { 02362 TRACE("Destroying %p\n", This); 02363 HeapFree(GetProcessHeap(), 0, This->info); 02364 HeapFree(GetProcessHeap(), 0, This); 02365 } 02366 return ref; 02367 } 02368 02369 static HRESULT WINAPI fnIEnumRfc1766_Clone( 02370 IEnumRfc1766 *iface, 02371 IEnumRfc1766 **ppEnum) 02372 { 02373 EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface ); 02374 02375 FIXME("%p %p\n", This, ppEnum); 02376 return E_NOTIMPL; 02377 } 02378 02379 static HRESULT WINAPI fnIEnumRfc1766_Next( 02380 IEnumRfc1766 *iface, 02381 ULONG celt, 02382 PRFC1766INFO rgelt, 02383 ULONG *pceltFetched) 02384 { 02385 ULONG i; 02386 EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface ); 02387 02388 TRACE("%p %u %p %p\n", This, celt, rgelt, pceltFetched); 02389 02390 if (!pceltFetched) return S_FALSE; 02391 *pceltFetched = 0; 02392 02393 if (!rgelt) return S_FALSE; 02394 02395 if (This->pos + celt > This->total) 02396 celt = This->total - This->pos; 02397 02398 if (!celt) return S_FALSE; 02399 02400 memcpy(rgelt, This->info + This->pos, celt * sizeof(RFC1766INFO)); 02401 *pceltFetched = celt; 02402 This->pos += celt; 02403 02404 for (i = 0; i < celt; i++) 02405 { 02406 TRACE("#%u: %08x %s %s\n", 02407 i, rgelt[i].lcid, 02408 wine_dbgstr_w(rgelt[i].wszRfc1766), 02409 wine_dbgstr_w(rgelt[i].wszLocaleName)); 02410 } 02411 return S_OK; 02412 } 02413 02414 static HRESULT WINAPI fnIEnumRfc1766_Reset( 02415 IEnumRfc1766 *iface) 02416 { 02417 EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface ); 02418 02419 TRACE("%p\n", This); 02420 02421 This->pos = 0; 02422 return S_OK; 02423 } 02424 02425 static HRESULT WINAPI fnIEnumRfc1766_Skip( 02426 IEnumRfc1766 *iface, 02427 ULONG celt) 02428 { 02429 EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface ); 02430 02431 TRACE("%p %u\n", This, celt); 02432 02433 if (celt >= This->total) return S_FALSE; 02434 02435 This->pos += celt; 02436 return S_OK; 02437 } 02438 02439 static const IEnumRfc1766Vtbl IEnumRfc1766_vtbl = 02440 { 02441 fnIEnumRfc1766_QueryInterface, 02442 fnIEnumRfc1766_AddRef, 02443 fnIEnumRfc1766_Release, 02444 fnIEnumRfc1766_Clone, 02445 fnIEnumRfc1766_Next, 02446 fnIEnumRfc1766_Reset, 02447 fnIEnumRfc1766_Skip 02448 }; 02449 02450 struct enum_locales_data 02451 { 02452 RFC1766INFO *info; 02453 DWORD total, allocated; 02454 }; 02455 02456 static BOOL CALLBACK enum_locales_proc(LPWSTR locale) 02457 { 02458 WCHAR *end; 02459 struct enum_locales_data *data = TlsGetValue(MLANG_tls_index); 02460 RFC1766INFO *info; 02461 02462 TRACE("%s\n", debugstr_w(locale)); 02463 02464 if (data->total >= data->allocated) 02465 { 02466 data->allocated += 32; 02467 data->info = HeapReAlloc(GetProcessHeap(), 0, data->info, data->allocated * sizeof(RFC1766INFO)); 02468 if (!data->info) return FALSE; 02469 } 02470 02471 info = &data->info[data->total]; 02472 02473 info->lcid = strtolW(locale, &end, 16); 02474 if (*end) /* invalid number */ 02475 return FALSE; 02476 02477 info->wszRfc1766[0] = 0; 02478 lcid_to_rfc1766W( info->lcid, info->wszRfc1766, MAX_RFC1766_NAME ); 02479 02480 info->wszLocaleName[0] = 0; 02481 GetLocaleInfoW(info->lcid, LOCALE_SLANGUAGE, info->wszLocaleName, MAX_LOCALE_NAME); 02482 TRACE("ISO639: %s SLANGUAGE: %s\n", wine_dbgstr_w(info->wszRfc1766), wine_dbgstr_w(info->wszLocaleName)); 02483 02484 data->total++; 02485 02486 return TRUE; 02487 } 02488 02489 static HRESULT EnumRfc1766_create(LANGID LangId, IEnumRfc1766 **ppEnum) 02490 { 02491 EnumRfc1766_impl *rfc; 02492 struct enum_locales_data data; 02493 02494 TRACE("%04x, %p\n", LangId, ppEnum); 02495 02496 rfc = HeapAlloc( GetProcessHeap(), 0, sizeof(EnumRfc1766_impl) ); 02497 rfc->IEnumRfc1766_iface.lpVtbl = &IEnumRfc1766_vtbl; 02498 rfc->ref = 1; 02499 rfc->pos = 0; 02500 rfc->total = 0; 02501 02502 data.total = 0; 02503 data.allocated = 160; 02504 data.info = HeapAlloc(GetProcessHeap(), 0, data.allocated * sizeof(RFC1766INFO)); 02505 if (!data.info) 02506 { 02507 HeapFree(GetProcessHeap(), 0, rfc); 02508 return E_OUTOFMEMORY; 02509 } 02510 02511 TlsSetValue(MLANG_tls_index, &data); 02512 EnumSystemLocalesW(enum_locales_proc, 0/*LOCALE_SUPPORTED*/); 02513 TlsSetValue(MLANG_tls_index, NULL); 02514 02515 TRACE("enumerated %d rfc1766 structures\n", data.total); 02516 02517 if (!data.total) 02518 { 02519 HeapFree(GetProcessHeap(), 0, data.info); 02520 HeapFree(GetProcessHeap(), 0, rfc); 02521 return E_FAIL; 02522 } 02523 02524 rfc->info = data.info; 02525 rfc->total = data.total; 02526 02527 *ppEnum = &rfc->IEnumRfc1766_iface; 02528 return S_OK; 02529 } 02530 02531 static HRESULT WINAPI fnIMultiLanguage_EnumRfc1766( 02532 IMultiLanguage *iface, 02533 IEnumRfc1766 **ppEnumRfc1766) 02534 { 02535 MLang_impl *This = impl_from_IMultiLanguage( iface ); 02536 02537 TRACE("%p %p\n", This, ppEnumRfc1766); 02538 02539 return EnumRfc1766_create(0, ppEnumRfc1766); 02540 } 02541 02542 /******************************************************************************/ 02543 02544 static HRESULT WINAPI fnIMultiLanguage_GetRfc1766Info( 02545 IMultiLanguage* iface, 02546 LCID Locale, 02547 PRFC1766INFO pRfc1766Info) 02548 { 02549 LCTYPE type = LOCALE_SLANGUAGE; 02550 02551 TRACE("(%p, 0x%04x, %p)\n", iface, Locale, pRfc1766Info); 02552 02553 if (!pRfc1766Info) 02554 return E_INVALIDARG; 02555 02556 if ((PRIMARYLANGID(Locale) == LANG_ENGLISH) || 02557 (PRIMARYLANGID(Locale) == LANG_CHINESE) || 02558 (PRIMARYLANGID(Locale) == LANG_ARABIC)) { 02559 02560 if (!SUBLANGID(Locale)) 02561 type = LOCALE_SENGLANGUAGE; /* suppress country */ 02562 } 02563 else 02564 { 02565 if (!SUBLANGID(Locale)) { 02566 TRACE("SUBLANGID missing in 0x%04x\n", Locale); 02567 return E_FAIL; 02568 } 02569 } 02570 02571 pRfc1766Info->lcid = Locale; 02572 pRfc1766Info->wszRfc1766[0] = 0; 02573 pRfc1766Info->wszLocaleName[0] = 0; 02574 02575 if ((!lcid_to_rfc1766W(Locale, pRfc1766Info->wszRfc1766, MAX_RFC1766_NAME)) && 02576 (GetLocaleInfoW(Locale, type, pRfc1766Info->wszLocaleName, MAX_LOCALE_NAME) > 0)) 02577 return S_OK; 02578 02579 /* Locale not supported */ 02580 return E_INVALIDARG; 02581 } 02582 02583 static HRESULT WINAPI fnIMultiLanguage_CreateConvertCharset( 02584 IMultiLanguage* iface, 02585 UINT uiSrcCodePage, 02586 UINT uiDstCodePage, 02587 DWORD dwProperty, 02588 IMLangConvertCharset** ppMLangConvertCharset) 02589 { 02590 FIXME("\n"); 02591 return E_NOTIMPL; 02592 } 02593 02594 static const IMultiLanguageVtbl IMultiLanguage_vtbl = 02595 { 02596 fnIMultiLanguage_QueryInterface, 02597 fnIMultiLanguage_AddRef, 02598 fnIMultiLanguage_Release, 02599 fnIMultiLanguage_GetNumberOfCodePageInfo, 02600 fnIMultiLanguage_GetCodePageInfo, 02601 fnIMultiLanguage_GetFamilyCodePage, 02602 fnIMultiLanguage_EnumCodePages, 02603 fnIMultiLanguage_GetCharsetInfo, 02604 fnIMultiLanguage_IsConvertible, 02605 fnIMultiLanguage_ConvertString, 02606 fnIMultiLanguage_ConvertStringToUnicode, 02607 fnIMultiLanguage_ConvertStringFromUnicode, 02608 fnIMultiLanguage_ConvertStringReset, 02609 fnIMultiLanguage_GetRfc1766FromLcid, 02610 fnIMultiLanguage_GetLcidFromRfc1766, 02611 fnIMultiLanguage_EnumRfc1766, 02612 fnIMultiLanguage_GetRfc1766Info, 02613 fnIMultiLanguage_CreateConvertCharset, 02614 }; 02615 02616 02617 /******************************************************************************/ 02618 02619 static inline MLang_impl *impl_from_IMultiLanguage3( IMultiLanguage3 *iface ) 02620 { 02621 return CONTAINING_RECORD( iface, MLang_impl, IMultiLanguage3_iface ); 02622 } 02623 02624 static HRESULT WINAPI fnIMultiLanguage2_QueryInterface( 02625 IMultiLanguage3* iface, 02626 REFIID riid, 02627 void** ppvObject) 02628 { 02629 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 02630 return MLang_QueryInterface( This, riid, ppvObject ); 02631 } 02632 02633 static ULONG WINAPI fnIMultiLanguage2_AddRef( IMultiLanguage3* iface ) 02634 { 02635 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 02636 return MLang_AddRef( This ); 02637 } 02638 02639 static ULONG WINAPI fnIMultiLanguage2_Release( IMultiLanguage3* iface ) 02640 { 02641 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 02642 return MLang_Release( This ); 02643 } 02644 02645 static HRESULT WINAPI fnIMultiLanguage2_GetNumberOfCodePageInfo( 02646 IMultiLanguage3* iface, 02647 UINT* pcCodePage) 02648 { 02649 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 02650 02651 TRACE("%p, %p\n", This, pcCodePage); 02652 02653 if (!pcCodePage) return E_INVALIDARG; 02654 02655 *pcCodePage = This->total_cp; 02656 return S_OK; 02657 } 02658 02659 static void fill_cp_info(const struct mlang_data *ml_data, UINT index, MIMECPINFO *mime_cp_info) 02660 { 02661 CHARSETINFO csi; 02662 02663 if (TranslateCharsetInfo((DWORD*)(DWORD_PTR)ml_data->family_codepage, &csi, 02664 TCI_SRCCODEPAGE)) 02665 mime_cp_info->bGDICharset = csi.ciCharset; 02666 else 02667 mime_cp_info->bGDICharset = DEFAULT_CHARSET; 02668 02669 mime_cp_info->dwFlags = ml_data->mime_cp_info[index].flags; 02670 mime_cp_info->uiCodePage = ml_data->mime_cp_info[index].cp; 02671 mime_cp_info->uiFamilyCodePage = ml_data->family_codepage; 02672 MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].description, -1, 02673 mime_cp_info->wszDescription, sizeof(mime_cp_info->wszDescription)/sizeof(WCHAR)); 02674 MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].web_charset, -1, 02675 mime_cp_info->wszWebCharset, sizeof(mime_cp_info->wszWebCharset)/sizeof(WCHAR)); 02676 MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].header_charset, -1, 02677 mime_cp_info->wszHeaderCharset, sizeof(mime_cp_info->wszHeaderCharset)/sizeof(WCHAR)); 02678 MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].body_charset, -1, 02679 mime_cp_info->wszBodyCharset, sizeof(mime_cp_info->wszBodyCharset)/sizeof(WCHAR)); 02680 02681 MultiByteToWideChar(CP_ACP, 0, ml_data->fixed_font, -1, 02682 mime_cp_info->wszFixedWidthFont, sizeof(mime_cp_info->wszFixedWidthFont)/sizeof(WCHAR)); 02683 MultiByteToWideChar(CP_ACP, 0, ml_data->proportional_font, -1, 02684 mime_cp_info->wszProportionalFont, sizeof(mime_cp_info->wszProportionalFont)/sizeof(WCHAR)); 02685 02686 TRACE("%08x %u %u %s %s %s %s %s %s %d\n", 02687 mime_cp_info->dwFlags, mime_cp_info->uiCodePage, 02688 mime_cp_info->uiFamilyCodePage, 02689 wine_dbgstr_w(mime_cp_info->wszDescription), 02690 wine_dbgstr_w(mime_cp_info->wszWebCharset), 02691 wine_dbgstr_w(mime_cp_info->wszHeaderCharset), 02692 wine_dbgstr_w(mime_cp_info->wszBodyCharset), 02693 wine_dbgstr_w(mime_cp_info->wszFixedWidthFont), 02694 wine_dbgstr_w(mime_cp_info->wszProportionalFont), 02695 mime_cp_info->bGDICharset); 02696 } 02697 02698 static HRESULT WINAPI fnIMultiLanguage2_GetCodePageInfo( 02699 IMultiLanguage3* iface, 02700 UINT uiCodePage, 02701 LANGID LangId, 02702 PMIMECPINFO pCodePageInfo) 02703 { 02704 UINT i, n; 02705 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 02706 02707 TRACE("%p, %u, %04x, %p\n", This, uiCodePage, LangId, pCodePageInfo); 02708 02709 for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 02710 { 02711 for (n = 0; n < mlang_data[i].number_of_cp; n++) 02712 { 02713 if (mlang_data[i].mime_cp_info[n].cp == uiCodePage) 02714 { 02715 fill_cp_info(&mlang_data[i], n, pCodePageInfo); 02716 return S_OK; 02717 } 02718 } 02719 } 02720 02721 return S_FALSE; 02722 } 02723 02724 static HRESULT WINAPI fnIMultiLanguage2_GetFamilyCodePage( 02725 IMultiLanguage3* iface, 02726 UINT uiCodePage, 02727 UINT* puiFamilyCodePage) 02728 { 02729 return GetFamilyCodePage(uiCodePage, puiFamilyCodePage); 02730 } 02731 02732 static HRESULT WINAPI fnIMultiLanguage2_EnumCodePages( 02733 IMultiLanguage3* iface, 02734 DWORD grfFlags, 02735 LANGID LangId, 02736 IEnumCodePage** ppEnumCodePage) 02737 { 02738 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 02739 02740 TRACE("%p %08x %04x %p\n", This, grfFlags, LangId, ppEnumCodePage); 02741 02742 return EnumCodePage_create( This, grfFlags, LangId, ppEnumCodePage ); 02743 } 02744 02745 static HRESULT WINAPI fnIMultiLanguage2_GetCharsetInfo( 02746 IMultiLanguage3* iface, 02747 BSTR Charset, 02748 PMIMECSETINFO pCharsetInfo) 02749 { 02750 UINT i, n; 02751 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 02752 02753 TRACE("%p %s %p\n", This, debugstr_w(Charset), pCharsetInfo); 02754 02755 if (!pCharsetInfo) return E_FAIL; 02756 02757 for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 02758 { 02759 for (n = 0; n < mlang_data[i].number_of_cp; n++) 02760 { 02761 WCHAR csetW[MAX_MIMECSET_NAME]; 02762 02763 MultiByteToWideChar(CP_ACP, 0, mlang_data[i].mime_cp_info[n].web_charset, -1, csetW, MAX_MIMECSET_NAME); 02764 if (!lstrcmpiW(Charset, csetW)) 02765 { 02766 pCharsetInfo->uiCodePage = mlang_data[i].family_codepage; 02767 pCharsetInfo->uiInternetEncoding = mlang_data[i].mime_cp_info[n].cp; 02768 strcpyW(pCharsetInfo->wszCharset, csetW); 02769 return S_OK; 02770 } 02771 } 02772 } 02773 02774 /* FIXME: 02775 * Since we do not support charsets like iso-2022-jp and do not have 02776 * them in our database as a primary (web_charset) encoding this loop 02777 * does an attempt to 'approximate' charset name by header_charset. 02778 */ 02779 for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 02780 { 02781 for (n = 0; n < mlang_data[i].number_of_cp; n++) 02782 { 02783 WCHAR csetW[MAX_MIMECSET_NAME]; 02784 02785 MultiByteToWideChar(CP_ACP, 0, mlang_data[i].mime_cp_info[n].header_charset, -1, csetW, MAX_MIMECSET_NAME); 02786 if (!lstrcmpiW(Charset, csetW)) 02787 { 02788 pCharsetInfo->uiCodePage = mlang_data[i].family_codepage; 02789 pCharsetInfo->uiInternetEncoding = mlang_data[i].mime_cp_info[n].cp; 02790 strcpyW(pCharsetInfo->wszCharset, csetW); 02791 return S_OK; 02792 } 02793 } 02794 } 02795 02796 return E_FAIL; 02797 } 02798 02799 static HRESULT WINAPI fnIMultiLanguage2_IsConvertible( 02800 IMultiLanguage3* iface, 02801 DWORD dwSrcEncoding, 02802 DWORD dwDstEncoding) 02803 { 02804 return IsConvertINetStringAvailable(dwSrcEncoding, dwDstEncoding); 02805 } 02806 02807 static HRESULT WINAPI fnIMultiLanguage2_ConvertString( 02808 IMultiLanguage3* iface, 02809 DWORD* pdwMode, 02810 DWORD dwSrcEncoding, 02811 DWORD dwDstEncoding, 02812 BYTE* pSrcStr, 02813 UINT* pcSrcSize, 02814 BYTE* pDstStr, 02815 UINT* pcDstSize) 02816 { 02817 return ConvertINetString(pdwMode, dwSrcEncoding, dwDstEncoding, 02818 (LPCSTR)pSrcStr, (LPINT)pcSrcSize, (LPSTR)pDstStr, (LPINT)pcDstSize); 02819 } 02820 02821 static HRESULT WINAPI fnIMultiLanguage2_ConvertStringToUnicode( 02822 IMultiLanguage3* iface, 02823 DWORD* pdwMode, 02824 DWORD dwEncoding, 02825 CHAR* pSrcStr, 02826 UINT* pcSrcSize, 02827 WCHAR* pDstStr, 02828 UINT* pcDstSize) 02829 { 02830 return ConvertINetMultiByteToUnicode(pdwMode, dwEncoding, 02831 pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize); 02832 } 02833 02834 static HRESULT WINAPI fnIMultiLanguage2_ConvertStringFromUnicode( 02835 IMultiLanguage3* iface, 02836 DWORD* pdwMode, 02837 DWORD dwEncoding, 02838 WCHAR* pSrcStr, 02839 UINT* pcSrcSize, 02840 CHAR* pDstStr, 02841 UINT* pcDstSize) 02842 { 02843 return ConvertINetUnicodeToMultiByte(pdwMode, dwEncoding, 02844 pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize); 02845 } 02846 02847 static HRESULT WINAPI fnIMultiLanguage2_ConvertStringReset( 02848 IMultiLanguage3* iface) 02849 { 02850 FIXME("\n"); 02851 return E_NOTIMPL; 02852 } 02853 02854 static HRESULT WINAPI fnIMultiLanguage2_GetRfc1766FromLcid( 02855 IMultiLanguage3* iface, 02856 LCID lcid, 02857 BSTR* pbstrRfc1766) 02858 { 02859 WCHAR buf[MAX_RFC1766_NAME]; 02860 02861 TRACE("%p %04x %p\n", iface, lcid, pbstrRfc1766); 02862 if (!pbstrRfc1766) 02863 return E_INVALIDARG; 02864 02865 if (!lcid_to_rfc1766W( lcid, buf, MAX_RFC1766_NAME )) 02866 { 02867 *pbstrRfc1766 = SysAllocString( buf ); 02868 return S_OK; 02869 } 02870 return E_FAIL; 02871 } 02872 02873 static HRESULT WINAPI fnIMultiLanguage2_GetLcidFromRfc1766( 02874 IMultiLanguage3* iface, 02875 LCID* pLocale, 02876 BSTR bstrRfc1766) 02877 { 02878 HRESULT hr; 02879 IEnumRfc1766 *rfc1766; 02880 02881 TRACE("%p %p %s\n", iface, pLocale, debugstr_w(bstrRfc1766)); 02882 02883 if (!pLocale || !bstrRfc1766) 02884 return E_INVALIDARG; 02885 02886 hr = IMultiLanguage2_EnumRfc1766(iface, 0, &rfc1766); 02887 if (FAILED(hr)) 02888 return hr; 02889 02890 hr = lcid_from_rfc1766(rfc1766, pLocale, bstrRfc1766); 02891 02892 IEnumRfc1766_Release(rfc1766); 02893 return hr; 02894 } 02895 02896 static HRESULT WINAPI fnIMultiLanguage2_EnumRfc1766( 02897 IMultiLanguage3* iface, 02898 LANGID LangId, 02899 IEnumRfc1766** ppEnumRfc1766) 02900 { 02901 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 02902 02903 TRACE("%p %p\n", This, ppEnumRfc1766); 02904 02905 return EnumRfc1766_create(LangId, ppEnumRfc1766); 02906 } 02907 02908 static HRESULT WINAPI fnIMultiLanguage2_GetRfc1766Info( 02909 IMultiLanguage3* iface, 02910 LCID Locale, 02911 LANGID LangId, 02912 PRFC1766INFO pRfc1766Info) 02913 { 02914 static LANGID last_lang = -1; 02915 LCTYPE type = LOCALE_SLANGUAGE; 02916 02917 TRACE("(%p, 0x%04x, 0x%04x, %p)\n", iface, Locale, LangId, pRfc1766Info); 02918 02919 if (!pRfc1766Info) 02920 return E_INVALIDARG; 02921 02922 if ((PRIMARYLANGID(Locale) == LANG_ENGLISH) || 02923 (PRIMARYLANGID(Locale) == LANG_CHINESE) || 02924 (PRIMARYLANGID(Locale) == LANG_ARABIC)) { 02925 02926 if (!SUBLANGID(Locale)) 02927 type = LOCALE_SENGLANGUAGE; /* suppress country */ 02928 } 02929 else 02930 { 02931 if (!SUBLANGID(Locale)) { 02932 TRACE("SUBLANGID missing in 0x%04x\n", Locale); 02933 return E_FAIL; 02934 } 02935 } 02936 02937 pRfc1766Info->lcid = Locale; 02938 pRfc1766Info->wszRfc1766[0] = 0; 02939 pRfc1766Info->wszLocaleName[0] = 0; 02940 02941 if ((PRIMARYLANGID(LangId) != LANG_ENGLISH) && 02942 (last_lang != LangId)) { 02943 FIXME("Only English names supported (requested: 0x%04x)\n", LangId); 02944 last_lang = LangId; 02945 } 02946 02947 if ((!lcid_to_rfc1766W(Locale, pRfc1766Info->wszRfc1766, MAX_RFC1766_NAME)) && 02948 (GetLocaleInfoW(Locale, type, pRfc1766Info->wszLocaleName, MAX_LOCALE_NAME) > 0)) 02949 return S_OK; 02950 02951 /* Locale not supported */ 02952 return E_INVALIDARG; 02953 } 02954 02955 static HRESULT WINAPI fnIMultiLanguage2_CreateConvertCharset( 02956 IMultiLanguage3* iface, 02957 UINT uiSrcCodePage, 02958 UINT uiDstCodePage, 02959 DWORD dwProperty, 02960 IMLangConvertCharset** ppMLangConvertCharset) 02961 { 02962 FIXME("\n"); 02963 return E_NOTIMPL; 02964 } 02965 02966 static HRESULT WINAPI fnIMultiLanguage2_ConvertStringInIStream( 02967 IMultiLanguage3* iface, 02968 DWORD* pdwMode, 02969 DWORD dwFlag, 02970 WCHAR* lpFallBack, 02971 DWORD dwSrcEncoding, 02972 DWORD dwDstEncoding, 02973 IStream* pstmIn, 02974 IStream* pstmOut) 02975 { 02976 char *src, *dst = NULL; 02977 INT srclen, dstlen; 02978 STATSTG stat; 02979 HRESULT hr; 02980 02981 TRACE("%p %0x8 %s %u %u %p %p\n", 02982 pdwMode, dwFlag, debugstr_w(lpFallBack), dwSrcEncoding, dwDstEncoding, pstmIn, pstmOut); 02983 02984 FIXME("dwFlag and lpFallBack not handled\n"); 02985 02986 hr = IStream_Stat(pstmIn, &stat, STATFLAG_NONAME); 02987 if (FAILED(hr)) return hr; 02988 02989 if (stat.cbSize.QuadPart > MAXLONG) return E_INVALIDARG; 02990 if (!(src = HeapAlloc(GetProcessHeap(), 0, stat.cbSize.QuadPart))) return E_OUTOFMEMORY; 02991 02992 hr = IStream_Read(pstmIn, src, stat.cbSize.QuadPart, (ULONG *)&srclen); 02993 if (FAILED(hr)) goto exit; 02994 02995 hr = ConvertINetString(pdwMode, dwSrcEncoding, dwDstEncoding, src, &srclen, NULL, &dstlen); 02996 if (FAILED(hr)) goto exit; 02997 02998 if (!(dst = HeapAlloc(GetProcessHeap(), 0, dstlen))) 02999 { 03000 hr = E_OUTOFMEMORY; 03001 goto exit; 03002 } 03003 hr = ConvertINetString(pdwMode, dwSrcEncoding, dwDstEncoding, src, &srclen, dst, &dstlen); 03004 if (FAILED(hr)) goto exit; 03005 03006 hr = IStream_Write(pstmOut, dst, dstlen, NULL); 03007 03008 exit: 03009 HeapFree(GetProcessHeap(), 0, src); 03010 HeapFree(GetProcessHeap(), 0, dst); 03011 return hr; 03012 } 03013 03014 static HRESULT WINAPI fnIMultiLanguage2_ConvertStringToUnicodeEx( 03015 IMultiLanguage3* iface, 03016 DWORD* pdwMode, 03017 DWORD dwEncoding, 03018 CHAR* pSrcStr, 03019 UINT* pcSrcSize, 03020 WCHAR* pDstStr, 03021 UINT* pcDstSize, 03022 DWORD dwFlag, 03023 WCHAR* lpFallBack) 03024 { 03025 if (dwFlag || lpFallBack) 03026 FIXME("Ignoring dwFlag (0x%x/%d) and lpFallBack (%p)\n", 03027 dwFlag, dwFlag, lpFallBack); 03028 03029 return ConvertINetMultiByteToUnicode(pdwMode, dwEncoding, 03030 pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize); 03031 } 03032 03033 /***************************************************************************** 03034 * MultiLanguage2::ConvertStringToUnicodeEx 03035 * 03036 * Translates the multibyte string from the specified code page to Unicode. 03037 * 03038 * PARAMS 03039 * see ConvertStringToUnicode 03040 * dwFlag 03041 * lpFallBack if dwFlag contains MLCONVCHARF_USEDEFCHAR, lpFallBack string used 03042 * instead unconvertible characters. 03043 * 03044 * RETURNS 03045 * S_OK Success. 03046 * S_FALSE The conversion is not supported. 03047 * E_FAIL Some error has occurred. 03048 * 03049 * TODO: handle dwFlag and lpFallBack 03050 */ 03051 static HRESULT WINAPI fnIMultiLanguage2_ConvertStringFromUnicodeEx( 03052 IMultiLanguage3* This, 03053 DWORD* pdwMode, 03054 DWORD dwEncoding, 03055 WCHAR* pSrcStr, 03056 UINT* pcSrcSize, 03057 CHAR* pDstStr, 03058 UINT* pcDstSize, 03059 DWORD dwFlag, 03060 WCHAR* lpFallBack) 03061 { 03062 FIXME("\n"); 03063 return ConvertINetUnicodeToMultiByte(pdwMode, dwEncoding, 03064 pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize); 03065 } 03066 03067 static HRESULT WINAPI fnIMultiLanguage2_DetectCodepageInIStream( 03068 IMultiLanguage3* iface, 03069 DWORD dwFlag, 03070 DWORD dwPrefWinCodePage, 03071 IStream* pstmIn, 03072 DetectEncodingInfo* lpEncoding, 03073 INT* pnScores) 03074 { 03075 FIXME("\n"); 03076 return E_NOTIMPL; 03077 } 03078 03079 static HRESULT WINAPI fnIMultiLanguage2_DetectInputCodepage( 03080 IMultiLanguage3* iface, 03081 DWORD dwFlag, 03082 DWORD dwPrefWinCodePage, 03083 CHAR* pSrcStr, 03084 INT* pcSrcSize, 03085 DetectEncodingInfo* lpEncoding, 03086 INT* pnScores) 03087 { 03088 FIXME("\n"); 03089 return E_NOTIMPL; 03090 } 03091 03092 static HRESULT WINAPI fnIMultiLanguage2_ValidateCodePage( 03093 IMultiLanguage3* iface, 03094 UINT uiCodePage, 03095 HWND hwnd) 03096 { 03097 return IMultiLanguage2_ValidateCodePageEx(iface,uiCodePage,hwnd,0); 03098 } 03099 03100 static HRESULT WINAPI fnIMultiLanguage2_GetCodePageDescription( 03101 IMultiLanguage3* iface, 03102 UINT uiCodePage, 03103 LCID lcid, 03104 LPWSTR lpWideCharStr, 03105 int cchWideChar) 03106 { 03107 /* Find first instance */ 03108 unsigned int i,n; 03109 03110 TRACE ("%u, %04x, %p, %d\n", uiCodePage, lcid, lpWideCharStr, cchWideChar); 03111 for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 03112 { 03113 for (n = 0; n < mlang_data[i].number_of_cp; n++) 03114 { 03115 if (mlang_data[i].mime_cp_info[n].cp == uiCodePage) 03116 { 03117 MultiByteToWideChar(CP_ACP, 0, 03118 mlang_data[i].mime_cp_info[n].description, 03119 -1, lpWideCharStr, cchWideChar); 03120 return S_OK; 03121 } 03122 } 03123 } 03124 03125 return S_FALSE; 03126 } 03127 03128 static HRESULT WINAPI fnIMultiLanguage2_IsCodePageInstallable( 03129 IMultiLanguage3* iface, 03130 UINT uiCodePage) 03131 { 03132 TRACE("%u\n", uiCodePage); 03133 03134 /* FIXME: the installable set is usually larger than the set of valid codepages */ 03135 return IMultiLanguage2_ValidateCodePageEx(iface, uiCodePage, NULL, CPIOD_PEEK); 03136 } 03137 03138 static HRESULT WINAPI fnIMultiLanguage2_SetMimeDBSource( 03139 IMultiLanguage3* iface, 03140 MIMECONTF dwSource) 03141 { 03142 FIXME("0x%08x\n", dwSource); 03143 return S_OK; 03144 } 03145 03146 static HRESULT WINAPI fnIMultiLanguage2_GetNumberOfScripts( 03147 IMultiLanguage3* iface, 03148 UINT* pnScripts) 03149 { 03150 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 03151 03152 TRACE("%p %p\n", This, pnScripts); 03153 03154 if (!pnScripts) return S_FALSE; 03155 03156 *pnScripts = This->total_scripts; 03157 return S_OK; 03158 } 03159 03160 static HRESULT WINAPI fnIMultiLanguage2_EnumScripts( 03161 IMultiLanguage3* iface, 03162 DWORD dwFlags, 03163 LANGID LangId, 03164 IEnumScript** ppEnumScript) 03165 { 03166 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 03167 03168 TRACE("%p %08x %04x %p\n", This, dwFlags, LangId, ppEnumScript); 03169 03170 return EnumScript_create( This, dwFlags, LangId, ppEnumScript ); 03171 } 03172 03173 static HRESULT WINAPI fnIMultiLanguage2_ValidateCodePageEx( 03174 IMultiLanguage3* iface, 03175 UINT uiCodePage, 03176 HWND hwnd, 03177 DWORD dwfIODControl) 03178 { 03179 int i; 03180 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 03181 03182 TRACE("%p %u %p %08x\n", This, uiCodePage, hwnd, dwfIODControl); 03183 03184 /* quick check for kernel32 supported code pages */ 03185 if (IsValidCodePage(uiCodePage)) 03186 return S_OK; 03187 03188 /* check for mlang supported code pages */ 03189 for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 03190 { 03191 int n; 03192 for (n = 0; n < mlang_data[i].number_of_cp; n++) 03193 { 03194 if (mlang_data[i].mime_cp_info[n].cp == uiCodePage) 03195 return S_OK; 03196 } 03197 } 03198 03199 if (dwfIODControl != CPIOD_PEEK) 03200 FIXME("Request to install codepage language pack not handled\n"); 03201 03202 return S_FALSE; 03203 } 03204 03205 static HRESULT WINAPI fnIMultiLanguage3_DetectOutboundCodePage( 03206 IMultiLanguage3 *iface, 03207 DWORD dwFlags, 03208 LPCWSTR lpWideCharStr, 03209 UINT cchWideChar, 03210 UINT *puiPreferredCodePages, 03211 UINT nPreferredCodePages, 03212 UINT *puiDetectedCodePages, 03213 UINT *pnDetectedCodePages, 03214 WCHAR *lpSpecialChar) 03215 { 03216 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 03217 03218 FIXME("(%p)->(%08x %s %u %p %u %p %p %p)\n", This, dwFlags, debugstr_w(lpWideCharStr), 03219 cchWideChar, puiPreferredCodePages, nPreferredCodePages, puiDetectedCodePages, 03220 pnDetectedCodePages, lpSpecialChar); 03221 return E_NOTIMPL; 03222 } 03223 03224 static HRESULT WINAPI fnIMultiLanguage3_DetectOutboundCodePageInIStream( 03225 IMultiLanguage3 *iface, 03226 DWORD dwFlags, 03227 IStream *pStrIn, 03228 UINT *puiPreferredCodePages, 03229 UINT nPreferredCodePages, 03230 UINT *puiDetectedCodePages, 03231 UINT *pnDetectedCodePages, 03232 WCHAR *lpSpecialChar) 03233 { 03234 MLang_impl *This = impl_from_IMultiLanguage3( iface ); 03235 03236 FIXME("(%p)->(%08x %p %p %u %p %p %p)\n", This, dwFlags, pStrIn, 03237 puiPreferredCodePages, nPreferredCodePages, puiDetectedCodePages, 03238 pnDetectedCodePages, lpSpecialChar); 03239 return E_NOTIMPL; 03240 } 03241 03242 static const IMultiLanguage3Vtbl IMultiLanguage3_vtbl = 03243 { 03244 fnIMultiLanguage2_QueryInterface, 03245 fnIMultiLanguage2_AddRef, 03246 fnIMultiLanguage2_Release, 03247 fnIMultiLanguage2_GetNumberOfCodePageInfo, 03248 fnIMultiLanguage2_GetCodePageInfo, 03249 fnIMultiLanguage2_GetFamilyCodePage, 03250 fnIMultiLanguage2_EnumCodePages, 03251 fnIMultiLanguage2_GetCharsetInfo, 03252 fnIMultiLanguage2_IsConvertible, 03253 fnIMultiLanguage2_ConvertString, 03254 fnIMultiLanguage2_ConvertStringToUnicode, 03255 fnIMultiLanguage2_ConvertStringFromUnicode, 03256 fnIMultiLanguage2_ConvertStringReset, 03257 fnIMultiLanguage2_GetRfc1766FromLcid, 03258 fnIMultiLanguage2_GetLcidFromRfc1766, 03259 fnIMultiLanguage2_EnumRfc1766, 03260 fnIMultiLanguage2_GetRfc1766Info, 03261 fnIMultiLanguage2_CreateConvertCharset, 03262 fnIMultiLanguage2_ConvertStringInIStream, 03263 fnIMultiLanguage2_ConvertStringToUnicodeEx, 03264 fnIMultiLanguage2_ConvertStringFromUnicodeEx, 03265 fnIMultiLanguage2_DetectCodepageInIStream, 03266 fnIMultiLanguage2_DetectInputCodepage, 03267 fnIMultiLanguage2_ValidateCodePage, 03268 fnIMultiLanguage2_GetCodePageDescription, 03269 fnIMultiLanguage2_IsCodePageInstallable, 03270 fnIMultiLanguage2_SetMimeDBSource, 03271 fnIMultiLanguage2_GetNumberOfScripts, 03272 fnIMultiLanguage2_EnumScripts, 03273 fnIMultiLanguage2_ValidateCodePageEx, 03274 fnIMultiLanguage3_DetectOutboundCodePage, 03275 fnIMultiLanguage3_DetectOutboundCodePageInIStream 03276 }; 03277 03278 /******************************************************************************/ 03279 03280 static inline MLang_impl *impl_from_IMLangFontLink2( IMLangFontLink2 *iface ) 03281 { 03282 return CONTAINING_RECORD( iface, MLang_impl, IMLangFontLink2_iface ); 03283 } 03284 03285 static HRESULT WINAPI fnIMLangFontLink2_QueryInterface( 03286 IMLangFontLink2 * iface, 03287 REFIID riid, 03288 void** ppvObject) 03289 { 03290 MLang_impl *This = impl_from_IMLangFontLink2( iface ); 03291 return MLang_QueryInterface( This, riid, ppvObject ); 03292 } 03293 03294 static ULONG WINAPI fnIMLangFontLink2_AddRef( IMLangFontLink2* iface ) 03295 { 03296 MLang_impl *This = impl_from_IMLangFontLink2( iface ); 03297 return MLang_AddRef( This ); 03298 } 03299 03300 static ULONG WINAPI fnIMLangFontLink2_Release( IMLangFontLink2* iface ) 03301 { 03302 MLang_impl *This = impl_from_IMLangFontLink2( iface ); 03303 return MLang_Release( This ); 03304 } 03305 03306 static HRESULT WINAPI fnIMLangFontLink2_GetCharCodePages( IMLangFontLink2* This, 03307 WCHAR chSrc, DWORD *pdwCodePages) 03308 { 03309 FIXME("(%p)->%s %p\n",This, debugstr_wn(&chSrc,1),pdwCodePages); 03310 return E_NOTIMPL; 03311 } 03312 03313 static HRESULT WINAPI fnIMLangFontLink2_GetStrCodePages( IMLangFontLink2* This, 03314 const WCHAR *pszSrc, LONG cchSrc, DWORD dwPriorityCodePages, 03315 DWORD *pdwCodePages, LONG *pcchCodePages) 03316 { 03317 return fnIMLangFontLink_GetStrCodePages((IMLangFontLink *)This, 03318 pszSrc, cchSrc, dwPriorityCodePages, pdwCodePages, pcchCodePages); 03319 } 03320 03321 static HRESULT WINAPI fnIMLangFontLink2_CodePageToCodePages(IMLangFontLink2* This, 03322 UINT uCodePage, 03323 DWORD *pdwCodePages) 03324 { 03325 FIXME("(%p)->%i %p\n",This, uCodePage, pdwCodePages); 03326 return E_NOTIMPL; 03327 } 03328 03329 static HRESULT WINAPI fnIMLangFontLink2_CodePagesToCodePage(IMLangFontLink2* This, 03330 DWORD dwCodePages, UINT uDefaultCodePage, UINT *puCodePage) 03331 { 03332 FIXME("(%p)->%i %i %p\n",This, dwCodePages, uDefaultCodePage, puCodePage); 03333 return E_NOTIMPL; 03334 } 03335 03336 static HRESULT WINAPI fnIMLangFontLink2_GetFontCodePages(IMLangFontLink2* This, 03337 HDC hDC, HFONT hFont, DWORD *pdwCodePages) 03338 { 03339 FIXME("(%p)->%p %p %p\n",This, hDC, hFont, pdwCodePages); 03340 return E_NOTIMPL; 03341 } 03342 03343 static HRESULT WINAPI fnIMLangFontLink2_ReleaseFont(IMLangFontLink2* This, 03344 HFONT hFont) 03345 { 03346 FIXME("(%p)->%p\n",This, hFont); 03347 return E_NOTIMPL; 03348 } 03349 03350 static HRESULT WINAPI fnIMLangFontLink2_ResetFontMapping(IMLangFontLink2* This) 03351 { 03352 FIXME("(%p)->\n",This); 03353 return E_NOTIMPL; 03354 } 03355 03356 static HRESULT WINAPI fnIMLangFontLink2_MapFont(IMLangFontLink2* This, 03357 HDC hDC, DWORD dwCodePages, WCHAR chSrc, HFONT *pFont) 03358 { 03359 FIXME("(%p)->%p %i %s %p\n",This, hDC, dwCodePages, debugstr_wn(&chSrc,1), pFont); 03360 return E_NOTIMPL; 03361 } 03362 03363 static HRESULT WINAPI fnIMLangFontLink2_GetFontUnicodeRanges(IMLangFontLink2* This, 03364 HDC hDC, UINT *puiRanges, UNICODERANGE *pUranges) 03365 { 03366 DWORD size; 03367 GLYPHSET *gs; 03368 03369 TRACE("(%p)->%p %p %p\n", This, hDC, puiRanges, pUranges); 03370 03371 if (!puiRanges) return E_INVALIDARG; 03372 if (!(size = GetFontUnicodeRanges(hDC, NULL))) return E_FAIL; 03373 if (!(gs = HeapAlloc(GetProcessHeap(), 0, size))) return E_OUTOFMEMORY; 03374 03375 GetFontUnicodeRanges(hDC, gs); 03376 *puiRanges = gs->cRanges; 03377 if (pUranges) 03378 { 03379 UINT i; 03380 for (i = 0; i < gs->cRanges; i++) 03381 { 03382 if (i >= *puiRanges) break; 03383 pUranges[i].wcFrom = gs->ranges[i].wcLow; 03384 pUranges[i].wcTo = gs->ranges[i].wcLow + gs->ranges[i].cGlyphs; 03385 } 03386 *puiRanges = i; 03387 } 03388 HeapFree(GetProcessHeap(), 0, gs); 03389 return S_OK; 03390 } 03391 03392 static HRESULT WINAPI fnIMLangFontLink2_GetScriptFontInfo(IMLangFontLink2* This, 03393 SCRIPT_ID sid, DWORD dwFlags, UINT *puiFonts, 03394 SCRIPTFONTINFO *pScriptFont) 03395 { 03396 UINT i, j; 03397 03398 TRACE("(%p)->%u %x %p %p\n", This, sid, dwFlags, puiFonts, pScriptFont); 03399 03400 if (!dwFlags) dwFlags = SCRIPTCONTF_PROPORTIONAL_FONT; 03401 03402 for (i = 0, j = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 03403 { 03404 if (sid == mlang_data[i].sid) 03405 { 03406 if (pScriptFont) 03407 { 03408 if (j >= *puiFonts) break; 03409 03410 pScriptFont[j].scripts = 1 << mlang_data[i].sid; 03411 if (dwFlags == SCRIPTCONTF_FIXED_FONT) 03412 { 03413 MultiByteToWideChar(CP_ACP, 0, mlang_data[i].fixed_font, -1, 03414 pScriptFont[j].wszFont, MAX_MIMEFACE_NAME); 03415 } 03416 else if (dwFlags == SCRIPTCONTF_PROPORTIONAL_FONT) 03417 { 03418 MultiByteToWideChar(CP_ACP, 0, mlang_data[i].proportional_font, -1, 03419 pScriptFont[j].wszFont, MAX_MIMEFACE_NAME); 03420 } 03421 } 03422 j++; 03423 } 03424 } 03425 *puiFonts = j; 03426 return S_OK; 03427 } 03428 03429 static HRESULT WINAPI fnIMLangFontLink2_CodePageToScriptID(IMLangFontLink2* This, 03430 UINT uiCodePage, SCRIPT_ID *pSid) 03431 { 03432 UINT i; 03433 03434 TRACE("(%p)->%i %p\n", This, uiCodePage, pSid); 03435 03436 if (uiCodePage == CP_UNICODE) return E_FAIL; 03437 03438 for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 03439 { 03440 if (uiCodePage == mlang_data[i].family_codepage) 03441 { 03442 if (pSid) *pSid = mlang_data[i].sid; 03443 return S_OK; 03444 } 03445 } 03446 return E_FAIL; 03447 } 03448 03449 static const IMLangFontLink2Vtbl IMLangFontLink2_vtbl = 03450 { 03451 fnIMLangFontLink2_QueryInterface, 03452 fnIMLangFontLink2_AddRef, 03453 fnIMLangFontLink2_Release, 03454 fnIMLangFontLink2_GetCharCodePages, 03455 fnIMLangFontLink2_GetStrCodePages, 03456 fnIMLangFontLink2_CodePageToCodePages, 03457 fnIMLangFontLink2_CodePagesToCodePage, 03458 fnIMLangFontLink2_GetFontCodePages, 03459 fnIMLangFontLink2_ReleaseFont, 03460 fnIMLangFontLink2_ResetFontMapping, 03461 fnIMLangFontLink2_MapFont, 03462 fnIMLangFontLink2_GetFontUnicodeRanges, 03463 fnIMLangFontLink2_GetScriptFontInfo, 03464 fnIMLangFontLink2_CodePageToScriptID 03465 }; 03466 03467 /******************************************************************************/ 03468 03469 static inline MLang_impl *impl_from_IMLangLineBreakConsole( IMLangLineBreakConsole *iface ) 03470 { 03471 return CONTAINING_RECORD( iface, MLang_impl, IMLangLineBreakConsole_iface ); 03472 } 03473 03474 static HRESULT WINAPI fnIMLangLineBreakConsole_QueryInterface( 03475 IMLangLineBreakConsole* iface, 03476 REFIID riid, 03477 void** ppvObject) 03478 { 03479 MLang_impl *This = impl_from_IMLangLineBreakConsole( iface ); 03480 return MLang_QueryInterface( This, riid, ppvObject ); 03481 } 03482 03483 static ULONG WINAPI fnIMLangLineBreakConsole_AddRef( 03484 IMLangLineBreakConsole* iface ) 03485 { 03486 MLang_impl *This = impl_from_IMLangLineBreakConsole( iface ); 03487 return MLang_AddRef( This ); 03488 } 03489 03490 static ULONG WINAPI fnIMLangLineBreakConsole_Release( 03491 IMLangLineBreakConsole* iface ) 03492 { 03493 MLang_impl *This = impl_from_IMLangLineBreakConsole( iface ); 03494 return MLang_Release( This ); 03495 } 03496 03497 static HRESULT WINAPI fnIMLangLineBreakConsole_BreakLineML( 03498 IMLangLineBreakConsole* iface, 03499 IMLangString* pSrcMLStr, 03500 LONG lSrcPos, 03501 LONG lSrcLen, 03502 LONG cMinColumns, 03503 LONG cMaxColumns, 03504 LONG* plLineLen, 03505 LONG* plSkipLen) 03506 { 03507 FIXME("(%p)->%p %i %i %i %i %p %p\n", iface, pSrcMLStr, lSrcPos, lSrcLen, cMinColumns, cMaxColumns, plLineLen, plSkipLen); 03508 return E_NOTIMPL; 03509 } 03510 03511 static HRESULT WINAPI fnIMLangLineBreakConsole_BreakLineW( 03512 IMLangLineBreakConsole* iface, 03513 LCID locale, 03514 const WCHAR* pszSrc, 03515 LONG cchSrc, 03516 LONG cMaxColumns, 03517 LONG* pcchLine, 03518 LONG* pcchSkip ) 03519 { 03520 FIXME("(%p)->%i %s %i %i %p %p\n", iface, locale, debugstr_wn(pszSrc,cchSrc), cchSrc, cMaxColumns, pcchLine, pcchSkip); 03521 03522 *pcchLine = cchSrc; 03523 *pcchSkip = 0; 03524 return S_OK; 03525 } 03526 03527 static HRESULT WINAPI fnIMLangLineBreakConsole_BreakLineA( 03528 IMLangLineBreakConsole* iface, 03529 LCID locale, 03530 UINT uCodePage, 03531 const CHAR* pszSrc, 03532 LONG cchSrc, 03533 LONG cMaxColumns, 03534 LONG* pcchLine, 03535 LONG* pcchSkip) 03536 { 03537 FIXME("(%p)->%i %i %s %i %i %p %p\n", iface, locale, uCodePage, debugstr_an(pszSrc,cchSrc), cchSrc, cMaxColumns, pcchLine, pcchSkip); 03538 03539 *pcchLine = cchSrc; 03540 *pcchSkip = 0; 03541 return S_OK; 03542 } 03543 03544 static const IMLangLineBreakConsoleVtbl IMLangLineBreakConsole_vtbl = 03545 { 03546 fnIMLangLineBreakConsole_QueryInterface, 03547 fnIMLangLineBreakConsole_AddRef, 03548 fnIMLangLineBreakConsole_Release, 03549 fnIMLangLineBreakConsole_BreakLineML, 03550 fnIMLangLineBreakConsole_BreakLineW, 03551 fnIMLangLineBreakConsole_BreakLineA 03552 }; 03553 03554 static HRESULT MultiLanguage_create(IUnknown *pUnkOuter, LPVOID *ppObj) 03555 { 03556 MLang_impl *mlang; 03557 UINT i; 03558 03559 TRACE("Creating MultiLanguage object\n"); 03560 03561 if( pUnkOuter ) 03562 return CLASS_E_NOAGGREGATION; 03563 03564 mlang = HeapAlloc( GetProcessHeap(), 0, sizeof (MLang_impl) ); 03565 mlang->IMLangFontLink_iface.lpVtbl = &IMLangFontLink_vtbl; 03566 mlang->IMultiLanguage_iface.lpVtbl = &IMultiLanguage_vtbl; 03567 mlang->IMultiLanguage3_iface.lpVtbl = &IMultiLanguage3_vtbl; 03568 mlang->IMLangFontLink2_iface.lpVtbl = &IMLangFontLink2_vtbl; 03569 mlang->IMLangLineBreakConsole_iface.lpVtbl = &IMLangLineBreakConsole_vtbl; 03570 03571 mlang->total_cp = 0; 03572 for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) 03573 mlang->total_cp += mlang_data[i].number_of_cp; 03574 03575 /* do not enumerate unicode flavours */ 03576 mlang->total_scripts = sizeof(mlang_data)/sizeof(mlang_data[0]) - 1; 03577 03578 mlang->ref = 1; 03579 *ppObj = mlang; 03580 TRACE("returning %p\n", mlang); 03581 03582 LockModule(); 03583 03584 return S_OK; 03585 } 03586 03587 /******************************************************************************/ 03588 03589 HRESULT WINAPI DllCanUnloadNow(void) 03590 { 03591 return dll_count == 0 ? S_OK : S_FALSE; 03592 } 03593 03594 03595 /*********************************************************************** 03596 * DllRegisterServer (MLANG.@) 03597 */ 03598 HRESULT WINAPI DllRegisterServer(void) 03599 { 03600 return __wine_register_resources( instance ); 03601 } 03602 03603 /*********************************************************************** 03604 * DllUnregisterServer (MLANG.@) 03605 */ 03606 HRESULT WINAPI DllUnregisterServer(void) 03607 { 03608 return __wine_unregister_resources( instance ); 03609 } 03610 03611 HRESULT WINAPI GetGlobalFontLinkObject(void **unknown) 03612 { 03613 if (!unknown) return E_INVALIDARG; 03614 03615 FIXME("%p: stub\n", unknown); 03616 03617 return S_FALSE; 03618 } Generated on Sun May 27 2012 04:24:41 for ReactOS by
1.7.6.1
|