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(szPath); 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 SERVICE_STATUS_PROCESS ServiceStatus; 490 BOOL bRet = FALSE; 491 DWORD BytesNeeded, WaitTime; 492 493 hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); 494 if (hSCManager == NULL) 495 { 496 DPRINT1("Unable to open the service control manager.\n"); 497 DPRINT1("Last Error %d\n", GetLastError()); 498 goto cleanup; 499 } 500 501 hService = OpenServiceW(hSCManager, 502 L"PlugPlay", 503 SERVICE_CHANGE_CONFIG | SERVICE_START | SERVICE_QUERY_STATUS); 504 if (hService == NULL) 505 { 506 DPRINT1("Unable to open PlugPlay service\n"); 507 goto cleanup; 508 } 509 510 bRet = ChangeServiceConfigW(hService, 511 SERVICE_NO_CHANGE, 512 SERVICE_AUTO_START, 513 SERVICE_NO_CHANGE, 514 NULL, NULL, NULL, 515 NULL, NULL, NULL, NULL); 516 if (!bRet) 517 { 518 DPRINT1("Unable to change the service configuration\n"); 519 goto cleanup; 520 } 521 522 bRet = StartServiceW(hService, 0, NULL); 523 if (!bRet && (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING)) 524 { 525 DPRINT1("Unable to start service\n"); 526 goto cleanup; 527 } 528 529 while (TRUE) 530 { 531 bRet = QueryServiceStatusEx(hService, 532 SC_STATUS_PROCESS_INFO, 533 (LPBYTE)&ServiceStatus, 534 sizeof(ServiceStatus), 535 &BytesNeeded); 536 if (!bRet) 537 { 538 DPRINT1("QueryServiceStatusEx() failed for PlugPlay service (error 0x%x)\n", GetLastError()); 539 goto cleanup; 540 } 541 542 if (ServiceStatus.dwCurrentState != SERVICE_START_PENDING) 543 break; 544 545 WaitTime = ServiceStatus.dwWaitHint / 10; 546 if (WaitTime < 1000) WaitTime = 1000; 547 else if (WaitTime > 10000) WaitTime = 10000; 548 Sleep(WaitTime); 549 }; 550 551 if (ServiceStatus.dwCurrentState != SERVICE_RUNNING) 552 { 553 bRet = FALSE; 554 DPRINT1("Failed to start PlugPlay service\n"); 555 goto cleanup; 556 } 557 558 bRet = TRUE; 559 560 cleanup: 561 if (hService != NULL) 562 CloseServiceHandle(hService); 563 if (hSCManager != NULL) 564 CloseServiceHandle(hSCManager); 565 return bRet; 566 } 567 568 static INT_PTR CALLBACK 569 StatusMessageWindowProc( 570 IN HWND hwndDlg, 571 IN UINT uMsg, 572 IN WPARAM wParam, 573 IN LPARAM lParam) 574 { 575 PDLG_DATA pDlgData; 576 UNREFERENCED_PARAMETER(wParam); 577 578 pDlgData = (PDLG_DATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 579 580 /* pDlgData is required for each case except WM_INITDIALOG */ 581 if (uMsg != WM_INITDIALOG && pDlgData == NULL) return FALSE; 582 583 switch (uMsg) 584 { 585 case WM_INITDIALOG: 586 { 587 BITMAP bm; 588 WCHAR szMsg[256]; 589 590 /* Allocate pDlgData */ 591 pDlgData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pDlgData)); 592 if (pDlgData) 593 { 594 /* Set pDlgData to GWLP_USERDATA, so we can get it for new messages */ 595 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)pDlgData); 596 597 /* Load bitmaps */ 598 pDlgData->hLogoBitmap = LoadImageW(hDllInstance, 599 MAKEINTRESOURCEW(IDB_REACTOS), IMAGE_BITMAP, 600 0, 0, LR_DEFAULTCOLOR); 601 602 pDlgData->hBarBitmap = LoadImageW(hDllInstance, MAKEINTRESOURCEW(IDB_LINE), 603 IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 604 GetObject(pDlgData->hBarBitmap, sizeof(bm), &bm); 605 pDlgData->BarWidth = bm.bmWidth; 606 pDlgData->BarHeight = bm.bmHeight; 607 608 if (pDlgData->hLogoBitmap && pDlgData->hBarBitmap) 609 { 610 if (SetTimer(hwndDlg, IDT_BAR, 20, NULL) == 0) 611 { 612 DPRINT1("SetTimer(IDT_BAR) failed: %lu\n", GetLastError()); 613 } 614 615 /* Get the animation bar control */ 616 pDlgData->hWndBarCtrl = GetDlgItem(hwndDlg, IDC_BAR); 617 } 618 } 619 620 /* Get and set status text */ 621 if (!LoadStringW(hDllInstance, IDS_STATUS_INSTALL_DEV, szMsg, ARRAYSIZE(szMsg))) 622 return FALSE; 623 SetDlgItemTextW(hwndDlg, IDC_STATUSLABEL, szMsg); 624 625 return TRUE; 626 } 627 628 case WM_TIMER: 629 { 630 if (pDlgData->hBarBitmap) 631 { 632 /* 633 * Default rotation bar image width is 413 (same as logo) 634 * We can divide 413 by 7 without remainder 635 */ 636 pDlgData->BarCounter = (pDlgData->BarCounter + 7) % pDlgData->BarWidth; 637 InvalidateRect(pDlgData->hWndBarCtrl, NULL, FALSE); 638 UpdateWindow(pDlgData->hWndBarCtrl); 639 } 640 return TRUE; 641 } 642 643 case WM_DRAWITEM: 644 { 645 LPDRAWITEMSTRUCT lpDis = (LPDRAWITEMSTRUCT)lParam; 646 647 if (lpDis->CtlID != IDC_BAR) 648 { 649 return FALSE; 650 } 651 652 if (pDlgData->hBarBitmap) 653 { 654 HDC hdcMem; 655 HGDIOBJ hOld; 656 DWORD off = pDlgData->BarCounter; 657 DWORD iw = pDlgData->BarWidth; 658 DWORD ih = pDlgData->BarHeight; 659 660 hdcMem = CreateCompatibleDC(lpDis->hDC); 661 hOld = SelectObject(hdcMem, pDlgData->hBarBitmap); 662 BitBlt(lpDis->hDC, off, 0, iw - off, ih, hdcMem, 0, 0, SRCCOPY); 663 BitBlt(lpDis->hDC, 0, 0, off, ih, hdcMem, iw - off, 0, SRCCOPY); 664 SelectObject(hdcMem, hOld); 665 DeleteDC(hdcMem); 666 return TRUE; 667 } 668 return FALSE; 669 } 670 671 case WM_DESTROY: 672 { 673 if (pDlgData->hBarBitmap) 674 { 675 KillTimer(hwndDlg, IDT_BAR); 676 } 677 678 DeleteObject(pDlgData->hLogoBitmap); 679 DeleteObject(pDlgData->hBarBitmap); 680 HeapFree(GetProcessHeap(), 0, pDlgData); 681 return TRUE; 682 } 683 } 684 return FALSE; 685 } 686 687 static DWORD WINAPI 688 ShowStatusMessageThread( 689 IN LPVOID lpParameter) 690 { 691 HWND hWnd; 692 MSG Msg; 693 UNREFERENCED_PARAMETER(lpParameter); 694 695 hWnd = CreateDialogParam(hDllInstance, 696 MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG), 697 GetDesktopWindow(), 698 StatusMessageWindowProc, 699 (LPARAM)NULL); 700 if (!hWnd) 701 return 0; 702 703 ShowWindow(hWnd, SW_SHOW); 704 705 /* Message loop for the Status window */ 706 while (GetMessage(&Msg, NULL, 0, 0)) 707 { 708 TranslateMessage(&Msg); 709 DispatchMessage(&Msg); 710 } 711 712 EndDialog(hWnd, 0); 713 714 return 0; 715 } 716 717 static LONG 718 ReadRegSzKey( 719 IN HKEY hKey, 720 IN LPCWSTR pszKey, 721 OUT LPWSTR* pValue) 722 { 723 LONG rc; 724 DWORD dwType; 725 DWORD cbData = 0; 726 LPWSTR pwszValue; 727 728 if (!pValue) 729 return ERROR_INVALID_PARAMETER; 730 731 *pValue = NULL; 732 rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData); 733 if (rc != ERROR_SUCCESS) 734 return rc; 735 if (dwType != REG_SZ) 736 return ERROR_FILE_NOT_FOUND; 737 pwszValue = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR)); 738 if (!pwszValue) 739 return ERROR_NOT_ENOUGH_MEMORY; 740 rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)pwszValue, &cbData); 741 if (rc != ERROR_SUCCESS) 742 { 743 HeapFree(GetProcessHeap(), 0, pwszValue); 744 return rc; 745 } 746 /* NULL-terminate the string */ 747 pwszValue[cbData / sizeof(WCHAR)] = '\0'; 748 749 *pValue = pwszValue; 750 return ERROR_SUCCESS; 751 } 752 753 static BOOL 754 IsConsoleBoot(VOID) 755 { 756 HKEY hControlKey = NULL; 757 LPWSTR pwszSystemStartOptions = NULL; 758 LPWSTR pwszCurrentOption, pwszNextOption; /* Pointers into SystemStartOptions */ 759 BOOL bConsoleBoot = FALSE; 760 LONG rc; 761 762 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 763 L"SYSTEM\\CurrentControlSet\\Control", 764 0, 765 KEY_QUERY_VALUE, 766 &hControlKey); 767 if (rc != ERROR_SUCCESS) 768 goto cleanup; 769 770 rc = ReadRegSzKey(hControlKey, L"SystemStartOptions", &pwszSystemStartOptions); 771 if (rc != ERROR_SUCCESS) 772 goto cleanup; 773 774 /* Check for CONSOLE switch in SystemStartOptions */ 775 pwszCurrentOption = pwszSystemStartOptions; 776 while (pwszCurrentOption) 777 { 778 pwszNextOption = wcschr(pwszCurrentOption, L' '); 779 if (pwszNextOption) 780 *pwszNextOption = L'\0'; 781 if (wcsicmp(pwszCurrentOption, L"CONSOLE") == 0) 782 { 783 DPRINT("Found %S. Switching to console boot\n", pwszCurrentOption); 784 bConsoleBoot = TRUE; 785 goto cleanup; 786 } 787 pwszCurrentOption = pwszNextOption ? pwszNextOption + 1 : NULL; 788 } 789 790 cleanup: 791 if (hControlKey != NULL) 792 RegCloseKey(hControlKey); 793 if (pwszSystemStartOptions) 794 HeapFree(GetProcessHeap(), 0, pwszSystemStartOptions); 795 return bConsoleBoot; 796 } 797 798 static BOOL 799 CommonInstall(VOID) 800 { 801 HANDLE hThread = NULL; 802 BOOL bResult = FALSE; 803 804 hSysSetupInf = SetupOpenInfFileW(L"syssetup.inf", 805 NULL, 806 INF_STYLE_WIN4, 807 NULL); 808 if (hSysSetupInf == INVALID_HANDLE_VALUE) 809 { 810 FatalError("SetupOpenInfFileW() failed to open 'syssetup.inf' (Error: %lu)\n", GetLastError()); 811 return FALSE; 812 } 813 814 if (!InstallSysSetupInfDevices()) 815 { 816 FatalError("InstallSysSetupInfDevices() failed!\n"); 817 goto Exit; 818 } 819 820 if(!InstallSysSetupInfComponents()) 821 { 822 FatalError("InstallSysSetupInfComponents() failed!\n"); 823 goto Exit; 824 } 825 826 if (!IsConsoleBoot()) 827 { 828 hThread = CreateThread(NULL, 829 0, 830 ShowStatusMessageThread, 831 NULL, 832 0, 833 NULL); 834 } 835 836 if (!EnableUserModePnpManager()) 837 { 838 FatalError("EnableUserModePnpManager() failed!\n"); 839 goto Exit; 840 } 841 842 if (CMP_WaitNoPendingInstallEvents(INFINITE) != WAIT_OBJECT_0) 843 { 844 FatalError("CMP_WaitNoPendingInstallEvents() failed!\n"); 845 goto Exit; 846 } 847 848 bResult = TRUE; 849 850 Exit: 851 852 if (bResult == FALSE) 853 { 854 SetupCloseInfFile(hSysSetupInf); 855 } 856 857 if (hThread != NULL) 858 { 859 PostThreadMessage(GetThreadId(hThread), WM_QUIT, 0, 0); 860 WaitForSingleObject(hThread, INFINITE); 861 CloseHandle(hThread); 862 } 863 864 return bResult; 865 } 866 867 static 868 DWORD 869 InstallLiveCD(VOID) 870 { 871 STARTUPINFOW StartupInfo; 872 PROCESS_INFORMATION ProcessInformation; 873 BOOL bRes; 874 875 if (!CommonInstall()) 876 goto error; 877 878 /* Install the TCP/IP protocol driver */ 879 bRes = InstallNetworkComponent(L"MS_TCPIP"); 880 if (!bRes && GetLastError() != ERROR_FILE_NOT_FOUND) 881 { 882 DPRINT("InstallNetworkComponent() failed with error 0x%lx\n", GetLastError()); 883 } 884 else 885 { 886 /* Start the TCP/IP protocol driver */ 887 SetupStartService(L"Tcpip", FALSE); 888 SetupStartService(L"Dhcp", FALSE); 889 SetupStartService(L"Dnscache", FALSE); 890 } 891 892 /* Register components */ 893 _SEH2_TRY 894 { 895 if (!SetupInstallFromInfSectionW(NULL, 896 hSysSetupInf, L"RegistrationPhase2", 897 SPINST_ALL, 898 0, NULL, 0, NULL, NULL, NULL, NULL)) 899 { 900 DPRINT1("SetupInstallFromInfSectionW failed!\n"); 901 } 902 903 RegisterTypeLibraries(hSysSetupInf, L"TypeLibraries"); 904 } 905 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 906 { 907 DPRINT1("Catching exception\n"); 908 } 909 _SEH2_END; 910 911 SetupCloseInfFile(hSysSetupInf); 912 913 /* Run the shell */ 914 ZeroMemory(&StartupInfo, sizeof(StartupInfo)); 915 StartupInfo.cb = sizeof(StartupInfo); 916 bRes = CreateProcessW(L"userinit.exe", 917 NULL, 918 NULL, 919 NULL, 920 FALSE, 921 0, 922 NULL, 923 NULL, 924 &StartupInfo, 925 &ProcessInformation); 926 if (!bRes) 927 goto error; 928 929 CloseHandle(ProcessInformation.hThread); 930 CloseHandle(ProcessInformation.hProcess); 931 932 return 0; 933 934 error: 935 MessageBoxW( 936 NULL, 937 L"Failed to load LiveCD! You can shutdown your computer, or press ENTER to reboot.", 938 L"ReactOS LiveCD", 939 MB_OK); 940 return 0; 941 } 942 943 944 static BOOL 945 SetSetupType(DWORD dwSetupType) 946 { 947 DWORD dwError; 948 HKEY hKey; 949 950 dwError = RegOpenKeyExW( 951 HKEY_LOCAL_MACHINE, 952 L"SYSTEM\\Setup", 953 0, 954 KEY_SET_VALUE, 955 &hKey); 956 if (dwError != ERROR_SUCCESS) 957 return FALSE; 958 959 dwError = RegSetValueExW( 960 hKey, 961 L"SetupType", 962 0, 963 REG_DWORD, 964 (LPBYTE)&dwSetupType, 965 sizeof(DWORD)); 966 RegCloseKey(hKey); 967 if (dwError != ERROR_SUCCESS) 968 return FALSE; 969 970 return TRUE; 971 } 972 973 static DWORD CALLBACK 974 HotkeyThread(LPVOID Parameter) 975 { 976 ATOM hotkey; 977 MSG msg; 978 979 DPRINT("HotkeyThread start\n"); 980 981 hotkey = GlobalAddAtomW(L"Setup Shift+F10 Hotkey"); 982 983 if (!RegisterHotKey(NULL, hotkey, MOD_SHIFT, VK_F10)) 984 DPRINT1("RegisterHotKey failed with %lu\n", GetLastError()); 985 986 while (GetMessage(&msg, NULL, 0, 0)) 987 { 988 if (msg.hwnd == NULL && msg.message == WM_HOTKEY && msg.wParam == hotkey) 989 { 990 STARTUPINFOW si = { sizeof(si) }; 991 PROCESS_INFORMATION pi; 992 993 if (CreateProcessW(L"cmd.exe", 994 NULL, 995 NULL, 996 NULL, 997 FALSE, 998 CREATE_NEW_CONSOLE, 999 NULL, 1000 NULL, 1001 &si, 1002 &pi)) 1003 { 1004 CloseHandle(pi.hProcess); 1005 CloseHandle(pi.hThread); 1006 } 1007 else 1008 { 1009 DPRINT1("Failed to launch command prompt: %lu\n", GetLastError()); 1010 } 1011 } 1012 } 1013 1014 UnregisterHotKey(NULL, hotkey); 1015 GlobalDeleteAtom(hotkey); 1016 1017 DPRINT("HotkeyThread terminate\n"); 1018 return 0; 1019 } 1020 1021 1022 static 1023 BOOL 1024 InitializeProgramFilesDir(VOID) 1025 { 1026 LONG Error; 1027 HKEY hKey; 1028 DWORD dwLength; 1029 WCHAR szProgramFilesDirPath[MAX_PATH]; 1030 WCHAR szCommonFilesDirPath[MAX_PATH]; 1031 WCHAR szBuffer[MAX_PATH]; 1032 1033 /* Load 'Program Files' location */ 1034 if (!LoadStringW(hDllInstance, 1035 IDS_PROGRAMFILES, 1036 szBuffer, 1037 ARRAYSIZE(szBuffer))) 1038 { 1039 DPRINT1("Error: %lu\n", GetLastError()); 1040 return FALSE; 1041 } 1042 1043 if (!LoadStringW(hDllInstance, 1044 IDS_COMMONFILES, 1045 szCommonFilesDirPath, 1046 ARRAYSIZE(szCommonFilesDirPath))) 1047 { 1048 DPRINT1("Warning: %lu\n", GetLastError()); 1049 } 1050 1051 /* Expand it */ 1052 if (!ExpandEnvironmentStringsW(szBuffer, 1053 szProgramFilesDirPath, 1054 ARRAYSIZE(szProgramFilesDirPath))) 1055 { 1056 DPRINT1("Error: %lu\n", GetLastError()); 1057 return FALSE; 1058 } 1059 1060 wcscpy(szBuffer, szProgramFilesDirPath); 1061 wcscat(szBuffer, L"\\"); 1062 wcscat(szBuffer, szCommonFilesDirPath); 1063 1064 if (!ExpandEnvironmentStringsW(szBuffer, 1065 szCommonFilesDirPath, 1066 ARRAYSIZE(szCommonFilesDirPath))) 1067 { 1068 DPRINT1("Warning: %lu\n", GetLastError()); 1069 } 1070 1071 /* Store it */ 1072 Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1073 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 1074 0, 1075 KEY_SET_VALUE, 1076 &hKey); 1077 if (Error != ERROR_SUCCESS) 1078 { 1079 DPRINT1("Error: %lu\n", Error); 1080 return FALSE; 1081 } 1082 1083 dwLength = (wcslen(szProgramFilesDirPath) + 1) * sizeof(WCHAR); 1084 Error = RegSetValueExW(hKey, 1085 L"ProgramFilesDir", 1086 0, 1087 REG_SZ, 1088 (LPBYTE)szProgramFilesDirPath, 1089 dwLength); 1090 if (Error != ERROR_SUCCESS) 1091 { 1092 DPRINT1("Error: %lu\n", Error); 1093 RegCloseKey(hKey); 1094 return FALSE; 1095 } 1096 1097 dwLength = (wcslen(szCommonFilesDirPath) + 1) * sizeof(WCHAR); 1098 Error = RegSetValueExW(hKey, 1099 L"CommonFilesDir", 1100 0, 1101 REG_SZ, 1102 (LPBYTE)szCommonFilesDirPath, 1103 dwLength); 1104 if (Error != ERROR_SUCCESS) 1105 { 1106 DPRINT1("Warning: %lu\n", Error); 1107 } 1108 1109 RegCloseKey(hKey); 1110 1111 /* Create directory */ 1112 // FIXME: Security! 1113 if (!CreateDirectoryW(szProgramFilesDirPath, NULL)) 1114 { 1115 if (GetLastError() != ERROR_ALREADY_EXISTS) 1116 { 1117 DPRINT1("Error: %lu\n", GetLastError()); 1118 return FALSE; 1119 } 1120 } 1121 1122 /* Create directory */ 1123 // FIXME: Security! 1124 if (!CreateDirectoryW(szCommonFilesDirPath, NULL)) 1125 { 1126 if (GetLastError() != ERROR_ALREADY_EXISTS) 1127 { 1128 DPRINT1("Warning: %lu\n", GetLastError()); 1129 // return FALSE; 1130 } 1131 } 1132 1133 return TRUE; 1134 } 1135 1136 1137 static 1138 VOID 1139 InitializeDefaultUserLocale(VOID) 1140 { 1141 WCHAR szBuffer[80]; 1142 PWSTR ptr; 1143 HKEY hLocaleKey; 1144 DWORD ret; 1145 DWORD dwSize; 1146 LCID lcid; 1147 INT i; 1148 1149 struct {LCTYPE LCType; PWSTR pValue;} LocaleData[] = { 1150 /* Number */ 1151 {LOCALE_SDECIMAL, L"sDecimal"}, 1152 {LOCALE_STHOUSAND, L"sThousand"}, 1153 {LOCALE_SNEGATIVESIGN, L"sNegativeSign"}, 1154 {LOCALE_SPOSITIVESIGN, L"sPositiveSign"}, 1155 {LOCALE_SGROUPING, L"sGrouping"}, 1156 {LOCALE_SLIST, L"sList"}, 1157 {LOCALE_SNATIVEDIGITS, L"sNativeDigits"}, 1158 {LOCALE_INEGNUMBER, L"iNegNumber"}, 1159 {LOCALE_IDIGITS, L"iDigits"}, 1160 {LOCALE_ILZERO, L"iLZero"}, 1161 {LOCALE_IMEASURE, L"iMeasure"}, 1162 {LOCALE_IDIGITSUBSTITUTION, L"NumShape"}, 1163 1164 /* Currency */ 1165 {LOCALE_SCURRENCY, L"sCurrency"}, 1166 {LOCALE_SMONDECIMALSEP, L"sMonDecimalSep"}, 1167 {LOCALE_SMONTHOUSANDSEP, L"sMonThousandSep"}, 1168 {LOCALE_SMONGROUPING, L"sMonGrouping"}, 1169 {LOCALE_ICURRENCY, L"iCurrency"}, 1170 {LOCALE_INEGCURR, L"iNegCurr"}, 1171 {LOCALE_ICURRDIGITS, L"iCurrDigits"}, 1172 1173 /* Time */ 1174 {LOCALE_STIMEFORMAT, L"sTimeFormat"}, 1175 {LOCALE_STIME, L"sTime"}, 1176 {LOCALE_S1159, L"s1159"}, 1177 {LOCALE_S2359, L"s2359"}, 1178 {LOCALE_ITIME, L"iTime"}, 1179 {LOCALE_ITIMEMARKPOSN, L"iTimePrefix"}, 1180 {LOCALE_ITLZERO, L"iTLZero"}, 1181 1182 /* Date */ 1183 {LOCALE_SLONGDATE, L"sLongDate"}, 1184 {LOCALE_SSHORTDATE, L"sShortDate"}, 1185 {LOCALE_SDATE, L"sDate"}, 1186 {LOCALE_IFIRSTDAYOFWEEK, L"iFirstDayOfWeek"}, 1187 {LOCALE_IFIRSTWEEKOFYEAR, L"iFirstWeekOfYear"}, 1188 {LOCALE_IDATE, L"iDate"}, 1189 {LOCALE_ICALENDARTYPE, L"iCalendarType"}, 1190 1191 /* Misc */ 1192 {LOCALE_SCOUNTRY, L"sCountry"}, 1193 {LOCALE_SABBREVLANGNAME, L"sLanguage"}, 1194 {LOCALE_ICOUNTRY, L"iCountry"}, 1195 {0, NULL}}; 1196 1197 ret = RegOpenKeyExW(HKEY_USERS, 1198 L".DEFAULT\\Control Panel\\International", 1199 0, 1200 KEY_READ | KEY_WRITE, 1201 &hLocaleKey); 1202 if (ret != ERROR_SUCCESS) 1203 { 1204 return; 1205 } 1206 1207 dwSize = 9 * sizeof(WCHAR); 1208 ret = RegQueryValueExW(hLocaleKey, 1209 L"Locale", 1210 NULL, 1211 NULL, 1212 (PBYTE)szBuffer, 1213 &dwSize); 1214 if (ret != ERROR_SUCCESS) 1215 goto done; 1216 1217 lcid = (LCID)wcstoul(szBuffer, &ptr, 16); 1218 if (lcid == 0) 1219 goto done; 1220 1221 i = 0; 1222 while (LocaleData[i].pValue != NULL) 1223 { 1224 if (GetLocaleInfoW(lcid, 1225 LocaleData[i].LCType | LOCALE_NOUSEROVERRIDE, 1226 szBuffer, 1227 ARRAYSIZE(szBuffer))) 1228 { 1229 RegSetValueExW(hLocaleKey, 1230 LocaleData[i].pValue, 1231 0, 1232 REG_SZ, 1233 (PBYTE)szBuffer, 1234 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1235 } 1236 1237 i++; 1238 } 1239 1240 done: 1241 RegCloseKey(hLocaleKey); 1242 } 1243 1244 1245 static 1246 DWORD 1247 SaveDefaultUserHive(VOID) 1248 { 1249 WCHAR szDefaultUserHive[MAX_PATH]; 1250 HKEY hUserKey = NULL; 1251 DWORD cchSize; 1252 DWORD dwError; 1253 1254 DPRINT("SaveDefaultUserHive()\n"); 1255 1256 cchSize = ARRAYSIZE(szDefaultUserHive); 1257 GetDefaultUserProfileDirectoryW(szDefaultUserHive, &cchSize); 1258 1259 wcscat(szDefaultUserHive, L"\\ntuser.dat"); 1260 1261 dwError = RegOpenKeyExW(HKEY_USERS, 1262 L".DEFAULT", 1263 0, 1264 KEY_READ, 1265 &hUserKey); 1266 if (dwError != ERROR_SUCCESS) 1267 { 1268 DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError); 1269 return dwError; 1270 } 1271 1272 pSetupEnablePrivilege(L"SeBackupPrivilege", TRUE); 1273 1274 /* Save the Default hive */ 1275 dwError = RegSaveKeyExW(hUserKey, 1276 szDefaultUserHive, 1277 NULL, 1278 REG_STANDARD_FORMAT); 1279 if (dwError == ERROR_ALREADY_EXISTS) 1280 { 1281 WCHAR szBackupHive[MAX_PATH]; 1282 1283 /* Build the backup hive file name by replacing the extension */ 1284 wcscpy(szBackupHive, szDefaultUserHive); 1285 wcscpy(&szBackupHive[wcslen(szBackupHive) - 4], L".bak"); 1286 1287 /* Back up the existing default user hive by renaming it, replacing any possible existing old backup */ 1288 if (!MoveFileExW(szDefaultUserHive, 1289 szBackupHive, 1290 MOVEFILE_REPLACE_EXISTING)) 1291 { 1292 dwError = GetLastError(); 1293 DPRINT1("Failed to create a default-user hive backup '%S', MoveFileExW failed (Error %lu)\n", 1294 szBackupHive, dwError); 1295 } 1296 else 1297 { 1298 /* The backup has been done, retry saving the Default hive */ 1299 dwError = RegSaveKeyExW(hUserKey, 1300 szDefaultUserHive, 1301 NULL, 1302 REG_STANDARD_FORMAT); 1303 } 1304 } 1305 if (dwError != ERROR_SUCCESS) 1306 { 1307 DPRINT1("RegSaveKeyExW() failed (Error %lu)\n", dwError); 1308 } 1309 1310 pSetupEnablePrivilege(L"SeBackupPrivilege", FALSE); 1311 1312 RegCloseKey(hUserKey); 1313 1314 return dwError; 1315 } 1316 1317 1318 static 1319 DWORD 1320 InstallReactOS(VOID) 1321 { 1322 WCHAR szBuffer[MAX_PATH]; 1323 HANDLE token; 1324 TOKEN_PRIVILEGES privs; 1325 HKEY hKey; 1326 HINF hShortcutsInf; 1327 HANDLE hHotkeyThread; 1328 BOOL ret; 1329 1330 InitializeSetupActionLog(FALSE); 1331 LogItem(NULL, L"Installing ReactOS"); 1332 1333 CreateTempDir(L"TEMP"); 1334 CreateTempDir(L"TMP"); 1335 1336 if (!InitializeProgramFilesDir()) 1337 { 1338 FatalError("InitializeProgramFilesDir() failed"); 1339 return 0; 1340 } 1341 1342 if (!InitializeProfiles()) 1343 { 1344 FatalError("InitializeProfiles() failed"); 1345 return 0; 1346 } 1347 1348 InitializeDefaultUserLocale(); 1349 1350 if (GetWindowsDirectoryW(szBuffer, ARRAYSIZE(szBuffer))) 1351 { 1352 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1353 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 1354 0, 1355 KEY_WRITE, 1356 &hKey) == ERROR_SUCCESS) 1357 { 1358 RegSetValueExW(hKey, 1359 L"PathName", 1360 0, 1361 REG_SZ, 1362 (LPBYTE)szBuffer, 1363 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1364 1365 RegSetValueExW(hKey, 1366 L"SystemRoot", 1367 0, 1368 REG_SZ, 1369 (LPBYTE)szBuffer, 1370 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1371 1372 RegCloseKey(hKey); 1373 } 1374 1375 PathAddBackslash(szBuffer); 1376 wcscat(szBuffer, L"system"); 1377 CreateDirectory(szBuffer, NULL); 1378 } 1379 1380 if (SaveDefaultUserHive() != ERROR_SUCCESS) 1381 { 1382 FatalError("SaveDefaultUserHive() failed"); 1383 return 0; 1384 } 1385 1386 if (!CopySystemProfile(0)) 1387 { 1388 FatalError("CopySystemProfile() failed"); 1389 return 0; 1390 } 1391 1392 hHotkeyThread = CreateThread(NULL, 0, HotkeyThread, NULL, 0, NULL); 1393 1394 if (!CommonInstall()) 1395 return 0; 1396 1397 /* Install the TCP/IP protocol driver */ 1398 ret = InstallNetworkComponent(L"MS_TCPIP"); 1399 if (!ret && GetLastError() != ERROR_FILE_NOT_FOUND) 1400 { 1401 DPRINT("InstallNetworkComponent() failed with error 0x%lx\n", GetLastError()); 1402 } 1403 else 1404 { 1405 /* Start the TCP/IP protocol driver */ 1406 SetupStartService(L"Tcpip", FALSE); 1407 SetupStartService(L"Dhcp", FALSE); 1408 SetupStartService(L"Dnscache", FALSE); 1409 } 1410 1411 InstallWizard(); 1412 1413 InstallSecurity(); 1414 1415 SetAutoAdminLogon(); 1416 1417 hShortcutsInf = SetupOpenInfFileW(L"shortcuts.inf", 1418 NULL, 1419 INF_STYLE_WIN4, 1420 NULL); 1421 if (hShortcutsInf == INVALID_HANDLE_VALUE) 1422 { 1423 FatalError("Failed to open shortcuts.inf"); 1424 return 0; 1425 } 1426 1427 if (!CreateShortcuts(hShortcutsInf, L"ShortcutFolders")) 1428 { 1429 FatalError("CreateShortcuts() failed"); 1430 return 0; 1431 } 1432 1433 SetupCloseInfFile(hShortcutsInf); 1434 1435 hShortcutsInf = SetupOpenInfFileW(L"rosapps_shortcuts.inf", 1436 NULL, 1437 INF_STYLE_WIN4, 1438 NULL); 1439 if (hShortcutsInf != INVALID_HANDLE_VALUE) 1440 { 1441 if (!CreateShortcuts(hShortcutsInf, L"ShortcutFolders")) 1442 { 1443 FatalError("CreateShortcuts(rosapps) failed"); 1444 return 0; 1445 } 1446 SetupCloseInfFile(hShortcutsInf); 1447 } 1448 1449 SetupCloseInfFile(hSysSetupInf); 1450 SetSetupType(0); 1451 1452 if (hHotkeyThread) 1453 { 1454 PostThreadMessage(GetThreadId(hHotkeyThread), WM_QUIT, 0, 0); 1455 CloseHandle(hHotkeyThread); 1456 } 1457 1458 LogItem(NULL, L"Installing ReactOS done"); 1459 TerminateSetupActionLog(); 1460 1461 if (AdminInfo.Name != NULL) 1462 RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo.Name); 1463 1464 if (AdminInfo.Domain != NULL) 1465 RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo.Domain); 1466 1467 if (AdminInfo.Password != NULL) 1468 RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo.Password); 1469 1470 /* Get shutdown privilege */ 1471 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) 1472 { 1473 FatalError("OpenProcessToken() failed!"); 1474 return 0; 1475 } 1476 if (!LookupPrivilegeValue(NULL, 1477 SE_SHUTDOWN_NAME, 1478 &privs.Privileges[0].Luid)) 1479 { 1480 FatalError("LookupPrivilegeValue() failed!"); 1481 return 0; 1482 } 1483 privs.PrivilegeCount = 1; 1484 privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 1485 if (AdjustTokenPrivileges(token, 1486 FALSE, 1487 &privs, 1488 0, 1489 (PTOKEN_PRIVILEGES)NULL, 1490 NULL) == 0) 1491 { 1492 FatalError("AdjustTokenPrivileges() failed!"); 1493 return 0; 1494 } 1495 1496 ExitWindowsEx(EWX_REBOOT, 0); 1497 return 0; 1498 } 1499 1500 1501 /* 1502 * Standard Windows-compatible export, which dispatches 1503 * to either 'InstallReactOS' or 'InstallLiveCD'. 1504 */ 1505 INT 1506 WINAPI 1507 InstallWindowsNt(INT argc, WCHAR** argv) 1508 { 1509 INT i; 1510 PWSTR p; 1511 1512 for (i = 0; i < argc; ++i) 1513 { 1514 p = argv[i]; 1515 if (*p == L'-') 1516 { 1517 p++; 1518 1519 // NOTE: On Windows, "mini" means "minimal UI", and can be used 1520 // in addition to "newsetup"; these options are not exclusive. 1521 if (_wcsicmp(p, L"newsetup") == 0) 1522 return (INT)InstallReactOS(); 1523 else if (_wcsicmp(p, L"mini") == 0) 1524 return (INT)InstallLiveCD(); 1525 1526 /* Add support for other switches */ 1527 } 1528 } 1529 1530 return 0; 1531 } 1532 1533 1534 /* 1535 * @unimplemented 1536 */ 1537 DWORD WINAPI 1538 SetupChangeFontSize( 1539 IN HANDLE hWnd, 1540 IN LPCWSTR lpszFontSize) 1541 { 1542 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 1543 return FALSE; 1544 } 1545 1546 /* 1547 * @unimplemented 1548 */ 1549 DWORD WINAPI 1550 SetupChangeLocaleEx(HWND hWnd, 1551 LCID Lcid, 1552 LPCWSTR lpSrcRootPath, 1553 char Unknown, 1554 DWORD dwUnused1, 1555 DWORD dwUnused2) 1556 { 1557 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 1558 return FALSE; 1559 } 1560 1561 /* 1562 * @implemented 1563 */ 1564 DWORD WINAPI 1565 SetupChangeLocale(HWND hWnd, LCID Lcid) 1566 { 1567 return SetupChangeLocaleEx(hWnd, Lcid, NULL, 0, 0, 0); 1568 } 1569 1570 1571 DWORD 1572 WINAPI 1573 SetupStartService( 1574 LPCWSTR lpServiceName, 1575 BOOL bWait) 1576 { 1577 SC_HANDLE hManager = NULL; 1578 SC_HANDLE hService = NULL; 1579 DWORD dwError = ERROR_SUCCESS; 1580 1581 hManager = OpenSCManagerW(NULL, 1582 NULL, 1583 SC_MANAGER_ALL_ACCESS); 1584 if (hManager == NULL) 1585 { 1586 dwError = GetLastError(); 1587 goto done; 1588 } 1589 1590 hService = OpenServiceW(hManager, 1591 lpServiceName, 1592 SERVICE_START); 1593 if (hService == NULL) 1594 { 1595 dwError = GetLastError(); 1596 goto done; 1597 } 1598 1599 if (!StartService(hService, 0, NULL)) 1600 { 1601 dwError = GetLastError(); 1602 goto done; 1603 } 1604 1605 done: 1606 if (hService != NULL) 1607 CloseServiceHandle(hService); 1608 1609 if (hManager != NULL) 1610 CloseServiceHandle(hManager); 1611 1612 return dwError; 1613 } 1614