reactos/reactos/lib/syssetup/install.c
Ged Murphy 1e8113e6e3 _MAX_PATH > MAXPATH
Shortcut to winemine, but commented out as winemine is broken.

svn path=/trunk/; revision=18702
2005-10-23 11:55:49 +00:00

579 lines
13 KiB
C

/*
* ReactOS kernel
* Copyright (C) 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: System setup
* FILE: lib/syssetup/install.c
* PROGRAMER: Eric Kohl
*/
/* INCLUDES *****************************************************************/
#define WIN32_NO_STATUS
#include <windows.h>
#define NTOS_MODE_USER
#include <ndk/ntndk.h>
#include <commctrl.h>
#include <stdio.h>
#include <io.h>
#include <tchar.h>
#include <stdlib.h>
#include <samlib/samlib.h>
#include <syssetup/syssetup.h>
#include <userenv.h>
#include <setupapi.h>
#include <shlobj.h>
#include <objidl.h>
#include <shlwapi.h>
#include "globals.h"
#include "resource.h"
#define VMWINST
/* GLOBALS ******************************************************************/
PSID DomainSid = NULL;
PSID AdminSid = NULL;
HINF hSysSetupInf = INVALID_HANDLE_VALUE;
/* FUNCTIONS ****************************************************************/
void
DebugPrint(char* fmt,...)
{
char buffer[512];
va_list ap;
va_start(ap, fmt);
vsprintf(buffer, fmt, ap);
va_end(ap);
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;
}
static VOID
CreateRandomSid (PSID *Sid)
{
SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
LARGE_INTEGER SystemTime;
PULONG Seed;
NtQuerySystemTime (&SystemTime);
Seed = &SystemTime.u.LowPart;
RtlAllocateAndInitializeSid (&SystemAuthority,
4,
SECURITY_NT_NON_UNIQUE_RID,
RtlUniform (Seed),
RtlUniform (Seed),
RtlUniform (Seed),
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
Sid);
}
static VOID
AppendRidToSid (PSID *Dst,
PSID Src,
ULONG NewRid)
{
ULONG Rid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
UCHAR RidCount;
ULONG i;
RidCount = *RtlSubAuthorityCountSid (Src);
for (i = 0; i < RidCount; i++)
Rid[i] = *RtlSubAuthoritySid (Src, i);
if (RidCount < 8)
{
Rid[RidCount] = NewRid;
RidCount++;
}
RtlAllocateAndInitializeSid (RtlIdentifierAuthoritySid (Src),
RidCount,
Rid[0],
Rid[1],
Rid[2],
Rid[3],
Rid[4],
Rid[5],
Rid[6],
Rid[7],
Dst);
}
INT_PTR CALLBACK
RestartDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
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 (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
_T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"),
0,
KEY_ALL_ACCESS,
&hKey))
{
DebugPrint("Error: %lu\n", GetLastError());
return;
}
/* 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))
{
return FALSE;
}
if (!SetupDiInstallClass(NULL, LineBuffer, DI_QUIETINSTALL, NULL))
{
return FALSE;
}
}
while (SetupFindNextLine(&InfContext, &InfContext));
return TRUE;
}
DWORD STDCALL
InstallReactOS (HINSTANCE hInstance)
{
TCHAR sAccessories[256];
TCHAR sGames[256];
TCHAR Sys[MAX_PATH];
# if 0
OutputDebugStringA ("InstallReactOS() called\n");
if (!InitializeSetupActionLog (FALSE))
{
OutputDebugStringA ("InitializeSetupActionLog() failed\n");
}
LogItem (SYSSETUP_SEVERITY_INFORMATION,
L"ReactOS Setup starting");
LogItem (SYSSETUP_SEVERITY_FATAL_ERROR,
L"Buuuuuuaaaah!");
LogItem (SYSSETUP_SEVERITY_INFORMATION,
L"ReactOS Setup finished");
TerminateSetupActionLog ();
#endif
#if 0
UNICODE_STRING SidString;
#endif
ULONG LastError;
if (!InitializeProfiles ())
{
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("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);
}
/* create Games subfolder and fill if the exe is available */
if (CreateShortcutFolder(CSIDL_PROGRAMS, IDS_GAMES, sGames, 256)) {
if(GetSystemDirectory(Sys, MAX_PATH)) {
if((_taccess(_tcscat(Sys, _T("\\sol.exe")), 0 )) != -1)
CreateShortcut(CSIDL_PROGRAMS, sGames, _T("Solitaire.lnk"), _T("sol.exe"), IDS_CMT_SOLITAIRE);
/* winemine is broken
if((_taccess(_tcscat(Sys, _T("\\winemine.exe")), 0 )) != -1)
CreateShortcut(CSIDL_PROGRAMS, sGames, _T("winemine.lnk"), _T("winemine.exe"), IDS_CMT_WINEMINE); */
}
}
CoUninitialize();
/* Create the semi-random Domain-SID */
CreateRandomSid (&DomainSid);
if (DomainSid == NULL)
{
DebugPrint ("Domain-SID creation failed!\n");
return 0;
}
#if 0
RtlConvertSidToUnicodeString (&SidString, DomainSid, TRUE);
DebugPrint ("Domain-SID: %wZ\n", &SidString);
RtlFreeUnicodeString (&SidString);
#endif
/* Initialize the Security Account Manager (SAM) */
if (!SamInitializeSAM ())
{
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;
}
/* Append the Admin-RID */
AppendRidToSid(&AdminSid, DomainSid, DOMAIN_USER_RID_ADMIN);
#if 0
RtlConvertSidToUnicodeString (&SidString, DomainSid, TRUE);
DebugPrint ("Admin-SID: %wZ\n", &SidString);
RtlFreeUnicodeString (&SidString);
#endif
/* 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)
{
DebugPrint("SamCreateUser() failed!\n");
RtlFreeSid(AdminSid);
RtlFreeSid(DomainSid);
return 0;
}
}
/* 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
DialogBox(hDllInstance,
MAKEINTRESOURCE(IDD_RESTART),
NULL,
RestartDlgProc);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
SetupChangeFontSize(HANDLE hWnd,
LPCWSTR lpszFontSize)
{
return FALSE;
}