Prepared bootloader installation.

svn path=/trunk/; revision=4022
This commit is contained in:
Eric Kohl 2003-01-17 13:18:15 +00:00
parent fec5d8fcaf
commit 5dc512f7c3
10 changed files with 1049 additions and 92 deletions

View file

@ -0,0 +1,282 @@
/*
* ReactOS kernel
* Copyright (C) 2002 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/bootsup.c
* PURPOSE: Bootloader support functions
* PROGRAMMER: Eric Kohl
*/
#include <ddk/ntddk.h>
#include <ntdll/rtl.h>
#include "usetup.h"
#include "inicache.h"
#include "bootsup.h"
/* FUNCTIONS ****************************************************************/
static VOID
CreateCommonFreeLoaderSections(PINICACHE IniCache)
{
PINICACHESECTION IniSection;
/* Create "FREELOADER" section */
IniSection = IniCacheAppendSection(IniCache,
L"FREELOADER");
#if 0
MessageLine=Welcome to FreeLoader!
MessageLine=Copyright (c) 2002 by Brian Palmer <brianp@sginet.com>
MessageLine=
MessageBox=Edit your FREELDR.INI file to change your boot settings.
#endif
/* DefaultOS=ReactOS */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"DefaultOS",
L"ReactOS");
/* Timeout=10 */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"TimeOut",
L"10");
/* Create "Display" section */
IniSection = IniCacheAppendSection(IniCache,
L"Display");
/* DisplayMode=NORMAL_VGA */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"DisplayMode",
L"NORMAL_VGA");
/* TitleText=Boot Menu */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"TitleText",
L"Boot Menu");
/* StatusBarColor=Cyan */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"StatusBarColor",
L"Cyan");
/* StatusBarTextColor=Black */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"StatusBarTextColor",
L"Black");
/* BackdropTextColor=White */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"BackdropTextColor",
L"White");
/* BackdropColor=Blue */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"BackdropColor",
L"Blue");
/* BackdropFillStyle=Medium */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"BackdropFillStyle",
L"Medium");
/* TitleBoxTextColor=White */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"TitleBoxTextColor",
L"White");
/* TitleBoxColor=Red */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"TitleBoxColor",
L"Red");
/* MessageBoxTextColor=White */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"MessageBoxTextColor",
L"White");
/* MessageBoxColor=Blue */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"MessageBoxColor",
L"Blue");
/* MenuTextColor=White */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"MenuTextColor",
L"White");
/* MenuColor=Blue */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"MenuColor",
L"Blue");
/* TextColor=Yellow */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"TextColor",
L"Yellow");
/* SelectedTextColor=Black */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"SelectedTextColor",
L"Black");
/* SelectedColor=Gray */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"SelectedColor",
L"Gray");
}
NTSTATUS
CreateFreeLoaderIniForDos(PWCHAR IniPath,
PWCHAR SystemPath)
{
PINICACHE IniCache;
PINICACHESECTION IniSection;
IniCache = IniCacheCreate();
CreateCommonFreeLoaderSections(IniCache);
/* Create "OperatingSystems" section */
IniSection = IniCacheAppendSection(IniCache,
L"OperatingSystems");
/* REACTOS=ReactOS */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"REACTOS",
L"ReactOS");
/* DOS=Dos/Windows */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"DOS",
L"DOS/Windows");
/* Create "REACTOS" section */
IniSection = IniCacheAppendSection(IniCache,
L"REACTOS");
/* BootType=ReactOS */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"BootType",
L"ReactOS");
/* SystemPath=multi(0)disk(0)rdisk(0)partition(1)\reactos */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"SystemPath",
SystemPath);
/* Options=/DEBUGPORT=SCREEN */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"Options",
L"/DEBUGPORT=SCREEN");
/* Kernel=\REACTOS\SYSTEM32\NTOSKRNL.EXE */
#if 0
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"Options",
L"/DEBUGPORT=SCREEN");
#endif
/* Hal=\REACTOS\SYSTEM32\HAL.DLL */
#if 0
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"Hal",
L"/DEBUGPORT=SCREEN");
#endif
/* Create "DOS" section */
IniSection = IniCacheAppendSection(IniCache,
L"DOS");
/* BootType=BootSector */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"BootType",
L"BootSector");
/* BootSector=BOOTDOS.BIN */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"BootSector",
L"BOOTDOS.BIN");
IniCacheSave(IniCache, IniPath);
IniCacheDestroy(IniCache);
}
/* EOF */

View file

