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