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 /////////////////////////////////////////////////////////////////////////////