- Added a new start menu folder "Accessibility" (IDS_SYS_ACCESSIBILITY)
[reactos.git] / reactos / dll / win32 / syssetup / install.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS system libraries
22 * PURPOSE: System setup
23 * FILE: lib/syssetup/install.c
24 * PROGRAMER: Eric Kohl
25 */
26
27 /* INCLUDES *****************************************************************/
28
29 #define WIN32_NO_STATUS
30 #include <windows.h>
31 #define NTOS_MODE_USER
32 #include <ndk/ntndk.h>
33
34 #include <commctrl.h>
35 #include <stdio.h>
36 #include <io.h>
37 #include <tchar.h>
38 #include <stdlib.h>
39
40 #include <samlib/samlib.h>
41 #include <syssetup/syssetup.h>
42 #include <userenv.h>
43 #include <setupapi.h>
44
45 #include <shlobj.h>
46 #include <objidl.h>
47 #include <shlwapi.h>
48
49 #include "globals.h"
50 #include "resource.h"
51
52 #include <debug.h>
53
54 DWORD WINAPI
55 CMP_WaitNoPendingInstallEvents(DWORD dwTimeout);
56
57 /* GLOBALS ******************************************************************/
58
59 PSID DomainSid = NULL;
60 PSID AdminSid = NULL;
61
62 HINF hSysSetupInf = INVALID_HANDLE_VALUE;
63
64 /* FUNCTIONS ****************************************************************/
65
66 static VOID
67 DebugPrint(char* fmt,...)
68 {
69 char buffer[512];
70 va_list ap;
71
72 va_start(ap, fmt);
73 vsprintf(buffer, fmt, ap);
74 va_end(ap);
75
76 LogItem(SYSSETUP_SEVERITY_FATAL_ERROR, L"Failed");
77
78 strcat(buffer, "\nRebooting now!");
79 MessageBoxA(NULL,
80 buffer,
81 "ReactOS Setup",
82 MB_OK);
83 }
84
85
86 HRESULT CreateShellLink(LPCTSTR linkPath, LPCTSTR cmd, LPCTSTR arg, LPCTSTR dir, LPCTSTR iconPath, int icon_nr, LPCTSTR comment)
87 {
88 IShellLink* psl;
89 IPersistFile* ppf;
90 #ifndef _UNICODE
91 WCHAR buffer[MAX_PATH];
92 #endif /* _UNICODE */
93
94 HRESULT hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (LPVOID*)&psl);
95
96 if (SUCCEEDED(hr))
97 {
98 hr = psl->lpVtbl->SetPath(psl, cmd);
99
100 if (arg)
101 {
102 hr = psl->lpVtbl->SetArguments(psl, arg);
103 }
104
105 if (dir)
106 {
107 hr = psl->lpVtbl->SetWorkingDirectory(psl, dir);
108 }
109
110 if (iconPath)
111 {
112 hr = psl->lpVtbl->SetIconLocation(psl, iconPath, icon_nr);
113 }
114
115 if (comment)
116 {
117 hr = psl->lpVtbl->SetDescription(psl, comment);
118 }
119
120 hr = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf);
121
122 if (SUCCEEDED(hr))
123 {
124 #ifdef _UNICODE
125 hr = ppf->lpVtbl->Save(ppf, linkPath, TRUE);
126 #else /* _UNICODE */
127 MultiByteToWideChar(CP_ACP, 0, linkPath, -1, buffer, MAX_PATH);
128
129 hr = ppf->lpVtbl->Save(ppf, buffer, TRUE);
130 #endif /* _UNICODE */
131
132 ppf->lpVtbl->Release(ppf);
133 }
134
135 psl->lpVtbl->Release(psl);
136 }
137
138 return hr;
139 }
140
141
142 static BOOL
143 CreateShortcut(int csidl, LPCTSTR folder, UINT nIdName, LPCTSTR command, UINT nIdTitle, BOOL bCheckExistence)
144 {
145 TCHAR path[MAX_PATH];
146 TCHAR exeName[MAX_PATH];
147 TCHAR title[256];
148 TCHAR name[256];
149 LPTSTR p = path;
150 TCHAR szWorkingDir[MAX_PATH];
151 LPTSTR lpWorkingDir = NULL;
152 LPTSTR lpFilePart;
153 DWORD dwLen;
154
155 if (ExpandEnvironmentStrings(command,
156 path,
157 sizeof(path) / sizeof(path[0])) == 0)
158 {
159 _tcscpy(path,
160 command);
161 }
162
163 if (bCheckExistence)
164 {
165 if ((_taccess(path, 0 )) == -1)
166 /* Expected error, don't return FALSE */
167 return TRUE;
168 }
169
170 dwLen = GetFullPathName(path,
171 sizeof(szWorkingDir) / sizeof(szWorkingDir[0]),
172 szWorkingDir,
173 &lpFilePart);
174 if (dwLen != 0 && dwLen <= sizeof(szWorkingDir) / sizeof(szWorkingDir[0]))
175 {
176 /* Save the file name */
177 _tcscpy(exeName, lpFilePart);
178
179 if (lpFilePart != NULL)
180 {
181 /* We're only interested in the path. Cut the file name off.
182 Also remove the trailing backslash unless the working directory
183 is only going to be a drive, ie. C:\ */
184 *(lpFilePart--) = _T('\0');
185 if (!(lpFilePart - szWorkingDir == 2 && szWorkingDir[1] == _T(':') &&
186 szWorkingDir[2] == _T('\\')))
187 {
188 *lpFilePart = _T('\0');
189 }
190 }
191
192 lpWorkingDir = szWorkingDir;
193 }
194
195
196 if (!SHGetSpecialFolderPath(0, path, csidl, TRUE))
197 return FALSE;
198
199 if (folder)
200 {
201 p = PathAddBackslash(p);
202 _tcscpy(p, folder);
203 }
204
205 p = PathAddBackslash(p);
206
207 if (!LoadString(hDllInstance, nIdName, name, sizeof(name)/sizeof(name[0])))
208 return FALSE;
209 _tcscpy(p, name);
210
211 if (!LoadString(hDllInstance, nIdTitle, title, sizeof(title)/sizeof(title[0])))
212 return FALSE;
213
214 // FIXME: we should pass 'command' straight in here, but shell32 doesn't expand it
215 return SUCCEEDED(CreateShellLink(path, exeName, _T(""), lpWorkingDir, NULL, 0, title));
216 }
217
218
219 static BOOL
220 CreateShortcutFolder(int csidl, UINT nID, LPTSTR name, int nameLen)
221 {
222 TCHAR path[MAX_PATH];
223 LPTSTR p;
224
225 if (!SHGetSpecialFolderPath(0, path, csidl, TRUE))
226 return FALSE;
227
228 if (!LoadString(hDllInstance, nID, name, nameLen))
229 return FALSE;
230
231 p = PathAddBackslash(path);
232 _tcscpy(p, name);
233
234 return CreateDirectory(path, NULL) || GetLastError()==ERROR_ALREADY_EXISTS;
235 }
236
237
238 static BOOL
239 CreateRandomSid(
240 OUT PSID *Sid)
241 {
242 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
243 LARGE_INTEGER SystemTime;
244 PULONG Seed;
245 NTSTATUS Status;
246
247 NtQuerySystemTime(&SystemTime);
248 Seed = &SystemTime.u.LowPart;
249
250 Status = RtlAllocateAndInitializeSid(
251 &SystemAuthority,
252 4,
253 SECURITY_NT_NON_UNIQUE,
254 RtlUniform(Seed),
255 RtlUniform(Seed),
256 RtlUniform(Seed),
257 SECURITY_NULL_RID,
258 SECURITY_NULL_RID,
259 SECURITY_NULL_RID,
260 SECURITY_NULL_RID,
261 Sid);
262 return NT_SUCCESS(Status);
263 }
264
265
266 static VOID
267 AppendRidToSid(
268 OUT PSID *Dst,
269 IN PSID Src,
270 IN ULONG NewRid)
271 {
272 ULONG Rid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
273 UCHAR RidCount;
274 ULONG i;
275
276 RidCount = *RtlSubAuthorityCountSid (Src);
277
278 for (i = 0; i < RidCount; i++)
279 Rid[i] = *RtlSubAuthoritySid (Src, i);
280
281 if (RidCount < 8)
282 {
283 Rid[RidCount] = NewRid;
284 RidCount++;
285 }
286
287 RtlAllocateAndInitializeSid(
288 RtlIdentifierAuthoritySid(Src),
289 RidCount,
290 Rid[0],
291 Rid[1],
292 Rid[2],
293 Rid[3],
294 Rid[4],
295 Rid[5],
296 Rid[6],
297 Rid[7],
298 Dst);
299 }
300
301
302 static VOID
303 CreateTempDir(
304 IN LPCWSTR VarName)
305 {
306 TCHAR szTempDir[MAX_PATH];
307 TCHAR szBuffer[MAX_PATH];
308 DWORD dwLength;
309 HKEY hKey;
310
311 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
312 _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"),
313 0,
314 KEY_QUERY_VALUE,
315 &hKey))
316 {
317 DebugPrint("Error: %lu\n", GetLastError());
318 return;
319 }
320
321 /* Get temp dir */
322 dwLength = MAX_PATH * sizeof(TCHAR);
323 if (RegQueryValueEx(hKey,
324 VarName,
325 NULL,
326 NULL,
327 (LPBYTE)szBuffer,
328 &dwLength))
329 {
330 DebugPrint("Error: %lu\n", GetLastError());
331 RegCloseKey(hKey);
332 return;
333 }
334
335 /* Expand it */
336 if (!ExpandEnvironmentStrings(szBuffer,
337 szTempDir,
338 MAX_PATH))
339 {
340 DebugPrint("Error: %lu\n", GetLastError());
341 RegCloseKey(hKey);
342 return;
343 }
344
345 /* Create profiles directory */
346 if (!CreateDirectory(szTempDir, NULL))
347 {
348 if (GetLastError() != ERROR_ALREADY_EXISTS)
349 {
350 DebugPrint("Error: %lu\n", GetLastError());
351 RegCloseKey(hKey);
352 return;
353 }
354 }
355
356 RegCloseKey(hKey);
357 }
358
359
360 BOOL
361 ProcessSysSetupInf(VOID)
362 {
363 INFCONTEXT InfContext;
364 TCHAR LineBuffer[256];
365 DWORD LineLength;
366
367 if (!SetupFindFirstLine(hSysSetupInf,
368 _T("DeviceInfsToInstall"),
369 NULL,
370 &InfContext))
371 {
372 return FALSE;
373 }
374
375 do
376 {
377 if (!SetupGetStringField(&InfContext,
378 0,
379 LineBuffer,
380 sizeof(LineBuffer)/sizeof(LineBuffer[0]),
381 &LineLength))
382 {
383 return FALSE;
384 }
385
386 if (!SetupDiInstallClass(NULL, LineBuffer, DI_QUIETINSTALL, NULL))
387 {
388 return FALSE;
389 }
390 }
391 while (SetupFindNextLine(&InfContext, &InfContext));
392
393 return TRUE;
394 }
395
396
397 static BOOL
398 EnableUserModePnpManager(VOID)
399 {
400 SC_HANDLE hSCManager = NULL;
401 SC_HANDLE hService = NULL;
402 BOOL ret = FALSE;
403
404 hSCManager = OpenSCManager(NULL, NULL, 0);
405 if (hSCManager == NULL)
406 goto cleanup;
407
408 hService = OpenService(hSCManager, _T("PlugPlay"), SERVICE_CHANGE_CONFIG | SERVICE_START);
409 if (hService == NULL)
410 goto cleanup;
411
412 ret = ChangeServiceConfig(
413 hService,
414 SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE,
415 NULL, NULL, NULL, NULL, NULL, NULL, NULL);
416 if (!ret)
417 goto cleanup;
418
419 ret = StartService(hService, 0, NULL);
420 if (!ret)
421 goto cleanup;
422
423 ret = TRUE;
424
425 cleanup:
426 if (hSCManager != NULL)
427 CloseServiceHandle(hSCManager);
428 if (hService != NULL)
429 CloseServiceHandle(hService);
430 return ret;
431 }
432
433
434 static BOOL CALLBACK
435 StatusMessageWindowProc(
436 IN HWND hwndDlg,
437 IN UINT uMsg,
438 IN WPARAM wParam,
439 IN LPARAM lParam)
440 {
441 UNREFERENCED_PARAMETER(wParam);
442
443 switch (uMsg)
444 {
445 case WM_INITDIALOG:
446 {
447 TCHAR szMsg[256];
448
449 if (!LoadString(hDllInstance, IDS_STATUS_INSTALL_DEV, szMsg, sizeof(szMsg)/sizeof(szMsg[0])))
450 return FALSE;
451 SetDlgItemText(hwndDlg, IDC_STATUSLABEL, szMsg);
452 return TRUE;
453 }
454 }
455 return FALSE;
456 }
457
458
459 static DWORD WINAPI
460 ShowStatusMessageThread(
461 IN LPVOID lpParameter)
462 {
463 HWND *phWnd = (HWND *)lpParameter;
464 HWND hWnd;
465 MSG Msg;
466
467 hWnd = CreateDialogParam(
468 hDllInstance,
469 MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG),
470 GetDesktopWindow(),
471 StatusMessageWindowProc,
472 (LPARAM)NULL);
473 if (!hWnd)
474 return 0;
475 *phWnd = hWnd;
476
477 ShowWindow(hWnd, SW_SHOW);
478
479 /* Message loop for the Status window */
480 while (GetMessage(&Msg, NULL, 0, 0))
481 {
482 TranslateMessage(&Msg);
483 DispatchMessage(&Msg);
484 }
485
486 return 0;
487 }
488
489 static BOOL
490 CommonInstall(VOID)
491 {
492 HWND hWnd = NULL;
493
494 hSysSetupInf = SetupOpenInfFileW(
495 L"syssetup.inf",
496 NULL,
497 INF_STYLE_WIN4,
498 NULL);
499 if (hSysSetupInf == INVALID_HANDLE_VALUE)
500 {
501 DebugPrint("SetupOpenInfFileW() failed to open 'syssetup.inf' (Error: %lu)\n", GetLastError());
502 return FALSE;
503 }
504
505 if (!ProcessSysSetupInf())
506 {
507 DebugPrint("ProcessSysSetupInf() failed!\n");
508 SetupCloseInfFile(hSysSetupInf);
509 return FALSE;
510 }
511
512 CreateThread(
513 NULL,
514 0,
515 ShowStatusMessageThread,
516 (LPVOID)&hWnd,
517 0,
518 NULL);
519
520 if (!EnableUserModePnpManager())
521 {
522 DebugPrint("EnableUserModePnpManager() failed!\n");
523 SetupCloseInfFile(hSysSetupInf);
524 EndDialog(hWnd, 0);
525 return FALSE;
526 }
527
528 if (CMP_WaitNoPendingInstallEvents(INFINITE) != WAIT_OBJECT_0)
529 {
530 DebugPrint("CMP_WaitNoPendingInstallEvents() failed!\n");
531 SetupCloseInfFile(hSysSetupInf);
532 EndDialog(hWnd, 0);
533 return FALSE;
534 }
535
536 EndDialog(hWnd, 0);
537 return TRUE;
538 }
539
540 DWORD WINAPI
541 InstallLiveCD(IN HINSTANCE hInstance)
542 {
543 STARTUPINFO StartupInfo;
544 PROCESS_INFORMATION ProcessInformation;
545 BOOL res;
546
547 if (!CommonInstall())
548 goto cleanup;
549 SetupCloseInfFile(hSysSetupInf);
550
551 /* Run the shell */
552 StartupInfo.cb = sizeof(StartupInfo);
553 StartupInfo.lpReserved = NULL;
554 StartupInfo.lpDesktop = NULL;
555 StartupInfo.lpTitle = NULL;
556 StartupInfo.dwFlags = 0;
557 StartupInfo.cbReserved2 = 0;
558 StartupInfo.lpReserved2 = 0;
559 res = CreateProcess(
560 _T("userinit.exe"),
561 NULL,
562 NULL,
563 NULL,
564 FALSE,
565 0,
566 NULL,
567 NULL,
568 &StartupInfo,
569 &ProcessInformation);
570 if (!res)
571 goto cleanup;
572
573 return 0;
574
575 cleanup:
576 MessageBoxA(
577 NULL,
578 "You can shutdown your computer, or press ENTER to reboot",
579 "ReactOS LiveCD",
580 MB_OK);
581 return 0;
582 }
583
584
585 static BOOL
586 CreateShortcuts(VOID)
587 {
588 TCHAR szFolder[256];
589
590 CoInitialize(NULL);
591
592 /* Create desktop shortcuts */
593 CreateShortcut(CSIDL_DESKTOP, NULL, IDS_SHORT_CMD, _T("%SystemRoot%\\system32\\cmd.exe"), IDS_CMT_CMD, FALSE);
594
595 /* Create program startmenu shortcuts */
596 CreateShortcut(CSIDL_PROGRAMS, NULL, IDS_SHORT_EXPLORER, _T("%SystemRoot%\\explorer.exe"), IDS_CMT_EXPLORER, FALSE);
597 CreateShortcut(CSIDL_PROGRAMS, NULL, IDS_SHORT_DOWNLOADER, _T("%SystemRoot%\\system32\\downloader.exe"), IDS_CMT_DOWNLOADER, TRUE);
598
599 /* Create administrative tools startmenu shortcuts */
600 CreateShortcut(CSIDL_COMMON_ADMINTOOLS, NULL, IDS_SHORT_SERVICE, _T("%SystemRoot%\\system32\\servman.exe"), IDS_CMT_SERVMAN, FALSE);
601 CreateShortcut(CSIDL_COMMON_ADMINTOOLS, NULL, IDS_SHORT_DEVICE, _T("%SystemRoot%\\system32\\devmgmt.exe"), IDS_CMT_DEVMGMT, FALSE);
602
603 /* Create and fill Accessories subfolder */
604 if (CreateShortcutFolder(CSIDL_PROGRAMS, IDS_ACCESSORIES, szFolder, sizeof(szFolder)/sizeof(szFolder[0])))
605 {
606 CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_CALC, _T("%SystemRoot%\\system32\\calc.exe"), IDS_CMT_CALC, FALSE);
607 CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_CMD, _T("%SystemRoot%\\system32\\cmd.exe"), IDS_CMT_CMD, FALSE);
608 CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_NOTEPAD, _T("%SystemRoot%\\system32\\notepad.exe"), IDS_CMT_NOTEPAD, FALSE);
609 CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_REGEDIT, _T("%SystemRoot%\\regedit.exe"), IDS_CMT_REGEDIT, FALSE);
610 CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_WORDPAD, _T("%SystemRoot%\\system32\\wordpad.exe"), IDS_CMT_WORDPAD, FALSE);
611 CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_SNAP, _T("%SystemRoot%\\system32\\screenshot.exe"), IDS_CMT_SCREENSHOT, TRUE);
612 }
613
614 /* Creacte System Tools subfolder and fill if the exe is available */
615 if (CreateShortcutFolder(CSIDL_PROGRAMS, IDS_SYS_TOOLS, szFolder, sizeof(szFolder)/sizeof(szFolder[0])))
616 {
617 CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_CHARMAP, _T("%SystemRoot%\\system32\\charmap.exe"), IDS_CMT_CHARMAP, FALSE);
618 }
619
620 /* Creacte Accessibility subfolder and fill if the exe is available */
621 if (CreateShortcutFolder(CSIDL_PROGRAMS, IDS_SYS_ACCESSIBILITY, szFolder, sizeof(szFolder)/sizeof(szFolder[0])))
622 {
623 CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_MAGNIFY, _T("%SystemRoot%\\system32\\magnify.exe"), IDS_CMT_MAGNIFY, FALSE);
624 }
625
626 /* Create Games subfolder and fill if the exe is available */
627 if (CreateShortcutFolder(CSIDL_PROGRAMS, IDS_GAMES, szFolder, sizeof(szFolder)/sizeof(szFolder[0])))
628 {
629 CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_SOLITAIRE, _T("%SystemRoot%\\system32\\sol.exe"), IDS_CMT_SOLITAIRE, FALSE);
630 CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_WINEMINE, _T("%SystemRoot%\\system32\\winemine.exe"), IDS_CMT_WINEMINE, FALSE);
631 }
632
633 CoUninitialize();
634
635 return TRUE;
636 }
637
638 static BOOL
639 SetSetupType(DWORD dwSetupType)
640 {
641 DWORD dwError;
642 HKEY hKey;
643
644 dwError = RegOpenKeyExW(
645 HKEY_LOCAL_MACHINE,
646 L"SYSTEM\\Setup",
647 0,
648 KEY_SET_VALUE,
649 &hKey);
650 if (dwError != ERROR_SUCCESS)
651 return FALSE;
652
653 dwError = RegSetValueExW(
654 hKey,
655 L"SetupType",
656 0,
657 REG_DWORD,
658 (LPBYTE)&dwSetupType,
659 sizeof(DWORD));
660 RegCloseKey(hKey);
661 if (dwError != ERROR_SUCCESS)
662 return FALSE;
663
664 return TRUE;
665 }
666
667 DWORD WINAPI
668 InstallReactOS(HINSTANCE hInstance)
669 {
670 TCHAR szBuffer[MAX_PATH];
671 DWORD LastError;
672 HANDLE token;
673 TOKEN_PRIVILEGES privs;
674
675 InitializeSetupActionLog(FALSE);
676 LogItem(SYSSETUP_SEVERITY_INFORMATION, L"Installing ReactOS");
677
678 /* Set user langage to the system language */
679 SetUserDefaultLCID(GetSystemDefaultLCID());
680 SetThreadLocale(GetSystemDefaultLCID());
681
682 if (!InitializeProfiles())
683 {
684 DebugPrint("InitializeProfiles() failed");
685 return 0;
686 }
687
688 if (!CreateShortcuts())
689 {
690 DebugPrint("InitializeProfiles() failed");
691 return 0;
692 }
693
694 /* Initialize the Security Account Manager (SAM) */
695 if (!SamInitializeSAM())
696 {
697 DebugPrint("SamInitializeSAM() failed!");
698 return 0;
699 }
700
701 /* Create the semi-random Domain-SID */
702 if (!CreateRandomSid(&DomainSid))
703 {
704 DebugPrint("Domain-SID creation failed!");
705 return 0;
706 }
707
708 /* Set the Domain SID (aka Computer SID) */
709 if (!SamSetDomainSid(DomainSid))
710 {
711 DebugPrint("SamSetDomainSid() failed!");
712 RtlFreeSid(DomainSid);
713 return 0;
714 }
715
716 /* Append the Admin-RID */
717 AppendRidToSid(&AdminSid, DomainSid, DOMAIN_USER_RID_ADMIN);
718
719 /* Create the Administrator account */
720 if (!SamCreateUser(L"Administrator", L"", AdminSid))
721 {
722 /* Check what the error was.
723 * If the Admin Account already exists, then it means Setup
724 * wasn't allowed to finish properly. Instead of rebooting
725 * and not completing it, let it restart instead
726 */
727 LastError = GetLastError();
728 if (LastError != ERROR_USER_EXISTS)
729 {
730 DebugPrint("SamCreateUser() failed!");
731 RtlFreeSid(AdminSid);
732 RtlFreeSid(DomainSid);
733 return 0;
734 }
735 }
736
737 RtlFreeSid(AdminSid);
738 RtlFreeSid(DomainSid);
739
740 /* ROS HACK, as long as NtUnloadKey is not implemented */
741 {
742 NTSTATUS Status = NtUnloadKey(NULL);
743 if (Status == STATUS_NOT_IMPLEMENTED)
744 {
745 /* Create the Administrator profile */
746 PROFILEINFOW ProfileInfo;
747 HANDLE hToken;
748 BOOL ret;
749 #define LOGON32_LOGON_NETWORK 3
750 ret = LogonUserW(L"Administrator", L"", L"", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken);
751 if (!ret)
752 {
753 DebugPrint("LogonUserW() failed!");
754 return 0;
755 }
756 ZeroMemory(&ProfileInfo, sizeof(PROFILEINFOW));
757 ProfileInfo.dwSize = sizeof(PROFILEINFOW);
758 ProfileInfo.lpUserName = L"Administrator";
759 ProfileInfo.dwFlags = PI_NOUI;
760 LoadUserProfileW(hToken, &ProfileInfo);
761 CloseHandle(hToken);
762 }
763 else
764 {
765 DPRINT1("ROS HACK not needed anymore. Please remove it\n");
766 }
767 }
768 /* END OF ROS HACK */
769
770 CreateTempDir(L"TEMP");
771 CreateTempDir(L"TMP");
772
773 if (GetWindowsDirectory(szBuffer, sizeof(szBuffer) / sizeof(TCHAR)))
774 {
775 PathAddBackslash(szBuffer);
776 _tcscat(szBuffer, _T("system"));
777 CreateDirectory(szBuffer, NULL);
778 }
779
780 if (!CommonInstall())
781 return 0;
782
783 InstallWizard();
784
785 SetupCloseInfFile(hSysSetupInf);
786 SetSetupType(0);
787
788 LogItem(SYSSETUP_SEVERITY_INFORMATION, L"Installing ReactOS done");
789 TerminateSetupActionLog();
790
791 /* Get shutdown privilege */
792 if (! OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
793 {
794 DebugPrint("OpenProcessToken() failed!");
795 return 0;
796 }
797 if (!LookupPrivilegeValue(
798 NULL,
799 SE_SHUTDOWN_NAME,
800 &privs.Privileges[0].Luid))
801 {
802 DebugPrint("LookupPrivilegeValue() failed!");
803 return 0;
804 }
805 privs.PrivilegeCount = 1;
806 privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
807 if (AdjustTokenPrivileges(
808 token,
809 FALSE,
810 &privs,
811 0,
812 (PTOKEN_PRIVILEGES)NULL,
813 NULL) == 0)
814 {
815 DebugPrint("AdjustTokenPrivileges() failed!");
816 return 0;
817 }
818
819 if (SetupData.BootCDRegtestActive)
820 {
821 /// THE FOLLOWING DPRINT IS FOR THE SYSTEM REGRESSION TOOL
822 /// DO NOT REMOVE!!!
823 DbgPrint("SYSREG_CHECKPOINT:SYSSETUP_COMPLETE\n");
824 }
825
826 ExitWindowsEx(EWX_REBOOT, 0);
827 return 0;
828 }
829
830
831 /*
832 * @unimplemented
833 */
834 DWORD STDCALL
835 SetupChangeFontSize(
836 IN HANDLE hWnd,
837 IN LPCWSTR lpszFontSize)
838 {
839 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
840 return FALSE;
841 }