[mbr] added mbr detection

* also added write_data() for Windows in file.h
* also merged/removed fat16/32 includes
* also removed disk-signature for zeroed MBR detection
This commit is contained in:
Pete Batard 2011-11-29 23:45:19 +00:00
parent 2d8a674b88
commit 88143701ed
13 changed files with 116 additions and 105 deletions

View File

@ -173,10 +173,7 @@
<ClInclude Include="..\inc\br_fat32_0x52.h" />
<ClInclude Include="..\inc\fat12.h" />
<ClInclude Include="..\inc\fat16.h" />
<ClInclude Include="..\inc\fat16fd.h" />
<ClInclude Include="..\inc\fat32.h" />
<ClInclude Include="..\inc\fat32fd.h" />
<ClInclude Include="..\inc\fat32nt.h" />
<ClInclude Include="..\inc\file.h" />
<ClInclude Include="..\inc\label_11_char.h" />
<ClInclude Include="..\inc\mbr_2000.h" />

View File

@ -110,18 +110,9 @@
<ClInclude Include="..\inc\fat16.h">
<Filter>Header Files\inc</Filter>
</ClInclude>
<ClInclude Include="..\inc\fat16fd.h">
<Filter>Header Files\inc</Filter>
</ClInclude>
<ClInclude Include="..\inc\fat32.h">
<Filter>Header Files\inc</Filter>
</ClInclude>
<ClInclude Include="..\inc\fat32fd.h">
<Filter>Header Files\inc</Filter>
</ClInclude>
<ClInclude Include="..\inc\fat32nt.h">
<Filter>Header Files\inc</Filter>
</ClInclude>
<ClInclude Include="..\inc\file.h">
<Filter>Header Files\inc</Filter>
</ClInclude>

View File

