1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * PURPOSE: System setup 5 * FILE: dll/win32/syssetup/install.c 6 * PROGRAMER: Eric Kohl 7 */ 8 9 /* INCLUDES *****************************************************************/ 10 11 #include "precomp.h" 12 13 #define COBJMACROS 14 15 #include <io.h> 16 #include <wincon.h> 17 #include <winnls.h> 18 #include <winsvc.h> 19 #include <userenv.h> 20 #include <shlobj.h> 21 #include <shlwapi.h> 22 #include <shobjidl.h> 23 #include <rpcproxy.h> 24 #include <ndk/cmfuncs.h> 25 26 #define NDEBUG 27 #include <debug.h> 28 29 //DWORD WINAPI 30 //CMP_WaitNoPendingInstallEvents(DWORD dwTimeout); 31 32 DWORD WINAPI 33 SetupStartService(LPCWSTR lpServiceName, BOOL bWait); 34 35 /* GLOBALS ******************************************************************/ 36 37 HINF hSysSetupInf = INVALID_HANDLE_VALUE; 38 ADMIN_INFO AdminInfo; 39 40 typedef struct _DLG_DATA 41 { 42 HBITMAP hLogoBitmap; 43 HBITMAP hBarBitmap; 44 HWND hWndBarCtrl; 45 DWORD BarCounter; 46 DWORD BarWidth; 47 DWORD BarHeight; 48 } DLG_DATA, *PDLG_DATA; 49 50 /* FUNCTIONS ****************************************************************/ 51 52 static VOID 53 FatalError(char *pszFmt,...) 54 { 55 char szBuffer[512]; 56 va_list ap; 57 58 va_start(ap, pszFmt); 59 vsprintf(szBuffer, pszFmt, ap); 60 va_end(ap); 61 62 LogItem(NULL, L"Failed"); 63 64 strcat(szBuffer, "\nRebooting now!"); 65 MessageBoxA(NULL, 66 szBuffer, 67 "ReactOS Setup", 68 MB_OK); 69 } 70 71 static HRESULT 72 CreateShellLink( 73 LPCWSTR pszLinkPath, 74 LPCWSTR pszCmd, 75 LPCWSTR pszArg, 76 LPCWSTR pszDir, 77 LPCWSTR pszIconPath, 78 INT iIconNr, 79 LPCWSTR pszComment) 80 { 81 IShellLinkW *psl; 82 IPersistFile *ppf; 83 84 HRESULT hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (LPVOID*)&psl); 85 86 if (SUCCEEDED(hr)) 87 { 88 hr = IShellLinkW_SetPath(psl, pszCmd); 89 90 if (pszArg) 91 hr = IShellLinkW_SetArguments(psl, pszArg); 92 93 if (pszDir) 94 hr = IShellLinkW_SetWorkingDirectory(psl, pszDir); 95 96 if (pszIconPath) 97 hr = IShellLinkW_SetIconLocation(psl, pszIconPath, iIconNr); 98 99 if (pszComment) 100 hr = IShellLinkW_SetDescription(psl, pszComment); 101 102 hr = IShellLinkW_QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf); 103 104 if (SUCCEEDED(hr)) 105 { 106 hr = IPersistFile_Save(ppf, pszLinkPath, TRUE); 107 IPersistFile_Release(ppf); 108 } 109 110 IShellLinkW_Release(psl); 111 } 112 113 return hr; 114 } 115 116 117 static BOOL 118 CreateShortcut( 119 LPCWSTR pszFolder, 120 LPCWSTR pszName, 121 LPCWSTR pszCommand, 122 LPCWSTR pszDescription, 123 INT iIconNr, 124 LPCWSTR pszWorkingDir) 125 { 126 DWORD dwLen; 127 LPWSTR Ptr; 128 LPWSTR lpFilePart; 129 WCHAR szPath[MAX_PATH]; 130 WCHAR szWorkingDirBuf[MAX_PATH]; 131 132 /* If no working directory is provided, try to compute a default one */ 133 if (pszWorkingDir == NULL || pszWorkingDir[0] == L'\0') 134 { 135 if (ExpandEnvironmentStringsW(pszCommand, szPath, ARRAYSIZE(szPath)) == 0) 136 wcscpy(szPath, pszCommand); 137 138 dwLen = GetFullPathNameW(szPath, 139 ARRAYSIZE(szWorkingDirBuf), 140 szWorkingDirBuf, 141 &lpFilePart); 142 if (dwLen != 0 && dwLen <= ARRAYSIZE(szWorkingDirBuf)) 143 { 144 /* Since those should only be called with (.exe) files, 145 lpFilePart has not to be NULL */ 146 ASSERT(lpFilePart != NULL); 147 148 /* We're only interested in the path. Cut the file name off. 149 Also remove the trailing backslash unless the working directory 150 is only going to be a drive, i.e. C:\ */ 151 *(lpFilePart--) = L'\0'; 152 if (!(lpFilePart - szWorkingDirBuf == 2 && 153 szWorkingDirBuf[1] == L':' && szWorkingDirBuf[2] == L'\\')) 154 { 155 *lpFilePart = L'\0'; 156 } 157 pszWorkingDir = szWorkingDirBuf; 158 } 159 } 160 161 /* If we failed to compute a working directory, just do not use one */ 162 if (pszWorkingDir && pszWorkingDir[0] == L'\0') 163 pszWorkingDir = NULL; 164 165 /* Build the shortcut file name */ 166 wcscpy(szPath, pszFolder); 167 Ptr = PathAddBackslash(szPath); 168 wcscpy(Ptr, pszName); 169 170 /* Create the shortcut */ 171 return SUCCEEDED(CreateShellLink(szPath, 172 pszCommand, 173 L"", 174 pszWorkingDir, 175 /* Special value to indicate no icon */ 176 (iIconNr != -1 ? pszCommand : NULL), 177 iIconNr, 178 pszDescription)); 179 } 180 181 182 static BOOL CreateShortcutsFromSection(HINF hinf, LPWSTR pszSection, LPCWSTR pszFolder) 183 { 184 INFCONTEXT Context; 185 DWORD dwFieldCount; 186 INT iIconNr; 187 WCHAR szCommand[MAX_PATH]; 188 WCHAR szName[MAX_PATH]; 189 WCHAR szDescription[MAX_PATH]; 190 WCHAR szDirectory[MAX_PATH]; 191 192 if (!SetupFindFirstLine(hinf, pszSection, NULL, &Context)) 193 return FALSE; 194 195 do 196 { 197 dwFieldCount = SetupGetFieldCount(&Context); 198 if (dwFieldCount < 3) 199 continue; 200 201 if (!SetupGetStringFieldW(&Context, 1, szCommand, ARRAYSIZE(szCommand), NULL)) 202 continue; 203 204 if (!SetupGetStringFieldW(&Context, 2, szName, ARRAYSIZE(szName), NULL)) 205 continue; 206 207 if (!SetupGetStringFieldW(&Context, 3, szDescription, ARRAYSIZE(szDescription), NULL)) 208 continue; 209 210 if (dwFieldCount < 4 || !SetupGetIntField(&Context, 4, &iIconNr)) 211 iIconNr = -1; /* Special value to indicate no icon */ 212 213 if (dwFieldCount < 5 || !SetupGetStringFieldW(&Context, 5, szDirectory, ARRAYSIZE(szDirectory), NULL)) 214 szDirectory[0] = L'\0'; 215 216 wcscat(szName, L".lnk"); 217 218 CreateShortcut(pszFolder, szName, szCommand, szDescription, iIconNr, szDirectory); 219 220 } while (SetupFindNextLine(&Context, &Context)); 221 222 return TRUE; 223 } 224 225 static BOOL CreateShortcuts(HINF hinf, LPCWSTR szSection) 226 { 227 INFCONTEXT Context; 228 WCHAR szPath[MAX_PATH]; 229 WCHAR szFolder[MAX_PATH]; 230 WCHAR szFolderSection[MAX_PATH]; 231 INT csidl; 232 233 CoInitialize(NULL); 234 235 if (!SetupFindFirstLine(hinf, szSection, NULL, &Context)) 236 return FALSE; 237 238 do 239 { 240 if (SetupGetFieldCount(&Context) < 2) 241 continue; 242 243 if (!SetupGetStringFieldW(&Context, 0, szFolderSection, ARRAYSIZE(szFolderSection), NULL)) 244 continue; 245 246 if (!SetupGetIntField(&Context, 1, &csidl)) 247 continue; 248 249 if (!SetupGetStringFieldW(&Context, 2, szFolder, ARRAYSIZE(szFolder), NULL)) 250 continue; 251 252 if (FAILED(SHGetFolderPathAndSubDirW(NULL, csidl|CSIDL_FLAG_CREATE, (HANDLE)-1, SHGFP_TYPE_DEFAULT, szFolder, szPath))) 253 continue; 254 255 CreateShortcutsFromSection(hinf, szFolderSection, szPath); 256 257 } while (SetupFindNextLine(&Context, &Context)); 258 259 CoUninitialize(); 260 261 return TRUE; 262 } 263 264 static VOID 265 CreateTempDir( 266 IN LPCWSTR VarName) 267 { 268 WCHAR szTempDir[MAX_PATH]; 269 WCHAR szBuffer[MAX_PATH]; 270 DWORD dwLength; 271 HKEY hKey; 272 273 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, 274 L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 275 0, 276 KEY_QUERY_VALUE, 277 &hKey) != ERROR_SUCCESS) 278 { 279 FatalError("Error: %lu\n", GetLastError()); 280 return; 281 } 282 283 /* Get temp dir */ 284 dwLength = sizeof(szBuffer); 285 if (RegQueryValueExW(hKey, 286 VarName, 287 NULL, 288 NULL, 289 (LPBYTE)szBuffer, 290 &dwLength) != ERROR_SUCCESS) 291 { 292 FatalError("Error: %lu\n", GetLastError()); 293 goto cleanup; 294 } 295 296 /* Expand it */ 297 if (!ExpandEnvironmentStringsW(szBuffer, szTempDir, ARRAYSIZE(szTempDir))) 298 { 299 FatalError("Error: %lu\n", GetLastError()); 300 goto cleanup; 301 } 302 303 /* Create profiles directory */ 304 if (!CreateDirectoryW(szTempDir, NULL)) 305 { 306 if (GetLastError() != ERROR_ALREADY_EXISTS) 307 { 308 FatalError("Error: %lu\n", GetLastError()); 309 goto cleanup; 310 } 311 } 312 313 cleanup: 314 RegCloseKey(hKey); 315 } 316 317 static BOOL 318 InstallSysSetupInfDevices(VOID) 319 { 320 INFCONTEXT InfContext; 321 WCHAR szLineBuffer[256]; 322 DWORD dwLineLength; 323 324 if (!SetupFindFirstLineW(hSysSetupInf, 325 L"DeviceInfsToInstall", 326 NULL, 327 &InfContext)) 328 { 329 return FALSE; 330 } 331 332 do 333 { 334 if (!SetupGetStringFieldW(&InfContext, 335 0, 336 szLineBuffer, 337 ARRAYSIZE(szLineBuffer), 338 &dwLineLength)) 339 { 340 return FALSE; 341 } 342 343 if (!SetupDiInstallClassW(NULL, szLineBuffer, DI_QUIETINSTALL, NULL)) 344 { 345 return FALSE; 346 } 347 } 348 while (SetupFindNextLine(&InfContext, &InfContext)); 349 350 return TRUE; 351 } 352 353 static BOOL 354 InstallSysSetupInfComponents(VOID) 355 { 356 INFCONTEXT InfContext; 357 WCHAR szNameBuffer[256]; 358 WCHAR szSectionBuffer[256]; 359 HINF hComponentInf = INVALID_HANDLE_VALUE; 360 361 if (!SetupFindFirstLineW(hSysSetupInf, 362 L"Infs.Always", 363 NULL, 364 &InfContext)) 365 { 366 DPRINT("No Inf.Always section found\n"); 367 } 368 else 369 { 370 do 371 { 372 if (!SetupGetStringFieldW(&InfContext, 373 1, // Get the component name 374 szNameBuffer, 375 ARRAYSIZE(szNameBuffer), 376 NULL)) 377 { 378 FatalError("Error while trying to get component name \n"); 379 return FALSE; 380 } 381 382 if (!SetupGetStringFieldW(&InfContext, 383 2, // Get the component install section 384 szSectionBuffer, 385 ARRAYSIZE(szSectionBuffer), 386 NULL)) 387 { 388 FatalError("Error while trying to get component install section \n"); 389 return FALSE; 390 } 391 392 DPRINT("Trying to execute install section '%S' from '%S' \n", szSectionBuffer, szNameBuffer); 393 394 hComponentInf = SetupOpenInfFileW(szNameBuffer, 395 NULL, 396 INF_STYLE_WIN4, 397 NULL); 398 399 if (hComponentInf == INVALID_HANDLE_VALUE) 400 { 401 FatalError("SetupOpenInfFileW() failed to open '%S' (Error: %lu)\n", szNameBuffer, GetLastError()); 402 return FALSE; 403 } 404 405 if (!SetupInstallFromInfSectionW(NULL, 406 hComponentInf, 407 szSectionBuffer, 408 SPINST_ALL, 409 NULL, 410 NULL, 411 SP_COPY_NEWER, 412 SetupDefaultQueueCallbackW, 413 NULL, 414 NULL, 415 NULL)) 416 { 417 FatalError("Error while trying to install : %S (Error: %lu)\n", szNameBuffer, GetLastError()); 418 SetupCloseInfFile(hComponentInf); 419 return FALSE; 420 } 421 422 SetupCloseInfFile(hComponentInf); 423 } 424 while (SetupFindNextLine(&InfContext, &InfContext)); 425 } 426 427 return TRUE; 428 } 429 430 431 432 BOOL 433 RegisterTypeLibraries(HINF hinf, LPCWSTR szSection) 434 { 435 INFCONTEXT InfContext; 436 BOOL res; 437 WCHAR szName[MAX_PATH]; 438 WCHAR szPath[MAX_PATH]; 439 INT csidl; 440 LPWSTR p; 441 HMODULE hmod; 442 HRESULT hret; 443 444 /* Begin iterating the entries in the inf section */ 445 res = SetupFindFirstLine(hinf, szSection, NULL, &InfContext); 446 if (!res) return FALSE; 447 448 do 449 { 450 /* Get the name of the current type library */ 451 if (!SetupGetStringFieldW(&InfContext, 1, szName, ARRAYSIZE(szName), NULL)) 452 { 453 FatalError("SetupGetStringFieldW failed\n"); 454 continue; 455 } 456 457 if (!SetupGetIntField(&InfContext, 2, &csidl)) 458 csidl = CSIDL_SYSTEM; 459 460 hret = SHGetFolderPathW(NULL, csidl, NULL, 0, szPath); 461 if (FAILED(hret)) 462 { 463 FatalError("SHGetFolderPathW failed hret=0x%lx\n", hret); 464 continue; 465 } 466 467 p = PathAddBackslash(szPath); 468 wcscpy(p, szName); 469 470 hmod = LoadLibraryW(szName); 471 if (hmod == NULL) 472 { 473 FatalError("LoadLibraryW failed\n"); 474 continue; 475 } 476 477 __wine_register_resources(hmod); 478 479 } while (SetupFindNextLine(&InfContext, &InfContext)); 480 481 return TRUE; 482 } 483 484 static BOOL 485 EnableUserModePnpManager(VOID) 486 { 487 SC_HANDLE hSCManager = NULL; 488 SC_HANDLE hService = NULL; 489 BOOL bRet = FALSE; 490 491 hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); 492 if (hSCManager == NULL) 493 { 494 DPRINT1("Unable to open the service control manager.\n"); 495 DPRINT1("Last Error %d\n", GetLastError()); 496 goto cleanup; 497 } 498 499 hService = OpenServiceW(hSCManager, 500 L"PlugPlay", 501 SERVICE_CHANGE_CONFIG | SERVICE_START); 502 if (hService == NULL) 503 { 504 DPRINT1("Unable to open PlugPlay service\n"); 505 goto cleanup; 506 } 507 508 bRet = ChangeServiceConfigW(hService, 509 SERVICE_NO_CHANGE, 510 SERVICE_AUTO_START, 511 SERVICE_NO_CHANGE, 512 NULL, NULL, NULL, 513 NULL, NULL, NULL, NULL); 514 if (!bRet) 515 { 516 DPRINT1("Unable to change the service configuration\n"); 517 goto cleanup; 518 } 519 520 bRet = StartServiceW(hService, 0, NULL); 521 if (!bRet && (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING)) 522 { 523 DPRINT1("Unable to start service\n"); 524 goto cleanup; 525 } 526 527 bRet = TRUE; 528 529 cleanup: 530 if (hService != NULL) 531 CloseServiceHandle(hService); 532 if (hSCManager != NULL) 533 CloseServiceHandle(hSCManager); 534 return bRet; 535 } 536 537 static INT_PTR CALLBACK 538 StatusMessageWindowProc( 539 IN HWND hwndDlg, 540 IN UINT uMsg, 541 IN WPARAM wParam, 542 IN LPARAM lParam) 543 { 544 PDLG_DATA pDlgData; 545 UNREFERENCED_PARAMETER(wParam); 546 547 pDlgData = (PDLG_DATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 548 549 /* pDlgData is required for each case except WM_INITDIALOG */ 550 if (uMsg != WM_INITDIALOG && pDlgData == NULL) return FALSE; 551 552 switch (uMsg) 553 { 554 case WM_INITDIALOG: 555 { 556 BITMAP bm; 557 WCHAR szMsg[256]; 558 559 /* Allocate pDlgData */ 560 pDlgData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pDlgData)); 561 if (pDlgData) 562 { 563 /* Set pDlgData to GWLP_USERDATA, so we can get it for new messages */ 564 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)pDlgData); 565 566 /* Load bitmaps */ 567 pDlgData->hLogoBitmap = LoadImageW(hDllInstance, 568 MAKEINTRESOURCEW(IDB_REACTOS), IMAGE_BITMAP, 569 0, 0, LR_DEFAULTCOLOR); 570 571 pDlgData->hBarBitmap = LoadImageW(hDllInstance, MAKEINTRESOURCEW(IDB_LINE), 572 IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 573 GetObject(pDlgData->hBarBitmap, sizeof(bm), &bm); 574 pDlgData->BarWidth = bm.bmWidth; 575 pDlgData->BarHeight = bm.bmHeight; 576 577 if (pDlgData->hLogoBitmap && pDlgData->hBarBitmap) 578 { 579 if (SetTimer(hwndDlg, IDT_BAR, 20, NULL) == 0) 580 { 581 DPRINT1("SetTimer(IDT_BAR) failed: %lu\n", GetLastError()); 582 } 583 584 /* Get the animation bar control */ 585 pDlgData->hWndBarCtrl = GetDlgItem(hwndDlg, IDC_BAR); 586 } 587 } 588 589 /* Get and set status text */ 590 if (!LoadStringW(hDllInstance, IDS_STATUS_INSTALL_DEV, szMsg, ARRAYSIZE(szMsg))) 591 return FALSE; 592 SetDlgItemTextW(hwndDlg, IDC_STATUSLABEL, szMsg); 593 594 return TRUE; 595 } 596 597 case WM_TIMER: 598 { 599 if (pDlgData->hBarBitmap) 600 { 601 /* 602 * Default rotation bar image width is 413 (same as logo) 603 * We can divide 413 by 7 without remainder 604 */ 605 pDlgData->BarCounter = (pDlgData->BarCounter + 7) % pDlgData->BarWidth; 606 InvalidateRect(pDlgData->hWndBarCtrl, NULL, FALSE); 607 UpdateWindow(pDlgData->hWndBarCtrl); 608 } 609 return TRUE; 610 } 611 612 case WM_DRAWITEM: 613 { 614 LPDRAWITEMSTRUCT lpDis = (LPDRAWITEMSTRUCT)lParam; 615 616 if (lpDis->CtlID != IDC_BAR) 617 { 618 return FALSE; 619 } 620 621 if (pDlgData->hBarBitmap) 622 { 623 HDC hdcMem; 624 HGDIOBJ hOld; 625 DWORD off = pDlgData->BarCounter; 626 DWORD iw = pDlgData->BarWidth; 627 DWORD ih = pDlgData->BarHeight; 628 629 hdcMem = CreateCompatibleDC(lpDis->hDC); 630 hOld = SelectObject(hdcMem, pDlgData->hBarBitmap); 631 BitBlt(lpDis->hDC, off, 0, iw - off, ih, hdcMem, 0, 0, SRCCOPY); 632 BitBlt(lpDis->hDC, 0, 0, off, ih, hdcMem, iw - off, 0, SRCCOPY); 633 SelectObject(hdcMem, hOld); 634 DeleteDC(hdcMem); 635 return TRUE; 636 } 637 return FALSE; 638 } 639 640 case WM_DESTROY: 641 { 642 if (pDlgData->hBarBitmap) 643 { 644 KillTimer(hwndDlg, IDT_BAR); 645 } 646 647 DeleteObject(pDlgData->hLogoBitmap); 648 DeleteObject(pDlgData->hBarBitmap); 649 HeapFree(GetProcessHeap(), 0, pDlgData); 650 return TRUE; 651 } 652 } 653 return FALSE; 654 } 655 656 static DWORD WINAPI 657 ShowStatusMessageThread( 658 IN LPVOID lpParameter) 659 { 660 HWND hWnd; 661 MSG Msg; 662 UNREFERENCED_PARAMETER(lpParameter); 663 664 hWnd = CreateDialogParam(hDllInstance, 665 MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG), 666 GetDesktopWindow(), 667 StatusMessageWindowProc, 668 (LPARAM)NULL); 669 if (!hWnd) 670 return 0; 671 672 ShowWindow(hWnd, SW_SHOW); 673 674 /* Message loop for the Status window */ 675 while (GetMessage(&Msg, NULL, 0, 0)) 676 { 677 TranslateMessage(&Msg); 678 DispatchMessage(&Msg); 679 } 680 681 EndDialog(hWnd, 0); 682 683 return 0; 684 } 685 686 static LONG 687 ReadRegSzKey( 688 IN HKEY hKey, 689 IN LPCWSTR pszKey, 690 OUT LPWSTR* pValue) 691 { 692 LONG rc; 693 DWORD dwType; 694 DWORD cbData = 0; 695 LPWSTR pwszValue; 696 697 if (!pValue) 698 return ERROR_INVALID_PARAMETER; 699 700 *pValue = NULL; 701 rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData); 702 if (rc != ERROR_SUCCESS) 703 return rc; 704 if (dwType != REG_SZ) 705 return ERROR_FILE_NOT_FOUND; 706 pwszValue = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR)); 707 if (!pwszValue) 708 return ERROR_NOT_ENOUGH_MEMORY; 709 rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)pwszValue, &cbData); 710 if (rc != ERROR_SUCCESS) 711 { 712 HeapFree(GetProcessHeap(), 0, pwszValue); 713 return rc; 714 } 715 /* NULL-terminate the string */ 716 pwszValue[cbData / sizeof(WCHAR)] = '\0'; 717 718 *pValue = pwszValue; 719 return ERROR_SUCCESS; 720 } 721 722 static BOOL 723 IsConsoleBoot(VOID) 724 { 725 HKEY hControlKey = NULL; 726 LPWSTR pwszSystemStartOptions = NULL; 727 LPWSTR pwszCurrentOption, pwszNextOption; /* Pointers into SystemStartOptions */ 728 BOOL bConsoleBoot = FALSE; 729 LONG rc; 730 731 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 732 L"SYSTEM\\CurrentControlSet\\Control", 733 0, 734 KEY_QUERY_VALUE, 735 &hControlKey); 736 if (rc != ERROR_SUCCESS) 737 goto cleanup; 738 739 rc = ReadRegSzKey(hControlKey, L"SystemStartOptions", &pwszSystemStartOptions); 740 if (rc != ERROR_SUCCESS) 741 goto cleanup; 742 743 /* Check for CONSOLE switch in SystemStartOptions */ 744 pwszCurrentOption = pwszSystemStartOptions; 745 while (pwszCurrentOption) 746 { 747 pwszNextOption = wcschr(pwszCurrentOption, L' '); 748 if (pwszNextOption) 749 *pwszNextOption = L'\0'; 750 if (wcsicmp(pwszCurrentOption, L"CONSOLE") == 0) 751 { 752 DPRINT("Found %S. Switching to console boot\n", pwszCurrentOption); 753 bConsoleBoot = TRUE; 754 goto cleanup; 755 } 756 pwszCurrentOption = pwszNextOption ? pwszNextOption + 1 : NULL; 757 } 758 759 cleanup: 760 if (hControlKey != NULL) 761 RegCloseKey(hControlKey); 762 if (pwszSystemStartOptions) 763 HeapFree(GetProcessHeap(), 0, pwszSystemStartOptions); 764 return bConsoleBoot; 765 } 766 767 static BOOL 768 CommonInstall(VOID) 769 { 770 HANDLE hThread = NULL; 771 BOOL bResult = FALSE; 772 773 hSysSetupInf = SetupOpenInfFileW(L"syssetup.inf", 774 NULL, 775 INF_STYLE_WIN4, 776 NULL); 777 if (hSysSetupInf == INVALID_HANDLE_VALUE) 778 { 779 FatalError("SetupOpenInfFileW() failed to open 'syssetup.inf' (Error: %lu)\n", GetLastError()); 780 return FALSE; 781 } 782 783 if (!InstallSysSetupInfDevices()) 784 { 785 FatalError("InstallSysSetupInfDevices() failed!\n"); 786 goto Exit; 787 } 788 789 if(!InstallSysSetupInfComponents()) 790 { 791 FatalError("InstallSysSetupInfComponents() failed!\n"); 792 goto Exit; 793 } 794 795 if (!IsConsoleBoot()) 796 { 797 hThread = CreateThread(NULL, 798 0, 799 ShowStatusMessageThread, 800 NULL, 801 0, 802 NULL); 803 } 804 805 if (!EnableUserModePnpManager()) 806 { 807 FatalError("EnableUserModePnpManager() failed!\n"); 808 goto Exit; 809 } 810 811 if (CMP_WaitNoPendingInstallEvents(INFINITE) != WAIT_OBJECT_0) 812 { 813 FatalError("CMP_WaitNoPendingInstallEvents() failed!\n"); 814 goto Exit; 815 } 816 817 bResult = TRUE; 818 819 Exit: 820 821 if (bResult == FALSE) 822 { 823 SetupCloseInfFile(hSysSetupInf); 824 } 825 826 if (hThread != NULL) 827 { 828 PostThreadMessage(GetThreadId(hThread), WM_QUIT, 0, 0); 829 WaitForSingleObject(hThread, INFINITE); 830 CloseHandle(hThread); 831 } 832 833 return bResult; 834 } 835 836 static 837 DWORD 838 InstallLiveCD(VOID) 839 { 840 STARTUPINFOW StartupInfo; 841 PROCESS_INFORMATION ProcessInformation; 842 BOOL bRes; 843 844 if (!CommonInstall()) 845 goto error; 846 847 /* Install the TCP/IP protocol driver */ 848 bRes = InstallNetworkComponent(L"MS_TCPIP"); 849 if (!bRes && GetLastError() != ERROR_FILE_NOT_FOUND) 850 { 851 DPRINT("InstallNetworkComponent() failed with error 0x%lx\n", GetLastError()); 852 } 853 else 854 { 855 /* Start the TCP/IP protocol driver */ 856 SetupStartService(L"Tcpip", FALSE); 857 SetupStartService(L"Dhcp", FALSE); 858 SetupStartService(L"Dnscache", FALSE); 859 } 860 861 /* Register components */ 862 _SEH2_TRY 863 { 864 if (!SetupInstallFromInfSectionW(NULL, 865 hSysSetupInf, L"RegistrationPhase2", 866 SPINST_ALL, 867 0, NULL, 0, NULL, NULL, NULL, NULL)) 868 { 869 DPRINT1("SetupInstallFromInfSectionW failed!\n"); 870 } 871 872 RegisterTypeLibraries(hSysSetupInf, L"TypeLibraries"); 873 } 874 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 875 { 876 DPRINT1("Catching exception\n"); 877 } 878 _SEH2_END; 879 880 SetupCloseInfFile(hSysSetupInf); 881 882 /* Run the shell */ 883 ZeroMemory(&StartupInfo, sizeof(StartupInfo)); 884 StartupInfo.cb = sizeof(StartupInfo); 885 bRes = CreateProcessW(L"userinit.exe", 886 NULL, 887 NULL, 888 NULL, 889 FALSE, 890 0, 891 NULL, 892 NULL, 893 &StartupInfo, 894 &ProcessInformation); 895 if (!bRes) 896 goto error; 897 898 CloseHandle(ProcessInformation.hThread); 899 CloseHandle(ProcessInformation.hProcess); 900 901 return 0; 902 903 error: 904 MessageBoxW( 905 NULL, 906 L"Failed to load LiveCD! You can shutdown your computer, or press ENTER to reboot.", 907 L"ReactOS LiveCD", 908 MB_OK); 909 return 0; 910 } 911 912 913 static BOOL 914 SetSetupType(DWORD dwSetupType) 915 { 916 DWORD dwError; 917 HKEY hKey; 918 919 dwError = RegOpenKeyExW( 920 HKEY_LOCAL_MACHINE, 921 L"SYSTEM\\Setup", 922 0, 923 KEY_SET_VALUE, 924 &hKey); 925 if (dwError != ERROR_SUCCESS) 926 return FALSE; 927 928 dwError = RegSetValueExW( 929 hKey, 930 L"SetupType", 931 0, 932 REG_DWORD, 933 (LPBYTE)&dwSetupType, 934 sizeof(DWORD)); 935 RegCloseKey(hKey); 936 if (dwError != ERROR_SUCCESS) 937 return FALSE; 938 939 return TRUE; 940 } 941 942 static DWORD CALLBACK 943 HotkeyThread(LPVOID Parameter) 944 { 945 ATOM hotkey; 946 MSG msg; 947 948 DPRINT("HotkeyThread start\n"); 949 950 hotkey = GlobalAddAtomW(L"Setup Shift+F10 Hotkey"); 951 952 if (!RegisterHotKey(NULL, hotkey, MOD_SHIFT, VK_F10)) 953 DPRINT1("RegisterHotKey failed with %lu\n", GetLastError()); 954 955 while (GetMessage(&msg, NULL, 0, 0)) 956 { 957 if (msg.hwnd == NULL && msg.message == WM_HOTKEY && msg.wParam == hotkey) 958 { 959 STARTUPINFOW si = { sizeof(si) }; 960 PROCESS_INFORMATION pi; 961 962 if (CreateProcessW(L"cmd.exe", 963 NULL, 964 NULL, 965 NULL, 966 FALSE, 967 CREATE_NEW_CONSOLE, 968 NULL, 969 NULL, 970 &si, 971 &pi)) 972 { 973 CloseHandle(pi.hProcess); 974 CloseHandle(pi.hThread); 975 } 976 else 977 { 978 DPRINT1("Failed to launch command prompt: %lu\n", GetLastError()); 979 } 980 } 981 } 982 983 UnregisterHotKey(NULL, hotkey); 984 GlobalDeleteAtom(hotkey); 985 986 DPRINT("HotkeyThread terminate\n"); 987 return 0; 988 } 989 990 991 static 992 BOOL 993 InitializeProgramFilesDir(VOID) 994 { 995 LONG Error; 996 HKEY hKey; 997 DWORD dwLength; 998 WCHAR szProgramFilesDirPath[MAX_PATH]; 999 WCHAR szCommonFilesDirPath[MAX_PATH]; 1000 WCHAR szBuffer[MAX_PATH]; 1001 1002 /* Load 'Program Files' location */ 1003 if (!LoadStringW(hDllInstance, 1004 IDS_PROGRAMFILES, 1005 szBuffer, 1006 ARRAYSIZE(szBuffer))) 1007 { 1008 DPRINT1("Error: %lu\n", GetLastError()); 1009 return FALSE; 1010 } 1011 1012 if (!LoadStringW(hDllInstance, 1013 IDS_COMMONFILES, 1014 szCommonFilesDirPath, 1015 ARRAYSIZE(szCommonFilesDirPath))) 1016 { 1017 DPRINT1("Warning: %lu\n", GetLastError()); 1018 } 1019 1020 /* Expand it */ 1021 if (!ExpandEnvironmentStringsW(szBuffer, 1022 szProgramFilesDirPath, 1023 ARRAYSIZE(szProgramFilesDirPath))) 1024 { 1025 DPRINT1("Error: %lu\n", GetLastError()); 1026 return FALSE; 1027 } 1028 1029 wcscpy(szBuffer, szProgramFilesDirPath); 1030 wcscat(szBuffer, L"\\"); 1031 wcscat(szBuffer, szCommonFilesDirPath); 1032 1033 if (!ExpandEnvironmentStringsW(szBuffer, 1034 szCommonFilesDirPath, 1035 ARRAYSIZE(szCommonFilesDirPath))) 1036 { 1037 DPRINT1("Warning: %lu\n", GetLastError()); 1038 } 1039 1040 /* Store it */ 1041 Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1042 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 1043 0, 1044 KEY_SET_VALUE, 1045 &hKey); 1046 if (Error != ERROR_SUCCESS) 1047 { 1048 DPRINT1("Error: %lu\n", Error); 1049 return FALSE; 1050 } 1051 1052 dwLength = (wcslen(szProgramFilesDirPath) + 1) * sizeof(WCHAR); 1053 Error = RegSetValueExW(hKey, 1054 L"ProgramFilesDir", 1055 0, 1056 REG_SZ, 1057 (LPBYTE)szProgramFilesDirPath, 1058 dwLength); 1059 if (Error != ERROR_SUCCESS) 1060 { 1061 DPRINT1("Error: %lu\n", Error); 1062 RegCloseKey(hKey); 1063 return FALSE; 1064 } 1065 1066 dwLength = (wcslen(szCommonFilesDirPath) + 1) * sizeof(WCHAR); 1067 Error = RegSetValueExW(hKey, 1068 L"CommonFilesDir", 1069 0, 1070 REG_SZ, 1071 (LPBYTE)szCommonFilesDirPath, 1072 dwLength); 1073 if (Error != ERROR_SUCCESS) 1074 { 1075 DPRINT1("Warning: %lu\n", Error); 1076 } 1077 1078 RegCloseKey(hKey); 1079 1080 /* Create directory */ 1081 // FIXME: Security! 1082 if (!CreateDirectoryW(szProgramFilesDirPath, NULL)) 1083 { 1084 if (GetLastError() != ERROR_ALREADY_EXISTS) 1085 { 1086 DPRINT1("Error: %lu\n", GetLastError()); 1087 return FALSE; 1088 } 1089 } 1090 1091 /* Create directory */ 1092 // FIXME: Security! 1093 if (!CreateDirectoryW(szCommonFilesDirPath, NULL)) 1094 { 1095 if (GetLastError() != ERROR_ALREADY_EXISTS) 1096 { 1097 DPRINT1("Warning: %lu\n", GetLastError()); 1098 // return FALSE; 1099 } 1100 } 1101 1102 return TRUE; 1103 } 1104 1105 1106 static 1107 VOID 1108 InitializeDefaultUserLocale(VOID) 1109 { 1110 WCHAR szBuffer[80]; 1111 PWSTR ptr; 1112 HKEY hLocaleKey; 1113 DWORD ret; 1114 DWORD dwSize; 1115 LCID lcid; 1116 INT i; 1117 1118 struct {LCTYPE LCType; PWSTR pValue;} LocaleData[] = { 1119 /* Number */ 1120 {LOCALE_SDECIMAL, L"sDecimal"}, 1121 {LOCALE_STHOUSAND, L"sThousand"}, 1122 {LOCALE_SNEGATIVESIGN, L"sNegativeSign"}, 1123 {LOCALE_SPOSITIVESIGN, L"sPositiveSign"}, 1124 {LOCALE_SGROUPING, L"sGrouping"}, 1125 {LOCALE_SLIST, L"sList"}, 1126 {LOCALE_SNATIVEDIGITS, L"sNativeDigits"}, 1127 {LOCALE_INEGNUMBER, L"iNegNumber"}, 1128 {LOCALE_IDIGITS, L"iDigits"}, 1129 {LOCALE_ILZERO, L"iLZero"}, 1130 {LOCALE_IMEASURE, L"iMeasure"}, 1131 {LOCALE_IDIGITSUBSTITUTION, L"NumShape"}, 1132 1133 /* Currency */ 1134 {LOCALE_SCURRENCY, L"sCurrency"}, 1135 {LOCALE_SMONDECIMALSEP, L"sMonDecimalSep"}, 1136 {LOCALE_SMONTHOUSANDSEP, L"sMonThousandSep"}, 1137 {LOCALE_SMONGROUPING, L"sMonGrouping"}, 1138 {LOCALE_ICURRENCY, L"iCurrency"}, 1139 {LOCALE_INEGCURR, L"iNegCurr"}, 1140 {LOCALE_ICURRDIGITS, L"iCurrDigits"}, 1141 1142 /* Time */ 1143 {LOCALE_STIMEFORMAT, L"sTimeFormat"}, 1144 {LOCALE_STIME, L"sTime"}, 1145 {LOCALE_S1159, L"s1159"}, 1146 {LOCALE_S2359, L"s2359"}, 1147 {LOCALE_ITIME, L"iTime"}, 1148 {LOCALE_ITIMEMARKPOSN, L"iTimePrefix"}, 1149 {LOCALE_ITLZERO, L"iTLZero"}, 1150 1151 /* Date */ 1152 {LOCALE_SLONGDATE, L"sLongDate"}, 1153 {LOCALE_SSHORTDATE, L"sShortDate"}, 1154 {LOCALE_SDATE, L"sDate"}, 1155 {LOCALE_IFIRSTDAYOFWEEK, L"iFirstDayOfWeek"}, 1156 {LOCALE_IFIRSTWEEKOFYEAR, L"iFirstWeekOfYear"}, 1157 {LOCALE_IDATE, L"iDate"}, 1158 {LOCALE_ICALENDARTYPE, L"iCalendarType"}, 1159 1160 /* Misc */ 1161 {LOCALE_SCOUNTRY, L"sCountry"}, 1162 {LOCALE_SABBREVLANGNAME, L"sLanguage"}, 1163 {LOCALE_ICOUNTRY, L"iCountry"}, 1164 {0, NULL}}; 1165 1166 ret = RegOpenKeyExW(HKEY_USERS, 1167 L".DEFAULT\\Control Panel\\International", 1168 0, 1169 KEY_READ | KEY_WRITE, 1170 &hLocaleKey); 1171 if (ret != ERROR_SUCCESS) 1172 { 1173 return; 1174 } 1175 1176 dwSize = 9 * sizeof(WCHAR); 1177 ret = RegQueryValueExW(hLocaleKey, 1178 L"Locale", 1179 NULL, 1180 NULL, 1181 (PBYTE)szBuffer, 1182 &dwSize); 1183 if (ret != ERROR_SUCCESS) 1184 goto done; 1185 1186 lcid = (LCID)wcstoul(szBuffer, &ptr, 16); 1187 if (lcid == 0) 1188 goto done; 1189 1190 i = 0; 1191 while (LocaleData[i].pValue != NULL) 1192 { 1193 if (GetLocaleInfoW(lcid, 1194 LocaleData[i].LCType | LOCALE_NOUSEROVERRIDE, 1195 szBuffer, 1196 ARRAYSIZE(szBuffer))) 1197 { 1198 RegSetValueExW(hLocaleKey, 1199 LocaleData[i].pValue, 1200 0, 1201 REG_SZ, 1202 (PBYTE)szBuffer, 1203 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1204 } 1205 1206 i++; 1207 } 1208 1209 done: 1210 RegCloseKey(hLocaleKey); 1211 } 1212 1213 1214 static 1215 DWORD 1216 SaveDefaultUserHive(VOID) 1217 { 1218 WCHAR szDefaultUserHive[MAX_PATH]; 1219 HKEY hUserKey = NULL; 1220 DWORD cchSize; 1221 DWORD dwError; 1222 1223 DPRINT("SaveDefaultUserHive()\n"); 1224 1225 cchSize = ARRAYSIZE(szDefaultUserHive); 1226 GetDefaultUserProfileDirectoryW(szDefaultUserHive, &cchSize); 1227 1228 wcscat(szDefaultUserHive, L"\\ntuser.dat"); 1229 1230 dwError = RegOpenKeyExW(HKEY_USERS, 1231 L".DEFAULT", 1232 0, 1233 KEY_READ, 1234 &hUserKey); 1235 if (dwError != ERROR_SUCCESS) 1236 { 1237 DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError); 1238 return dwError; 1239 } 1240 1241 pSetupEnablePrivilege(L"SeBackupPrivilege", TRUE); 1242 1243 /* Save the Default hive */ 1244 dwError = RegSaveKeyExW(hUserKey, 1245 szDefaultUserHive, 1246 NULL, 1247 REG_STANDARD_FORMAT); 1248 if (dwError == ERROR_ALREADY_EXISTS) 1249 { 1250 WCHAR szBackupHive[MAX_PATH]; 1251 1252 /* Build the backup hive file name by replacing the extension */ 1253 wcscpy(szBackupHive, szDefaultUserHive); 1254 wcscpy(&szBackupHive[wcslen(szBackupHive) - 4], L".bak"); 1255 1256 /* Back up the existing default user hive by renaming it, replacing any possible existing old backup */ 1257 if (!MoveFileExW(szDefaultUserHive, 1258 szBackupHive, 1259 MOVEFILE_REPLACE_EXISTING)) 1260 { 1261 dwError = GetLastError(); 1262 DPRINT1("Failed to create a default-user hive backup '%S', MoveFileExW failed (Error %lu)\n", 1263 szBackupHive, dwError); 1264 } 1265 else 1266 { 1267 /* The backup has been done, retry saving the Default hive */ 1268 dwError = RegSaveKeyExW(hUserKey, 1269 szDefaultUserHive, 1270 NULL, 1271 REG_STANDARD_FORMAT); 1272 } 1273 } 1274 if (dwError != ERROR_SUCCESS) 1275 { 1276 DPRINT1("RegSaveKeyExW() failed (Error %lu)\n", dwError); 1277 } 1278 1279 pSetupEnablePrivilege(L"SeBackupPrivilege", FALSE); 1280 1281 RegCloseKey(hUserKey); 1282 1283 return dwError; 1284 } 1285 1286 1287 static 1288 DWORD 1289 InstallReactOS(VOID) 1290 { 1291 WCHAR szBuffer[MAX_PATH]; 1292 HANDLE token; 1293 TOKEN_PRIVILEGES privs; 1294 HKEY hKey; 1295 HINF hShortcutsInf; 1296 HANDLE hHotkeyThread; 1297 BOOL ret; 1298 1299 InitializeSetupActionLog(FALSE); 1300 LogItem(NULL, L"Installing ReactOS"); 1301 1302 CreateTempDir(L"TEMP"); 1303 CreateTempDir(L"TMP"); 1304 1305 if (!InitializeProgramFilesDir()) 1306 { 1307 FatalError("InitializeProgramFilesDir() failed"); 1308 return 0; 1309 } 1310 1311 if (!InitializeProfiles()) 1312 { 1313 FatalError("InitializeProfiles() failed"); 1314 return 0; 1315 } 1316 1317 InitializeDefaultUserLocale(); 1318 1319 if (GetWindowsDirectoryW(szBuffer, ARRAYSIZE(szBuffer))) 1320 { 1321 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1322 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 1323 0, 1324 KEY_WRITE, 1325 &hKey) == ERROR_SUCCESS) 1326 { 1327 RegSetValueExW(hKey, 1328 L"PathName", 1329 0, 1330 REG_SZ, 1331 (LPBYTE)szBuffer, 1332 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1333 1334 RegSetValueExW(hKey, 1335 L"SystemRoot", 1336 0, 1337 REG_SZ, 1338 (LPBYTE)szBuffer, 1339 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1340 1341 RegCloseKey(hKey); 1342 } 1343 1344 PathAddBackslash(szBuffer); 1345 wcscat(szBuffer, L"system"); 1346 CreateDirectory(szBuffer, NULL); 1347 } 1348 1349 if (SaveDefaultUserHive() != ERROR_SUCCESS) 1350 { 1351 FatalError("SaveDefaultUserHive() failed"); 1352 return 0; 1353 } 1354 1355 if (!CopySystemProfile(0)) 1356 { 1357 FatalError("CopySystemProfile() failed"); 1358 return 0; 1359 } 1360 1361 hHotkeyThread = CreateThread(NULL, 0, HotkeyThread, NULL, 0, NULL); 1362 1363 if (!CommonInstall()) 1364 return 0; 1365 1366 /* Install the TCP/IP protocol driver */ 1367 ret = InstallNetworkComponent(L"MS_TCPIP"); 1368 if (!ret && GetLastError() != ERROR_FILE_NOT_FOUND) 1369 { 1370 DPRINT("InstallNetworkComponent() failed with error 0x%lx\n", GetLastError()); 1371 } 1372 else 1373 { 1374 /* Start the TCP/IP protocol driver */ 1375 SetupStartService(L"Tcpip", FALSE); 1376 SetupStartService(L"Dhcp", FALSE); 1377 SetupStartService(L"Dnscache", FALSE); 1378 } 1379 1380 InstallWizard(); 1381 1382 InstallSecurity(); 1383 1384 SetAutoAdminLogon(); 1385 1386 hShortcutsInf = SetupOpenInfFileW(L"shortcuts.inf", 1387 NULL, 1388 INF_STYLE_WIN4, 1389 NULL); 1390 if (hShortcutsInf == INVALID_HANDLE_VALUE) 1391 { 1392 FatalError("Failed to open shortcuts.inf"); 1393 return 0; 1394 } 1395 1396 if (!CreateShortcuts(hShortcutsInf, L"ShortcutFolders")) 1397 { 1398 FatalError("CreateShortcuts() failed"); 1399 return 0; 1400 } 1401 1402 SetupCloseInfFile(hShortcutsInf); 1403 1404 hShortcutsInf = SetupOpenInfFileW(L"rosapps_shortcuts.inf", 1405 NULL, 1406 INF_STYLE_WIN4, 1407 NULL); 1408 if (hShortcutsInf != INVALID_HANDLE_VALUE) 1409 { 1410 if (!CreateShortcuts(hShortcutsInf, L"ShortcutFolders")) 1411 { 1412 FatalError("CreateShortcuts(rosapps) failed"); 1413 return 0; 1414 } 1415 SetupCloseInfFile(hShortcutsInf); 1416 } 1417 1418 SetupCloseInfFile(hSysSetupInf); 1419 SetSetupType(0); 1420 1421 if (hHotkeyThread) 1422 { 1423 PostThreadMessage(GetThreadId(hHotkeyThread), WM_QUIT, 0, 0); 1424 CloseHandle(hHotkeyThread); 1425 } 1426 1427 LogItem(NULL, L"Installing ReactOS done"); 1428 TerminateSetupActionLog(); 1429 1430 if (AdminInfo.Name != NULL) 1431 RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo.Name); 1432 1433 if (AdminInfo.Domain != NULL) 1434 RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo.Domain); 1435 1436 if (AdminInfo.Password != NULL) 1437 RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo.Password); 1438 1439 /* Get shutdown privilege */ 1440 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) 1441 { 1442 FatalError("OpenProcessToken() failed!"); 1443 return 0; 1444 } 1445 if (!LookupPrivilegeValue(NULL, 1446 SE_SHUTDOWN_NAME, 1447 &privs.Privileges[0].Luid)) 1448 { 1449 FatalError("LookupPrivilegeValue() failed!"); 1450 return 0; 1451 } 1452 privs.PrivilegeCount = 1; 1453 privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 1454 if (AdjustTokenPrivileges(token, 1455 FALSE, 1456 &privs, 1457 0, 1458 (PTOKEN_PRIVILEGES)NULL, 1459 NULL) == 0) 1460 { 1461 FatalError("AdjustTokenPrivileges() failed!"); 1462 return 0; 1463 } 1464 1465 ExitWindowsEx(EWX_REBOOT, 0); 1466 return 0; 1467 } 1468 1469 1470 /* 1471 * Standard Windows-compatible export, which dispatches 1472 * to either 'InstallReactOS' or 'InstallLiveCD'. 1473 */ 1474 INT 1475 WINAPI 1476 InstallWindowsNt(INT argc, WCHAR** argv) 1477 { 1478 INT i; 1479 PWSTR p; 1480 1481 for (i = 0; i < argc; ++i) 1482 { 1483 p = argv[i]; 1484 if (*p == L'-') 1485 { 1486 p++; 1487 1488 // NOTE: On Windows, "mini" means "minimal UI", and can be used 1489 // in addition to "newsetup"; these options are not exclusive. 1490 if (_wcsicmp(p, L"newsetup") == 0) 1491 return (INT)InstallReactOS(); 1492 else if (_wcsicmp(p, L"mini") == 0) 1493 return (INT)InstallLiveCD(); 1494 1495 /* Add support for other switches */ 1496 } 1497 } 1498 1499 return 0; 1500 } 1501 1502 1503 /* 1504 * @unimplemented 1505 */ 1506 DWORD WINAPI 1507 SetupChangeFontSize( 1508 IN HANDLE hWnd, 1509 IN LPCWSTR lpszFontSize) 1510 { 1511 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 1512 return FALSE; 1513 } 1514 1515 /* 1516 * @unimplemented 1517 */ 1518 DWORD WINAPI 1519 SetupChangeLocaleEx(HWND hWnd, 1520 LCID Lcid, 1521 LPCWSTR lpSrcRootPath, 1522 char Unknown, 1523 DWORD dwUnused1, 1524 DWORD dwUnused2) 1525 { 1526 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 1527 return FALSE; 1528 } 1529 1530 /* 1531 * @implemented 1532 */ 1533 DWORD WINAPI 1534 SetupChangeLocale(HWND hWnd, LCID Lcid) 1535 { 1536 return SetupChangeLocaleEx(hWnd, Lcid, NULL, 0, 0, 0); 1537 } 1538 1539 1540 DWORD 1541 WINAPI 1542 SetupStartService( 1543 LPCWSTR lpServiceName, 1544 BOOL bWait) 1545 { 1546 SC_HANDLE hManager = NULL; 1547 SC_HANDLE hService = NULL; 1548 DWORD dwError = ERROR_SUCCESS; 1549 1550 hManager = OpenSCManagerW(NULL, 1551 NULL, 1552 SC_MANAGER_ALL_ACCESS); 1553 if (hManager == NULL) 1554 { 1555 dwError = GetLastError(); 1556 goto done; 1557 } 1558 1559 hService = OpenServiceW(hManager, 1560 lpServiceName, 1561 SERVICE_START); 1562 if (hService == NULL) 1563 { 1564 dwError = GetLastError(); 1565 goto done; 1566 } 1567 1568 if (!StartService(hService, 0, NULL)) 1569 { 1570 dwError = GetLastError(); 1571 goto done; 1572 } 1573 1574 done: 1575 if (hService != NULL) 1576 CloseServiceHandle(hService); 1577 1578 if (hManager != NULL) 1579 CloseServiceHandle(hManager); 1580 1581 return dwError; 1582 } 1583