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 /* Set UI language for this thread */ 719 SetThreadLocale(NewLcid); 720 721 SetKeyboardLayout(GetDlgItem(hwndDlg, IDC_LAYOUTLIST)); 722 723 pState->NextPage = STARTPAGE; 724 EndDialog(hwndDlg, LOWORD(wParam)); 725 } 726 break; 727 728 case IDCANCEL: 729 if (HIWORD(wParam) == BN_CLICKED) 730 { 731 static WCHAR szMsg[RC_STRING_MAX_SIZE]; 732 INT ret; 733 LoadStringW(GetModuleHandle(NULL), IDS_CANCEL_CONFIRM, szMsg, ARRAYSIZE(szMsg)); 734 ret = MessageBoxW(hwndDlg, szMsg, L"ReactOS LiveCD", MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2); 735 if (ret == IDOK || ret == IDYES) 736 { 737 pState->NextPage = DONE; 738 pState->Run = REBOOT; 739 EndDialog(hwndDlg, LOWORD(wParam)); 740 } 741 } 742 break; 743 744 default: 745 break; 746 } 747 break; 748 749 default: 750 break; 751 } 752 753 return FALSE; 754 } 755 756 757 static 758 INT_PTR 759 CALLBACK 760 StartDlgProc( 761 HWND hwndDlg, 762 UINT uMsg, 763 WPARAM wParam, 764 LPARAM lParam) 765 { 766 PSTATE pState; 767 768 /* Retrieve pointer to the state */ 769 pState = (PSTATE)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 770 771 switch (uMsg) 772 { 773 case WM_INITDIALOG: 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 if (pState->Unattend->bEnabled) 782 { 783 // Click on the 'Run' button 784 PostMessageW(hwndDlg, WM_COMMAND, MAKELONG(IDC_RUN, BN_CLICKED), 0L); 785 } 786 787 return FALSE; 788 789 case WM_DRAWITEM: 790 OnDrawItem((LPDRAWITEMSTRUCT)lParam, 791 pState, 792 IDC_STARTLOGO); 793 return TRUE; 794 795 case WM_COMMAND: 796 if (HIWORD(wParam) == BN_CLICKED) 797 { 798 switch (LOWORD(wParam)) 799 { 800 case IDC_RUN: 801 pState->NextPage = DONE; 802 pState->Run = SHELL; 803 EndDialog(hwndDlg, LOWORD(wParam)); 804 break; 805 806 case IDC_INSTALL: 807 pState->NextPage = DONE; 808 pState->Run = INSTALLER; 809 EndDialog(hwndDlg, LOWORD(wParam)); 810 break; 811 812 case IDOK: 813 pState->NextPage = LOCALEPAGE; 814 EndDialog(hwndDlg, LOWORD(wParam)); 815 break; 816 817 case IDCANCEL: 818 if (HIWORD(wParam) == BN_CLICKED) 819 { 820 static WCHAR szMsg[RC_STRING_MAX_SIZE]; 821 INT ret; 822 LoadStringW(GetModuleHandle(NULL), IDS_CANCEL_CONFIRM, szMsg, ARRAYSIZE(szMsg)); 823 ret = MessageBoxW(hwndDlg, szMsg, L"ReactOS LiveCD", MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2); 824 if (ret == IDOK || ret == IDYES) 825 { 826 pState->NextPage = DONE; 827 pState->Run = REBOOT; 828 EndDialog(hwndDlg, LOWORD(wParam)); 829 } 830 } 831 break; 832 833 default: 834 break; 835 } 836 } 837 break; 838 839 default: 840 break; 841 } 842 843 return FALSE; 844 } 845 846 VOID ParseUnattend(LPCWSTR UnattendInf, LIVECD_UNATTEND* pUnattend) 847 { 848 WCHAR Buffer[MAX_PATH]; 849 850 pUnattend->bEnabled = FALSE; 851 852 if (!GetPrivateProfileStringW(L"Unattend", L"Signature", L"", Buffer, _countof(Buffer), UnattendInf)) 853 { 854 ERR("Unable to parse Signature\n"); 855 return; 856 } 857 858 if (_wcsicmp(Buffer, L"$ReactOS$") && _wcsicmp(Buffer, L"$Windows NT$")) 859 { 860 TRACE("Unknown signature: %S\n", Buffer); 861 return; 862 } 863 864 if (!GetPrivateProfileStringW(L"Unattend", L"UnattendSetupEnabled", L"", Buffer, _countof(Buffer), UnattendInf)) 865 { 866 ERR("Unable to parse UnattendSetupEnabled\n"); 867 return; 868 } 869 870 if (_wcsicmp(Buffer, L"yes")) 871 { 872 TRACE("Unattended setup is not enabled\n", Buffer); 873 return; 874 } 875 876 pUnattend->bEnabled = TRUE; 877 pUnattend->LocaleID = 0; 878 879 if (GetPrivateProfileStringW(L"Unattend", L"LocaleID", L"", Buffer, _countof(Buffer), UnattendInf) && Buffer[0]) 880 { 881 pUnattend->LocaleID = wcstol(Buffer, NULL, 16); 882 } 883 } 884 885 VOID 886 RunLiveCD( 887 PSTATE pState) 888 { 889 LIVECD_UNATTEND Unattend = {0}; 890 WCHAR UnattendInf[MAX_PATH]; 891 892 InitLogo(&pState->ImageInfo, NULL); 893 894 GetWindowsDirectoryW(UnattendInf, _countof(UnattendInf)); 895 wcscat(UnattendInf, L"\\unattend.inf"); 896 ParseUnattend(UnattendInf, &Unattend); 897 pState->Unattend = &Unattend; 898 899 while (pState->NextPage != DONE) 900 { 901 switch (pState->NextPage) 902 { 903 case LOCALEPAGE: 904 DialogBoxParamW(hInstance, 905 MAKEINTRESOURCEW(IDD_LOCALEPAGE), 906 NULL, 907 LocaleDlgProc, 908 (LPARAM)pState); 909 break; 910 911 case STARTPAGE: 912 DialogBoxParamW(hInstance, 913 MAKEINTRESOURCEW(IDD_STARTPAGE), 914 NULL, 915 StartDlgProc, 916 (LPARAM)pState); 917 break; 918 919 default: 920 break; 921 } 922 } 923 924 DeleteObject(pState->ImageInfo.hBitmap); 925 } 926 927 /* EOF */ 928