mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[boot] added MS-DOS file extraction from diskcopy.dll
* diskcopy.dll contains a resource ('BINFILE') that is a 1.4MB floppy image of a bootable MS-DOS disk (FAT12) * we can extract these files and use them for bootable USB
This commit is contained in:
parent
60ac60ceb0
commit
f75a9fc7cb
6 changed files with 205 additions and 1 deletions
|
@ -143,11 +143,13 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\msdos.c" />
|
||||
<ClCompile Include="..\rufus.c" />
|
||||
<ClCompile Include="..\stdlg.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\msapi_utf8.h" />
|
||||
<ClInclude Include="..\msdos.h" />
|
||||
<ClInclude Include="..\rufus.h" />
|
||||
<ClInclude Include="..\license.h" />
|
||||
<ClInclude Include="..\sys_types.h" />
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
<ClCompile Include="..\stdlg.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\msdos.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\rufus.h">
|
||||
|
@ -35,6 +38,9 @@
|
|||
<ClInclude Include="..\sys_types.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\msdos.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\rufus.ico">
|
||||
|
|
|
@ -25,4 +25,5 @@ SXS_APPLICATION_MANIFEST=common_controls_and_elevation.manifest
|
|||
|
||||
SOURCES=rufus.c \
|
||||
stdlg.c \
|
||||
msdos.c \
|
||||
rufus.rc
|
||||
|
|
2
Makefile
2
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
|
||||
|
||||
|
|
145
msdos.c
Normal file
145
msdos.c
Normal file
|
@ -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 <pete@akeo.ie>
|
||||
*
|
||||
* 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.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Memory leaks detection - define _CRTDBG_MAP_ALLOC as preprocessor macro */
|
||||
#ifdef _CRTDBG_MAP_ALLOC
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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<FAT12_ROOTDIR_NB_ENTRIES; i++) {
|
||||
if (DiskImage[FAT12_ROOTDIR_OFFSET + i*FAT12_ROOTDIR_ENTRY_SIZE] == FAT12_DELETED_ENTRY)
|
||||
continue;
|
||||
for (j=0; j<ARRAYSIZE(extractlist); j++) {
|
||||
if (memcmp(extractlist[j], &DiskImage[FAT12_ROOTDIR_OFFSET + i*FAT12_ROOTDIR_ENTRY_SIZE], 8+3) == 0) {
|
||||
ExtractFAT(i, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreeLibrary(hDLL);
|
||||
return TRUE;
|
||||
}
|
50
msdos.h
Normal file
50
msdos.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Rufus: The Resourceful USB Formatting Utility
|
||||
* MS-DOS boot file extraction, from the FAT12 floppy image in diskcopy.dll
|
||||
* Copyright (c) 2011 Pete Batard <pete@akeo.ie>
|
||||
*
|
||||
* 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.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* 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
|
Loading…
Reference in a new issue