fix crash at startup
[scilab.git] / scilab / modules / localization / src / c / LanguagePreferences_Windows.c
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2008-2010 - DIGITEO - Allan CORNET
4 *
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution.  The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10 *
11 */
12
13 /*--------------------------------------------------------------------------*/
14 #include <stdio.h>
15 #include <Windows.h>
16 #include <wchar.h>
17 #include "LanguagePreferences_Windows.h"
18 #include "os_string.h"
19 #include "charEncoding.h"
20 #include "setgetlanguage.h"
21 #include "version.h"
22 #include "sci_malloc.h"
23 #include "GetWindowsVersion.h"
24 /*--------------------------------------------------------------------------*/
25 #define HKCU_LANGUAGE_FORMAT L"SOFTWARE\\Scilab\\%s\\Settings" /* r/w registry */
26 #define HKCM_LANGUAGE_FORMAT L"SOFTWARE\\Scilab\\%s" /* only read registry */
27 #define LANGUAGE_ENTRY L"LANGUAGE"
28 #define DEFAULT_LANGUAGE_VALUE L"en_US"
29 /*--------------------------------------------------------------------------*/
30 static wchar_t *languageFromCommandLine = NULL;
31 /*--------------------------------------------------------------------------*/
32 static wchar_t *getLanguagePreferencesCurrentUser(void);
33 static wchar_t *getLanguagePreferencesAllUsers(void);
34 static wchar_t *readRegistryLanguage(HKEY hKeyRoot, wchar_t *keyString);
35 /*--------------------------------------------------------------------------*/
36 BOOL isValidLanguage(wchar_t *lang)
37 {
38     if (lang)
39     {
40         if ( wcscmp(lang, L"") == 0 || wcscmp(lang, L"C") == 0 )
41         {
42             return TRUE;
43         }
44
45         /* xx_XX */
46         if ( ((int) wcslen(lang) == 5) && (lang[2] == L'_') )
47         {
48             return TRUE;
49         }
50         else if ((wcslen(lang) == 2) && (convertlanguagealias(lang)))
51         {
52             return TRUE;
53         }
54     }
55     return FALSE;
56 }
57 /*--------------------------------------------------------------------------*/
58 BOOL setLanguageFromCommandLine(wchar_t *lang)
59 {
60     if (lang)
61     {
62         if (languageFromCommandLine)
63         {
64             FREE(languageFromCommandLine);
65             languageFromCommandLine = NULL;
66         }
67
68         languageFromCommandLine = os_wcsdup(convertlanguagealias(lang));
69
70         return TRUE;
71     }
72     return FALSE;
73 }
74 /*--------------------------------------------------------------------------*/
75 wchar_t *getLanguagePreferences(void)
76 {
77     wchar_t *LanguageUser = NULL;
78
79     if (languageFromCommandLine)
80     {
81         LanguageUser = languageFromCommandLine;
82     }
83     else
84     {
85         LanguageUser = getLanguagePreferencesCurrentUser();
86     }
87
88     if (LanguageUser == NULL)
89     {
90         wchar_t *LanguageAllUsers = getLanguagePreferencesAllUsers();
91
92         if (LanguageAllUsers == NULL)
93         {
94             return os_wcsdup(L"");
95         }
96         else
97         {
98             if (isValidLanguage(LanguageAllUsers))
99             {
100                 return LanguageAllUsers;
101             }
102
103             FREE(LanguageAllUsers);
104         }
105     }
106     else
107     {
108         if (isValidLanguage(LanguageUser))
109         {
110             return LanguageUser;
111         }
112
113         FREE(LanguageUser);
114     }
115     return os_wcsdup(L"");
116 }
117 /*--------------------------------------------------------------------------*/
118 static wchar_t *readRegistryLanguage(HKEY hKeyRoot, wchar_t *keyStringFormat)
119 {
120 #define LENGTH_LANGUAGE_REGISTRY 64
121     wchar_t LANGUAGE_REGISTRY[LENGTH_LANGUAGE_REGISTRY] = DEFAULT_LANGUAGE_VALUE;
122     wchar_t *keyString = NULL;
123     int lenkeyString = (int)(wcslen(keyStringFormat) + wcslen(SCI_VERSION_WIDE_STRING)) + 1;
124
125     keyString = (wchar_t*) MALLOC(sizeof(wchar_t) * lenkeyString);
126
127     if (keyString)
128     {
129
130         DWORD OpensKeyOptions = 0;
131         HKEY hKey;
132         int length = LENGTH_LANGUAGE_REGISTRY;
133         wsprintfW(keyString, keyStringFormat, SCI_VERSION_WIDE_STRING);
134 #ifdef _WIN64 /* Scilab x64 on x64 windows */
135         OpensKeyOptions = KEY_READ | KEY_WOW64_64KEY;
136 #else
137         if (IsWow64()) /* Scilab 32 bits on x64 windows */
138         {
139             OpensKeyOptions = KEY_READ | KEY_WOW64_32KEY;
140         }
141         else /* Scilab 32 bits on windows 32 bits */
142         {
143             OpensKeyOptions = KEY_READ;
144         }
145 #endif
146         if ( RegOpenKeyExW(hKeyRoot, keyString, 0, OpensKeyOptions, &hKey) != ERROR_SUCCESS )
147         {
148             RegCloseKey(hKey);
149             if (keyString)
150             {
151                 FREE(keyString);
152                 keyString = NULL;
153             }
154             return NULL;
155         }
156
157         if ( RegQueryValueExW(hKey, LANGUAGE_ENTRY, 0, NULL , (LPBYTE)LANGUAGE_REGISTRY, &length)  !=  ERROR_SUCCESS )
158         {
159             RegCloseKey(hKey);
160             if (keyString)
161             {
162                 FREE(keyString);
163                 keyString = NULL;
164             }
165             return NULL;
166         }
167
168         RegCloseKey(hKey);
169         if (keyString)
170         {
171             FREE(keyString);
172             keyString = NULL;
173         }
174     }
175     return os_wcsdup(LANGUAGE_REGISTRY);
176 }
177 /*--------------------------------------------------------------------------*/
178 static wchar_t *getLanguagePreferencesCurrentUser(void)
179 {
180     return readRegistryLanguage(HKEY_CURRENT_USER, HKCU_LANGUAGE_FORMAT);
181 }
182 /*--------------------------------------------------------------------------*/
183 static wchar_t *getLanguagePreferencesAllUsers(void)
184 {
185     return readRegistryLanguage(HKEY_LOCAL_MACHINE, HKCM_LANGUAGE_FORMAT);
186 }
187 /*--------------------------------------------------------------------------*/
188 BOOL setLanguagePreferences(void)
189 {
190     wchar_t* pwstLang = getlanguage();
191     char *LANGUAGE = wide_string_to_UTF8(pwstLang);
192     free(pwstLang);
193
194     if (LANGUAGE)
195     {
196         wchar_t *keyString = NULL;
197         int lenkeyString = (int)(wcslen(HKCU_LANGUAGE_FORMAT) + wcslen(SCI_VERSION_WIDE_STRING)) + 1;
198         keyString = (wchar_t*) MALLOC(sizeof(wchar_t) * lenkeyString);
199         if (keyString)
200         {
201             DWORD OpensKeyOptions = 0;
202             HKEY hKey;
203             DWORD result = 0;
204             wsprintfW(keyString, HKCU_LANGUAGE_FORMAT, SCI_VERSION_WIDE_STRING);
205
206 #ifdef _WIN64 /* Scilab x64 on x64 windows */
207             OpensKeyOptions = KEY_ALL_ACCESS | KEY_WOW64_64KEY;
208 #else
209             if ( IsWow64() ) /* Scilab 32 bits on x64 windows */
210             {
211                 OpensKeyOptions = KEY_ALL_ACCESS | KEY_WOW64_32KEY;
212             }
213             else /* Scilab 32 bits on windows 32 bits */
214             {
215                 OpensKeyOptions = KEY_ALL_ACCESS;
216             }
217 #endif
218             if ( RegCreateKeyExW(HKEY_CURRENT_USER, keyString, 0, NULL, REG_OPTION_NON_VOLATILE, OpensKeyOptions, NULL, &hKey, &result) != ERROR_SUCCESS)
219             {
220                 RegCloseKey(hKey);
221                 if (keyString)
222                 {
223                     FREE(keyString);
224                     keyString = NULL;
225                 }
226                 return FALSE;
227             }
228
229             if ( RegSetValueExW(hKey, LANGUAGE_ENTRY, 0, REG_SZ, (LPBYTE)LANGUAGE, (DWORD)(strlen(LANGUAGE) + 1)) != ERROR_SUCCESS)
230             {
231                 RegCloseKey(hKey);
232                 if (keyString)
233                 {
234                     FREE(keyString);
235                     keyString = NULL;
236                 }
237                 return FALSE;
238             }
239
240             RegCloseKey(hKey);
241             if (keyString)
242             {
243                 FREE(keyString);
244                 keyString = NULL;
245             }
246             return TRUE;
247         }
248     }
249     return FALSE;
250 }
251 /*--------------------------------------------------------------------------*/