2003-01-17 13:18:15 +00:00
/*
* COPYRIGHT : See COPYING in the top level directory
* PROJECT : ReactOS text - mode setup
* FILE : subsys / system / usetup / bootsup . c
* PURPOSE : Bootloader support functions
* PROGRAMMER : Eric Kohl
*/
2006-08-31 09:13:03 +00:00
# include "usetup.h"
2003-01-17 13:18:15 +00:00
2010-06-07 21:38:49 +00:00
# define NDEBUG
2003-12-01 18:28:54 +00:00
# include <debug.h>
2003-01-17 13:18:15 +00:00
2003-01-28 17:29:22 +00:00
# define SECTORSIZE 512
2010-09-06 01:46:06 +00:00
# include <pshpack1.h>
typedef struct _FAT_BOOTSECTOR
{
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 ;
# include <poppack.h>
extern PPARTLIST PartitionList ;
2003-01-17 13:18:15 +00:00
/* FUNCTIONS ****************************************************************/
2011-07-20 17:54:28 +00:00
static
VOID
2014-05-12 14:17:37 +00:00
CreateCommonFreeLoaderSections (
PINICACHE IniCache )
2003-01-17 13:18:15 +00:00
{
2011-07-20 17:54:28 +00:00
PINICACHESECTION IniSection ;
2003-01-17 13:18:15 +00:00
2011-07-20 17:54:28 +00:00
/* Create "FREELOADER" section */
IniSection = IniCacheAppendSection ( IniCache ,
L " FREELOADER " ) ;
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 */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " DefaultOS " ,
2011-11-19 22:50:04 +00:00
# ifndef _WINKD_
2011-07-20 17:54:28 +00:00
L " ReactOS_KdSerial " ) ;
2011-11-19 22:50:04 +00:00
# else
L " ReactOS_Debug " ) ;
# 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 */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " DefaultOS " ,
L " ReactOS " ) ;
}
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
{
/* Timeout=0 for unattended or non debug*/
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " TimeOut " ,
L " 0 " ) ;
}
2009-06-17 12:44:05 +00:00
# if DBG
2011-07-20 17:54:28 +00:00
else
{
/* Timeout=0 or 10 */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " TimeOut " ,
L " 10 " ) ;
}
2006-04-25 01:31:00 +00:00
# endif
2003-01-17 13:18:15 +00:00
2011-07-20 17:54:28 +00:00
/* Create "Display" section */
IniSection = IniCacheAppendSection ( IniCache , L " Display " ) ;
/* TitleText=ReactOS Boot Manager */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " TitleText " ,
L " ReactOS Boot Manager " ) ;
/* StatusBarColor=Cyan */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " StatusBarColor " ,
L " Cyan " ) ;
/* StatusBarTextColor=Black */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " StatusBarTextColor " ,
L " Black " ) ;
/* BackdropTextColor=White */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BackdropTextColor " ,
L " White " ) ;
/* BackdropColor=Blue */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BackdropColor " ,
L " Blue " ) ;
/* BackdropFillStyle=Medium */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BackdropFillStyle " ,
L " Medium " ) ;
/* TitleBoxTextColor=White */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " TitleBoxTextColor " ,
L " White " ) ;
/* TitleBoxColor=Red */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " TitleBoxColor " ,
L " Red " ) ;
/* MessageBoxTextColor=White */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " MessageBoxTextColor " ,
L " White " ) ;
/* MessageBoxColor=Blue */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " MessageBoxColor " ,
L " Blue " ) ;
/* MenuTextColor=White */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " MenuTextColor " ,
L " Gray " ) ;
/* MenuColor=Blue */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " MenuColor " ,
L " Black " ) ;
/* TextColor=Yellow */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " TextColor " ,
L " Gray " ) ;
/* SelectedTextColor=Black */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " SelectedTextColor " ,
L " Black " ) ;
/* SelectedColor=Gray */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " SelectedColor " ,
L " Gray " ) ;
2006-10-09 04:00:34 +00:00
/* SelectedColor=Gray */
2011-07-20 17:54:28 +00:00
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " ShowTime " ,
L " No " ) ;
/* SelectedColor=Gray */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " MenuBox " ,
L " No " ) ;
2006-10-09 04:00:34 +00:00
/* SelectedColor=Gray */
2011-07-20 17:54:28 +00:00
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " CenterMenu " ,
L " No " ) ;
2006-10-09 04:00:34 +00:00
/* SelectedColor=Gray */
2011-07-20 17:54:28 +00:00
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " MinimalUI " ,
L " Yes " ) ;
2006-10-09 04:00:34 +00:00
/* SelectedColor=Gray */
2011-07-20 17:54:28 +00:00
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " TimeText " ,
L " Seconds until highlighted choice will be started automatically: " ) ;
2003-01-17 13:18:15 +00:00
}
NTSTATUS
2011-07-20 17:54:28 +00:00
CreateFreeLoaderIniForDos (
PWCHAR IniPath ,
PWCHAR ArcPath )
2003-01-17 13:18:15 +00:00
{
2011-07-20 17:54:28 +00:00
PINICACHE IniCache ;
PINICACHESECTION IniSection ;
IniCache = IniCacheCreate ( ) ;
CreateCommonFreeLoaderSections ( IniCache ) ;
/* Create "Operating Systems" section */
IniSection = IniCacheAppendSection ( IniCache , L " Operating Systems " ) ;
/* REACTOS=ReactOS */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " ReactOS " ,
L " \" ReactOS \" " ) ;
/* ReactOS_Debug="ReactOS (Debug)" */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " ReactOS_Debug " ,
L " \" ReactOS (Debug) \" " ) ;
/* DOS=Dos/Windows */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " DOS " ,
L " \" DOS/Windows \" " ) ;
/* Create "ReactOS" section */
IniSection = IniCacheAppendSection ( IniCache , L " ReactOS " ) ;
/* BootType=ReactOS */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BootType " ,
L " ReactOS " ) ;
/* SystemPath=<ArcPath> */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " SystemPath " ,
ArcPath ) ;
/* Create "ReactOS_Debug" section */
IniSection = IniCacheAppendSection ( IniCache , L " ReactOS_Debug " ) ;
/* BootType=ReactOS */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BootType " ,
L " ReactOS " ) ;
/* SystemPath=<ArcPath> */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " SystemPath " ,
ArcPath ) ;
/* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " Options " ,
L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS " ) ;
/* Create "DOS" section */
IniSection = IniCacheAppendSection ( IniCache ,
L " DOS " ) ;
/* BootType=BootSector */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BootType " ,
L " BootSector " ) ;
/* BootDrive=hd0 */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BootDrive " ,
L " hd0 " ) ;
/* BootPartition=1 */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BootPartition " ,
L " 1 " ) ;
/* BootSector=BOOTSECT.DOS */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BootSectorFile " ,
L " BOOTSECT.DOS " ) ;
IniCacheSave ( IniCache , IniPath ) ;
IniCacheDestroy ( IniCache ) ;
return STATUS_SUCCESS ;
2003-01-17 13:18:15 +00:00
}
2003-01-28 17:29:22 +00:00
2009-10-03 19:43:29 +00:00
NTSTATUS
CreateFreeLoaderEntry (
PINICACHE IniCache ,
PINICACHESECTION OSSection ,
PWCHAR Section ,
PWCHAR Description ,
PWCHAR BootType ,
PWCHAR ArcPath ,
PWCHAR Options )
{
PINICACHESECTION IniSection ;
/* Insert entry into "Operating Systems" section */
IniCacheInsertKey ( OSSection ,
2011-07-20 17:54:28 +00:00
NULL ,
INSERT_LAST ,
Section ,
Description ) ;
2009-10-03 19:43:29 +00:00
/* Create new section */
IniSection = IniCacheAppendSection ( IniCache , Section ) ;
/* BootType= */
IniCacheInsertKey ( IniSection ,
2011-07-20 17:54:28 +00:00
NULL ,
INSERT_LAST ,
L " BootType " ,
BootType ) ;
2009-10-03 19:43:29 +00:00
/* SystemPath= */
IniCacheInsertKey ( IniSection ,
2011-07-20 17:54:28 +00:00
NULL ,
INSERT_LAST ,
L " SystemPath " ,
ArcPath ) ;
2009-10-03 19:43:29 +00:00
/* Options=*/
IniCacheInsertKey ( IniSection ,
2011-07-20 17:54:28 +00:00
NULL ,
INSERT_LAST ,
L " Options " ,
Options ) ;
2009-10-03 19:43:29 +00:00
return STATUS_SUCCESS ;
}
2003-01-28 17:29:22 +00:00
NTSTATUS
2011-07-20 17:54:28 +00:00
CreateFreeLoaderIniForReactos (
PWCHAR IniPath ,
PWCHAR ArcPath )
2003-01-28 17:29:22 +00:00
{
2011-07-20 17:54:28 +00:00
PINICACHE IniCache ;
PINICACHESECTION IniSection ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
IniCache = IniCacheCreate ( ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
CreateCommonFreeLoaderSections ( IniCache ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
/* Create "Operating Systems" section */
IniSection = IniCacheAppendSection ( IniCache , L " Operating Systems " ) ;
2003-01-28 17:29:22 +00:00
2009-10-03 19:43:29 +00:00
/* ReactOS */
CreateFreeLoaderEntry ( IniCache , IniSection ,
2011-07-20 17:54:28 +00:00
L " ReactOS " , L " \" ReactOS \" " ,
L " Windows2003 " , ArcPath ,
L " " ) ;
2003-01-28 17:29:22 +00:00
2009-10-03 19:43:29 +00:00
/* ReactOS_Debug */
CreateFreeLoaderEntry ( IniCache , IniSection ,
2011-07-20 17:54:28 +00:00
L " ReactOS_Debug " , L " \" ReactOS (Debug) \" " ,
L " Windows2003 " , ArcPath ,
L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS " ) ;
2003-01-28 17:29:22 +00:00
2009-06-17 12:44:05 +00:00
# if DBG
2011-07-12 00:27:22 +00:00
# ifndef _WINKD_
2009-10-03 19:43:29 +00:00
/* ReactOS_KdSerial */
CreateFreeLoaderEntry ( IniCache , IniSection ,
2011-07-20 17:54:28 +00:00
L " ReactOS_KdSerial " , L " \" ReactOS (RosDbg) \" " ,
L " Windows2003 " , ArcPath ,
L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL " ) ;
2011-07-12 00:27:22 +00:00
# endif
2009-10-03 19:43:29 +00:00
2011-11-21 05:28:08 +00:00
/* ReactOS_Screen */
CreateFreeLoaderEntry ( IniCache , IniSection ,
L " ReactOS_Screen " , L " \" ReactOS (Screen) \" " ,
L " Windows2003 " , ArcPath ,
L " /DEBUG /DEBUGPORT=SCREEN /SOS " ) ;
2009-10-07 19:58:15 +00:00
/* ReactOS_LogFile */
CreateFreeLoaderEntry ( IniCache , IniSection ,
2011-07-20 17:54:28 +00:00
L " ReactOS_LogFile " , L " \" ReactOS (Log file) \" " ,
L " Windows2003 " , ArcPath ,
L " /DEBUG /DEBUGPORT=FILE /SOS " ) ;
2009-10-07 19:58:15 +00:00
2009-10-03 19:43:29 +00:00
/* ReactOS_Ram */
CreateFreeLoaderEntry ( IniCache , IniSection ,
2011-07-20 17:54:28 +00:00
L " ReactOS_Ram " , L " \" ReactOS (RAM Disk) \" " ,
2013-08-13 03:11:02 +00:00
L " Windows2003 " , L " ramdisk(0) \\ ReactOS " ,
2011-07-20 17:54:28 +00:00
L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256 " ) ;
2013-08-13 03:11:02 +00:00
/* ReactOS_EMS */
CreateFreeLoaderEntry ( IniCache , IniSection ,
L " ReactOS_EMS " , L " \" ReactOS (Emergency Management Services) \" " ,
L " Windows2003 " , ArcPath ,
L " /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200 " ) ;
2008-06-01 19:15:15 +00:00
# endif
2008-02-27 20:13:34 +00:00
2011-07-20 17:54:28 +00:00
/* Save the ini file */
IniCacheSave ( IniCache , IniPath ) ;
IniCacheDestroy ( IniCache ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
return STATUS_SUCCESS ;
2003-01-30 14:41:45 +00:00
}
NTSTATUS
2011-07-20 17:54:28 +00:00
UpdateFreeLoaderIni (
PWCHAR IniPath ,
PWCHAR ArcPath )
2003-01-30 14:41:45 +00:00
{
2011-07-20 17:54:28 +00:00
UNICODE_STRING Name ;
PINICACHE IniCache ;
PINICACHESECTION IniSection ;
PINICACHESECTION OsIniSection ;
WCHAR SectionName [ 80 ] ;
WCHAR OsName [ 80 ] ;
WCHAR SystemPath [ 200 ] ;
WCHAR SectionName2 [ 200 ] ;
PWCHAR KeyData ;
ULONG i , j ;
NTSTATUS Status ;
RtlInitUnicodeString ( & Name , IniPath ) ;
Status = IniCacheLoad ( & IniCache , & Name , FALSE ) ;
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
2011-07-20 17:54:28 +00:00
/* Get "Operating Systems" section */
IniSection = IniCacheGetSection ( IniCache , L " Operating Systems " ) ;
if ( IniSection = = NULL )
2004-03-10 16:57:36 +00:00
{
2011-07-20 17:54:28 +00:00
IniCacheDestroy ( IniCache ) ;
return STATUS_UNSUCCESSFUL ;
2004-03-10 16:57:36 +00:00
}
2011-07-20 17:54:28 +00:00
/* Find an existing usable or an unused section name */
i = 1 ;
wcscpy ( SectionName , L " ReactOS " ) ;
wcscpy ( OsName , L " \" ReactOS \" " ) ;
while ( TRUE )
2004-03-10 16:57:36 +00:00
{
2011-07-20 17:54:28 +00:00
Status = IniCacheGetKey ( IniSection , SectionName , & KeyData ) ;
if ( ! NT_SUCCESS ( Status ) )
break ;
2004-03-10 16:57:36 +00:00
2011-07-20 17:54:28 +00:00
/* Get operation system section */
if ( KeyData [ 0 ] = = ' " ' )
2004-03-10 16:57:36 +00:00
{
2011-07-20 17:54:28 +00:00
wcscpy ( SectionName2 , & KeyData [ 1 ] ) ;
j = wcslen ( SectionName2 ) ;
if ( j > 0 )
{
SectionName2 [ j - 1 ] = 0 ;
}
2004-03-10 16:57:36 +00:00
}
else
{
2011-07-20 17:54:28 +00:00
wcscpy ( SectionName2 , KeyData ) ;
2004-03-10 16:57:36 +00:00
}
2011-07-20 17:54:28 +00:00
OsIniSection = IniCacheGetSection ( IniCache , SectionName2 ) ;
if ( OsIniSection ! = NULL )
{
BOOLEAN UseExistingEntry = TRUE ;
/* Check BootType */
Status = IniCacheGetKey ( OsIniSection , L " BootType " , & KeyData ) ;
if ( NT_SUCCESS ( Status ) )
{
if ( ( KeyData = = NULL ) | |
( ( _wcsicmp ( KeyData , L " ReactOS " ) ! = 0 ) & &
( _wcsicmp ( KeyData , L " \" ReactOS \" " ) ! = 0 ) ) )
{
/* This is not a ReactOS entry */
UseExistingEntry = FALSE ;
}
}
else
{
UseExistingEntry = FALSE ;
}
if ( UseExistingEntry )
{
/* BootType is ReactOS. Now check SystemPath */
Status = IniCacheGetKey ( OsIniSection , L " SystemPath " , & KeyData ) ;
if ( NT_SUCCESS ( Status ) )
{
swprintf ( SystemPath , L " \" %S \" " , ArcPath ) ;
if ( ( KeyData = = NULL ) | |
( ( _wcsicmp ( KeyData , ArcPath ) ! = 0 ) & &
( _wcsicmp ( KeyData , SystemPath ) ! = 0 ) ) )
{
/* This entry is a ReactOS entry, but the SystemRoot does not
match the one we are looking for */
UseExistingEntry = FALSE ;
}
}
else
{
UseExistingEntry = FALSE ;
}
}
if ( UseExistingEntry )
{
IniCacheDestroy ( IniCache ) ;
return STATUS_SUCCESS ;
}
}
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
swprintf ( SectionName , L " ReactOS_%lu " , i ) ;
swprintf ( OsName , L " \" ReactOS %lu \" " , i ) ;
i + + ;
}
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
/* <SectionName>=<OsName> */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
SectionName ,
OsName ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
/* Create <SectionName> section */
IniSection = IniCacheAppendSection ( IniCache , SectionName ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
/* BootType=ReactOS */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " BootType " ,
L " ReactOS " ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
/* SystemPath=<ArcPath> */
IniCacheInsertKey ( IniSection ,
NULL ,
INSERT_LAST ,
L " SystemPath " ,
ArcPath ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
IniCacheSave ( IniCache , IniPath ) ;
IniCacheDestroy ( IniCache ) ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
return STATUS_SUCCESS ;
2003-01-28 17:29:22 +00:00
}
2003-04-05 15:36:34 +00:00
NTSTATUS
2011-07-20 17:54:28 +00:00
SaveCurrentBootSector (
PWSTR RootPath ,
PWSTR DstPath )
2003-04-05 15:36:34 +00:00
{
2010-09-06 01:46:06 +00:00
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
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 */
BootSector = RtlAllocateHeap ( ProcessHeap , 0 , SECTORSIZE ) ;
if ( BootSector = = NULL )
return STATUS_INSUFFICIENT_RESOURCES ;
2003-04-05 15:36:34 +00:00
2010-09-06 01:46:06 +00:00
/* Read current boot sector into buffer */
2011-07-20 17:54:28 +00:00
RtlInitUnicodeString ( & Name , RootPath ) ;
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
2010-09-06 01:46:06 +00:00
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
2011-07-20 17:54:28 +00:00
BootSector ,
2010-09-06 01:46:06 +00:00
SECTORSIZE ,
NULL ,
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 ,
SECTORSIZE ,
NULL ,
NULL ) ;
2003-01-28 17:29:22 +00:00
NtClose ( FileHandle ) ;
2011-07-20 17:54:28 +00:00
/* Free the new boot sector */
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
2011-07-20 17:54:28 +00:00
InstallFat16BootCodeToFile (
PWSTR SrcPath ,
PWSTR DstPath ,
PWSTR RootPath )
2003-01-28 17:29:22 +00:00
{
2011-07-20 17:54:28 +00:00
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
PFAT_BOOTSECTOR OrigBootSector ;
PFAT_BOOTSECTOR NewBootSector ;
2003-01-28 17:29:22 +00:00
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 ;
2003-01-28 17:29:22 +00:00
2011-07-20 17:54:28 +00:00
/* Read current boot sector into buffer */
RtlInitUnicodeString ( & Name , RootPath ) ;
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
2011-07-20 17:54:28 +00:00
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
NULL ,
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 */
NewBootSector = RtlAllocateHeap ( ProcessHeap , 0 , SECTORSIZE ) ;
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 ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
/* Adjust bootsector (copy a part of the FAT BPB) */
memcpy ( & NewBootSector - > OemName ,
& OrigBootSector - > OemName ,
2011-07-20 19:56:58 +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 ) ;
/* Write new bootsector to DstPath */
RtlInitUnicodeString ( & Name , DstPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
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_OVERWRITE_IF ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ,
NULL ,
0 ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
#if 0
FilePosition . QuadPart = 0 ;
# endif
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
NTSTATUS
InstallFat32BootCodeToFile (
PWSTR SrcPath ,
PWSTR DstPath ,
PWSTR RootPath )
{
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
PFAT32_BOOTSECTOR OrigBootSector ;
PFAT32_BOOTSECTOR NewBootSector ;
LARGE_INTEGER FileOffset ;
/* Allocate buffer for original bootsector */
OrigBootSector = RtlAllocateHeap ( ProcessHeap , 0 , SECTORSIZE ) ;
if ( OrigBootSector = = NULL )
return STATUS_INSUFFICIENT_RESOURCES ;
/* Read current boot sector into buffer */
RtlInitUnicodeString ( & Name , RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
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 ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return Status ;
}
/* Allocate buffer for new bootsector (2 sectors) */
NewBootSector = RtlAllocateHeap ( ProcessHeap , 0 , 2 * SECTORSIZE ) ;
if ( NewBootSector = = NULL )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return STATUS_INSUFFICIENT_RESOURCES ;
}
/* Read new bootsector from SrcPath */
RtlInitUnicodeString ( & Name , SrcPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
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 ,
2 * SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
/* Adjust bootsector (copy a part of the FAT32 BPB) */
memcpy ( & NewBootSector - > OemName ,
& OrigBootSector - > OemName ,
FIELD_OFFSET ( FAT32_BOOTSECTOR , BootCodeAndData ) -
FIELD_OFFSET ( FAT32_BOOTSECTOR , OemName ) ) ;
/* Disable the backup boot sector */
NewBootSector - > BackupBootSector = 0 ;
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
/* Write the first sector of the new bootcode to DstPath */
RtlInitUnicodeString ( & Name , DstPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
Status = NtCreateFile ( & FileHandle ,
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 ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
/* Write the second sector of the new bootcode to boot disk sector 14 */
RtlInitUnicodeString ( & Name , RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_WRITE | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
FileOffset . QuadPart = ( ULONGLONG ) ( 14 * SECTORSIZE ) ;
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
2011-10-31 07:32:00 +00:00
( ( PUCHAR ) NewBootSector + SECTORSIZE ) ,
2011-07-20 17:54:28 +00:00
SECTORSIZE ,
& FileOffset ,
NULL ) ;
if ( ! NT_SUCCESS ( Status ) )
{
}
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
NTSTATUS
InstallMbrBootCodeToDisk (
PWSTR SrcPath ,
PWSTR RootPath )
{
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
PPARTITION_SECTOR OrigBootSector ;
PPARTITION_SECTOR NewBootSector ;
/* Allocate buffer for original bootsector */
OrigBootSector = ( PPARTITION_SECTOR ) RtlAllocateHeap ( ProcessHeap ,
0 ,
sizeof ( PARTITION_SECTOR ) ) ;
if ( OrigBootSector = = NULL )
return STATUS_INSUFFICIENT_RESOURCES ;
/* Read current boot sector into buffer */
RtlInitUnicodeString ( & Name ,
RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
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 ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return Status ;
}
/* Allocate buffer for new bootsector */
NewBootSector = ( PPARTITION_SECTOR ) RtlAllocateHeap ( ProcessHeap ,
0 ,
sizeof ( PARTITION_SECTOR ) ) ;
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 ,
sizeof ( PARTITION_SECTOR ) ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
/* Copy partition table from old MBR to new */
RtlCopyMemory ( & NewBootSector - > Signature ,
& OrigBootSector - > Signature ,
sizeof ( PARTITION_SECTOR ) - offsetof ( PARTITION_SECTOR , Signature ) /* Length of partition table */ ) ;
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
/* Write new bootsector to RootPath */
RtlInitUnicodeString ( & Name , RootPath ) ;
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 ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
NTSTATUS
2014-05-12 14:17:37 +00:00
InstallFat12BootCodeToFloppy (
PWSTR SrcPath ,
PWSTR RootPath )
2011-10-29 15:10:11 +00:00
{
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
PFAT_BOOTSECTOR OrigBootSector ;
PFAT_BOOTSECTOR NewBootSector ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
/* Allocate buffer for original bootsector */
OrigBootSector = RtlAllocateHeap ( ProcessHeap , 0 , SECTORSIZE ) ;
if ( OrigBootSector = = NULL )
return STATUS_INSUFFICIENT_RESOURCES ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
/* Read current boot sector into buffer */
RtlInitUnicodeString ( & Name , RootPath ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_READ | SYNCHRONIZE ,
2011-10-29 15:10:11 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return Status ;
}
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return Status ;
}
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
/* Allocate buffer for new bootsector */
NewBootSector = RtlAllocateHeap ( ProcessHeap ,
0 ,
SECTORSIZE ) ;
if ( NewBootSector = = NULL )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return STATUS_INSUFFICIENT_RESOURCES ;
}
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
/* Read new bootsector from SrcPath */
RtlInitUnicodeString ( & Name , SrcPath ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_READ | SYNCHRONIZE ,
2011-10-29 15:10:11 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
/* Adjust bootsector (copy a part of the FAT16 BPB) */
memcpy ( & NewBootSector - > OemName ,
& OrigBootSector - > OemName ,
FIELD_OFFSET ( FAT_BOOTSECTOR , BootCodeAndData ) -
FIELD_OFFSET ( FAT_BOOTSECTOR , OemName ) ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
/* Write new bootsector to RootPath */
RtlInitUnicodeString ( & Name , RootPath ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
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 ) )
{
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
#if 0
FilePosition . QuadPart = 0 ;
# endif
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
return Status ;
}
2011-07-20 17:54:28 +00:00
NTSTATUS
InstallFat16BootCodeToDisk (
PWSTR SrcPath ,
PWSTR RootPath )
{
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
PFAT_BOOTSECTOR OrigBootSector ;
PFAT_BOOTSECTOR NewBootSector ;
/* Allocate buffer for original bootsector */
OrigBootSector = RtlAllocateHeap ( ProcessHeap , 0 , SECTORSIZE ) ;
if ( OrigBootSector = = NULL )
return STATUS_INSUFFICIENT_RESOURCES ;
/* Read current boot sector into buffer */
RtlInitUnicodeString ( & Name , RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
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 ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return Status ;
}
/* Allocate buffer for new bootsector */
NewBootSector = RtlAllocateHeap ( ProcessHeap ,
0 ,
SECTORSIZE ) ;
if ( NewBootSector = = NULL )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return STATUS_INSUFFICIENT_RESOURCES ;
}
/* Read new bootsector from SrcPath */
RtlInitUnicodeString ( & Name , SrcPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
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 ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
/* Adjust bootsector (copy a part of the FAT16 BPB) */
memcpy ( & NewBootSector - > OemName ,
& OrigBootSector - > OemName ,
2011-07-20 19:56:58 +00:00
FIELD_OFFSET ( FAT_BOOTSECTOR , BootCodeAndData ) -
FIELD_OFFSET ( FAT_BOOTSECTOR , OemName ) ) ;
2011-07-20 17:54:28 +00:00
2014-05-18 15:14:24 +00:00
NewBootSector - > HiddenSectors = PartitionList - > CurrentDisk - > SectorsPerTrack ;
2011-07-20 17:54:28 +00:00
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
/* Write new bootsector to RootPath */
RtlInitUnicodeString ( & Name , RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
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 ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
#if 0
FilePosition . QuadPart = 0 ;
# endif
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
NTSTATUS
InstallFat32BootCodeToDisk (
PWSTR SrcPath ,
PWSTR RootPath )
{
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
UNICODE_STRING Name ;
HANDLE FileHandle ;
NTSTATUS Status ;
PFAT32_BOOTSECTOR OrigBootSector ;
PFAT32_BOOTSECTOR NewBootSector ;
LARGE_INTEGER FileOffset ;
USHORT BackupBootSector ;
/* Allocate buffer for original bootsector */
OrigBootSector = RtlAllocateHeap ( ProcessHeap , 0 , SECTORSIZE ) ;
if ( OrigBootSector = = NULL )
return STATUS_INSUFFICIENT_RESOURCES ;
/* Read current boot sector into buffer */
RtlInitUnicodeString ( & Name , RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
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 ;
}
Status = NtReadFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
OrigBootSector ,
SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return Status ;
}
/* Allocate buffer for new bootsector (2 sectors) */
NewBootSector = RtlAllocateHeap ( ProcessHeap , 0 , 2 * SECTORSIZE ) ;
if ( NewBootSector = = NULL )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
return STATUS_INSUFFICIENT_RESOURCES ;
}
/* Read new bootsector from SrcPath */
RtlInitUnicodeString ( & Name , SrcPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
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 ,
2 * SECTORSIZE ,
NULL ,
NULL ) ;
NtClose ( FileHandle ) ;
if ( ! NT_SUCCESS ( Status ) )
{
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
/* Adjust bootsector (copy a part of the FAT32 BPB) */
memcpy ( & NewBootSector - > OemName ,
& OrigBootSector - > OemName ,
FIELD_OFFSET ( FAT32_BOOTSECTOR , BootCodeAndData ) -
FIELD_OFFSET ( FAT32_BOOTSECTOR , OemName ) ) ;
2014-05-18 15:14:24 +00:00
NewBootSector - > HiddenSectors = PartitionList - > CurrentDisk - > SectorsPerTrack ;
2011-07-20 17:54:28 +00:00
/* Get the location of the backup boot sector */
BackupBootSector = OrigBootSector - > BackupBootSector ;
/* Free the original boot sector */
RtlFreeHeap ( ProcessHeap , 0 , OrigBootSector ) ;
/* Write the first sector of the new bootcode to DstPath */
RtlInitUnicodeString ( & Name , RootPath ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
0 ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_WRITE | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& 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 ;
}
/* Write sector 0 */
FileOffset . QuadPart = 0ULL ;
Status = NtWriteFile ( FileHandle ,
NULL ,
NULL ,
NULL ,
& IoStatusBlock ,
NewBootSector ,
SECTORSIZE ,
& FileOffset ,
NULL ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtWriteFile() failed (Status %lx) \n " , Status ) ;
NtClose ( FileHandle ) ;
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
/* Write backup boot sector */
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 ) ;
}
NtClose ( FileHandle ) ;
/* Free the new boot sector */
RtlFreeHeap ( ProcessHeap , 0 , NewBootSector ) ;
return Status ;
}
static
NTSTATUS
UnprotectBootIni (
PWSTR FileName ,
PULONG Attributes )
{
UNICODE_STRING Name ;
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
FILE_BASIC_INFORMATION FileInfo ;
HANDLE FileHandle ;
NTSTATUS Status ;
RtlInitUnicodeString ( & Name , FileName ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( Status = = STATUS_NO_SUCH_FILE )
{
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
* Attributes = 0 ;
return STATUS_SUCCESS ;
}
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
Status = NtQueryInformationFile ( FileHandle ,
& IoStatusBlock ,
& FileInfo ,
sizeof ( FILE_BASIC_INFORMATION ) ,
FileBasicInformation ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtQueryInformationFile() failed (Status %lx) \n " , Status ) ;
NtClose ( FileHandle ) ;
return Status ;
}
* Attributes = FileInfo . FileAttributes ;
/* Delete attributes SYSTEM, HIDDEN and READONLY */
FileInfo . FileAttributes = FileInfo . FileAttributes &
~ ( FILE_ATTRIBUTE_SYSTEM |
FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_READONLY ) ;
Status = NtSetInformationFile ( FileHandle ,
& IoStatusBlock ,
& FileInfo ,
sizeof ( FILE_BASIC_INFORMATION ) ,
FileBasicInformation ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtSetInformationFile() failed (Status %lx) \n " , Status ) ;
}
NtClose ( FileHandle ) ;
return Status ;
}
static
NTSTATUS
ProtectBootIni (
PWSTR FileName ,
ULONG Attributes )
{
UNICODE_STRING Name ;
OBJECT_ATTRIBUTES ObjectAttributes ;
IO_STATUS_BLOCK IoStatusBlock ;
FILE_BASIC_INFORMATION FileInfo ;
HANDLE FileHandle ;
NTSTATUS Status ;
RtlInitUnicodeString ( & Name , FileName ) ;
InitializeObjectAttributes ( & ObjectAttributes ,
& Name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
NULL ) ;
Status = NtOpenFile ( & FileHandle ,
2013-07-19 14:03:46 +00:00
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE ,
2011-07-20 17:54:28 +00:00
& ObjectAttributes ,
& IoStatusBlock ,
0 ,
FILE_SYNCHRONOUS_IO_NONALERT ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtOpenFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
Status = NtQueryInformationFile ( FileHandle ,
& IoStatusBlock ,
& FileInfo ,
sizeof ( FILE_BASIC_INFORMATION ) ,
FileBasicInformation ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtQueryInformationFile() failed (Status %lx) \n " , Status ) ;
NtClose ( FileHandle ) ;
return Status ;
}
FileInfo . FileAttributes = FileInfo . FileAttributes | Attributes ;
Status = NtSetInformationFile ( FileHandle ,
& IoStatusBlock ,
& FileInfo ,
sizeof ( FILE_BASIC_INFORMATION ) ,
FileBasicInformation ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " NtSetInformationFile() failed (Status %lx) \n " , Status ) ;
}
NtClose ( FileHandle ) ;
return Status ;
}
NTSTATUS
UpdateBootIni (
PWSTR BootIniPath ,
PWSTR EntryName ,
PWSTR EntryValue )
{
UNICODE_STRING Name ;
PINICACHE Cache = NULL ;
PINICACHESECTION Section = NULL ;
NTSTATUS Status ;
ULONG FileAttribute ;
PWCHAR OldValue = NULL ;
RtlInitUnicodeString ( & Name , BootIniPath ) ;
Status = IniCacheLoad ( & Cache , & Name , FALSE ) ;
if ( ! NT_SUCCESS ( Status ) )
{
return Status ;
}
Section = IniCacheGetSection ( Cache ,
L " operating systems " ) ;
if ( Section = = NULL )
{
IniCacheDestroy ( Cache ) ;
return STATUS_UNSUCCESSFUL ;
}
/* Check - maybe record already exists */
Status = IniCacheGetKey ( Section , EntryName , & OldValue ) ;
/* If either key was not found, or contains something else - add new one */
if ( ! NT_SUCCESS ( Status ) | | wcscmp ( OldValue , EntryValue ) )
{
IniCacheInsertKey ( Section ,
NULL ,
INSERT_LAST ,
EntryName ,
EntryValue ) ;
}
Status = UnprotectBootIni ( BootIniPath ,
& FileAttribute ) ;
if ( ! NT_SUCCESS ( Status ) )
{
IniCacheDestroy ( Cache ) ;
return Status ;
}
Status = IniCacheSave ( Cache , BootIniPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
IniCacheDestroy ( Cache ) ;
return Status ;
}
FileAttribute | = ( FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY ) ;
Status = ProtectBootIni ( BootIniPath , FileAttribute ) ;
IniCacheDestroy ( Cache ) ;
return Status ;
}
2014-05-12 14:17:37 +00:00
2011-07-20 17:54:28 +00:00
BOOLEAN
CheckInstallFatBootcodeToPartition (
PUNICODE_STRING SystemRootPath )
{
# ifdef __REACTOS__
if ( DoesFileExist ( SystemRootPath - > Buffer , L " ntldr " ) | |
DoesFileExist ( SystemRootPath - > Buffer , L " boot.ini " ) )
{
return TRUE ;
}
else if ( DoesFileExist ( SystemRootPath - > Buffer , L " io.sys " ) | |
DoesFileExist ( SystemRootPath - > Buffer , L " msdos.sys " ) )
{
return TRUE ;
}
# endif
return FALSE ;
}
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
{
2006-11-10 21:00:24 +00:00
# ifdef __REACTOS__
2011-07-20 17:54:28 +00:00
WCHAR SrcPath [ MAX_PATH ] ;
WCHAR DstPath [ MAX_PATH ] ;
NTSTATUS Status ;
/* FAT or FAT32 partition */
DPRINT ( " System path: '%wZ' \n " , SystemRootPath ) ;
if ( DoesFileExist ( SystemRootPath - > Buffer , L " ntldr " ) = = TRUE | |
DoesFileExist ( SystemRootPath - > Buffer , L " boot.ini " ) = = TRUE )
{
/* Search root directory for 'ntldr' and 'boot.ini'. */
DPRINT ( " Found Microsoft Windows NT/2000/XP boot loader \n " ) ;
/* Copy FreeLoader to the boot partition */
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ freeldr.sys " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.sys " ) ;
DPRINT ( " Copy: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = SetupCopyFile ( SrcPath , DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " SetupCopyFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Create or update freeldr.ini */
if ( DoesFileExist ( SystemRootPath - > Buffer , L " freeldr.ini " ) = = FALSE )
{
/* Create new 'freeldr.ini' */
DPRINT1 ( " Create new 'freeldr.ini' \n " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.ini " ) ;
Status = CreateFreeLoaderIniForReactos ( DstPath ,
DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " CreateFreeLoaderIniForReactos() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Install new bootcode */
if ( PartitionType = = PARTITION_FAT32 | |
PartitionType = = PARTITION_FAT32_XINT13 )
{
/* Install FAT32 bootcode */
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat32.bin " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ bootsect.ros " ) ;
DPRINT1 ( " Install FAT32 bootcode: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = InstallFat32BootCodeToFile ( SrcPath ,
DstPath ,
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat32BootCodeToFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
else
{
/* Install FAT16 bootcode */
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat.bin " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ bootsect.ros " ) ;
DPRINT1 ( " Install FAT bootcode: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = InstallFat16BootCodeToFile ( SrcPath ,
DstPath ,
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat16BootCodeToFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
}
else
{
/* Update existing 'freeldr.ini' */
DPRINT1 ( " Update existing 'freeldr.ini' \n " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.ini " ) ;
Status = UpdateFreeLoaderIni ( DstPath ,
DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " UpdateFreeLoaderIni() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
/* Update 'boot.ini' */
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ boot.ini " ) ;
DPRINT1 ( " Update 'boot.ini': %S \n " , DstPath ) ;
Status = UpdateBootIni ( DstPath ,
L " C: \\ bootsect.ros " ,
L " \" ReactOS \" " ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " UpdateBootIni() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
else if ( DoesFileExist ( SystemRootPath - > Buffer , L " io.sys " ) = = TRUE | |
DoesFileExist ( SystemRootPath - > Buffer , L " msdos.sys " ) = = TRUE )
{
/* Search for root directory for 'io.sys' and 'msdos.sys'. */
DPRINT1 ( " Found Microsoft DOS or Windows 9x boot loader \n " ) ;
/* Copy FreeLoader to the boot partition */
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ freeldr.sys " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.sys " ) ;
DPRINT ( " Copy: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = SetupCopyFile ( SrcPath , DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " SetupCopyFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Create or update 'freeldr.ini' */
if ( DoesFileExist ( SystemRootPath - > Buffer , L " freeldr.ini " ) = = FALSE )
{
/* Create new 'freeldr.ini' */
DPRINT1 ( " Create new 'freeldr.ini' \n " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.ini " ) ;
Status = CreateFreeLoaderIniForDos ( DstPath ,
DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " CreateFreeLoaderIniForDos() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Save current bootsector as 'BOOTSECT.DOS' */
wcscpy ( SrcPath , SystemRootPath - > Buffer ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ bootsect.dos " ) ;
DPRINT1 ( " Save bootsector: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = SaveCurrentBootSector ( SrcPath ,
DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " SaveCurrentBootSector() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Install new bootsector */
if ( PartitionType = = PARTITION_FAT32 | |
PartitionType = = PARTITION_FAT32_XINT13 )
{
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat32.bin " ) ;
DPRINT1 ( " Install FAT32 bootcode: %S ==> %S \n " , SrcPath , SystemRootPath - > Buffer ) ;
Status = InstallFat32BootCodeToDisk ( SrcPath ,
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat32BootCodeToDisk() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
else
{
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat.bin " ) ;
DPRINT1 ( " Install FAT bootcode: %S ==> %S \n " , SrcPath , SystemRootPath - > Buffer ) ;
Status = InstallFat16BootCodeToDisk ( SrcPath ,
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat16BootCodeToDisk() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
}
else
{
/* Update existing 'freeldr.ini' */
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.ini " ) ;
Status = UpdateFreeLoaderIni ( DstPath , DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " UpdateFreeLoaderIni() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
}
else
{
/* No or unknown boot loader */
DPRINT1 ( " No or unknown boot loader found \n " ) ;
/* Copy FreeLoader to the boot partition */
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ freeldr.sys " ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.sys " ) ;
DPRINT ( " Copy: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = SetupCopyFile ( SrcPath , DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " SetupCopyFile() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Create or update 'freeldr.ini' */
if ( DoesFileExist ( SystemRootPath - > Buffer , L " freeldr.ini " ) = = FALSE )
{
/* Create new freeldr.ini */
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.ini " ) ;
DPRINT ( " Copy: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = CreateFreeLoaderIniForReactos ( DstPath ,
DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " CreateFreeLoaderIniForReactos() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Save current bootsector as 'BOOTSECT.OLD' */
wcscpy ( SrcPath , SystemRootPath - > Buffer ) ;
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ bootsect.old " ) ;
DPRINT ( " Save bootsector: %S ==> %S \n " , SrcPath , DstPath ) ;
Status = SaveCurrentBootSector ( SrcPath ,
DstPath ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " SaveCurrentBootSector() failed (Status %lx) \n " , Status ) ;
return Status ;
}
/* Install new bootsector */
if ( ( PartitionType = = PARTITION_FAT32 ) | |
( PartitionType = = PARTITION_FAT32_XINT13 ) )
{
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat32.bin " ) ;
DPRINT ( " Install FAT32 bootcode: %S ==> %S \n " , SrcPath , SystemRootPath - > Buffer ) ;
Status = InstallFat32BootCodeToDisk ( SrcPath ,
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat32BootCodeToDisk() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
else
{
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat.bin " ) ;
DPRINT ( " Install FAT bootcode: %S ==> %S \n " , SrcPath , SystemRootPath - > Buffer ) ;
Status = InstallFat16BootCodeToDisk ( SrcPath ,
SystemRootPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " InstallFat16BootCodeToDisk() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
}
else
{
/* Update existing 'freeldr.ini' */
wcscpy ( DstPath , SystemRootPath - > Buffer ) ;
wcscat ( DstPath , L " \\ freeldr.ini " ) ;
Status = UpdateFreeLoaderIni ( DstPath ,
DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " UpdateFreeLoaderIni() failed (Status %lx) \n " , Status ) ;
return Status ;
}
}
}
return STATUS_SUCCESS ;
2006-11-10 21:00:24 +00:00
# else
2011-07-20 17:54:28 +00:00
return STATUS_NOT_IMPLEMENTED ;
2006-11-10 21:00:24 +00:00
# endif
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
{
if ( ( PartitionType = = PARTITION_FAT_12 ) | |
( PartitionType = = PARTITION_FAT_16 ) | |
( PartitionType = = PARTITION_HUGE ) | |
( PartitionType = = PARTITION_XINT13 ) | |
( PartitionType = = PARTITION_FAT32 ) | |
( PartitionType = = PARTITION_FAT32_XINT13 ) )
{
return InstallFatBootcodeToPartition ( SystemRootPath ,
SourceRootPath ,
DestinationArcPath ,
PartitionType ) ;
}
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
{
2006-11-10 21:00:24 +00:00
# ifdef __REACTOS__
2011-10-29 15:10:11 +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 ] ;
NTSTATUS Status ;
2014-05-12 14:17:37 +00:00
2011-10-29 15:10:11 +00:00
/* Format the floppy first */
Status = VfatFormat ( & FloppyDevice ,
FMIFS_FLOPPY ,
NULL ,
TRUE ,
0 ,
NULL ) ;
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 */
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ freeldr.sys " ) ;
2004-06-23 14:09:55 +00:00
2011-07-20 17:54:28 +00:00
wcscpy ( DstPath , L " \\ Device \\ Floppy0 \\ 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' */
wcscpy ( DstPath , L " \\ Device \\ Floppy0 \\ freeldr.ini " ) ;
2004-06-23 14:09:55 +00:00
2011-07-20 17:54:28 +00:00
DPRINT ( " Create new 'freeldr.ini' \n " ) ;
Status = CreateFreeLoaderIniForReactos ( DstPath , DestinationArcPath - > Buffer ) ;
if ( ! NT_SUCCESS ( Status ) )
2004-06-23 14:09:55 +00:00
{
2011-07-20 17:54:28 +00:00
DPRINT1 ( " CreateFreeLoaderIniForReactos() failed (Status %lx) \n " , Status ) ;
return Status ;
2004-06-23 14:09:55 +00:00
}
2011-07-20 17:54:28 +00:00
/* Install FAT12/16 boosector */
wcscpy ( SrcPath , SourceRootPath - > Buffer ) ;
wcscat ( SrcPath , L " \\ loader \\ fat.bin " ) ;
2004-06-23 14:09:55 +00:00
2011-07-20 17:54:28 +00:00
wcscpy ( DstPath , L " \\ Device \\ Floppy0 " ) ;
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
{
2011-07-20 17:54:28 +00:00
DPRINT1 ( " InstallFat16BootCodeToDisk() failed (Status %lx) \n " , Status ) ;
return Status ;
2004-06-23 14:09:55 +00:00
}
2011-07-20 17:54:28 +00:00
return STATUS_SUCCESS ;
2006-11-10 21:00:24 +00:00
# else
2011-07-20 17:54:28 +00:00
return STATUS_NOT_IMPLEMENTED ;
2006-11-10 21:00:24 +00:00
# endif
2004-06-23 14:09:55 +00:00
}
2003-01-30 17:37:13 +00:00
/* EOF */