@ -0,0 +1,37 @@
/*
* ReactOS kernel
* Copyright (C) 2002 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: bootsup.h,v 1.1 2003/01/17 13:18:15 ekohl Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/bootsup.h
* PURPOSE: Bootloader support functions
* PROGRAMMER: Eric Kohl
*/
#ifndef __BOOTSUP_H__
#define __BOOTSUP_H__
NTSTATUS
CreateFreeLoaderIniForDos(PWCHAR IniPath,
PWCHAR SystemPath);
#endif /* __BOOTSUP_H__ */
/* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: filesup.c,v 1.3 2003/01/11 16:03:55 hbirr Exp $
/* $Id: filesup.c,v 1.4 2003/01/17 13:18:15 ekohl Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/filesup.c
@ -276,4 +276,50 @@ CHECKPOINT1;
return(STATUS_SUCCESS);
}
BOOLEAN
DoesFileExist(PWSTR PathName,
PWSTR FileName)
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING Name;
WCHAR FullName[MAX_PATH];
HANDLE FileHandle;
NTSTATUS Status;
wcscpy(FullName, PathName);
if (FileName != NULL)
{
if (FileName[0] != L'\\')
wcscat(FullName, L"\\");
wcscat(FullName, FileName);
}
RtlInitUnicodeString(&Name,
FullName);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
FILE_READ_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
0,
FILE_SYNCHRONOUS_IO_ALERT);
if (!NT_SUCCESS(Status))
{
CHECKPOINT1;
return(FALSE);
}
NtClose(FileHandle);
return(TRUE);
}
/* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: filesup.h,v 1.2 2002/11/23 01:55:27 ekohl Exp $
/* $Id: filesup.h,v 1.3 2003/01/17 13:18:15 ekohl Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/filesup.h
@ -34,6 +34,10 @@ NTSTATUS
SetupCopyFile(PWCHAR SourceFileName,
PWCHAR DestinationFileName);
BOOLEAN
DoesFileExist(PWSTR PathName,
PWSTR FileName);
#endif /* __FILESUP_H__ */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: inicache.c,v 1.1 2002/11/13 18:25:18 ekohl Exp $
/* $Id: inicache.c,v 1.2 2003/01/17 13:18:15 ekohl Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/inicache.c
@ -53,12 +53,12 @@ IniCacheFreeKey(PINICACHEKEY Key)
Key->Name = NULL;
}
if (Key->Value != NULL)
if (Key->Data != NULL)
{
RtlFreeHeap(ProcessHeap,
0,
Key->Value);
Key->Value = NULL;
Key->Data);
Key->Data = NULL;
}
RtlFreeHeap(ProcessHeap,
@ -129,8 +129,8 @@ static PINICACHEKEY
IniCacheAddKey(PINICACHESECTION Section,
PCHAR Name,
ULONG NameLength,
PCHAR Value,
ULONG ValueLength)
PCHAR Data,
ULONG DataLength)
{
PINICACHEKEY Key;
ULONG i;
@ -140,8 +140,8 @@ IniCacheAddKey(PINICACHESECTION Section,
if (Section == NULL ||
Name == NULL ||
NameLength == 0 ||
Value == NULL ||
ValueLength == 0)
Data == NULL ||
DataLength == 0)
{
DPRINT("Invalid parameter\n");
return(NULL);
@ -180,10 +180,10 @@ IniCacheAddKey(PINICACHESECTION Section,
Key->Name[NameLength] = 0;
Key->Value = RtlAllocateHeap(ProcessHeap,
Key->Data = RtlAllocateHeap(ProcessHeap,
0,
(ValueLength + 1) * sizeof(WCHAR));
if (Key->Value == NULL)
(DataLength + 1) * sizeof(WCHAR));
if (Key->Data == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
RtlFreeHeap(ProcessHeap,
@ -196,11 +196,11 @@ IniCacheAddKey(PINICACHESECTION Section,
}
/* Copy value data */
for (i = 0; i < ValueLength; i++)
for (i = 0; i < DataLength; i++)
{
Key->Value[i] = (WCHAR)Value[i];
Key->Data[i] = (WCHAR)Data[i];
}
Key->Value[ValueLength] = 0;
Key->Data[DataLength] = 0;
if (Section->FirstKey == NULL)
@ -711,7 +711,7 @@ IniCacheGetSection(PINICACHE Cache,
return(NULL);
}
/* iterate through list of sections */
/* Iterate through list of sections */
Section = Cache->FirstSection;
while (Section != NULL)
{
@ -734,17 +734,17 @@ IniCacheGetSection(PINICACHE Cache,
NTSTATUS
IniCacheGetKey(PINICACHESECTION Section,
PWCHAR KeyName,
PWCHAR *KeyValue)
PWCHAR *KeyData)
{
PINICACHEKEY Key;
if (Section == NULL || KeyName == NULL || KeyValue == NULL)
if (Section == NULL || KeyName == NULL || KeyData == NULL)
{
DPRINT("Invalid parameter\n");
return(STATUS_INVALID_PARAMETER);
}
*KeyValue = NULL;
*KeyData = NULL;
Key = IniCacheFindKey(Section, KeyName, wcslen(KeyName));
if (Key == NULL)
@ -752,7 +752,7 @@ IniCacheGetKey(PINICACHESECTION Section,
return(STATUS_INVALID_PARAMETER);
}
*KeyValue = Key->Value;
*KeyData = Key->Data;
return(STATUS_SUCCESS);
}
@ -761,12 +761,12 @@ IniCacheGetKey(PINICACHESECTION Section,
PINICACHEITERATOR
IniCacheFindFirstValue(PINICACHESECTION Section,
PWCHAR *KeyName,
PWCHAR *KeyValue)
PWCHAR *KeyData)
{
PINICACHEITERATOR Iterator;
PINICACHEKEY Key;
if (Section == NULL || KeyName == NULL || KeyValue == NULL)
if (Section == NULL || KeyName == NULL || KeyData == NULL)
{
DPRINT("Invalid parameter\n");
return(NULL);
@ -780,7 +780,7 @@ IniCacheFindFirstValue(PINICACHESECTION Section,
}
*KeyName = Key->Name;
*KeyValue = Key->Value;
*KeyData = Key->Data;
Iterator = (PINICACHEITERATOR)RtlAllocateHeap(ProcessHeap,
0,
@ -801,11 +801,11 @@ IniCacheFindFirstValue(PINICACHESECTION Section,
BOOLEAN
IniCacheFindNextValue(PINICACHEITERATOR Iterator,
PWCHAR *KeyName,
PWCHAR *KeyValue)
PWCHAR *KeyData)
{
PINICACHEKEY Key;
if (Iterator == NULL || KeyName == NULL || KeyValue == NULL)
if (Iterator == NULL || KeyName == NULL || KeyData == NULL)
{
DPRINT("Invalid parameter\n");
return(FALSE);
@ -819,7 +819,7 @@ IniCacheFindNextValue(PINICACHEITERATOR Iterator,
}
*KeyName = Key->Name;
*KeyValue = Key->Value;
*KeyData = Key->Data;
Iterator->Key = Key;
@ -838,4 +838,334 @@ IniCacheFindClose(PINICACHEITERATOR Iterator)
Iterator);
}
PINICACHEKEY
IniCacheInsertKey(PINICACHESECTION Section,
PINICACHEKEY AnchorKey,
INSERTATION_TYPE InsertationType,
PWCHAR Name,
PWCHAR Data)
{
PINICACHEKEY Key;
ULONG i;
Key = NULL;
if (Section == NULL ||
Name == NULL ||
*Name == 0 ||
Data == NULL ||
*Data == 0)
{
DPRINT("Invalid parameter\n");
return(NULL);
}
/* Allocate key buffer */
Key = (PINICACHEKEY)RtlAllocateHeap(ProcessHeap,
0,
sizeof(INICACHEKEY));
if (Key == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
return(NULL);
}
RtlZeroMemory(Key,
sizeof(INICACHEKEY));
/* Allocate name buffer */
Key->Name = RtlAllocateHeap(ProcessHeap,
0,
(wcslen(Name) + 1) * sizeof(WCHAR));
if (Key->Name == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
RtlFreeHeap(ProcessHeap,
0,
Key);
return(NULL);
}
/* Copy value name */
wcscpy(Key->Name, Name);
/* Allocate data buffer */
Key->Data = RtlAllocateHeap(ProcessHeap,
0,
(wcslen(Data) + 1) * sizeof(WCHAR));
if (Key->Data == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
RtlFreeHeap(ProcessHeap,
0,
Key->Name);
RtlFreeHeap(ProcessHeap,
0,
Key);
return(NULL);
}
/* Copy value data */
wcscpy(Key->Data, Data);
/* Insert key into section */
if (Section->FirstKey == NULL)
{
Section->FirstKey = Key;
Section->LastKey = Key;
}
else if ((InsertationType == INSERT_FIRST) ||
((InsertationType == INSERT_BEFORE) && ((AnchorKey == NULL) || (AnchorKey == Section->FirstKey))))
{
/* Insert at the head of the list */
Section->FirstKey->Prev = Key;
Key->Next = Section->FirstKey;
Section->FirstKey = Key;
}
else if ((InsertationType == INSERT_BEFORE) && (AnchorKey != NULL))
{
/* Insert before the anchor key */
Key->Next = AnchorKey;
Key->Prev = AnchorKey->Prev;
AnchorKey->Prev->Next = Key;
AnchorKey->Prev = Key;
}
else if ((InsertationType == INSERT_LAST) ||
((InsertationType == INSERT_AFTER) && ((AnchorKey == NULL) || (AnchorKey == Section->LastKey))))
{
Section->LastKey->Next = Key;
Key->Prev = Section->LastKey;
Section->LastKey = Key;
}
else if ((InsertationType == INSERT_AFTER) && (AnchorKey != NULL))
{
/* Insert before the anchor key */
Key->Next = AnchorKey->Next;
Key->Prev = AnchorKey;
AnchorKey->Next->Prev = Key;
AnchorKey->Next = Key;
}
return(Key);
}
PINICACHE
IniCacheCreate(VOID)
{
PINICACHE Cache;
/* Allocate inicache header */
Cache = (PINICACHE)RtlAllocateHeap(ProcessHeap,
0,
sizeof(INICACHE));
if (Cache == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
return(NULL);
}
/* Initialize inicache header */
RtlZeroMemory(Cache,
sizeof(INICACHE));
return(Cache);
}
NTSTATUS
IniCacheSave(PINICACHE Cache,
PWCHAR FileName)
{
UNICODE_STRING Name;
PINICACHESECTION Section;
PINICACHEKEY Key;
ULONG BufferSize;
PCHAR Buffer;
PCHAR Ptr;
ULONG Len;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER Offset;
HANDLE FileHandle;
/* Calculate required buffer size */
BufferSize = 0;
Section = Cache->FirstSection;
while (Section != NULL)
{
BufferSize += (Section->Name ? wcslen(Section->Name) : 0)
+ 4; /* "[]\r\n" */
Key = Section->FirstKey;
while (Key != NULL)
{
BufferSize += wcslen(Key->Name)
+ (Key->Data ? wcslen(Key->Data) : 0)
+ 3; /* "=\r\n" */
Key = Key->Next;
}
Section = Section->Next;
if (Section != NULL)
BufferSize += 2; /* extra "\r\n" at end of each section */
}
BufferSize++; /* Null-terminator */
DPRINT1("BufferSize: %lu\n", BufferSize);
/* Allocate file buffer */
Buffer = RtlAllocateHeap(ProcessHeap,
0,
BufferSize);
if (Buffer == NULL)
{
DPRINT1("RtlAllocateHeap() failed\n");
return(STATUS_INSUFFICIENT_RESOURCES);
}
RtlZeroMemory(Buffer, BufferSize);
/* Fill file buffer */
Ptr = Buffer;
Section = Cache->FirstSection;
while (Section != NULL)
{
Len = sprintf(Ptr, "[%S]\r\n", Section->Name);
Ptr += Len;
Key = Section->FirstKey;
while (Key != NULL)
{
Len = sprintf(Ptr, "%S=%S\r\n", Key->Name, Key->Data);
Ptr += Len;
Key = Key->Next;
}
Section = Section->Next;
if (Section != NULL)
{
Len = sprintf(Ptr, "\r\n");
Ptr += Len;
}
}
/* Create ini file */
RtlInitUnicodeString(&Name,
FileName);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
0,
NULL,
NULL);
Status = NtCreateFile(&FileHandle,
FILE_WRITE_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OVERWRITE_IF,
FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY,
NULL,
0);
if (!NT_SUCCESS(Status))
{
DPRINT("NtCreateFile() failed (Status %lx)\n", Status);
RtlFreeHeap(ProcessHeap,
0,
Buffer);
return(Status);
}
Offset.QuadPart = 0LL;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
Buffer,
BufferSize,
&Offset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
NtClose(FileHandle);
RtlFreeHeap(ProcessHeap,
0,
Buffer);
return(Status);
}
NtClose(FileHandle);
RtlFreeHeap(ProcessHeap,
0,
Buffer);
return(STATUS_SUCCESS);
}
PINICACHESECTION
IniCacheAppendSection(PINICACHE Cache,
PWCHAR Name)
{
PINICACHESECTION Section = NULL;
ULONG i;
if (Cache == NULL || Name == NULL || *Name == 0)
{
DPRINT("Invalid parameter\n");
return(NULL);
}
Section = (PINICACHESECTION)RtlAllocateHeap(ProcessHeap,
0,
sizeof(INICACHESECTION));
if (Section == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
return(NULL);
}
RtlZeroMemory(Section,
sizeof(INICACHESECTION));
/* Allocate and initialize section name */
Section->Name = RtlAllocateHeap(ProcessHeap,
0,
(wcslen(Name) + 1) * sizeof(WCHAR));
if (Section->Name == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
RtlFreeHeap(ProcessHeap,
0,
Section);
return(NULL);
}
/* Copy section name */
wcscpy(Section->Name, Name);
/* Append section */
if (Cache->FirstSection == NULL)
{
Cache->FirstSection = Section;
Cache->LastSection = Section;
}
else
{
Cache->LastSection->Next = Section;
Section->Prev = Cache->LastSection;
Cache->LastSection = Section;
}
return(Section);
}
/* EOF */

View file

@ -32,7 +32,7 @@
typedef struct _INICACHEKEY
{
PWCHAR Name;
PWCHAR Value;
PWCHAR Data;
struct _INICACHEKEY *Next;
struct _INICACHEKEY *Prev;
@ -65,6 +65,14 @@ typedef struct _PINICACHEITERATOR
} INICACHEITERATOR, *PINICACHEITERATOR;
typedef enum
{
INSERT_FIRST,
INSERT_BEFORE,
INSERT_AFTER,
INSERT_LAST
} INSERTATION_TYPE;
/* FUNCTIONS ****************************************************************/
NTSTATUS
@ -81,24 +89,43 @@ IniCacheGetSection(PINICACHE Cache,
NTSTATUS
IniCacheGetKey(PINICACHESECTION Section,
PWCHAR KeyName,
PWCHAR *KeyValue);
PWCHAR *KeyData);
PINICACHEITERATOR
IniCacheFindFirstValue(PINICACHESECTION Section,
PWCHAR *KeyName,
PWCHAR *KeyValue);
PWCHAR *KeyData);
BOOLEAN
IniCacheFindNextValue(PINICACHEITERATOR Iterator,
PWCHAR *KeyName,
PWCHAR *KeyValue);
PWCHAR *KeyData);
VOID
IniCacheFindClose(PINICACHEITERATOR Iterator);
PINICACHEKEY
IniCacheInsertKey(PINICACHESECTION Section,
PINICACHEKEY AnchorKey,
INSERTATION_TYPE InsertationType,
PWCHAR Name,
PWCHAR Data);
PINICACHE
IniCacheCreate(VOID);
NTSTATUS
IniCacheSave(PINICACHE Cache,
PWCHAR FileName);
PINICACHESECTION
IniCacheAppendSection(PINICACHE Cache,
PWCHAR Name);
#endif /* __INICACHE_H__ */
/* EOF */

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.6 2002/12/06 21:39:03 ekohl Exp $
# $Id: makefile,v 1.7 2003/01/17 13:18:15 ekohl Exp $
PATH_TO_TOP = ../../..
@ -12,8 +12,8 @@ TARGET_INSTALLDIR = system32
TARGET_CFLAGS = -D__NTAPP__
TARGET_OBJECTS = $(TARGET_NAME).o console.o drivesup.o filequeue.o filesup.o \
inicache.o partlist.o progress.o
TARGET_OBJECTS = $(TARGET_NAME).o bootsup.o console.o drivesup.o filequeue.o \
filesup.o inicache.o partlist.o progress.o
include $(PATH_TO_TOP)/rules.mak

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: partlist.c,v 1.5 2002/11/28 19:20:37 ekohl Exp $
/* $Id: partlist.c,v 1.6 2003/01/17 13:18:15 ekohl Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/partlist.c
@ -104,6 +104,7 @@ AddPartitionList(ULONG DiskNumber,
PartEntry->PartSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart;
PartEntry->PartNumber = LayoutBuffer->PartitionEntry[i].PartitionNumber,
PartEntry->PartType = LayoutBuffer->PartitionEntry[i].PartitionType;
PartEntry->Active = LayoutBuffer->PartitionEntry[i].BootIndicator;
PartEntry->DriveLetter = GetDriveLetter(DiskNumber,
LayoutBuffer->PartitionEntry[i].PartitionNumber);
@ -817,7 +818,7 @@ ScrollUpPartitionList(PPARTLIST List)
BOOL
GetPartitionData(PPARTLIST List,
GetSelectedPartition(PPARTLIST List,
PPARTDATA Data)
{
PDISKENTRY DiskEntry;
@ -873,4 +874,69 @@ GetPartitionData(PPARTLIST List,
return(TRUE);
}
BOOL
GetActiveBootPartition(PPARTLIST List,
PPARTDATA Data)
{
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
ULONG i;
if (List->CurrentDisk >= List->DiskCount)
return(FALSE);
DiskEntry = &List->DiskArray[0];
if (DiskEntry->FixedDisk == FALSE)
return(FALSE);
for (i = 0; i < DiskEntry->PartCount; i++)
{
if (DiskEntry->PartArray[i].Active)
{
PartEntry = &DiskEntry->PartArray[i];
if (PartEntry->Used == FALSE)
return(FALSE);
/* Copy disk-specific data */
Data->DiskSize = DiskEntry->DiskSize;
Data->DiskNumber = DiskEntry->DiskNumber;
Data->Port = DiskEntry->Port;
Data->Bus = DiskEntry->Bus;
Data->Id = DiskEntry->Id;
/* Copy driver name */
RtlInitUnicodeString(&Data->DriverName,
NULL);
if (DiskEntry->DriverName.Length != 0)
{
Data->DriverName.Buffer = RtlAllocateHeap(ProcessHeap,
0,
DiskEntry->DriverName.MaximumLength);
if (Data->DriverName.Buffer != NULL)
{
Data->DriverName.MaximumLength = DiskEntry->DriverName.MaximumLength;
Data->DriverName.Length = DiskEntry->DriverName.Length;
RtlCopyMemory(Data->DriverName.Buffer,
DiskEntry->DriverName.Buffer,
DiskEntry->DriverName.MaximumLength);
}
}
/* Copy partition-specific data */
Data->PartSize = PartEntry->PartSize;
Data->PartNumber = PartEntry->PartNumber;
Data->PartType = PartEntry->PartType;
Data->DriveLetter = PartEntry->DriveLetter;
return(TRUE);
}
}
return(FALSE);
}
/* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: partlist.h,v 1.5 2002/11/28 19:20:37 ekohl Exp $
/* $Id: partlist.h,v 1.6 2003/01/17 13:18:15 ekohl Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/partlist.h
@ -50,6 +50,7 @@ typedef struct _PARTENTRY
ULONGLONG PartSize;
ULONG PartNumber;
ULONG PartType;
BOOLEAN Active;
CHAR DriveLetter;
CHAR VolumeLabel[17];
@ -119,7 +120,11 @@ VOID
ScrollUpPartitionList(PPARTLIST List);
BOOL
GetPartitionData(PPARTLIST List,
GetSelectedPartition(PPARTLIST List,
PPARTDATA Data);
BOOL
GetActiveBootPartition(PPARTLIST List,
PPARTDATA Data);
#endif /* __PARTLIST_H__ */

