-/*
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
#include "precomp.h"
-#include <tchar.h>
+#define COBJMACROS
+
+#include <io.h>
#include <wincon.h>
+#include <winnls.h>
#include <winsvc.h>
#include <userenv.h>
#include <shlobj.h>
#include <shlwapi.h>
+#include <shobjidl.h>
#include <rpcproxy.h>
#include <ndk/cmfuncs.h>
DWORD WINAPI
CMP_WaitNoPendingInstallEvents(DWORD dwTimeout);
+DWORD WINAPI
+SetupStartService(LPCWSTR lpServiceName, BOOL bWait);
+
/* GLOBALS ******************************************************************/
HINF hSysSetupInf = INVALID_HANDLE_VALUE;
vsprintf(szBuffer, pszFmt, ap);
va_end(ap);
- LogItem(SYSSETUP_SEVERITY_FATAL_ERROR, L"Failed");
+ LogItem(NULL, L"Failed");
strcat(szBuffer, "\nRebooting now!");
MessageBoxA(NULL,
static HRESULT
CreateShellLink(
- LPCTSTR pszLinkPath,
- LPCTSTR pszCmd,
- LPCTSTR pszArg,
- LPCTSTR pszDir,
- LPCTSTR pszIconPath,
- int iIconNr,
- LPCTSTR pszComment)
+ LPCWSTR pszLinkPath,
+ LPCWSTR pszCmd,
+ LPCWSTR pszArg,
+ LPCWSTR pszDir,
+ LPCWSTR pszIconPath,
+ INT iIconNr,
+ LPCWSTR pszComment)
{
- IShellLink *psl;
+ IShellLinkW *psl;
IPersistFile *ppf;
-#ifndef _UNICODE
- WCHAR wszBuf[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, pszCmd);
+ hr = IShellLinkW_SetPath(psl, pszCmd);
if (pszArg)
- {
- hr = psl->lpVtbl->SetArguments(psl, pszArg);
- }
+ hr = IShellLinkW_SetArguments(psl, pszArg);
if (pszDir)
- {
- hr = psl->lpVtbl->SetWorkingDirectory(psl, pszDir);
- }
+ hr = IShellLinkW_SetWorkingDirectory(psl, pszDir);
if (pszIconPath)
- {
- hr = psl->lpVtbl->SetIconLocation(psl, pszIconPath, iIconNr);
- }
+ hr = IShellLinkW_SetIconLocation(psl, pszIconPath, iIconNr);
if (pszComment)
- {
- hr = psl->lpVtbl->SetDescription(psl, pszComment);
- }
+ hr = IShellLinkW_SetDescription(psl, pszComment);
- hr = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf);
+ hr = IShellLinkW_QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf);
if (SUCCEEDED(hr))
{
-#ifdef _UNICODE
- hr = ppf->lpVtbl->Save(ppf, pszLinkPath, TRUE);
-#else /* _UNICODE */
- MultiByteToWideChar(CP_ACP, 0, pszLinkPath, -1, wszBuf, MAX_PATH);
-
- hr = ppf->lpVtbl->Save(ppf, wszBuf, TRUE);
-#endif /* _UNICODE */
-
- ppf->lpVtbl->Release(ppf);
+ hr = IPersistFile_Save(ppf, pszLinkPath, TRUE);
+ IPersistFile_Release(ppf);
}
- psl->lpVtbl->Release(psl);
+ IShellLinkW_Release(psl);
}
return hr;
static BOOL
CreateShortcut(
- LPCTSTR pszFolder,
- LPCTSTR pszName,
- LPCTSTR pszCommand,
- LPCTSTR pszDescription,
- INT iIconNr)
+ LPCWSTR pszFolder,
+ LPCWSTR pszName,
+ LPCWSTR pszCommand,
+ LPCWSTR pszDescription,
+ INT iIconNr,
+ LPCWSTR pszWorkingDir)
{
- TCHAR szPath[MAX_PATH];
- TCHAR szExeName[MAX_PATH];
- LPTSTR Ptr;
- TCHAR szWorkingDirBuf[MAX_PATH];
- LPTSTR pszWorkingDir = NULL;
- LPTSTR lpFilePart;
DWORD dwLen;
+ LPWSTR Ptr;
+ LPWSTR lpFilePart;
+ WCHAR szPath[MAX_PATH];
+ WCHAR szWorkingDirBuf[MAX_PATH];
- if (ExpandEnvironmentStrings(pszCommand,
- szPath,
- sizeof(szPath) / sizeof(szPath[0])) == 0)
- {
- _tcscpy(szPath, pszCommand);
- }
-
- if ((_taccess(szPath, 0 )) == -1)
- /* Expected error, don't return FALSE */
- return TRUE;
-
- dwLen = GetFullPathName(szPath,
- sizeof(szWorkingDirBuf) / sizeof(szWorkingDirBuf[0]),
- szWorkingDirBuf,
- &lpFilePart);
- if (dwLen != 0 && dwLen <= sizeof(szWorkingDirBuf) / sizeof(szWorkingDirBuf[0]))
+ /* If no working directory is provided, try to compute a default one */
+ if (pszWorkingDir == NULL || pszWorkingDir[0] == L'\0')
{
- /* Since those should only be called with (.exe) files,
- lpFilePart has not to be NULL */
- ASSERT(lpFilePart != NULL);
-
- /* Save the file name */
- _tcscpy(szExeName, lpFilePart);
-
- /* We're only interested in the path. Cut the file name off.
- Also remove the trailing backslash unless the working directory
- is only going to be a drive, ie. C:\ */
- *(lpFilePart--) = _T('\0');
- if (!(lpFilePart - szWorkingDirBuf == 2 && szWorkingDirBuf[1] == _T(':') &&
- szWorkingDirBuf[2] == _T('\\')))
+ if (ExpandEnvironmentStringsW(pszCommand, szPath, ARRAYSIZE(szPath)) == 0)
+ wcscpy(szPath, pszCommand);
+
+ dwLen = GetFullPathNameW(szPath,
+ ARRAYSIZE(szWorkingDirBuf),
+ szWorkingDirBuf,
+ &lpFilePart);
+ if (dwLen != 0 && dwLen <= ARRAYSIZE(szWorkingDirBuf))
{
- *lpFilePart = _T('\0');
+ /* Since those should only be called with (.exe) files,
+ lpFilePart has not to be NULL */
+ ASSERT(lpFilePart != NULL);
+
+ /* We're only interested in the path. Cut the file name off.
+ Also remove the trailing backslash unless the working directory
+ is only going to be a drive, i.e. C:\ */
+ *(lpFilePart--) = L'\0';
+ if (!(lpFilePart - szWorkingDirBuf == 2 &&
+ szWorkingDirBuf[1] == L':' && szWorkingDirBuf[2] == L'\\'))
+ {
+ *lpFilePart = L'\0';
+ }
+ pszWorkingDir = szWorkingDirBuf;
}
-
- pszWorkingDir = szWorkingDirBuf;
}
- _tcscpy(szPath, pszFolder);
+ /* If we failed to compute a working directory, just do not use one */
+ if (pszWorkingDir && pszWorkingDir[0] == L'\0')
+ pszWorkingDir = NULL;
+ /* Build the shortcut file name */
+ wcscpy(szPath, pszFolder);
Ptr = PathAddBackslash(szPath);
-
- _tcscpy(Ptr, pszName);
-
- // FIXME: we should pass 'command' straight in here, but shell32 doesn't expand it
- return SUCCEEDED(CreateShellLink(szPath, szExeName, _T(""), pszWorkingDir, szExeName, iIconNr, pszDescription));
+ wcscpy(Ptr, pszName);
+
+ /* Create the shortcut */
+ return SUCCEEDED(CreateShellLink(szPath,
+ pszCommand,
+ L"",
+ pszWorkingDir,
+ /* Special value to indicate no icon */
+ (iIconNr != -1 ? pszCommand : NULL),
+ iIconNr,
+ pszDescription));
}
-static BOOL CreateShortcutsFromSection(HINF hinf, LPWSTR pszSection, LPCWSTR pszFolder)
+static BOOL CreateShortcutsFromSection(HINF hinf, LPWSTR pszSection, LPCWSTR pszFolder)
{
INFCONTEXT Context;
+ DWORD dwFieldCount;
+ INT iIconNr;
WCHAR szCommand[MAX_PATH];
WCHAR szName[MAX_PATH];
WCHAR szDescription[MAX_PATH];
- INT iIconNr;
+ WCHAR szDirectory[MAX_PATH];
if (!SetupFindFirstLine(hinf, pszSection, NULL, &Context))
return FALSE;
do
{
- if (SetupGetFieldCount(&Context) < 4)
+ dwFieldCount = SetupGetFieldCount(&Context);
+ if (dwFieldCount < 3)
continue;
- if (!SetupGetStringFieldW(&Context, 1, szCommand, MAX_PATH, NULL))
+ if (!SetupGetStringFieldW(&Context, 1, szCommand, ARRAYSIZE(szCommand), NULL))
continue;
- if (!SetupGetStringFieldW(&Context, 2, szName, MAX_PATH, NULL))
+ if (!SetupGetStringFieldW(&Context, 2, szName, ARRAYSIZE(szName), NULL))
continue;
- if (!SetupGetStringFieldW(&Context, 3, szDescription, MAX_PATH, NULL))
+ if (!SetupGetStringFieldW(&Context, 3, szDescription, ARRAYSIZE(szDescription), NULL))
continue;
- if (!SetupGetIntField(&Context, 4, &iIconNr))
- continue;
+ if (dwFieldCount < 4 || !SetupGetIntField(&Context, 4, &iIconNr))
+ iIconNr = -1; /* Special value to indicate no icon */
- _tcscat(szName, L".lnk");
+ if (dwFieldCount < 5 || !SetupGetStringFieldW(&Context, 5, szDirectory, ARRAYSIZE(szDirectory), NULL))
+ szDirectory[0] = L'\0';
- CreateShortcut(pszFolder, szName, szCommand, szDescription, iIconNr);
+ wcscat(szName, L".lnk");
- }while (SetupFindNextLine(&Context, &Context));
+ CreateShortcut(pszFolder, szName, szCommand, szDescription, iIconNr, szDirectory);
+
+ } while (SetupFindNextLine(&Context, &Context));
return TRUE;
}
WCHAR szFolder[MAX_PATH];
WCHAR szFolderSection[MAX_PATH];
INT csidl;
- LPWSTR p;
CoInitialize(NULL);
if (SetupGetFieldCount(&Context) < 2)
continue;
- if (!SetupGetStringFieldW(&Context, 0, szFolderSection, MAX_PATH, NULL))
+ if (!SetupGetStringFieldW(&Context, 0, szFolderSection, ARRAYSIZE(szFolderSection), NULL))
continue;
if (!SetupGetIntField(&Context, 1, &csidl))
continue;
- if (!SetupGetStringFieldW(&Context, 2, szFolder, MAX_PATH, NULL))
+ if (!SetupGetStringFieldW(&Context, 2, szFolder, ARRAYSIZE(szFolder), NULL))
continue;
- if (FAILED(SHGetFolderPathW(NULL, csidl|CSIDL_FLAG_CREATE, (HANDLE)-1, SHGFP_TYPE_DEFAULT, szPath)))
+ if (FAILED(SHGetFolderPathAndSubDirW(NULL, csidl|CSIDL_FLAG_CREATE, (HANDLE)-1, SHGFP_TYPE_DEFAULT, szFolder, szPath)))
continue;
- p = PathAddBackslash(szPath);
- _tcscpy(p, szFolder);
-
- if (!CreateDirectory(szPath, NULL))
- {
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- {
- continue;
- }
- }
-
CreateShortcutsFromSection(hinf, szFolderSection, szPath);
- }while (SetupFindNextLine(&Context, &Context));
+ } while (SetupFindNextLine(&Context, &Context));
CoUninitialize();
HKEY hKey;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
- 0,
- KEY_QUERY_VALUE,
- &hKey) != ERROR_SUCCESS)
+ L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
+ 0,
+ KEY_QUERY_VALUE,
+ &hKey) != ERROR_SUCCESS)
{
FatalError("Error: %lu\n", GetLastError());
return;
}
/* Get temp dir */
- dwLength = MAX_PATH * sizeof(WCHAR);
+ dwLength = sizeof(szBuffer);
if (RegQueryValueExW(hKey,
- VarName,
- NULL,
- NULL,
- (LPBYTE)szBuffer,
- &dwLength) != ERROR_SUCCESS)
+ VarName,
+ NULL,
+ NULL,
+ (LPBYTE)szBuffer,
+ &dwLength) != ERROR_SUCCESS)
{
FatalError("Error: %lu\n", GetLastError());
goto cleanup;
}
/* Expand it */
- if (!ExpandEnvironmentStringsW(szBuffer,
- szTempDir,
- MAX_PATH))
+ if (!ExpandEnvironmentStringsW(szBuffer, szTempDir, ARRAYSIZE(szTempDir)))
{
FatalError("Error: %lu\n", GetLastError());
goto cleanup;
do
{
if (!SetupGetStringFieldW(&InfContext,
- 0,
- szLineBuffer,
- sizeof(szLineBuffer)/sizeof(szLineBuffer[0]),
- &dwLineLength))
+ 0,
+ szLineBuffer,
+ ARRAYSIZE(szLineBuffer),
+ &dwLineLength))
{
return FALSE;
}
HINF hComponentInf = INVALID_HANDLE_VALUE;
if (!SetupFindFirstLineW(hSysSetupInf,
- L"Infs.Always",
- NULL,
- &InfContext))
+ L"Infs.Always",
+ NULL,
+ &InfContext))
{
DPRINT("No Inf.Always section found\n");
}
do
{
if (!SetupGetStringFieldW(&InfContext,
- 1, // Get the component name
- szNameBuffer,
- sizeof(szNameBuffer)/sizeof(szNameBuffer[0]),
- NULL))
+ 1, // Get the component name
+ szNameBuffer,
+ ARRAYSIZE(szNameBuffer),
+ NULL))
{
FatalError("Error while trying to get component name \n");
return FALSE;
}
if (!SetupGetStringFieldW(&InfContext,
- 2, // Get the component install section
- szSectionBuffer,
- sizeof(szSectionBuffer)/sizeof(szSectionBuffer[0]),
- NULL))
+ 2, // Get the component install section
+ szSectionBuffer,
+ ARRAYSIZE(szSectionBuffer),
+ NULL))
{
FatalError("Error while trying to get component install section \n");
return FALSE;
}
if (!SetupInstallFromInfSectionW(NULL,
- hComponentInf,
- szSectionBuffer,
- SPINST_ALL,
- NULL,
- NULL,
- SP_COPY_NEWER,
- SetupDefaultQueueCallbackW,
- NULL,
- NULL,
- NULL))
+ hComponentInf,
+ szSectionBuffer,
+ SPINST_ALL,
+ NULL,
+ NULL,
+ SP_COPY_NEWER,
+ SetupDefaultQueueCallbackW,
+ NULL,
+ NULL,
+ NULL))
{
FatalError("Error while trying to install : %S (Error: %lu)\n", szNameBuffer, GetLastError());
SetupCloseInfFile(hComponentInf);
-
BOOL
-RegisterTypeLibraries (HINF hinf, LPCWSTR szSection)
+RegisterTypeLibraries(HINF hinf, LPCWSTR szSection)
{
INFCONTEXT InfContext;
BOOL res;
do
{
/* Get the name of the current type library */
- if (!SetupGetStringFieldW(&InfContext, 1, szName, MAX_PATH, NULL))
+ if (!SetupGetStringFieldW(&InfContext, 1, szName, ARRAYSIZE(szName), NULL))
{
FatalError("SetupGetStringFieldW failed\n");
continue;
hret = SHGetFolderPathW(NULL, csidl, NULL, 0, szPath);
if (FAILED(hret))
{
- FatalError("SHGetFolderPathW failed hret=0x%d\n", hret);
+ FatalError("SHGetFolderPathW failed hret=0x%lx\n", hret);
continue;
}
p = PathAddBackslash(szPath);
- _tcscpy(p, szName);
+ wcscpy(p, szName);
hmod = LoadLibraryW(szName);
if (hmod == NULL)
__wine_register_resources(hmod);
- }while (SetupFindNextLine(&InfContext, &InfContext));
+ } while (SetupFindNextLine(&InfContext, &InfContext));
return TRUE;
}
}
bRet = ChangeServiceConfigW(hService,
- SERVICE_NO_CHANGE,
- SERVICE_AUTO_START,
- SERVICE_NO_CHANGE,
- NULL, NULL, NULL,
- NULL, NULL, NULL, NULL);
+ SERVICE_NO_CHANGE,
+ SERVICE_AUTO_START,
+ SERVICE_NO_CHANGE,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL);
if (!bRet)
{
DPRINT1("Unable to change the service configuration\n");
{
WCHAR szMsg[256];
- if (!LoadStringW(hDllInstance, IDS_STATUS_INSTALL_DEV, szMsg, sizeof(szMsg)/sizeof(szMsg[0])))
+ if (!LoadStringW(hDllInstance, IDS_STATUS_INSTALL_DEV, szMsg, ARRAYSIZE(szMsg)))
return FALSE;
SetDlgItemTextW(hwndDlg, IDC_STATUSLABEL, szMsg);
return TRUE;
IN LPVOID lpParameter)
{
HWND *phWnd = (HWND *)lpParameter;
- HWND hWnd;
+ HWND hWnd, hItem;
MSG Msg;
- hWnd = CreateDialogParam(
- hDllInstance,
- MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG),
- GetDesktopWindow(),
- StatusMessageWindowProc,
- (LPARAM)NULL);
+ hWnd = CreateDialogParam(hDllInstance,
+ MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG),
+ GetDesktopWindow(),
+ StatusMessageWindowProc,
+ (LPARAM)NULL);
if (!hWnd)
return 0;
*phWnd = hWnd;
ShowWindow(hWnd, SW_SHOW);
+ hItem = GetDlgItem(hWnd, IDC_STATUSPROGRESS);
+ if (hItem)
+ {
+ PostMessage(hItem, PBM_SETMARQUEE, TRUE, 40);
+ }
+
/* Message loop for the Status window */
while (GetMessage(&Msg, NULL, 0, 0))
{
BOOL bConsoleBoot = FALSE;
LONG rc;
- rc = RegOpenKeyExW(
- HKEY_LOCAL_MACHINE,
- L"SYSTEM\\CurrentControlSet\\Control",
- 0,
- KEY_QUERY_VALUE,
- &hControlKey);
+ rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"SYSTEM\\CurrentControlSet\\Control",
+ 0,
+ KEY_QUERY_VALUE,
+ &hControlKey);
if (rc != ERROR_SUCCESS)
goto cleanup;
{
HWND hWnd = NULL;
- hSysSetupInf = SetupOpenInfFileW(
- L"syssetup.inf",
- NULL,
- INF_STYLE_WIN4,
- NULL);
+ hSysSetupInf = SetupOpenInfFileW(L"syssetup.inf",
+ NULL,
+ INF_STYLE_WIN4,
+ NULL);
if (hSysSetupInf == INVALID_HANDLE_VALUE)
{
FatalError("SetupOpenInfFileW() failed to open 'syssetup.inf' (Error: %lu)\n", GetLastError());
{
HANDLE hThread;
- hThread = CreateThread(
- NULL,
- 0,
- ShowStatusMessageThread,
- (LPVOID)&hWnd,
- 0,
- NULL);
-
+ hThread = CreateThread(NULL,
+ 0,
+ ShowStatusMessageThread,
+ (LPVOID)&hWnd,
+ 0,
+ NULL);
if (hThread)
CloseHandle(hThread);
}
return FALSE;
}
-DWORD WINAPI
-InstallLiveCD(IN HINSTANCE hInstance)
+/* Install a section of a .inf file
+ * Returns TRUE if success, FALSE if failure. Error code can
+ * be retrieved with GetLastError()
+ */
+static
+BOOL
+InstallInfSection(
+ IN HWND hWnd,
+ IN LPCWSTR InfFile,
+ IN LPCWSTR InfSection OPTIONAL,
+ IN LPCWSTR InfService OPTIONAL)
+{
+ WCHAR Buffer[MAX_PATH];
+ HINF hInf = INVALID_HANDLE_VALUE;
+ UINT BufferSize;
+ PVOID Context = NULL;
+ BOOL ret = FALSE;
+
+ /* Get Windows directory */
+ BufferSize = ARRAYSIZE(Buffer) - 5 - wcslen(InfFile);
+ if (GetWindowsDirectoryW(Buffer, BufferSize) > BufferSize)
+ {
+ /* Function failed */
+ SetLastError(ERROR_GEN_FAILURE);
+ goto cleanup;
+ }
+ /* We have enough space to add some information in the buffer */
+ if (Buffer[wcslen(Buffer) - 1] != '\\')
+ wcscat(Buffer, L"\\");
+ wcscat(Buffer, L"Inf\\");
+ wcscat(Buffer, InfFile);
+
+ /* Install specified section */
+ hInf = SetupOpenInfFileW(Buffer, NULL, INF_STYLE_WIN4, NULL);
+ if (hInf == INVALID_HANDLE_VALUE)
+ goto cleanup;
+
+ Context = SetupInitDefaultQueueCallback(hWnd);
+ if (Context == NULL)
+ goto cleanup;
+
+ ret = TRUE;
+ if (ret && InfSection)
+ {
+ ret = SetupInstallFromInfSectionW(
+ hWnd, hInf,
+ InfSection, SPINST_ALL,
+ NULL, NULL, SP_COPY_NEWER,
+ SetupDefaultQueueCallbackW, Context,
+ NULL, NULL);
+ }
+ if (ret && InfService)
+ {
+ ret = SetupInstallServicesFromInfSectionW(hInf, InfService, 0);
+ }
+
+cleanup:
+ if (Context)
+ SetupTermDefaultQueueCallback(Context);
+ if (hInf != INVALID_HANDLE_VALUE)
+ SetupCloseInfFile(hInf);
+ return ret;
+}
+
+static
+DWORD
+InstallLiveCD(VOID)
{
STARTUPINFOW StartupInfo;
PROCESS_INFORMATION ProcessInformation;
BOOL bRes;
+ /* Hack: Install TCP/IP protocol driver */
+ bRes = InstallInfSection(NULL,
+ L"nettcpip.inf",
+ L"MS_TCPIP.PrimaryInstall",
+ L"MS_TCPIP.PrimaryInstall.Services");
+ if (!bRes && GetLastError() != ERROR_FILE_NOT_FOUND)
+ {
+ DPRINT("InstallInfSection() failed with error 0x%lx\n", GetLastError());
+ }
+ else
+ {
+ /* Start the TCP/IP protocol driver */
+ SetupStartService(L"Tcpip", FALSE);
+ SetupStartService(L"Dhcp", FALSE);
+ }
+
if (!CommonInstall())
goto error;
-
+
/* Register components */
_SEH2_TRY
{
if (!SetupInstallFromInfSectionW(NULL,
- hSysSetupInf, L"RegistrationPhase2",
- SPINST_ALL,
- 0, NULL, 0, NULL, NULL, NULL, NULL))
+ hSysSetupInf, L"RegistrationPhase2",
+ SPINST_ALL,
+ 0, NULL, 0, NULL, NULL, NULL, NULL))
{
DPRINT1("SetupInstallFromInfSectionW failed!\n");
}
DPRINT1("Catching exception\n");
}
_SEH2_END;
-
+
SetupCloseInfFile(hSysSetupInf);
/* Run the shell */
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof(StartupInfo);
- bRes = CreateProcessW(
- L"userinit.exe",
- NULL,
- NULL,
- NULL,
- FALSE,
- 0,
- NULL,
- NULL,
- &StartupInfo,
- &ProcessInformation);
+ bRes = CreateProcessW(L"userinit.exe",
+ NULL,
+ NULL,
+ NULL,
+ FALSE,
+ 0,
+ NULL,
+ NULL,
+ &StartupInfo,
+ &ProcessInformation);
if (!bRes)
goto error;
return TRUE;
}
-DWORD WINAPI
-InstallReactOS(HINSTANCE hInstance)
+static DWORD CALLBACK
+HotkeyThread(LPVOID Parameter)
{
- TCHAR szBuffer[MAX_PATH];
+ ATOM hotkey;
+ MSG msg;
+
+ DPRINT("HotkeyThread start\n");
+
+ hotkey = GlobalAddAtomW(L"Setup Shift+F10 Hotkey");
+
+ if (!RegisterHotKey(NULL, hotkey, MOD_SHIFT, VK_F10))
+ DPRINT1("RegisterHotKey failed with %lu\n", GetLastError());
+
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ if (msg.hwnd == NULL && msg.message == WM_HOTKEY && msg.wParam == hotkey)
+ {
+ STARTUPINFOW si = { sizeof(si) };
+ PROCESS_INFORMATION pi;
+
+ if (CreateProcessW(L"cmd.exe",
+ NULL,
+ NULL,
+ NULL,
+ FALSE,
+ CREATE_NEW_CONSOLE,
+ NULL,
+ NULL,
+ &si,
+ &pi))
+ {
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
+ else
+ {
+ DPRINT1("Failed to launch command prompt: %lu\n", GetLastError());
+ }
+ }
+ }
+
+ UnregisterHotKey(NULL, hotkey);
+ GlobalDeleteAtom(hotkey);
+
+ DPRINT("HotkeyThread terminate\n");
+ return 0;
+}
+
+
+static
+BOOL
+InitializeProgramFilesDir(VOID)
+{
+ LONG Error;
+ HKEY hKey;
+ DWORD dwLength;
+ WCHAR szProgramFilesDirPath[MAX_PATH];
+ WCHAR szCommonFilesDirPath[MAX_PATH];
+ WCHAR szBuffer[MAX_PATH];
+
+ /* Load 'Program Files' location */
+ if (!LoadStringW(hDllInstance,
+ IDS_PROGRAMFILES,
+ szBuffer,
+ ARRAYSIZE(szBuffer)))
+ {
+ DPRINT1("Error: %lu\n", GetLastError());
+ return FALSE;
+ }
+
+ if (!LoadStringW(hDllInstance,
+ IDS_COMMONFILES,
+ szCommonFilesDirPath,
+ ARRAYSIZE(szCommonFilesDirPath)))
+ {
+ DPRINT1("Warning: %lu\n", GetLastError());
+ }
+
+ /* Expand it */
+ if (!ExpandEnvironmentStringsW(szBuffer,
+ szProgramFilesDirPath,
+ ARRAYSIZE(szProgramFilesDirPath)))
+ {
+ DPRINT1("Error: %lu\n", GetLastError());
+ return FALSE;
+ }
+
+ wcscpy(szBuffer, szProgramFilesDirPath);
+ wcscat(szBuffer, L"\\");
+ wcscat(szBuffer, szCommonFilesDirPath);
+
+ if (!ExpandEnvironmentStringsW(szBuffer,
+ szCommonFilesDirPath,
+ ARRAYSIZE(szCommonFilesDirPath)))
+ {
+ DPRINT1("Warning: %lu\n", GetLastError());
+ }
+
+ /* Store it */
+ Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
+ 0,
+ KEY_SET_VALUE,
+ &hKey);
+ if (Error != ERROR_SUCCESS)
+ {
+ DPRINT1("Error: %lu\n", Error);
+ return FALSE;
+ }
+
+ dwLength = (wcslen(szProgramFilesDirPath) + 1) * sizeof(WCHAR);
+ Error = RegSetValueExW(hKey,
+ L"ProgramFilesDir",
+ 0,
+ REG_SZ,
+ (LPBYTE)szProgramFilesDirPath,
+ dwLength);
+ if (Error != ERROR_SUCCESS)
+ {
+ DPRINT1("Error: %lu\n", Error);
+ RegCloseKey(hKey);
+ return FALSE;
+ }
+
+ dwLength = (wcslen(szCommonFilesDirPath) + 1) * sizeof(WCHAR);
+ Error = RegSetValueExW(hKey,
+ L"CommonFilesDir",
+ 0,
+ REG_SZ,
+ (LPBYTE)szCommonFilesDirPath,
+ dwLength);
+ if (Error != ERROR_SUCCESS)
+ {
+ DPRINT1("Warning: %lu\n", Error);
+ }
+
+ RegCloseKey(hKey);
+
+ /* Create directory */
+ // FIXME: Security!
+ if (!CreateDirectoryW(szProgramFilesDirPath, NULL))
+ {
+ if (GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ DPRINT1("Error: %lu\n", GetLastError());
+ return FALSE;
+ }
+ }
+
+ /* Create directory */
+ // FIXME: Security!
+ if (!CreateDirectoryW(szCommonFilesDirPath, NULL))
+ {
+ if (GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ DPRINT1("Warning: %lu\n", GetLastError());
+ // return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+static
+VOID
+InitializeDefaultUserLocale(VOID)
+{
+ WCHAR szBuffer[80];
+ PWSTR ptr;
+ HKEY hLocaleKey;
+ DWORD ret;
+ DWORD dwSize;
+ LCID lcid;
+ INT i;
+
+ struct {LCTYPE LCType; PWSTR pValue;} LocaleData[] = {
+ /* Number */
+ {LOCALE_SDECIMAL, L"sDecimal"},
+ {LOCALE_STHOUSAND, L"sThousand"},
+ {LOCALE_SNEGATIVESIGN, L"sNegativeSign"},
+ {LOCALE_SPOSITIVESIGN, L"sPositiveSign"},
+ {LOCALE_SGROUPING, L"sGrouping"},
+ {LOCALE_SLIST, L"sList"},
+ {LOCALE_SNATIVEDIGITS, L"sNativeDigits"},
+ {LOCALE_INEGNUMBER, L"iNegNumber"},
+ {LOCALE_IDIGITS, L"iDigits"},
+ {LOCALE_ILZERO, L"iLZero"},
+ {LOCALE_IMEASURE, L"iMeasure"},
+ {LOCALE_IDIGITSUBSTITUTION, L"NumShape"},
+
+ /* Currency */
+ {LOCALE_SCURRENCY, L"sCurrency"},
+ {LOCALE_SMONDECIMALSEP, L"sMonDecimalSep"},
+ {LOCALE_SMONTHOUSANDSEP, L"sMonThousandSep"},
+ {LOCALE_SMONGROUPING, L"sMonGrouping"},
+ {LOCALE_ICURRENCY, L"iCurrency"},
+ {LOCALE_INEGCURR, L"iNegCurr"},
+ {LOCALE_ICURRDIGITS, L"iCurrDigits"},
+
+ /* Time */
+ {LOCALE_STIMEFORMAT, L"sTimeFormat"},
+ {LOCALE_STIME, L"sTime"},
+ {LOCALE_S1159, L"s1159"},
+ {LOCALE_S2359, L"s2359"},
+ {LOCALE_ITIME, L"iTime"},
+ {LOCALE_ITIMEMARKPOSN, L"iTimePrefix"},
+ {LOCALE_ITLZERO, L"iTLZero"},
+
+ /* Date */
+ {LOCALE_SLONGDATE, L"sLongDate"},
+ {LOCALE_SSHORTDATE, L"sShortDate"},
+ {LOCALE_SDATE, L"sDate"},
+ {LOCALE_IFIRSTDAYOFWEEK, L"iFirstDayOfWeek"},
+ {LOCALE_IFIRSTWEEKOFYEAR, L"iFirstWeekOfYear"},
+ {LOCALE_IDATE, L"iDate"},
+ {LOCALE_ICALENDARTYPE, L"iCalendarType"},
+
+ /* Misc */
+ {LOCALE_SCOUNTRY, L"sCountry"},
+ {LOCALE_SABBREVLANGNAME, L"sLanguage"},
+ {LOCALE_ICOUNTRY, L"iCountry"},
+ {0, NULL}};
+
+ ret = RegOpenKeyExW(HKEY_USERS,
+ L".DEFAULT\\Control Panel\\International",
+ 0,
+ KEY_READ | KEY_WRITE,
+ &hLocaleKey);
+ if (ret != ERROR_SUCCESS)
+ {
+ return;
+ }
+
+ dwSize = 9 * sizeof(WCHAR);
+ ret = RegQueryValueExW(hLocaleKey,
+ L"Locale",
+ NULL,
+ NULL,
+ (PBYTE)szBuffer,
+ &dwSize);
+ if (ret != ERROR_SUCCESS)
+ goto done;
+
+ lcid = (LCID)wcstoul(szBuffer, &ptr, 16);
+ if (lcid == 0)
+ goto done;
+
+ i = 0;
+ while (LocaleData[i].pValue != NULL)
+ {
+ if (GetLocaleInfoW(lcid,
+ LocaleData[i].LCType | LOCALE_NOUSEROVERRIDE,
+ szBuffer,
+ ARRAYSIZE(szBuffer)))
+ {
+ RegSetValueExW(hLocaleKey,
+ LocaleData[i].pValue,
+ 0,
+ REG_SZ,
+ (PBYTE)szBuffer,
+ (wcslen(szBuffer) + 1) * sizeof(WCHAR));
+ }
+
+ i++;
+ }
+
+done:
+ RegCloseKey(hLocaleKey);
+}
+
+
+static
+DWORD
+SaveDefaultUserHive(VOID)
+{
+ WCHAR szDefaultUserHive[MAX_PATH];
+ HKEY hUserKey = NULL;
+ DWORD cchSize;
+ DWORD dwError;
+
+ DPRINT("SaveDefaultUserHive()\n");
+
+ cchSize = ARRAYSIZE(szDefaultUserHive);
+ GetDefaultUserProfileDirectoryW(szDefaultUserHive, &cchSize);
+
+ wcscat(szDefaultUserHive, L"\\ntuser.dat");
+
+ dwError = RegOpenKeyExW(HKEY_USERS,
+ L".DEFAULT",
+ 0,
+ KEY_READ,
+ &hUserKey);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError);
+ return dwError;
+ }
+
+ pSetupEnablePrivilege(L"SeBackupPrivilege", TRUE);
+
+ /* Save the Default hive */
+ dwError = RegSaveKeyExW(hUserKey,
+ szDefaultUserHive,
+ NULL,
+ REG_STANDARD_FORMAT);
+ if (dwError == ERROR_ALREADY_EXISTS)
+ {
+ WCHAR szBackupHive[MAX_PATH];
+
+ /* Build the backup hive file name by replacing the extension */
+ wcscpy(szBackupHive, szDefaultUserHive);
+ wcscpy(&szBackupHive[wcslen(szBackupHive) - 4], L".bak");
+
+ /* Back up the existing default user hive by renaming it, replacing any possible existing old backup */
+ if (!MoveFileExW(szDefaultUserHive,
+ szBackupHive,
+ MOVEFILE_REPLACE_EXISTING))
+ {
+ dwError = GetLastError();
+ DPRINT1("Failed to create a default-user hive backup '%S', MoveFileExW failed (Error %lu)\n",
+ szBackupHive, dwError);
+ }
+ else
+ {
+ /* The backup has been done, retry saving the Default hive */
+ dwError = RegSaveKeyExW(hUserKey,
+ szDefaultUserHive,
+ NULL,
+ REG_STANDARD_FORMAT);
+ }
+ }
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("RegSaveKeyExW() failed (Error %lu)\n", dwError);
+ }
+
+ pSetupEnablePrivilege(L"SeBackupPrivilege", FALSE);
+
+ RegCloseKey(hUserKey);
+
+ return dwError;
+}
+
+
+static
+DWORD
+InstallReactOS(VOID)
+{
+ WCHAR szBuffer[MAX_PATH];
HANDLE token;
TOKEN_PRIVILEGES privs;
HKEY hKey;
HINF hShortcutsInf;
+ HANDLE hHotkeyThread;
+ BOOL ret;
InitializeSetupActionLog(FALSE);
- LogItem(SYSSETUP_SEVERITY_INFORMATION, L"Installing ReactOS");
+ LogItem(NULL, L"Installing ReactOS");
+
+ CreateTempDir(L"TEMP");
+ CreateTempDir(L"TMP");
+
+ if (!InitializeProgramFilesDir())
+ {
+ FatalError("InitializeProgramFilesDir() failed");
+ return 0;
+ }
if (!InitializeProfiles())
{
return 0;
}
- CreateTempDir(L"TEMP");
- CreateTempDir(L"TMP");
+ InitializeDefaultUserLocale();
- if (GetWindowsDirectory(szBuffer, sizeof(szBuffer) / sizeof(TCHAR)))
+ if (GetWindowsDirectoryW(szBuffer, ARRAYSIZE(szBuffer)))
{
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
}
PathAddBackslash(szBuffer);
- _tcscat(szBuffer, _T("system"));
+ wcscat(szBuffer, L"system");
CreateDirectory(szBuffer, NULL);
}
+ if (SaveDefaultUserHive() != ERROR_SUCCESS)
+ {
+ FatalError("SaveDefaultUserHive() failed");
+ return 0;
+ }
+
+ if (!CopySystemProfile(0))
+ {
+ FatalError("CopySystemProfile() failed");
+ return 0;
+ }
+
+ hHotkeyThread = CreateThread(NULL, 0, HotkeyThread, NULL, 0, NULL);
+
+ /* Hack: Install TCP/IP protocol driver */
+ ret = InstallInfSection(NULL,
+ L"nettcpip.inf",
+ L"MS_TCPIP.PrimaryInstall",
+ L"MS_TCPIP.PrimaryInstall.Services");
+ if (!ret && GetLastError() != ERROR_FILE_NOT_FOUND)
+ {
+ DPRINT("InstallInfSection() failed with error 0x%lx\n", GetLastError());
+ }
+ else
+ {
+ /* Start the TCP/IP protocol driver */
+ SetupStartService(L"Tcpip", FALSE);
+ SetupStartService(L"Dhcp", FALSE);
+ }
+
+
if (!CommonInstall())
return 0;
NULL,
INF_STYLE_WIN4,
NULL);
- if (hShortcutsInf == INVALID_HANDLE_VALUE)
+ if (hShortcutsInf == INVALID_HANDLE_VALUE)
{
FatalError("Failed to open shortcuts.inf");
return 0;
SetupCloseInfFile(hShortcutsInf);
- /* ROS HACK, as long as NtUnloadKey is not implemented */
+ hShortcutsInf = SetupOpenInfFileW(L"rosapps_shortcuts.inf",
+ NULL,
+ INF_STYLE_WIN4,
+ NULL);
+ if (hShortcutsInf != INVALID_HANDLE_VALUE)
{
- NTSTATUS Status = NtUnloadKey(NULL);
- if (Status == STATUS_NOT_IMPLEMENTED)
+ if (!CreateShortcuts(hShortcutsInf, L"ShortcutFolders"))
{
- /* Create the Administrator profile */
- PROFILEINFOW ProfileInfo;
- HANDLE hToken;
- BOOL ret;
-
- ret = LogonUserW(AdminInfo.Name,
- AdminInfo.Domain,
- AdminInfo.Password,
- LOGON32_LOGON_INTERACTIVE,
- LOGON32_PROVIDER_DEFAULT,
- &hToken);
- if (!ret)
- {
- FatalError("LogonUserW() failed!");
- return 0;
- }
- ZeroMemory(&ProfileInfo, sizeof(PROFILEINFOW));
- ProfileInfo.dwSize = sizeof(PROFILEINFOW);
- ProfileInfo.lpUserName = L"Administrator";
- ProfileInfo.dwFlags = PI_NOUI;
- LoadUserProfileW(hToken, &ProfileInfo);
- CloseHandle(hToken);
- }
- else
- {
- DPRINT1("ROS HACK not needed anymore. Please remove it\n");
+ FatalError("CreateShortcuts(rosapps) failed");
+ return 0;
}
+ SetupCloseInfFile(hShortcutsInf);
}
- /* END OF ROS HACK */
SetupCloseInfFile(hSysSetupInf);
SetSetupType(0);
- LogItem(SYSSETUP_SEVERITY_INFORMATION, L"Installing ReactOS done");
+ if (hHotkeyThread)
+ {
+ PostThreadMessage(GetThreadId(hHotkeyThread), WM_QUIT, 0, 0);
+ CloseHandle(hHotkeyThread);
+ }
+
+ LogItem(NULL, L"Installing ReactOS done");
TerminateSetupActionLog();
if (AdminInfo.Name != NULL)
FatalError("OpenProcessToken() failed!");
return 0;
}
- if (!LookupPrivilegeValue(
- NULL,
- SE_SHUTDOWN_NAME,
- &privs.Privileges[0].Luid))
+ if (!LookupPrivilegeValue(NULL,
+ SE_SHUTDOWN_NAME,
+ &privs.Privileges[0].Luid))
{
FatalError("LookupPrivilegeValue() failed!");
return 0;
}
privs.PrivilegeCount = 1;
privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- if (AdjustTokenPrivileges(
- token,
- FALSE,
- &privs,
- 0,
- (PTOKEN_PRIVILEGES)NULL,
- NULL) == 0)
+ if (AdjustTokenPrivileges(token,
+ FALSE,
+ &privs,
+ 0,
+ (PTOKEN_PRIVILEGES)NULL,
+ NULL) == 0)
{
FatalError("AdjustTokenPrivileges() failed!");
return 0;
}
+/*
+ * Standard Windows-compatible export, which dispatches
+ * to either 'InstallReactOS' or 'InstallLiveCD'.
+ */
+INT
+WINAPI
+InstallWindowsNt(INT argc, WCHAR** argv)
+{
+ INT i;
+ PWSTR p;
+
+ for (i = 0; i < argc; ++i)
+ {
+ p = argv[i];
+ if (*p == L'-')
+ {
+ p++;
+
+ // NOTE: On Windows, "mini" means "minimal UI", and can be used
+ // in addition to "newsetup"; these options are not exclusive.
+ if (_wcsicmp(p, L"newsetup") == 0)
+ return (INT)InstallReactOS();
+ else if (_wcsicmp(p, L"mini") == 0)
+ return (INT)InstallLiveCD();
+
+ /* Add support for other switches */
+ }
+ }
+
+ return 0;
+}
+
+
/*
* @unimplemented
*/
{
return SetupChangeLocaleEx(hWnd, Lcid, NULL, 0, 0, 0);
}
+
+
+DWORD
+WINAPI
+SetupStartService(
+ LPCWSTR lpServiceName,
+ BOOL bWait)
+{
+ SC_HANDLE hManager = NULL;
+ SC_HANDLE hService = NULL;
+ DWORD dwError = ERROR_SUCCESS;
+
+ hManager = OpenSCManagerW(NULL,
+ NULL,
+ SC_MANAGER_ALL_ACCESS);
+ if (hManager == NULL)
+ {
+ dwError = GetLastError();
+ goto done;
+ }
+
+ hService = OpenServiceW(hManager,
+ lpServiceName,
+ SERVICE_START);
+ if (hService == NULL)
+ {
+ dwError = GetLastError();
+ goto done;
+ }
+
+ if (!StartService(hService, 0, NULL))
+ {
+ dwError = GetLastError();
+ goto done;
+ }
+
+done:
+ if (hService != NULL)
+ CloseServiceHandle(hService);
+
+ if (hManager != NULL)
+ CloseServiceHandle(hManager);
+
+ return dwError;
+}