xref: /reactos/dll/cpl/intl/intl.c (revision 58aee30e)
1 /*
2  *  ReactOS
3  *  Copyright (C) 2004 ReactOS Team
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 /*
20  * PROJECT:         ReactOS International Control Panel
21  * FILE:            dll/cpl/intl/intl.c
22  * PURPOSE:         Property sheet code
23  * PROGRAMMER:      Eric Kohl
24  */
25 
26 #include "intl.h"
27 
28 #include <debug.h>
29 
30 #define NUM_APPLETS    (1)
31 
32 #define BUFFERSIZE 512
33 
34 static LONG APIENTRY
35 Applet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam);
36 
37 
38 HINSTANCE hApplet = 0;
39 HWND hCPLWindow;
40 HINF hSetupInf = INVALID_HANDLE_VALUE;
41 DWORD IsUnattendedSetupEnabled = 0;
42 DWORD UnattendLCID = 0;
43 
44 
45 /* Applets */
46 APPLET Applets[NUM_APPLETS] =
47 {
48     {IDC_CPLICON, IDS_CPLNAME, IDS_CPLDESCRIPTION, Applet}
49 };
50 
51 VOID
52 PrintErrorMsgBox(UINT msg)
53 {
54     WCHAR szErrorText[BUFFERSIZE];
55     WCHAR szErrorCaption[BUFFERSIZE];
56 
57     LoadStringW(hApplet, msg, szErrorText, sizeof(szErrorText) / sizeof(WCHAR));
58     LoadStringW(hApplet, IDS_ERROR, szErrorCaption, sizeof(szErrorCaption) / sizeof(WCHAR));
59 
60     MessageBoxW(NULL, szErrorText, szErrorCaption, MB_OK | MB_ICONERROR);
61 }
62 
63 INT
64 ResourceMessageBox(
65     HWND hwnd,
66     UINT uType,
67     UINT uCaptionId,
68     UINT uMessageId)
69 {
70     WCHAR szErrorText[BUFFERSIZE];
71     WCHAR szErrorCaption[BUFFERSIZE];
72 
73     LoadStringW(hApplet, uMessageId, szErrorText, sizeof(szErrorText) / sizeof(WCHAR));
74     LoadStringW(hApplet, uCaptionId, szErrorCaption, sizeof(szErrorCaption) / sizeof(WCHAR));
75 
76     return MessageBoxW(hwnd, szErrorText, szErrorCaption, uType);
77 }
78 
79 static VOID
80 InitIntlPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc, LPARAM lParam)
81 {
82     ZeroMemory(psp, sizeof(PROPSHEETPAGE));
83     psp->dwSize = sizeof(PROPSHEETPAGE);
84     psp->dwFlags = PSP_DEFAULT;
85     psp->hInstance = hApplet;
86     psp->pszTemplate = MAKEINTRESOURCE(idDlg);
87     psp->pfnDlgProc = DlgProc;
88     psp->lParam = lParam;
89 }
90 
91 BOOL
92 OpenSetupInf(VOID)
93 {
94     PWSTR lpCmdLine;
95     PWSTR lpSwitch;
96     size_t len;
97 
98     lpCmdLine = GetCommandLineW();
99 
100     lpSwitch = wcsstr(lpCmdLine, L"/f:\"");
101     if (!lpSwitch)
102         return FALSE;
103 
104     len = wcslen(lpSwitch);
105     if (len < 5 || lpSwitch[len-1] != L'\"')
106     {
107         DPRINT1("Invalid switch: %ls\n", lpSwitch);
108         return FALSE;
109     }
110 
111     lpSwitch[len-1] = L'\0';
112 
113     hSetupInf = SetupOpenInfFileW(&lpSwitch[4], NULL, INF_STYLE_OLDNT, NULL);
114     if (hSetupInf == INVALID_HANDLE_VALUE)
115     {
116         DPRINT1("Failed to open INF file: %ls\n", &lpSwitch[4]);
117         return FALSE;
118     }
119 
120     return TRUE;
121 }
122 
123 VOID
124 ParseSetupInf(VOID)
125 {
126     INFCONTEXT InfContext;
127     WCHAR szBuffer[30];
128 
129     if (!SetupFindFirstLineW(hSetupInf,
130                              L"Unattend",
131                              L"LocaleID",
132                              &InfContext))
133     {
134         SetupCloseInfFile(hSetupInf);
135         DPRINT1("SetupFindFirstLine failed\n");
136         return;
137     }
138 
139     if (!SetupGetStringFieldW(&InfContext, 1, szBuffer,
140                               sizeof(szBuffer) / sizeof(WCHAR), NULL))
141     {
142         SetupCloseInfFile(hSetupInf);
143         DPRINT1("SetupGetStringField failed\n");
144         return;
145     }
146 
147     UnattendLCID = wcstoul(szBuffer, NULL, 16);
148     IsUnattendedSetupEnabled = 1;
149     SetupCloseInfFile(hSetupInf);
150 }
151 
152 static int CALLBACK
153 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
154 {
155     // NOTE: This callback is needed to set large icon correctly.
156     HICON hIcon;
157     switch (uMsg)
158     {
159         case PSCB_INITIALIZED:
160         {
161             hIcon = LoadIconW(hApplet, MAKEINTRESOURCEW(IDC_CPLICON));
162             SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
163             break;
164         }
165     }
166     return 0;
167 }
168 
169 static LONG APIENTRY
170 Applet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
171 {
172     TCHAR Caption[BUFFERSIZE];
173     PROPSHEETPAGE psp[3];
174     PROPSHEETHEADER psh;
175     PGLOBALDATA pGlobalData;
176     LONG ret;
177 
178     if (OpenSetupInf())
179     {
180         ParseSetupInf();
181     }
182 
183     pGlobalData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLOBALDATA));
184     if (pGlobalData == NULL)
185         return FALSE;
186 
187     pGlobalData->SystemLCID = GetSystemDefaultLCID();
188     pGlobalData->bIsUserAdmin = IsUserAdmin();
189 
190     LoadString(hApplet, IDS_CPLNAME, Caption, sizeof(Caption) / sizeof(TCHAR));
191 
192     ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
193     psh.dwSize = sizeof(PROPSHEETHEADER);
194     psh.dwFlags =  PSH_PROPSHEETPAGE | PSH_USEICONID | PSH_USECALLBACK;
195     psh.hwndParent = hCPLWindow;
196     psh.hInstance = hApplet;
197     psh.pszIcon = MAKEINTRESOURCEW(IDC_CPLICON);
198     psh.pszCaption = Caption;
199     psh.nPages = 0; //sizeof(psp) / sizeof(PROPSHEETPAGE);
200     psh.nStartPage = 0;
201     psh.ppsp = psp;
202     psh.pfnCallback = PropSheetProc;
203 
204     InitIntlPropSheetPage(&psp[0], IDD_GENERALPAGE, GeneralPageProc, (LPARAM)pGlobalData);
205     psh.nPages++;
206     InitIntlPropSheetPage(&psp[1], IDD_LANGUAGESPAGE, LanguagesPageProc, (LPARAM)pGlobalData);
207     psh.nPages++;
208 
209     if (pGlobalData->bIsUserAdmin)
210     {
211         InitIntlPropSheetPage(&psp[2], IDD_ADVANCEDPAGE, AdvancedPageProc, (LPARAM)pGlobalData);
212         psh.nPages++;
213     }
214 
215     ret = (LONG)(PropertySheet(&psh) != -1);
216 
217     HeapFree(GetProcessHeap(), 0, pGlobalData);
218 
219     return ret;
220 }
221 
222 
223 /* Control Panel Callback */
224 LONG APIENTRY
225 CPlApplet(HWND hwndCpl,
226           UINT uMsg,
227           LPARAM lParam1,
228           LPARAM lParam2)
229 {
230     switch(uMsg)
231     {
232         case CPL_INIT:
233             return TRUE;
234 
235         case CPL_GETCOUNT:
236             return NUM_APPLETS;
237 
238         case CPL_INQUIRE:
239         {
240             CPLINFO *CPlInfo = (CPLINFO*)lParam2;
241             UINT uAppIndex = (UINT)lParam1;
242 
243             CPlInfo->lData = 0;
244             CPlInfo->idIcon = Applets[uAppIndex].idIcon;
245             CPlInfo->idName = Applets[uAppIndex].idName;
246             CPlInfo->idInfo = Applets[uAppIndex].idDescription;
247             break;
248         }
249 
250         case CPL_DBLCLK:
251         {
252             UINT uAppIndex = (UINT)lParam1;
253             hCPLWindow = hwndCpl;
254             Applets[uAppIndex].AppletProc(hwndCpl, uMsg, lParam1, lParam2);
255             break;
256         }
257     }
258 
259     return FALSE;
260 }
261 
262 
263 BOOL WINAPI
264 DllMain(HINSTANCE hinstDLL,
265         DWORD dwReason,
266         LPVOID lpReserved)
267 {
268     switch(dwReason)
269     {
270         case DLL_PROCESS_ATTACH:
271         case DLL_THREAD_ATTACH:
272             hApplet = hinstDLL;
273             break;
274     }
275 
276   return TRUE;
277 }
278