usetup.c
来自「一个类似windows」· C语言 代码 · 共 2,599 行 · 第 1/5 页
C
2,599 行
/*
* ReactOS kernel
* Copyright (C) 2002, 2003, 2004 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.
*/
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/usetup.c
* PURPOSE: Text-mode setup
* PROGRAMMER: Eric Kohl
* Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
#include <usetup.h>
#define NDEBUG
#include <debug.h>
typedef enum _PAGE_NUMBER
{
START_PAGE,
INTRO_PAGE,
LICENSE_PAGE,
INSTALL_INTRO_PAGE,
// SCSI_CONTROLLER_PAGE,
DEVICE_SETTINGS_PAGE,
COMPUTER_SETTINGS_PAGE,
DISPLAY_SETTINGS_PAGE,
KEYBOARD_SETTINGS_PAGE,
LAYOUT_SETTINGS_PAGE,
SELECT_PARTITION_PAGE,
CREATE_PARTITION_PAGE,
DELETE_PARTITION_PAGE,
SELECT_FILE_SYSTEM_PAGE,
FORMAT_PARTITION_PAGE,
CHECK_FILE_SYSTEM_PAGE,
PREPARE_COPY_PAGE,
INSTALL_DIRECTORY_PAGE,
FILE_COPY_PAGE,
REGISTRY_PAGE,
BOOT_LOADER_PAGE,
BOOT_LOADER_FLOPPY_PAGE,
BOOT_LOADER_HARDDISK_PAGE,
REPAIR_INTRO_PAGE,
SUCCESS_PAGE,
QUIT_PAGE,
FLUSH_PAGE,
REBOOT_PAGE, /* virtual page */
} PAGE_NUMBER, *PPAGE_NUMBER;
typedef struct _COPYCONTEXT
{
ULONG TotalOperations;
ULONG CompletedOperations;
PPROGRESSBAR ProgressBar;
} COPYCONTEXT, *PCOPYCONTEXT;
/* GLOBALS ******************************************************************/
HANDLE ProcessHeap;
UNICODE_STRING SourceRootPath;
BOOLEAN IsUnattendedSetup;
LONG UnattendDestinationDiskNumber;
LONG UnattendDestinationPartitionNumber;
WCHAR UnattendInstallationDirectory[MAX_PATH];
/* LOCALS *******************************************************************/
static PPARTLIST PartitionList = NULL;
static PFILE_SYSTEM_LIST FileSystemList = NULL;
static UNICODE_STRING SourcePath;
static UNICODE_STRING InstallPath;
/* Path to the install directory */
static UNICODE_STRING DestinationPath;
static UNICODE_STRING DestinationArcPath;
static UNICODE_STRING DestinationRootPath;
/* Path to the active partition (boot manager) */
static UNICODE_STRING SystemRootPath;
static HINF SetupInf;
static HSPFILEQ SetupFileQueue = NULL;
static BOOLEAN WarnLinuxPartitions = TRUE;
static PGENERIC_LIST ComputerList = NULL;
static PGENERIC_LIST DisplayList = NULL;
static PGENERIC_LIST KeyboardList = NULL;
static PGENERIC_LIST LayoutList = NULL;
/* FUNCTIONS ****************************************************************/
static VOID
PrintString(char* fmt,...)
{
char buffer[512];
va_list ap;
UNICODE_STRING UnicodeString;
ANSI_STRING AnsiString;
va_start(ap, fmt);
vsprintf(buffer, fmt, ap);
va_end(ap);
RtlInitAnsiString(&AnsiString, buffer);
RtlAnsiStringToUnicodeString(&UnicodeString,
&AnsiString,
TRUE);
NtDisplayString(&UnicodeString);
RtlFreeUnicodeString(&UnicodeString);
}
static VOID
PopupError(PCHAR Text,
PCHAR Status)
{
SHORT xScreen;
SHORT yScreen;
SHORT yTop;
SHORT xLeft;
COORD coPos;
ULONG Written;
ULONG Length;
ULONG MaxLength;
ULONG Lines;
PCHAR p;
PCHAR pnext;
BOOLEAN LastLine;
SHORT Width;
SHORT Height;
/* Count text lines and longest line */
MaxLength = 0;
Lines = 0;
pnext = Text;
while (TRUE)
{
p = strchr(pnext, '\n');
if (p == NULL)
{
Length = strlen(pnext);
LastLine = TRUE;
}
else
{
Length = (ULONG)(p - pnext);
LastLine = FALSE;
}
Lines++;
if (Length > MaxLength)
MaxLength = Length;
if (LastLine == TRUE)
break;
pnext = p + 1;
}
/* Check length of status line */
if (Status != NULL)
{
Length = strlen(Status);
if (Length > MaxLength)
MaxLength = Length;
}
GetScreenSize(&xScreen, &yScreen);
Width = MaxLength + 4;
Height = Lines + 2;
if (Status != NULL)
Height += 2;
yTop = (yScreen - Height) / 2;
xLeft = (xScreen - Width) / 2;
/* Set screen attributes */
coPos.X = xLeft;
for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++)
{
FillConsoleOutputAttribute(0x74,
Width,
coPos,
&Written);
}
/* draw upper left corner */
coPos.X = xLeft;
coPos.Y = yTop;
FillConsoleOutputCharacter(0xDA, // '+',
1,
coPos,
&Written);
/* draw upper edge */
coPos.X = xLeft + 1;
coPos.Y = yTop;
FillConsoleOutputCharacter(0xC4, // '-',
Width - 2,
coPos,
&Written);
/* draw upper right corner */
coPos.X = xLeft + Width - 1;
coPos.Y = yTop;
FillConsoleOutputCharacter(0xBF, // '+',
1,
coPos,
&Written);
/* Draw right edge, inner space and left edge */
for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++)
{
coPos.X = xLeft;
FillConsoleOutputCharacter(0xB3, // '|',
1,
coPos,
&Written);
coPos.X = xLeft + 1;
FillConsoleOutputCharacter(' ',
Width - 2,
coPos,
&Written);
coPos.X = xLeft + Width - 1;
FillConsoleOutputCharacter(0xB3, // '|',
1,
coPos,
&Written);
}
/* draw lower left corner */
coPos.X = xLeft;
coPos.Y = yTop + Height - 1;
FillConsoleOutputCharacter(0xC0, // '+',
1,
coPos,
&Written);
/* draw lower edge */
coPos.X = xLeft + 1;
coPos.Y = yTop + Height - 1;
FillConsoleOutputCharacter(0xC4, // '-',
Width - 2,
coPos,
&Written);
/* draw lower right corner */
coPos.X = xLeft + Width - 1;
coPos.Y = yTop + Height - 1;
FillConsoleOutputCharacter(0xD9, // '+',
1,
coPos,
&Written);
/* Print message text */
coPos.Y = yTop + 1;
pnext = Text;
while (TRUE)
{
p = strchr(pnext, '\n');
if (p == NULL)
{
Length = strlen(pnext);
LastLine = TRUE;
}
else
{
Length = (ULONG)(p - pnext);
LastLine = FALSE;
}
if (Length != 0)
{
coPos.X = xLeft + 2;
WriteConsoleOutputCharacters(pnext,
Length,
coPos);
}
if (LastLine == TRUE)
break;
coPos.Y++;
pnext = p + 1;
}
/* Print separator line and status text */
if (Status != NULL)
{
coPos.Y = yTop + Height - 3;
coPos.X = xLeft;
FillConsoleOutputCharacter(0xC3, // '+',
1,
coPos,
&Written);
coPos.X = xLeft + 1;
FillConsoleOutputCharacter(0xC4, // '-',
Width - 2,
coPos,
&Written);
coPos.X = xLeft + Width - 1;
FillConsoleOutputCharacter(0xB4, // '+',
1,
coPos,
&Written);
coPos.Y++;
coPos.X = xLeft + 2;
WriteConsoleOutputCharacters(Status,
min(strlen(Status), (SIZE_T)Width - 4),
coPos);
}
}
/*
* Confirm quit setup
* RETURNS
* TRUE: Quit setup.
* FALSE: Don't quit setup.
*/
static BOOL
ConfirmQuit(PINPUT_RECORD Ir)
{
BOOL Result = FALSE;
PopupError("ReactOS is not completely installed on your\n"
"computer. If you quit Setup now, you will need to\n"
"run Setup again to install ReactOS.\n"
"\n"
" \x07 Press ENTER to continue Setup.\n"
" \x07 Press F3 to quit Setup.",
"F3= Quit ENTER = Continue");
while(TRUE)
{
ConInKey(Ir);
if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
(Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
{
Result = TRUE;
break;
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
Result = FALSE;
break;
}
}
return Result;
}
VOID
CheckUnattendedSetup(VOID)
{
WCHAR UnattendInfPath[MAX_PATH];
UNICODE_STRING FileName;
PINFCONTEXT Context;
HINF UnattendInf;
ULONG ErrorLine;
NTSTATUS Status;
LONG IntValue;
PWCHAR Value;
if (DoesFileExist(SourcePath.Buffer, L"unattend.inf") == FALSE)
{
DPRINT("Does not exist: %S\\%S\n", SourcePath.Buffer, L"unattend.inf");
IsUnattendedSetup = FALSE;
return;
}
wcscpy(UnattendInfPath, SourcePath.Buffer);
wcscat(UnattendInfPath, L"\\unattend.inf");
RtlInitUnicodeString(&FileName,
UnattendInfPath);
/* Load 'unattend.inf' from install media. */
Status = InfOpenFile(&UnattendInf,
&FileName,
&ErrorLine);
if (!NT_SUCCESS(Status))
{
DPRINT("InfOpenFile() failed with status 0x%x\n", Status);
return;
}
/* Open 'Unattend' section */
if (!InfFindFirstLine(UnattendInf, L"Unattend", L"Signature", &Context))
{
DPRINT("InfFindFirstLine() failed for section 'Unattend'\n");
InfFreeContext(Context);
InfCloseFile(UnattendInf);
return;
}
/* Get pointer 'Signature' key */
if (!InfGetData(Context, NULL, &Value))
{
DPRINT("InfGetData() failed for key 'Signature'\n");
InfFreeContext(Context);
InfCloseFile(UnattendInf);
return;
}
/* Check 'Signature' string */
if (_wcsicmp(Value, L"$ReactOS$") != 0)
{
DPRINT("Signature not $ReactOS$\n");
InfFreeContext(Context);
InfCloseFile(UnattendInf);
return;
}
/* Search for 'DestinationDiskNumber' in the 'Unattend' section */
if (!InfFindFirstLine(UnattendInf, L"Unattend", L"DestinationDiskNumber", &Context))
{
DPRINT("InfFindFirstLine() failed for key 'DestinationDiskNumber'\n");
InfFreeContext(Context);
InfCloseFile(UnattendInf);
return;
}
if (!InfGetIntField(Context, 0, &IntValue))
{
DPRINT("InfGetIntField() failed for key 'DestinationDiskNumber'\n");
InfFreeContext(Context);
InfCloseFile(UnattendInf);
return;
}
UnattendDestinationDiskNumber = IntValue;
InfFreeContext(Context);
/* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
if (!InfFindFirstLine(UnattendInf, L"Unattend", L"DestinationPartitionNumber", &Context))
{
DPRINT("InfFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
InfFreeContext(Context);
InfCloseFile(UnattendInf);
return;
}
if (!InfGetIntField(Context, 0, &IntValue))
{
DPRINT("InfGetIntField() failed for key 'DestinationPartitionNumber'\n");
InfFreeContext(Context);
InfCloseFile(UnattendInf);
return;
}
UnattendDestinationPartitionNumber = IntValue;
InfFreeContext(Context);
/* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
if (!InfFindFirstLine(UnattendInf, L"Unattend", L"DestinationPartitionNumber", &Context))
{
DPRINT("InfFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
InfCloseFile(UnattendInf);
return;
}
/* Get pointer 'InstallationDirectory' key */
if (!InfGetData(Context, NULL, &Value))
{
DPRINT("InfGetData() failed for key 'InstallationDirectory'\n");
InfFreeContext(Context);
InfCloseFile(UnattendInf);
return;
}
wcscpy(UnattendInstallationDirectory, Value);
InfFreeContext(Context);
InfCloseFile(UnattendInf);
IsUnattendedSetup = TRUE;
DPRINT("Running unattended setup\n");
}
/*
* Start page
* RETURNS
* Number of the next page.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?