rufus/src/ms-sys/br.c
Robert McQueen 234b0a3fde [ms-sys] fix for detecting windows MBRs with localised messages
* Windows MBRs contain localised strings which mean the bytes between the
  executable code and the disk signature / partition table can change depending
  on locale. This patch adds lengths to reflect the offsets which are the same
  for every locale, and only compares these lengths when detecting existing
  Windows MBRs.
2016-09-21 17:37:16 +01:00

353 lines
8.1 KiB
C

/******************************************************************
Copyright (C) 2009-2015 Henrik Carlqvist
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
******************************************************************/
#include <stdio.h>
#include "file.h"
#include "nls.h"
#include "br.h"
unsigned long ulBytesPerSector = 512;
void set_bytes_per_sector(unsigned long ulValue)
{
ulBytesPerSector = ulValue;
if ((ulBytesPerSector < 512) || (ulBytesPerSector > 65536))
ulBytesPerSector = 512;
} /* set_bytes_per_sector */
uint32_t read_windows_disk_signature(FILE *fp)
{
uint32_t tWDS;
if(!read_data(fp, 0x1b8, &tWDS, 4))
return 0;
return tWDS;
} /* read_windows_disk_signature */
int write_windows_disk_signature(FILE *fp, uint32_t tWDS)
{
return write_data(fp, 0x1b8, &tWDS, 4);
} /* write_windows_disk_signature */
uint16_t read_mbr_copy_protect_bytes(FILE *fp)
{
uint16_t tOut;
if(!read_data(fp, 0x1bc, &tOut, 2))
return 0xffff;
return tOut;
} /* read_mbr_copy_protect_bytes */
const char *read_mbr_copy_protect_bytes_explained(FILE *fp)
{
uint16_t t = read_mbr_copy_protect_bytes(fp);
switch(t)
{
case 0:
return _("not copy protected");
case 0x5a5a:
return _("copy protected");
default:
return _("unknown value");
}
} /* read_mbr_copy_protect_bytes_explained */
int is_br(FILE *fp)
{
/* A "file" is probably some kind of boot record if it contains the magic
chars 0x55, 0xAA at position 0x1FE */
unsigned char aucRef[] = {0x55, 0xAA};
return contains_data(fp, 0x1FE, aucRef, sizeof(aucRef));
} /* is_br */
int is_lilo_br(FILE *fp)
{
/* A "file" is probably a LILO boot record if it contains the magic
chars LILO at position 0x6 or 0x2 for floppies */
unsigned char aucRef[] = {'L','I','L','O'};
return ( contains_data(fp, 0x6, aucRef, sizeof(aucRef)) ||
contains_data(fp, 0x2, aucRef, sizeof(aucRef)) );
} /* is_lilo_br */
int is_dos_mbr(FILE *fp)
{
#include "mbr_dos.h"
return
contains_data(fp, 0x0, mbr_dos_0x0, sizeof(mbr_dos_0x0)) &&
is_br(fp);
} /* is_dos_mbr */
int is_dos_f2_mbr(FILE *fp)
{
#include "mbr_dos_f2.h"
return
contains_data(fp, 0x0, mbr_dos_f2_0x0, sizeof(mbr_dos_f2_0x0)) &&
is_br(fp);
} /* is_dos_f2_mbr */
int is_95b_mbr(FILE *fp)
{
#include "mbr_95b.h"
return
contains_data(fp, 0x0, mbr_95b_0x0, sizeof(mbr_95b_0x0)) &&
contains_data(fp, 0x0e0, mbr_95b_0x0e0, sizeof(mbr_95b_0x0e0)) &&
is_br(fp);
} /* is_95b_mbr */
int is_2000_mbr(FILE *fp)
{
#include "mbr_2000.h"
return
contains_data(fp, 0x0, mbr_2000_0x0, MBR_2000_LANG_INDEP_LEN) &&
is_br(fp);
} /* is_2000_mbr */
int is_vista_mbr(FILE *fp)
{
#include "mbr_vista.h"
return
contains_data(fp, 0x0, mbr_vista_0x0, MBR_VISTA_LANG_INDEP_LEN) &&
is_br(fp);
} /* is_vista_mbr */
int is_win7_mbr(FILE *fp)
{
#include "mbr_win7.h"
return
contains_data(fp, 0x0, mbr_win7_0x0, MBR_WIN7_LANG_INDEP_LEN) &&
is_br(fp);
} /* is_win7_mbr */
int is_rufus_mbr(FILE *fp)
{
#include "mbr_rufus.h"
return
contains_data(fp, 0x0, mbr_rufus_0x0, sizeof(mbr_rufus_0x0)) &&
is_br(fp);
} /* is_rufus_mbr */
int is_reactos_mbr(FILE *fp)
{
#include "mbr_reactos.h"
return
contains_data(fp, 0x0, mbr_reactos_0x0, sizeof(mbr_reactos_0x0)) &&
is_br(fp);
} /* is_reactos_mbr */
int is_grub4dos_mbr(FILE *fp)
{
#include "mbr_grub.h"
return
contains_data(fp, 0x0, mbr_grub_0x0, sizeof(mbr_grub_0x0)) &&
is_br(fp);
} /* is_grub_mbr */
int is_grub2_mbr(FILE *fp)
{
#include "mbr_grub2.h"
return
contains_data(fp, 0x0, mbr_grub2_0x0, sizeof(mbr_grub2_0x0)) &&
is_br(fp);
} /* is_grub2_mbr */
int is_kolibrios_mbr(FILE *fp)
{
#include "mbr_kolibri.h"
return
contains_data(fp, 0x0, mbr_kolibri_0x0, sizeof(mbr_kolibri_0x0)) &&
is_br(fp);
} /* is_kolibri_mbr */
int is_syslinux_mbr(FILE *fp)
{
#include "mbr_syslinux.h"
return
contains_data(fp, 0x0, mbr_syslinux_0x0, sizeof(mbr_syslinux_0x0)) &&
is_br(fp);
} /* is_syslinux_mbr */
int is_syslinux_gpt_mbr(FILE *fp)
{
#include "mbr_gpt_syslinux.h"
return
contains_data(fp, 0x0, mbr_gpt_syslinux_0x0,
sizeof(mbr_gpt_syslinux_0x0)) &&
is_br(fp);
} /* is_syslinux_gpt_mbr */
int is_zero_mbr(FILE *fp)
{
#include "mbr_zero.h"
return
contains_data(fp, 0x0, mbr_zero_0x0, sizeof(mbr_zero_0x0));
/* Don't bother to check 55AA signature */
} /* is_zero_mbr */
int is_zero_mbr_not_including_disk_signature_or_copy_protect(FILE *fp)
{
#include "mbr_zero.h"
return
contains_data(fp, 0x0, mbr_zero_0x0, 0x1b8);
} /* is_zero_mbr_not_including_disk_signature_or_copy_protect */
/* Handle nonstandard sector sizes (such as 4K) by writing
the boot marker at every 512-2 bytes location */
static int write_bootmark(FILE *fp)
{
unsigned char aucRef[] = {0x55, 0xAA};
unsigned long pos = 0x1FE;
for (pos = 0x1FE; pos < ulBytesPerSector; pos += 0x200) {
if (!write_data(fp, pos, aucRef, sizeof(aucRef)))
return 0;
}
return 1;
}
int write_dos_mbr(FILE *fp)
{
#include "mbr_dos.h"
return
write_data(fp, 0x0, mbr_dos_0x0, sizeof(mbr_dos_0x0)) &&
write_bootmark(fp);
} /* write_dos_mbr */
int write_95b_mbr(FILE *fp)
{
#include "mbr_95b.h"
return
write_data(fp, 0x0, mbr_95b_0x0, sizeof(mbr_95b_0x0)) &&
write_data(fp, 0x0e0, mbr_95b_0x0e0, sizeof(mbr_95b_0x0e0)) &&
write_bootmark(fp);
} /* write_95b_mbr */
int write_2000_mbr(FILE *fp)
{
#include "mbr_2000.h"
return
write_data(fp, 0x0, mbr_2000_0x0, sizeof(mbr_2000_0x0)) &&
write_bootmark(fp);
} /* write_2000_mbr */
int write_vista_mbr(FILE *fp)
{
#include "mbr_vista.h"
return
write_data(fp, 0x0, mbr_vista_0x0, sizeof(mbr_vista_0x0)) &&
write_bootmark(fp);
} /* write_vista_mbr */
int write_win7_mbr(FILE *fp)
{
#include "mbr_win7.h"
return
write_data(fp, 0x0, mbr_win7_0x0, sizeof(mbr_win7_0x0)) &&
write_bootmark(fp);
} /* write_win7_mbr */
int write_rufus_mbr(FILE *fp)
{
#include "mbr_rufus.h"
return
write_data(fp, 0x0, mbr_rufus_0x0, sizeof(mbr_rufus_0x0)) &&
write_bootmark(fp);
} /* write_rufus_mbr */
int write_reactos_mbr(FILE *fp)
{
#include "mbr_reactos.h"
return
write_data(fp, 0x0, mbr_reactos_0x0, sizeof(mbr_reactos_0x0)) &&
write_bootmark(fp);
} /* write_reactos_mbr */
int write_kolibrios_mbr(FILE *fp)
{
#include "mbr_kolibri.h"
return
write_data(fp, 0x0, mbr_kolibri_0x0, sizeof(mbr_kolibri_0x0)) &&
write_bootmark(fp);
} /* write_kolibri_mbr */
int write_syslinux_mbr(FILE *fp)
{
#include "mbr_syslinux.h"
return
write_data(fp, 0x0, mbr_syslinux_0x0, sizeof(mbr_syslinux_0x0)) &&
write_bootmark(fp);
} /* write_syslinux_mbr */
int write_syslinux_gpt_mbr(FILE *fp)
{
#include "mbr_gpt_syslinux.h"
return
write_data(fp, 0x0, mbr_gpt_syslinux_0x0, sizeof(mbr_gpt_syslinux_0x0)) &&
write_bootmark(fp);
} /* write_syslinux_gpt_mbr */
int write_grub4dos_mbr(FILE *fp)
{
#include "mbr_grub.h"
return
write_data(fp, 0x0, mbr_grub_0x0, sizeof(mbr_grub_0x0)) &&
write_bootmark(fp);
}
int write_grub2_mbr(FILE *fp)
{
#include "mbr_grub2.h"
return
write_data(fp, 0x0, mbr_grub2_0x0, sizeof(mbr_grub2_0x0)) &&
write_bootmark(fp);
}
int write_zero_mbr(FILE *fp)
{
#include "mbr_zero.h"
return
write_data(fp, 0x0, mbr_zero_0x0, sizeof(mbr_zero_0x0)) &&
write_bootmark(fp);
} /* write_zero_mbr */