View file

@ -36,6 +36,7 @@
#include "inicache.h"
#include "filequeue.h"
#include "progress.h"
#include "bootsup.h"
#define START_PAGE 0
@ -48,7 +49,8 @@
#define PREPARE_COPY_PAGE 7
#define INSTALL_DIRECTORY_PAGE 8
#define FILE_COPY_PAGE 9
#define INIT_SYSTEM_PAGE 10
#define REGISTRY_PAGE 10
#define BOOT_LOADER_PAGE 11
#define REPAIR_INTRO_PAGE 20
@ -72,11 +74,18 @@ HANDLE ProcessHeap;
BOOLEAN PartDataValid;
PARTDATA PartData;
WCHAR InstallDir[51];
BOOLEAN ActivePartitionValid;
PARTDATA ActivePartition;
UNICODE_STRING SourcePath;
UNICODE_STRING SourceRootPath;
UNICODE_STRING InstallPath;
UNICODE_STRING DestinationPath;
UNICODE_STRING DestinationRootPath;
UNICODE_STRING SystemRootPath; /* Path to the active partition */
PINICACHE IniCache;
HSPFILEQ SetupFileQueue = NULL;
@ -627,6 +636,7 @@ InstallIntroPage(PINPUT_RECORD Ir)
static ULONG
SelectPartitionPage(PINPUT_RECORD Ir)
{
WCHAR PathBuffer[MAX_PATH];
PPARTLIST PartList;
SHORT xScreen;
SHORT yScreen;
@ -641,6 +651,9 @@ SelectPartitionPage(PINPUT_RECORD Ir)
SetStatusText(" Please wait...");
RtlFreeUnicodeString(&DestinationPath);
RtlFreeUnicodeString(&DestinationRootPath);
GetScreenSize(&xScreen, &yScreen);
PartList = CreatePartitionList(2, 19, xScreen - 3, yScreen - 3);
@ -678,8 +691,28 @@ SelectPartitionPage(PINPUT_RECORD Ir)
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
PartDataValid = GetPartitionData(PartList, &PartData);
PartDataValid = GetSelectedPartition(PartList,
&PartData);
ActivePartitionValid = GetActiveBootPartition(PartList,
&ActivePartition);
DestroyPartitionList(PartList);
RtlFreeUnicodeString(&DestinationRootPath);
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
PartData.DiskNumber,
PartData.PartNumber);
RtlCreateUnicodeString(&DestinationRootPath,
PathBuffer);
RtlFreeUnicodeString(&SystemRootPath);
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
ActivePartition.DiskNumber,
ActivePartition.PartNumber);
RtlCreateUnicodeString(&SystemRootPath,
PathBuffer);
return(SELECT_FILE_SYSTEM_PAGE);
}
@ -846,6 +879,8 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
static ULONG
InstallDirectoryPage(PINPUT_RECORD Ir)
{
WCHAR PathBuffer[MAX_PATH];
WCHAR InstallDir[51];
ULONG Length;
SetTextXY(6, 8, "Setup installs ReactOS files onto the selected partition. Choose a");
@ -876,6 +911,21 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
/* Create 'DestinationPath' string */
RtlFreeUnicodeString(&InstallPath);
RtlCreateUnicodeString(&InstallPath,
InstallDir);
/* Create 'DestinationPath' string */
RtlFreeUnicodeString(&DestinationPath);
wcscpy(PathBuffer,
DestinationRootPath.Buffer);
if (InstallDir[0] != L'\\')
wcscat(PathBuffer,
L"\\");
wcscat(PathBuffer, InstallDir);
RtlCreateUnicodeString(&DestinationPath,
PathBuffer);
return(PREPARE_COPY_PAGE);
}
@ -1048,14 +1098,8 @@ PrepareCopyPage(PINPUT_RECORD Ir)
* Install directories like '\reactos\test' are not handled yet.
*/
/* Build full install directory name */
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
PartData.DiskNumber,
PartData.PartNumber);
if (InstallDir[0] != L'\\')
wcscat(PathBuffer, L"\\");
wcscat(PathBuffer, InstallDir);
/* Get destination path */
wcscpy(PathBuffer, DestinationPath.Buffer);
/* Remove trailing backslash */
Length = wcslen(PathBuffer);
@ -1095,10 +1139,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
{
DPRINT("Absolute Path: '%S'\n", KeyValue);
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
PartData.DiskNumber,
PartData.PartNumber);
wcscpy(PathBuffer, DestinationRootPath.Buffer);
wcscat(PathBuffer, KeyValue);
DPRINT("FullPath: '%S'\n", PathBuffer);
@ -1106,14 +1147,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
else if (KeyValue[0] != L'\\')
{
DPRINT("RelativePath: '%S'\n", KeyValue);
swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
PartData.DiskNumber,
PartData.PartNumber);
if (InstallDir[0] != L'\\')
wcscat(PathBuffer, L"\\");
wcscat(PathBuffer, InstallDir);
wcscpy(PathBuffer, DestinationPath.Buffer);
wcscat(PathBuffer, L"\\");
wcscat(PathBuffer, KeyValue);
@ -1214,7 +1248,6 @@ FileCopyCallback(PVOID Context,
static ULONG
FileCopyPage(PINPUT_RECORD Ir)
{
WCHAR TargetRootPath[MAX_PATH];
COPYCONTEXT CopyContext;
SHORT xScreen;
SHORT yScreen;
@ -1232,14 +1265,9 @@ FileCopyPage(PINPUT_RECORD Ir)
xScreen - 7,
yScreen - 10);
swprintf(TargetRootPath,
L"\\Device\\Harddisk%lu\\Partition%lu",
PartData.DiskNumber,
PartData.PartNumber);
SetupCommitFileQueue(SetupFileQueue,
TargetRootPath,
InstallDir,
DestinationRootPath.Buffer,
InstallPath.Buffer,
(PSP_FILE_CALLBACK)FileCopyCallback,
&CopyContext);
@ -1262,7 +1290,7 @@ FileCopyPage(PINPUT_RECORD Ir)
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
return(INIT_SYSTEM_PAGE);
return(REGISTRY_PAGE);
}
}
@ -1272,17 +1300,14 @@ FileCopyPage(PINPUT_RECORD Ir)
static ULONG
InitSystemPage(PINPUT_RECORD Ir)
RegistryPage(PINPUT_RECORD Ir)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
UNICODE_STRING ValueName;
HANDLE KeyHandle;
NTSTATUS Status;
WCHAR TargetPath[MAX_PATH];
UNICODE_STRING ValueName;
SetTextXY(6, 8, "Initializing system settings");
@ -1290,7 +1315,6 @@ InitSystemPage(PINPUT_RECORD Ir)
SetTextXY(6, 14, "Update registry hives");
SetTextXY(6, 16, "Install/update boot manager");
SetStatusText(" Please wait...");
@ -1314,20 +1338,12 @@ InitSystemPage(PINPUT_RECORD Ir)
RtlInitUnicodeStringFromLiteral(&ValueName,
L"InstallPath");
swprintf(TargetPath,
L"\\Device\\Harddisk%lu\\Partition%lu",
PartData.DiskNumber,
PartData.PartNumber);
if (InstallDir[0] != L'\\')
wcscat(TargetPath, L"\\");
wcscat(TargetPath, InstallDir);
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_SZ,
(PVOID)TargetPath,
wcslen(TargetPath) * sizeof(WCHAR));
(PVOID)DestinationPath.Buffer,
DestinationPath.Length);
NtClose(KeyHandle);
if (!NT_SUCCESS(Status))
{
@ -1351,6 +1367,136 @@ InitSystemPage(PINPUT_RECORD Ir)
SetStatusText(" ENTER = Continue F3 = Quit");
while(TRUE)
{
ConInKey(Ir);
if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
(Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
{
if (ConfirmQuit(Ir) == TRUE)
return(QUIT_PAGE);
break;
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
return(BOOT_LOADER_PAGE);
}
}
return(REGISTRY_PAGE);
}
static ULONG
BootLoaderPage(PINPUT_RECORD Ir)
{
WCHAR SrcPath[MAX_PATH];
WCHAR DstPath[MAX_PATH];
PINICACHE IniCache;
PINICACHESECTION IniSection;
SetTextXY(6, 8, "Installing the boot loader");
SetStatusText(" Please wait...");
if (ActivePartitionValid == FALSE)
{
SetTextXY(6, 10, "Error: no active partition found");
for(;;);
}
if (ActivePartition.PartType == PARTITION_ENTRY_UNUSED)
{
SetTextXY(6, 10, "Error: active partition invalid (unused)");
for(;;);
}
if (ActivePartition.PartType == 0x0A)
{
/* OS/2 boot manager partition */
SetTextXY(6, 12, "Found OS/2 boot manager");
}
else if (ActivePartition.PartType == 0x83)
{
/* Linux ext2 partition */
SetTextXY(6, 12, "Found Linux ext2 partition");
}
else if (ActivePartition.PartType == PARTITION_IFS)
{
/* NTFS partition */
SetTextXY(6, 12, "Found NTFS partition");
}
else if ((ActivePartition.PartType == PARTITION_FAT_12) ||
(ActivePartition.PartType == PARTITION_FAT_16) ||
(ActivePartition.PartType == PARTITION_HUGE) ||
(ActivePartition.PartType == PARTITION_XINT13) ||
(ActivePartition.PartType == PARTITION_FAT32) ||
(ActivePartition.PartType == PARTITION_FAT32_XINT13))
{
/* FAT or FAT 32 partition */
PrintTextXY(6, 10, "System path: '%wZ'", &SystemRootPath);
if (DoesFileExist(SystemRootPath.Buffer, L"ntldr") == TRUE ||
DoesFileExist(SystemRootPath.Buffer, L"boot.ini") == TRUE)
{
/* Search root directory for 'ntldr' and 'boot.ini'. */
SetTextXY(6, 12, "Found Microsoft Windows NT/2000/XP boot loader");
}
else if (DoesFileExist(SystemRootPath.Buffer, L"io.sys") == TRUE ||
DoesFileExist(SystemRootPath.Buffer, L"msdos.sys") == TRUE)
{
/* Search for root directory for 'io.sys' and 'msdos.sys'. */
SetTextXY(6, 12, "Found Microsoft DOS or Windows 9x boot loader");
/* Copy FreeLoader to the boot partition */
wcscpy(SrcPath, SourceRootPath.Buffer);
wcscat(SrcPath, L"\\loader\\freeldr.sys");
wcscpy(DstPath, SystemRootPath.Buffer);
wcscat(DstPath, L"\\freeldr.sys");
PrintTextXY(6, 14, "Copy: %S ==> %S", SrcPath, DstPath);
SetupCopyFile(SrcPath, DstPath);
/* Create freeldr.ini */
wcscpy(DstPath, SystemRootPath.Buffer);
wcscat(DstPath, L"\\freeldr.ini");
CreateFreeLoaderIniForDos(DstPath,
DestinationPath.Buffer);
/* Copy current bootsector to 'BOOTSECT.DOS' */
if ((ActivePartition.PartType == PARTITION_FAT32) ||
(ActivePartition.PartType == PARTITION_FAT32_XINT13))
{
}
else
{
}
}
else
{
SetTextXY(6, 12, "No or unknown boot loader found");
}
}
else
{
/* unknown partition */
SetTextXY(6, 12, "Unknown partition found");
}
SetStatusText(" ENTER = Continue F3 = Quit");
while(TRUE)
@ -1370,10 +1516,11 @@ InitSystemPage(PINPUT_RECORD Ir)
}
}
return(INIT_SYSTEM_PAGE);
return(BOOT_LOADER_PAGE);
}
static ULONG
QuitPage(PINPUT_RECORD Ir)
{
@ -1445,6 +1592,15 @@ NtProcessStartup(PPEB Peb)
PartDataValid = FALSE;
/* Initialize global unicode strings */
RtlInitUnicodeString(&SourcePath, NULL);
RtlInitUnicodeString(&SourceRootPath, NULL);
RtlInitUnicodeString(&InstallPath, NULL);
RtlInitUnicodeString(&DestinationPath, NULL);
RtlInitUnicodeString(&DestinationRootPath, NULL);
RtlInitUnicodeString(&SystemRootPath, NULL);
Page = START_PAGE;
while (Page != REBOOT_PAGE)
{
@ -1503,8 +1659,12 @@ NtProcessStartup(PPEB Peb)
Page = FileCopyPage(&Ir);
break;
case INIT_SYSTEM_PAGE:
Page = InitSystemPage(&Ir);
case REGISTRY_PAGE:
Page = RegistryPage(&Ir);
break;
case BOOT_LOADER_PAGE:
Page = BootLoaderPage(&Ir);
break;