Reactos
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
10HWND hList;
11HWND hLocaleList;
12BOOL bSpain = FALSE;
13
14typedef struct _LIVECD_UNATTEND
15{
16 BOOL bEnabled;
17 LCID LocaleID;
18} LIVECD_UNATTEND;
19
20
21/*
22 * Taken and adapted from dll/cpl/sysdm/general.c
23 */
24static VOID
25InitLogo(PIMGINFO pImgInfo, HWND hwndDlg)
26{
27 BITMAP logoBitmap;
28 BITMAP maskBitmap;
29 BITMAPINFO bmpi;
30 HDC hDC, hDCLogo, hDCMask;
31 HBITMAP hMask = NULL, hLogo = NULL;
32 HBITMAP hAlphaLogo = NULL;
33 COLORREF *pBits;
34 INT line, column;
35
36 hDC = GetDC(hwndDlg);
37 hDCLogo = CreateCompatibleDC(NULL);
38 hDCMask = CreateCompatibleDC(NULL);
39
40 if (hDC == NULL || hDCLogo == NULL || hDCMask == NULL)
41 goto Cleanup;
42
43 ZeroMemory(pImgInfo, sizeof(*pImgInfo));
44 ZeroMemory(&bmpi, sizeof(bmpi));
45
46 hLogo = (HBITMAP)LoadImageW(hInstance, MAKEINTRESOURCEW(IDB_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
47 hMask = (HBITMAP)LoadImageW(hInstance, MAKEINTRESOURCEW(IDB_ROSMASK), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
48
49 if (hLogo == NULL || hMask == NULL)
50 goto Cleanup;
51
52 GetObject(hLogo, sizeof(logoBitmap), &logoBitmap);
53 GetObject(hMask, sizeof(maskBitmap), &maskBitmap);
54
55 if (logoBitmap.bmHeight != maskBitmap.bmHeight || logoBitmap.bmWidth != maskBitmap.bmWidth)
56 goto Cleanup;
57
58 bmpi.bmiHeader.biSize = sizeof(BITMAPINFO);
59 bmpi.bmiHeader.biWidth = logoBitmap.bmWidth;
60 bmpi.bmiHeader.biHeight = logoBitmap.bmHeight;
61 bmpi.bmiHeader.biPlanes = 1;
62 bmpi.bmiHeader.biBitCount = 32;
63 bmpi.bmiHeader.biCompression = BI_RGB;
64 bmpi.bmiHeader.biSizeImage = 4 * logoBitmap.bmWidth * logoBitmap.bmHeight;
65
66 /* Create a premultiplied bitmap */
67 hAlphaLogo = CreateDIBSection(hDC, &bmpi, DIB_RGB_COLORS, (PVOID*)&pBits, 0, 0);
68 if (!hAlphaLogo)
69 goto Cleanup;
70
71 SelectObject(hDCLogo, hLogo);
72 SelectObject(hDCMask, hMask);
73
74 for (line = logoBitmap.bmHeight - 1; line >= 0; line--)
75 {
76 for (column = 0; column < logoBitmap.bmWidth; column++)
77 {
78 COLORREF alpha = GetPixel(hDCMask, column, line) & 0xFF;
79 COLORREF Color = GetPixel(hDCLogo, column, line);
80 DWORD r, g, b;
81
82 r = GetRValue(Color) * alpha / 255;
83 g = GetGValue(Color) * alpha / 255;
84 b = GetBValue(Color) * alpha / 255;
85
86 *pBits++ = b | (g << 8) | (r << 16) | (alpha << 24);
87 }
88 }
89
90 pImgInfo->hBitmap = hAlphaLogo;
91 pImgInfo->cxSource = logoBitmap.bmWidth;
92 pImgInfo->cySource = logoBitmap.bmHeight;
93 pImgInfo->iBits = logoBitmap.bmBitsPixel;
94 pImgInfo->iPlanes = logoBitmap.bmPlanes;
95
96Cleanup:
97 if (hMask != NULL) DeleteObject(hMask);
98 if (hLogo != NULL) DeleteObject(hLogo);
99 if (hDCMask != NULL) DeleteDC(hDCMask);
100 if (hDCLogo != NULL) DeleteDC(hDCLogo);
101 if (hDC != NULL) ReleaseDC(hwndDlg, hDC);
102}
103
104
105BOOL
106IsLiveCD(VOID)
107{
108 HKEY ControlKey = NULL;
109 LPWSTR SystemStartOptions = NULL;
110 LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */
111 LONG rc;
112 BOOL ret = FALSE;
113
114 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
115 REGSTR_PATH_CURRENT_CONTROL_SET,
116 0,
117 KEY_QUERY_VALUE,
118 &ControlKey);
119 if (rc != ERROR_SUCCESS)
120 {
121 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
122 goto cleanup;
123 }
124
125 rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions);
126 if (rc != ERROR_SUCCESS)
127 {
128 WARN("ReadRegSzKey() failed with error %lu\n", rc);
129 goto cleanup;
130 }
131
132 /* Check for CONSOLE switch in SystemStartOptions */
133 CurrentOption = SystemStartOptions;
134 while (CurrentOption)
135 {
136 NextOption = wcschr(CurrentOption, L' ');
137 if (NextOption)
138 *NextOption = L'\0';
139 if (_wcsicmp(CurrentOption, L"MININT") == 0)
140 {
141 TRACE("Found 'MININT' boot option\n");
142 ret = TRUE;
143 goto cleanup;
144 }
145 CurrentOption = NextOption ? NextOption + 1 : NULL;
146 }
147
148cleanup:
149 if (ControlKey != NULL)
150 RegCloseKey(ControlKey);
151 HeapFree(GetProcessHeap(), 0, SystemStartOptions);
152
153 TRACE("IsLiveCD() returning %u\n", ret);
154 return ret;
155}
156
157
158static BOOL CALLBACK
159LocalesEnumProc(LPTSTR lpLocale)
160{
161 LCID lcid;
162 WCHAR lang[255];
163 INT index;
164 BOOL bNoShow = FALSE;
165
166 lcid = wcstoul(lpLocale, NULL, 16);
167
168 /* Display only languages with installed support */
169 if (!IsValidLocale(lcid, LCID_INSTALLED))
170 return TRUE;
171
172 // See http://archives.miloush.net/michkap/archive/2006/09/23/768178.html for why we handle spain differently
173 if (lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), SORT_DEFAULT) ||
174 lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN), SORT_DEFAULT))
175 {
176 if (bSpain == FALSE)
177 {
178 LoadStringW(hInstance, IDS_SPAIN, lang, ARRAYSIZE(lang));
179 bSpain = TRUE;
180 }
181 else
182 {
183 bNoShow = TRUE;
184 }
185 }
186 else
187 {
188 GetLocaleInfoW(lcid, LOCALE_SLANGUAGE, lang, ARRAYSIZE(lang));
189 }
190
191 if (bNoShow == FALSE)
192 {
193 index = SendMessageW(hList,
194 CB_ADDSTRING,
195 0,
196 (LPARAM)lang);
197
198 SendMessageW(hList,
199 CB_SETITEMDATA,
200 index,
201 (LPARAM)lcid);
202 }
203
204 return TRUE;
205}
206
207
208static VOID
209CreateLanguagesList(HWND hwnd, PSTATE pState)
210{
211 WCHAR langSel[255];
212 LCID Locale = 0;
213
214 hList = hwnd;
215 bSpain = FALSE;
216 EnumSystemLocalesW(LocalesEnumProc, LCID_SUPPORTED);
217
218 if (pState->Unattend->bEnabled)
219 Locale = pState->Unattend->LocaleID;
220
221 if (!Locale)
222 {
223 /* Select current locale */
224 /* or should it be System and not user? */
225 Locale = GetUserDefaultLCID();
226 }
227 GetLocaleInfoW(Locale, LOCALE_SLANGUAGE, langSel, ARRAYSIZE(langSel));
228
229 SendMessageW(hList,
230 CB_SELECTSTRING,
231 -1,
232 (LPARAM)langSel);
233}
234
235
236static
237BOOL
238GetLayoutName(
239 LPCWSTR szLCID,
240 LPWSTR szName)
241{
242 HKEY hKey;
243 DWORD dwBufLen;
244 WCHAR szBuf[MAX_PATH], szDispName[MAX_PATH], szIndex[MAX_PATH], szPath[MAX_PATH];
245 HANDLE hLib;
246 UINT i, j, k;
247
248 wsprintf(szBuf, L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s", szLCID);
249
250 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szBuf, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
251 {
252 dwBufLen = sizeof(szDispName);
253
254 if (RegQueryValueExW(hKey, L"Layout Display Name", NULL, NULL, (LPBYTE)szDispName, &dwBufLen) == ERROR_SUCCESS)
255 {
256 if (szDispName[0] == '@')
257 {
258 for (i = 0; i < wcslen(szDispName); i++)
259 {
260 if ((szDispName[i] == ',') && (szDispName[i + 1] == '-'))
261 {
262 for (j = i + 2, k = 0; j < wcslen(szDispName)+1; j++, k++)
263 {
264 szIndex[k] = szDispName[j];
265 }
266 szDispName[i - 1] = '\0';
267 break;
268 }
269 else
270 szDispName[i] = szDispName[i + 1];
271 }
272
273 if (ExpandEnvironmentStringsW(szDispName, szPath, ARRAYSIZE(szPath)))
274 {
275 hLib = LoadLibraryW(szPath);
276 if (hLib)
277 {
278 if (LoadStringW(hLib, _wtoi(szIndex), szPath, ARRAYSIZE(szPath)) != 0)
279 {
280 wcscpy(szName, szPath);
281 RegCloseKey(hKey);
282 return TRUE;
283 }
284 FreeLibrary(hLib);
285 }
286 }
287 }
288 }
289
290 dwBufLen = sizeof(szBuf);
291
292 if (RegQueryValueExW(hKey, L"Layout Text", NULL, NULL, (LPBYTE)szName, &dwBufLen) == ERROR_SUCCESS)
293 {
294 RegCloseKey(hKey);
295 return TRUE;
296 }
297 }
298
299 return FALSE;
300}
301
302
303static
304VOID
305SetKeyboardLayout(
306 HWND hwnd)
307{
308 INT iCurSel;
309 ULONG ulLayoutId;
310 HKL hKl;
311 WCHAR szLayoutId[9];
312
313 iCurSel = SendMessageW(hwnd, CB_GETCURSEL, 0, 0);
314 if (iCurSel == CB_ERR)
315 return;
316
317 ulLayoutId = (ULONG)SendMessageW(hwnd, CB_GETITEMDATA, iCurSel, 0);
318 if (ulLayoutId == (ULONG)CB_ERR)
319 return;
320
321 swprintf(szLayoutId, L"%08lx", ulLayoutId);
322
323 hKl = LoadKeyboardLayoutW(szLayoutId, KLF_ACTIVATE | KLF_REPLACELANG | KLF_SETFORPROCESS);
324 SystemParametersInfoW(SPI_SETDEFAULTINPUTLANG, 0, &hKl, SPIF_SENDCHANGE);
325}
326
327
328static
329VOID
330SelectKeyboardForLanguage(
331 HWND hwnd,
332 LCID lcid)
333{
334 INT i, nCount;
335 LCID LayoutId;
336
337 TRACE("LCID: %08lx\n", lcid);
338 TRACE("LangID: %04lx\n", LANGIDFROMLCID(lcid));
339
340 nCount = SendMessageW(hwnd, CB_GETCOUNT, 0, 0);
341
342 for (i = 0; i < nCount; i++)
343 {
344 LayoutId = (LCID)SendMessageW(hwnd, CB_GETITEMDATA, i, 0);
345 TRACE("Layout: %08lx\n", LayoutId);
346
347 if (LANGIDFROMLCID(LayoutId) == LANGIDFROMLCID(lcid))
348 {
349 TRACE("Found 1: %08lx --> %08lx\n", LayoutId, lcid);
350 SendMessageW(hwnd, CB_SETCURSEL, i, 0);
351 return;
352 }
353 }
354
355 for (i = 0; i < nCount; i++)
356 {
357 LayoutId = (LCID)SendMessageW(hwnd, CB_GETITEMDATA, i, 0);
358 TRACE("Layout: %08lx\n", LayoutId);
359
360 if (PRIMARYLANGID(LayoutId) == PRIMARYLANGID(lcid))
361 {
362 TRACE("Found 2: %08lx --> %08lx\n", LayoutId, lcid);
363 SendMessageW(hwnd, CB_SETCURSEL, i, 0);
364 return;
365 }
366 }
367
368 TRACE("No match found!\n");
369}
370
371
372static
373VOID
374CreateKeyboardLayoutList(
375 HWND hItemsList)
376{
377 HKEY hKey;
378 WCHAR szLayoutId[9], szCurrentLayoutId[9];
379 WCHAR KeyName[MAX_PATH];
380 DWORD dwIndex = 0;
381 DWORD dwSize;
382 INT iIndex;
383 LONG lError;
384 ULONG ulLayoutId;
385
386 if (!GetKeyboardLayoutNameW(szCurrentLayoutId))
387 wcscpy(szCurrentLayoutId, L"00000409");
388
389 lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
390 L"System\\CurrentControlSet\\Control\\Keyboard Layouts",
391 0,
392 KEY_ENUMERATE_SUB_KEYS,
393 &hKey);
394 if (lError != ERROR_SUCCESS)
395 return;
396
397 while (TRUE)
398 {
399 dwSize = ARRAYSIZE(szLayoutId);
400
401 lError = RegEnumKeyExW(hKey,
402 dwIndex,
403 szLayoutId,
404 &dwSize,
405 NULL,
406 NULL,
407 NULL,
408 NULL);
409 if (lError != ERROR_SUCCESS)
410 break;
411
412 GetLayoutName(szLayoutId, KeyName);
413
414 iIndex = (INT)SendMessageW(hItemsList, CB_ADDSTRING, 0, (LPARAM)KeyName);
415
416 ulLayoutId = wcstoul(szLayoutId, NULL, 16);
417 SendMessageW(hItemsList, CB_SETITEMDATA, iIndex, (LPARAM)ulLayoutId);
418
419 if (wcscmp(szLayoutId, szCurrentLayoutId) == 0)
420 {
421 SendMessageW(hItemsList, CB_SETCURSEL, (WPARAM)iIndex, (LPARAM)0);
422 }
423
424 dwIndex++;
425 }
426
427 RegCloseKey(hKey);
428}
429
430
431static
432VOID
433InitializeDefaultUserLocale(
434 PLCID pNewLcid)
435{
436 WCHAR szBuffer[80];
437 PWSTR ptr;
438 HKEY hLocaleKey;
439 DWORD ret;
440 DWORD dwSize;
441 LCID lcid;
442 INT i;
443
444 struct {LCTYPE LCType; PWSTR pValue;} LocaleData[] = {
445 /* Number */
446 {LOCALE_SDECIMAL, L"sDecimal"},
447 {LOCALE_STHOUSAND, L"sThousand"},
448 {LOCALE_SNEGATIVESIGN, L"sNegativeSign"},
449 {LOCALE_SPOSITIVESIGN, L"sPositiveSign"},
450 {LOCALE_SGROUPING, L"sGrouping"},
451 {LOCALE_SLIST, L"sList"},
452 {LOCALE_SNATIVEDIGITS, L"sNativeDigits"},
453 {LOCALE_INEGNUMBER, L"iNegNumber"},
454 {LOCALE_IDIGITS, L"iDigits"},
455 {LOCALE_ILZERO, L"iLZero"},
456 {LOCALE_IMEASURE, L"iMeasure"},
457 {LOCALE_IDIGITSUBSTITUTION, L"NumShape"},
458
459 /* Currency */
460 {LOCALE_SCURRENCY, L"sCurrency"},
461 {LOCALE_SMONDECIMALSEP, L"sMonDecimalSep"},
462 {LOCALE_SMONTHOUSANDSEP, L"sMonThousandSep"},
463 {LOCALE_SMONGROUPING, L"sMonGrouping"},
464 {LOCALE_ICURRENCY, L"iCurrency"},
465 {LOCALE_INEGCURR, L"iNegCurr"},
466 {LOCALE_ICURRDIGITS, L"iCurrDigits"},
467
468 /* Time */
469 {LOCALE_STIMEFORMAT, L"sTimeFormat"},
470 {LOCALE_STIME, L"sTime"},
471 {LOCALE_S1159, L"s1159"},
472 {LOCALE_S2359, L"s2359"},
473 {LOCALE_ITIME, L"iTime"},
474 {LOCALE_ITIMEMARKPOSN, L"iTimePrefix"},
475 {LOCALE_ITLZERO, L"iTLZero"},
476
477 /* Date */
478 {LOCALE_SLONGDATE, L"sLongDate"},
479 {LOCALE_SSHORTDATE, L"sShortDate"},
480 {LOCALE_SDATE, L"sDate"},
481 {LOCALE_IFIRSTDAYOFWEEK, L"iFirstDayOfWeek"},
482 {LOCALE_IFIRSTWEEKOFYEAR, L"iFirstWeekOfYear"},
483 {LOCALE_IDATE, L"iDate"},
484 {LOCALE_ICALENDARTYPE, L"iCalendarType"},
485
486 /* Misc */
487 {LOCALE_SCOUNTRY, L"sCountry"},
488 {LOCALE_SABBREVLANGNAME, L"sLanguage"},
489 {LOCALE_ICOUNTRY, L"iCountry"},
490 {0, NULL}};
491
492 ret = RegOpenKeyExW(HKEY_USERS,
493 L".DEFAULT\\Control Panel\\International",
494 0,
495 KEY_READ | KEY_WRITE,
496 &hLocaleKey);
497 if (ret != ERROR_SUCCESS)
498 {
499 return;
500 }
501
502 if (pNewLcid == NULL)
503 {
504 dwSize = 9 * sizeof(WCHAR);
505 ret = RegQueryValueExW(hLocaleKey,
506 L"Locale",
507 NULL,
508 NULL,
509 (PBYTE)szBuffer,
510 &dwSize);
511 if (ret != ERROR_SUCCESS)
512 goto done;
513
514 lcid = (LCID)wcstoul(szBuffer, &ptr, 16);
515 if (lcid == 0)
516 goto done;
517 }
518 else
519 {
520 lcid = *pNewLcid;
521
522 swprintf(szBuffer, L"%08lx", lcid);
523 RegSetValueExW(hLocaleKey,
524 L"Locale",
525 0,
526 REG_SZ,
527 (PBYTE)szBuffer,
528 (wcslen(szBuffer) + 1) * sizeof(WCHAR));
529 }
530
531 i = 0;
532 while (LocaleData[i].pValue != NULL)
533 {
534 if (GetLocaleInfoW(lcid,
535 LocaleData[i].LCType | LOCALE_NOUSEROVERRIDE,
536 szBuffer,
537 ARRAYSIZE(szBuffer)))
538 {
539 RegSetValueExW(hLocaleKey,
540 LocaleData[i].pValue,
541 0,
542 REG_SZ,
543 (PBYTE)szBuffer,
544 (wcslen(szBuffer) + 1) * sizeof(WCHAR));
545 }
546
547 i++;
548 }
549
550done:
551 RegCloseKey(hLocaleKey);
552}
553
554
555VOID
556CenterWindow(HWND hWnd)
557{
558 HWND hWndParent;
559 RECT rcParent;
560 RECT rcWindow;
561
562 hWndParent = GetParent(hWnd);
563 if (hWndParent == NULL)
564 hWndParent = GetDesktopWindow();
565
566 GetWindowRect(hWndParent, &rcParent);
567 GetWindowRect(hWnd, &rcWindow);
568
569 SetWindowPos(hWnd,
570 HWND_TOP,
571 ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
572 ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
573 0,
574 0,
575 SWP_NOSIZE);
576}
577
578
579static
580VOID
581OnDrawItem(
582 LPDRAWITEMSTRUCT lpDrawItem,
583 PSTATE pState,
584 UINT uCtlID)
585{
586 HDC hdcMem;
587 LONG left;
588
589 if (lpDrawItem->CtlID == uCtlID)
590 {
591 /* Position image in centre of dialog */
592 left = (lpDrawItem->rcItem.right - pState->ImageInfo.cxSource) / 2;
593
594 hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
595 if (hdcMem != NULL)
596 {
597 static BLENDFUNCTION BlendFunc = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
598
599 SelectObject(hdcMem, pState->ImageInfo.hBitmap);
600 GdiAlphaBlend(lpDrawItem->hDC,
601 left,
602 lpDrawItem->rcItem.top,
603 pState->ImageInfo.cxSource,
604 pState->ImageInfo.cySource,
605 hdcMem,
606 0, 0,
607 pState->ImageInfo.cxSource,
608 pState->ImageInfo.cySource,
609 BlendFunc);
610 DeleteDC(hdcMem);
611 }
612 }
613}
614
615
616static
617INT_PTR
618CALLBACK
619LocaleDlgProc(
620 HWND hwndDlg,
621 UINT uMsg,
622 WPARAM wParam,
623 LPARAM lParam)
624{
625 PSTATE pState;
626
627 /* Retrieve pointer to the state */
628 pState = (PSTATE)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA);
629
630 switch (uMsg)
631 {
632 case WM_INITDIALOG:
633 /* Save pointer to the state */
634 pState = (PSTATE)lParam;
635 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pState);
636
637 /* Center the dialog window */
638 CenterWindow(hwndDlg);
639
640 /* Fill the language and keyboard layout lists */
641 CreateLanguagesList(GetDlgItem(hwndDlg, IDC_LANGUAGELIST), pState);
642 CreateKeyboardLayoutList(GetDlgItem(hwndDlg, IDC_LAYOUTLIST));
643 if (pState->Unattend->bEnabled)
644 {
645 /* Advance to the next page */
646 PostMessageW(hwndDlg, WM_COMMAND, MAKEWPARAM(IDOK, BN_CLICKED), 0L);
647 }
648 return FALSE;
649
650 case WM_DRAWITEM:
651 OnDrawItem((LPDRAWITEMSTRUCT)lParam,
652 pState,
653 IDC_LOCALELOGO);
654 return TRUE;
655
656 case WM_COMMAND:
657 switch (LOWORD(wParam))
658 {
659 case IDC_LANGUAGELIST:
660 if (HIWORD(wParam) == CBN_SELCHANGE)
661 {
662 LCID NewLcid;
663 INT iCurSel;
664
665 iCurSel = SendDlgItemMessageW(hwndDlg,
666 IDC_LANGUAGELIST,
667 CB_GETCURSEL,
668 0,
669 0);
670 if (iCurSel == CB_ERR)
671 break;
672
673 NewLcid = SendDlgItemMessageW(hwndDlg,
674 IDC_LANGUAGELIST,
675 CB_GETITEMDATA,
676 iCurSel,
677 0);
678 if (NewLcid == (LCID)CB_ERR)
679 break;
680
681 TRACE("LCID: 0x%08lx\n", NewLcid);
682 SelectKeyboardForLanguage(GetDlgItem(hwndDlg, IDC_LAYOUTLIST),
683 NewLcid);
684 }
685 break;
686
687 case IDOK:
688 if (HIWORD(wParam) == BN_CLICKED)
689 {
690 LCID NewLcid;
691 INT iCurSel;
692
693 iCurSel = SendDlgItemMessageW(hwndDlg,
694 IDC_LANGUAGELIST,
695 CB_GETCURSEL,
696 0,
697 0);
698 if (iCurSel == CB_ERR)
699 break;
700
701 NewLcid = SendDlgItemMessageW(hwndDlg,
702 IDC_LANGUAGELIST,
703 CB_GETITEMDATA,
704 iCurSel,
705 0);
706 if (NewLcid == (LCID)CB_ERR)
707 break;
708
709 /* Set the locale for the current thread */
710 NtSetDefaultLocale(TRUE, NewLcid);
711
712 /* Store the locale settings in the registry */
713 InitializeDefaultUserLocale(&NewLcid);
714
715 /* Set UI language for this thread */
716 SetThreadLocale(NewLcid);
717
718 SetKeyboardLayout(GetDlgItem(hwndDlg, IDC_LAYOUTLIST));
719
720 pState->NextPage = STARTPAGE;
721 EndDialog(hwndDlg, LOWORD(wParam));
722 }
723 break;
724
725 case IDCANCEL:
726 if (HIWORD(wParam) == BN_CLICKED)
727 {
728 static WCHAR szMsg[RC_STRING_MAX_SIZE];
729 INT ret;
730 LoadStringW(GetModuleHandle(NULL), IDS_CANCEL_CONFIRM, szMsg, ARRAYSIZE(szMsg));
731 ret = MessageBoxW(hwndDlg, szMsg, L"ReactOS LiveCD", MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);
732 if (ret == IDOK || ret == IDYES)
733 {
734 pState->NextPage = DONE;
735 pState->Run = REBOOT;
736 EndDialog(hwndDlg, LOWORD(wParam));
737 }
738 }
739 break;
740
741 default:
742 break;
743 }
744 break;
745
746 default:
747 break;
748 }
749
750 return FALSE;
751}
752
753
754static
755INT_PTR
756CALLBACK
757StartDlgProc(
758 HWND hwndDlg,
759 UINT uMsg,
760 WPARAM wParam,
761 LPARAM lParam)
762{
763 PSTATE pState;
764
765 /* Retrieve pointer to the state */
766 pState = (PSTATE)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA);
767
768 switch (uMsg)
769 {
770 case WM_INITDIALOG:
771 {
772 WCHAR Installer[MAX_PATH];
773
774 /* Save pointer to the state */
775 pState = (PSTATE)lParam;
776 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pState);
777
778 /* Center the dialog window */
779 CenterWindow(hwndDlg);
780
781 /* Check whether we can find the ReactOS installer. If not,
782 * disable the "Install" button and directly start the LiveCD. */
783 *Installer = UNICODE_NULL;
784 if (!ExpandInstallerPath(L"reactos.exe", Installer, ARRAYSIZE(Installer)))
785 EnableWindow(GetDlgItem(hwndDlg, IDC_INSTALL), FALSE);
786
787 if (pState->Unattend->bEnabled || (*Installer == UNICODE_NULL))
788 {
789 /* Click on the 'Run' button */
790 PostMessageW(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_RUN, BN_CLICKED), 0L);
791 }
792 return FALSE;
793 }
794
795 case WM_DRAWITEM:
796 OnDrawItem((LPDRAWITEMSTRUCT)lParam,
797 pState,
798 IDC_STARTLOGO);
799 return TRUE;
800
801 case WM_COMMAND:
802 if (HIWORD(wParam) == BN_CLICKED)
803 {
804 switch (LOWORD(wParam))
805 {
806 case IDC_RUN:
807 pState->NextPage = DONE;
808 pState->Run = SHELL;
809 EndDialog(hwndDlg, LOWORD(wParam));
810 break;
811
812 case IDC_INSTALL:
813 pState->NextPage = DONE;
814 pState->Run = INSTALLER;
815 EndDialog(hwndDlg, LOWORD(wParam));
816 break;
817
818 case IDOK:
819 pState->NextPage = LOCALEPAGE;
820 EndDialog(hwndDlg, LOWORD(wParam));
821 break;
822
823 case IDCANCEL:
824 if (HIWORD(wParam) == BN_CLICKED)
825 {
826 static WCHAR szMsg[RC_STRING_MAX_SIZE];
827 INT ret;
828 LoadStringW(GetModuleHandle(NULL), IDS_CANCEL_CONFIRM, szMsg, ARRAYSIZE(szMsg));
829 ret = MessageBoxW(hwndDlg, szMsg, L"ReactOS LiveCD", MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);
830 if (ret == IDOK || ret == IDYES)
831 {
832 pState->NextPage = DONE;
833 pState->Run = REBOOT;
834 EndDialog(hwndDlg, LOWORD(wParam));
835 }
836 }
837 break;
838
839 default:
840 break;
841 }
842 }
843 break;
844
845 default:
846 break;
847 }
848
849 return FALSE;
850}
851
852VOID ParseUnattend(LPCWSTR UnattendInf, LIVECD_UNATTEND* pUnattend)
853{
854 WCHAR Buffer[MAX_PATH];
855
856 pUnattend->bEnabled = FALSE;
857
858 if (!GetPrivateProfileStringW(L"Unattend", L"Signature", L"", Buffer, _countof(Buffer), UnattendInf))
859 {
860 ERR("Unable to parse Signature\n");
861 return;
862 }
863
864 if (_wcsicmp(Buffer, L"$ReactOS$") && _wcsicmp(Buffer, L"$Windows NT$"))
865 {
866 TRACE("Unknown signature: %S\n", Buffer);
867 return;
868 }
869
870 if (!GetPrivateProfileStringW(L"Unattend", L"UnattendSetupEnabled", L"", Buffer, _countof(Buffer), UnattendInf))
871 {
872 ERR("Unable to parse UnattendSetupEnabled\n");
873 return;
874 }
875
876 if (_wcsicmp(Buffer, L"yes"))
877 {
878 TRACE("Unattended setup is not enabled\n", Buffer);
879 return;
880 }
881
882 pUnattend->bEnabled = TRUE;
883 pUnattend->LocaleID = 0;
884
885 if (GetPrivateProfileStringW(L"Unattend", L"LocaleID", L"", Buffer, _countof(Buffer), UnattendInf) && Buffer[0])
886 {
887 pUnattend->LocaleID = wcstol(Buffer, NULL, 16);
888 }
889}
890
891VOID
892RunLiveCD(
893 PSTATE pState)
894{
895 LIVECD_UNATTEND Unattend = {0};
896 WCHAR UnattendInf[MAX_PATH];
897
898 InitLogo(&pState->ImageInfo, NULL);
899
900 GetWindowsDirectoryW(UnattendInf, _countof(UnattendInf));
901 wcscat(UnattendInf, L"\\unattend.inf");
902 ParseUnattend(UnattendInf, &Unattend);
903 pState->Unattend = &Unattend;
904
905 while (pState->NextPage != DONE)
906 {
907 switch (pState->NextPage)
908 {
909 case LOCALEPAGE:
910 DialogBoxParamW(hInstance,
911 MAKEINTRESOURCEW(IDD_LOCALEPAGE),
912 NULL,
913 LocaleDlgProc,
914 (LPARAM)pState);
915 break;
916
917 case STARTPAGE:
918 DialogBoxParamW(hInstance,
919 MAKEINTRESOURCEW(IDD_STARTPAGE),
920 NULL,
921 StartDlgProc,
922 (LPARAM)pState);
923 break;
924
925 default:
926 break;
927 }
928 }
929
930 DeleteObject(pState->ImageInfo.hBitmap);
931}
932
933/* EOF */