Reactos
at master 933 lines 27 kB view raw
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 */