2003-01-17 13:18:15 +00:00
/*
* COPYRIGHT : See COPYING in the top level directory
* PROJECT : ReactOS text - mode setup
2015-09-13 16:40:36 +00:00
* FILE : base / setup / usetup / bootsup . c
2003-01-17 13:18:15 +00:00
* PURPOSE : Bootloader support functions
2017-05-31 02:03:10 +00:00
* PROGRAMMERS : . . .
* Hermes Belusca - Maito ( hermes . belusca @ sfr . fr )
2003-01-17 13:18:15 +00:00
*/
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
2017-05-31 02:03:10 +00:00
/*
* BIG FIXME ! !
* = = = = = = = = = = =
*
* All that stuff * MUST * go into the fsutil . c module .
* Indeed , all that relates to filesystem formatting details and as such
* * MUST * be abstracted out from this module ( bootsup . c ) .
* However , bootsup . c can still deal with MBR code ( actually it ' ll have
* at some point to share or give it to partlist . c , because when we ' ll
* support GPT disks , things will change a bit ) .
* And , bootsup . c can still manage initializing / adding boot entries
* into NTLDR and FREELDR , and installing the latter , and saving the old
* MBR / boot sectors in files .
*/
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
{
2011-07-20 17:54:28 +00:00
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
2010-09-06 01:46:06 +00:00
} FAT_BOOTSECTOR , * PFAT_BOOTSECTOR ;
typedef struct _FAT32_BOOTSECTOR
{
2011-07-20 17:54:28 +00:00
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
2010-09-06 01:46:06 +00:00
} FAT32_BOOTSECTOR , * PFAT32_BOOTSECTOR ;
2016-02-02 01:55:05 +00:00
2018-06-13 23:30:06 +00:00
typedef struct _BTRFS_BOOTSECTOR
2016-02-02 01:55:05 +00:00
{
2018-06-13 23:30:06 +00:00
UCHAR JumpBoot [ 3 ] ;
UCHAR ChunkMapSize ;
UCHAR BootDrive ;
ULONGLONG PartitionStartLBA ;
UCHAR Fill [ 1521 ] ; // 1536 - 15
USHORT BootSectorMagic ;
} BTRFS_BOOTSECTOR , * PBTRFS_BOOTSECTOR ;
C_ASSERT ( sizeof ( BTRFS_BOOTSECTOR ) = = 3 * 512 ) ;
2016-02-02 01:55:05 +00:00
// TODO: Add more bootsector structures!
2010-09-06 01:46:06 +00:00
# include <poppack.h>
2017-05-31 02:03:10 +00:00
/* End of BIG FIXME!! */
2010-09-06 01:46:06 +00:00
2003-01-17 13:18:15 +00:00
/* FUNCTIONS ****************************************************************/
2017-05-31 02:03:10 +00:00
static VOID
TrimTrailingPathSeparators_UStr (
IN OUT PUNICODE_STRING UnicodeString )
{
while ( UnicodeString - > Length > = sizeof ( WCHAR ) & &
UnicodeString - > Buffer [ UnicodeString - > Length / sizeof ( WCHAR ) - 1 ] = = OBJ_NAME_PATH_SEPARATOR )
{
UnicodeString - > Length - = sizeof ( WCHAR ) ;
}
}
2003-01-17 13:18:15 +00:00
2017-06-08 02:43:51 +00:00
static VOID
CreateFreeLoaderReactOSEntries (
IN PVOID BootStoreHandle ,
IN PCWSTR ArcPath )
2003-01-17 13:18:15 +00:00
{
2017-06-08 17:30:23 +00:00
UCHAR xxBootEntry [ FIELD_OFFSET ( BOOT_STORE_ENTRY , OsOptions ) + sizeof ( NTOS_OPTIONS ) ] ;
PBOOT_STORE_ENTRY BootEntry = ( PBOOT_STORE_ENTRY ) & xxBootEntry ;
2017-06-08 02:43:51 +00:00
PNTOS_OPTIONS Options = ( PNTOS_OPTIONS ) & BootEntry - > OsOptions ;
2017-06-08 17:30:23 +00:00
BOOT_STORE_OPTIONS BootOptions ;
2017-06-08 02:43:51 +00:00
2017-06-08 17:30:23 +00:00
BootEntry - > Version = FreeLdr ;
2017-06-08 02:43:51 +00:00
BootEntry - > BootFilePath = NULL ;
BootEntry - > OsOptionsLength = sizeof ( NTOS_OPTIONS ) ;
RtlCopyMemory ( Options - > Signature ,
NTOS_OPTIONS_SIGNATURE ,
RTL_FIELD_SIZE ( NTOS_OPTIONS , Signature ) ) ;
Options - > OsLoadPath = ArcPath ;
/* ReactOS */
// BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS");
BootEntry - > FriendlyName = L " \" ReactOS \" " ;
Options - > OsLoadOptions = NULL ; // L"";
2017-06-08 17:30:23 +00:00
AddBootStoreEntry ( BootStoreHandle , BootEntry , MAKESTRKEY ( L " ReactOS " ) ) ;
2017-06-08 02:43:51 +00:00
/* ReactOS_Debug */
// BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Debug");
BootEntry - > FriendlyName = L " \" ReactOS (Debug) \" " ;
Options - > OsLoadOptions = L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS " ;
2017-06-08 17:30:23 +00:00
AddBootStoreEntry ( BootStoreHandle , BootEntry , MAKESTRKEY ( L " ReactOS_Debug " ) ) ;
2017-06-08 02:43:51 +00:00
# ifdef _WINKD_
/* ReactOS_VBoxDebug */
// BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_VBoxDebug");
BootEntry - > FriendlyName = L " \" ReactOS (VBoxDebug) \" " ;
Options - > OsLoadOptions = L " /DEBUG /DEBUGPORT=VBOX /SOS " ;
2017-06-08 17:30:23 +00:00
AddBootStoreEntry ( BootStoreHandle , BootEntry , MAKESTRKEY ( L " ReactOS_VBoxDebug " ) ) ;
2017-06-08 02:43:51 +00:00
# endif
# if DBG
# ifndef _WINKD_
/* ReactOS_KdSerial */
// BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial");
BootEntry - > FriendlyName = L " \" ReactOS (RosDbg) \" " ;
Options - > OsLoadOptions = L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL " ;
2017-06-08 17:30:23 +00:00
AddBootStoreEntry ( BootStoreHandle , BootEntry , MAKESTRKEY ( L " ReactOS_KdSerial " ) ) ;
2017-06-08 02:43:51 +00:00
# endif
/* ReactOS_Screen */
// BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Screen");
BootEntry - > FriendlyName = L " \" ReactOS (Screen) \" " ;
Options - > OsLoadOptions = L " /DEBUG /DEBUGPORT=SCREEN /SOS " ;
2017-06-08 17:30:23 +00:00
AddBootStoreEntry ( BootStoreHandle , BootEntry , MAKESTRKEY ( L " ReactOS_Screen " ) ) ;
2017-06-08 02:43:51 +00:00
/* ReactOS_LogFile */
// BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_LogFile");
BootEntry - > FriendlyName = L " \" ReactOS (Log file) \" " ;
Options - > OsLoadOptions = L " /DEBUG /DEBUGPORT=FILE /SOS " ;
2017-06-08 17:30:23 +00:00
AddBootStoreEntry ( BootStoreHandle , BootEntry , MAKESTRKEY ( L " ReactOS_LogFile " ) ) ;
2017-06-08 02:43:51 +00:00
/* ReactOS_Ram */
// BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Ram");
BootEntry - > FriendlyName = L " \" ReactOS (RAM Disk) \" " ;
Options - > OsLoadPath = L " ramdisk(0) \\ ReactOS " ;
Options - > OsLoadOptions = L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDPATH=reactos.img /RDIMAGEOFFSET=32256 " ;
2017-06-08 17:30:23 +00:00
AddBootStoreEntry ( BootStoreHandle , BootEntry , MAKESTRKEY ( L " ReactOS_Ram " ) ) ;
2017-06-08 02:43:51 +00:00
/* ReactOS_EMS */
// BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_EMS");
BootEntry - > FriendlyName = L " \" ReactOS (Emergency Management Services) \" " ;
Options - > OsLoadPath = ArcPath ;
Options - > OsLoadOptions = L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200 " ;
2017-06-08 17:30:23 +00:00
AddBootStoreEntry ( BootStoreHandle , BootEntry , MAKESTRKEY ( L " ReactOS_EMS " ) ) ;
2017-06-08 02:43:51 +00:00
# endif
2003-01-17 13:18:15 +00:00
2009-06-17 12:44:05 +00:00
# if DBG
2011-07-20 17:54:28 +00:00
if ( IsUnattendedSetup )
{
/* DefaultOS=ReactOS */
2011-11-19 22:50:04 +00:00
# ifndef _WINKD_
2017-06-08 02:43:51 +00:00
BootOptions . CurrentBootEntryKey = MAKESTRKEY ( L " ReactOS_KdSerial " ) ;
2011-11-19 22:50:04 +00:00
# else
2017-06-08 02:43:51 +00:00
BootOptions . CurrentBootEntryKey = MAKESTRKEY ( L " ReactOS_Debug " ) ;
2011-11-19 22:50:04 +00:00
# endif
2011-07-20 17:54:28 +00:00
}
else
2006-10-30 12:41:17 +00:00
# endif
2011-07-20 17:54:28 +00:00
{
/* DefaultOS=ReactOS */
2017-06-08 02:43:51 +00:00
BootOptions . CurrentBootEntryKey = MAKESTRKEY ( L " ReactOS " ) ;
2011-07-20 17:54:28 +00:00
}
2003-01-17 13:18:15 +00:00
2009-06-17 12:44:05 +00:00
# if DBG
2011-07-20 17:54:28 +00:00
if ( IsUnattendedSetup )
2006-10-30 12:41:17 +00:00
# endif
2011-07-20 17:54:28 +00:00
{
2017-06-08 02:43:51 +00:00
/* Timeout=0 for unattended or non debug */
BootOptions . Timeout = 0 ;
2011-07-20 17:54:28 +00:00
}
2009-06-17 12:44:05 +00:00
# if DBG
2011-07-20 17:54:28 +00:00
else
{
2017-06-08 02:43:51 +00:00
/* Timeout=10 */
BootOptions . Timeout = 10 ;
2011-07-20 17:54:28 +00:00
}
2006-04-25 01:31:00 +00:00
# endif
2003-01-17 13:18:15 +00:00
2017-06-08 17:30:23 +00:00
BootOptions . Version = FreeLdr ;
SetBootStoreOptions ( BootStoreHandle , & BootOptions , 2 | 1 ) ;
2015-12-30 18:26:42 +00:00
}
2008-02-27 20:13:34 +00:00
2017-06-08 02:43:51 +00:00
static NTSTATUS
2015-12-30 18:26:42 +00:00
CreateFreeLoaderIniForReactOS (
2017-06-08 02:43:51 +00:00
IN PCWSTR IniPath ,
IN PCWSTR ArcPath )
2015-12-30 18:26:42 +00:00
{
2017-06-08 02:43:51 +00:00
NTSTATUS Status ;
PVOID BootStoreHandle ;
2015-12-30 18:26:42 +00:00
2017-06-08 02:43:51 +00:00
/* Initialize the INI file and create the common FreeLdr sections */
2017-06-08 17:30:23 +00:00
Status = OpenBootStore ( & BootStoreHandle , IniPath , FreeLdr , TRUE ) ;
2017-06-08 02:43:51 +00:00
if ( ! NT_SUCCESS ( Status ) )
return Status ;
2015-12-30 18:26:42 +00:00
/* Add the ReactOS entries */
2017-06-08 02:43:51 +00:00
CreateFreeLoaderReactOSEntries ( BootStoreHandle , ArcPath ) ;
2015-12-30 18:26:42 +00:00
2017-06-08 02:43:51 +00:00
/* Close the INI file */
2017-06-08 17:30:23 +00:00
CloseBootStore ( BootStoreHandle ) ;
2015-12-30 18:26:42 +00:00
return STATUS_SUCCESS ;
}
2017-06-08 02:43:51 +00:00
static NTSTATUS
2016-02-02 01:55:05 +00:00
CreateFreeLoaderIniForReactOSAndBootSector (
2017-05-31 01:43:12 +00:00
IN PCWSTR IniPath ,
IN PCWSTR ArcPath ,
IN PCWSTR Section ,
IN PCWSTR Description ,
IN PCWSTR BootDrive ,
IN PCWSTR BootPartition ,
IN PCWSTR BootSector )
2003-01-30 14:41:45 +00:00
{
2016-02-02 01:55:05 +00:00
NTSTATUS Status ;
2017-06-08 02:43:51 +00:00
PVOID BootStoreHandle ;
2017-06-08 17:30:23 +00:00
UCHAR xxBootEntry [ FIELD_OFFSET ( BOOT_STORE_ENTRY , OsOptions ) + sizeof ( BOOT_SECTOR_OPTIONS ) ] ;
PBOOT_STORE_ENTRY BootEntry = ( PBOOT_STORE_ENTRY ) & xxBootEntry ;
2017-06-08 02:43:51 +00:00
PBOOT_SECTOR_OPTIONS Options = ( PBOOT_SECTOR_OPTIONS ) & BootEntry - > OsOptions ;
2011-07-20 17:54:28 +00:00
2017-06-08 02:43:51 +00:00
/* Initialize the INI file and create the common FreeLdr sections */
2017-06-08 17:30:23 +00:00
Status = OpenBootStore ( & BootStoreHandle , IniPath , FreeLdr , TRUE ) ;
2003-01-30 14:41:45 +00:00
if ( ! NT_SUCCESS ( Status ) )
2011-07-20 17:54:28 +00:00
return Status ;
2003-01-30 14:41:45 +00:00
2017-06-08 02:43:51 +00:00
/* Add the ReactOS entries */
CreateFreeLoaderReactOSEntries ( BootStoreHandle , ArcPath ) ;
2011-07-20 17:54:28 +00:00
2017-06-08 17:30:23 +00:00
BootEntry - > Version = FreeLdr ;
2017-06-08 02:43:51 +00:00
BootEntry - > BootFilePath = NULL ;
2003-01-28 17:29:22 +00:00
2017-06-08 02:43:51 +00:00
BootEntry - > OsOptionsLength = sizeof ( BOOT_SECTOR_OPTIONS ) ;
RtlCopyMemory ( Options - > Signature ,
BOOT_SECTOR_OPTIONS_SIGNATURE ,
RTL_FIELD_SIZE ( BOOT_SECTOR_OPTIONS , Signature ) ) ;
2003-01-28 17:29:22 +00:00
2017-06-08 02:43:51 +00:00
Options - > Drive = BootDrive ;
Options - > Partition = BootPartition ;
Options - > BootSectorFileName = BootSector ;
2003-01-28 17:29:22 +00:00
2017-06-08 02:43:51 +00:00
// BootEntry->BootEntryKey = MAKESTRKEY(Section);
BootEntry - > FriendlyName = Description ;
2017-06-08 17:30:23 +00:00
AddBootStoreEntry ( BootStoreHandle , BootEntry , MAKESTRKEY ( Section ) ) ;
2003-01-28 17:29:22 +00:00
2017-06-08 02:43:51 +00:00
/* Close the INI file */
2017-06-08 17:30:23 +00:00
CloseBootStore ( BootStoreHandle ) ;
2011-07-20 17:54:28 +00:00
return STATUS_SUCCESS ;
2003-01-28 17:29:22 +00:00
}
2017-06-08 02:43:51 +00:00
//
// I think this function can be generalizable as:
// "find the corresponding 'ReactOS' boot entry in this loader config file
// (here abstraction comes there), and if none, add a new one".
//
2017-05-31 01:47:39 +00:00
2017-06-08 02:43:51 +00:00
typedef struct _ENUM_REACTOS_ENTRIES_DATA
{
ULONG i ;
BOOLEAN UseExistingEntry ;
PCWSTR ArcPath ;
WCHAR SectionName [ 80 ] ;
WCHAR OsName [ 80 ] ;
} ENUM_REACTOS_ENTRIES_DATA , * PENUM_REACTOS_ENTRIES_DATA ;
// PENUM_BOOT_ENTRIES_ROUTINE
static NTSTATUS
NTAPI
EnumerateReactOSEntries (
2017-06-08 17:30:23 +00:00
IN BOOT_STORE_TYPE Type ,
IN PBOOT_STORE_ENTRY BootEntry ,
2017-06-08 02:43:51 +00:00
IN PVOID Parameter OPTIONAL )
{
PENUM_REACTOS_ENTRIES_DATA Data = ( PENUM_REACTOS_ENTRIES_DATA ) Parameter ;
PNTOS_OPTIONS Options = ( PNTOS_OPTIONS ) & BootEntry - > OsOptions ;
WCHAR SystemPath [ MAX_PATH ] ;
2017-05-31 01:47:39 +00:00
2017-06-08 02:43:51 +00:00
/* We have a boot entry */
2017-05-31 01:47:39 +00:00
2017-06-08 02:43:51 +00:00
/* Check for supported boot type "Windows2003" */
if ( BootEntry - > OsOptionsLength < sizeof ( NTOS_OPTIONS ) | |
RtlCompareMemory ( & BootEntry - > OsOptions /* Signature */ ,
NTOS_OPTIONS_SIGNATURE ,
RTL_FIELD_SIZE ( NTOS_OPTIONS , Signature ) ) ! =
RTL_FIELD_SIZE ( NTOS_OPTIONS , Signature ) )
2017-05-31 01:47:39 +00:00
{
2017-06-08 02:43:51 +00:00
/* This is not a ReactOS entry */
2017-06-08 17:30:23 +00:00
// DPRINT1(" An installation '%S' of unsupported type '%S'\n",
// BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a");
DPRINT1 ( " An installation '%S' of unsupported type %lu \n " ,
BootEntry - > FriendlyName , BootEntry - > OsOptionsLength ) ;
2017-06-08 02:43:51 +00:00
/* Continue the enumeration */
goto SkipThisEntry ;
2017-05-31 01:47:39 +00:00
}
2017-06-08 02:43:51 +00:00
/* BootType is Windows2003, now check OsLoadPath */
if ( ! Options - > OsLoadPath | | ! * Options - > OsLoadPath )
2017-05-31 01:47:39 +00:00
{
2017-06-08 02:43:51 +00:00
/* Certainly not a ReactOS installation */
DPRINT1 ( " A Win2k3 install '%S' without an ARC path?! \n " , BootEntry - > FriendlyName ) ;
/* Continue the enumeration */
goto SkipThisEntry ;
2017-05-31 01:47:39 +00:00
}
2017-06-08 02:43:51 +00:00
RtlStringCchPrintfW ( SystemPath , ARRAYSIZE ( SystemPath ) , L " \" %s \" " , Data - > ArcPath ) ;
if ( ( _wcsicmp ( Options - > OsLoadPath , Data - > ArcPath ) ! = 0 ) & &
( _wcsicmp ( Options - > OsLoadPath , SystemPath ) ! = 0 ) )
2017-05-31 01:47:39 +00:00
{
2017-06-08 02:43:51 +00:00
/*
* This entry is a ReactOS entry , but the SystemRoot
* does not match the one we are looking for .
*/
/* Continue the enumeration */
goto SkipThisEntry ;
2017-05-31 01:47:39 +00:00
}
2017-06-08 02:43:51 +00:00
DPRINT1 ( " Found a candidate Win2k3 install '%S' with ARC path '%S' \n " ,
BootEntry - > FriendlyName , Options - > OsLoadPath ) ;
// DPRINT1(" Found a Win2k3 install '%S' with ARC path '%S'\n",
// BootEntry->FriendlyName, Options->OsLoadPath);
2017-05-31 01:47:39 +00:00
2017-06-08 02:43:51 +00:00
DPRINT1 ( " EnumerateReactOSEntries: OsLoadPath: '%S' \n " , Options - > OsLoadPath ) ;
2017-05-31 01:47:39 +00:00
2017-06-08 02:43:51 +00:00
Data - > UseExistingEntry = TRUE ;
RtlStringCchCopyW ( Data - > OsName , ARRAYSIZE ( Data - > OsName ) , BootEntry - > FriendlyName ) ;
/* We have found our entry, stop the enumeration now! */
return STATUS_NO_MORE_ENTRIES ;
SkipThisEntry :
Data - > UseExistingEntry = FALSE ;
if ( Type = = FreeLdr & & wcscmp ( Data - > SectionName , ( PWSTR ) BootEntry - > BootEntryKey ) = = 0 )
2017-05-31 01:47:39 +00:00
{
2017-06-08 02:43:51 +00:00
RtlStringCchPrintfW ( Data - > SectionName , ARRAYSIZE ( Data - > SectionName ) ,
L " ReactOS_%lu " , Data - > i ) ;
RtlStringCchPrintfW ( Data - > OsName , ARRAYSIZE ( Data - > OsName ) ,
L " \" ReactOS %lu \" " , Data - > i ) ;
Data - > i + + ;
2017-05-31 01:47:39 +00:00
}
2017-06-08 02:43:51 +00:00
return STATUS_SUCCESS ;
2017-05-31 01:47:39 +00:00
}
static
NTSTATUS
2017-06-08 02:43:51 +00:00
UpdateFreeLoaderIni (
IN PCWSTR IniPath ,
IN PCWSTR ArcPath )
2017-05-31 01:47:39 +00:00
{
NTSTATUS Status ;
2017-06-08 02:43:51 +00:00
PVOID BootStoreHandle ;
ENUM_REACTOS_ENTRIES_DATA Data ;
2017-06-08 17:30:23 +00:00
UCHAR xxBootEntry [ FIELD_OFFSET ( BOOT_STORE_ENTRY , OsOptions ) + sizeof ( NTOS_OPTIONS ) ] ;
PBOOT_STORE_ENTRY BootEntry = ( PBOOT_STORE_ENTRY ) & xxBootEntry ;
2017-06-08 02:43:51 +00:00
PNTOS_OPTIONS Options = ( PNTOS_OPTIONS ) & BootEntry - > OsOptions ;
/* Open the INI file */
2017-06-08 17:30:23 +00:00
Status = OpenBootStore ( & BootStoreHandle , IniPath , FreeLdr , /*TRUE*/ FALSE ) ;
2017-06-08 02:43:51 +00:00
if ( ! NT_SUCCESS ( Status ) )
return Status ;
2017-05-31 01:47:39 +00:00
2017-06-08 02:43:51 +00:00
/* Find an existing usable or an unused section name */
Data . UseExistingEntry = TRUE ;
Data . i = 1 ;
Data . ArcPath = ArcPath ;
RtlStringCchCopyW ( Data . SectionName , ARRAYSIZE ( Data . SectionName ) , L " ReactOS " ) ;
RtlStringCchCopyW ( Data . OsName , ARRAYSIZE ( Data . OsName ) , L " \" ReactOS \" " ) ;
2017-05-31 01:47:39 +00:00
2017-06-08 02:43:51 +00:00
//
2017-06-08 17:30:23 +00:00
// FIXME: We temporarily use EnumerateBootStoreEntries, until
// both QueryBootStoreEntry and ModifyBootStoreEntry get implemented.
2017-06-08 02:43:51 +00:00
//
2017-06-08 17:30:23 +00:00
Status = EnumerateBootStoreEntries ( BootStoreHandle , EnumerateReactOSEntries , & Data ) ;
2017-05-31 01:47:39 +00:00
2017-06-08 02:43:51 +00:00
/* Create a new "ReactOS" entry if there is none already existing that suits us */
if ( ! Data . UseExistingEntry )
2017-05-31 01:47:39 +00:00
{
2017-06-08 02:43:51 +00:00
// RtlStringCchPrintfW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS_%lu", Data.i);
// RtlStringCchPrintfW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS %lu\"", Data.i);
2017-05-31 01:47:39 +00:00
2017-06-08 17:30:23 +00:00
BootEntry - > Version = FreeLdr ;
2017-06-08 02:43:51 +00:00
BootEntry - > BootFilePath = NULL ;
2017-05-31 01:47:39 +00:00
2017-06-08 02:43:51 +00:00
BootEntry - > OsOptionsLength = sizeof ( NTOS_OPTIONS ) ;
RtlCopyMemory ( Options - > Signature ,
NTOS_OPTIONS_SIGNATURE ,
RTL_FIELD_SIZE ( NTOS_OPTIONS , Signature ) ) ;
2017-05-31 01:47:39 +00:00
2017-06-08 02:43:51 +00:00
Options - > OsLoadPath = ArcPath ;
// BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName);
BootEntry - > FriendlyName = Data . OsName ;
Options - > OsLoadOptions = NULL ; // L"";
2017-06-08 17:30:23 +00:00
AddBootStoreEntry ( BootStoreHandle , BootEntry , MAKESTRKEY ( Data . SectionName ) ) ;
2017-05-31 01:47:39 +00:00
}
2017-06-08 02:43:51 +00:00
/* Close the INI file */
2017-06-08 17:30:23 +00:00
CloseBootStore ( BootStoreHandle ) ;
2017-06-08 02:43:51 +00:00
return STATUS_SUCCESS ;
2017-05-31 01:47:39 +00:00
}
static
NTSTATUS
UpdateBootIni (
2017-06-08 02:43:51 +00:00
IN PCWSTR IniPath ,
IN PCWSTR EntryName , // ~= ArcPath
IN PCWSTR EntryValue )
2017-05-31 01:47:39 +00:00
{
NTSTATUS Status ;
2017-06-08 02:43:51 +00:00
PVOID BootStoreHandle ;
ENUM_REACTOS_ENTRIES_DATA Data ;
2017-05-31 01:47:39 +00:00
2017-06-08 02:43:51 +00:00
// NOTE: Technically it would be "BootSector"...
2017-06-08 17:30:23 +00:00
UCHAR xxBootEntry [ FIELD_OFFSET ( BOOT_STORE_ENTRY , OsOptions ) + sizeof ( NTOS_OPTIONS ) ] ;
PBOOT_STORE_ENTRY BootEntry = ( PBOOT_STORE_ENTRY ) & xxBootEntry ;
2017-06-08 02:43:51 +00:00
PNTOS_OPTIONS Options = ( PNTOS_OPTIONS ) & BootEntry - > OsOptions ;
2017-05-31 01:47:39 +00:00
2017-06-08 02:43:51 +00:00
/* Open the INI file */
2017-06-08 17:30:23 +00:00
Status = OpenBootStore ( & BootStoreHandle , IniPath , NtLdr , FALSE ) ;
2017-05-31 01:47:39 +00:00
if ( ! NT_SUCCESS ( Status ) )
return Status ;
2017-06-08 02:43:51 +00:00
/* Find an existing usable or an unused section name */
Data . UseExistingEntry = TRUE ;
// Data.i = 1;
Data . ArcPath = EntryName ;
// RtlStringCchCopyW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS");
RtlStringCchCopyW ( Data . OsName , ARRAYSIZE ( Data . OsName ) , L " \" ReactOS \" " ) ;
//
2017-06-08 17:30:23 +00:00
// FIXME: We temporarily use EnumerateBootStoreEntries, until
// both QueryBootStoreEntry and ModifyBootStoreEntry get implemented.
2017-06-08 02:43:51 +00:00
//
2017-06-08 17:30:23 +00:00
Status = EnumerateBootStoreEntries ( BootStoreHandle , EnumerateReactOSEntries , & Data ) ;
2017-06-08 02:43:51 +00:00
/* If either the key was not found, or contains something else, add a new one */
if ( ! Data . UseExistingEntry /* ||
( ( Status = = STATUS_NO_MORE_ENTRIES ) & & wcscmp ( Data . OsName , EntryValue ) ) */ )
{
2017-06-08 17:30:23 +00:00
BootEntry - > Version = NtLdr ;
2017-06-08 02:43:51 +00:00
BootEntry - > BootFilePath = NULL ;
BootEntry - > OsOptionsLength = sizeof ( NTOS_OPTIONS ) ;
RtlCopyMemory ( Options - > Signature ,
NTOS_OPTIONS_SIGNATURE ,
RTL_FIELD_SIZE ( NTOS_OPTIONS , Signature ) ) ;
Options - > OsLoadPath = EntryName ;
// BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName);
// BootEntry->FriendlyName = Data.OsName;
BootEntry - > FriendlyName = EntryValue ;
Options - > OsLoadOptions = NULL ; // L"";
2017-06-08 17:30:23 +00:00
AddBootStoreEntry ( BootStoreHandle , BootEntry , MAKESTRKEY ( 0 /*Data.SectionName*/ ) ) ;
2017-06-08 02:43:51 +00:00
}
/* Close the INI file */
2017-06-08 17:30:23 +00:00
CloseBootStore ( BootStoreHandle ) ;
2017-06-08 02:43:51 +00:00
return STATUS_SUCCESS ; // Status;
2017-05-31 01:47:39 +00:00
}
2016-02-02 01:55:05 +00:00
BOOLEAN
2017-05-31 02:03:10 +00:00
IsThereAValidBootSector (
IN PCWSTR RootPath )
2016-02-02 01:55:05 +00:00
{
/*
2017-05-09 15:31:53 +00:00
* We first demand that the bootsector has a valid signature at its end .
* We then check the first 3 bytes ( as a ULONG ) of the bootsector for a
* potential " valid " instruction ( the BIOS starts execution of the bootsector
* at its beginning ) . Currently this criterium is that this ULONG must be
* non - zero . If both these tests pass , then the bootsector is valid ; otherwise
* it is invalid and certainly needs to be overwritten .
2016-02-02 01:55:05 +00:00
*/
2017-05-31 02:03:10 +00:00
2017-05-09 15:31:53 +00:00
BOOLEAN IsValid = FALSE ;
2016-02-02 01:55:05 +00:00
NTSTATUS Status ;
2017-05-31 02:03:10 +00:00
UNICODE_STRING RootPartition ;
2016-02-02 01:55:05 +00:00
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
HANDLE FileHandle ;
LARGE_INTEGER FileOffset ;
PUCHAR BootSector ;
ULONG Instruction ;
/* Allocate buffer for bootsector */
BootSector = RtlAllocateHeap ( ProcessHeap , 0 , SECTORSIZE ) ;
if ( BootSector = = NULL )
return FALSE ; // STATUS_INSUFFICIENT_RESOURCES;
2017-05-31 02:03:10 +00:00
RtlZeroMemory ( BootSector , SECTORSIZE ) ;
2016-02-02 01:55:05 +00:00
2017-05-31 02:03:10 +00:00
/* Open the root partition - Remove any trailing backslash if needed */
RtlInitUnicodeString ( & RootPartition , RootPath ) ;
TrimTrailingPathSeparators_UStr ( & RootPartition ) ;
2016-02-02 01:55:05 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
2017-05-31 02:03:10 +00:00
& RootPartition ,
2016-02-02 01:55:05 +00:00
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
GENERIC_READ | SYNCHRONIZE ,
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
2017-05-09 15:31:53 +00:00
goto Quit ;
2017-05-31 02:03:10 +00:00
/* Read current boot sector into buffer */
2016-02-02 01:55:05 +00:00
FileOffset . QuadPart = 0ULL ;
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
BootSector ,
SECTORSIZE ,
& FileOffset ,
NULL ) ;
NtClose ( FileHandle ) ;
2017-05-09 15:31:53 +00:00
if ( ! NT_SUCCESS ( Status ) )
goto Quit ;
2016-02-02 01:55:05 +00:00
2017-05-09 15:31:53 +00:00
/* Check the instruction; we use a ULONG to read three bytes */
Instruction = ( * ( PULONG ) BootSector ) & 0x00FFFFFF ;
IsValid = ( Instruction ! = 0x00000000 ) ;
2016-02-02 01:55:05 +00:00
2017-05-09 15:31:53 +00:00
/* Check the bootsector signature */
IsValid & = ( * ( PUSHORT ) ( BootSector + 0x1fe ) = = 0xaa55 ) ;
Quit :
2016-02-02 01:55:05 +00:00
/* Free the boot sector */
RtlFreeHeap ( ProcessHeap , 0 , BootSector ) ;
2017-05-09 15:31:53 +00:00
return IsValid ; // Status;
2016-02-02 01:55:05 +00:00
}
2003-01-28 17:29:22 +00:00
2003-04-05 15:36:34 +00:00
NTSTATUS
[USETUP]
- bootsup.c/.h, usetup.c: Save the old MBR sector in the system partition (this makes easier to restore the old one).
- fslist.c/.h, usetup.h: Fix header inclusion order.
- partlist.c/.h, usetup.c: On BIOS-PC architectures, the system partition can be formatted in any FS as long as it is the active partition (on the contrary, on architectures where such system partition is required, it is formatted in FAT). We currently do not have write support for all FSes out there (apart for FAT until now), so do a "clever" "trick" to work around this problem: on initialized disks, find the active partition and check its FS. If we support write access to this FS then we're OK, otherwise we change the (active) system partition for the one on which we are going to install ReactOS (which is, by construction, formatted with a FS on which we support write access).
The MBR (resp. the VBR) of the disk (resp. of the system partition) are always saved into files, making easy for people to boot on them (using FreeLdr) or restoring them.
CORE-10898
svn path=/trunk/; revision=70837
2016-03-01 15:00:56 +00:00
SaveBootSector (
2017-05-31 02:03:10 +00:00
IN PCWSTR RootPath ,
IN PCWSTR DstPath ,
IN ULONG Length )
2003-04-05 15:36:34 +00:00
{
2016-02-02 01:55:05 +00:00
NTSTATUS Status ;
UNICODE_STRING Name ;
2010-09-06 01:46:06 +00:00
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
HANDLE FileHandle ;
2016-02-02 01:55:05 +00:00
LARGE_INTEGER FileOffset ;
2011-07-20 17:54:28 +00:00
PUCHAR BootSector ;
2003-04-05 15:36:34 +00:00
2011-07-20 17:54:28 +00:00
/* Allocate buffer for bootsector */
2016-02-02 01:55:05 +00:00
BootSector = RtlAllocateHeap ( ProcessHeap , 0 , Length ) ;
2011-07-20 17:54:28 +00:00
if ( BootSector = = NULL )
return STATUS_INSUFFICIENT_RESOURCES ;
2003-04-05 15:36:34 +00:00
2017-05-31 02:03:10 +00:00
/* Open the root partition - Remove any trailing backslash if needed */
2011-07-20 17:54:28 +00:00
RtlInitUnicodeString ( & Name , RootPath ) ;
2017-05-31 02:03:10 +00:00
TrimTrailingPathSeparators_UStr ( & Name ) ;
2003-04-05 15:36:34 +00:00
2010-09-06 01:46:06 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_READ | SYNCHRONIZE ,
2010-09-06 01:46:06 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , BootSector ) ;
return Status ;
}
2003-04-05 15:36:34 +00:00
2017-05-31 02:03:10 +00:00
/* Read current boot sector into buffer */
2016-02-02 01:55:05 +00:00
FileOffset . QuadPart = 0ULL ;
2010-09-06 01:46:06 +00:00
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
2011-07-20 17:54:28 +00:00
BootSector ,
2016-02-02 01:55:05 +00:00
Length ,
& FileOffset ,
2010-09-06 01:46:06 +00:00
NULL ) ;
NtClose ( FileHandle ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , BootSector ) ;
return Status ;
}
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
/* Write bootsector to DstPath */
RtlInitUnicodeString ( & Name , DstPath ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
Status = NtCreateFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_WRITE | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
NULL ,
FILE_ATTRIBUTE_NORMAL ,
0 ,
FILE_SUPERSEDE ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ,
NULL ,
0 ) ;
2003-01-28 17:29:22 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2011-07-20 17:54:28 +00:00
RtlFreeHeap ( ProcessHeap , 0 , BootSector ) ;
return Status ;
}
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
BootSector ,
2016-02-02 01:55:05 +00:00
Length ,
2011-07-20 17:54:28 +00:00
NULL ,
NULL ) ;
2003-01-28 17:29:22 +00:00
NtClose ( FileHandle ) ;
2016-02-02 01:55:05 +00:00
/* Free the boot sector */
2011-07-20 17:54:28 +00:00
RtlFreeHeap ( ProcessHeap , 0 , BootSector ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
return Status ;
2003-01-28 17:29:22 +00:00
}
NTSTATUS
2017-05-31 01:47:39 +00:00
InstallMbrBootCodeToDisk (
2017-05-31 02:03:10 +00:00
IN PCWSTR SrcPath ,
IN PCWSTR RootPath )
2003-01-28 17:29:22 +00:00
{
2016-02-02 01:55:05 +00:00
NTSTATUS Status ;
UNICODE_STRING Name ;
2011-07-20 17:54:28 +00:00
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
HANDLE FileHandle ;
2016-02-02 01:55:05 +00:00
LARGE_INTEGER FileOffset ;
2017-05-31 01:47:39 +00:00
PPARTITION_SECTOR OrigBootSector ;
PPARTITION_SECTOR NewBootSector ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
/* Allocate buffer for original bootsector */
2017-05-31 02:03:10 +00:00
OrigBootSector = RtlAllocateHeap ( ProcessHeap , 0 , sizeof ( PARTITION_SECTOR ) ) ;
2011-07-20 17:54:28 +00:00
if ( OrigBootSector = = NULL )
2016-02-02 01:55:05 +00:00
return STATUS_INSUFFICIENT_RESOURCES ;
2003-01-28 17:29:22 +00:00
2017-05-31 02:03:10 +00:00
/* Open the root partition - Remove any trailing backslash if needed */
RtlInitUnicodeString ( & Name , RootPath ) ;
TrimTrailingPathSeparators_UStr ( & Name ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_READ | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return Status ;
}
2003-01-28 17:29:22 +00:00
2017-05-31 02:03:10 +00:00
/* Read current boot sector into buffer */
2016-02-02 01:55:05 +00:00
FileOffset . QuadPart = 0ULL ;
2011-07-20 17:54:28 +00:00
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
2017-05-31 01:47:39 +00:00
sizeof ( PARTITION_SECTOR ) ,
2016-02-02 01:55:05 +00:00
& FileOffset ,
2011-07-20 17:54:28 +00:00
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
2004-06-23 14:09:55 +00:00
{
2011-07-20 17:54:28 +00:00
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return Status ;
2004-06-23 14:09:55 +00:00
}
2011-07-20 17:54:28 +00:00
/* Allocate buffer for new bootsector */
2017-05-31 02:03:10 +00:00
NewBootSector = RtlAllocateHeap ( ProcessHeap , 0 , sizeof ( PARTITION_SECTOR ) ) ;
2011-07-20 17:54:28 +00:00
if ( NewBootSector = = NULL )
2004-06-23 14:09:55 +00:00
{
2011-07-20 17:54:28 +00:00
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return STATUS_INSUFFICIENT_RESOURCES ;
2004-06-23 14:09:55 +00:00
}
2011-07-20 17:54:28 +00:00
/* Read new bootsector from SrcPath */
RtlInitUnicodeString ( & Name , SrcPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_READ | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
2017-05-31 01:47:39 +00:00
sizeof ( PARTITION_SECTOR ) ,
NULL ,
2011-07-20 17:54:28 +00:00
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2017-05-31 01:47:39 +00:00
/*
* Copy the disk signature , the reserved fields and
* the partition table from the old MBR to the new one .
*/
RtlCopyMemory ( & NewBootSector - > Signature ,
& OrigBootSector - > Signature ,
2017-05-31 02:03:10 +00:00
sizeof ( PARTITION_SECTOR ) - offsetof ( PARTITION_SECTOR , Signature )
/* Length of partition table */ ) ;
2011-07-20 17:54:28 +00:00
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
2018-10-18 20:58:48 +00:00
/* Open the root partition - Remove any trailing backslash if needed */
2017-05-31 01:47:39 +00:00
RtlInitUnicodeString ( & Name , RootPath ) ;
2018-10-18 20:58:48 +00:00
TrimTrailingPathSeparators_UStr ( & Name ) ;
2011-07-20 17:54:28 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
2017-05-31 01:47:39 +00:00
Status = NtOpenFile ( & FileHandle ,
GENERIC_WRITE | SYNCHRONIZE ,
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2017-05-31 01:47:39 +00:00
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
2011-07-20 17:54:28 +00:00
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2018-10-18 20:58:48 +00:00
/* Write new bootsector to RootPath */
2017-05-31 01:47:39 +00:00
FileOffset . QuadPart = 0ULL ;
2011-07-20 17:54:28 +00:00
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
2017-05-31 01:47:39 +00:00
sizeof ( PARTITION_SECTOR ) ,
& FileOffset ,
2011-07-20 17:54:28 +00:00
NULL ) ;
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2017-05-31 02:03:10 +00:00
2016-02-02 01:55:05 +00:00
static
2011-07-20 17:54:28 +00:00
NTSTATUS
2017-05-31 01:47:39 +00:00
InstallFat12BootCodeToFloppy (
2017-05-31 02:03:10 +00:00
IN PCWSTR SrcPath ,
IN PCWSTR RootPath )
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
NTSTATUS Status ;
UNICODE_STRING Name ;
2011-07-20 17:54:28 +00:00
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
HANDLE FileHandle ;
2016-02-02 01:55:05 +00:00
LARGE_INTEGER FileOffset ;
2017-05-31 01:47:39 +00:00
PFAT_BOOTSECTOR OrigBootSector ;
PFAT_BOOTSECTOR NewBootSector ;
2011-07-20 17:54:28 +00:00
/* Allocate buffer for original bootsector */
OrigBootSector = RtlAllocateHeap ( ProcessHeap , 0 , SECTORSIZE ) ;
if ( OrigBootSector = = NULL )
return STATUS_INSUFFICIENT_RESOURCES ;
2017-05-31 02:03:10 +00:00
/* Open the root partition - Remove any trailing backslash if needed */
2011-07-20 17:54:28 +00:00
RtlInitUnicodeString ( & Name , RootPath ) ;
2017-05-31 02:03:10 +00:00
TrimTrailingPathSeparators_UStr ( & Name ) ;
2011-07-20 17:54:28 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_READ | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return Status ;
}
2017-05-31 02:03:10 +00:00
/* Read current boot sector into buffer */
2017-05-31 01:47:39 +00:00
FileOffset . QuadPart = 0ULL ;
2011-07-20 17:54:28 +00:00
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
2017-05-31 01:47:39 +00:00
& FileOffset ,
2011-07-20 17:54:28 +00:00
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return Status ;
}
2017-05-31 01:47:39 +00:00
/* Allocate buffer for new bootsector */
NewBootSector = RtlAllocateHeap ( ProcessHeap ,
0 ,
SECTORSIZE ) ;
2011-07-20 17:54:28 +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 ,
2013-07-19 14:03:46 +00:00
GENERIC_READ | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
2017-05-31 01:47:39 +00:00
SECTORSIZE ,
2011-07-20 17:54:28 +00:00
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2017-05-31 01:47:39 +00:00
/* Adjust bootsector (copy a part of the FAT16 BPB) */
2011-07-20 17:54:28 +00:00
memcpy ( & NewBootSector - > OemName ,
& OrigBootSector - > OemName ,
2017-05-31 01:47:39 +00:00
FIELD_OFFSET ( FAT_BOOTSECTOR , BootCodeAndData ) -
FIELD_OFFSET ( FAT_BOOTSECTOR , OemName ) ) ;
2011-07-20 17:54:28 +00:00
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
2018-10-18 20:58:48 +00:00
/* Open the root partition - Remove any trailing backslash if needed */
2011-07-20 17:54:28 +00:00
RtlInitUnicodeString ( & Name , RootPath ) ;
2018-10-18 20:58:48 +00:00
TrimTrailingPathSeparators_UStr ( & Name ) ;
2011-07-20 17:54:28 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_WRITE | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2017-05-31 01:47:39 +00:00
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2017-05-31 01:47:39 +00:00
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
2011-07-20 17:54:28 +00:00
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2018-10-18 20:58:48 +00:00
/* Write new bootsector to RootPath */
2017-05-31 01:47:39 +00:00
FileOffset . QuadPart = 0ULL ;
2011-07-20 17:54:28 +00:00
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
2017-05-31 01:47:39 +00:00
NewBootSector ,
2011-07-20 17:54:28 +00:00
SECTORSIZE ,
& FileOffset ,
NULL ) ;
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2017-05-31 01:47:39 +00:00
static
2011-07-20 17:54:28 +00:00
NTSTATUS
2017-05-31 02:03:10 +00:00
InstallFat16BootCode (
IN PCWSTR SrcPath , // FAT16 bootsector source file (on the installation medium)
IN HANDLE DstPath , // Where to save the bootsector built from the source + partition information
IN HANDLE RootPartition ) // Partition holding the (old) FAT16 information
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
NTSTATUS Status ;
UNICODE_STRING Name ;
2011-07-20 17:54:28 +00:00
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
HANDLE FileHandle ;
2016-02-02 01:55:05 +00:00
LARGE_INTEGER FileOffset ;
2017-05-31 01:47:39 +00:00
PFAT_BOOTSECTOR OrigBootSector ;
PFAT_BOOTSECTOR NewBootSector ;
2011-07-20 17:54:28 +00:00
2017-05-31 02:03:10 +00:00
/* Allocate a buffer for the original bootsector */
2017-05-31 01:47:39 +00:00
OrigBootSector = RtlAllocateHeap ( ProcessHeap , 0 , SECTORSIZE ) ;
2011-07-20 17:54:28 +00:00
if ( OrigBootSector = = NULL )
return STATUS_INSUFFICIENT_RESOURCES ;
2017-05-31 02:03:10 +00:00
/* Read the current partition boot sector into the buffer */
2016-02-02 01:55:05 +00:00
FileOffset . QuadPart = 0ULL ;
2017-05-31 02:03:10 +00:00
Status = NtReadFile ( RootPartition ,
2011-07-20 17:54:28 +00:00
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
2017-05-31 01:47:39 +00:00
SECTORSIZE ,
2016-02-02 01:55:05 +00:00
& FileOffset ,
2011-07-20 17:54:28 +00:00
NULL ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return Status ;
}
2017-05-31 02:03:10 +00:00
/* Allocate a buffer for the new bootsector */
2017-05-31 01:47:39 +00:00
NewBootSector = RtlAllocateHeap ( ProcessHeap , 0 , SECTORSIZE ) ;
2011-07-20 17:54:28 +00:00
if ( NewBootSector = = NULL )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return STATUS_INSUFFICIENT_RESOURCES ;
}
2017-05-31 02:03:10 +00:00
/* Read the new bootsector from SrcPath */
2011-07-20 17:54:28 +00:00
RtlInitUnicodeString ( & Name , SrcPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_READ | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2017-05-31 01:47:39 +00:00
FileOffset . QuadPart = 0ULL ;
2011-07-20 17:54:28 +00:00
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
2017-05-31 01:47:39 +00:00
SECTORSIZE ,
& FileOffset ,
2011-07-20 17:54:28 +00:00
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2017-05-31 02:03:10 +00:00
/* Adjust the bootsector (copy a part of the FAT16 BPB) */
2017-05-31 01:47:39 +00:00
memcpy ( & NewBootSector - > OemName ,
& OrigBootSector - > OemName ,
FIELD_OFFSET ( FAT_BOOTSECTOR , BootCodeAndData ) -
FIELD_OFFSET ( FAT_BOOTSECTOR , OemName ) ) ;
2011-07-20 17:54:28 +00:00
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
2017-05-31 02:03:10 +00:00
/* Write the new bootsector to DstPath */
2016-02-02 01:55:05 +00:00
FileOffset . QuadPart = 0ULL ;
2017-05-31 02:03:10 +00:00
Status = NtWriteFile ( DstPath ,
2011-07-20 17:54:28 +00:00
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
2017-05-31 01:47:39 +00:00
SECTORSIZE ,
2017-05-31 02:03:10 +00:00
& FileOffset ,
2011-07-20 17:54:28 +00:00
NULL ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2016-02-02 01:55:05 +00:00
static
2011-10-29 15:10:11 +00:00
NTSTATUS
2017-05-31 02:03:10 +00:00
InstallFat16BootCodeToFile (
IN PCWSTR SrcPath ,
IN PCWSTR DstPath ,
IN PCWSTR RootPath )
2011-10-29 15:10:11 +00:00
{
2016-02-02 01:55:05 +00:00
NTSTATUS Status ;
UNICODE_STRING Name ;
2011-10-29 15:10:11 +00:00
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
2017-05-31 02:03:10 +00:00
HANDLE PartitionHandle , FileHandle ;
2014-05-12 14:17:37 +00:00
2017-05-31 02:03:10 +00:00
/*
* Open the root partition from which the boot sector
* parameters will be obtained .
* Remove any trailing backslash if needed .
*/
2011-10-29 15:10:11 +00:00
RtlInitUnicodeString ( & Name , RootPath ) ;
2017-05-31 02:03:10 +00:00
TrimTrailingPathSeparators_UStr ( & Name ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
2017-05-31 02:03:10 +00:00
Status = NtOpenFile ( & PartitionHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_READ | SYNCHRONIZE ,
2011-10-29 15:10:11 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2017-05-31 02:03:10 +00:00
FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */ ) ;
2011-10-29 15:10:11 +00:00
if ( ! NT_SUCCESS ( Status ) )
return Status ;
2014-05-12 14:17:37 +00:00
2017-05-31 02:03:10 +00:00
/* Open or create the file where the new bootsector will be saved */
RtlInitUnicodeString ( & Name , DstPath ) ;
2011-10-29 15:10:11 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
2017-05-31 02:03:10 +00:00
0 , // OBJ_CASE_INSENSITIVE,
2011-10-29 15:10:11 +00:00
NULL ,
NULL ) ;
2017-05-31 02:03:10 +00:00
Status = NtCreateFile ( & FileHandle ,
GENERIC_WRITE | SYNCHRONIZE ,
& ObjectAttributes ,
& IoStatusBlock ,
NULL ,
FILE_ATTRIBUTE_NORMAL ,
0 ,
FILE_OVERWRITE_IF ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ,
NULL ,
0 ) ;
2011-10-29 15:10:11 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2017-05-31 02:03:10 +00:00
DPRINT1 ( " NtCreateFile() failed (Status %lx) \n " , Status ) ;
NtClose ( PartitionHandle ) ;
2011-10-29 15:10:11 +00:00
return Status ;
}
2014-05-12 14:17:37 +00:00
2017-05-31 02:03:10 +00:00
/* Install the FAT16 boot sector */
Status = InstallFat16BootCode ( SrcPath , FileHandle , PartitionHandle ) ;
/* Close the file and the partition */
2011-10-29 15:10:11 +00:00
NtClose ( FileHandle ) ;
2017-05-31 02:03:10 +00:00
NtClose ( PartitionHandle ) ;
2014-05-12 14:17:37 +00:00
2017-05-31 02:03:10 +00:00
return Status ;
}
2014-05-12 14:17:37 +00:00
2017-05-31 02:03:10 +00:00
static
NTSTATUS
InstallFat16BootCodeToDisk (
IN PCWSTR SrcPath ,
IN PCWSTR RootPath )
{
NTSTATUS Status ;
UNICODE_STRING Name ;
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
HANDLE PartitionHandle ;
2014-05-12 14:17:37 +00:00
2017-05-31 02:03:10 +00:00
/*
* Open the root partition from which the boot sector parameters will be
* obtained ; this is also where we will write the updated boot sector .
* Remove any trailing backslash if needed .
*/
2011-10-29 15:10:11 +00:00
RtlInitUnicodeString ( & Name , RootPath ) ;
2017-05-31 02:03:10 +00:00
TrimTrailingPathSeparators_UStr ( & Name ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
2017-05-31 02:03:10 +00:00
OBJ_CASE_INSENSITIVE ,
2011-10-29 15:10:11 +00:00
NULL ,
NULL ) ;
2017-05-31 02:03:10 +00:00
Status = NtOpenFile ( & PartitionHandle ,
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE ,
2011-10-29 15:10:11 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ) ;
if ( ! NT_SUCCESS ( Status ) )
return Status ;
2014-05-12 14:17:37 +00:00
2017-05-31 02:03:10 +00:00
/* Install the FAT16 boot sector */
Status = InstallFat16BootCode ( SrcPath , PartitionHandle , PartitionHandle ) ;
2014-05-12 14:17:37 +00:00
2017-05-31 02:03:10 +00:00
/* Close the partition */
NtClose ( PartitionHandle ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
return Status ;
}
2017-05-31 02:03:10 +00:00
2016-02-02 01:55:05 +00:00
static
2011-07-20 17:54:28 +00:00
NTSTATUS
2017-05-31 02:03:10 +00:00
InstallFat32BootCode (
IN PCWSTR SrcPath , // FAT32 bootsector source file (on the installation medium)
IN HANDLE DstPath , // Where to save the bootsector built from the source + partition information
IN HANDLE RootPartition ) // Partition holding the (old) FAT32 information
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
NTSTATUS Status ;
UNICODE_STRING Name ;
2011-07-20 17:54:28 +00:00
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
HANDLE FileHandle ;
2016-02-02 01:55:05 +00:00
LARGE_INTEGER FileOffset ;
2017-05-31 01:47:39 +00:00
PFAT32_BOOTSECTOR OrigBootSector ;
PFAT32_BOOTSECTOR NewBootSector ;
2017-05-31 02:03:10 +00:00
USHORT BackupBootSector ;
2011-07-20 17:54:28 +00:00
2017-05-31 02:03:10 +00:00
/* Allocate a buffer for the original bootsector */
2011-07-20 17:54:28 +00:00
OrigBootSector = RtlAllocateHeap ( ProcessHeap , 0 , SECTORSIZE ) ;
if ( OrigBootSector = = NULL )
return STATUS_INSUFFICIENT_RESOURCES ;
2017-05-31 02:03:10 +00:00
/* Read the current boot sector into the buffer */
2016-02-02 01:55:05 +00:00
FileOffset . QuadPart = 0ULL ;
2017-05-31 02:03:10 +00:00
Status = NtReadFile ( RootPartition ,
2011-07-20 17:54:28 +00:00
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
2017-05-31 02:03:10 +00:00
& FileOffset ,
2011-07-20 17:54:28 +00:00
NULL ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return Status ;
}
2017-05-31 02:03:10 +00:00
/* Allocate a buffer for the new bootsector (2 sectors) */
2017-05-31 01:47:39 +00:00
NewBootSector = RtlAllocateHeap ( ProcessHeap , 0 , 2 * SECTORSIZE ) ;
2011-07-20 17:54:28 +00:00
if ( NewBootSector = = NULL )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return STATUS_INSUFFICIENT_RESOURCES ;
}
2017-05-31 02:03:10 +00:00
/* Read the new bootsector from SrcPath */
2011-07-20 17:54:28 +00:00
RtlInitUnicodeString ( & Name , SrcPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
2017-05-31 01:47:39 +00:00
Status = NtOpenFile ( & FileHandle ,
GENERIC_READ | SYNCHRONIZE ,
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2017-05-31 02:03:10 +00:00
FileOffset . QuadPart = 0ULL ;
2017-05-31 01:47:39 +00:00
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
2 * SECTORSIZE ,
2017-05-31 02:03:10 +00:00
& FileOffset ,
2017-05-31 01:47:39 +00:00
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2017-05-31 02:03:10 +00:00
/* Adjust the bootsector (copy a part of the FAT32 BPB) */
2017-05-31 01:47:39 +00:00
memcpy ( & NewBootSector - > OemName ,
& OrigBootSector - > OemName ,
FIELD_OFFSET ( FAT32_BOOTSECTOR , BootCodeAndData ) -
FIELD_OFFSET ( FAT32_BOOTSECTOR , OemName ) ) ;
2017-05-31 02:03:10 +00:00
/*
* We know we copy the boot code to a file only when DstPath ! = RootPartition ,
* otherwise the boot code is copied to the specified root partition .
*/
if ( DstPath ! = RootPartition )
{
/* Copy to a file: Disable the backup boot sector */
NewBootSector - > BackupBootSector = 0 ;
}
else
{
/* Copy to a disk: Get the location of the backup boot sector */
BackupBootSector = OrigBootSector - > BackupBootSector ;
}
2017-05-31 01:47:39 +00:00
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
2017-05-31 02:03:10 +00:00
/* Write the first sector of the new bootcode to DstPath sector 0 */
2017-05-31 01:47:39 +00:00
FileOffset . QuadPart = 0ULL ;
2017-05-31 02:03:10 +00:00
Status = NtWriteFile ( DstPath ,
2017-05-31 01:47:39 +00:00
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
2017-05-31 02:03:10 +00:00
& FileOffset ,
2017-05-31 01:47:39 +00:00
NULL ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2017-05-31 02:03:10 +00:00
DPRINT1 ( " NtWriteFile() failed (Status %lx) \n " , Status ) ;
2011-07-20 17:54:28 +00:00
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2017-05-31 02:03:10 +00:00
if ( DstPath = = RootPartition )
2011-07-20 17:54:28 +00:00
{
2017-05-31 02:03:10 +00:00
/* Copy to a disk: Write the backup boot sector */
if ( ( BackupBootSector ! = 0x0000 ) & & ( BackupBootSector ! = 0xFFFF ) )
{
FileOffset . QuadPart = ( ULONGLONG ) ( ( ULONG ) BackupBootSector * SECTORSIZE ) ;
Status = NtWriteFile ( DstPath ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
& FileOffset ,
NULL ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtWriteFile() failed (Status %lx) \n " , Status ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
}
2011-07-20 17:54:28 +00:00
}
2017-05-31 02:03:10 +00:00
/* Write the second sector of the new bootcode to boot disk sector 14 */
// FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE);
FileOffset . QuadPart = 14 * SECTORSIZE ;
Status = NtWriteFile ( DstPath , // or really RootPartition ???
2011-07-20 17:54:28 +00:00
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
2017-05-31 01:47:39 +00:00
( ( PUCHAR ) NewBootSector + SECTORSIZE ) ,
2011-07-20 17:54:28 +00:00
SECTORSIZE ,
2016-02-02 01:55:05 +00:00
& FileOffset ,
2011-07-20 17:54:28 +00:00
NULL ) ;
2017-05-31 01:47:39 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2017-05-31 02:03:10 +00:00
DPRINT1 ( " NtWriteFile() failed (Status %lx) \n " , Status ) ;
2017-05-31 01:47:39 +00:00
}
2011-07-20 17:54:28 +00:00
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2016-02-02 01:55:05 +00:00
static
2011-07-20 17:54:28 +00:00
NTSTATUS
2017-05-31 02:03:10 +00:00
InstallFat32BootCodeToFile (
IN PCWSTR SrcPath ,
IN PCWSTR DstPath ,
IN PCWSTR RootPath )
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
NTSTATUS Status ;
UNICODE_STRING Name ;
2011-07-20 17:54:28 +00:00
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
2017-05-31 02:03:10 +00:00
HANDLE PartitionHandle , FileHandle ;
2011-07-20 17:54:28 +00:00
2017-05-31 02:03:10 +00:00
/*
* Open the root partition from which the boot sector parameters
* will be obtained .
* FIXME ? It might be possible that we need to also open it for writing
* access in case we really need to still write the second portion of
* the boot sector ? ? ? ?
*
* Remove any trailing backslash if needed .
*/
2011-07-20 17:54:28 +00:00
RtlInitUnicodeString ( & Name , RootPath ) ;
2017-05-31 02:03:10 +00:00
TrimTrailingPathSeparators_UStr ( & Name ) ;
2011-07-20 17:54:28 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
2017-05-31 02:03:10 +00:00
Status = NtOpenFile ( & PartitionHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_READ | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2017-05-31 02:03:10 +00:00
FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */ ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
return Status ;
2017-05-31 02:03:10 +00:00
/* Open or create the file where (the first sector of ????) the new bootsector will be saved */
RtlInitUnicodeString ( & Name , DstPath ) ;
2011-07-20 17:54:28 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
2017-05-31 02:03:10 +00:00
0 , // OBJ_CASE_INSENSITIVE,
2011-07-20 17:54:28 +00:00
NULL ,
NULL ) ;
2017-05-31 02:03:10 +00:00
Status = NtCreateFile ( & FileHandle ,
GENERIC_WRITE | SYNCHRONIZE ,
& ObjectAttributes ,
& IoStatusBlock ,
NULL ,
FILE_ATTRIBUTE_NORMAL ,
0 ,
FILE_SUPERSEDE , // FILE_OVERWRITE_IF, <- is used for FAT16
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ,
NULL ,
0 ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2017-05-31 02:03:10 +00:00
DPRINT1 ( " NtCreateFile() failed (Status %lx) \n " , Status ) ;
NtClose ( PartitionHandle ) ;
2011-07-20 17:54:28 +00:00
return Status ;
}
2017-05-31 02:03:10 +00:00
/* Install the FAT32 boot sector */
Status = InstallFat32BootCode ( SrcPath , FileHandle , PartitionHandle ) ;
2011-07-20 17:54:28 +00:00
2017-05-31 02:03:10 +00:00
/* Close the file and the partition */
NtClose ( FileHandle ) ;
NtClose ( PartitionHandle ) ;
2011-07-20 17:54:28 +00:00
2017-05-31 02:03:10 +00:00
return Status ;
}
2011-07-20 17:54:28 +00:00
2017-05-31 02:03:10 +00:00
static
NTSTATUS
InstallFat32BootCodeToDisk (
IN PCWSTR SrcPath ,
IN PCWSTR RootPath )
{
NTSTATUS Status ;
UNICODE_STRING Name ;
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
HANDLE PartitionHandle ;
2011-07-20 17:54:28 +00:00
2017-05-31 02:03:10 +00:00
/*
* Open the root partition from which the boot sector parameters will be
* obtained ; this is also where we will write the updated boot sector .
* Remove any trailing backslash if needed .
*/
2011-07-20 17:54:28 +00:00
RtlInitUnicodeString ( & Name , RootPath ) ;
2017-05-31 02:03:10 +00:00
TrimTrailingPathSeparators_UStr ( & Name ) ;
2011-07-20 17:54:28 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
2017-05-31 02:03:10 +00:00
OBJ_CASE_INSENSITIVE ,
2011-07-20 17:54:28 +00:00
NULL ,
NULL ) ;
2017-05-31 02:03:10 +00:00
Status = NtOpenFile ( & PartitionHandle ,
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
2017-05-31 02:03:10 +00:00
FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */ ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
return Status ;
2017-05-31 02:03:10 +00:00
/* Install the FAT32 boot sector */
Status = InstallFat32BootCode ( SrcPath , PartitionHandle , PartitionHandle ) ;
2011-07-20 17:54:28 +00:00
2017-05-31 02:03:10 +00:00
/* Close the partition */
NtClose ( PartitionHandle ) ;
2011-07-20 17:54:28 +00:00
return Status ;
}
static
NTSTATUS
2018-06-13 23:30:06 +00:00
InstallBtrfsBootCodeToDisk (
2018-10-18 20:58:48 +00:00
IN PCWSTR SrcPath ,
IN PCWSTR RootPath )
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
NTSTATUS Status ;
2011-07-20 17:54:28 +00:00
UNICODE_STRING Name ;
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
HANDLE FileHandle ;
2016-02-02 01:55:05 +00:00
LARGE_INTEGER FileOffset ;
// PEXT2_BOOTSECTOR OrigBootSector;
2018-06-13 23:30:06 +00:00
PBTRFS_BOOTSECTOR NewBootSector ;
2016-02-02 01:55:05 +00:00
// USHORT BackupBootSector;
2018-06-13 23:30:06 +00:00
PARTITION_INFORMATION_EX PartInfo ;
2011-07-20 17:54:28 +00:00
2016-02-02 01:55:05 +00:00
#if 0
/* Allocate buffer for original bootsector */
OrigBootSector = RtlAllocateHeap ( ProcessHeap , 0 , SECTORSIZE ) ;
if ( OrigBootSector = = NULL )
return STATUS_INSUFFICIENT_RESOURCES ;
2017-05-31 02:03:10 +00:00
/* Open the root partition - Remove any trailing backslash if needed */
2016-02-02 01:55:05 +00:00
RtlInitUnicodeString ( & Name , RootPath ) ;
2017-05-31 02:03:10 +00:00
TrimTrailingPathSeparators_UStr ( & Name ) ;
2011-07-20 17:54:28 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2016-02-02 01:55:05 +00:00
GENERIC_READ | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
{
2016-02-02 01:55:05 +00:00
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
2011-07-20 17:54:28 +00:00
return Status ;
}
2017-05-31 02:03:10 +00:00
/* Read current boot sector into buffer */
2016-02-02 01:55:05 +00:00
FileOffset . QuadPart = 0ULL ;
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
& FileOffset ,
NULL ) ;
NtClose ( FileHandle ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2016-02-02 01:55:05 +00:00
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
2011-07-20 17:54:28 +00:00
return Status ;
}
2016-02-02 01:55:05 +00:00
# endif
2011-07-20 17:54:28 +00:00
2016-02-02 01:55:05 +00:00
/* Allocate buffer for new bootsector */
2018-06-13 23:30:06 +00:00
NewBootSector = RtlAllocateHeap ( ProcessHeap , 0 , sizeof ( BTRFS_BOOTSECTOR ) ) ;
2016-02-02 01:55:05 +00:00
if ( NewBootSector = = NULL )
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
// RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
return STATUS_INSUFFICIENT_RESOURCES ;
2011-07-20 17:54:28 +00:00
}
2016-02-02 01:55:05 +00:00
/* Read new bootsector from SrcPath */
RtlInitUnicodeString ( & Name , SrcPath ) ;
2011-07-20 17:54:28 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2016-02-02 01:55:05 +00:00
GENERIC_READ | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
{
2016-02-02 01:55:05 +00:00
// RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
2011-07-20 17:54:28 +00:00
return Status ;
}
2016-02-02 01:55:05 +00:00
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
2018-06-13 23:30:06 +00:00
sizeof ( BTRFS_BOOTSECTOR ) ,
2016-02-02 01:55:05 +00:00
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
// RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
#if 0
/* Adjust bootsector (copy a part of the FAT32 BPB) */
memcpy ( & NewBootSector - > OemName ,
& OrigBootSector - > OemName ,
FIELD_OFFSET ( FAT32_BOOTSECTOR , BootCodeAndData ) -
FIELD_OFFSET ( FAT32_BOOTSECTOR , OemName ) ) ;
/* Get the location of the backup boot sector */
BackupBootSector = OrigBootSector - > BackupBootSector ;
/* Free the original boot sector */
// RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
# endif
2018-10-18 20:58:48 +00:00
/* Open the root partition - Remove any trailing backslash if needed */
2016-02-02 01:55:05 +00:00
RtlInitUnicodeString ( & Name , RootPath ) ;
2018-10-18 20:58:48 +00:00
TrimTrailingPathSeparators_UStr ( & Name ) ;
2016-02-02 01:55:05 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
GENERIC_WRITE | SYNCHRONIZE ,
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2018-06-13 23:30:06 +00:00
/* Obtaining partition info and writing it to bootsector */
Status = NtDeviceIoControlFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
IOCTL_DISK_GET_PARTITION_INFO_EX ,
NULL ,
0 ,
& PartInfo ,
sizeof ( PartInfo ) ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " IOCTL_DISK_GET_PARTITION_INFO_EX failed (Status %lx) \n " , Status ) ;
NtClose ( FileHandle ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2018-10-18 20:58:48 +00:00
/* Write new bootsector to RootPath */
2018-06-13 23:30:06 +00:00
NewBootSector - > PartitionStartLBA = PartInfo . StartingOffset . QuadPart / SECTORSIZE ;
2016-02-02 01:55:05 +00:00
/* Write sector 0 */
FileOffset . QuadPart = 0ULL ;
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
2018-06-13 23:30:06 +00:00
sizeof ( BTRFS_BOOTSECTOR ) ,
2016-02-02 01:55:05 +00:00
& FileOffset ,
NULL ) ;
#if 0
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtWriteFile() failed (Status %lx) \n " , Status ) ;
NtClose ( FileHandle ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
/* Write backup boot sector */
if ( ( BackupBootSector ! = 0x0000 ) & & ( BackupBootSector ! = 0xFFFF ) )
{
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 = 14 * SECTORSIZE ;
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
( ( PUCHAR ) NewBootSector + SECTORSIZE ) ,
SECTORSIZE ,
& FileOffset ,
NULL ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtWriteFile() failed (Status %lx) \n " , Status ) ;
}
# endif
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
static
2004-06-23 14:09:55 +00:00
NTSTATUS
2011-07-20 17:54:28 +00:00
InstallFatBootcodeToPartition (
PUNICODE_STRING SystemRootPath ,
PUNICODE_STRING SourceRootPath ,
PUNICODE_STRING DestinationArcPath ,
UCHAR PartitionType )
2004-06-23 14:09:55 +00:00
{
2016-02-02 01:55:05 +00:00
NTSTATUS Status ;
BOOLEAN DoesFreeLdrExist ;
2011-07-20 17:54:28 +00:00
WCHAR SrcPath [ MAX_PATH ] ;
WCHAR DstPath [ MAX_PATH ] ;
/* FAT or FAT32 partition */
DPRINT ( " System path: '%wZ' \n " , SystemRootPath ) ;
2017-05-31 01:43:12 +00:00
/* Copy FreeLoader to the system partition, always overwriting the older version */
2017-05-23 22:30:54 +00:00
CombinePaths ( SrcPath , ARRAYSIZE ( SrcPath ) , 2 , SourceRootPath - > Buffer , L " \\ loader \\ freeldr.sys " ) ;
2017-05-31 01:43:12 +00:00
CombinePaths ( DstPath , ARRAYSIZE ( DstPath ) , 2 , SystemRootPath - > Buffer , L " freeldr.sys " ) ;
2016-02-02 01:55:05 +00:00
DPRINT ( " Copy: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = SetupCopyFile ( SrcPath , DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
DPRINT1 ( " SetupCopyFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
2011-07-20 17:54:28 +00:00
2017-05-31 01:43:12 +00:00
/* Prepare for possibly updating 'freeldr.ini' */
2017-06-08 02:43:51 +00:00
DoesFreeLdrExist = DoesFileExist_2 ( SystemRootPath - > Buffer , L " freeldr.ini " ) ;
2016-02-02 01:55:05 +00:00
if ( DoesFreeLdrExist )
{
/* Update existing 'freeldr.ini' */
DPRINT1 ( " Update existing 'freeldr.ini' \n " ) ;
2017-06-08 02:43:51 +00:00
Status = UpdateFreeLoaderIni ( SystemRootPath - > Buffer , DestinationArcPath - > Buffer ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2016-02-02 01:55:05 +00:00
DPRINT1 ( " UpdateFreeLoaderIni() failed (Status %lx) \n " , Status ) ;
2011-07-20 17:54:28 +00:00
return Status ;
}
2016-02-02 01:55:05 +00:00
}
2011-07-20 17:54:28 +00:00
2016-02-02 01:55:05 +00:00
/* Check for NT and other bootloaders */
// FIXME: Check for Vista+ bootloader!
2017-06-08 17:30:23 +00:00
/*** Status = FindBootStore(PartitionHandle, NtLdr, &Version); ***/
/*** Status = FindBootStore(PartitionHandle, BootMgr, &Version); ***/
2017-05-31 01:43:12 +00:00
if ( DoesFileExist_2 ( SystemRootPath - > Buffer , L " NTLDR " ) = = TRUE | |
DoesFileExist_2 ( SystemRootPath - > Buffer , L " BOOT.INI " ) = = TRUE )
2016-02-02 01:55:05 +00:00
{
2017-05-31 01:43:12 +00:00
/* Search root directory for 'NTLDR' and 'BOOT.INI' */
2016-02-02 01:55:05 +00:00
DPRINT1 ( " Found Microsoft Windows NT/2000/XP boot loader \n " ) ;
/* Create or update 'freeldr.ini' */
if ( DoesFreeLdrExist = = FALSE )
2011-07-20 17:54:28 +00:00
{
/* Create new 'freeldr.ini' */
DPRINT1 ( " Create new 'freeldr.ini' \n " ) ;
2017-06-08 02:43:51 +00:00
Status = CreateFreeLoaderIniForReactOS ( SystemRootPath - > Buffer , DestinationArcPath - > Buffer ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2015-04-18 09:21:51 +00:00
DPRINT1 ( " CreateFreeLoaderIniForReactOS() failed (Status %lx) \n " , Status ) ;
2011-07-20 17:54:28 +00:00
return Status ;
}
2016-02-02 01:55:05 +00:00
/* Install new bootcode into a file */
2017-05-31 01:43:12 +00:00
CombinePaths ( DstPath , ARRAYSIZE ( DstPath ) , 2 , SystemRootPath - > Buffer , L " bootsect.ros " ) ;
2016-02-02 01:55:05 +00:00
2011-07-20 17:54:28 +00:00
if ( PartitionType = = PARTITION_FAT32 | |
2015-12-30 20:23:18 +00:00
PartitionType = = PARTITION_FAT32_XINT13 )
2011-07-20 17:54:28 +00:00
{
/* Install FAT32 bootcode */
2017-05-23 22:30:54 +00:00
CombinePaths ( SrcPath , ARRAYSIZE ( SrcPath ) , 2 , SourceRootPath - > Buffer , L " \\ loader \\ fat32.bin " ) ;
2011-07-20 17:54:28 +00:00
DPRINT1 ( " Install FAT32 bootcode: %S ==> %S \n " , SrcPath , DstPath ) ;
2016-02-02 01:55:05 +00:00
Status = InstallFat32BootCodeToFile ( SrcPath , DstPath ,
2011-07-20 17:54:28 +00:00
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat32BootCodeToFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
else
{
/* Install FAT16 bootcode */
2017-05-23 22:30:54 +00:00
CombinePaths ( SrcPath , ARRAYSIZE ( SrcPath ) , 2 , SourceRootPath - > Buffer , L " \\ loader \\ fat.bin " ) ;
2011-07-20 17:54:28 +00:00
DPRINT1 ( " Install FAT bootcode: %S ==> %S \n " , SrcPath , DstPath ) ;
2016-02-02 01:55:05 +00:00
Status = InstallFat16BootCodeToFile ( SrcPath , DstPath ,
2011-07-20 17:54:28 +00:00
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat16BootCodeToFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
}
/* Update 'boot.ini' */
2018-08-28 10:45:03 +00:00
/* Windows' NTLDR loads an external bootsector file when the specified drive
letter is C : , otherwise it will interpret it as a boot DOS path specifier . */
2017-06-08 02:43:51 +00:00
DPRINT1 ( " Update 'boot.ini' \n " ) ;
Status = UpdateBootIni ( SystemRootPath - > Buffer ,
2011-07-20 17:54:28 +00:00
L " C: \\ bootsect.ros " ,
L " \" ReactOS \" " ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " UpdateBootIni() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
2016-02-02 01:55:05 +00:00
else
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
/* Non-NT bootloaders: install our own bootloader */
2011-07-20 17:54:28 +00:00
2017-05-31 01:43:12 +00:00
PCWSTR Section ;
PCWSTR Description ;
PCWSTR BootDrive ;
PCWSTR BootPartition ;
PCWSTR BootSector ;
2011-07-20 17:54:28 +00:00
2017-05-31 01:43:12 +00:00
/* Search for COMPAQ MS-DOS 1.x (1.11, 1.12, based on MS-DOS 1.25) boot loader */
if ( DoesFileExist_2 ( SystemRootPath - > Buffer , L " IOSYS.COM " ) = = TRUE | |
DoesFileExist_2 ( SystemRootPath - > Buffer , L " MSDOS.COM " ) = = TRUE )
{
DPRINT1 ( " Found COMPAQ MS-DOS 1.x (1.11, 1.12) / MS-DOS 1.25 boot loader \n " ) ;
2017-06-06 23:44:56 +00:00
Section = L " CPQDOS " ;
2017-05-31 01:43:12 +00:00
Description = L " \" COMPAQ MS-DOS 1.x / MS-DOS 1.25 \" " ;
BootDrive = L " hd0 " ;
BootPartition = L " 1 " ;
BootSector = L " BOOTSECT.DOS " ;
}
else
/* Search for Microsoft DOS or Windows 9x boot loader */
if ( DoesFileExist_2 ( SystemRootPath - > Buffer , L " IO.SYS " ) = = TRUE | |
DoesFileExist_2 ( SystemRootPath - > Buffer , L " MSDOS.SYS " ) = = TRUE )
// WINBOOT.SYS
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
DPRINT1 ( " Found Microsoft DOS or Windows 9x boot loader \n " ) ;
2017-06-06 23:44:56 +00:00
Section = L " MSDOS " ;
2017-05-31 01:43:12 +00:00
Description = L " \" MS-DOS/Windows \" " ;
BootDrive = L " hd0 " ;
BootPartition = L " 1 " ;
BootSector = L " BOOTSECT.DOS " ;
}
else
/* Search for IBM PC-DOS or DR-DOS 5.x boot loader */
if ( DoesFileExist_2 ( SystemRootPath - > Buffer , L " IBMIO.COM " ) = = TRUE | | // Some people refer to this file instead of IBMBIO.COM...
DoesFileExist_2 ( SystemRootPath - > Buffer , L " IBMBIO.COM " ) = = TRUE | |
DoesFileExist_2 ( SystemRootPath - > Buffer , L " IBMDOS.COM " ) = = TRUE )
{
DPRINT1 ( " Found IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0 \n " ) ;
2017-06-06 23:44:56 +00:00
Section = L " IBMDOS " ;
2017-05-31 01:43:12 +00:00
Description = L " \" IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0 \" " ;
2016-02-02 01:55:05 +00:00
BootDrive = L " hd0 " ;
BootPartition = L " 1 " ;
BootSector = L " BOOTSECT.DOS " ;
2017-05-31 01:43:12 +00:00
}
else
/* Search for DR-DOS 3.x boot loader */
if ( DoesFileExist_2 ( SystemRootPath - > Buffer , L " DRBIOS.SYS " ) = = TRUE | |
DoesFileExist_2 ( SystemRootPath - > Buffer , L " DRBDOS.SYS " ) = = TRUE )
{
DPRINT1 ( " Found DR-DOS 3.x \n " ) ;
2017-06-06 23:44:56 +00:00
Section = L " DRDOS " ;
2017-05-31 01:43:12 +00:00
Description = L " \" DR-DOS 3.x \" " ;
BootDrive = L " hd0 " ;
BootPartition = L " 1 " ;
BootSector = L " BOOTSECT.DOS " ;
}
else
2017-06-06 23:44:56 +00:00
/* Search for Dell Real-Mode Kernel (DRMK) OS */
if ( DoesFileExist_2 ( SystemRootPath - > Buffer , L " DELLBIO.BIN " ) = = TRUE | |
DoesFileExist_2 ( SystemRootPath - > Buffer , L " DELLRMK.BIN " ) = = TRUE )
{
DPRINT1 ( " Found Dell Real-Mode Kernel OS \n " ) ;
Section = L " DRMK " ;
Description = L " \" Dell Real-Mode Kernel OS \" " ;
BootDrive = L " hd0 " ;
BootPartition = L " 1 " ;
BootSector = L " BOOTSECT.DOS " ;
}
else
2017-05-31 01:43:12 +00:00
/* Search for MS OS/2 1.x */
if ( DoesFileExist_2 ( SystemRootPath - > Buffer , L " OS2BOOT.COM " ) = = TRUE | |
DoesFileExist_2 ( SystemRootPath - > Buffer , L " OS2BIO.COM " ) = = TRUE | |
DoesFileExist_2 ( SystemRootPath - > Buffer , L " OS2DOS.COM " ) = = TRUE )
{
DPRINT1 ( " Found MS OS/2 1.x \n " ) ;
2017-06-06 23:44:56 +00:00
Section = L " MSOS2 " ;
2017-05-31 01:43:12 +00:00
Description = L " \" MS OS/2 1.x \" " ;
BootDrive = L " hd0 " ;
BootPartition = L " 1 " ;
BootSector = L " BOOTSECT.OS2 " ;
}
else
/* Search for MS or IBM OS/2 */
if ( DoesFileExist_2 ( SystemRootPath - > Buffer , L " OS2BOOT " ) = = TRUE | |
DoesFileExist_2 ( SystemRootPath - > Buffer , L " OS2LDR " ) = = TRUE | |
DoesFileExist_2 ( SystemRootPath - > Buffer , L " OS2KRNL " ) = = TRUE )
{
DPRINT1 ( " Found MS/IBM OS/2 \n " ) ;
2016-02-02 01:55:05 +00:00
2017-06-06 23:44:56 +00:00
Section = L " IBMOS2 " ;
2017-05-31 01:43:12 +00:00
Description = L " \" MS/IBM OS/2 \" " ;
BootDrive = L " hd0 " ;
BootPartition = L " 1 " ;
BootSector = L " BOOTSECT.OS2 " ;
2016-02-02 01:55:05 +00:00
}
else
2017-05-31 01:43:12 +00:00
/* Search for FreeDOS boot loader */
2017-05-24 16:37:49 +00:00
if ( DoesFileExist_2 ( SystemRootPath - > Buffer , L " kernel.sys " ) = = TRUE )
2016-02-02 01:55:05 +00:00
{
DPRINT1 ( " Found FreeDOS boot loader \n " ) ;
2017-06-06 23:44:56 +00:00
Section = L " FDOS " ;
2016-02-02 01:55:05 +00:00
Description = L " \" FreeDOS \" " ;
BootDrive = L " hd0 " ;
BootPartition = L " 1 " ;
BootSector = L " BOOTSECT.DOS " ;
}
else
{
/* No or unknown boot loader */
DPRINT1 ( " No or unknown boot loader found \n " ) ;
Section = L " Unknown " ;
Description = L " \" Unknown Operating System \" " ;
BootDrive = L " hd0 " ;
BootPartition = L " 1 " ;
BootSector = L " BOOTSECT.OLD " ;
2011-07-20 17:54:28 +00:00
}
/* Create or update 'freeldr.ini' */
2016-02-02 01:55:05 +00:00
if ( DoesFreeLdrExist = = FALSE )
2011-07-20 17:54:28 +00:00
{
/* Create new 'freeldr.ini' */
DPRINT1 ( " Create new 'freeldr.ini' \n " ) ;
2016-02-02 01:55:05 +00:00
if ( IsThereAValidBootSector ( SystemRootPath - > Buffer ) )
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
Status = CreateFreeLoaderIniForReactOSAndBootSector (
2017-06-08 02:43:51 +00:00
SystemRootPath - > Buffer , DestinationArcPath - > Buffer ,
2016-02-02 01:55:05 +00:00
Section , Description ,
BootDrive , BootPartition , BootSector ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx) \n " , Status ) ;
return Status ;
}
2011-07-20 17:54:28 +00:00
2016-02-02 01:55:05 +00:00
/* Save current bootsector */
2017-05-31 01:43:12 +00:00
CombinePaths ( DstPath , ARRAYSIZE ( DstPath ) , 2 , SystemRootPath - > Buffer , BootSector ) ;
2011-07-20 17:54:28 +00:00
2016-02-02 01:55:05 +00:00
DPRINT1 ( " Save bootsector: %S ==> %S \n " , SystemRootPath - > Buffer , DstPath ) ;
[USETUP]
- bootsup.c/.h, usetup.c: Save the old MBR sector in the system partition (this makes easier to restore the old one).
- fslist.c/.h, usetup.h: Fix header inclusion order.
- partlist.c/.h, usetup.c: On BIOS-PC architectures, the system partition can be formatted in any FS as long as it is the active partition (on the contrary, on architectures where such system partition is required, it is formatted in FAT). We currently do not have write support for all FSes out there (apart for FAT until now), so do a "clever" "trick" to work around this problem: on initialized disks, find the active partition and check its FS. If we support write access to this FS then we're OK, otherwise we change the (active) system partition for the one on which we are going to install ReactOS (which is, by construction, formatted with a FS on which we support write access).
The MBR (resp. the VBR) of the disk (resp. of the system partition) are always saved into files, making easy for people to boot on them (using FreeLdr) or restoring them.
CORE-10898
svn path=/trunk/; revision=70837
2016-03-01 15:00:56 +00:00
Status = SaveBootSector ( SystemRootPath - > Buffer , DstPath , SECTORSIZE ) ;
2016-02-02 01:55:05 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
[USETUP]
- bootsup.c/.h, usetup.c: Save the old MBR sector in the system partition (this makes easier to restore the old one).
- fslist.c/.h, usetup.h: Fix header inclusion order.
- partlist.c/.h, usetup.c: On BIOS-PC architectures, the system partition can be formatted in any FS as long as it is the active partition (on the contrary, on architectures where such system partition is required, it is formatted in FAT). We currently do not have write support for all FSes out there (apart for FAT until now), so do a "clever" "trick" to work around this problem: on initialized disks, find the active partition and check its FS. If we support write access to this FS then we're OK, otherwise we change the (active) system partition for the one on which we are going to install ReactOS (which is, by construction, formatted with a FS on which we support write access).
The MBR (resp. the VBR) of the disk (resp. of the system partition) are always saved into files, making easy for people to boot on them (using FreeLdr) or restoring them.
CORE-10898
svn path=/trunk/; revision=70837
2016-03-01 15:00:56 +00:00
DPRINT1 ( " SaveBootSector() failed (Status %lx) \n " , Status ) ;
2016-02-02 01:55:05 +00:00
return Status ;
}
}
else
2011-07-20 17:54:28 +00:00
{
2017-06-08 02:43:51 +00:00
Status = CreateFreeLoaderIniForReactOS ( SystemRootPath - > Buffer , DestinationArcPath - > Buffer ) ;
2016-02-02 01:55:05 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " CreateFreeLoaderIniForReactOS() failed (Status %lx) \n " , Status ) ;
return Status ;
}
2011-07-20 17:54:28 +00:00
}
2016-02-02 01:55:05 +00:00
/* Install new bootsector on the disk */
2011-07-20 17:54:28 +00:00
if ( PartitionType = = PARTITION_FAT32 | |
2015-12-30 20:23:18 +00:00
PartitionType = = PARTITION_FAT32_XINT13 )
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
/* Install FAT32 bootcode */
2017-05-23 22:30:54 +00:00
CombinePaths ( SrcPath , ARRAYSIZE ( SrcPath ) , 2 , SourceRootPath - > Buffer , L " \\ loader \\ fat32.bin " ) ;
2011-07-20 17:54:28 +00:00
DPRINT1 ( " Install FAT32 bootcode: %S ==> %S \n " , SrcPath , SystemRootPath - > Buffer ) ;
2016-02-02 01:55:05 +00:00
Status = InstallFat32BootCodeToDisk ( SrcPath , SystemRootPath - > Buffer ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat32BootCodeToDisk() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
else
{
2016-02-02 01:55:05 +00:00
/* Install FAT16 bootcode */
2017-05-23 22:30:54 +00:00
CombinePaths ( SrcPath , ARRAYSIZE ( SrcPath ) , 2 , SourceRootPath - > Buffer , L " \\ loader \\ fat.bin " ) ;
2011-07-20 17:54:28 +00:00
2016-02-02 01:55:05 +00:00
DPRINT1 ( " Install FAT16 bootcode: %S ==> %S \n " , SrcPath , SystemRootPath - > Buffer ) ;
Status = InstallFat16BootCodeToDisk ( SrcPath , SystemRootPath - > Buffer ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat16BootCodeToDisk() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
}
}
2016-02-02 01:55:05 +00:00
return STATUS_SUCCESS ;
}
static
NTSTATUS
2018-06-13 23:30:06 +00:00
InstallBtrfsBootcodeToPartition (
2016-02-02 01:55:05 +00:00
PUNICODE_STRING SystemRootPath ,
PUNICODE_STRING SourceRootPath ,
PUNICODE_STRING DestinationArcPath ,
UCHAR PartitionType )
{
NTSTATUS Status ;
BOOLEAN DoesFreeLdrExist ;
WCHAR SrcPath [ MAX_PATH ] ;
WCHAR DstPath [ MAX_PATH ] ;
2018-06-13 23:30:06 +00:00
/* BTRFS partition */
2016-02-02 01:55:05 +00:00
DPRINT ( " System path: '%wZ' \n " , SystemRootPath ) ;
2017-05-31 01:43:12 +00:00
/* Copy FreeLoader to the system partition, always overwriting the older version */
2017-05-23 22:30:54 +00:00
CombinePaths ( SrcPath , ARRAYSIZE ( SrcPath ) , 2 , SourceRootPath - > Buffer , L " \\ loader \\ freeldr.sys " ) ;
2017-05-31 01:43:12 +00:00
CombinePaths ( DstPath , ARRAYSIZE ( DstPath ) , 2 , SystemRootPath - > Buffer , L " freeldr.sys " ) ;
2016-02-02 01:55:05 +00:00
DPRINT ( " Copy: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = SetupCopyFile ( SrcPath , DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
DPRINT1 ( " SetupCopyFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
2011-07-20 17:54:28 +00:00
2017-06-08 02:43:51 +00:00
/* Prepare for possibly updating 'freeldr.ini' */
DoesFreeLdrExist = DoesFileExist_2 ( SystemRootPath - > Buffer , L " freeldr.ini " ) ;
2016-02-02 01:55:05 +00:00
if ( DoesFreeLdrExist )
{
/* Update existing 'freeldr.ini' */
DPRINT1 ( " Update existing 'freeldr.ini' \n " ) ;
2017-06-08 02:43:51 +00:00
Status = UpdateFreeLoaderIni ( SystemRootPath - > Buffer , DestinationArcPath - > Buffer ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2016-02-02 01:55:05 +00:00
DPRINT1 ( " UpdateFreeLoaderIni() failed (Status %lx) \n " , Status ) ;
2011-07-20 17:54:28 +00:00
return Status ;
}
2016-02-02 01:55:05 +00:00
}
2011-07-20 17:54:28 +00:00
2016-02-02 01:55:05 +00:00
/* Check for *nix bootloaders */
/* Create or update 'freeldr.ini' */
if ( DoesFreeLdrExist = = FALSE )
{
/* Create new 'freeldr.ini' */
DPRINT1 ( " Create new 'freeldr.ini' \n " ) ;
/* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
DPRINT1 ( " *nix or unknown boot loader found \n " ) ;
2011-07-20 17:54:28 +00:00
2016-02-02 01:55:05 +00:00
if ( IsThereAValidBootSector ( SystemRootPath - > Buffer ) )
{
2017-05-31 01:43:12 +00:00
PCWSTR BootSector = L " BOOTSECT.OLD " ;
2016-02-02 01:55:05 +00:00
Status = CreateFreeLoaderIniForReactOSAndBootSector (
2017-06-08 02:43:51 +00:00
SystemRootPath - > Buffer , DestinationArcPath - > Buffer ,
2016-02-02 01:55:05 +00:00
L " Linux " , L " \" Linux \" " ,
2017-05-31 01:43:12 +00:00
L " hd0 " , L " 1 " , BootSector ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2016-02-02 01:55:05 +00:00
DPRINT1 ( " CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx) \n " , Status ) ;
2011-07-20 17:54:28 +00:00
return Status ;
}
2016-02-02 01:55:05 +00:00
/* Save current bootsector */
2017-05-31 01:43:12 +00:00
CombinePaths ( DstPath , ARRAYSIZE ( DstPath ) , 2 , SystemRootPath - > Buffer , BootSector ) ;
2011-07-20 17:54:28 +00:00
2016-02-02 01:55:05 +00:00
DPRINT1 ( " Save bootsector: %S ==> %S \n " , SystemRootPath - > Buffer , DstPath ) ;
2018-06-13 23:30:06 +00:00
Status = SaveBootSector ( SystemRootPath - > Buffer , DstPath , sizeof ( BTRFS_BOOTSECTOR ) ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
[USETUP]
- bootsup.c/.h, usetup.c: Save the old MBR sector in the system partition (this makes easier to restore the old one).
- fslist.c/.h, usetup.h: Fix header inclusion order.
- partlist.c/.h, usetup.c: On BIOS-PC architectures, the system partition can be formatted in any FS as long as it is the active partition (on the contrary, on architectures where such system partition is required, it is formatted in FAT). We currently do not have write support for all FSes out there (apart for FAT until now), so do a "clever" "trick" to work around this problem: on initialized disks, find the active partition and check its FS. If we support write access to this FS then we're OK, otherwise we change the (active) system partition for the one on which we are going to install ReactOS (which is, by construction, formatted with a FS on which we support write access).
The MBR (resp. the VBR) of the disk (resp. of the system partition) are always saved into files, making easy for people to boot on them (using FreeLdr) or restoring them.
CORE-10898
svn path=/trunk/; revision=70837
2016-03-01 15:00:56 +00:00
DPRINT1 ( " SaveBootSector() failed (Status %lx) \n " , Status ) ;
2011-07-20 17:54:28 +00:00
return Status ;
}
2016-02-02 01:55:05 +00:00
}
else
{
2017-06-08 02:43:51 +00:00
Status = CreateFreeLoaderIniForReactOS ( SystemRootPath - > Buffer , DestinationArcPath - > Buffer ) ;
2016-02-02 01:55:05 +00:00
if ( ! NT_SUCCESS ( Status ) )
2011-07-20 17:54:28 +00:00
{
2016-02-02 01:55:05 +00:00
DPRINT1 ( " CreateFreeLoaderIniForReactOS() failed (Status %lx) \n " , Status ) ;
return Status ;
2011-07-20 17:54:28 +00:00
}
}
2016-02-02 01:55:05 +00:00
/* Install new bootsector on the disk */
// if (PartitionType == PARTITION_EXT2)
2011-07-20 17:54:28 +00:00
{
2018-06-13 23:30:06 +00:00
/* Install BTRFS bootcode */
CombinePaths ( SrcPath , ARRAYSIZE ( SrcPath ) , 2 , SourceRootPath - > Buffer , L " \\ loader \\ btrfs.bin " ) ;
2011-07-20 17:54:28 +00:00
2018-06-13 23:30:06 +00:00
DPRINT1 ( " Install BTRFS bootcode: %S ==> %S \n " , SrcPath , SystemRootPath - > Buffer ) ;
Status = InstallBtrfsBootCodeToDisk ( SrcPath , SystemRootPath - > Buffer ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2018-06-13 23:30:06 +00:00
DPRINT1 ( " InstallBtrfsBootCodeToDisk() failed (Status %lx) \n " , Status ) ;
2011-07-20 17:54:28 +00:00
return Status ;
}
}
}
return STATUS_SUCCESS ;
2004-06-23 14:09:55 +00:00
}
2014-05-12 14:17:37 +00:00
2010-09-05 17:09:18 +00:00
NTSTATUS
2011-07-20 17:54:28 +00:00
InstallVBRToPartition (
PUNICODE_STRING SystemRootPath ,
PUNICODE_STRING SourceRootPath ,
PUNICODE_STRING DestinationArcPath ,
UCHAR PartitionType )
2010-09-05 17:09:18 +00:00
{
2016-02-02 01:55:05 +00:00
switch ( PartitionType )
{
case PARTITION_FAT_12 :
case PARTITION_FAT_16 :
case PARTITION_HUGE :
case PARTITION_XINT13 :
case PARTITION_FAT32 :
case PARTITION_FAT32_XINT13 :
{
return InstallFatBootcodeToPartition ( SystemRootPath ,
SourceRootPath ,
DestinationArcPath ,
PartitionType ) ;
}
2018-06-13 23:30:06 +00:00
case PARTITION_LINUX :
2016-02-02 01:55:05 +00:00
{
2018-06-13 23:30:06 +00:00
return InstallBtrfsBootcodeToPartition ( SystemRootPath ,
SourceRootPath ,
DestinationArcPath ,
PartitionType ) ;
2016-02-02 01:55:05 +00:00
}
case PARTITION_IFS :
2017-05-31 01:43:12 +00:00
DPRINT1 ( " Partitions of type NTFS or HPFS are not supported yet! \n " ) ;
2016-02-02 01:55:05 +00:00
break ;
default :
2016-02-27 20:49:17 +00:00
DPRINT1 ( " PartitionType 0x%02X unknown! \n " , PartitionType ) ;
2016-02-02 01:55:05 +00:00
break ;
2010-09-05 17:09:18 +00:00
}
2011-06-29 20:27:07 +00:00
2010-09-05 17:09:18 +00:00
return STATUS_UNSUCCESSFUL ;
}
2004-06-23 14:09:55 +00:00
NTSTATUS
2011-07-20 17:54:28 +00:00
InstallFatBootcodeToFloppy (
PUNICODE_STRING SourceRootPath ,
PUNICODE_STRING DestinationArcPath )
2004-06-23 14:09:55 +00:00
{
2016-02-02 01:55:05 +00:00
NTSTATUS Status ;
[SETUPLIB][USETUP] Introduce a 'SetupLib' library. CORE-13544
- Create the beginnings of a "setuplib" library, whose aim is to be shared between the (currently existing) 1st-stage text-mode installer, and the (future) 1st-stage GUI installer.
- Finish to split the GenList and PartList codes into their UI part, which remain in usetup, and their algorithmic part, which go into setuplib.
- Move SetMountedDeviceValue into the PartList module.
- Split the FileSystem list code into its UI and the algorithmic part (which goes into setuplib under the name fsutil.c).
* The algo part is meant to be able to manage the filesystems available on the running system, similarly to what is mostly done (in scattered form) in fmifs, format, chkdsk / autochk codes...
It also manages the partition filesystem recognition, using OS routines.
* The UI part manages the FS list as it appears on screen, showing only the possible FSes that can be used to format the selected partition (a bit similar to what we do in the shell32's drive.c, etc...).
- Adapt the calling code to these changes.
- Remove some "host" code that was dating back from the dark old times.
svn path=/branches/setup_improvements/; revision=74570
svn path=/branches/setup_improvements/; revision=74659
2017-05-17 23:37:41 +00:00
PFILE_SYSTEM FatFS ;
2017-05-31 01:43:12 +00:00
UNICODE_STRING FloppyDevice = RTL_CONSTANT_STRING ( L " \\ Device \\ Floppy0 \\ " ) ;
2011-07-20 17:54:28 +00:00
WCHAR SrcPath [ MAX_PATH ] ;
WCHAR DstPath [ MAX_PATH ] ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
/* Format the floppy first */
[SETUPLIB][USETUP] Introduce a 'SetupLib' library. CORE-13544
- Create the beginnings of a "setuplib" library, whose aim is to be shared between the (currently existing) 1st-stage text-mode installer, and the (future) 1st-stage GUI installer.
- Finish to split the GenList and PartList codes into their UI part, which remain in usetup, and their algorithmic part, which go into setuplib.
- Move SetMountedDeviceValue into the PartList module.
- Split the FileSystem list code into its UI and the algorithmic part (which goes into setuplib under the name fsutil.c).
* The algo part is meant to be able to manage the filesystems available on the running system, similarly to what is mostly done (in scattered form) in fmifs, format, chkdsk / autochk codes...
It also manages the partition filesystem recognition, using OS routines.
* The UI part manages the FS list as it appears on screen, showing only the possible FSes that can be used to format the selected partition (a bit similar to what we do in the shell32's drive.c, etc...).
- Adapt the calling code to these changes.
- Remove some "host" code that was dating back from the dark old times.
svn path=/branches/setup_improvements/; revision=74570
svn path=/branches/setup_improvements/; revision=74659
2017-05-17 23:37:41 +00:00
FatFS = GetFileSystemByName ( L " FAT " ) ;
if ( ! FatFS )
{
DPRINT1 ( " FAT FS non existent on this system?! \n " ) ;
return STATUS_NOT_SUPPORTED ;
}
Status = FatFS - > FormatFunc ( & FloppyDevice ,
FMIFS_FLOPPY ,
NULL ,
TRUE ,
0 ,
NULL ) ;
2011-10-29 15:10:11 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " VfatFormat() failed (Status %lx) \n " , Status ) ;
return Status ;
}
2004-06-23 14:09:55 +00:00
2011-07-20 17:54:28 +00:00
/* Copy FreeLoader to the boot partition */
2017-05-23 22:30:54 +00:00
CombinePaths ( SrcPath , ARRAYSIZE ( SrcPath ) , 2 , SourceRootPath - > Buffer , L " \\ loader \\ freeldr.sys " ) ;
2017-05-31 01:43:12 +00:00
CombinePaths ( DstPath , ARRAYSIZE ( DstPath ) , 2 , FloppyDevice . Buffer , L " freeldr.sys " ) ;
2004-06-23 14:09:55 +00:00
2011-07-20 17:54:28 +00:00
DPRINT ( " Copy: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = SetupCopyFile ( SrcPath , DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
2004-06-23 14:09:55 +00:00
{
2011-07-20 17:54:28 +00:00
DPRINT1 ( " SetupCopyFile() failed (Status %lx) \n " , Status ) ;
return Status ;
2004-06-23 14:09:55 +00:00
}
2011-07-20 17:54:28 +00:00
/* Create new 'freeldr.ini' */
DPRINT ( " Create new 'freeldr.ini' \n " ) ;
2017-06-08 02:43:51 +00:00
Status = CreateFreeLoaderIniForReactOS ( FloppyDevice . Buffer , DestinationArcPath - > Buffer ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
2004-06-23 14:09:55 +00:00
{
2015-04-18 09:21:51 +00:00
DPRINT1 ( " CreateFreeLoaderIniForReactOS() failed (Status %lx) \n " , Status ) ;
2011-07-20 17:54:28 +00:00
return Status ;
2004-06-23 14:09:55 +00:00
}
2017-05-31 01:43:12 +00:00
/* Install FAT12 boosector */
2017-05-23 22:30:54 +00:00
CombinePaths ( SrcPath , ARRAYSIZE ( SrcPath ) , 2 , SourceRootPath - > Buffer , L " \\ loader \\ fat.bin " ) ;
2017-06-08 02:43:51 +00:00
CombinePaths ( DstPath , ARRAYSIZE ( DstPath ) , 1 , FloppyDevice . Buffer ) ;
2004-06-23 14:09:55 +00:00
2011-07-20 17:54:28 +00:00
DPRINT ( " Install FAT bootcode: %S ==> %S \n " , SrcPath , DstPath ) ;
2011-10-29 15:10:11 +00:00
Status = InstallFat12BootCodeToFloppy ( SrcPath , DstPath ) ;
2011-07-20 17:54:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
2004-06-23 14:09:55 +00:00
{
2017-05-31 01:43:12 +00:00
DPRINT1 ( " InstallFat12BootCodeToFloppy() failed (Status %lx) \n " , Status ) ;
2011-07-20 17:54:28 +00:00
return Status ;
2004-06-23 14:09:55 +00:00
}
2011-07-20 17:54:28 +00:00
return STATUS_SUCCESS ;
2004-06-23 14:09:55 +00:00
}
2003-01-30 17:37:13 +00:00
/* EOF */