diff --git a/.msvc/rufus_2010.vcxproj b/.msvc/rufus_2010.vcxproj
index fde20c6f..73dffd2a 100644
--- a/.msvc/rufus_2010.vcxproj
+++ b/.msvc/rufus_2010.vcxproj
@@ -173,10 +173,7 @@
-
-
-
diff --git a/.msvc/rufus_2010.vcxproj.filters b/.msvc/rufus_2010.vcxproj.filters
index 03dee667..a844cfd8 100644
--- a/.msvc/rufus_2010.vcxproj.filters
+++ b/.msvc/rufus_2010.vcxproj.filters
@@ -110,18 +110,9 @@
Header Files\inc
-
- Header Files\inc
-
Header Files\inc
-
- Header Files\inc
-
-
- Header Files\inc
-
Header Files\inc
diff --git a/fat16.c b/fat16.c
index 9db91fa8..12c1dad1 100644
--- a/fat16.c
+++ b/fat16.c
@@ -20,7 +20,6 @@
#include "file.h"
#include "fat16.h"
-#include "fat16fd.h"
int is_fat_16_fs(FILE *fp)
{
diff --git a/fat32.c b/fat32.c
index 2154be6f..8b785b5d 100644
--- a/fat32.c
+++ b/fat32.c
@@ -20,8 +20,6 @@
#include "file.h"
#include "fat32.h"
-#include "fat32fd.h"
-#include "fat32nt.h"
int is_fat_32_fs(FILE *fp)
{
diff --git a/file.c b/file.c
index 01d81746..15140671 100644
--- a/file.c
+++ b/file.c
@@ -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 */
diff --git a/inc/fat16.h b/inc/fat16.h
index a8704bac..222e4812 100644
--- a/inc/fat16.h
+++ b/inc/fat16.h
@@ -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
diff --git a/inc/fat16fd.h b/inc/fat16fd.h
deleted file mode 100644
index d9698a6b..00000000
--- a/inc/fat16fd.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef FAT16FD_H
-#define FAT16FD_H
-
-#include
-
-/* 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
diff --git a/inc/fat32.h b/inc/fat32.h
index 6eb7f5bf..dbd61ecb 100644
--- a/inc/fat32.h
+++ b/inc/fat32.h
@@ -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
diff --git a/inc/fat32fd.h b/inc/fat32fd.h
deleted file mode 100644
index 6451814b..00000000
--- a/inc/fat32fd.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef FAT32FD_H
-#define FAT32FD_H
-
-#include
-
-/* 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
diff --git a/inc/fat32nt.h b/inc/fat32nt.h
deleted file mode 100644
index c3cb0d2f..00000000
--- a/inc/fat32nt.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef FAT32NT_H
-#define FAT32NT_H
-
-#include
-
-/* 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
diff --git a/inc/mbr_zero.h b/inc/mbr_zero.h
index 1470717e..09535624 100644
--- a/inc/mbr_zero.h
+++ b/inc/mbr_zero.h
@@ -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 };
diff --git a/rufus.c b/rufus.c
index e9951cb9..b846de64 100644
--- a/rufus.c
+++ b/rufus.c
@@ -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;
diff --git a/rufus.rc b/rufus.rc
index 7fd9c268..dd1f64d3 100644
--- a/rufus.rc
+++ b/rufus.rc
@@ -63,7 +63,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP
CONTROL "https://github.com/pbatard/rufus",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