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