diff --git a/.msvc/rufus_2010.vcxproj b/.msvc/rufus_2010.vcxproj
index e571395f..25bfc3f9 100644
--- a/.msvc/rufus_2010.vcxproj
+++ b/.msvc/rufus_2010.vcxproj
@@ -143,11 +143,13 @@
+
+
diff --git a/.msvc/rufus_2010.vcxproj.filters b/.msvc/rufus_2010.vcxproj.filters
index 0c416acc..dc7c559d 100644
--- a/.msvc/rufus_2010.vcxproj.filters
+++ b/.msvc/rufus_2010.vcxproj.filters
@@ -21,6 +21,9 @@
Source Files
+
+ Source Files
+
@@ -35,6 +38,9 @@
Header Files
+
+ Header Files
+
diff --git a/.msvc/rufus_sources b/.msvc/rufus_sources
index e7e6cd33..d167a9cb 100644
--- a/.msvc/rufus_sources
+++ b/.msvc/rufus_sources
@@ -25,4 +25,5 @@ SXS_APPLICATION_MANIFEST=common_controls_and_elevation.manifest
SOURCES=rufus.c \
stdlg.c \
+ msdos.c \
rufus.rc
diff --git a/Makefile b/Makefile
index 18a7d11b..2fc73edf 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ STRIP = strip
CFLAGS = -std=gnu99 -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration -Wno-pointer-sign -Wshadow -O2 -Wl,--subsystem,windows -DWINVER=0x501 -D_WIN32_IE=0x501
LIBS = -lsetupapi -lole32 -lgdi32
-RUFUS_SRC = rufus.c stdlg.c
+RUFUS_SRC = rufus.c stdlg.c msdos.c
.PHONY: all clean
diff --git a/msdos.c b/msdos.c
new file mode 100644
index 00000000..9c6ce37e
--- /dev/null
+++ b/msdos.c
@@ -0,0 +1,145 @@
+/*
+ * Rufus: The Resourceful USB Formatting Utility
+ * MS-DOS boot file extraction, from the FAT12 floppy image in diskcopy.dll
+ * Copyright (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
+ * the Free Software Foundation, either version 3 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, see .
+ */
+
+/* Memory leaks detection - define _CRTDBG_MAP_ALLOC as preprocessor macro */
+#ifdef _CRTDBG_MAP_ALLOC
+#include
+#include
+#endif
+
+#include
+#include
+#include
+
+#include "rufus.h"
+#include "msdos.h"
+
+static BYTE* DiskImage;
+static size_t DiskImageSize;
+
+/* Extract the file identified by FAT RootDir index 'entry' to 'path' */
+static BOOL ExtractFAT(int entry, const char* path)
+{
+ FILE* fd;
+ char filename[MAX_PATH];
+ size_t i, pos;
+ size_t filestart;
+ size_t filesize;
+ size_t FATFile = FAT12_ROOTDIR_OFFSET + entry*FAT12_ROOTDIR_ENTRY_SIZE;
+
+ if ((path == NULL) || ((safe_strlen(path) + 14) > sizeof(filename))) {
+ uprintf("invalid path supplied for MS-DOS FAT extraction\n");
+ return FALSE;
+ }
+ strcpy(filename, path);
+ pos = strlen(path);
+ filename[pos++] = '\\';
+
+ for(i=0; i<8; i++) {
+ if (DiskImage[FATFile + i] == ' ')
+ break;
+ filename[pos++] = DiskImage[FATFile + i];
+ }
+ filename[pos++] = '.';
+ for (i=8; i<11; i++) {
+ if (DiskImage[FATFile + i] == ' ')
+ break;
+ filename[pos++] = DiskImage[FATFile + i];
+ }
+ filename[pos] = 0;
+ GET_ULONG_LE(filesize, DiskImage, FATFile + FAT12_ROOTDIR_FILESIZE);
+ GET_USHORT_LE(filestart, DiskImage, FATFile + FAT12_ROOTDIR_FIRSTCLUSTER);
+ filestart += FAT12_CLUSTER_OFFSET;
+ filestart *= FAT12_CLUSTER_SIZE;
+ if ((filestart + filesize) > DiskImageSize) {
+ uprintf("FAT File %s would be out of bounds\n", filename);
+ return FALSE;
+ }
+
+ fd = fopen(filename, "wb");
+ if (fd == NULL) {
+ uprintf("Unable to create file '%s'.\n", filename);
+ return FALSE;
+ }
+
+ if (fwrite(&DiskImage[filestart], 1, filesize, fd) != filesize) {
+ uprintf("Couldn't write file '%s'.\n", filename);
+ fclose(fd);
+ return FALSE;
+ }
+ fclose(fd);
+
+ uprintf("Succesfully wrote '%s' (%d bytes)\n", filename, filesize);
+
+ // TODO: MSDOS.SYS and IO.SYS should have 'rahs' attributes
+ return TRUE;
+}
+
+/* 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)
+{
+ char dllname[MAX_PATH] = "C:\\Windows\\System32";
+ int i, j;
+ HMODULE hDLL;
+ HRSRC hDiskImage;
+
+ // TODO: optionally extract some more, including "deleted" entries
+ char* extractlist[] = {"MSDOS SYS", "COMMAND COM", "IO SYS"};
+
+ GetSystemDirectoryA(dllname, sizeof(dllname));
+ safe_strcat(dllname, sizeof(dllname), "\\diskcopy.dll");
+ hDLL = LoadLibraryA(dllname);
+ if (hDLL == NULL) {
+ uprintf("Unable to open %s: %s\n", dllname, WindowsErrorString());
+ return FALSE;
+ }
+ hDiskImage = FindResourceA(hDLL, MAKEINTRESOURCEA(1), "BINFILE");
+ if (hDiskImage == NULL) {
+ uprintf("Unable to locate disk image in %s: %s\n", dllname, WindowsErrorString());
+ FreeLibrary(hDLL);
+ return FALSE;
+ }
+ DiskImage = (BYTE*)LockResource(LoadResource(hDLL, hDiskImage));
+ if (DiskImage == NULL) {
+ uprintf("Unable to access disk image in %s: %s\n", dllname, WindowsErrorString());
+ FreeLibrary(hDLL);
+ return FALSE;
+ }
+ DiskImageSize = (size_t)SizeofResource(hDLL, hDiskImage);
+ // Sanity check
+ if (DiskImageSize < 700*1024) {
+ uprintf("MS-DOS disk image is too small (%d bytes)\n", dllname, DiskImageSize);
+ FreeLibrary(hDLL);
+ return FALSE;
+ }
+
+ for (i=0; i
+ *
+ * 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 3 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, see .
+ */
+
+/* http://www.c-jump.com/CIS24/Slides/FAT/lecture.html */
+#define FAT12_ROOTDIR_OFFSET 0x2600
+#define FAT12_ROOTDIR_ENTRY_SIZE 0x20
+#define FAT12_ROOTDIR_NB_ENTRIES 0xE0
+#define FAT12_ROOTDIR_FIRSTCLUSTER 0x1A // No need for high word on a 1.44 MB media
+#define FAT12_ROOTDIR_FILESIZE 0x1C
+#define FAT12_DELETED_ENTRY 0xE5
+
+/* Ideally, we'd read those from the FAT Boot Sector, but we have
+ a pretty good idea of what they are for a 1.44 MB floppy image */
+#define FAT12_CLUSTER_SIZE 0x200 // = sector size
+#define FAT12_DATA_START 0x4200
+#define FAT12_CLUSTER_OFFSET ((FAT12_DATA_START/FAT12_CLUSTER_SIZE)-2) // First cluster in data area is #2
+
+#ifndef GET_ULONG_LE
+#define GET_ULONG_LE(n,b,i) \
+{ \
+ (n) = ( (ULONG) (b)[(i) ] ) \
+ | ( (ULONG) (b)[(i) + 1] << 8 ) \
+ | ( (ULONG) (b)[(i) + 2] << 16 ) \
+ | ( (ULONG) (b)[(i) + 3] << 24 ); \
+}
+#endif
+
+#ifndef GET_USHORT_LE
+#define GET_USHORT_LE(n,b,i) \
+{ \
+ (n) = ( (USHORT) (b)[(i) ] ) \
+ | ( (USHORT) (b)[(i) + 1] << 8 ); \
+}
+#endif