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 = GetDC(hwndDlg); 31 HDC hDCLogo = CreateCompatibleDC(NULL); 32 HDC hDCMask = CreateCompatibleDC(NULL); 33 HBITMAP hMask, hLogo, hAlphaLogo = NULL; 34 COLORREF *pBits; 35 INT line, column; 36 37 if (hDC == NULL || hDCLogo == NULL || hDCMask == NULL) 38 goto Cleanup; 39 40 ZeroMemory(pImgInfo, sizeof(*pImgInfo)); 41 ZeroMemory(&bmpi, sizeof(bmpi)); 42 43 hLogo = (HBITMAP)LoadImageW(hInstance, MAKEINTRESOURCEW(IDB_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 44 hMask = (HBITMAP)LoadImageW(hInstance, MAKEINTRESOURCEW(IDB_ROSMASK), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 45 46 if (hLogo != NULL && hMask != NULL) 47 { 48 GetObject(hLogo, sizeof(logoBitmap), &logoBitmap); 49 GetObject(hMask, sizeof(maskBitmap), &maskBitmap); 50 51 if (logoBitmap.bmHeight != maskBitmap.bmHeight || logoBitmap.bmWidth != maskBitmap.bmWidth) 52 goto Cleanup; 53 54 bmpi.bmiHeader.biSize = sizeof(BITMAPINFO); 55 bmpi.bmiHeader.biWidth = logoBitmap.bmWidth; 56 bmpi.bmiHeader.biHeight = logoBitmap.bmHeight; 57 bmpi.bmiHeader.biPlanes = 1; 58 bmpi.bmiHeader.biBitCount = 32; 59 bmpi.bmiHeader.biCompression = BI_RGB; 60 bmpi.bmiHeader.biSizeImage = 4 * logoBitmap.bmWidth * logoBitmap.bmHeight; 61 62 /* Create a premultiplied bitmap */ 63 hAlphaLogo = CreateDIBSection(hDC, &bmpi, DIB_RGB_COLORS, (PVOID*)&pBits, 0, 0); 64 if (!hAlphaLogo) 65 goto Cleanup; 66 67 SelectObject(hDCLogo, hLogo); 68 SelectObject(hDCMask, hMask); 69 70 for (line = logoBitmap.bmHeight - 1; line >= 0; line--) 71 { 72 for (column = 0; column < logoBitmap.bmWidth; column++) 73 { 74 COLORREF alpha = GetPixel(hDCMask, column, line) & 0xFF; 75 COLORREF Color = GetPixel(hDCLogo, column, line); 76 DWORD r, g, b; 77 78 r = GetRValue(Color) * alpha / 255; 79 g = GetGValue(Color) * alpha / 255; 80 b = GetBValue(Color) * alpha / 255; 81 82 *pBits++ = b | (g << 8) | (r << 16) | (alpha << 24); 83 } 84 } 85 86 pImgInfo->hBitmap = hAlphaLogo; 87 pImgInfo->cxSource = logoBitmap.bmWidth; 88 pImgInfo->cySource = logoBitmap.bmHeight; 89 pImgInfo->iBits = logoBitmap.bmBitsPixel; 90 pImgInfo->iPlanes = logoBitmap.bmPlanes; 91 } 92 93 Cleanup: 94 if (hMask != NULL) DeleteObject(hMask); 95 if (hLogo != NULL) DeleteObject(hLogo); 96 if (hDCMask != NULL) DeleteDC(hDCMask); 97 if (hDCLogo != NULL) DeleteDC(hDCLogo); 98 if (hDC != NULL) ReleaseDC(hwndDlg, hDC); 99 } 100 101 102 BOOL 103 IsLiveCD(VOID) 104 { 105 HKEY ControlKey = NULL; 106 LPWSTR SystemStartOptions = NULL; 107 LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */ 108 LONG rc; 109 BOOL ret = FALSE; 110 111 TRACE("IsLiveCD()\n"); 112 113 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 114 REGSTR_PATH_CURRENT_CONTROL_SET, 115 0, 116 KEY_QUERY_VALUE, 117 &ControlKey); 118 if (rc != ERROR_SUCCESS) 119 { 120 WARN("RegOpenKeyEx() failed with error %lu\n", rc); 121 goto cleanup; 122 } 123 124 rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions); 125 if (rc != ERROR_SUCCESS) 126 { 127 WARN("ReadRegSzKey() failed with error %lu\n", rc); 128 goto cleanup; 129 } 130 131 /* Check for CONSOLE switch in SystemStartOptions */ 132 CurrentOption = SystemStartOptions; 133 while (CurrentOption) 134 { 135 NextOption = wcschr(CurrentOption, L' '); 136 if (NextOption) 137 *NextOption = L'\0'; 138 if (_wcsicmp(CurrentOption, L"MININT") == 0) 139 { 140 TRACE("Found 'MININT' boot option\n"); 141 ret = TRUE; 142 goto cleanup; 143 } 144 CurrentOption = NextOption ? NextOption + 1 : NULL; 145 } 146 147 cleanup: 148 if (ControlKey != NULL) 149 RegCloseKey(ControlKey); 150 HeapFree(GetProcessHeap(), 0, SystemStartOptions); 151 152 TRACE("IsLiveCD() returning %d\n", ret); 153 154 return ret; 155 } 156 157 158 static BOOL CALLBACK 159 LocalesEnumProc(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 208 static VOID 209 CreateLanguagesList(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 236 static 237 BOOL 238 GetLayoutName( 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, (LPCTSTR)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 303 static 304 VOID 305 SetKeyboardLayout( 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 328 static 329 VOID 330 SelectKeyboardForLanguage( 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 372 static 373 VOID 374 CreateKeyboardLayoutList( 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 431 static 432 VOID 433 InitializeDefaultUserLocale( 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 550 done: 551 RegCloseKey(hLocaleKey); 552 } 553 554 555 VOID 556 CenterWindow(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 579 static 580 VOID 581 OnDrawItem( 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 616 static 617 INT_PTR 618 CALLBACK 619 LocaleDlgProc( 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 global 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, MAKELONG(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 SetKeyboardLayout(GetDlgItem(hwndDlg, IDC_LAYOUTLIST)); 716 717 pState->NextPage = STARTPAGE; 718 EndDialog(hwndDlg, LOWORD(wParam)); 719 } 720 break; 721 722 case IDCANCEL: 723 if (HIWORD(wParam) == BN_CLICKED) 724 { 725 static WCHAR szMsg[RC_STRING_MAX_SIZE]; 726 INT ret; 727 LoadStringW(GetModuleHandle(NULL), IDS_CANCEL_CONFIRM, szMsg, ARRAYSIZE(szMsg)); 728 ret = MessageBoxW(hwndDlg, szMsg, L"ReactOS LiveCD", MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2); 729 if (ret == IDOK || ret == IDYES) 730 { 731 pState->NextPage = DONE; 732 pState->Run = REBOOT; 733 EndDialog(hwndDlg, LOWORD(wParam)); 734 } 735 } 736 break; 737 738 default: 739 break; 740 } 741 break; 742 743 default: 744 break; 745 } 746 747 return FALSE; 748 } 749 750 751 static 752 INT_PTR 753 CALLBACK 754 StartDlgProc( 755 HWND hwndDlg, 756 UINT uMsg, 757 WPARAM wParam, 758 LPARAM lParam) 759 { 760 PSTATE pState; 761 762 /* Retrieve pointer to the state */ 763 pState = (PSTATE)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 764 765 switch (uMsg) 766 { 767 case WM_INITDIALOG: 768 /* Save pointer to the state */ 769 pState = (PSTATE)lParam; 770 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pState); 771 772 /* Center the dialog window */ 773 CenterWindow(hwndDlg); 774 775 if (pState->Unattend->bEnabled) 776 { 777 // Click on the 'Run' button 778 PostMessageW(hwndDlg, WM_COMMAND, MAKELONG(IDC_RUN, BN_CLICKED), 0L); 779 } 780 781 return FALSE; 782 783 case WM_DRAWITEM: 784 OnDrawItem((LPDRAWITEMSTRUCT)lParam, 785 pState, 786 IDC_STARTLOGO); 787 return TRUE; 788 789 case WM_COMMAND: 790 if (HIWORD(wParam) == BN_CLICKED) 791 { 792 switch (LOWORD(wParam)) 793 { 794 case IDC_RUN: 795 pState->NextPage = DONE; 796 pState->Run = SHELL; 797 EndDialog(hwndDlg, LOWORD(wParam)); 798 break; 799 800 case IDC_INSTALL: 801 pState->NextPage = DONE; 802 pState->Run = INSTALLER; 803 EndDialog(hwndDlg, LOWORD(wParam)); 804 break; 805 806 case IDOK: 807 pState->NextPage = LOCALEPAGE; 808 EndDialog(hwndDlg, LOWORD(wParam)); 809 break; 810 811 case IDCANCEL: 812 if (HIWORD(wParam) == BN_CLICKED) 813 { 814 static WCHAR szMsg[RC_STRING_MAX_SIZE]; 815 INT ret; 816 LoadStringW(GetModuleHandle(NULL), IDS_CANCEL_CONFIRM, szMsg, ARRAYSIZE(szMsg)); 817 ret = MessageBoxW(hwndDlg, szMsg, L"ReactOS LiveCD", MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2); 818 if (ret == IDOK || ret == IDYES) 819 { 820 pState->NextPage = DONE; 821 pState->Run = REBOOT; 822 EndDialog(hwndDlg, LOWORD(wParam)); 823 } 824 } 825 break; 826 827 default: 828 break; 829 } 830 } 831 break; 832 833 default: 834 break; 835 } 836 837 return FALSE; 838 } 839 840 VOID ParseUnattend(LPCWSTR UnattendInf, LIVECD_UNATTEND* pUnattend) 841 { 842 WCHAR Buffer[MAX_PATH]; 843 844 pUnattend->bEnabled = FALSE; 845 846 if (!GetPrivateProfileStringW(L"Unattend", L"Signature", L"", Buffer, _countof(Buffer), UnattendInf)) 847 { 848 ERR("Unable to parse Signature\n"); 849 return; 850 } 851 852 if (_wcsicmp(Buffer, L"$ReactOS$") && _wcsicmp(Buffer, L"$Windows NT$")) 853 { 854 TRACE("Unknown signature: %S\n", Buffer); 855 return; 856 } 857 858 if (!GetPrivateProfileStringW(L"Unattend", L"UnattendSetupEnabled", L"", Buffer, _countof(Buffer), UnattendInf)) 859 { 860 ERR("Unable to parse UnattendSetupEnabled\n"); 861 return; 862 } 863 864 if (_wcsicmp(Buffer, L"yes")) 865 { 866 TRACE("Unattended setup is not enabled\n", Buffer); 867 return; 868 } 869 870 pUnattend->bEnabled = TRUE; 871 pUnattend->LocaleID = 0; 872 873 if (GetPrivateProfileStringW(L"Unattend", L"LocaleID", L"", Buffer, _countof(Buffer), UnattendInf) && Buffer[0]) 874 { 875 pUnattend->LocaleID = wcstol(Buffer, NULL, 16); 876 } 877 } 878 879 VOID 880 RunLiveCD( 881 PSTATE pState) 882 { 883 LIVECD_UNATTEND Unattend = {0}; 884 WCHAR UnattendInf[MAX_PATH]; 885 886 InitLogo(&pState->ImageInfo, NULL); 887 888 GetWindowsDirectoryW(UnattendInf, _countof(UnattendInf)); 889 wcscat(UnattendInf, L"\\unattend.inf"); 890 ParseUnattend(UnattendInf, &Unattend); 891 pState->Unattend = &Unattend; 892 893 while (pState->NextPage != DONE) 894 { 895 switch (pState->NextPage) 896 { 897 case LOCALEPAGE: 898 DialogBoxParamW(hInstance, 899 MAKEINTRESOURCEW(IDD_LOCALEPAGE), 900 NULL, 901 LocaleDlgProc, 902 (LPARAM)pState); 903 break; 904 905 case STARTPAGE: 906 DialogBoxParamW(hInstance, 907 MAKEINTRESOURCEW(IDD_STARTPAGE), 908 NULL, 909 StartDlgProc, 910 (LPARAM)pState); 911 break; 912 913 default: 914 break; 915 } 916 } 917 918 DeleteObject(pState->ImageInfo.hBitmap); 919 } 920 921 /* EOF */ 922