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
15 * Taken and adapted from dll/cpl/sysdm/general.c
18 InitLogo(PIMGINFO pImgInfo
, HWND hwndDlg
)
23 HDC hDC
= GetDC(hwndDlg
);
24 HDC hDCLogo
= CreateCompatibleDC(NULL
);
25 HDC hDCMask
= CreateCompatibleDC(NULL
);
26 HBITMAP hMask
, hLogo
, hAlphaLogo
= NULL
;
30 ZeroMemory(pImgInfo
, sizeof(*pImgInfo
));
31 ZeroMemory(&bmpi
, sizeof(bmpi
));
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
);
36 if (hLogo
!= NULL
&& hMask
!= NULL
)
38 GetObject(hLogo
, sizeof(logoBitmap
), &logoBitmap
);
39 GetObject(hMask
, sizeof(maskBitmap
), &maskBitmap
);
41 if (logoBitmap
.bmHeight
!= maskBitmap
.bmHeight
|| logoBitmap
.bmWidth
!= maskBitmap
.bmWidth
)
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
;
52 /* Create a premultiplied bitmap */
53 hAlphaLogo
= CreateDIBSection(hDC
, &bmpi
, DIB_RGB_COLORS
, (PVOID
*)&pBits
, 0, 0);
57 SelectObject(hDCLogo
, hLogo
);
58 SelectObject(hDCMask
, hMask
);
60 for (line
= logoBitmap
.bmHeight
- 1; line
>= 0; line
--)
62 for (column
= 0; column
< logoBitmap
.bmWidth
; column
++)
64 COLORREF alpha
= GetPixel(hDCMask
, column
, line
) & 0xFF;
65 COLORREF Color
= GetPixel(hDCLogo
, column
, line
);
68 r
= GetRValue(Color
) * alpha
/ 255;
69 g
= GetGValue(Color
) * alpha
/ 255;
70 b
= GetBValue(Color
) * alpha
/ 255;
72 *pBits
++ = b
| g
<< 8 | r
<< 16 | alpha
<< 24;
76 pImgInfo
->hBitmap
= hAlphaLogo
;
77 pImgInfo
->cxSource
= logoBitmap
.bmWidth
;
78 pImgInfo
->cySource
= logoBitmap
.bmHeight
;
79 pImgInfo
->iBits
= logoBitmap
.bmBitsPixel
;
80 pImgInfo
->iPlanes
= logoBitmap
.bmPlanes
;
94 HKEY ControlKey
= NULL
;
95 LPWSTR SystemStartOptions
= NULL
;
96 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
100 TRACE("IsLiveCD()\n");
102 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
103 REGSTR_PATH_CURRENT_CONTROL_SET
,
107 if (rc
!= ERROR_SUCCESS
)
109 WARN("RegOpenKeyEx() failed with error %lu\n", rc
);
113 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
114 if (rc
!= ERROR_SUCCESS
)
116 WARN("ReadRegSzKey() failed with error %lu\n", rc
);
120 /* Check for CONSOLE switch in SystemStartOptions */
121 CurrentOption
= SystemStartOptions
;
122 while (CurrentOption
)
124 NextOption
= wcschr(CurrentOption
, L
' ');
127 if (_wcsicmp(CurrentOption
, L
"MININT") == 0)
129 TRACE("Found 'MININT' boot option\n");
133 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
137 if (ControlKey
!= NULL
)
138 RegCloseKey(ControlKey
);
139 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
141 TRACE("IsLiveCD() returning %d\n", ret
);
148 LocalesEnumProc(LPTSTR lpLocale
)
153 BOOL bNoShow
= FALSE
;
155 lcid
= wcstoul(lpLocale
, NULL
, 16);
157 /* Display only languages with installed support */
158 if (!IsValidLocale(lcid
, LCID_INSTALLED
))
161 if (lcid
== MAKELCID(MAKELANGID(LANG_SPANISH
, SUBLANG_SPANISH
), SORT_DEFAULT
) ||
162 lcid
== MAKELCID(MAKELANGID(LANG_SPANISH
, SUBLANG_SPANISH_MODERN
), SORT_DEFAULT
))
166 LoadStringW(hInstance
, IDS_SPAIN
, lang
, ARRAYSIZE(lang
));
176 GetLocaleInfoW(lcid
, LOCALE_SLANGUAGE
, lang
, ARRAYSIZE(lang
));
179 if (bNoShow
== FALSE
)
181 index
= SendMessageW(hList
,
197 CreateLanguagesList(HWND hwnd
)
203 EnumSystemLocalesW(LocalesEnumProc
, LCID_SUPPORTED
);
205 /* Select current locale */
206 /* or should it be System and not user? */
207 GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_SLANGUAGE
, langSel
, ARRAYSIZE(langSel
));
224 WCHAR szBuf
[MAX_PATH
], szDispName
[MAX_PATH
], szIndex
[MAX_PATH
], szPath
[MAX_PATH
];
228 wsprintf(szBuf
, L
"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s", szLCID
);
230 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, (LPCTSTR
)szBuf
, 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
232 dwBufLen
= sizeof(szDispName
);
234 if (RegQueryValueExW(hKey
, L
"Layout Display Name", NULL
, NULL
, (LPBYTE
)szDispName
, &dwBufLen
) == ERROR_SUCCESS
)
236 if (szDispName
[0] == '@')
238 for (i
= 0; i
< wcslen(szDispName
); i
++)
240 if ((szDispName
[i
] == ',') && (szDispName
[i
+ 1] == '-'))
242 for (j
= i
+ 2, k
= 0; j
< wcslen(szDispName
)+1; j
++, k
++)
244 szIndex
[k
] = szDispName
[j
];
246 szDispName
[i
- 1] = '\0';
250 szDispName
[i
] = szDispName
[i
+ 1];
253 if (ExpandEnvironmentStringsW(szDispName
, szPath
, ARRAYSIZE(szPath
)))
255 hLib
= LoadLibraryW(szPath
);
258 if (LoadStringW(hLib
, _wtoi(szIndex
), szPath
, ARRAYSIZE(szPath
)) != 0)
260 wcscpy(szName
, szPath
);
270 dwBufLen
= sizeof(szBuf
);
272 if (RegQueryValueExW(hKey
, L
"Layout Text", NULL
, NULL
, (LPBYTE
)szName
, &dwBufLen
) == ERROR_SUCCESS
)
293 iCurSel
= SendMessageW(hwnd
, CB_GETCURSEL
, 0, 0);
294 if (iCurSel
== CB_ERR
)
297 ulLayoutId
= (ULONG
)SendMessageW(hwnd
, CB_GETITEMDATA
, iCurSel
, 0);
298 if (ulLayoutId
== (ULONG
)CB_ERR
)
301 swprintf(szLayoutId
, L
"%08lx", ulLayoutId
);
303 hKl
= LoadKeyboardLayoutW(szLayoutId
, KLF_ACTIVATE
| KLF_REPLACELANG
| KLF_SETFORPROCESS
);
304 SystemParametersInfoW(SPI_SETDEFAULTINPUTLANG
, 0, &hKl
, SPIF_SENDWININICHANGE
);
310 SelectKeyboardForLanguage(
317 TRACE("LCID: %08lx\n", lcid
);
318 TRACE("LangID: %04lx\n", LANGIDFROMLCID(lcid
));
320 nCount
= SendMessageW(hwnd
, CB_GETCOUNT
, 0, 0);
322 for (i
= 0; i
< nCount
; i
++)
324 LayoutId
= (LCID
)SendMessageW(hwnd
, CB_GETITEMDATA
, i
, 0);
325 TRACE("Layout: %08lx\n", LayoutId
);
327 if (LANGIDFROMLCID(LayoutId
) == LANGIDFROMLCID(lcid
))
329 TRACE("Found 1: %08lx --> %08lx\n", LayoutId
, lcid
);
330 SendMessageW(hwnd
, CB_SETCURSEL
, i
, 0);
335 for (i
= 0; i
< nCount
; i
++)
337 LayoutId
= (LCID
)SendMessageW(hwnd
, CB_GETITEMDATA
, i
, 0);
338 TRACE("Layout: %08lx\n", LayoutId
);
340 if (PRIMARYLANGID(LayoutId
) == PRIMARYLANGID(lcid
))
342 TRACE("Found 2: %08lx --> %08lx\n", LayoutId
, lcid
);
343 SendMessageW(hwnd
, CB_SETCURSEL
, i
, 0);
348 TRACE("No match found!\n");
354 CreateKeyboardLayoutList(
358 WCHAR szLayoutId
[9], szCurrentLayoutId
[9];
359 WCHAR KeyName
[MAX_PATH
];
366 if (!GetKeyboardLayoutNameW(szCurrentLayoutId
))
367 wcscpy(szCurrentLayoutId
, L
"00000409");
369 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
370 L
"System\\CurrentControlSet\\Control\\Keyboard Layouts",
372 KEY_ENUMERATE_SUB_KEYS
,
374 if (lError
!= ERROR_SUCCESS
)
379 dwSize
= ARRAYSIZE(szLayoutId
);
381 lError
= RegEnumKeyExW(hKey
,
389 if (lError
!= ERROR_SUCCESS
)
392 GetLayoutName(szLayoutId
, KeyName
);
394 iIndex
= (INT
)SendMessageW(hItemsList
, CB_ADDSTRING
, 0, (LPARAM
)KeyName
);
396 ulLayoutId
= wcstoul(szLayoutId
, NULL
, 16);
397 SendMessageW(hItemsList
, CB_SETITEMDATA
, iIndex
, (LPARAM
)ulLayoutId
);
399 if (wcscmp(szLayoutId
, szCurrentLayoutId
) == 0)
401 SendMessageW(hItemsList
, CB_SETCURSEL
, (WPARAM
)iIndex
, (LPARAM
)0);
413 InitializeDefaultUserLocale(
424 struct {LCTYPE LCType
; PWSTR pValue
;} LocaleData
[] = {
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"},
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"},
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"},
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"},
467 {LOCALE_SCOUNTRY
, L
"sCountry"},
468 {LOCALE_SLANGUAGE
, L
"sLanguage"},
469 {LOCALE_ICOUNTRY
, L
"iCountry"},
472 ret
= RegOpenKeyExW(HKEY_USERS
,
473 L
".DEFAULT\\Control Panel\\International",
475 KEY_READ
| KEY_WRITE
,
477 if (ret
!= ERROR_SUCCESS
)
482 if (pNewLcid
== NULL
)
484 dwSize
= 9 * sizeof(WCHAR
);
485 ret
= RegQueryValueExW(hLocaleKey
,
491 if (ret
!= ERROR_SUCCESS
)
494 lcid
= (LCID
)wcstoul(szBuffer
, &ptr
, 16);
502 swprintf(szBuffer
, L
"%08lx", lcid
);
503 RegSetValueExW(hLocaleKey
,
508 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
512 while (LocaleData
[i
].pValue
!= NULL
)
514 if (GetLocaleInfoW(lcid
,
515 LocaleData
[i
].LCType
| LOCALE_NOUSEROVERRIDE
,
517 ARRAYSIZE(szBuffer
)))
519 RegSetValueExW(hLocaleKey
,
520 LocaleData
[i
].pValue
,
524 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
531 RegCloseKey(hLocaleKey
);
536 CenterWindow(HWND hWnd
)
542 hWndParent
= GetParent(hWnd
);
543 if (hWndParent
== NULL
)
544 hWndParent
= GetDesktopWindow();
546 GetWindowRect(hWndParent
, &rcParent
);
547 GetWindowRect(hWnd
, &rcWindow
);
551 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
552 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
562 LPDRAWITEMSTRUCT lpDrawItem
,
569 if (lpDrawItem
->CtlID
== uCtlID
)
571 /* Position image in centre of dialog */
572 left
= (lpDrawItem
->rcItem
.right
- pState
->ImageInfo
.cxSource
) / 2;
574 hdcMem
= CreateCompatibleDC(lpDrawItem
->hDC
);
577 static BLENDFUNCTION BlendFunc
= {AC_SRC_OVER
, 0, 255, AC_SRC_ALPHA
};
579 SelectObject(hdcMem
, pState
->ImageInfo
.hBitmap
);
580 GdiAlphaBlend(lpDrawItem
->hDC
,
582 lpDrawItem
->rcItem
.top
,
583 pState
->ImageInfo
.cxSource
,
584 pState
->ImageInfo
.cySource
,
587 pState
->ImageInfo
.cxSource
,
588 pState
->ImageInfo
.cySource
,
607 /* Retrieve pointer to the state */
608 pState
= (PSTATE
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
613 /* Save pointer to the global state */
614 pState
= (PSTATE
)lParam
;
615 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)pState
);
617 /* Center the dialog window */
618 CenterWindow(hwndDlg
);
620 /* Fill the language and keyboard layout lists */
621 CreateLanguagesList(GetDlgItem(hwndDlg
, IDC_LANGUAGELIST
));
622 CreateKeyboardLayoutList(GetDlgItem(hwndDlg
, IDC_LAYOUTLIST
));
626 OnDrawItem((LPDRAWITEMSTRUCT
)lParam
,
632 switch (LOWORD(wParam
))
634 case IDC_LANGUAGELIST
:
635 if (HIWORD(wParam
) == CBN_SELCHANGE
)
640 iCurSel
= SendDlgItemMessageW(hwndDlg
,
645 if (iCurSel
== CB_ERR
)
648 NewLcid
= SendDlgItemMessageW(hwndDlg
,
653 if (NewLcid
== (LCID
)CB_ERR
)
656 TRACE("LCID: 0x%08lx\n", NewLcid
);
657 SelectKeyboardForLanguage(GetDlgItem(hwndDlg
, IDC_LAYOUTLIST
),
663 if (HIWORD(wParam
) == BN_CLICKED
)
668 iCurSel
= SendDlgItemMessageW(hwndDlg
,
673 if (iCurSel
== CB_ERR
)
676 NewLcid
= SendDlgItemMessageW(hwndDlg
,
681 if (NewLcid
== (LCID
)CB_ERR
)
684 /* Set the locale for the current thread */
685 NtSetDefaultLocale(TRUE
, NewLcid
);
687 /* Store the locale settings in the registry */
688 InitializeDefaultUserLocale(&NewLcid
);
690 SetKeyboardLayout(GetDlgItem(hwndDlg
, IDC_LAYOUTLIST
));
692 pState
->NextPage
= STARTPAGE
;
693 EndDialog(hwndDlg
, LOWORD(wParam
));
698 if (HIWORD(wParam
) == BN_CLICKED
)
700 static WCHAR szMsg
[RC_STRING_MAX_SIZE
];
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
)
706 pState
->NextPage
= DONE
;
707 pState
->Run
= REBOOT
;
708 EndDialog(hwndDlg
, LOWORD(wParam
));
737 /* Retrieve pointer to the state */
738 pState
= (PSTATE
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
743 /* Save pointer to the state */
744 pState
= (PSTATE
)lParam
;
745 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)pState
);
747 /* Center the dialog window */
748 CenterWindow(hwndDlg
);
752 OnDrawItem((LPDRAWITEMSTRUCT
)lParam
,
758 if (HIWORD(wParam
) == BN_CLICKED
)
760 switch (LOWORD(wParam
))
763 pState
->NextPage
= DONE
;
765 EndDialog(hwndDlg
, LOWORD(wParam
));
769 pState
->NextPage
= DONE
;
770 pState
->Run
= INSTALLER
;
771 EndDialog(hwndDlg
, LOWORD(wParam
));
775 pState
->NextPage
= LOCALEPAGE
;
776 EndDialog(hwndDlg
, LOWORD(wParam
));
780 if (HIWORD(wParam
) == BN_CLICKED
)
782 static WCHAR szMsg
[RC_STRING_MAX_SIZE
];
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
)
788 pState
->NextPage
= DONE
;
789 pState
->Run
= REBOOT
;
790 EndDialog(hwndDlg
, LOWORD(wParam
));
813 InitLogo(&pState
->ImageInfo
, NULL
);
815 while (pState
->NextPage
!= DONE
)
817 switch (pState
->NextPage
)
820 DialogBoxParamW(hInstance
,
821 MAKEINTRESOURCEW(IDD_LOCALEPAGE
),
828 DialogBoxParamW(hInstance
,
829 MAKEINTRESOURCEW(IDD_STARTPAGE
),
840 DeleteObject(pState
->ImageInfo
.hBitmap
);