1 /* 2 * ReactOS applications 3 * Copyright (C) 2001, 2002 ReactOS Team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 /* 20 * COPYRIGHT: See COPYING in the top level directory 21 * PROJECT: ReactOS Userinit Logon Application 22 * FILE: base/system/userinit/userinit.c 23 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net) 24 * Herv� Poussineau (hpoussin@reactos.org) 25 */ 26 27 #include "userinit.h" 28 29 #define CMP_MAGIC 0x01234567 30 31 /* GLOBALS ******************************************************************/ 32 33 HINSTANCE hInstance; 34 35 36 /* FUNCTIONS ****************************************************************/ 37 38 LONG 39 ReadRegSzKey( 40 IN HKEY hKey, 41 IN LPCWSTR pszKey, 42 OUT LPWSTR *pValue) 43 { 44 LONG rc; 45 DWORD dwType; 46 DWORD cbData = 0; 47 LPWSTR Value; 48 49 TRACE("(%p, %s, %p)\n", hKey, debugstr_w(pszKey), pValue); 50 51 rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData); 52 if (rc != ERROR_SUCCESS) 53 { 54 WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(pszKey), rc); 55 return rc; 56 } 57 if (dwType != REG_SZ) 58 { 59 WARN("Wrong registry data type (%u vs %u)\n", dwType, REG_SZ); 60 return ERROR_FILE_NOT_FOUND; 61 } 62 Value = (WCHAR*) HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR)); 63 if (!Value) 64 { 65 WARN("No memory\n"); 66 return ERROR_NOT_ENOUGH_MEMORY; 67 } 68 rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData); 69 if (rc != ERROR_SUCCESS) 70 { 71 WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(pszKey), rc); 72 HeapFree(GetProcessHeap(), 0, Value); 73 return rc; 74 } 75 /* NULL-terminate the string */ 76 Value[cbData / sizeof(WCHAR)] = L'\0'; 77 78 *pValue = Value; 79 return ERROR_SUCCESS; 80 } 81 82 static BOOL 83 IsConsoleShell(VOID) 84 { 85 HKEY ControlKey = NULL; 86 LPWSTR SystemStartOptions = NULL; 87 LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */ 88 LONG rc; 89 BOOL ret = FALSE; 90 91 TRACE("()\n"); 92 93 rc = RegOpenKeyEx( 94 HKEY_LOCAL_MACHINE, 95 REGSTR_PATH_CURRENT_CONTROL_SET, 96 0, 97 KEY_QUERY_VALUE, 98 &ControlKey); 99 if (rc != ERROR_SUCCESS) 100 { 101 WARN("RegOpenKeyEx() failed with error %lu\n", rc); 102 goto cleanup; 103 } 104 105 rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions); 106 if (rc != ERROR_SUCCESS) 107 { 108 WARN("ReadRegSzKey() failed with error %lu\n", rc); 109 goto cleanup; 110 } 111 112 /* Check for CONSOLE switch in SystemStartOptions */ 113 CurrentOption = SystemStartOptions; 114 while (CurrentOption) 115 { 116 NextOption = wcschr(CurrentOption, L' '); 117 if (NextOption) 118 *NextOption = L'\0'; 119 if (_wcsicmp(CurrentOption, L"CONSOLE") == 0) 120 { 121 TRACE("Found 'CONSOLE' boot option\n"); 122 ret = TRUE; 123 goto cleanup; 124 } 125 CurrentOption = NextOption ? NextOption + 1 : NULL; 126 } 127 128 cleanup: 129 if (ControlKey != NULL) 130 RegCloseKey(ControlKey); 131 HeapFree(GetProcessHeap(), 0, SystemStartOptions); 132 TRACE("IsConsoleShell() returning %d\n", ret); 133 return ret; 134 } 135 136 static BOOL 137 GetShell( 138 OUT WCHAR *CommandLine, /* must be at least MAX_PATH long */ 139 IN HKEY hRootKey) 140 { 141 HKEY hKey; 142 DWORD Type, Size; 143 WCHAR Shell[MAX_PATH]; 144 BOOL ConsoleShell = IsConsoleShell(); 145 LONG rc; 146 147 TRACE("(%p, %p)\n", CommandLine, hRootKey); 148 149 rc = RegOpenKeyExW(hRootKey, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 150 0, KEY_QUERY_VALUE, &hKey); 151 if (rc != ERROR_SUCCESS) 152 { 153 WARN("RegOpenKeyEx() failed with error %lu\n", rc); 154 return FALSE; 155 } 156 157 Size = sizeof(Shell); 158 rc = RegQueryValueExW(hKey, 159 ConsoleShell ? L"ConsoleShell" : L"Shell", 160 NULL, 161 &Type, 162 (LPBYTE)Shell, 163 &Size); 164 RegCloseKey(hKey); 165 166 if (rc != ERROR_SUCCESS) 167 { 168 WARN("RegQueryValueEx() failed with error %lu\n", rc); 169 return FALSE; 170 } 171 172 if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ)) 173 { 174 TRACE("Found command line %s\n", debugstr_w(Shell)); 175 wcscpy(CommandLine, Shell); 176 return TRUE; 177 } 178 else 179 { 180 WARN("Wrong type %lu (expected %u or %u)\n", Type, REG_SZ, REG_EXPAND_SZ); 181 return FALSE; 182 } 183 } 184 185 static BOOL 186 StartProcess( 187 IN LPCWSTR CommandLine) 188 { 189 STARTUPINFO si; 190 PROCESS_INFORMATION pi; 191 WCHAR ExpandedCmdLine[MAX_PATH]; 192 193 TRACE("(%s)\n", debugstr_w(CommandLine)); 194 195 ExpandEnvironmentStringsW(CommandLine, ExpandedCmdLine, ARRAYSIZE(ExpandedCmdLine)); 196 197 ZeroMemory(&si, sizeof(si)); 198 si.cb = sizeof(si); 199 si.dwFlags = STARTF_USESHOWWINDOW; 200 si.wShowWindow = SW_SHOWNORMAL; 201 ZeroMemory(&pi, sizeof(pi)); 202 203 if (!CreateProcessW(NULL, 204 ExpandedCmdLine, 205 NULL, 206 NULL, 207 FALSE, 208 NORMAL_PRIORITY_CLASS, 209 NULL, 210 NULL, 211 &si, 212 &pi)) 213 { 214 WARN("CreateProcessW() failed with error %lu\n", GetLastError()); 215 return FALSE; 216 } 217 218 CloseHandle(pi.hProcess); 219 CloseHandle(pi.hThread); 220 return TRUE; 221 } 222 223 static BOOL 224 StartShell(VOID) 225 { 226 WCHAR Shell[MAX_PATH]; 227 WCHAR szMsg[RC_STRING_MAX_SIZE]; 228 DWORD Type, Size; 229 DWORD Value = 0; 230 LONG rc; 231 HKEY hKey; 232 233 TRACE("()\n"); 234 235 /* Safe Mode shell run */ 236 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 237 L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Option", 238 0, KEY_QUERY_VALUE, &hKey); 239 if (rc == ERROR_SUCCESS) 240 { 241 Size = sizeof(Value); 242 rc = RegQueryValueExW(hKey, L"UseAlternateShell", NULL, 243 &Type, (LPBYTE)&Value, &Size); 244 RegCloseKey(hKey); 245 246 if (rc == ERROR_SUCCESS) 247 { 248 if (Type == REG_DWORD) 249 { 250 if (Value) 251 { 252 /* Safe Mode Alternate Shell required */ 253 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 254 L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot", 255 0, KEY_READ, &hKey); 256 if (rc == ERROR_SUCCESS) 257 { 258 Size = sizeof(Shell); 259 rc = RegQueryValueExW(hKey, L"AlternateShell", NULL, 260 &Type, (LPBYTE)Shell, &Size); 261 RegCloseKey(hKey); 262 263 if (rc == ERROR_SUCCESS) 264 { 265 if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ)) 266 { 267 TRACE("Key located - %s\n", debugstr_w(Shell)); 268 269 /* Try to run alternate shell */ 270 if (StartProcess(Shell)) 271 { 272 TRACE("Alternate shell started (Safe Mode)\n"); 273 return TRUE; 274 } 275 } 276 else 277 { 278 WARN("Wrong type %lu (expected %u or %u)\n", 279 Type, REG_SZ, REG_EXPAND_SZ); 280 } 281 } 282 else 283 { 284 WARN("Alternate shell in Safe Mode required but not specified."); 285 } 286 } 287 } 288 } 289 else 290 { 291 WARN("Wrong type %lu (expected %u)\n", Type, REG_DWORD); 292 } 293 } 294 } 295 296 /* Try to run shell in user key */ 297 if (GetShell(Shell, HKEY_CURRENT_USER) && StartProcess(Shell)) 298 { 299 TRACE("Started shell from HKEY_CURRENT_USER\n"); 300 return TRUE; 301 } 302 303 /* Try to run shell in local machine key */ 304 if (GetShell(Shell, HKEY_LOCAL_MACHINE) && StartProcess(Shell)) 305 { 306 TRACE("Started shell from HKEY_LOCAL_MACHINE\n"); 307 return TRUE; 308 } 309 310 /* Try default shell */ 311 if (IsConsoleShell()) 312 { 313 *Shell = UNICODE_NULL; 314 if (GetSystemDirectoryW(Shell, ARRAYSIZE(Shell) - 8)) 315 StringCchCatW(Shell, ARRAYSIZE(Shell), L"\\"); 316 StringCchCatW(Shell, ARRAYSIZE(Shell), L"cmd.exe"); 317 } 318 else 319 { 320 *Shell = UNICODE_NULL; 321 if (GetSystemWindowsDirectoryW(Shell, ARRAYSIZE(Shell) - 13)) 322 StringCchCatW(Shell, ARRAYSIZE(Shell), L"\\"); 323 StringCchCatW(Shell, ARRAYSIZE(Shell), L"explorer.exe"); 324 } 325 326 if (!StartProcess(Shell)) 327 { 328 WARN("Failed to start default shell '%s'\n", debugstr_w(Shell)); 329 LoadStringW(GetModuleHandle(NULL), IDS_SHELL_FAIL, szMsg, ARRAYSIZE(szMsg)); 330 MessageBoxW(NULL, szMsg, NULL, MB_OK); 331 return FALSE; 332 } 333 return TRUE; 334 } 335 336 const WCHAR g_RegColorNames[][32] = { 337 L"Scrollbar", /* 00 = COLOR_SCROLLBAR */ 338 L"Background", /* 01 = COLOR_DESKTOP */ 339 L"ActiveTitle", /* 02 = COLOR_ACTIVECAPTION */ 340 L"InactiveTitle", /* 03 = COLOR_INACTIVECAPTION */ 341 L"Menu", /* 04 = COLOR_MENU */ 342 L"Window", /* 05 = COLOR_WINDOW */ 343 L"WindowFrame", /* 06 = COLOR_WINDOWFRAME */ 344 L"MenuText", /* 07 = COLOR_MENUTEXT */ 345 L"WindowText", /* 08 = COLOR_WINDOWTEXT */ 346 L"TitleText", /* 09 = COLOR_CAPTIONTEXT */ 347 L"ActiveBorder", /* 10 = COLOR_ACTIVEBORDER */ 348 L"InactiveBorder", /* 11 = COLOR_INACTIVEBORDER */ 349 L"AppWorkSpace", /* 12 = COLOR_APPWORKSPACE */ 350 L"Hilight", /* 13 = COLOR_HIGHLIGHT */ 351 L"HilightText", /* 14 = COLOR_HIGHLIGHTTEXT */ 352 L"ButtonFace", /* 15 = COLOR_BTNFACE */ 353 L"ButtonShadow", /* 16 = COLOR_BTNSHADOW */ 354 L"GrayText", /* 17 = COLOR_GRAYTEXT */ 355 L"ButtonText", /* 18 = COLOR_BTNTEXT */ 356 L"InactiveTitleText", /* 19 = COLOR_INACTIVECAPTIONTEXT */ 357 L"ButtonHilight", /* 20 = COLOR_BTNHIGHLIGHT */ 358 L"ButtonDkShadow", /* 21 = COLOR_3DDKSHADOW */ 359 L"ButtonLight", /* 22 = COLOR_3DLIGHT */ 360 L"InfoText", /* 23 = COLOR_INFOTEXT */ 361 L"InfoWindow", /* 24 = COLOR_INFOBK */ 362 L"ButtonAlternateFace", /* 25 = COLOR_ALTERNATEBTNFACE */ 363 L"HotTrackingColor", /* 26 = COLOR_HOTLIGHT */ 364 L"GradientActiveTitle", /* 27 = COLOR_GRADIENTACTIVECAPTION */ 365 L"GradientInactiveTitle", /* 28 = COLOR_GRADIENTINACTIVECAPTION */ 366 L"MenuHilight", /* 29 = COLOR_MENUHILIGHT */ 367 L"MenuBar" /* 30 = COLOR_MENUBAR */ 368 }; 369 370 static COLORREF 371 StrToColorref( 372 IN LPWSTR lpszCol) 373 { 374 BYTE rgb[3]; 375 376 TRACE("(%s)\n", debugstr_w(lpszCol)); 377 378 rgb[0] = (BYTE)wcstoul(lpszCol, &lpszCol, 10); 379 rgb[1] = (BYTE)wcstoul(lpszCol, &lpszCol, 10); 380 rgb[2] = (BYTE)wcstoul(lpszCol, &lpszCol, 10); 381 return RGB(rgb[0], rgb[1], rgb[2]); 382 } 383 384 static VOID 385 SetUserSysColors(VOID) 386 { 387 HKEY hKey; 388 INT i; 389 WCHAR szColor[25]; 390 DWORD Type, Size; 391 COLORREF crColor; 392 LONG rc; 393 394 TRACE("()\n"); 395 396 rc = RegOpenKeyExW(HKEY_CURRENT_USER, REGSTR_PATH_COLORS, 397 0, KEY_QUERY_VALUE, &hKey); 398 if (rc != ERROR_SUCCESS) 399 { 400 WARN("RegOpenKeyEx() failed with error %lu\n", rc); 401 return; 402 } 403 404 for (i = 0; i < ARRAYSIZE(g_RegColorNames); i++) 405 { 406 Size = sizeof(szColor); 407 rc = RegQueryValueExW(hKey, g_RegColorNames[i], NULL, &Type, 408 (LPBYTE)szColor, &Size); 409 if (rc == ERROR_SUCCESS && Type == REG_SZ) 410 { 411 crColor = StrToColorref(szColor); 412 SetSysColors(1, &i, &crColor); 413 } 414 else 415 { 416 WARN("RegQueryValueEx(%s) failed with error %lu\n", 417 debugstr_w(g_RegColorNames[i]), rc); 418 } 419 } 420 421 RegCloseKey(hKey); 422 } 423 424 static VOID 425 SetUserWallpaper(VOID) 426 { 427 HKEY hKey; 428 DWORD Type, Size; 429 WCHAR szWallpaper[MAX_PATH + 1]; 430 LONG rc; 431 432 TRACE("()\n"); 433 434 rc = RegOpenKeyExW(HKEY_CURRENT_USER, REGSTR_PATH_DESKTOP, 435 0, KEY_QUERY_VALUE, &hKey); 436 if (rc != ERROR_SUCCESS) 437 { 438 WARN("RegOpenKeyEx() failed with error %lu\n", rc); 439 return; 440 } 441 442 Size = sizeof(szWallpaper); 443 rc = RegQueryValueExW(hKey, 444 L"Wallpaper", 445 NULL, 446 &Type, 447 (LPBYTE)szWallpaper, 448 &Size); 449 RegCloseKey(hKey); 450 451 if (rc == ERROR_SUCCESS && Type == REG_SZ) 452 { 453 ExpandEnvironmentStringsW(szWallpaper, szWallpaper, ARRAYSIZE(szWallpaper)); 454 TRACE("Using wallpaper %s\n", debugstr_w(szWallpaper)); 455 456 /* Load and change the wallpaper */ 457 SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, szWallpaper, SPIF_SENDCHANGE); 458 } 459 else 460 { 461 /* Remove the wallpaper */ 462 TRACE("No wallpaper set in registry (error %lu)\n", rc); 463 SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE); 464 } 465 } 466 467 static VOID 468 SetUserSettings(VOID) 469 { 470 TRACE("()\n"); 471 472 UpdatePerUserSystemParameters(1, TRUE); 473 SetUserSysColors(); 474 SetUserWallpaper(); 475 } 476 477 typedef DWORD (WINAPI *PCMP_REPORT_LOGON)(DWORD, DWORD); 478 479 static VOID 480 NotifyLogon(VOID) 481 { 482 HINSTANCE hModule; 483 PCMP_REPORT_LOGON CMP_Report_LogOn; 484 485 TRACE("()\n"); 486 487 hModule = LoadLibraryW(L"setupapi.dll"); 488 if (!hModule) 489 { 490 WARN("LoadLibrary() failed with error %lu\n", GetLastError()); 491 return; 492 } 493 494 CMP_Report_LogOn = (PCMP_REPORT_LOGON)GetProcAddress(hModule, "CMP_Report_LogOn"); 495 if (CMP_Report_LogOn) 496 CMP_Report_LogOn(CMP_MAGIC, GetCurrentProcessId()); 497 else 498 WARN("GetProcAddress() failed\n"); 499 500 FreeLibrary(hModule); 501 } 502 503 static BOOL 504 StartInstaller(IN LPCTSTR lpInstallerName) 505 { 506 SYSTEM_INFO SystemInfo; 507 SIZE_T cchInstallerNameLen; 508 PWSTR ptr; 509 DWORD dwAttribs; 510 WCHAR Installer[MAX_PATH]; 511 WCHAR szMsg[RC_STRING_MAX_SIZE]; 512 513 cchInstallerNameLen = wcslen(lpInstallerName); 514 if (ARRAYSIZE(Installer) < cchInstallerNameLen) 515 { 516 /* The buffer is not large enough to contain the installer file name */ 517 return FALSE; 518 } 519 520 /* 521 * First, try to find the installer using the default drive, under 522 * the directory whose name corresponds to the currently-running 523 * CPU architecture. 524 */ 525 GetSystemInfo(&SystemInfo); 526 527 *Installer = UNICODE_NULL; 528 /* Alternatively one can use SharedUserData->NtSystemRoot */ 529 GetSystemWindowsDirectoryW(Installer, ARRAYSIZE(Installer) - cchInstallerNameLen - 1); 530 ptr = wcschr(Installer, L'\\'); 531 if (ptr) 532 *++ptr = UNICODE_NULL; 533 else 534 *Installer = UNICODE_NULL; 535 536 /* Append the corresponding CPU architecture */ 537 switch (SystemInfo.wProcessorArchitecture) 538 { 539 case PROCESSOR_ARCHITECTURE_INTEL: 540 StringCchCatW(Installer, ARRAYSIZE(Installer), L"I386"); 541 break; 542 543 case PROCESSOR_ARCHITECTURE_MIPS: 544 StringCchCatW(Installer, ARRAYSIZE(Installer), L"MIPS"); 545 break; 546 547 case PROCESSOR_ARCHITECTURE_ALPHA: 548 StringCchCatW(Installer, ARRAYSIZE(Installer), L"ALPHA"); 549 break; 550 551 case PROCESSOR_ARCHITECTURE_PPC: 552 StringCchCatW(Installer, ARRAYSIZE(Installer), L"PPC"); 553 break; 554 555 case PROCESSOR_ARCHITECTURE_SHX: 556 StringCchCatW(Installer, ARRAYSIZE(Installer), L"SHX"); 557 break; 558 559 case PROCESSOR_ARCHITECTURE_ARM: 560 StringCchCatW(Installer, ARRAYSIZE(Installer), L"ARM"); 561 break; 562 563 case PROCESSOR_ARCHITECTURE_IA64: 564 StringCchCatW(Installer, ARRAYSIZE(Installer), L"IA64"); 565 break; 566 567 case PROCESSOR_ARCHITECTURE_ALPHA64: 568 StringCchCatW(Installer, ARRAYSIZE(Installer), L"ALPHA64"); 569 break; 570 571 case PROCESSOR_ARCHITECTURE_AMD64: 572 StringCchCatW(Installer, ARRAYSIZE(Installer), L"AMD64"); 573 break; 574 575 // case PROCESSOR_ARCHITECTURE_MSIL: /* .NET CPU-independent code */ 576 case PROCESSOR_ARCHITECTURE_UNKNOWN: 577 default: 578 WARN("Unknown processor architecture %lu\n", SystemInfo.wProcessorArchitecture); 579 SystemInfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_UNKNOWN; 580 break; 581 } 582 583 if (SystemInfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_UNKNOWN) 584 StringCchCatW(Installer, ARRAYSIZE(Installer), L"\\"); 585 StringCchCatW(Installer, ARRAYSIZE(Installer), lpInstallerName); 586 587 dwAttribs = GetFileAttributesW(Installer); 588 if ((dwAttribs != INVALID_FILE_ATTRIBUTES) && 589 !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY)) 590 { 591 /* We have found the installer */ 592 if (StartProcess(Installer)) 593 return TRUE; 594 } 595 596 ERR("Failed to start the installer '%s', trying alternative.\n", debugstr_w(Installer)); 597 598 /* 599 * We failed. Try to find the installer from either the current 600 * ReactOS installation directory, or from our current directory. 601 */ 602 *Installer = UNICODE_NULL; 603 /* Alternatively one can use SharedUserData->NtSystemRoot */ 604 if (GetSystemWindowsDirectoryW(Installer, ARRAYSIZE(Installer) - cchInstallerNameLen - 1)) 605 StringCchCatW(Installer, ARRAYSIZE(Installer), L"\\"); 606 StringCchCatW(Installer, ARRAYSIZE(Installer), lpInstallerName); 607 608 dwAttribs = GetFileAttributesW(Installer); 609 if ((dwAttribs != INVALID_FILE_ATTRIBUTES) && 610 !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY)) 611 { 612 /* We have found the installer */ 613 if (StartProcess(Installer)) 614 return TRUE; 615 } 616 617 /* We failed. Display an error message and quit. */ 618 ERR("Failed to start the installer '%s'.\n", debugstr_w(Installer)); 619 LoadStringW(GetModuleHandle(NULL), IDS_INSTALLER_FAIL, szMsg, ARRAYSIZE(szMsg)); 620 MessageBoxW(NULL, szMsg, NULL, MB_OK); 621 return FALSE; 622 } 623 624 /* Used to get the shutdown privilege */ 625 static BOOL 626 EnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege) 627 { 628 BOOL Success; 629 HANDLE hToken; 630 TOKEN_PRIVILEGES tp; 631 632 Success = OpenProcessToken(GetCurrentProcess(), 633 TOKEN_ADJUST_PRIVILEGES, 634 &hToken); 635 if (!Success) return Success; 636 637 Success = LookupPrivilegeValueW(NULL, 638 lpszPrivilegeName, 639 &tp.Privileges[0].Luid); 640 if (!Success) goto Quit; 641 642 tp.PrivilegeCount = 1; 643 tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0); 644 645 Success = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL); 646 647 Quit: 648 CloseHandle(hToken); 649 return Success; 650 } 651 652 653 int WINAPI 654 wWinMain(IN HINSTANCE hInst, 655 IN HINSTANCE hPrevInstance, 656 IN LPWSTR lpszCmdLine, 657 IN int nCmdShow) 658 { 659 BOOL bIsLiveCD, Success = TRUE; 660 STATE State; 661 662 hInstance = hInst; 663 664 bIsLiveCD = IsLiveCD(); 665 666 Restart: 667 SetUserSettings(); 668 669 if (bIsLiveCD) 670 { 671 State.NextPage = LOCALEPAGE; 672 State.Run = SHELL; 673 } 674 else 675 { 676 State.NextPage = DONE; 677 State.Run = SHELL; 678 } 679 680 if (State.NextPage != DONE) // && bIsLiveCD 681 { 682 RunLiveCD(&State); 683 } 684 685 switch (State.Run) 686 { 687 case SHELL: 688 Success = StartShell(); 689 if (Success) 690 NotifyLogon(); 691 break; 692 693 case INSTALLER: 694 Success = StartInstaller(L"reactos.exe"); 695 break; 696 697 case REBOOT: 698 { 699 EnablePrivilege(SE_SHUTDOWN_NAME, TRUE); 700 ExitWindowsEx(EWX_REBOOT, 0); 701 EnablePrivilege(SE_SHUTDOWN_NAME, FALSE); 702 Success = TRUE; 703 break; 704 } 705 706 default: 707 Success = FALSE; 708 break; 709 } 710 711 /* 712 * In LiveCD mode, go back to the main menu if we failed 713 * to either start the shell or the installer. 714 */ 715 if (bIsLiveCD && !Success) 716 goto Restart; 717 718 return 0; 719 } 720 721 /* EOF */ 722