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