@ -20,7 +20,6 @@
#include "file.h"
#include "fat16.h"
#include "fat16fd.h"
int is_fat_16_fs(FILE *fp)
{

View File

@ -20,8 +20,6 @@
#include "file.h"
#include "fat32.h"
#include "fat32fd.h"
#include "fat32nt.h"
int is_fat_32_fs(FILE *fp)
{

53
file.c
View File

@ -1,6 +1,6 @@
/******************************************************************
Copyright (C) 2009 Henrik Carlqvist
Modified for Windows/Rufus (C) 2011 Pete Batard
Modified for Rufus/Windows (C) 2011 Pete Batard
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
@ -106,38 +106,37 @@ int contains_data(FILE *fp, unsigned long ulPosition,
if(memcmp(pData, &aucBuf[ulPosition - ulStartSector*ulSectorSize], uiLen))
return 0;
return 1;
/*
// ONLY WORKS IN SECTORS!!!
ptr.QuadPart = ulPosition;
uprintf("HANDLE = %p\n", (HANDLE)fp);
if (!SetFilePointerEx((HANDLE)fp, ptr, NULL, FILE_BEGIN))
{
uprintf("Could not access byte %d - %s\n", ulPosition, WindowsErrorString());
return 0;
}
uprintf("SEEK to %d OK\n", WindowsErrorString());
uiLen = 512;
if ((!ReadFile((HANDLE)fp, aucBuf, (DWORD)uiLen, &size, NULL)) || (size != (DWORD)uiLen)) {
uprintf("Read error (size = %d vs %d) - %s\n", size, (DWORD)uiLen, WindowsErrorString());
return 0;
}
uiLen = 2;
uprintf("aucBuf[0] = %02X, aucBuf[1] = %02X\n", aucBuf[0], aucBuf[1]);
if(memcmp(pData, aucBuf, uiLen))
return 0;
return 1;
*/
} /* contains_data */
/* May read/write the same sector many times, but compatible with existing ms-sys */
int write_data(FILE *fp, unsigned long ulPosition,
const void *pData, unsigned int uiLen)
{
if(fseek(fp, ulPosition, SEEK_SET))
unsigned char aucBuf[MAX_DATA_LEN];
HANDLE hDrive = (HANDLE)fp->_ptr;
unsigned long ulSectorSize = (unsigned long)fp->_bufsiz;
unsigned long ulStartSector, ulEndSector, ulNumSectors;
ulStartSector = ulPosition/ulSectorSize;
ulEndSector = (ulPosition+uiLen+ulSectorSize-1)/ulSectorSize;
ulNumSectors = ulEndSector - ulStartSector;
if((ulNumSectors*ulSectorSize) > MAX_DATA_LEN)
{
uprintf("Please increase MAX_DATA_LEN in file.h\n");
return 0;
if(!fwrite(pData, uiLen, 1, fp))
}
/* Data to write may not be aligned on a sector boundary => read into a sector buffer first */
if(!read_sectors(hDrive, ulSectorSize, ulStartSector,
ulNumSectors, aucBuf, sizeof(aucBuf)))
return 0;
if(!memcpy(&aucBuf[ulPosition - ulStartSector*ulSectorSize], pData, uiLen))
return 0;
if(!write_sectors(hDrive, ulSectorSize, ulStartSector,
ulNumSectors, aucBuf, sizeof(aucBuf)))
return 0;
return 1;
} /* write_data */

View File

@ -20,4 +20,13 @@ int entire_fat_16_br_matches(FILE *fp);
FALSE */
int write_fat_16_br(FILE *fp, int bKeepLabel);
/* returns TRUE if the file has an exact match ot the FAT16 boot record this
program would create for FreeDOS, otherwise FALSE.
The file position will change when this function is called! */
int entire_fat_16_fd_br_matches(FILE *fp);
/* Writes a FAT16 FreeDOS boot record to a file, returns TRUE on success,
otherwise FALSE */
int write_fat_16_fd_br(FILE *fp, int bKeepLabel);
#endif

View File

@ -1,15 +0,0 @@
#ifndef FAT16FD_H
#define FAT16FD_H
#include <stdio.h>
/* returns TRUE if the file has an exact match ot the FAT16 boot record this
program would create for FreeDOS, otherwise FALSE.
The file position will change when this function is called! */
int entire_fat_16_fd_br_matches(FILE *fp);
/* Writes a FAT16 FreeDOS boot record to a file, returns TRUE on success,
otherwise FALSE */
int write_fat_16_fd_br(FILE *fp, int bKeepLabel);
#endif

View File

@ -20,4 +20,22 @@ int entire_fat_32_br_matches(FILE *fp);
FALSE */
int write_fat_32_br(FILE *fp, int bKeepLabel);
/* returns TRUE if the file has an exact match ot the FAT32 boot record this
program would create for FreeDOS, otherwise FALSE.
The file position will change when this function is called! */
int entire_fat_32_fd_br_matches(FILE *fp);
/* Writes a FAT32 FreeDOS boot record to a file, returns TRUE on success,
otherwise FALSE */
int write_fat_32_fd_br(FILE *fp, int bKeepLabel);
/* returns TRUE if the file has an exact match ot the FAT32 boot record this
program would create for NT, otherwise FALSE.
The file position will change when this function is called! */
int entire_fat_32_nt_br_matches(FILE *fp);
/* Writes a FAT32 NT boot record to a file, returns TRUE on success, otherwise
FALSE */
int write_fat_32_nt_br(FILE *fp, int bKeepLabel);
#endif

View File

@ -1,15 +0,0 @@
#ifndef FAT32FD_H
#define FAT32FD_H
#include <stdio.h>
/* returns TRUE if the file has an exact match ot the FAT32 boot record this
program would create for FreeDOS, otherwise FALSE.
The file position will change when this function is called! */
int entire_fat_32_fd_br_matches(FILE *fp);
/* Writes a FAT32 FreeDOS boot record to a file, returns TRUE on success,
otherwise FALSE */
int write_fat_32_fd_br(FILE *fp, int bKeepLabel);
#endif

View File

@ -1,15 +0,0 @@
#ifndef FAT32NT_H
#define FAT32NT_H
#include <stdio.h>
/* returns TRUE if the file has an exact match ot the FAT32 boot record this
program would create for NT, otherwise FALSE.
The file position will change when this function is called! */
int entire_fat_32_nt_br_matches(FILE *fp);
/* Writes a FAT32 NT boot record to a file, returns TRUE on success, otherwise
FALSE */
int write_fat_32_nt_br(FILE *fp, int bKeepLabel);
#endif

View File

@ -1,4 +1,4 @@
/* First 446 bytes of a zeroed MBR*/
/* First 440 bytes of a zeroed MBR (disk signature is excluded) */
unsigned char mbr_zero_0x0[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -36,6 +36,4 @@ unsigned char mbr_zero_0x0[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00
};
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

63
rufus.c
View File

@ -49,6 +49,7 @@
#include "rufus.h"
#include "sys_types.h"
#include "br.h"
#include "fat16.h"
#include "fat32.h"
#include "file.h"
@ -646,14 +647,63 @@ out:
return r;
}
static BOOL AnalyzeMBR(HANDLE hPhysicalDrive)
{
FILE fake_fd;
fake_fd._ptr = (char*)hPhysicalDrive;
fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector;
// TODO: Apply this detection before partitioning
// TODO: since we detect all these, might as well give some MBR choice to the user?
if (is_br(&fake_fd)) {
uprintf("Drive has an x86 boot sector\n");
} else{
uprintf("Drive is missing an x86 boot sector!\n");
return FALSE;
}
// TODO: Add/Eliminate FAT12?
if (is_fat_16_br(&fake_fd) || is_fat_32_br(&fake_fd)) {
if (entire_fat_16_br_matches(&fake_fd)) {
uprintf("Exact FAT16 DOS boot record match\n");
} else if (entire_fat_16_fd_br_matches(&fake_fd)) {
uprintf("Exact FAT16 FreeDOS boot record match\n");
} else if (entire_fat_32_br_matches(&fake_fd)) {
uprintf("Exact FAT32 DOS boot record match\n");
} else if (entire_fat_32_nt_br_matches(&fake_fd)) {
uprintf("Exact FAT32 NT boot record match\n");
} else if (entire_fat_32_fd_br_matches(&fake_fd)) {
uprintf("Exactly FAT32 FreeDOS boot record match\n");
} else {
uprintf("Unknown FAT16 or FAT32 boot record\n");
}
} else if (is_dos_mbr(&fake_fd)) {
uprintf("Microsoft DOS/NT/95A master boot record match\n");
} else if (is_dos_f2_mbr(&fake_fd)) {
uprintf("Microsoft DOS/NT/95A master boot record with the undocumented\n");
uprintf("F2 instruction match\n");
} else if (is_95b_mbr(&fake_fd)) {
uprintf("Microsoft 95B/98/98SE/ME master boot record match\n");
} else if (is_2000_mbr(&fake_fd)) {
uprintf("Microsoft 2000/XP/2003 master boot record match\n");
} else if (is_vista_mbr(&fake_fd)) {
uprintf("Microsoft Vista master boot record match\n");
} else if (is_win7_mbr(&fake_fd)) {
uprintf("Microsoft 7 master boot record match\n");
} else if (is_zero_mbr(&fake_fd)) {
uprintf("Zeroed non-bootable master boot record match\n");
} else {
uprintf("Unknown boot record\n");
}
return TRUE;
}
/*
* Process the MBR
*/
static BOOL ProcessMBR(HANDLE hPhysicalDrive)
{
BOOL r = FALSE;
HANDLE hDrive = hPhysicalDrive;
FILE fake_fd;
unsigned char* buf = NULL;
size_t SecSize = SelectedDrive.Geometry.BytesPerSector;
size_t nSecs = 0x200/min(0x200, SelectedDrive.Geometry.BytesPerSector);
@ -665,10 +715,7 @@ static BOOL ProcessMBR(HANDLE hPhysicalDrive)
}
PrintStatus("Processing MBR...\n");
fake_fd._ptr = (char*)hPhysicalDrive;
fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector;
uprintf("I'm %sa boot record\n", is_br(&fake_fd)?"":"NOT ");
if (!AnalyzeMBR(hPhysicalDrive)) return FALSE;
// FormatEx rewrites the MBR and removes the LBA attribute of FAT16
// and FAT32 partitions - we need to correct this in the MBR
@ -680,7 +727,7 @@ static BOOL ProcessMBR(HANDLE hPhysicalDrive)
goto out;
}
if (!read_sectors(hDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize)) {
if (!read_sectors(hPhysicalDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize)) {
uprintf("Could not read MBR\n");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_READ_FAULT;
goto out;
@ -696,7 +743,7 @@ static BOOL ProcessMBR(HANDLE hPhysicalDrive)
break;
}
if (!write_sectors(hDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize)) {
if (!write_sectors(hPhysicalDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize)) {
uprintf("Could not write MBR\n");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
goto out;

View File

@ -63,7 +63,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP
CONTROL "<a href=""https://github.com/pbatard/rufus/wiki/Rufus"">https://github.com/pbatard/rufus</a>",IDC_ABOUT_RUFUS_URL,
"SysLink",WS_TABSTOP,46,47,114,9
LTEXT "Version 1.0.0 (Build 48)",IDC_STATIC,46,19,78,8
LTEXT "Version 1.0.0 (Build 49)",IDC_STATIC,46,19,78,8
PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP
EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL
LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8
@ -162,8 +162,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,48
PRODUCTVERSION 1,0,0,48
FILEVERSION 1,0,0,49
PRODUCTVERSION 1,0,0,49
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -180,13 +180,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "akeo.ie"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.0.0.48"
VALUE "FileVersion", "1.0.0.49"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "1.0.0.48"
VALUE "ProductVersion", "1.0.0.49"
END
END
BLOCK "VarFileInfo"
@ -212,7 +212,7 @@ IDI_ICON ICON "rufus.ico"
STRINGTABLE
BEGIN
IDS_VERSION "Rufus v1.0.0.48"
IDS_VERSION "Rufus v1.0.0.49"
END
#endif // English resources