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