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
FatalError(char * pszFmt,...)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
CreateShellLink(LPCWSTR pszLinkPath,LPCWSTR pszCmd,LPCWSTR pszArg,LPCWSTR pszDir,LPCWSTR pszIconPath,INT iIconNr,LPCWSTR pszComment)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
CreateShortcut(LPCWSTR pszFolder,LPCWSTR pszName,LPCWSTR pszCommand,LPCWSTR pszDescription,INT iIconNr,LPCWSTR pszWorkingDir,LPCWSTR pszArgs)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
CreateShortcutsFromSection(HINF hinf,LPWSTR pszSection,LPCWSTR pszFolder)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
CreateShortcuts(HINF hinf,LPCWSTR szSection)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
CreateTempDir(IN LPCWSTR VarName)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
InstallSysSetupInfDevices(VOID)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
InstallSysSetupInfComponents(VOID)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
RegisterTypeLibraries(HINF hinf,LPCWSTR szSection)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
EnableUserModePnpManager(VOID)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
AdjustStatusMessageWindow(HWND hwndDlg,PDLG_DATA pDlgData)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
StatusMessageWindowProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)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
ShowStatusMessageThread(IN LPVOID lpParameter)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
ReadRegSzKey(IN HKEY hKey,IN LPCWSTR pszKey,OUT LPWSTR * pValue)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
IsConsoleBoot(VOID)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
CommonInstall(VOID)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
InstallLiveCD(VOID)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
SetSetupType(DWORD dwSetupType)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
HotkeyThread(LPVOID Parameter)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
InitializeProgramFilesDir(VOID)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
InitializeDefaultUserLocale(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
SaveDefaultUserHive(VOID)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
InstallReactOS(VOID)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
InstallWindowsNt(INT argc,WCHAR ** argv)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
SetupChangeFontSize(IN HANDLE hWnd,IN LPCWSTR lpszFontSize)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
SetupChangeLocaleEx(HWND hWnd,LCID Lcid,LPCWSTR lpSrcRootPath,char Unknown,DWORD dwUnused1,DWORD dwUnused2)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
SetupChangeLocale(HWND hWnd,LCID Lcid)1635 SetupChangeLocale(HWND hWnd, LCID Lcid)
1636 {
1637 return SetupChangeLocaleEx(hWnd, Lcid, NULL, 0, 0, 0);
1638 }
1639
1640
1641 DWORD
1642 WINAPI
SetupStartService(LPCWSTR lpServiceName,BOOL bWait)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