* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: install.c,v 1.6 2004/01/16 21:33:23 ekohl Exp $
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: System setup
* FILE: lib/syssetup/install.c
- * PROGRAMER: Eric Kohl (ekohl@rz-online.de)
+ * PROGRAMER: Eric Kohl
*/
/* INCLUDES *****************************************************************/
-#include <ntos.h>
#include <windows.h>
+#define NTOS_MODE_USER
+#include <ndk/ntndk.h>
+
+#include <commctrl.h>
#include <stdio.h>
+#include <tchar.h>
+#include <stdlib.h>
-#include <syssetup.h>
+#include <samlib/samlib.h>
+#include <syssetup/syssetup.h>
+#include <userenv.h>
+#include <setupapi.h>
-#if 0
-VOID Wizard (VOID);
-#endif
+#include <shlobj.h>
+#include <objidl.h>
+#include <shlwapi.h>
+
+#include "globals.h"
+#include "resource.h"
-/* userenv.dll */
-BOOL WINAPI InitializeProfiles (VOID);
-BOOL WINAPI CreateUserProfileW (PSID Sid, LPCWSTR lpUserName);
+#define VMWINST
/* GLOBALS ******************************************************************/
PSID DomainSid = NULL;
PSID AdminSid = NULL;
+HINF hSysSetupInf = INVALID_HANDLE_VALUE;
/* FUNCTIONS ****************************************************************/
vsprintf(buffer, fmt, ap);
va_end(ap);
- OutputDebugStringA(buffer);
+ strcat(buffer, "\nRebooting now!");
+ MessageBoxA(NULL,
+ buffer,
+ "ReactOS Setup",
+ MB_OK);
+}
+
+
+#ifdef VMWINST
+static BOOL
+RunVMWInstall(VOID)
+{
+ PROCESS_INFORMATION ProcInfo;
+ STARTUPINFO si;
+ WCHAR InstallName[] = L"vmwinst.exe";
+
+ ZeroMemory(&si, sizeof(STARTUPINFO));
+ si.cb = sizeof(STARTUPINFO);
+
+ if(CreateProcess(NULL, InstallName, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS,
+ NULL, NULL, &si, &ProcInfo))
+ {
+ WaitForSingleObject(ProcInfo.hProcess, INFINITE);
+ CloseHandle(ProcInfo.hThread);
+ CloseHandle(ProcInfo.hProcess);
+ return TRUE;
+ }
+ return FALSE;
+}
+#endif
+
+
+HRESULT CreateShellLink(LPCTSTR linkPath, LPCTSTR cmd, LPCTSTR arg, LPCTSTR dir, LPCTSTR iconPath, int icon_nr, LPCTSTR comment)
+{
+ IShellLink* psl;
+ IPersistFile* ppf;
+#ifndef _UNICODE
+ WCHAR buffer[MAX_PATH];
+#endif /* _UNICODE */
+
+ HRESULT hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (LPVOID*)&psl);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = psl->lpVtbl->SetPath(psl, cmd);
+
+ if (arg)
+ {
+ hr = psl->lpVtbl->SetArguments(psl, arg);
+ }
+
+ if (dir)
+ {
+ hr = psl->lpVtbl->SetWorkingDirectory(psl, dir);
+ }
+
+ if (iconPath)
+ {
+ hr = psl->lpVtbl->SetIconLocation(psl, iconPath, icon_nr);
+ }
+
+ if (comment)
+ {
+ hr = psl->lpVtbl->SetDescription(psl, comment);
+ }
+
+ hr = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf);
+
+ if (SUCCEEDED(hr))
+ {
+#ifdef _UNICODE
+ hr = ppf->lpVtbl->Save(ppf, linkPath, TRUE);
+#else /* _UNICODE */
+ MultiByteToWideChar(CP_ACP, 0, linkPath, -1, buffer, MAX_PATH);
+
+ hr = ppf->lpVtbl->Save(ppf, buffer, TRUE);
+#endif /* _UNICODE */
+
+ ppf->lpVtbl->Release(ppf);
+ }
+
+ psl->lpVtbl->Release(psl);
+ }
+
+ return hr;
+}
+
+
+static BOOL
+CreateShortcut(int csidl, LPCTSTR folder, LPCTSTR linkName, LPCTSTR command, UINT nIdTitle)
+{
+ TCHAR path[MAX_PATH];
+ TCHAR title[256];
+ LPTSTR p = path;
+
+ if (!SHGetSpecialFolderPath(0, path, csidl, TRUE))
+ return FALSE;
+
+ if (folder)
+ {
+ p = PathAddBackslash(p);
+ _tcscpy(p, folder);
+ }
+
+ p = PathAddBackslash(p);
+ _tcscpy(p, linkName);
+
+ if (!LoadString(hDllInstance, nIdTitle, title, 256))
+ return FALSE;
+
+ return SUCCEEDED(CreateShellLink(path, command, _T(""), NULL, NULL, 0, title));
+}
+
+
+static BOOL
+CreateShortcutFolder(int csidl, UINT nID, LPTSTR name, int nameLen)
+{
+ TCHAR path[MAX_PATH];
+ LPTSTR p;
+
+ if (!SHGetSpecialFolderPath(0, path, csidl, TRUE))
+ return FALSE;
+
+ if (!LoadString(hDllInstance, nID, name, nameLen))
+ return FALSE;
+
+ p = PathAddBackslash(path);
+ _tcscpy(p, name);
+
+ return CreateDirectory(path, NULL) || GetLastError()==ERROR_ALREADY_EXISTS;
}
Sid);
}
+
static VOID
AppendRidToSid (PSID *Dst,
PSID Src,
Dst);
}
-static BOOL
-SaveDomainSid (PSID Sid)
+INT_PTR CALLBACK
+RestartDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
- DWORD dwDisposition;
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hWnd, IDC_RESTART_PROGRESS, PBM_SETRANGE, 0,
+ MAKELPARAM(0, 300));
+ SetTimer(hWnd, 1, 50, NULL);
+ return TRUE;
+
+ case WM_TIMER:
+ {
+ INT Position;
+ HWND hWndProgress;
+
+ hWndProgress = GetDlgItem(hWnd, IDC_RESTART_PROGRESS);
+ Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0);
+ if (Position == 300)
+ EndDialog(hWnd, 0);
+ else
+ SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case IDOK:
+ case IDCANCEL:
+ EndDialog(hWnd, 0);
+ return TRUE;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+static VOID
+CreateTempDir(LPCWSTR VarName)
+{
+ TCHAR szTempDir[MAX_PATH];
+ TCHAR szBuffer[MAX_PATH];
+ DWORD dwLength;
HKEY hKey;
- if (RegCreateKeyExW (HKEY_LOCAL_MACHINE,
- L"SAM\\Accounts",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hKey,
- &dwDisposition))
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"),
+ 0,
+ KEY_ALL_ACCESS,
+ &hKey))
{
-#if 0
- DebugPrint ("Failed to create Accounts key! (Error %lu)\n", GetLastError());
-#endif
- return FALSE;
+ DebugPrint("Error: %lu\n", GetLastError());
+ return;
}
- if (RegSetValueExW (hKey,
- L"DomainSID",
- 0,
- REG_BINARY,
- (LPBYTE)Sid,
- RtlLengthSid (Sid)))
+ /* Get temp dir */
+ dwLength = MAX_PATH * sizeof(TCHAR);
+ if (RegQueryValueEx(hKey,
+ VarName,
+ NULL,
+ NULL,
+ (LPBYTE)szBuffer,
+ &dwLength))
+ {
+ DebugPrint("Error: %lu\n", GetLastError());
+ RegCloseKey(hKey);
+ return;
+ }
+
+ /* Expand it */
+ if (!ExpandEnvironmentStrings(szBuffer,
+ szTempDir,
+ MAX_PATH))
+ {
+ DebugPrint("Error: %lu\n", GetLastError());
+ RegCloseKey(hKey);
+ return;
+ }
+
+ /* Create profiles directory */
+ if (!CreateDirectory(szTempDir, NULL))
+ {
+ if (GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ DebugPrint("Error: %lu\n", GetLastError());
+ RegCloseKey(hKey);
+ return;
+ }
+ }
+
+ RegCloseKey(hKey);
+}
+
+
+BOOL
+ProcessSysSetupInf(VOID)
+{
+ INFCONTEXT InfContext;
+ TCHAR LineBuffer[256];
+ DWORD LineLength;
+
+ if (!SetupFindFirstLine(hSysSetupInf,
+ _T("DeviceInfsToInstall"),
+ NULL,
+ &InfContext))
+ {
+ return FALSE;
+ }
+
+ do
+ {
+ if (!SetupGetStringField(&InfContext,
+ 0,
+ LineBuffer,
+ 256,
+ &LineLength))
{
-#if 0
- DebugPrint ("Failed to set DomainSID value! (Error %lu)\n", GetLastError());
-#endif
- RegCloseKey (hKey);
return FALSE;
}
- RegCloseKey (hKey);
+ if (!SetupDiInstallClass(NULL, LineBuffer, DI_QUIETINSTALL, NULL))
+ {
+ return FALSE;
+ }
+ }
+ while (SetupFindNextLine(&InfContext, &InfContext));
return TRUE;
}
DWORD STDCALL
InstallReactOS (HINSTANCE hInstance)
{
+ TCHAR sAccessories[256];
+
# if 0
OutputDebugStringA ("InstallReactOS() called\n");
#if 0
UNICODE_STRING SidString;
#endif
+ ULONG LastError;
if (!InitializeProfiles ())
{
-#if 0
- OutputDebugStringA ("InitializeProfiles() failed\n");
-#endif
- MessageBoxA (NULL,
- "Profile initialization failed!\nRebooting now!",
- "ReactOS Setup",
- MB_OK);
+ DebugPrint ("InitializeProfiles() failed\n");
return 0;
}
+ CoInitialize(NULL);
+
+ /* create desktop shortcuts */
+ CreateShortcut(CSIDL_DESKTOP, NULL, _T("Command Prompt.lnk"), _T("cmd.exe"), IDS_CMT_CMD);
+
+ /* create program startmenu shortcuts */
+ CreateShortcut(CSIDL_PROGRAMS, NULL, _T("winefile.lnk"), _T("winefile.exe"), IDS_CMT_WINEFILE);
+
+ /* create and fill Accessories subfolder */
+ if (CreateShortcutFolder(CSIDL_PROGRAMS, IDS_ACCESSORIES, sAccessories, 256)) {
+ //CreateShortcut(CSIDL_PROGRAMS, sAccessories, _T("Calculator.lnk"), _T("calc.exe"), IDS_CMT_CALC);
+ CreateShortcut(CSIDL_PROGRAMS, sAccessories, _T("Command Prompt.lnk"), _T("cmd.exe"), IDS_CMT_CMD);
+ CreateShortcut(CSIDL_PROGRAMS, sAccessories, _T("notepad.lnk"), _T("notepad.exe"), IDS_CMT_NOTEPAD);
+ CreateShortcut(CSIDL_PROGRAMS, sAccessories, _T("explorer.lnk"), _T("explorer.exe"), IDS_CMT_EXPLORER);
+ CreateShortcut(CSIDL_PROGRAMS, sAccessories, _T("regedit.lnk"), _T("regedit.exe"), IDS_CMT_REGEDIT);
+ }
+
+ CoUninitialize();
+
+ /* Create the semi-random Domain-SID */
CreateRandomSid (&DomainSid);
if (DomainSid == NULL)
{
-#if 0
- OutputDebugStringA ("Failed to create the Domain-SID!\n");
-#endif
- MessageBoxA (NULL,
- "Failed to create the Domain SID!\nRebooting now!",
- "ReactOS Setup",
- MB_OK);
-
+ DebugPrint ("Domain-SID creation failed!\n");
return 0;
}
RtlFreeUnicodeString (&SidString);
#endif
- if (!SaveDomainSid (DomainSid))
+ /* Initialize the Security Account Manager (SAM) */
+ if (!SamInitializeSAM ())
{
-#if 0
- OutputDebugStringA ("Failed to create the Domain-SID!\n");
-#endif
- MessageBoxA (NULL,
- "Failed to save the Domain SID!\nRebooting now!",
- "ReactOS Setup",
- MB_OK);
+ DebugPrint ("SamInitializeSAM() failed!\n");
+ RtlFreeSid (DomainSid);
+ return 0;
+ }
+ /* Set the Domain SID (aka Computer SID) */
+ if (!SamSetDomainSid (DomainSid))
+ {
+ DebugPrint ("SamSetDomainSid() failed!\n");
RtlFreeSid (DomainSid);
return 0;
}
- AppendRidToSid (&AdminSid, DomainSid, DOMAIN_USER_RID_ADMIN);
+ /* Append the Admin-RID */
+ AppendRidToSid(&AdminSid, DomainSid, DOMAIN_USER_RID_ADMIN);
#if 0
- RtlConvertSidToUnicodeString (&SidString, AdminSid, TRUE);
- DebugPrint ("Admin SID: %wZ\n", &SidString);
+ RtlConvertSidToUnicodeString (&SidString, DomainSid, TRUE);
+ DebugPrint ("Admin-SID: %wZ\n", &SidString);
RtlFreeUnicodeString (&SidString);
#endif
- if (!CreateUserProfileW (AdminSid, L"Administrator"))
+ /* Create the Administrator account */
+ if (!SamCreateUser(L"Administrator", L"", AdminSid))
+ {
+ /* Check what the error was.
+ * If the Admin Account already exists, then it means Setup
+ * wasn't allowed to finish properly. Instead of rebooting
+ * and not completing it, let it restart instead
+ */
+ LastError = GetLastError();
+ if (LastError != ERROR_USER_EXISTS)
{
-#if 0
- DebugPrint ("Failed to create the admin user profile!\n");
-#endif
- MessageBoxA (NULL,
- "Failed to create the admin user profile!\nRebooting now!",
- "ReactOS Setup",
- MB_OK);
-
- RtlFreeSid (AdminSid);
- RtlFreeSid (DomainSid);
+ DebugPrint("SamCreateUser() failed!\n");
+ RtlFreeSid(AdminSid);
+ RtlFreeSid(DomainSid);
return 0;
}
-
- RtlFreeSid (AdminSid);
- RtlFreeSid (DomainSid);
-
-#if 0
- OutputDebugStringA ("System setup successful\n");
+ }
+
+ /* Create the Administrator profile */
+ if (!CreateUserProfileW(AdminSid, L"Administrator"))
+ {
+ DebugPrint("CreateUserProfileW() failed!\n");
+ RtlFreeSid(AdminSid);
+ RtlFreeSid(DomainSid);
+ return 0;
+ }
+
+ RtlFreeSid(AdminSid);
+ RtlFreeSid(DomainSid);
+
+ CreateTempDir(L"TEMP");
+ CreateTempDir(L"TMP");
+
+ hSysSetupInf = SetupOpenInfFileW(L"syssetup.inf",
+ NULL,
+ INF_STYLE_WIN4,
+ NULL);
+ if (hSysSetupInf == INVALID_HANDLE_VALUE)
+ {
+ DebugPrint("SetupOpenInfFileW() failed to open 'syssetup.inf' (Error: %lu)\n", GetLastError());
+ return 0;
+ }
+
+ if (!ProcessSysSetupInf())
+ {
+ DebugPrint("ProcessSysSetupInf() failed!\n");
+ return 0;
+ }
+
+ InstallWizard();
+
+ SetupCloseInfFile(hSysSetupInf);
+
+#ifdef VMWINST
+ RunVMWInstall();
#endif
- MessageBoxA (NULL,
- "Profile initialization successful!\nRebooting now!",
- "ReactOS Setup",
- MB_OK);
-#if 0
- Wizard ();
-#endif
+ DialogBox(hDllInstance,
+ MAKEINTRESOURCE(IDD_RESTART),
+ NULL,
+ RestartDlgProc);
return 0;
}
+
/*
* @unimplemented
*/
-DWORD STDCALL SetupChangeFontSize(HANDLE HWindow,
- LPCWSTR lpszFontSize)
+DWORD STDCALL
+SetupChangeFontSize(HANDLE hWnd,
+ LPCWSTR lpszFontSize)
{
- return(FALSE);
+ return FALSE;
}