diff --git a/freedos/COMMAND.COM b/freedos/COMMAND.COM
new file mode 100644
index 00000000..4a301682
Binary files /dev/null and b/freedos/COMMAND.COM differ
diff --git a/freedos/KERNEL.SYS b/freedos/KERNEL.SYS
new file mode 100644
index 00000000..59c18f09
Binary files /dev/null and b/freedos/KERNEL.SYS differ
diff --git a/freedos/readme.txt b/freedos/readme.txt
new file mode 100644
index 00000000..89f51225
--- /dev/null
+++ b/freedos/readme.txt
@@ -0,0 +1,2 @@
+These files were extracted from the fd11tst3.img image available at:
+http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.1-test3/
diff --git a/src/.msvc/rufus_2010.vcxproj b/src/.msvc/rufus_2010.vcxproj
index dffe0f9f..d3b6b764 100644
--- a/src/.msvc/rufus_2010.vcxproj
+++ b/src/.msvc/rufus_2010.vcxproj
@@ -194,6 +194,7 @@
+
@@ -202,6 +203,8 @@
+
+
diff --git a/src/.msvc/rufus_2010.vcxproj.filters b/src/.msvc/rufus_2010.vcxproj.filters
index 8bcbbec1..9180397b 100644
--- a/src/.msvc/rufus_2010.vcxproj.filters
+++ b/src/.msvc/rufus_2010.vcxproj.filters
@@ -16,6 +16,9 @@
{ecff9fec-41c4-4ce8-b725-27ee39754cb7}
+
+ {340c377e-7530-411d-a367-49825f080d85}
+
@@ -167,11 +170,20 @@
Header Files\ms-sys inc
+
+ Header Files
+
Resource Files
+
+ Resource Files\freedos
+
+
+ Resource Files\freedos
+
diff --git a/src/format.c b/src/format.c
index fe041d7f..722d98c7 100644
--- a/src/format.c
+++ b/src/format.c
@@ -318,7 +318,7 @@ out:
/*
* Process the Partition Boot Record
*/
-static BOOL WritePBR(HANDLE hLogicalVolume)
+static BOOL WritePBR(HANDLE hLogicalVolume, BOOL bFreeDOS)
{
int i;
FILE fake_fd = { 0 };
@@ -334,9 +334,11 @@ static BOOL WritePBR(HANDLE hLogicalVolume)
break;
}
uprintf("Confirmed new volume has a FAT16 boot sector\n");
- if (!write_fat_16_br(&fake_fd, 0) ||
- // Disk Drive ID needs to be corrected on XP
- !write_partition_physical_disk_drive_id_fat16(&fake_fd))
+ if (bFreeDOS) {
+ if (!write_fat_16_fd_br(&fake_fd, 0)) break;
+ } else if (!write_fat_16_br(&fake_fd, 0)) break;
+ // Disk Drive ID needs to be corrected on XP
+ if (!write_partition_physical_disk_drive_id_fat16(&fake_fd))
break;
return TRUE;
case FS_FAT32:
@@ -347,9 +349,11 @@ static BOOL WritePBR(HANDLE hLogicalVolume)
}
uprintf("Confirmed new volume has a %s FAT32 boot sector\n", i?"secondary":"primary");
uprintf("Setting %s FAT32 boot sector for DOS boot...\n", i?"secondary":"primary");
- if (!write_fat_32_br(&fake_fd, 0) ||
- // Disk Drive ID needs to be corrected on XP
- !write_partition_physical_disk_drive_id_fat32(&fake_fd))
+ if (bFreeDOS) {
+ if (!write_fat_32_fd_br(&fake_fd, 0)) break;
+ } else if (!write_fat_32_br(&fake_fd, 0)) break;
+ // Disk Drive ID needs to be corrected on XP
+ if (!write_partition_physical_disk_drive_id_fat32(&fake_fd))
break;
fake_fd._cnt += 6 * (int)SelectedDrive.Geometry.BytesPerSector;
}
@@ -469,15 +473,15 @@ void __cdecl FormatThread(void* param)
goto out;
}
PrintStatus(0, "Writing partition boot record...\n");
- if (!WritePBR(hLogicalVolume)) {
+ if (!WritePBR(hLogicalVolume, ComboBox_GetCurSel(hDOSType) == DT_FREEDOS)) {
// Errorcode has already been set
goto out;
}
// ...but we must have relinquished that lock to write the MS-DOS files
safe_unlockclose(hLogicalVolume);
UpdateProgress(OP_DOS, -1.0f);
- PrintStatus(0, "Copying MS-DOS files...\n");
- if (!ExtractMSDOS(drive_name)) {
+ PrintStatus(0, "Copying DOS files...\n");
+ if (!ExtractDOS(drive_name, ComboBox_GetCurSel(hDOSType))) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
goto out;
}
diff --git a/src/license.h b/src/license.h
index f339665b..93b08a4c 100644
--- a/src/license.h
+++ b/src/license.h
@@ -26,7 +26,7 @@ const char* additional_copyrights =
"http://ms-sys.sourceforge.net\r\n"
"GNU General Public License (GPL) v2 or later\r\n"
"\r\n"
-"Bad blocks testing from e2fsprogs by Theodore T'so and al:\r\n"
+"Bad blocks testing from e2fsprogs by Theodore T'so et al:\r\n"
"http://e2fsprogs.sourceforge.net\r\n"
"GNU General Public License (GPL) v3 compatible\r\n"
"\r\n"
diff --git a/src/msdos.c b/src/msdos.c
index 11806e92..69d7cb45 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -29,6 +29,7 @@
#include "rufus.h"
#include "msdos.h"
+#include "resource.h"
static BYTE* DiskImage;
static size_t DiskImageSize;
@@ -257,7 +258,7 @@ static BOOL ExtractFAT(int entry, const char* path)
if ((!WriteFile(hFile, &DiskImage[filestart], (DWORD)filesize, &Size, 0)) || (filesize != Size)) {
uprintf("Couldn't write file '%s': %s.\n", filename, WindowsErrorString());
safe_closehandle(hFile);
- return FALSE; safe_closehandle(hFile);
+ return FALSE;
}
/* Restore timestamps from FAT */
@@ -284,7 +285,7 @@ static BOOL ExtractFAT(int entry, const char* path)
/* Extract the MS-DOS files contained in the FAT12 1.4MB floppy
image included as resource "BINFILE" in diskcopy.dll */
-BOOL ExtractMSDOS(const char* path)
+static BOOL ExtractMSDOS(const char* path)
{
char dllname[MAX_PATH] = "C:\\Windows\\System32";
int i, j;
@@ -337,3 +338,74 @@ BOOL ExtractMSDOS(const char* path)
return r;
}
+
+/* Extract the FreeDOS files embedded in the app */
+BOOL ExtractFreeDOS(const char* path)
+{
+ const char* res_name[2] = { "COMMAND.COM", "KERNEL.SYS" };
+ const int res_id[2] = { IDR_FD_COMMAND_COM, IDR_FD_KERNEL_SYS };
+ char filename[MAX_PATH];
+ HGLOBAL res_handle[2];
+ HRSRC res[2];
+ BYTE* res_data[2];
+ DWORD res_size[2], Size;
+ HANDLE hFile;
+ size_t pos;
+ int i;
+
+ if ((path == NULL) || ((safe_strlen(path) + 14) > sizeof(filename))) {
+ uprintf("invalid path supplied for FreeDOS extraction\n");
+ return FALSE;
+ }
+
+ for (i=0; i<2; i++) {
+ res[i] = FindResource(hMainInstance, MAKEINTRESOURCE(res_id[i]), RT_RCDATA);
+ if (res[i] == NULL) {
+ uprintf("Unable to locate FreeDOS resource %s: %s\n", res_name[i], WindowsErrorString());
+ return FALSE;
+ }
+ res_handle[i] = LoadResource(NULL, res[i]);
+ if (res_handle[i] == NULL) {
+ uprintf("Unable to load FreeDOS resource %s: %s\n", res_name[i], WindowsErrorString());
+ return FALSE;
+ }
+ res_data[i] = (BYTE*)LockResource(res_handle[i]);
+ res_size[i] = SizeofResource(NULL, res[i]);
+
+ strcpy(filename, path);
+ pos = strlen(path);
+ filename[pos++] = '\\';
+ filename[pos] = 0;
+ safe_strcat(filename, sizeof(filename), res_name[i]);
+
+ // TODO: set attributes
+ hFile = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
+ NULL, CREATE_ALWAYS, 0, 0);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ uprintf("Unable to create file '%s': %s.\n", filename, WindowsErrorString());
+ return FALSE;
+ }
+
+ if ((!WriteFile(hFile, res_data[i], res_size[i], &Size, 0)) || (res_size[i] != Size)) {
+ uprintf("Couldn't write file '%s': %s.\n", filename, WindowsErrorString());
+ safe_closehandle(hFile);
+ return FALSE;
+ }
+
+ // TODO: Restore timestamps from resource
+// if (!SetFileTime(hFile, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime)) {
+// uprintf("Could not set timestamps: %s\n", WindowsErrorString());
+// }
+
+ safe_closehandle(hFile);
+ uprintf("Succesfully wrote '%s' (%d bytes)\n", filename, res_size[i]);
+ }
+ return TRUE;
+}
+
+BOOL ExtractDOS(const char* path, int dos_type)
+{
+ if (dos_type == DT_WINME)
+ return ExtractMSDOS(path);
+ return ExtractFreeDOS(path);
+}
diff --git a/src/resource.h b/src/resource.h
index f4037f05..b21e4929 100644
--- a/src/resource.h
+++ b/src/resource.h
@@ -8,6 +8,8 @@
#define IDD_NOTIFICATION 104
#define IDD_LICENSE 105
#define IDS_VERSION 106
+#define IDR_FD_COMMAND_COM 300
+#define IDR_FD_KERNEL_SYS 301
#define IDC_DEVICE 1001
#define IDC_FILESYSTEM 1002
#define IDC_START 1003
@@ -30,6 +32,7 @@
#define IDC_NOTIFICATION_ICON 1040
#define IDC_NOTIFICATION_TEXT 1041
#define IDC_NOTIFICATION_LINE 1042
+#define IDC_DOSTYPE 1043
// Next default values for new objects
//
@@ -38,7 +41,7 @@
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 107
#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1043
+#define _APS_NEXT_CONTROL_VALUE 1044
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/src/rufus.c b/src/rufus.c
index 50df95ce..470ee252 100644
--- a/src/rufus.c
+++ b/src/rufus.c
@@ -53,7 +53,7 @@ HWND hMainDialog;
char szFolderPath[MAX_PATH];
float fScale = 1.0f;
int default_fs;
-HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel;
+HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel, hDOSType;
static HWND hDeviceTooltip = NULL, hFSTooltip = NULL, hProgress = NULL;
static StrArray DriveID, DriveLabel;
@@ -234,7 +234,6 @@ static BOOL SetClusterSizes(int FSType)
IGNORE_RETVAL(ComboBox_ResetContent(hClusterSize));
if ((FSType < 0) || (FSType >= FS_MAX)) {
- uprintf("Invalid FS value passed to SetClusterSizes\n");
return FALSE;
}
@@ -846,8 +845,10 @@ static void EnableControls(BOOL bEnable)
if (bEnable) {
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
EnableWindow(GetDlgItem(hMainDialog, IDC_DOS), (fs == FS_FAT16) || (fs == FS_FAT32));
+ EnableWindow(GetDlgItem(hMainDialog, IDC_DOSTYPE), (fs == FS_FAT16) || (fs == FS_FAT32));
} else {
EnableWindow(GetDlgItem(hMainDialog, IDC_DOS), FALSE);
+ EnableWindow(GetDlgItem(hMainDialog, IDC_DOSTYPE), FALSE);
}
EnableWindow(GetDlgItem(hMainDialog, IDC_BADBLOCKS), bEnable);
EnableWindow(GetDlgItem(hMainDialog, IDC_ABOUT), bEnable);
@@ -900,6 +901,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
hLabel = GetDlgItem(hDlg, IDC_LABEL);
hProgress = GetDlgItem(hDlg, IDC_PROGRESS);
hDOS = GetDlgItem(hDlg, IDC_DOS);
+ hDOSType = GetDlgItem(hDlg, IDC_DOSTYPE);
// High DPI scaling
hDC = GetDC(hDlg);
fScale = GetDeviceCaps(hDC, LOGPIXELSX) / 96.0f;
@@ -913,6 +915,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
CreateStatusBar();
// Use maximum granularity for the progress bar
SendMessage(hProgress, PBM_SETRANGE, 0, MAX_PROGRESS<<16);
+ // Fill up the DOS type dropdown
+ IGNORE_RETVAL(ComboBox_AddStringU(hDOSType, "FreeDOS"));
+ IGNORE_RETVAL(ComboBox_AddStringU(hDOSType, "WinMe"));
+ // TODO: enable folder selection
+ // IGNORE_RETVAL(ComboBox_AddStringU(hDOSType, "Custom"));
+ IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, 0));
// Create the string array
StrArrayCreate(&DriveID, MAX_DRIVES);
StrArrayCreate(&DriveLabel, MAX_DRIVES);
@@ -978,6 +986,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
if ((fs == FS_FAT16) || (fs == FS_FAT32)) {
if (!IsWindowEnabled(hDOS)) {
EnableWindow(hDOS, TRUE);
+ EnableWindow(hDOSType, TRUE);
CheckDlgButton(hDlg, IDC_DOS, uDOSChecked);
}
} else {
@@ -985,6 +994,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
uDOSChecked = IsDlgButtonChecked(hMainDialog, IDC_DOS);
CheckDlgButton(hDlg, IDC_DOS, BST_UNCHECKED);
EnableWindow(hDOS, FALSE);
+ EnableWindow(hDOSType, FALSE);
}
}
break;
diff --git a/src/rufus.h b/src/rufus.h
index ab4aa0b5..8581f722 100644
--- a/src/rufus.h
+++ b/src/rufus.h
@@ -116,6 +116,12 @@ enum {
FS_MAX
};
+enum dos_type {
+ DT_FREEDOS = 0,
+ DT_WINME,
+ DT_MAX
+};
+
/* Current drive info */
typedef struct {
DWORD DeviceNumber;
@@ -134,7 +140,7 @@ typedef struct {
*/
extern HINSTANCE hMainInstance;
extern HWND hMainDialog, hStatus, hDeviceList, hCapacity;
-extern HWND hFileSystem, hClusterSize, hLabel;
+extern HWND hFileSystem, hClusterSize, hLabel, hDOSType;
extern float fScale;
extern char szFolderPath[MAX_PATH];
extern DWORD FormatStatus;
@@ -156,7 +162,7 @@ extern HWND CreateTooltip(HWND hControl, const char* message, int duration);
extern void DestroyTooltip(HWND hWnd);
extern void DestroyAllTooltips(void);
extern BOOL Notification(int type, char* title, char* format, ...);
-extern BOOL ExtractMSDOS(const char* path);
+extern BOOL ExtractDOS(const char* path, int dos_type);
extern void __cdecl FormatThread(void* param);
extern BOOL CreatePartition(HANDLE hDrive);
extern HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive);
diff --git a/src/rufus.rc b/src/rufus.rc
index 6cf84f35..9c232122 100644
--- a/src/rufus.rc
+++ b/src/rufus.rc
@@ -30,7 +30,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 206, 278
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
-CAPTION "Rufus v1.0.3.95"
+CAPTION "Rufus v1.0.3.96"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,236,50,14
@@ -48,9 +48,10 @@ BEGIN
EDITTEXT IDC_LABEL,7,131,190,13,ES_AUTOHSCROLL
CONTROL "Check device for bad blocks",IDC_BADBLOCKS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,161,171,10
CONTROL "Quick Format",IDC_QUICKFORMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,173,58,10
- CONTROL "Create a DOS bootable disk",IDC_DOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,185,115,10
+ CONTROL "Create a DOS bootable disk:",IDC_DOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,185,101,10
LTEXT "New volume label",IDC_STATIC,9,121,105,10
CONTROL "",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH | WS_BORDER,7,210,189,9
+ COMBOBOX IDC_DOSTYPE,116,183,45,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
END
IDD_ABOUTBOX DIALOGEX 0, 0, 287, 195
@@ -64,7 +65,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP
CONTROL "http://rufus.akeo.ie",IDC_ABOUT_RUFUS_URL,
"SysLink",WS_TABSTOP,46,47,114,9
- LTEXT "Version 1.0.3 (Build 95)",IDC_STATIC,46,19,78,8
+ LTEXT "Version 1.0.3 (Build 96)",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
@@ -163,8 +164,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,3,95
- PRODUCTVERSION 1,0,3,95
+ FILEVERSION 1,0,3,96
+ PRODUCTVERSION 1,0,3,96
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -181,13 +182,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "akeo.ie"
VALUE "FileDescription", "Rufus"
- VALUE "FileVersion", "1.0.3.95"
+ VALUE "FileVersion", "1.0.3.96"
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.3.95"
+ VALUE "ProductVersion", "1.0.3.96"
END
END
BLOCK "VarFileInfo"
@@ -205,6 +206,14 @@ END
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON ICON "rufus.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// RCDATA
+//
+
+IDR_FD_COMMAND_COM RCDATA "../freedos/COMMAND.COM"
+IDR_FD_KERNEL_SYS RCDATA "../freedos/KERNEL.SYS"
#endif // English resources
/////////////////////////////////////////////////////////////////////////////