23#define MAX_LANGUAGES 200
25#define WIN32_LEAN_AND_MEAN
36#include <systools/win32/uwinapi.h>
39#include <spellchecker_selection.hxx>
41static bool GetMsiPropA( MSIHANDLE hMSI,
const char* pPropName,
char** ppValue )
44 if ( MsiGetPropertyA( hMSI, pPropName,
const_cast<char *
>(
""), &sz ) == ERROR_MORE_DATA ) {
46 DWORD nbytes = sz *
sizeof( char );
47 char* buff =
static_cast<char*
>( malloc( nbytes ) );
49 ZeroMemory( buff, nbytes );
50 MsiGetPropertyA( hMSI, pPropName, buff, &sz );
52 return ( buff[0] !=
'\0' );
66 case LANG_AFRIKAANS:
return "af";
67 case LANG_AMHARIC:
return "am";
68 case LANG_ARABIC:
return "ar";
69 case LANG_ASSAMESE:
return "as";
70 case LANG_BELARUSIAN:
return "be";
71 case LANG_BULGARIAN:
return "bg";
72 case LANG_BENGALI:
return "bn";
73 case LANG_BRETON:
return "br";
74 case LANG_CATALAN:
return "ca";
75 case LANG_CZECH:
return "cs";
76 case LANG_WELSH:
return "cy";
77 case LANG_DANISH:
return "da";
78 case LANG_GERMAN:
return "de";
79 case LANG_GREEK:
return "el";
80 case LANG_ENGLISH:
return "en";
82 case LANG_ESTONIAN:
return "et";
83 case LANG_BASQUE:
return "eu";
84 case LANG_FARSI:
return "fa";
85 case LANG_FINNISH:
return "fi";
86 case LANG_FAEROESE:
return "fo";
87 case LANG_FRENCH:
return "fr";
88 case LANG_IRISH:
return "ga";
89 case LANG_GALICIAN:
return "gl";
90 case LANG_GUJARATI:
return "gu";
91 case LANG_HEBREW:
return "he";
92 case LANG_HINDI:
return "hi";
93 case LANG_HUNGARIAN:
return "hu";
94 case LANG_ARMENIAN:
return "hy";
95 case LANG_INDONESIAN:
return "id";
96 case LANG_ICELANDIC:
return "is";
97 case LANG_ITALIAN:
return "it";
98 case LANG_JAPANESE:
return "ja";
99 case LANG_GEORGIAN:
return "ka";
100 case LANG_KAZAK:
return "kk";
101 case LANG_KHMER:
return "km";
102 case LANG_KANNADA:
return "kn";
103 case LANG_KOREAN:
return "ko";
104 case LANG_KASHMIRI:
return "ks";
105 case LANG_LAO:
return "lo";
106 case LANG_LITHUANIAN:
return "lt";
107 case LANG_LATVIAN:
return "lv";
108 case LANG_MACEDONIAN:
return "mk";
109 case LANG_MALAYALAM:
return "ml";
110 case LANG_MONGOLIAN:
return "mn";
111 case LANG_MARATHI:
return "mr";
112 case LANG_MALAY:
return "ms";
113 case LANG_MALTESE:
return "mt";
114 case LANG_NEPALI:
return "ne";
115 case LANG_DUTCH:
return "nl";
116 case LANG_SOTHO:
return "ns";
117 case LANG_ORIYA:
return "or";
118 case LANG_PUNJABI:
return "pa";
119 case LANG_POLISH:
return "pl";
120 case LANG_PORTUGUESE:
return "pt";
121 case LANG_ROMANSH:
return "rm";
122 case LANG_ROMANIAN:
return "ro";
123 case LANG_RUSSIAN:
return "ru";
124 case LANG_KINYARWANDA:
return "rw";
125 case LANG_SANSKRIT:
return "sa";
126 case LANG_UPPER_SORBIAN:
return "sb";
127 case LANG_SINDHI:
return "sd";
128 case LANG_SLOVAK:
return "sk";
129 case LANG_SLOVENIAN:
return "sl";
130 case LANG_ALBANIAN:
return "sq";
131 case LANG_SWEDISH:
return "sv";
132 case LANG_SWAHILI:
return "sw";
133 case LANG_TAMIL:
return "ta";
134 case LANG_TELUGU:
return "te";
135 case LANG_TAJIK:
return "tg";
136 case LANG_THAI:
return "th";
137 case LANG_TIGRIGNA:
return "ti";
138 case LANG_TSWANA:
return "tn";
139 case LANG_TURKISH:
return "tr";
140 case LANG_TATAR:
return "tt";
141 case LANG_UKRAINIAN:
return "uk";
142 case LANG_URDU:
return "ur";
143 case LANG_UZBEK:
return "uz";
144 case LANG_VIETNAMESE:
return "vi";
145 case LANG_XHOSA:
return "xh";
146 case LANG_CHINESE:
return "zh";
147 case LANG_ZULU:
return "zu";
151 case MAKELANGID(LANG_SERBIAN, 0x05):
return "bs";
152 case MAKELANGID(LANG_SERBIAN, SUBLANG_DEFAULT):
return "hr";
153 case MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL):
return "nb";
154 case MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_NYNORSK):
return "nn";
155 case MAKELANGID(LANG_SERBIAN, SUBLANG_SERBIAN_LATIN):
return "sh";
156 case MAKELANGID(LANG_SERBIAN, SUBLANG_SERBIAN_CYRILLIC):
return "sr";
157 default:
return nullptr;
178 long langid = strtol(language,
nullptr, 16);
192 if (strchr (lang,
'_') !=
nullptr)
207struct InstallLocalized {
208 char lang[
sizeof(
"lll_Ssss_CC_vvvvvvvv")];
212void addMatchingDictionaries(
213 char const * lang, InstallLocalized * dicts,
int ndicts)
215 for (
int i = 0;
i !=
SAL_N_ELEMENTS(setup_native::languageDictionaries);
218 if (strcmp(lang, setup_native::languageDictionaries[i].language) == 0) {
219 for (
char const *
const * p = setup_native::languageDictionaries[i].
223 for (
int j = 0; j != ndicts; ++j) {
224 if (_stricmp(*p, dicts[j].lang) == 0) {
225 dicts[j].install =
true;
237extern "C" __declspec(dllexport) UINT __stdcall SelectLanguage( MSIHANDLE handle )
240 MSIHANDLE database, view, record;
247 database = MsiGetActiveDatabase(handle);
249 if (MsiDatabaseOpenViewA(database,
"SELECT Feature from Feature WHERE Feature_Parent = 'gm_Langpack_Languageroot'", &view) != ERROR_SUCCESS) {
250 MsiCloseHandle(database);
251 return ERROR_SUCCESS;
254 if (MsiViewExecute(view, 0) != ERROR_SUCCESS) {
255 MsiCloseHandle(view);
256 MsiCloseHandle(database);
257 return ERROR_SUCCESS;
261 MsiViewFetch(view, &record) == ERROR_SUCCESS) {
263 if (MsiRecordGetStringA(record, 1, feature, &
length) != ERROR_SUCCESS) {
264 MsiCloseHandle(record);
265 MsiCloseHandle(view);
266 MsiCloseHandle(database);
267 return ERROR_SUCCESS;
272 strcpy(langs[nlangs].lang, feature + strlen(
"gm_Langpack_r_"));
273 langs[nlangs].install =
false;
276 MsiCloseHandle(record);
279 MsiCloseHandle(view);
283 if (MsiDatabaseOpenViewA(
285 (
"SELECT Feature from Feature WHERE"
286 " Feature_Parent = 'gm_Dictionaries'"),
290 if (MsiViewExecute(view, 0) == ERROR_SUCCESS) {
292 MsiViewFetch(view, &record) == ERROR_SUCCESS)
295 if (MsiRecordGetStringA(record, 1, feature, &
length)
299 feature,
"gm_r_ex_Dictionary_",
300 strlen(
"gm_r_ex_Dictionary_"))
305 feature + strlen(
"gm_r_ex_Dictionary_"));
306 dicts[ndicts].install =
false;
310 MsiCloseHandle(record);
313 MsiCloseHandle(view);
319 char* pVal =
nullptr;
320 if ( (
GetMsiPropA( handle,
"UI_LANGS", &pVal )) && pVal ) {
322 str_ptr = strtok(pVal,
",");
323 for(; str_ptr != nullptr ;) {
325 str_ptr = strtok(
nullptr,
",");
337 long langid = strtol(pVal,
nullptr, 10);
352 bool matches =
false;
353 for (
int i = 0;
i < nlangs;
i++) {
355 langs[
i].install =
true;
360 for (
int i = 0;
i < nlangs;
i++) {
361 if (strcmp(langs[
i].lang,
"en_US") == 0) {
362 langs[
i].install =
true;
368 for (
int i = 0;
i < nlangs;
i++) {
369 langs[
i].install =
true;
374 for (
int i = 0;
i < nlangs;
i++) {
375 if (langs[
i].install) {
376 addMatchingDictionaries(langs[
i].lang, dicts, ndicts);
378 sprintf(feature,
"gm_Langpack_r_%s", langs[
i].lang);
379 MsiSetFeatureStateA(handle, feature, INSTALLSTATE_ABSENT);
384 for (
int i = 0;
i != ndicts; ++
i) {
385 if (!dicts[
i].install) {
386 sprintf(feature,
"gm_r_ex_Dictionary_%s", dicts[
i].lang);
387 MsiSetFeatureStateA(handle, feature, INSTALLSTATE_ABSENT);
391 MsiCloseHandle(database);
393 return ERROR_SUCCESS;
#define PRIMARYLANGID(lgid)
#define SAL_N_ELEMENTS(arr)
int sprintf(char(&s)[N], char const *format, T &&... arguments)
const wchar_t *typedef BOOL
static bool present_in_ui_langs(const char *lang)
__declspec(dllexport) UINT __stdcall SelectLanguage(MSIHANDLE handle)
static BOOL CALLBACK enum_ui_lang_proc(LPTSTR language, LONG_PTR)
static void add_ui_lang(char const *lang)
static bool GetMsiPropA(MSIHANDLE hMSI, const char *pPropName, char **ppValue)
static const char * langid_to_string(LANGID langid)
static const char * ui_langs[MAX_LANGUAGES]