3 * Copyright (C) 2003 ReactOS Team
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.
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.
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.
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
27 /* INCLUDES *****************************************************************/
29 #define WIN32_NO_STATUS
31 #define NTOS_MODE_USER
32 #include <ndk/ntndk.h>
40 #include <samlib/samlib.h>
41 #include <syssetup/syssetup.h>
53 CMP_WaitNoPendingInstallEvents(DWORD dwTimeout
);
55 /* GLOBALS ******************************************************************/
57 PSID DomainSid
= NULL
;
60 HINF hSysSetupInf
= INVALID_HANDLE_VALUE
;
62 /* FUNCTIONS ****************************************************************/
65 DebugPrint(char* fmt
,...)
71 vsprintf(buffer
, fmt
, ap
);
74 strcat(buffer
, "\nRebooting now!");
82 HRESULT
CreateShellLink(LPCTSTR linkPath
, LPCTSTR cmd
, LPCTSTR arg
, LPCTSTR dir
, LPCTSTR iconPath
, int icon_nr
, LPCTSTR comment
)
87 WCHAR buffer
[MAX_PATH
];
90 HRESULT hr
= CoCreateInstance(&CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IShellLink
, (LPVOID
*)&psl
);
94 hr
= psl
->lpVtbl
->SetPath(psl
, cmd
);
98 hr
= psl
->lpVtbl
->SetArguments(psl
, arg
);
103 hr
= psl
->lpVtbl
->SetWorkingDirectory(psl
, dir
);
108 hr
= psl
->lpVtbl
->SetIconLocation(psl
, iconPath
, icon_nr
);
113 hr
= psl
->lpVtbl
->SetDescription(psl
, comment
);
116 hr
= psl
->lpVtbl
->QueryInterface(psl
, &IID_IPersistFile
, (LPVOID
*)&ppf
);
121 hr
= ppf
->lpVtbl
->Save(ppf
, linkPath
, TRUE
);
123 MultiByteToWideChar(CP_ACP
, 0, linkPath
, -1, buffer
, MAX_PATH
);
125 hr
= ppf
->lpVtbl
->Save(ppf
, buffer
, TRUE
);
126 #endif /* _UNICODE */
128 ppf
->lpVtbl
->Release(ppf
);
131 psl
->lpVtbl
->Release(psl
);
139 CreateShortcut(int csidl
, LPCTSTR folder
, LPCTSTR linkName
, LPCTSTR command
, UINT nIdTitle
)
141 TCHAR path
[MAX_PATH
];
145 if (!SHGetSpecialFolderPath(0, path
, csidl
, TRUE
))
150 p
= PathAddBackslash(p
);
154 p
= PathAddBackslash(p
);
155 _tcscpy(p
, linkName
);
157 if (!LoadString(hDllInstance
, nIdTitle
, title
, 256))
160 return SUCCEEDED(CreateShellLink(path
, command
, _T(""), NULL
, NULL
, 0, title
));
165 CreateShortcutFolder(int csidl
, UINT nID
, LPTSTR name
, int nameLen
)
167 TCHAR path
[MAX_PATH
];
170 if (!SHGetSpecialFolderPath(0, path
, csidl
, TRUE
))
173 if (!LoadString(hDllInstance
, nID
, name
, nameLen
))
176 p
= PathAddBackslash(path
);
179 return CreateDirectory(path
, NULL
) || GetLastError()==ERROR_ALREADY_EXISTS
;
184 CreateRandomSid (PSID
*Sid
)
186 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
187 LARGE_INTEGER SystemTime
;
190 NtQuerySystemTime (&SystemTime
);
191 Seed
= &SystemTime
.u
.LowPart
;
193 RtlAllocateAndInitializeSid (&SystemAuthority
,
195 SECURITY_NT_NON_UNIQUE
,
208 AppendRidToSid (PSID
*Dst
,
212 ULONG Rid
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
216 RidCount
= *RtlSubAuthorityCountSid (Src
);
218 for (i
= 0; i
< RidCount
; i
++)
219 Rid
[i
] = *RtlSubAuthoritySid (Src
, i
);
223 Rid
[RidCount
] = NewRid
;
227 RtlAllocateAndInitializeSid (RtlIdentifierAuthoritySid (Src
),
242 CreateTempDir(LPCWSTR VarName
)
244 TCHAR szTempDir
[MAX_PATH
];
245 TCHAR szBuffer
[MAX_PATH
];
249 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
250 _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"),
255 DebugPrint("Error: %lu\n", GetLastError());
260 dwLength
= MAX_PATH
* sizeof(TCHAR
);
261 if (RegQueryValueEx(hKey
,
268 DebugPrint("Error: %lu\n", GetLastError());
274 if (!ExpandEnvironmentStrings(szBuffer
,
278 DebugPrint("Error: %lu\n", GetLastError());
283 /* Create profiles directory */
284 if (!CreateDirectory(szTempDir
, NULL
))
286 if (GetLastError() != ERROR_ALREADY_EXISTS
)
288 DebugPrint("Error: %lu\n", GetLastError());
299 ProcessSysSetupInf(VOID
)
301 INFCONTEXT InfContext
;
302 TCHAR LineBuffer
[256];
305 if (!SetupFindFirstLine(hSysSetupInf
,
306 _T("DeviceInfsToInstall"),
315 if (!SetupGetStringField(&InfContext
,
324 if (!SetupDiInstallClass(NULL
, LineBuffer
, DI_QUIETINSTALL
, NULL
))
329 while (SetupFindNextLine(&InfContext
, &InfContext
));
336 EnableUserModePnpManager(VOID
)
338 SC_HANDLE hSCManager
= NULL
;
339 SC_HANDLE hService
= NULL
;
342 hSCManager
= OpenSCManager(NULL
, NULL
, 0);
343 if (hSCManager
== NULL
)
346 hService
= OpenService(hSCManager
, _T("PlugPlay"), SERVICE_CHANGE_CONFIG
| SERVICE_START
);
347 if (hService
== NULL
)
350 ret
= ChangeServiceConfig(
352 SERVICE_NO_CHANGE
, SERVICE_AUTO_START
, SERVICE_NO_CHANGE
,
353 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
357 ret
= StartService(hService
, 0, NULL
);
364 if (hSCManager
!= NULL
)
365 CloseServiceHandle(hSCManager
);
366 if (hService
!= NULL
)
367 CloseServiceHandle(hService
);
373 InstallLiveCD (HINSTANCE hInstance
)
380 TCHAR CommandLine
[MAX_PATH
];
381 STARTUPINFO StartupInfo
;
382 PROCESS_INFORMATION ProcessInformation
;
385 hSysSetupInf
= SetupOpenInfFileW(
390 if (hSysSetupInf
== INVALID_HANDLE_VALUE
)
392 DebugPrint("SetupOpenInfFileW() failed to open 'syssetup.inf' (Error: %lu)\n", GetLastError());
396 if (!ProcessSysSetupInf())
398 DebugPrint("ProcessSysSetupInf() failed!\n");
402 SetupCloseInfFile(hSysSetupInf
);
404 if (!EnableUserModePnpManager())
406 DebugPrint("EnableUserModePnpManager() failed!\n");
410 /* Load the default shell */
413 TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), /* FIXME: should be REGSTR_PATH_WINLOGON */
417 if (rc
!= ERROR_SUCCESS
)
419 rc
= RegQueryValueEx(
426 if (rc
!= ERROR_SUCCESS
)
428 else if (dwType
!= REG_SZ
&& dwType
!= REG_EXPAND_SZ
)
430 else if (requiredSize
> (MAX_PATH
- 1) * sizeof(TCHAR
))
432 Shell
= HeapAlloc(GetProcessHeap(), 0, requiredSize
+ sizeof(TCHAR
));
435 Shell
[requiredSize
/ sizeof(WCHAR
)] = '\0';
436 rc
= RegQueryValueEx(
443 if (rc
!= ERROR_SUCCESS
)
445 if (dwType
== REG_EXPAND_SZ
)
446 ExpandEnvironmentStrings(Shell
, CommandLine
, MAX_PATH
);
447 else if (dwType
== REG_SZ
)
448 _tcscpy(CommandLine
, Shell
);
451 StartupInfo
.cb
= sizeof(StartupInfo
);
452 StartupInfo
.lpReserved
= NULL
;
453 StartupInfo
.lpDesktop
= NULL
;
454 StartupInfo
.lpTitle
= NULL
;
455 StartupInfo
.dwFlags
= 0;
456 StartupInfo
.cbReserved2
= 0;
457 StartupInfo
.lpReserved2
= 0;
468 &ProcessInformation
);
472 /* Wait for process termination */
473 WaitForSingleObject(ProcessInformation
.hProcess
, INFINITE
);
478 HeapFree(GetProcessHeap(), 0, Shell
);
481 "You can shutdown your computer, or press ENTER to reboot",
489 InstallReactOS (HINSTANCE hInstance
)
491 TCHAR sAccessories
[256];
493 TCHAR szBuffer
[MAX_PATH
];
496 OutputDebugStringA ("InstallReactOS() called\n");
498 if (!InitializeSetupActionLog (FALSE
))
500 OutputDebugStringA ("InitializeSetupActionLog() failed\n");
503 LogItem (SYSSETUP_SEVERITY_INFORMATION
,
504 L
"ReactOS Setup starting");
506 LogItem (SYSSETUP_SEVERITY_FATAL_ERROR
,
509 LogItem (SYSSETUP_SEVERITY_INFORMATION
,
510 L
"ReactOS Setup finished");
512 TerminateSetupActionLog ();
515 UNICODE_STRING SidString
;
519 if (!InitializeProfiles ())
521 DebugPrint ("InitializeProfiles() failed\n");
527 /* create desktop shortcuts */
528 CreateShortcut(CSIDL_DESKTOP
, NULL
, _T("Command Prompt.lnk"), _T("cmd.exe"), IDS_CMT_CMD
);
530 /* create program startmenu shortcuts */
531 CreateShortcut(CSIDL_PROGRAMS
, NULL
, _T("winefile.lnk"), _T("winefile.exe"), IDS_CMT_WINEFILE
);
532 CreateShortcut(CSIDL_PROGRAMS
, NULL
, _T("ibrowser.lnk"), _T("ibrowser.exe"), IDS_CMT_IBROWSER
);
533 CreateShortcut(CSIDL_PROGRAMS
, NULL
, _T("Get Firefox.lnk"), _T("getfirefox.exe"), IDS_CMT_GETFIREFOX
);
535 /* create administritive tools startmenu shortcuts */
536 CreateShortcut(CSIDL_ADMINTOOLS
, NULL
, _T("Services.lnk"), _T("servman.exe"), IDS_CMT_SERVMAN
);
538 /* create and fill Accessories subfolder */
539 if (CreateShortcutFolder(CSIDL_PROGRAMS
, IDS_ACCESSORIES
, sAccessories
, 256))
541 CreateShortcut(CSIDL_PROGRAMS
, sAccessories
, _T("Calculator.lnk"), _T("calc.exe"), IDS_CMT_CALC
);
542 CreateShortcut(CSIDL_PROGRAMS
, sAccessories
, _T("Command Prompt.lnk"), _T("cmd.exe"), IDS_CMT_CMD
);
543 CreateShortcut(CSIDL_PROGRAMS
, sAccessories
, _T("Notepad.lnk"), _T("notepad.exe"), IDS_CMT_NOTEPAD
);
544 CreateShortcut(CSIDL_PROGRAMS
, sAccessories
, _T("ReactOS Explorer.lnk"), _T("explorer.exe"), IDS_CMT_EXPLORER
);
545 CreateShortcut(CSIDL_PROGRAMS
, sAccessories
, _T("Regedit.lnk"), _T("regedit.exe"), IDS_CMT_REGEDIT
);
546 CreateShortcut(CSIDL_PROGRAMS
, sAccessories
, _T("WordPad.lnk"), _T("wordpad.exe"), IDS_CMT_WORDPAD
);
547 CreateShortcut(CSIDL_PROGRAMS
, sAccessories
, _T("SnapShot.lnk"), _T("screenshot.exe"), IDS_CMT_SCREENSHOT
);
551 /* create Games subfolder and fill if the exe is available */
552 if (CreateShortcutFolder(CSIDL_PROGRAMS
, IDS_GAMES
, sGames
, 256))
554 CreateShortcut(CSIDL_PROGRAMS
, sGames
, _T("Solitaire.lnk"), _T("sol.exe"), IDS_CMT_SOLITAIRE
);
555 CreateShortcut(CSIDL_PROGRAMS
, sGames
, _T("WineMine.lnk"), _T("winemine.exe"), IDS_CMT_WINEMINE
);
560 /* Create the semi-random Domain-SID */
561 CreateRandomSid (&DomainSid
);
562 if (DomainSid
== NULL
)
564 DebugPrint ("Domain-SID creation failed!\n");
569 RtlConvertSidToUnicodeString (&SidString
, DomainSid
, TRUE
);
570 DebugPrint ("Domain-SID: %wZ\n", &SidString
);
571 RtlFreeUnicodeString (&SidString
);
574 /* Initialize the Security Account Manager (SAM) */
575 if (!SamInitializeSAM ())
577 DebugPrint ("SamInitializeSAM() failed!\n");
578 RtlFreeSid (DomainSid
);
582 /* Set the Domain SID (aka Computer SID) */
583 if (!SamSetDomainSid (DomainSid
))
585 DebugPrint ("SamSetDomainSid() failed!\n");
586 RtlFreeSid (DomainSid
);
590 /* Append the Admin-RID */
591 AppendRidToSid(&AdminSid
, DomainSid
, DOMAIN_USER_RID_ADMIN
);
594 RtlConvertSidToUnicodeString (&SidString
, DomainSid
, TRUE
);
595 DebugPrint ("Admin-SID: %wZ\n", &SidString
);
596 RtlFreeUnicodeString (&SidString
);
599 /* Create the Administrator account */
600 if (!SamCreateUser(L
"Administrator", L
"", AdminSid
))
602 /* Check what the error was.
603 * If the Admin Account already exists, then it means Setup
604 * wasn't allowed to finish properly. Instead of rebooting
605 * and not completing it, let it restart instead
607 LastError
= GetLastError();
608 if (LastError
!= ERROR_USER_EXISTS
)
610 DebugPrint("SamCreateUser() failed!\n");
611 RtlFreeSid(AdminSid
);
612 RtlFreeSid(DomainSid
);
617 /* Create the Administrator profile */
618 if (!CreateUserProfileW(AdminSid
, L
"Administrator"))
620 DebugPrint("CreateUserProfileW() failed!\n");
621 RtlFreeSid(AdminSid
);
622 RtlFreeSid(DomainSid
);
626 RtlFreeSid(AdminSid
);
627 RtlFreeSid(DomainSid
);
629 CreateTempDir(L
"TEMP");
630 CreateTempDir(L
"TMP");
632 if (GetWindowsDirectory(szBuffer
, sizeof(szBuffer
) / sizeof(TCHAR
)))
634 PathAddBackslash(szBuffer
);
635 _tcscat(szBuffer
, _T("system"));
636 CreateDirectory(szBuffer
, NULL
);
639 hSysSetupInf
= SetupOpenInfFileW(L
"syssetup.inf",
643 if (hSysSetupInf
== INVALID_HANDLE_VALUE
)
645 DebugPrint("SetupOpenInfFileW() failed to open 'syssetup.inf' (Error: %lu)\n", GetLastError());
649 if (!ProcessSysSetupInf())
651 DebugPrint("ProcessSysSetupInf() failed!\n");
655 if (!EnableUserModePnpManager())
657 DebugPrint("EnableUserModePnpManager() failed!\n");
661 if (CMP_WaitNoPendingInstallEvents(INFINITE
) != WAIT_OBJECT_0
)
663 DebugPrint("CMP_WaitNoPendingInstallEvents() failed!\n");
669 SetupCloseInfFile(hSysSetupInf
);
679 SetupChangeFontSize(HANDLE hWnd
,
680 LPCWSTR lpszFontSize
)