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