#include "reactos.h"
#include "resource.h"
+#define NDEBUG
+#include <debug.h>
+
/* GLOBALS ******************************************************************/
+HANDLE ProcessHeap;
+BOOLEAN IsUnattendedSetup = FALSE;
+SETUPDATA SetupData;
-LONG LoadGenentry(HINF hinf,PCTSTR name,PGENENTRY *gen,PINFCONTEXT context);
/* FUNCTIONS ****************************************************************/
+LONG LoadGenentry(HINF hinf,PCTSTR name,PGENENTRY *gen,PINFCONTEXT context);
+
static VOID
CenterWindow(HWND hWnd)
{
return hFont;
}
+INT DisplayError(
+ IN HWND hParentWnd OPTIONAL,
+ IN UINT uIDTitle,
+ IN UINT uIDMessage)
+{
+ WCHAR message[512], caption[64];
+
+ LoadStringW(SetupData.hInstance, uIDMessage, message, ARRAYSIZE(message));
+ LoadStringW(SetupData.hInstance, uIDTitle, caption, ARRAYSIZE(caption));
+
+ return MessageBoxW(hParentWnd, message, caption, MB_OK | MB_ICONERROR);
+}
+
static INT_PTR CALLBACK
StartDlgProc(HWND hwndDlg,
UINT uMsg,
if (tindex != CB_ERR)
{
pSetupData->SelectedComputer = SendMessage(hList,
- CB_GETITEMDATA,
- (WPARAM) tindex,
- (LPARAM) 0);
+ CB_GETITEMDATA,
+ (WPARAM) tindex,
+ (LPARAM) 0);
}
hList = GetDlgItem(hwndDlg, IDC_DISPLAY);
if (tindex != CB_ERR)
{
pSetupData->SelectedDisplay = SendMessage(hList,
- CB_GETITEMDATA,
- (WPARAM) tindex,
- (LPARAM) 0);
+ CB_GETITEMDATA,
+ (WPARAM) tindex,
+ (LPARAM) 0);
}
hList =GetDlgItem(hwndDlg, IDC_KEYBOARD);
if (tindex != CB_ERR)
{
pSetupData->SelectedKeyboard = SendMessage(hList,
- CB_GETITEMDATA,
- (WPARAM) tindex,
- (LPARAM) 0);
+ CB_GETITEMDATA,
+ (WPARAM) tindex,
+ (LPARAM) 0);
}
return TRUE;
}
BOOL LoadSetupData(
PSETUPDATA pSetupData)
{
- WCHAR szPath[MAX_PATH];
- TCHAR tmp[10];
- WCHAR *ch;
- HINF hTxtsetupSif = INVALID_HANDLE_VALUE;
+ BOOL ret = TRUE;
INFCONTEXT InfContext;
+ TCHAR tmp[10];
//TCHAR szValue[MAX_PATH];
DWORD LineLength;
LONG Count;
- BOOL ret = TRUE;
-
- GetModuleFileNameW(NULL,szPath,MAX_PATH);
- ch = strrchrW(szPath,L'\\');
- if (ch != NULL)
- *ch = L'\0';
-
- wcscat(szPath, L"\\txtsetup.sif");
- hTxtsetupSif = SetupOpenInfFileW(szPath, NULL, INF_STYLE_OLDNT, NULL);
- if (hTxtsetupSif == INVALID_HANDLE_VALUE)
- {
- TCHAR message[512], caption[64];
-
- // txtsetup.sif cannot be found
- LoadString(pSetupData->hInstance, IDS_NO_TXTSETUP_SIF, message, sizeof(message)/sizeof(TCHAR));
- LoadString(pSetupData->hInstance, IDS_CAPTION, caption, sizeof(caption)/sizeof(TCHAR));
-
- MessageBox(NULL, message, caption, MB_OK | MB_ICONERROR);
- return FALSE;
- }
// get language list
- pSetupData->LangCount = SetupGetLineCount(hTxtsetupSif, _T("Language"));
+ pSetupData->LangCount = SetupGetLineCount(pSetupData->SetupInf, _T("Language"));
if (pSetupData->LangCount > 0)
{
pSetupData->pLanguages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LANG) * pSetupData->LangCount);
}
Count = 0;
- if (SetupFindFirstLine(hTxtsetupSif, _T("Language"), NULL, &InfContext))
+ if (SetupFindFirstLine(pSetupData->SetupInf, _T("Language"), NULL, &InfContext))
{
do
{
}
// get keyboard layout list
- pSetupData->KbLayoutCount = SetupGetLineCount(hTxtsetupSif, _T("KeyboardLayout"));
+ pSetupData->KbLayoutCount = SetupGetLineCount(pSetupData->SetupInf, _T("KeyboardLayout"));
if (pSetupData->KbLayoutCount > 0)
{
pSetupData->pKbLayouts = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KBLAYOUT) * pSetupData->KbLayoutCount);
}
Count = 0;
- if (SetupFindFirstLine(hTxtsetupSif, _T("KeyboardLayout"), NULL, &InfContext))
+ if (SetupFindFirstLine(pSetupData->SetupInf, _T("KeyboardLayout"), NULL, &InfContext))
{
do
{
pSetupData->DefaultLang = -1;
// TODO: get defaults from underlaying running system
- if (SetupFindFirstLine(hTxtsetupSif, _T("NLS"), _T("DefaultLayout"), &InfContext))
+ if (SetupFindFirstLine(pSetupData->SetupInf, _T("NLS"), _T("DefaultLayout"), &InfContext))
{
SetupGetStringField(&InfContext, 1, tmp, sizeof(tmp) / sizeof(TCHAR), &LineLength);
for (Count = 0; Count < pSetupData->KbLayoutCount; Count++)
}
}
- if (SetupFindFirstLine(hTxtsetupSif, _T("NLS"), _T("DefaultLanguage"), &InfContext))
+ if (SetupFindFirstLine(pSetupData->SetupInf, _T("NLS"), _T("DefaultLanguage"), &InfContext))
{
SetupGetStringField(&InfContext, 1, tmp, sizeof(tmp) / sizeof(TCHAR), &LineLength);
for (Count = 0; Count < pSetupData->LangCount; Count++)
}
// get computers list
- pSetupData->CompCount = LoadGenentry(hTxtsetupSif,_T("Computer"),&pSetupData->pComputers,&InfContext);
+ pSetupData->CompCount = LoadGenentry(pSetupData->SetupInf,_T("Computer"),&pSetupData->pComputers,&InfContext);
// get display list
- pSetupData->DispCount = LoadGenentry(hTxtsetupSif,_T("Display"),&pSetupData->pDisplays,&InfContext);
+ pSetupData->DispCount = LoadGenentry(pSetupData->SetupInf,_T("Display"),&pSetupData->pDisplays,&InfContext);
// get keyboard list
- pSetupData->KeybCount = LoadGenentry(hTxtsetupSif, _T("Keyboard"),&pSetupData->pKeyboards,&InfContext);
+ pSetupData->KeybCount = LoadGenentry(pSetupData->SetupInf, _T("Keyboard"),&pSetupData->pKeyboards,&InfContext);
// get install directory
- if (SetupFindFirstLine(hTxtsetupSif, _T("SetupData"), _T("DefaultPath"), &InfContext))
+ if (SetupFindFirstLine(pSetupData->SetupInf, _T("SetupData"), _T("DefaultPath"), &InfContext))
{
SetupGetStringField(&InfContext,
1,
- pSetupData->InstallDir,
- sizeof(pSetupData->InstallDir) / sizeof(TCHAR),
+ pSetupData->USetupData.InstallationDirectory,
+ sizeof(pSetupData->USetupData.InstallationDirectory) / sizeof(TCHAR),
&LineLength);
}
}
}
- if (hTxtsetupSif != INVALID_HANDLE_VALUE)
- SetupCloseInfFile(hTxtsetupSif);
-
return ret;
}
return TotalCount;
}
-BOOL isUnattendSetup(VOID)
+/*
+ * Attempts to convert a pure NT file path into a corresponding Win32 path.
+ * Adapted from GetInstallSourceWin32() in dll/win32/syssetup/wizard.c
+ */
+BOOL
+ConvertNtPathToWin32Path(
+ OUT PWSTR pwszPath,
+ IN DWORD cchPathMax,
+ IN PCWSTR pwszNTPath)
{
- WCHAR szPath[MAX_PATH];
- WCHAR *ch;
- HINF hUnattendedInf;
- INFCONTEXT InfContext;
- TCHAR szValue[MAX_PATH];
- DWORD LineLength;
- //HKEY hKey;
- BOOL result = 0;
+ WCHAR wszDrives[512];
+ WCHAR wszNTPath[512]; // MAX_PATH ?
+ DWORD cchDrives;
+ PWCHAR pwszDrive;
- GetModuleFileNameW(NULL, szPath, MAX_PATH);
- ch = strrchrW(szPath, L'\\');
- if (ch != NULL)
- *ch = L'\0';
+ *pwszPath = UNICODE_NULL;
- wcscat(szPath, L"\\unattend.inf");
- hUnattendedInf = SetupOpenInfFileW(szPath, NULL, INF_STYLE_OLDNT, NULL);
+ cchDrives = GetLogicalDriveStringsW(_countof(wszDrives) - 1, wszDrives);
+ if (cchDrives == 0 || cchDrives >= _countof(wszDrives))
+ {
+ /* Buffer too small or failure */
+ DPRINT1("GetLogicalDriveStringsW failed\n");
+ return FALSE;
+ }
- if (hUnattendedInf != INVALID_HANDLE_VALUE)
+ for (pwszDrive = wszDrives; *pwszDrive; pwszDrive += wcslen(pwszDrive) + 1)
{
- if (SetupFindFirstLine(hUnattendedInf, _T("Unattend"), _T("UnattendSetupEnabled"),&InfContext))
+ /* Retrieve the NT path corresponding to the current Win32 DOS path */
+ pwszDrive[2] = UNICODE_NULL; // Temporarily remove the backslash
+ QueryDosDeviceW(pwszDrive, wszNTPath, _countof(wszNTPath));
+ pwszDrive[2] = L'\\'; // Restore the backslash
+
+ wcscat(wszNTPath, L"\\"); // Concat a backslash
+
+ DPRINT1("Testing '%S' --> '%S'\n", pwszDrive, wszNTPath);
+
+ /* Check whether the NT path corresponds to the NT installation source path */
+ if (!_wcsnicmp(wszNTPath, pwszNTPath, wcslen(wszNTPath)))
{
- if (SetupGetStringField(&InfContext,
- 1,
- szValue,
- sizeof(szValue) / sizeof(TCHAR),
- &LineLength) && (_tcsicmp(szValue, _T("yes")) == 0))
- {
- result = 1; // unattendSetup enabled
- // read values and store in SetupData
- }
+ /* Found it! */
+ wsprintf(pwszPath, L"%s%s", // cchPathMax
+ pwszDrive, pwszNTPath + wcslen(wszNTPath));
+ DPRINT1("ConvertNtPathToWin32Path: %S\n", pwszPath);
+ return TRUE;
}
- SetupCloseInfFile(hUnattendedInf);
}
- return result;
+ return FALSE;
}
-#if 0
-static
-VOID
-EnableShutdownPrivilege(VOID)
+/* Used to enable and disable the shutdown privilege */
+/* static */ BOOL
+EnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege)
{
- HANDLE hToken = NULL;
- TOKEN_PRIVILEGES Privileges;
-
- /* Get shutdown privilege */
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
- {
-// FatalError("OpenProcessToken() failed!");
- return;
- }
+ BOOL Success;
+ HANDLE hToken;
+ TOKEN_PRIVILEGES tp;
- if (!LookupPrivilegeValue(NULL,
- SE_SHUTDOWN_NAME,
- &Privileges.Privileges[0].Luid))
- {
-// FatalError("LookupPrivilegeValue() failed!");
- goto done;
- }
+ Success = OpenProcessToken(GetCurrentProcess(),
+ TOKEN_ADJUST_PRIVILEGES,
+ &hToken);
+ if (!Success) return Success;
- Privileges.PrivilegeCount = 1;
- Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ Success = LookupPrivilegeValueW(NULL,
+ lpszPrivilegeName,
+ &tp.Privileges[0].Luid);
+ if (!Success) goto Quit;
- if (AdjustTokenPrivileges(hToken,
- FALSE,
- &Privileges,
- 0,
- (PTOKEN_PRIVILEGES)NULL,
- NULL) == 0)
- {
-// FatalError("AdjustTokenPrivileges() failed!");
- goto done;
- }
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0);
-done:
- if (hToken != NULL)
- CloseHandle(hToken);
+ Success = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
- return;
+Quit:
+ CloseHandle(hToken);
+ return Success;
}
-#endif
int WINAPI
_tWinMain(HINSTANCE hInst,
LPTSTR lpszCmdLine,
int nCmdShow)
{
- PSETUPDATA pSetupData = NULL;
+ NTSTATUS Status;
+ ULONG Error;
PROPSHEETHEADER psh;
HPROPSHEETPAGE ahpsp[8];
PROPSHEETPAGE psp = {0};
UINT nPages = 0;
- pSetupData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SETUPDATA));
- if (pSetupData == NULL)
+ ProcessHeap = GetProcessHeap();
+
+ /* Initialize global unicode strings */
+ RtlInitUnicodeString(&SetupData.USetupData.SourcePath, NULL);
+ RtlInitUnicodeString(&SetupData.USetupData.SourceRootPath, NULL);
+ RtlInitUnicodeString(&SetupData.USetupData.SourceRootDir, NULL);
+ // RtlInitUnicodeString(&InstallPath, NULL);
+ RtlInitUnicodeString(&SetupData.USetupData.DestinationPath, NULL);
+ RtlInitUnicodeString(&SetupData.USetupData.DestinationArcPath, NULL);
+ RtlInitUnicodeString(&SetupData.USetupData.DestinationRootPath, NULL);
+ RtlInitUnicodeString(&SetupData.USetupData.SystemRootPath, NULL);
+
+ /* Get the source path and source root path */
+ //
+ // NOTE: Sometimes the source path may not be in SystemRoot !!
+ // (and this is the case when using the 1st-stage GUI setup!)
+ //
+ Status = GetSourcePaths(&SetupData.USetupData.SourcePath,
+ &SetupData.USetupData.SourceRootPath,
+ &SetupData.USetupData.SourceRootDir);
+ if (!NT_SUCCESS(Status))
{
- return 1;
+ DPRINT1("GetSourcePaths() failed (Status 0x%08lx)", Status);
+ // MUIDisplayError(ERROR_NO_SOURCE_DRIVE, Ir, POPUP_WAIT_ENTER);
+ MessageBoxW(NULL, L"GetSourcePaths failed!", L"Error", MB_ICONERROR);
+ goto Quit;
}
+ DPRINT1("SourcePath: '%wZ'\n", &SetupData.USetupData.SourcePath);
+ DPRINT1("SourceRootPath: '%wZ'\n", &SetupData.USetupData.SourceRootPath);
+ DPRINT1("SourceRootDir: '%wZ'\n", &SetupData.USetupData.SourceRootDir);
- pSetupData->hInstance = hInst;
- pSetupData->bUnattend = isUnattendSetup();
+ /* Load 'txtsetup.sif' from the installation media */
+ Error = LoadSetupInf(&SetupData.SetupInf, &SetupData.USetupData);
+ if (Error != ERROR_SUCCESS)
+ {
+ // MUIDisplayError(Error, Ir, POPUP_WAIT_ENTER);
+ DisplayError(NULL, IDS_CAPTION, IDS_NO_TXTSETUP_SIF);
+ goto Quit;
+ }
+ /* Load extra setup data (HW lists etc...) */
+ if (!LoadSetupData(&SetupData))
+ goto Quit;
- LoadString(hInst,IDS_ABORTSETUP, pSetupData->szAbortMessage, sizeof(pSetupData->szAbortMessage)/sizeof(TCHAR));
- LoadString(hInst,IDS_ABORTSETUP2, pSetupData->szAbortTitle, sizeof(pSetupData->szAbortTitle)/sizeof(TCHAR));
+ SetupData.hInstance = hInst;
+
+ CheckUnattendedSetup(&SetupData.USetupData);
+ SetupData.bUnattend = IsUnattendedSetup;
+
+ LoadStringW(hInst, IDS_ABORTSETUP, SetupData.szAbortMessage, ARRAYSIZE(SetupData.szAbortMessage));
+ LoadStringW(hInst, IDS_ABORTSETUP2, SetupData.szAbortTitle, ARRAYSIZE(SetupData.szAbortTitle));
/* Create title font */
- pSetupData->hTitleFont = CreateTitleFont();
+ SetupData.hTitleFont = CreateTitleFont();
- if (!pSetupData->bUnattend)
+ if (!SetupData.bUnattend)
{
- if (!LoadSetupData(pSetupData))
- {
- HeapFree(GetProcessHeap(), 0, pSetupData);
- return 0;
- }
-
/* Create the Start page, until setup is working */
+ // NOTE: What does "until setup is working" mean??
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
psp.hInstance = hInst;
- psp.lParam = (LPARAM)pSetupData;
+ psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = StartDlgProc;
psp.pszTemplate = MAKEINTRESOURCE(IDD_STARTPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_TYPETITLE);
psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_TYPESUBTITLE);
psp.hInstance = hInst;
- psp.lParam = (LPARAM)pSetupData;
+ psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = TypeDlgProc;
psp.pszTemplate = MAKEINTRESOURCE(IDD_TYPEPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DEVICETITLE);
psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DEVICESUBTITLE);
psp.hInstance = hInst;
- psp.lParam = (LPARAM)pSetupData;
+ psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = DeviceDlgProc;
psp.pszTemplate = MAKEINTRESOURCE(IDD_DEVICEPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DRIVETITLE);
psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DRIVESUBTITLE);
psp.hInstance = hInst;
- psp.lParam = (LPARAM)pSetupData;
+ psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = DriveDlgProc;
psp.pszTemplate = MAKEINTRESOURCE(IDD_DRIVEPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SUMMARYTITLE);
psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_SUMMARYSUBTITLE);
psp.hInstance = hInst;
- psp.lParam = (LPARAM)pSetupData;
+ psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = SummaryDlgProc;
psp.pszTemplate = MAKEINTRESOURCE(IDD_SUMMARYPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROCESSTITLE);
psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PROCESSSUBTITLE);
psp.hInstance = hInst;
- psp.lParam = (LPARAM)pSetupData;
+ psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = ProcessDlgProc;
psp.pszTemplate = MAKEINTRESOURCE(IDD_PROCESSPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
psp.hInstance = hInst;
- psp.lParam = (LPARAM)pSetupData;
+ psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = RestartDlgProc;
psp.pszTemplate = MAKEINTRESOURCE(IDD_RESTARTPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
/* Display the wizard */
PropertySheet(&psh);
- if (pSetupData->hTitleFont)
- DeleteObject(pSetupData->hTitleFont);
+ if (SetupData.hTitleFont)
+ DeleteObject(SetupData.hTitleFont);
+
+ SetupCloseInfFile(SetupData.SetupInf);
- HeapFree(GetProcessHeap(), 0, pSetupData);
+Quit:
-#if 0
- EnableShutdownPrivilege();
+#if 0 // NOTE: Disabled for testing purposes only!
+ EnablePrivilege(SE_SHUTDOWN_NAME, TRUE);
ExitWindowsEx(EWX_REBOOT, 0);
+ EnablePrivilege(SE_SHUTDOWN_NAME, FALSE);
#endif
return 0;