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…
	
	Add table
		Add a link
		
	
		Reference in a new issue