2003-01-17 13:18:15 +00:00
/*
* 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 .
*
2009-10-07 19:58:15 +00:00
* 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 .
2003-01-17 13:18:15 +00:00
*/
/*
* 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
*/
2006-08-31 09:13:03 +00:00
# include "usetup.h"
2003-01-17 13:18:15 +00:00
2010-06-07 21:38:49 +00:00
# define NDEBUG
2003-12-01 18:28:54 +00:00
# include <debug.h>
2003-01-17 13:18:15 +00:00
2003-01-28 17:29:22 +00:00
# define SECTORSIZE 512
2010-09-06 01:46:06 +00:00
# include <pshpack1.h>
typedef struct _FAT_BOOTSECTOR
{
UCHAR JumpBoot [ 3 ] ; // Jump instruction to boot code
CHAR OemName [ 8 ] ; // "MSWIN4.1" for MS formatted volumes
USHORT BytesPerSector ; // Bytes per sector
UCHAR SectorsPerCluster ; // Number of sectors in a cluster
USHORT ReservedSectors ; // Reserved sectors, usually 1 (the bootsector)
UCHAR NumberOfFats ; // Number of FAT tables
USHORT RootDirEntries ; // Number of root directory entries (fat12/16)
USHORT TotalSectors ; // Number of total sectors on the drive, 16-bit
UCHAR MediaDescriptor ; // Media descriptor byte
USHORT SectorsPerFat ; // Sectors per FAT table (fat12/16)
USHORT SectorsPerTrack ; // Number of sectors in a track
USHORT NumberOfHeads ; // Number of heads on the disk
ULONG HiddenSectors ; // Hidden sectors (sectors before the partition start like the partition table)
ULONG TotalSectorsBig ; // This field is the new 32-bit total count of sectors on the volume
UCHAR DriveNumber ; // Int 0x13 drive number (e.g. 0x80)
UCHAR Reserved1 ; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
UCHAR BootSignature ; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
ULONG VolumeSerialNumber ; // Volume serial number
CHAR VolumeLabel [ 11 ] ; // Volume label. This field matches the 11-byte volume label recorded in the root directory
CHAR FileSystemType [ 8 ] ; // One of the strings "FAT12 ", "FAT16 ", or "FAT "
UCHAR BootCodeAndData [ 448 ] ; // The remainder of the boot sector
USHORT BootSectorMagic ; // 0xAA55
} FAT_BOOTSECTOR , * PFAT_BOOTSECTOR ;
typedef struct _FAT32_BOOTSECTOR
{
UCHAR JumpBoot [ 3 ] ; // Jump instruction to boot code
CHAR OemName [ 8 ] ; // "MSWIN4.1" for MS formatted volumes
USHORT BytesPerSector ; // Bytes per sector
UCHAR SectorsPerCluster ; // Number of sectors in a cluster
USHORT ReservedSectors ; // Reserved sectors, usually 1 (the bootsector)
UCHAR NumberOfFats ; // Number of FAT tables
USHORT RootDirEntries ; // Number of root directory entries (fat12/16)
USHORT TotalSectors ; // Number of total sectors on the drive, 16-bit
UCHAR MediaDescriptor ; // Media descriptor byte
USHORT SectorsPerFat ; // Sectors per FAT table (fat12/16)
USHORT SectorsPerTrack ; // Number of sectors in a track
USHORT NumberOfHeads ; // Number of heads on the disk
ULONG HiddenSectors ; // Hidden sectors (sectors before the partition start like the partition table)
ULONG TotalSectorsBig ; // This field is the new 32-bit total count of sectors on the volume
ULONG SectorsPerFatBig ; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0
USHORT ExtendedFlags ; // Extended flags (fat32)
USHORT FileSystemVersion ; // File system version (fat32)
ULONG RootDirStartCluster ; // Starting cluster of the root directory (fat32)
USHORT FsInfo ; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.
USHORT BackupBootSector ; // If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6.
UCHAR Reserved [ 12 ] ; // Reserved for future expansion
UCHAR DriveNumber ; // Int 0x13 drive number (e.g. 0x80)
UCHAR Reserved1 ; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
UCHAR BootSignature ; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
ULONG VolumeSerialNumber ; // Volume serial number
CHAR VolumeLabel [ 11 ] ; // Volume label. This field matches the 11-byte volume label recorded in the root directory
CHAR FileSystemType [ 8 ] ; // Always set to the string "FAT32 "
UCHAR BootCodeAndData [ 420 ] ; // The remainder of the boot sector
USHORT BootSectorMagic ; // 0xAA55
} FAT32_BOOTSECTOR , * PFAT32_BOOTSECTOR ;
# include <poppack.h>
extern PPARTLIST PartitionList ;
2003-01-17 13:18:15 +00:00
/* FUNCTIONS ****************************************************************/
static VOID
CreateCommonFreeLoaderSections ( PINICACHE IniCache )
{
PINICACHESECTION IniSection ;
/* Create "FREELOADER" section */
IniSection = IniCacheAppendSection ( IniCache ,
L " FREELOADER " ) ;
2009-06-17 12:44:05 +00:00
# if DBG
2006-10-30 12:41:17 +00:00
if ( IsUnattendedSetup )
{
/* DefaultOS=ReactOS */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " DefaultOS " ,
2008-09-15 06:25:31 +00:00
L " ReactOS_KdSerial " ) ;
2006-10-30 12:41:17 +00:00
}
else
# endif
{
/* DefaultOS=ReactOS */
IniCacheInsertKey ( IniSection ,
NULL ,
2003-01-17 13:18:15 +00:00
INSERT_LAST ,
L " DefaultOS " ,
L " ReactOS " ) ;
2006-10-30 12:41:17 +00:00
}
2003-01-17 13:18:15 +00:00
2009-06-17 12:44:05 +00:00
# if DBG
2006-10-30 12:41:17 +00:00
if ( IsUnattendedSetup )
# endif
{
/* Timeout=0 for unattended or non debug*/
IniCacheInsertKey ( IniSection ,
2003-01-17 13:18:15 +00:00
NULL ,
INSERT_LAST ,
L " TimeOut " ,
2006-04-25 01:31:00 +00:00
L " 0 " ) ;
2006-10-30 12:41:17 +00:00
}
2009-06-17 12:44:05 +00:00
# if DBG
2006-10-30 12:41:17 +00:00
else
{
/* Timeout=0 or 10 */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " TimeOut " ,
2006-04-25 01:31:00 +00:00
L " 10 " ) ;
2006-10-30 12:41:17 +00:00
}
2006-04-25 01:31:00 +00:00
# endif
2003-01-17 13:18:15 +00:00
/* Create "Display" section */
IniSection = IniCacheAppendSection ( IniCache ,
L " Display " ) ;
2003-01-28 17:29:22 +00:00
/* TitleText=ReactOS Boot Manager */
2003-01-17 13:18:15 +00:00
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
2003-01-28 17:29:22 +00:00
L " TitleText " ,
L " ReactOS Boot Manager " ) ;
2003-01-17 13:18:15 +00:00
/* 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 " ,
2006-10-09 04:00:34 +00:00
L " Gray " ) ;
2003-01-17 13:18:15 +00:00
/* MenuColor=Blue */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " MenuColor " ,
2006-10-09 04:00:34 +00:00
L " Black " ) ;
2003-01-17 13:18:15 +00:00
/* TextColor=Yellow */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " TextColor " ,
2006-10-09 04:00:34 +00:00
L " Gray " ) ;
2003-01-17 13:18:15 +00:00
/* SelectedTextColor=Black */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " SelectedTextColor " ,
L " Black " ) ;
/* SelectedColor=Gray */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " SelectedColor " ,
L " Gray " ) ;
2006-10-09 04:00:34 +00:00
/* SelectedColor=Gray */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " ShowTime " ,
L " No " ) ;
/* SelectedColor=Gray */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " MenuBox " ,
L " No " ) ;
/* SelectedColor=Gray */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " CenterMenu " ,
L " No " ) ;
/* SelectedColor=Gray */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " MinimalUI " ,
L " Yes " ) ;
/* SelectedColor=Gray */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " TimeText " ,
L " Seconds until highlighted choice will be started automatically: " ) ;
2003-01-17 13:18:15 +00:00
}
NTSTATUS
CreateFreeLoaderIniForDos ( PWCHAR IniPath ,
2003-01-28 17:29:22 +00:00
PWCHAR ArcPath )
2003-01-17 13:18:15 +00:00
{
PINICACHE IniCache ;
PINICACHESECTION IniSection ;
IniCache = IniCacheCreate ( ) ;
CreateCommonFreeLoaderSections ( IniCache ) ;
2003-01-28 17:29:22 +00:00
/* Create "Operating Systems" section */
2003-01-17 13:18:15 +00:00
IniSection = IniCacheAppendSection ( IniCache ,
2003-01-28 17:29:22 +00:00
L " Operating Systems " ) ;
2003-01-17 13:18:15 +00:00
/* REACTOS=ReactOS */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
2003-01-28 17:29:22 +00:00
L " ReactOS " ,
L " \" ReactOS \" " ) ;
2003-01-17 13:18:15 +00:00
2003-01-30 14:41:45 +00:00
/* ReactOS_Debug="ReactOS (Debug)" */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " ReactOS_Debug " ,
L " \" ReactOS (Debug) \" " ) ;
2003-01-17 13:18:15 +00:00
/* DOS=Dos/Windows */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " DOS " ,
2003-01-28 17:29:22 +00:00
L " \" DOS/Windows \" " ) ;
2003-01-17 13:18:15 +00:00
2003-01-28 17:29:22 +00:00
/* Create "ReactOS" section */
2003-01-17 13:18:15 +00:00
IniSection = IniCacheAppendSection ( IniCache ,
2003-01-28 17:29:22 +00:00
L " ReactOS " ) ;
2003-01-17 13:18:15 +00:00
/* BootType=ReactOS */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BootType " ,
L " ReactOS " ) ;
2003-01-30 14:41:45 +00:00
/* SystemPath=<ArcPath> */
2003-01-17 13:18:15 +00:00
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " SystemPath " ,
2003-01-28 17:29:22 +00:00
ArcPath ) ;
2003-01-17 13:18:15 +00:00
2003-01-30 14:41:45 +00:00
/* Create "ReactOS_Debug" section */
IniSection = IniCacheAppendSection ( IniCache ,
L " ReactOS_Debug " ) ;
/* BootType=ReactOS */
2003-01-17 13:18:15 +00:00
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
2003-01-30 14:41:45 +00:00
L " BootType " ,
L " ReactOS " ) ;
2003-01-17 13:18:15 +00:00
2003-01-30 14:41:45 +00:00
/* SystemPath=<ArcPath> */
2003-01-17 13:18:15 +00:00
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
2003-01-30 14:41:45 +00:00
L " SystemPath " ,
ArcPath ) ;
2003-01-17 13:18:15 +00:00
2009-10-07 19:58:15 +00:00
/* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS */
2003-01-17 13:18:15 +00:00
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
2003-01-30 14:41:45 +00:00
L " Options " ,
2007-03-05 02:29:46 +00:00
L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS " ) ;
2003-01-17 13:18:15 +00:00
/* Create "DOS" section */
IniSection = IniCacheAppendSection ( IniCache ,
L " DOS " ) ;
/* BootType=BootSector */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BootType " ,
L " BootSector " ) ;
2003-01-28 17:29:22 +00:00
/* BootDrive=hd0 */
2003-01-17 13:18:15 +00:00
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
2003-01-28 17:29:22 +00:00
L " BootDrive " ,
L " hd0 " ) ;
/* BootPartition=1 */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BootPartition " ,
L " 1 " ) ;
/* BootSector=BOOTSECT.DOS */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BootSectorFile " ,
L " BOOTSECT.DOS " ) ;
2003-01-17 13:18:15 +00:00
IniCacheSave ( IniCache , IniPath ) ;
IniCacheDestroy ( IniCache ) ;
2003-01-30 14:41:45 +00:00
return ( STATUS_SUCCESS ) ;
2003-01-17 13:18:15 +00:00
}
2003-01-28 17:29:22 +00:00
2009-10-03 19:43:29 +00:00
NTSTATUS
CreateFreeLoaderEntry (
PINICACHE IniCache ,
PINICACHESECTION OSSection ,
PWCHAR Section ,
PWCHAR Description ,
PWCHAR BootType ,
PWCHAR ArcPath ,
PWCHAR Options )
{
PINICACHESECTION IniSection ;
/* Insert entry into "Operating Systems" section */
IniCacheInsertKey ( OSSection ,
NULL ,
INSERT_LAST ,
Section ,
Description ) ;
/* Create new section */
IniSection = IniCacheAppendSection ( IniCache , Section ) ;
/* BootType= */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BootType " ,
BootType ) ;
/* SystemPath= */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " SystemPath " ,
ArcPath ) ;
/* Options=*/
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " Options " ,
Options ) ;
return STATUS_SUCCESS ;
}
2003-01-28 17:29:22 +00:00
NTSTATUS
CreateFreeLoaderIniForReactos ( PWCHAR IniPath ,
PWCHAR ArcPath )
{
PINICACHE IniCache ;
PINICACHESECTION IniSection ;
IniCache = IniCacheCreate ( ) ;
CreateCommonFreeLoaderSections ( IniCache ) ;
/* Create "Operating Systems" section */
IniSection = IniCacheAppendSection ( IniCache ,
L " Operating Systems " ) ;
2009-10-03 19:43:29 +00:00
/* ReactOS */
CreateFreeLoaderEntry ( IniCache , IniSection ,
L " ReactOS " , L " \" ReactOS \" " ,
2009-10-03 20:09:57 +00:00
L " Windows2003 " , ArcPath ,
2009-10-03 19:43:29 +00:00
L " " ) ;
2003-01-28 17:29:22 +00:00
2009-10-03 19:43:29 +00:00
/* ReactOS_Debug */
CreateFreeLoaderEntry ( IniCache , IniSection ,
L " ReactOS_Debug " , L " \" ReactOS (Debug) \" " ,
2009-10-03 20:09:57 +00:00
L " Windows2003 " , ArcPath ,
2009-10-03 19:43:29 +00:00
L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS " ) ;
2003-01-28 17:29:22 +00:00
2009-06-17 12:44:05 +00:00
# if DBG
2009-10-03 19:43:29 +00:00
/* ReactOS_KdSerial */
CreateFreeLoaderEntry ( IniCache , IniSection ,
L " ReactOS_KdSerial " , L " \" ReactOS (RosDbg) \" " ,
2010-04-10 19:24:21 +00:00
L " Windows2003 " , ArcPath ,
2009-10-03 19:43:29 +00:00
L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL " ) ;
2009-10-07 19:58:15 +00:00
/* ReactOS_LogFile */
CreateFreeLoaderEntry ( IniCache , IniSection ,
L " ReactOS_LogFile " , L " \" ReactOS (Log file) \" " ,
L " Windows2003 " , ArcPath ,
L " /DEBUG /DEBUGPORT=FILE /SOS " ) ;
2009-10-03 19:43:29 +00:00
/* ReactOS_Ram */
CreateFreeLoaderEntry ( IniCache , IniSection ,
L " ReactOS_Ram " , L " \" ReactOS (RAM Disk) \" " ,
L " ReactOS " , L " ramdisk(0) \\ ReactOS " ,
L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256 " ) ;
2008-06-01 19:15:15 +00:00
# endif
2008-02-27 20:13:34 +00:00
2009-10-03 20:09:57 +00:00
/* ReactOS_old */
CreateFreeLoaderEntry ( IniCache , IniSection ,
L " ReactOS_old " , L " \" ReactOS (old boot method) \" " ,
L " ReactOS " , ArcPath ,
L " " ) ;
/* ReactOS_Debug_old */
CreateFreeLoaderEntry ( IniCache , IniSection ,
L " ReactOS_Debug_old " , L " \" ReactOS (Debug, old boot method) \" " ,
L " ReactOS " , ArcPath ,
L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS " ) ;
2003-01-30 14:41:45 +00:00
/* Save the ini file */
IniCacheSave ( IniCache , IniPath ) ;
IniCacheDestroy ( IniCache ) ;
2003-01-28 17:29:22 +00:00
2003-01-30 14:41:45 +00:00
return ( STATUS_SUCCESS ) ;
}
NTSTATUS
UpdateFreeLoaderIni ( PWCHAR IniPath ,
PWCHAR ArcPath )
{
UNICODE_STRING Name ;
PINICACHE IniCache ;
PINICACHESECTION IniSection ;
2004-03-10 16:57:36 +00:00
PINICACHESECTION OsIniSection ;
2003-01-30 14:41:45 +00:00
WCHAR SectionName [ 80 ] ;
WCHAR OsName [ 80 ] ;
2004-03-10 16:57:36 +00:00
WCHAR SystemPath [ 200 ] ;
WCHAR SectionName2 [ 200 ] ;
2003-01-30 14:41:45 +00:00
PWCHAR KeyData ;
2004-03-10 16:57:36 +00:00
ULONG i , j ;
2003-01-30 14:41:45 +00:00
NTSTATUS Status ;
RtlInitUnicodeString ( & Name ,
IniPath ) ;
Status = IniCacheLoad ( & IniCache ,
2003-01-30 17:37:13 +00:00
& Name ,
FALSE ) ;
2003-01-30 14:41:45 +00:00
if ( ! NT_SUCCESS ( Status ) )
return ( Status ) ;
/* Get "Operating Systems" section */
IniSection = IniCacheGetSection ( IniCache ,
L " Operating Systems " ) ;
if ( IniSection = = NULL )
2004-03-10 16:57:36 +00:00
{
IniCacheDestroy ( IniCache ) ;
2003-01-30 14:41:45 +00:00
return ( STATUS_UNSUCCESSFUL ) ;
2004-03-10 16:57:36 +00:00
}
2003-01-30 14:41:45 +00:00
2004-03-10 16:57:36 +00:00
/* Find an existing usable or an unused section name */
2003-01-30 14:41:45 +00:00
i = 1 ;
wcscpy ( SectionName , L " ReactOS " ) ;
wcscpy ( OsName , L " \" ReactOS \" " ) ;
while ( TRUE )
{
Status = IniCacheGetKey ( IniSection ,
SectionName ,
& KeyData ) ;
if ( ! NT_SUCCESS ( Status ) )
break ;
2004-03-10 16:57:36 +00:00
/* Get operation system section */
if ( KeyData [ 0 ] = = ' " ' )
{
wcscpy ( SectionName2 , & KeyData [ 1 ] ) ;
j = wcslen ( SectionName2 ) ;
if ( j > 0 )
{
SectionName2 [ j - 1 ] = 0 ;
}
}
else
{
wcscpy ( SectionName2 , KeyData ) ;
}
OsIniSection = IniCacheGetSection ( IniCache ,
SectionName2 ) ;
if ( OsIniSection ! = NULL )
{
BOOLEAN UseExistingEntry = TRUE ;
/* Check BootType */
Status = IniCacheGetKey ( OsIniSection ,
L " BootType " ,
& KeyData ) ;
if ( NT_SUCCESS ( Status ) )
{
if ( KeyData = = NULL
| | ( _wcsicmp ( KeyData , L " ReactOS " ) ! = 0
& & _wcsicmp ( KeyData , L " \" ReactOS \" " ) ! = 0 ) )
{
/* This is not a ReactOS entry */
UseExistingEntry = FALSE ;
}
}
else
{
UseExistingEntry = FALSE ;
}
if ( UseExistingEntry )
{
/* BootType is ReactOS. Now check SystemPath */
Status = IniCacheGetKey ( OsIniSection ,
L " SystemPath " ,
& KeyData ) ;
if ( NT_SUCCESS ( Status ) )
{
swprintf ( SystemPath , L " \" %S \" " , ArcPath ) ;
if ( KeyData = = NULL
| | ( _wcsicmp ( KeyData , ArcPath ) ! = 0
& & _wcsicmp ( KeyData , SystemPath ) ! = 0 ) )
{
/* This entry is a ReactOS entry, but the SystemRoot does not
match the one we are looking for */
UseExistingEntry = FALSE ;
}
}
else
{
UseExistingEntry = FALSE ;
}
}
if ( UseExistingEntry )
{
IniCacheDestroy ( IniCache ) ;
return ( STATUS_SUCCESS ) ;
}
}
2003-01-30 14:41:45 +00:00
swprintf ( SectionName , L " ReactOS_%lu " , i ) ;
swprintf ( OsName , L " \" ReactOS %lu \" " , i ) ;
i + + ;
}
/* <SectionName>=<OsName> */
2003-01-28 17:29:22 +00:00
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
2003-01-30 14:41:45 +00:00
SectionName ,
OsName ) ;
2003-01-28 17:29:22 +00:00
2003-01-30 14:41:45 +00:00
/* Create <SectionName> section */
IniSection = IniCacheAppendSection ( IniCache ,
SectionName ) ;
/* BootType=ReactOS */
2003-01-28 17:29:22 +00:00
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
2003-01-30 14:41:45 +00:00
L " BootType " ,
L " ReactOS " ) ;
/* SystemPath=<ArcPath> */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " SystemPath " ,
ArcPath ) ;
2003-01-28 17:29:22 +00:00
IniCacheSave ( IniCache , IniPath ) ;
IniCacheDestroy ( IniCache ) ;
2003-01-30 14:41:45 +00:00
return ( STATUS_SUCCESS ) ;
2003-01-28 17:29:22 +00:00
}
NTSTATUS
SaveCurrentBootSector ( PWSTR RootPath ,
PWSTR DstPath )
{
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
PUCHAR BootSector ;
/* Allocate buffer for bootsector */
BootSector = ( PUCHAR ) RtlAllocateHeap ( ProcessHeap ,
0 ,
SECTORSIZE ) ;
if ( BootSector = = NULL )
return ( STATUS_INSUFFICIENT_RESOURCES ) ;
/* Read current boot sector into buffer */
RtlInitUnicodeString ( & Name ,
RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_READ ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , BootSector ) ;
return ( Status ) ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
BootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , BootSector ) ;
return ( Status ) ;
}
/* Write bootsector to DstPath */
RtlInitUnicodeString ( & Name ,
DstPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
Status = NtCreateFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_WRITE ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
NULL ,
FILE_ATTRIBUTE_NORMAL ,
0 ,
FILE_SUPERSEDE ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ,
2003-01-28 17:29:22 +00:00
NULL ,
0 ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , BootSector ) ;
return ( Status ) ;
}
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
BootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , BootSector ) ;
return ( Status ) ;
}
NTSTATUS
InstallFat16BootCodeToFile ( PWSTR SrcPath ,
PWSTR DstPath ,
PWSTR RootPath )
{
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
PUCHAR OrigBootSector ;
PUCHAR NewBootSector ;
/* Allocate buffer for original bootsector */
OrigBootSector = ( PUCHAR ) RtlAllocateHeap ( ProcessHeap ,
0 ,
SECTORSIZE ) ;
if ( OrigBootSector = = NULL )
return ( STATUS_INSUFFICIENT_RESOURCES ) ;
/* Read current boot sector into buffer */
RtlInitUnicodeString ( & Name ,
RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_READ ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( Status ) ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( Status ) ;
}
/* Allocate buffer for new bootsector */
NewBootSector = ( PUCHAR ) RtlAllocateHeap ( ProcessHeap ,
0 ,
SECTORSIZE ) ;
if ( NewBootSector = = NULL )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( STATUS_INSUFFICIENT_RESOURCES ) ;
}
/* Read new bootsector from SrcPath */
RtlInitUnicodeString ( & Name ,
SrcPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_READ ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
/* Adjust bootsector (copy a part of the FAT BPB) */
memcpy ( ( NewBootSector + 11 ) , ( OrigBootSector + 11 ) , 51 /*fat BPB length*/ ) ;
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
/* Write new bootsector to DstPath */
RtlInitUnicodeString ( & Name ,
DstPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
Status = NtCreateFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_WRITE ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
NULL ,
FILE_ATTRIBUTE_NORMAL ,
0 ,
FILE_OVERWRITE_IF ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ,
2003-01-28 17:29:22 +00:00
NULL ,
0 ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
#if 0
FilePosition . QuadPart = 0 ;
# endif
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
NTSTATUS
InstallFat32BootCodeToFile ( PWSTR SrcPath ,
PWSTR DstPath ,
PWSTR RootPath )
{
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
PUCHAR OrigBootSector ;
PUCHAR NewBootSector ;
LARGE_INTEGER FileOffset ;
/* Allocate buffer for original bootsector */
OrigBootSector = ( PUCHAR ) RtlAllocateHeap ( ProcessHeap ,
0 ,
SECTORSIZE ) ;
if ( OrigBootSector = = NULL )
return ( STATUS_INSUFFICIENT_RESOURCES ) ;
/* Read current boot sector into buffer */
RtlInitUnicodeString ( & Name ,
RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_READ ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( Status ) ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( Status ) ;
}
/* Allocate buffer for new bootsector (2 sectors) */
NewBootSector = ( PUCHAR ) RtlAllocateHeap ( ProcessHeap ,
0 ,
2 * SECTORSIZE ) ;
if ( NewBootSector = = NULL )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( STATUS_INSUFFICIENT_RESOURCES ) ;
}
/* Read new bootsector from SrcPath */
RtlInitUnicodeString ( & Name ,
SrcPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_READ ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
2 * SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
/* Adjust bootsector (copy a part of the FAT32 BPB) */
memcpy ( ( NewBootSector + 3 ) ,
( OrigBootSector + 3 ) ,
87 ) ; /* FAT32 BPB length */
/* Disable the backup boot sector */
2003-04-28 19:44:13 +00:00
NewBootSector [ 0x32 ] = 0x00 ;
NewBootSector [ 0x33 ] = 0x00 ;
2003-01-28 17:29:22 +00:00
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
/* Write the first sector of the new bootcode to DstPath */
RtlInitUnicodeString ( & Name ,
DstPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
Status = NtCreateFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_WRITE ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
NULL ,
FILE_ATTRIBUTE_NORMAL ,
0 ,
FILE_SUPERSEDE ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ,
2003-01-28 17:29:22 +00:00
NULL ,
0 ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
/* Write the second sector of the new bootcode to boot disk sector 14 */
RtlInitUnicodeString ( & Name ,
RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_WRITE ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
FileOffset . QuadPart = ( ULONGLONG ) ( 14 * SECTORSIZE ) ;
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
( NewBootSector + SECTORSIZE ) ,
SECTORSIZE ,
& FileOffset ,
NULL ) ;
if ( ! NT_SUCCESS ( Status ) )
{
}
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
2003-04-05 15:36:34 +00:00
NTSTATUS
2003-08-19 15:54:47 +00:00
InstallMbrBootCodeToDisk ( PWSTR SrcPath ,
PWSTR RootPath )
2003-04-05 15:36:34 +00:00
{
2010-09-06 01:46:06 +00:00
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
2005-09-17 22:00:35 +00:00
PPARTITION_SECTOR OrigBootSector ;
PPARTITION_SECTOR NewBootSector ;
2003-04-05 15:36:34 +00:00
2010-09-06 01:46:06 +00:00
/* Allocate buffer for original bootsector */
2005-09-17 22:00:35 +00:00
OrigBootSector = ( PPARTITION_SECTOR ) RtlAllocateHeap ( ProcessHeap ,
0 ,
sizeof ( PARTITION_SECTOR ) ) ;
2003-04-05 15:36:34 +00:00
if ( OrigBootSector = = NULL )
return ( STATUS_INSUFFICIENT_RESOURCES ) ;
2010-09-06 01:46:06 +00:00
/* Read current boot sector into buffer */
2003-04-05 15:36:34 +00:00
RtlInitUnicodeString ( & Name ,
RootPath ) ;
2010-09-06 01:46:06 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
GENERIC_READ ,
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-04-05 15:36:34 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( Status ) ;
}
2010-09-06 01:46:06 +00:00
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
2003-04-05 15:36:34 +00:00
OrigBootSector ,
2010-09-06 01:46:06 +00:00
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
2003-04-05 15:36:34 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( Status ) ;
}
/* Allocate buffer for new bootsector */
2005-09-17 22:00:35 +00:00
NewBootSector = ( PPARTITION_SECTOR ) RtlAllocateHeap ( ProcessHeap ,
0 ,
sizeof ( PARTITION_SECTOR ) ) ;
2003-04-05 15:36:34 +00:00
if ( NewBootSector = = NULL )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( STATUS_INSUFFICIENT_RESOURCES ) ;
}
/* Read new bootsector from SrcPath */
RtlInitUnicodeString ( & Name ,
SrcPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_READ ,
2003-04-05 15:36:34 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-04-05 15:36:34 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
2005-09-17 22:00:35 +00:00
sizeof ( PARTITION_SECTOR ) ,
2003-04-05 15:36:34 +00:00
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
/* Copy partition table from old MBR to new */
2005-09-17 22:00:35 +00:00
RtlCopyMemory ( & NewBootSector - > Signature ,
& OrigBootSector - > Signature ,
sizeof ( PARTITION_SECTOR ) - offsetof ( PARTITION_SECTOR , Signature ) /* Length of partition table */ ) ;
2003-04-05 15:36:34 +00:00
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
/* Write new bootsector to RootPath */
RtlInitUnicodeString ( & Name ,
RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
2005-05-01 22:20:13 +00:00
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_WRITE ,
2005-05-01 22:20:13 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ) ;
2003-04-05 15:36:34 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2005-05-01 22:20:13 +00:00
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
2003-04-05 15:36:34 +00:00
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
2003-01-28 17:29:22 +00:00
NTSTATUS
InstallFat16BootCodeToDisk ( PWSTR SrcPath ,
PWSTR RootPath )
{
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
2010-09-06 01:46:06 +00:00
PFAT_BOOTSECTOR OrigBootSector ;
PFAT_BOOTSECTOR NewBootSector ;
PARTITION_INFORMATION * PartInfo ;
2003-01-28 17:29:22 +00:00
/* Allocate buffer for original bootsector */
2010-09-06 01:46:06 +00:00
OrigBootSector = RtlAllocateHeap ( ProcessHeap ,
2003-01-28 17:29:22 +00:00
0 ,
SECTORSIZE ) ;
if ( OrigBootSector = = NULL )
return ( STATUS_INSUFFICIENT_RESOURCES ) ;
/* Read current boot sector into buffer */
RtlInitUnicodeString ( & Name ,
RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_READ ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( Status ) ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( Status ) ;
}
/* Allocate buffer for new bootsector */
2010-09-06 01:46:06 +00:00
NewBootSector = RtlAllocateHeap ( ProcessHeap ,
2003-01-28 17:29:22 +00:00
0 ,
SECTORSIZE ) ;
if ( NewBootSector = = NULL )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( STATUS_INSUFFICIENT_RESOURCES ) ;
}
/* Read new bootsector from SrcPath */
RtlInitUnicodeString ( & Name ,
SrcPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-03 23:18:21 +00:00
GENERIC_READ ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
2003-08-21 15:35:32 +00:00
/* Adjust bootsector (copy a part of the FAT16 BPB) */
2010-09-06 01:46:06 +00:00
memcpy ( & NewBootSector - > BytesPerSector ,
& OrigBootSector - > BytesPerSector ,
51 ) ; /* FAT16 BPB length */
PartInfo = & PartitionList - > CurrentPartition - > PartInfo [ PartitionList - > CurrentPartitionNumber ] ;
NewBootSector - > HiddenSectors = PartInfo - > HiddenSectors ;
2003-01-28 17:29:22 +00:00
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
/* Write new bootsector to RootPath */
RtlInitUnicodeString ( & Name ,
RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
2005-05-01 22:20:13 +00:00
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_WRITE ,
2005-05-01 22:20:13 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2005-05-01 22:20:13 +00:00
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
2003-01-28 17:29:22 +00:00
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
#if 0
FilePosition . QuadPart = 0 ;
# endif
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
NTSTATUS
InstallFat32BootCodeToDisk ( PWSTR SrcPath ,
PWSTR RootPath )
{
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
2010-09-06 01:46:06 +00:00
PFAT32_BOOTSECTOR OrigBootSector ;
PFAT32_BOOTSECTOR NewBootSector ;
2003-01-28 17:29:22 +00:00
LARGE_INTEGER FileOffset ;
USHORT BackupBootSector ;
2010-09-06 01:46:06 +00:00
PARTITION_INFORMATION * PartInfo ;
2003-01-28 17:29:22 +00:00
/* Allocate buffer for original bootsector */
2010-09-06 01:46:06 +00:00
OrigBootSector = RtlAllocateHeap ( ProcessHeap ,
2003-01-28 17:29:22 +00:00
0 ,
SECTORSIZE ) ;
if ( OrigBootSector = = NULL )
return ( STATUS_INSUFFICIENT_RESOURCES ) ;
/* Read current boot sector into buffer */
RtlInitUnicodeString ( & Name ,
RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_READ ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( Status ) ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( Status ) ;
}
/* Allocate buffer for new bootsector (2 sectors) */
2010-09-06 01:46:06 +00:00
NewBootSector = RtlAllocateHeap ( ProcessHeap ,
2003-01-28 17:29:22 +00:00
0 ,
2 * SECTORSIZE ) ;
if ( NewBootSector = = NULL )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return ( STATUS_INSUFFICIENT_RESOURCES ) ;
}
/* Read new bootsector from SrcPath */
RtlInitUnicodeString ( & Name ,
SrcPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_READ ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
2 * SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
/* Adjust bootsector (copy a part of the FAT32 BPB) */
2010-09-06 01:46:06 +00:00
memcpy ( & NewBootSector - > BytesPerSector ,
& OrigBootSector - > BytesPerSector ,
79 ) ; /* FAT32 BPB length */
PartInfo = & PartitionList - > CurrentPartition - > PartInfo [ PartitionList - > CurrentPartitionNumber ] ;
NewBootSector - > HiddenSectors = PartInfo - > HiddenSectors ;
2003-01-28 17:29:22 +00:00
/* Get the location of the backup boot sector */
2010-09-06 01:46:06 +00:00
BackupBootSector = OrigBootSector - > BackupBootSector ;
2003-01-28 17:29:22 +00:00
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
/* Write the first sector of the new bootcode to DstPath */
RtlInitUnicodeString ( & Name ,
RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_WRITE ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
/* Write sector 0 */
FileOffset . QuadPart = 0ULL ;
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
& FileOffset ,
NULL ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtWriteFile() failed (Status %lx) \n " , Status ) ;
NtClose ( FileHandle ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
/* Write backup boot sector */
2003-04-28 19:44:13 +00:00
if ( ( BackupBootSector ! = 0x0000 ) & & ( BackupBootSector ! = 0xFFFF ) )
2003-01-28 17:29:22 +00:00
{
FileOffset . QuadPart = ( ULONGLONG ) ( ( ULONG ) BackupBootSector * SECTORSIZE ) ;
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
& FileOffset ,
NULL ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtWriteFile() failed (Status %lx) \n " , Status ) ;
NtClose ( FileHandle ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
}
/* Write sector 14 */
FileOffset . QuadPart = ( ULONGLONG ) ( 14 * SECTORSIZE ) ;
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
2010-09-06 01:46:06 +00:00
( ( PUCHAR ) NewBootSector + SECTORSIZE ) ,
2003-01-28 17:29:22 +00:00
SECTORSIZE ,
& FileOffset ,
NULL ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtWriteFile() failed (Status %lx) \n " , Status ) ;
}
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return ( Status ) ;
}
static NTSTATUS
UnprotectBootIni ( PWSTR FileName ,
PULONG Attributes )
{
UNICODE_STRING Name ;
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
FILE_BASIC_INFORMATION FileInfo ;
HANDLE FileHandle ;
NTSTATUS Status ;
RtlInitUnicodeString ( & Name ,
FileName ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_READ | GENERIC_WRITE ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-01-28 17:29:22 +00:00
if ( Status = = STATUS_NO_SUCH_FILE )
{
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
* Attributes = 0 ;
return ( STATUS_SUCCESS ) ;
}
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
return ( Status ) ;
}
Status = NtQueryInformationFile ( FileHandle ,
& IoStatusBlock ,
& FileInfo ,
sizeof ( FILE_BASIC_INFORMATION ) ,
FileBasicInformation ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtQueryInformationFile() failed (Status %lx) \n " , Status ) ;
NtClose ( FileHandle ) ;
return ( Status ) ;
}
* Attributes = FileInfo . FileAttributes ;
/* Delete attributes SYSTEM, HIDDEN and READONLY */
FileInfo . FileAttributes = FileInfo . FileAttributes &
~ ( FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY ) ;
Status = NtSetInformationFile ( FileHandle ,
& IoStatusBlock ,
& FileInfo ,
sizeof ( FILE_BASIC_INFORMATION ) ,
FileBasicInformation ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtSetInformationFile() failed (Status %lx) \n " , Status ) ;
}
NtClose ( FileHandle ) ;
return ( Status ) ;
}
static NTSTATUS
ProtectBootIni ( PWSTR FileName ,
ULONG Attributes )
{
UNICODE_STRING Name ;
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
FILE_BASIC_INFORMATION FileInfo ;
HANDLE FileHandle ;
NTSTATUS Status ;
RtlInitUnicodeString ( & Name ,
FileName ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2005-05-02 20:30:29 +00:00
GENERIC_READ | GENERIC_WRITE ,
2003-01-28 17:29:22 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2003-11-08 09:13:46 +00:00
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
return ( Status ) ;
}
Status = NtQueryInformationFile ( FileHandle ,
& IoStatusBlock ,
& FileInfo ,
sizeof ( FILE_BASIC_INFORMATION ) ,
FileBasicInformation ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtQueryInformationFile() failed (Status %lx) \n " , Status ) ;
NtClose ( FileHandle ) ;
return ( Status ) ;
}
FileInfo . FileAttributes = FileInfo . FileAttributes | Attributes ;
Status = NtSetInformationFile ( FileHandle ,
& IoStatusBlock ,
& FileInfo ,
sizeof ( FILE_BASIC_INFORMATION ) ,
FileBasicInformation ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtSetInformationFile() failed (Status %lx) \n " , Status ) ;
}
NtClose ( FileHandle ) ;
return ( Status ) ;
}
NTSTATUS
UpdateBootIni ( PWSTR BootIniPath ,
PWSTR EntryName ,
PWSTR EntryValue )
{
UNICODE_STRING Name ;
PINICACHE Cache = NULL ;
PINICACHESECTION Section = NULL ;
NTSTATUS Status ;
ULONG FileAttribute ;
2006-10-01 21:48:05 +00:00
PWCHAR OldValue = NULL ;
2003-01-28 17:29:22 +00:00
RtlInitUnicodeString ( & Name ,
BootIniPath ) ;
Status = IniCacheLoad ( & Cache ,
2003-01-30 17:37:13 +00:00
& Name ,
FALSE ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
return ( Status ) ;
}
Section = IniCacheGetSection ( Cache ,
L " operating systems " ) ;
if ( Section = = NULL )
{
IniCacheDestroy ( Cache ) ;
return ( STATUS_UNSUCCESSFUL ) ;
}
2006-10-01 21:48:05 +00:00
/* Check - maybe record already exists */
Status = IniCacheGetKey ( Section ,
EntryName ,
& OldValue ) ;
/* If either key was not found, or contains something else - add new one */
if ( ! NT_SUCCESS ( Status ) | | wcscmp ( OldValue , EntryValue ) )
{
IniCacheInsertKey ( Section ,
2003-01-28 17:29:22 +00:00
NULL ,
INSERT_LAST ,
EntryName ,
EntryValue ) ;
2006-10-01 21:48:05 +00:00
}
2003-01-28 17:29:22 +00:00
Status = UnprotectBootIni ( BootIniPath ,
& FileAttribute ) ;
if ( ! NT_SUCCESS ( Status ) )
{
IniCacheDestroy ( Cache ) ;
return ( Status ) ;
}
Status = IniCacheSave ( Cache ,
BootIniPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
IniCacheDestroy ( Cache ) ;
return ( Status ) ;
}
FileAttribute | = ( FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY ) ;
Status = ProtectBootIni ( BootIniPath ,
FileAttribute ) ;
IniCacheDestroy ( Cache ) ;
return ( Status ) ;
}
2004-06-23 14:09:55 +00:00
BOOLEAN
CheckInstallFatBootcodeToPartition ( PUNICODE_STRING SystemRootPath )
{
2006-11-10 21:00:24 +00:00
# ifdef __REACTOS__
2004-06-23 14:09:55 +00:00
if ( DoesFileExist ( SystemRootPath - > Buffer , L " ntldr " ) | |
DoesFileExist ( SystemRootPath - > Buffer , L " boot.ini " ) )
{
return TRUE ;
}
else if ( DoesFileExist ( SystemRootPath - > Buffer , L " io.sys " ) | |
DoesFileExist ( SystemRootPath - > Buffer , L " msdos.sys " ) )
{
return TRUE ;
}
2006-11-10 21:00:24 +00:00
# endif
2004-06-23 14:09:55 +00:00
return FALSE ;
}
NTSTATUS
InstallFatBootcodeToPartition ( PUNICODE_STRING SystemRootPath ,
PUNICODE_STRING SourceRootPath ,
PUNICODE_STRING DestinationArcPath ,
UCHAR PartitionType )
{
2006-11-10 21:00:24 +00:00
# ifdef __REACTOS__
2006-10-04 12:26:12 +00:00
WCHAR SrcPath [ MAX_PATH ] ;
WCHAR DstPath [ MAX_PATH ] ;
NTSTATUS Status ;
2004-06-23 14:09:55 +00:00
2006-10-04 12:26:12 +00:00
/* FAT or FAT32 partition */
2007-08-07 11:45:30 +00:00
DPRINT ( " System path: '%wZ' \n " , SystemRootPath ) ;
2004-06-23 14:09:55 +00:00
2006-10-04 12:26:12 +00:00
if ( DoesFileExist ( SystemRootPath - > Buffer , L " ntldr " ) = = TRUE | |
DoesFileExist ( SystemRootPath - > Buffer , L " boot.ini " ) = = TRUE )
2004-06-23 14:09:55 +00:00
{
2006-10-04 12:26:12 +00:00
/* Search root directory for 'ntldr' and 'boot.ini'. */
DPRINT ( " Found Microsoft Windows NT/2000/XP boot loader \n " ) ;
/* 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 " ) ;
DPRINT ( " Copy: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = SetupCopyFile ( SrcPath , DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " SetupCopyFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Create or update freeldr.ini */
if ( DoesFileExist ( SystemRootPath - > Buffer , L " freeldr.ini " ) = = FALSE )
{
/* Create new 'freeldr.ini' */
DPRINT1 ( " Create new 'freeldr.ini' \n " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.ini " ) ;
Status = CreateFreeLoaderIniForReactos ( DstPath ,
DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " CreateFreeLoaderIniForReactos() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Install new bootcode */
if ( PartitionType = = PARTITION_FAT32 | |
PartitionType = = PARTITION_FAT32_XINT13 )
{
/* Install FAT32 bootcode */
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat32.bin " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ bootsect.ros " ) ;
DPRINT1 ( " Install FAT32 bootcode: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = InstallFat32BootCodeToFile ( SrcPath ,
DstPath ,
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat32BootCodeToFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
else
{
/* Install FAT16 bootcode */
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat.bin " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ bootsect.ros " ) ;
DPRINT1 ( " Install FAT bootcode: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = InstallFat16BootCodeToFile ( SrcPath ,
DstPath ,
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat16BootCodeToFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
}
else
{
/* Update existing 'freeldr.ini' */
DPRINT1 ( " Update existing 'freeldr.ini' \n " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.ini " ) ;
Status = UpdateFreeLoaderIni ( DstPath ,
DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " UpdateFreeLoaderIni() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
/* Update 'boot.ini' */
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ boot.ini " ) ;
DPRINT1 ( " Update 'boot.ini': %S \n " , DstPath ) ;
Status = UpdateBootIni ( DstPath ,
L " C: \\ bootsect.ros " ,
L " \" ReactOS \" " ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " UpdateBootIni() failed (Status %lx) \n " , Status ) ;
return Status ;
}
2004-06-23 14:09:55 +00:00
}
2006-10-04 12:26:12 +00:00
else if ( DoesFileExist ( SystemRootPath - > Buffer , L " io.sys " ) = = TRUE | |
DoesFileExist ( SystemRootPath - > Buffer , L " msdos.sys " ) = = TRUE )
2004-06-23 14:09:55 +00:00
{
2006-10-04 12:26:12 +00:00
/* Search for root directory for 'io.sys' and 'msdos.sys'. */
DPRINT1 ( " Found Microsoft DOS or Windows 9x boot loader \n " ) ;
/* 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 " ) ;
DPRINT ( " Copy: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = SetupCopyFile ( SrcPath , DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " SetupCopyFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Create or update 'freeldr.ini' */
if ( DoesFileExist ( SystemRootPath - > Buffer , L " freeldr.ini " ) = = FALSE )
{
/* Create new 'freeldr.ini' */
DPRINT1 ( " Create new 'freeldr.ini' \n " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.ini " ) ;
Status = CreateFreeLoaderIniForDos ( DstPath ,
DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " CreateFreeLoaderIniForDos() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Save current bootsector as 'BOOTSECT.DOS' */
wcscpy ( SrcPath , SystemRootPath - > Buffer ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ bootsect.dos " ) ;
DPRINT1 ( " Save bootsector: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = SaveCurrentBootSector ( SrcPath ,
DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " SaveCurrentBootSector() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Install new bootsector */
if ( PartitionType = = PARTITION_FAT32 | |
PartitionType = = PARTITION_FAT32_XINT13 )
{
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat32.bin " ) ;
DPRINT1 ( " Install FAT32 bootcode: %S ==> %S \n " , SrcPath , SystemRootPath - > Buffer ) ;
Status = InstallFat32BootCodeToDisk ( SrcPath ,
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat32BootCodeToDisk() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
else
{
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat.bin " ) ;
DPRINT1 ( " Install FAT bootcode: %S ==> %S \n " , SrcPath , SystemRootPath - > Buffer ) ;
Status = InstallFat16BootCodeToDisk ( SrcPath ,
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat16BootCodeToDisk() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
}
else
{
/* Update existing 'freeldr.ini' */
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.ini " ) ;
Status = UpdateFreeLoaderIni ( DstPath ,
DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " UpdateFreeLoaderIni() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
2004-06-23 14:09:55 +00:00
}
else
{
2006-10-04 12:26:12 +00:00
/* No or unknown boot loader */
DPRINT1 ( " No or unknown boot loader found \n " ) ;
/* 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 " ) ;
2007-08-07 11:45:30 +00:00
DPRINT ( " Copy: %S ==> %S \n " , SrcPath , DstPath ) ;
2006-10-04 12:26:12 +00:00
Status = SetupCopyFile ( SrcPath , DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " SetupCopyFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Create or update 'freeldr.ini' */
if ( DoesFileExist ( SystemRootPath - > Buffer , L " freeldr.ini " ) = = FALSE )
{
/* Create new freeldr.ini */
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.ini " ) ;
2007-08-07 11:45:30 +00:00
DPRINT ( " Copy: %S ==> %S \n " , SrcPath , DstPath ) ;
2006-10-04 12:26:12 +00:00
Status = CreateFreeLoaderIniForReactos ( DstPath ,
DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " CreateFreeLoaderIniForReactos() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Save current bootsector as 'BOOTSECT.OLD' */
wcscpy ( SrcPath , SystemRootPath - > Buffer ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ bootsect.old " ) ;
2007-08-07 11:45:30 +00:00
DPRINT ( " Save bootsector: %S ==> %S \n " , SrcPath , DstPath ) ;
2006-10-04 12:26:12 +00:00
Status = SaveCurrentBootSector ( SrcPath ,
DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " SaveCurrentBootSector() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Install new bootsector */
if ( PartitionType = = PARTITION_FAT32 | |
PartitionType = = PARTITION_FAT32_XINT13 )
{
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat32.bin " ) ;
DPRINT ( " Install FAT32 bootcode: %S ==> %S \n " , SrcPath , SystemRootPath - > Buffer ) ;
Status = InstallFat32BootCodeToDisk ( SrcPath ,
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat32BootCodeToDisk() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
else
{
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat.bin " ) ;
DPRINT ( " Install FAT bootcode: %S ==> %S \n " , SrcPath , SystemRootPath - > Buffer ) ;
Status = InstallFat16BootCodeToDisk ( SrcPath ,
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat16BootCodeToDisk() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
}
else
{
/* Update existing 'freeldr.ini' */
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.ini " ) ;
Status = UpdateFreeLoaderIni ( DstPath ,
DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " UpdateFreeLoaderIni() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
2004-06-23 14:09:55 +00:00
}
2006-10-04 12:26:12 +00:00
return STATUS_SUCCESS ;
2006-11-10 21:00:24 +00:00
# else
return STATUS_NOT_IMPLEMENTED ;
# endif
2004-06-23 14:09:55 +00:00
}
2010-09-05 17:09:18 +00:00
NTSTATUS
InstallVBRToPartition ( PUNICODE_STRING SystemRootPath ,
PUNICODE_STRING SourceRootPath ,
PUNICODE_STRING DestinationArcPath ,
UCHAR PartitionType )
{
if ( ( PartitionType = = PARTITION_FAT_12 ) | |
( PartitionType = = PARTITION_FAT_16 ) | |
( PartitionType = = PARTITION_HUGE ) | |
( PartitionType = = PARTITION_XINT13 ) | |
( PartitionType = = PARTITION_FAT32 ) | |
( PartitionType = = PARTITION_FAT32_XINT13 ) )
{
return InstallFatBootcodeToPartition ( SystemRootPath ,
SourceRootPath ,
DestinationArcPath ,
PartitionType ) ;
}
return STATUS_UNSUCCESSFUL ;
}
2004-06-23 14:09:55 +00:00
NTSTATUS
InstallFatBootcodeToFloppy ( PUNICODE_STRING SourceRootPath ,
PUNICODE_STRING DestinationArcPath )
{
2006-11-10 21:00:24 +00:00
# ifdef __REACTOS__
2004-06-23 14:09:55 +00:00
WCHAR SrcPath [ MAX_PATH ] ;
WCHAR DstPath [ MAX_PATH ] ;
NTSTATUS Status ;
/* Copy FreeLoader to the boot partition */
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ freeldr.sys " ) ;
2005-05-01 22:20:13 +00:00
wcscpy ( DstPath , L " \\ Device \\ Floppy0 \\ freeldr.sys " ) ;
2004-06-23 14:09:55 +00:00
DPRINT ( " Copy: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = SetupCopyFile ( SrcPath , DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " SetupCopyFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Create new 'freeldr.ini' */
2005-05-01 22:20:13 +00:00
wcscpy ( DstPath , L " \\ Device \\ Floppy0 \\ freeldr.ini " ) ;
2004-06-23 14:09:55 +00:00
DPRINT ( " Create new 'freeldr.ini' \n " ) ;
Status = CreateFreeLoaderIniForReactos ( DstPath ,
DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " CreateFreeLoaderIniForReactos() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Install FAT12/16 boosector */
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat.bin " ) ;
2005-05-01 22:20:13 +00:00
wcscpy ( DstPath , L " \\ Device \\ Floppy0 " ) ;
2004-06-23 14:09:55 +00:00
DPRINT ( " Install FAT bootcode: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = InstallFat16BootCodeToDisk ( SrcPath ,
DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat16BootCodeToDisk() failed (Status %lx) \n " , Status ) ;
return Status ;
}
return STATUS_SUCCESS ;
2006-11-10 21:00:24 +00:00
# else
return STATUS_NOT_IMPLEMENTED ;
# endif
2004-06-23 14:09:55 +00:00
}
2003-01-30 17:37:13 +00:00
/* EOF */