[USERINIT]
[reactos.git] / reactos / base / system / userinit / livecd.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Userinit Logon Application
4 * FILE: base/system/userinit/livecd.c
5 * PROGRAMMERS: Eric Kohl
6 */
7
8 #include "userinit.h"
9
10 HWND hList;
11 HWND hLocaleList;
12 BOOL bSpain = FALSE;
13
14 static VOID
15 InitImageInfo(PIMGINFO ImgInfo)
16 {
17 BITMAP bitmap;
18
19 ZeroMemory(ImgInfo, sizeof(*ImgInfo));
20
21 ImgInfo->hBitmap = LoadImage(hInstance,
22 MAKEINTRESOURCE(IDB_ROSLOGO),
23 IMAGE_BITMAP,
24 0,
25 0,
26 LR_DEFAULTCOLOR);
27
28 if (ImgInfo->hBitmap != NULL)
29 {
30 GetObject(ImgInfo->hBitmap, sizeof(BITMAP), &bitmap);
31
32 ImgInfo->cxSource = bitmap.bmWidth;
33 ImgInfo->cySource = bitmap.bmHeight;
34 }
35 }
36
37
38 BOOL
39 IsLiveCD(VOID)
40 {
41 HKEY ControlKey = NULL;
42 LPWSTR SystemStartOptions = NULL;
43 LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */
44 LONG rc;
45 BOOL ret = FALSE;
46
47 TRACE("IsLiveCD()\n");
48
49 rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
50 REGSTR_PATH_CURRENT_CONTROL_SET,
51 0,
52 KEY_QUERY_VALUE,
53 &ControlKey);
54 if (rc != ERROR_SUCCESS)
55 {
56 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
57 goto cleanup;
58 }
59
60 rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions);
61 if (rc != ERROR_SUCCESS)
62 {
63 WARN("ReadRegSzKey() failed with error %lu\n", rc);
64 goto cleanup;
65 }
66
67 /* Check for CONSOLE switch in SystemStartOptions */
68 CurrentOption = SystemStartOptions;
69 while (CurrentOption)
70 {
71 NextOption = wcschr(CurrentOption, L' ');
72 if (NextOption)
73 *NextOption = L'\0';
74 if (_wcsicmp(CurrentOption, L"MININT") == 0)
75 {
76 TRACE("Found 'MININT' boot option\n");
77 ret = TRUE;
78 goto cleanup;
79 }
80 CurrentOption = NextOption ? NextOption + 1 : NULL;
81 }
82
83 cleanup:
84 if (ControlKey != NULL)
85 RegCloseKey(ControlKey);
86 HeapFree(GetProcessHeap(), 0, SystemStartOptions);
87
88 TRACE("IsLiveCD() returning %d\n", ret);
89
90 return ret;
91 }
92
93
94 static BOOL CALLBACK
95 LocalesEnumProc(LPTSTR lpLocale)
96 {
97 LCID lcid;
98 WCHAR lang[255];
99 INT index;
100 BOOL bNoShow = FALSE;
101
102 lcid = wcstoul(lpLocale, NULL, 16);
103
104 /* Display only languages with installed support */
105 if (!IsValidLocale(lcid, LCID_INSTALLED))
106 return TRUE;
107
108 if (lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), SORT_DEFAULT) ||
109 lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN), SORT_DEFAULT))
110 {
111 if (bSpain == FALSE)
112 {
113 LoadStringW(hInstance, IDS_SPAIN, lang, 255);
114 bSpain = TRUE;
115 }
116 else
117 {
118 bNoShow = TRUE;
119 }
120 }
121 else
122 {
123 GetLocaleInfoW(lcid, LOCALE_SLANGUAGE, lang, sizeof(lang)/sizeof(WCHAR));
124 }
125
126 if (bNoShow == FALSE)
127 {
128 index = SendMessageW(hList,
129 CB_ADDSTRING,
130 0,
131 (LPARAM)lang);
132
133 SendMessageW(hList,
134 CB_SETITEMDATA,
135 index,
136 (LPARAM)lcid);
137 }
138
139 return TRUE;
140 }
141
142
143 static VOID
144 CreateLanguagesList(HWND hwnd)
145 {
146 WCHAR langSel[255];
147
148 hList = hwnd;
149 bSpain = FALSE;
150 EnumSystemLocalesW(LocalesEnumProc, LCID_SUPPORTED);
151
152 /* Select current locale */
153 /* or should it be System and not user? */
154 GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_SLANGUAGE, langSel, sizeof(langSel)/sizeof(WCHAR));
155
156 SendMessageW(hList,
157 CB_SELECTSTRING,
158 -1,
159 (LPARAM)langSel);
160 }
161
162
163 static
164 VOID
165 InitializeDefaultUserLocale(
166 PLCID pNewLcid)
167 {
168 WCHAR szBuffer[80];
169 PWSTR ptr;
170 HKEY hLocaleKey;
171 DWORD ret;
172 DWORD dwSize;
173 LCID lcid;
174 INT i;
175
176 struct {LCTYPE LCType; PWSTR pValue;} LocaleData[] = {
177 /* Number */
178 {LOCALE_SDECIMAL, L"sDecimal"},
179 {LOCALE_STHOUSAND, L"sThousand"},
180 {LOCALE_SNEGATIVESIGN, L"sNegativeSign"},
181 {LOCALE_SPOSITIVESIGN, L"sPositiveSign"},
182 {LOCALE_SGROUPING, L"sGrouping"},
183 {LOCALE_SLIST, L"sList"},
184 {LOCALE_SNATIVEDIGITS, L"sNativeDigits"},
185 {LOCALE_INEGNUMBER, L"iNegNumber"},
186 {LOCALE_IDIGITS, L"iDigits"},
187 {LOCALE_ILZERO, L"iLZero"},
188 {LOCALE_IMEASURE, L"iMeasure"},
189 {LOCALE_IDIGITSUBSTITUTION, L"NumShape"},
190
191 /* Currency */
192 {LOCALE_SCURRENCY, L"sCurrency"},
193 {LOCALE_SMONDECIMALSEP, L"sMonDecimalSep"},
194 {LOCALE_SMONTHOUSANDSEP, L"sMonThousandSep"},
195 {LOCALE_SMONGROUPING, L"sMonGrouping"},
196 {LOCALE_ICURRENCY, L"iCurrency"},
197 {LOCALE_INEGCURR, L"iNegCurr"},
198 {LOCALE_ICURRDIGITS, L"iCurrDigits"},
199
200 /* Time */
201 {LOCALE_STIMEFORMAT, L"sTimeFormat"},
202 {LOCALE_STIME, L"sTime"},
203 {LOCALE_S1159, L"s1159"},
204 {LOCALE_S2359, L"s2359"},
205 {LOCALE_ITIME, L"iTime"},
206 {LOCALE_ITIMEMARKPOSN, L"iTimePrefix"},
207 {LOCALE_ITLZERO, L"iTLZero"},
208
209 /* Date */
210 {LOCALE_SLONGDATE, L"sLongDate"},
211 {LOCALE_SSHORTDATE, L"sShortDate"},
212 {LOCALE_SDATE, L"sDate"},
213 {LOCALE_IFIRSTDAYOFWEEK, L"iFirstDayOfWeek"},
214 {LOCALE_IFIRSTWEEKOFYEAR, L"iFirstWeekOfYear"},
215 {LOCALE_IDATE, L"iDate"},
216 {LOCALE_ICALENDARTYPE, L"iCalendarType"},
217
218 /* Misc */
219 {LOCALE_SCOUNTRY, L"sCountry"},
220 {LOCALE_SLANGUAGE, L"sLanguage"},
221 {LOCALE_ICOUNTRY, L"iCountry"},
222 {0, NULL}};
223
224 ret = RegOpenKeyExW(HKEY_USERS,
225 L".DEFAULT\\Control Panel\\International",
226 0,
227 KEY_READ | KEY_WRITE,
228 &hLocaleKey);
229 if (ret != ERROR_SUCCESS)
230 {
231 return;
232 }
233
234 if (pNewLcid == NULL)
235 {
236 dwSize = 9 * sizeof(WCHAR);
237 ret = RegQueryValueExW(hLocaleKey,
238 L"Locale",
239 NULL,
240 NULL,
241 (PBYTE)szBuffer,
242 &dwSize);
243 if (ret != ERROR_SUCCESS)
244 goto done;
245
246 lcid = (LCID)wcstoul(szBuffer, &ptr, 16);
247 if (lcid == 0)
248 goto done;
249 }
250 else
251 {
252 lcid = *pNewLcid;
253
254 swprintf(szBuffer, L"%08lx", lcid);
255 RegSetValueExW(hLocaleKey,
256 L"Locale",
257 0,
258 REG_SZ,
259 (PBYTE)szBuffer,
260 (wcslen(szBuffer) + 1) * sizeof(WCHAR));
261 }
262
263 i = 0;
264 while (LocaleData[i].pValue != NULL)
265 {
266 if (GetLocaleInfo(lcid,
267 LocaleData[i].LCType | LOCALE_NOUSEROVERRIDE,
268 szBuffer,
269 sizeof(szBuffer) / sizeof(WCHAR)))
270 {
271 RegSetValueExW(hLocaleKey,
272 LocaleData[i].pValue,
273 0,
274 REG_SZ,
275 (PBYTE)szBuffer,
276 (wcslen(szBuffer) + 1) * sizeof(WCHAR));
277 }
278
279 i++;
280 }
281
282 done:
283 RegCloseKey(hLocaleKey);
284 }
285
286
287 VOID
288 CenterWindow(HWND hWnd)
289 {
290 HWND hWndParent;
291 RECT rcParent;
292 RECT rcWindow;
293
294 hWndParent = GetParent(hWnd);
295 if (hWndParent == NULL)
296 hWndParent = GetDesktopWindow();
297
298 GetWindowRect(hWndParent, &rcParent);
299 GetWindowRect(hWnd, &rcWindow);
300
301 SetWindowPos(hWnd,
302 HWND_TOP,
303 ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
304 ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
305 0,
306 0,
307 SWP_NOSIZE);
308 }
309
310
311 static
312 VOID
313 OnDrawItem(
314 LPDRAWITEMSTRUCT lpDrawItem,
315 PSTATE pState,
316 UINT uCtlID)
317 {
318 HDC hdcMem;
319 LONG left;
320
321 if (lpDrawItem->CtlID == uCtlID)
322 {
323 /* position image in centre of dialog */
324 left = (lpDrawItem->rcItem.right - pState->ImageInfo.cxSource) / 2;
325
326 hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
327 if (hdcMem != NULL)
328 {
329 SelectObject(hdcMem, pState->ImageInfo.hBitmap);
330 BitBlt(lpDrawItem->hDC,
331 left,
332 lpDrawItem->rcItem.top,
333 lpDrawItem->rcItem.right - lpDrawItem->rcItem.left,
334 lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
335 hdcMem,
336 0,
337 0,
338 SRCCOPY);
339 DeleteDC(hdcMem);
340 }
341 }
342 }
343
344
345 static
346 INT_PTR
347 CALLBACK
348 LocaleDlgProc(
349 HWND hwndDlg,
350 UINT uMsg,
351 WPARAM wParam,
352 LPARAM lParam)
353 {
354 PSTATE pState;
355
356 /* Retrieve pointer to the state */
357 pState = (PSTATE)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
358
359 switch (uMsg)
360 {
361 case WM_INITDIALOG:
362 /* Save pointer to the global state */
363 pState = (PSTATE)lParam;
364 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pState);
365
366 /* Center the dialog window */
367 CenterWindow (hwndDlg);
368 CreateLanguagesList(GetDlgItem(hwndDlg, IDC_LANGUAGELIST));
369
370 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
371 return FALSE;
372
373 case WM_DRAWITEM:
374 OnDrawItem((LPDRAWITEMSTRUCT)lParam,
375 pState,
376 IDC_LOCALELOGO);
377 return TRUE;
378
379 case WM_COMMAND:
380 if (HIWORD(wParam) == BN_CLICKED)
381 {
382 switch (LOWORD(wParam))
383 {
384 case IDOK:
385 {
386 LCID NewLcid;
387 INT iCurSel;
388
389 iCurSel = SendDlgItemMessageW(hwndDlg,
390 IDC_LANGUAGELIST,
391 CB_GETCURSEL,
392 0,
393 0);
394 if (iCurSel == CB_ERR)
395 break;
396
397 NewLcid = SendDlgItemMessageW(hwndDlg,
398 IDC_LANGUAGELIST,
399 CB_GETITEMDATA,
400 iCurSel,
401 0);
402 if (NewLcid == (LCID)CB_ERR)
403 break;
404
405 NtSetDefaultLocale(TRUE, NewLcid);
406 InitializeDefaultUserLocale(&NewLcid);
407 }
408
409 pState->NextPage = STARTPAGE;
410 EndDialog(hwndDlg, 0);
411 break;
412
413 default:
414 break;
415 }
416 }
417 break;
418
419 default:
420 break;
421 }
422
423 return FALSE;
424 }
425
426
427 static
428 INT_PTR
429 CALLBACK
430 StartDlgProc(
431 HWND hwndDlg,
432 UINT uMsg,
433 WPARAM wParam,
434 LPARAM lParam)
435 {
436 PSTATE pState;
437
438 /* Retrieve pointer to the state */
439 pState = (PSTATE)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
440
441 switch (uMsg)
442 {
443 case WM_INITDIALOG:
444 /* Save pointer to the state */
445 pState = (PSTATE)lParam;
446 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pState);
447
448 /* Center the dialog window */
449 CenterWindow(hwndDlg);
450
451 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
452 return FALSE;
453
454 case WM_DRAWITEM:
455 OnDrawItem((LPDRAWITEMSTRUCT)lParam,
456 pState,
457 IDC_STARTLOGO);
458 return TRUE;
459
460 case WM_COMMAND:
461 if (HIWORD(wParam) == BN_CLICKED)
462 {
463 switch (LOWORD(wParam))
464 {
465 case IDC_RUN:
466 pState->NextPage = DONE;
467 pState->Run = SHELL;
468 EndDialog(hwndDlg, 0);
469 break;
470
471 case IDC_INSTALL:
472 pState->NextPage = DONE;
473 pState->Run = INSTALLER;
474 EndDialog(hwndDlg, 0);
475 break;
476
477 case IDOK:
478 pState->NextPage = LOCALEPAGE;
479 EndDialog(hwndDlg, 0);
480 break;
481
482 default:
483 break;
484 }
485 }
486 break;
487
488 default:
489 break;
490 }
491
492 return FALSE;
493 }
494
495
496 VOID
497 RunLiveCD(
498 PSTATE pState)
499 {
500 InitImageInfo(&pState->ImageInfo);
501
502 while (pState->NextPage != DONE)
503 {
504 switch (pState->NextPage)
505 {
506 case LOCALEPAGE:
507 DialogBoxParam(hInstance,
508 MAKEINTRESOURCE(IDD_LOCALEPAGE),
509 NULL,
510 LocaleDlgProc,
511 (LPARAM)pState);
512 break;
513
514 case STARTPAGE:
515 DialogBoxParam(hInstance,
516 MAKEINTRESOURCE(IDD_STARTPAGE),
517 NULL,
518 StartDlgProc,
519 (LPARAM)pState);
520 break;
521
522 default:
523 break;
524 }
525 }
526
527 DeleteObject(pState->ImageInfo.hBitmap);
528 }
529
530 /* EOF */