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> |     </Link> | ||||||
|   </ItemDefinitionGroup> |   </ItemDefinitionGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |     <ClCompile Include="..\msdos.c" /> | ||||||
|     <ClCompile Include="..\rufus.c" /> |     <ClCompile Include="..\rufus.c" /> | ||||||
|     <ClCompile Include="..\stdlg.c" /> |     <ClCompile Include="..\stdlg.c" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClInclude Include="..\msapi_utf8.h" /> |     <ClInclude Include="..\msapi_utf8.h" /> | ||||||
|  |     <ClInclude Include="..\msdos.h" /> | ||||||
|     <ClInclude Include="..\rufus.h" /> |     <ClInclude Include="..\rufus.h" /> | ||||||
|     <ClInclude Include="..\license.h" /> |     <ClInclude Include="..\license.h" /> | ||||||
|     <ClInclude Include="..\sys_types.h" /> |     <ClInclude Include="..\sys_types.h" /> | ||||||
|  |  | ||||||
|  | @ -21,6 +21,9 @@ | ||||||
|     <ClCompile Include="..\stdlg.c"> |     <ClCompile Include="..\stdlg.c"> | ||||||
|       <Filter>Source Files</Filter> |       <Filter>Source Files</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\msdos.c"> | ||||||
|  |       <Filter>Source Files</Filter> | ||||||
|  |     </ClCompile> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClInclude Include="..\rufus.h"> |     <ClInclude Include="..\rufus.h"> | ||||||
|  | @ -35,6 +38,9 @@ | ||||||
|     <ClInclude Include="..\sys_types.h"> |     <ClInclude Include="..\sys_types.h"> | ||||||
|       <Filter>Header Files</Filter> |       <Filter>Header Files</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\msdos.h"> | ||||||
|  |       <Filter>Header Files</Filter> | ||||||
|  |     </ClInclude> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <None Include="..\rufus.ico"> |     <None Include="..\rufus.ico"> | ||||||
|  |  | ||||||
|  | @ -25,4 +25,5 @@ SXS_APPLICATION_MANIFEST=common_controls_and_elevation.manifest | ||||||
| 
 | 
 | ||||||
| SOURCES=rufus.c \ | SOURCES=rufus.c \ | ||||||
|         stdlg.c \ |         stdlg.c \ | ||||||
|  |         msdos.c \ | ||||||
|         rufus.rc |         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 | 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 | LIBS   = -lsetupapi -lole32 -lgdi32 | ||||||
| 
 | 
 | ||||||
| RUFUS_SRC = rufus.c stdlg.c | RUFUS_SRC = rufus.c stdlg.c msdos.c | ||||||
| 
 | 
 | ||||||
| .PHONY: all clean | .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…
	
	Add table
		Add a link
		
	
		Reference in a new issue