mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[efi] add support for Windows 7 UEFI boot
* Add WIM file handling in vhd.c to extract bootx64.efi * x64 only, since Microsoft does not provide Win7 x86 EFI support
This commit is contained in:
parent
997c0a0f28
commit
84e4aecfcd
11 changed files with 186 additions and 21 deletions
|
@ -175,6 +175,7 @@
|
||||||
<ClCompile Include="..\stdio.c" />
|
<ClCompile Include="..\stdio.c" />
|
||||||
<ClCompile Include="..\stdlg.c" />
|
<ClCompile Include="..\stdlg.c" />
|
||||||
<ClCompile Include="..\syslinux.c" />
|
<ClCompile Include="..\syslinux.c" />
|
||||||
|
<ClCompile Include="..\vhd.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\badblocks.h" />
|
<ClInclude Include="..\badblocks.h" />
|
||||||
|
|
|
@ -54,6 +54,9 @@
|
||||||
<ClCompile Include="..\net.c">
|
<ClCompile Include="..\net.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\vhd.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\rufus.h">
|
<ClInclude Include="..\rufus.h">
|
||||||
|
|
|
@ -41,4 +41,5 @@ SOURCES=rufus.c \
|
||||||
badblocks.c \
|
badblocks.c \
|
||||||
drive.c \
|
drive.c \
|
||||||
syslinux.c \
|
syslinux.c \
|
||||||
|
vhd.c \
|
||||||
rufus.rc
|
rufus.rc
|
||||||
|
|
|
@ -9,7 +9,7 @@ pkg_v_rc_0 = @echo " RC $@";
|
||||||
%_rc.o: %.rc
|
%_rc.o: %.rc
|
||||||
$(pkg_v_rc)$(WINDRES) $(AM_RCFLAGS) -i $< -o $@
|
$(pkg_v_rc)$(WINDRES) $(AM_RCFLAGS) -i $< -o $@
|
||||||
|
|
||||||
rufus_SOURCES = drive.c icon.c parser.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c format.c stdio.c stdlg.c rufus.c
|
rufus_SOURCES = drive.c icon.c parser.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c vhd.c format.c stdio.c stdlg.c rufus.c
|
||||||
rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./libcdio $(AM_CFLAGS)
|
rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./libcdio $(AM_CFLAGS)
|
||||||
rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows
|
rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows
|
||||||
rufus_LDADD = rufus_rc.o ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
|
rufus_LDADD = rufus_rc.o ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
|
||||||
|
|
|
@ -47,8 +47,9 @@ am_rufus_OBJECTS = rufus-drive.$(OBJEXT) rufus-icon.$(OBJEXT) \
|
||||||
rufus-parser.$(OBJEXT) rufus-iso.$(OBJEXT) rufus-net.$(OBJEXT) \
|
rufus-parser.$(OBJEXT) rufus-iso.$(OBJEXT) rufus-net.$(OBJEXT) \
|
||||||
rufus-dos.$(OBJEXT) rufus-dos_locale.$(OBJEXT) \
|
rufus-dos.$(OBJEXT) rufus-dos_locale.$(OBJEXT) \
|
||||||
rufus-badblocks.$(OBJEXT) rufus-syslinux.$(OBJEXT) \
|
rufus-badblocks.$(OBJEXT) rufus-syslinux.$(OBJEXT) \
|
||||||
rufus-format.$(OBJEXT) rufus-stdio.$(OBJEXT) \
|
rufus-vhd.$(OBJEXT) rufus-format.$(OBJEXT) \
|
||||||
rufus-stdlg.$(OBJEXT) rufus-rufus.$(OBJEXT)
|
rufus-stdio.$(OBJEXT) rufus-stdlg.$(OBJEXT) \
|
||||||
|
rufus-rufus.$(OBJEXT)
|
||||||
rufus_OBJECTS = $(am_rufus_OBJECTS)
|
rufus_OBJECTS = $(am_rufus_OBJECTS)
|
||||||
rufus_DEPENDENCIES = rufus_rc.o ms-sys/libmssys.a \
|
rufus_DEPENDENCIES = rufus_rc.o ms-sys/libmssys.a \
|
||||||
syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
|
syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
|
||||||
|
@ -183,7 +184,7 @@ SUBDIRS = ms-sys syslinux/libfat syslinux/libinstaller libcdio/iso9660 libcdio/u
|
||||||
pkg_v_rc = $(pkg_v_rc_$(V))
|
pkg_v_rc = $(pkg_v_rc_$(V))
|
||||||
pkg_v_rc_ = $(pkg_v_rc_$(AM_DEFAULT_VERBOSITY))
|
pkg_v_rc_ = $(pkg_v_rc_$(AM_DEFAULT_VERBOSITY))
|
||||||
pkg_v_rc_0 = @echo " RC $@";
|
pkg_v_rc_0 = @echo " RC $@";
|
||||||
rufus_SOURCES = drive.c icon.c parser.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c format.c stdio.c stdlg.c rufus.c
|
rufus_SOURCES = drive.c icon.c parser.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c vhd.c format.c stdio.c stdlg.c rufus.c
|
||||||
rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./libcdio $(AM_CFLAGS)
|
rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./libcdio $(AM_CFLAGS)
|
||||||
rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows
|
rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows
|
||||||
rufus_LDADD = rufus_rc.o ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
|
rufus_LDADD = rufus_rc.o ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
|
||||||
|
@ -316,6 +317,14 @@ rufus-syslinux.obj: syslinux.c
|
||||||
$(AM_V_CC) @AM_BACKSLASH@
|
$(AM_V_CC) @AM_BACKSLASH@
|
||||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-syslinux.obj `if test -f 'syslinux.c'; then $(CYGPATH_W) 'syslinux.c'; else $(CYGPATH_W) '$(srcdir)/syslinux.c'; fi`
|
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-syslinux.obj `if test -f 'syslinux.c'; then $(CYGPATH_W) 'syslinux.c'; else $(CYGPATH_W) '$(srcdir)/syslinux.c'; fi`
|
||||||
|
|
||||||
|
rufus-vhd.o: vhd.c
|
||||||
|
$(AM_V_CC) @AM_BACKSLASH@
|
||||||
|
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-vhd.o `test -f 'vhd.c' || echo '$(srcdir)/'`vhd.c
|
||||||
|
|
||||||
|
rufus-vhd.obj: vhd.c
|
||||||
|
$(AM_V_CC) @AM_BACKSLASH@
|
||||||
|
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-vhd.obj `if test -f 'vhd.c'; then $(CYGPATH_W) 'vhd.c'; else $(CYGPATH_W) '$(srcdir)/vhd.c'; fi`
|
||||||
|
|
||||||
rufus-format.o: format.c
|
rufus-format.o: format.c
|
||||||
$(AM_V_CC) @AM_BACKSLASH@
|
$(AM_V_CC) @AM_BACKSLASH@
|
||||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-format.o `test -f 'format.c' || echo '$(srcdir)/'`format.c
|
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-format.o `test -f 'format.c' || echo '$(srcdir)/'`format.c
|
||||||
|
|
21
src/format.c
21
src/format.c
|
@ -1122,6 +1122,8 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
char drive_name[] = "?:\\";
|
char drive_name[] = "?:\\";
|
||||||
char bb_msg[512];
|
char bb_msg[512];
|
||||||
char logfile[MAX_PATH], *userdir;
|
char logfile[MAX_PATH], *userdir;
|
||||||
|
char wim_image[] = "?:\\sources\\install.wim";
|
||||||
|
char efi_dst[] = "?:\\efi\\boot\\bootx64.efi";
|
||||||
FILE* log_fd;
|
FILE* log_fd;
|
||||||
|
|
||||||
hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE);
|
hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE);
|
||||||
|
@ -1250,7 +1252,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
if (IsChecked(IDC_DOS)) {
|
if (IsChecked(IDC_DOS)) {
|
||||||
if (pt == PT_GPT) {
|
if (pt == PT_GPT) {
|
||||||
// For once, no need to do anything - just check our sanity
|
// For once, no need to do anything - just check our sanity
|
||||||
if ( (dt != DT_ISO) || (!iso_report.has_efi) || (fs > FS_FAT32) ) {
|
if ( (dt != DT_ISO) || (!IS_EFI(iso_report)) || (fs > FS_FAT32) ) {
|
||||||
uprintf("Spock gone crazy error!\n");
|
uprintf("Spock gone crazy error!\n");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INSTALL_FAILURE;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INSTALL_FAILURE;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1310,6 +1312,23 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if ((pt == PT_GPT) && (!iso_report.has_efi) && (iso_report.has_win7_efi)) {
|
||||||
|
// TODO: progress
|
||||||
|
PrintStatus(0, TRUE, "Win7 EFI boot setup (this may take a while)...");
|
||||||
|
wim_image[0] = drive_name[0];
|
||||||
|
efi_dst[0] = drive_name[0];
|
||||||
|
efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = 0;
|
||||||
|
if (!CreateDirectoryA(efi_dst, 0)) {
|
||||||
|
uprintf("Could not create directory '%s': %s\n", WindowsErrorString());
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
||||||
|
} else {
|
||||||
|
efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\';
|
||||||
|
if (!WIMExtractFile(wim_image, 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst)) {
|
||||||
|
uprintf("Failed to setup Win7 EFI boot\n");
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( (pt == PT_MBR) && (IS_WINPE(iso_report.winpe)) ) {
|
if ( (pt == PT_MBR) && (IS_WINPE(iso_report.winpe)) ) {
|
||||||
// Apply WinPe fixup
|
// Apply WinPe fixup
|
||||||
|
|
13
src/iso.c
13
src/iso.c
|
@ -55,7 +55,7 @@ RUFUS_ISO_REPORT iso_report;
|
||||||
int64_t iso_blocking_status = -1;
|
int64_t iso_blocking_status = -1;
|
||||||
#define ISO_BLOCKING(x) do {x; iso_blocking_status++; } while(0)
|
#define ISO_BLOCKING(x) do {x; iso_blocking_status++; } while(0)
|
||||||
static const char* psz_extract_dir;
|
static const char* psz_extract_dir;
|
||||||
static const char* bootmgr_name = "bootmgr";
|
static const char* bootmgr_efi_name = "bootmgr.efi";
|
||||||
static const char* ldlinux_name = "ldlinux.sys";
|
static const char* ldlinux_name = "ldlinux.sys";
|
||||||
static const char* efi_dirname = "/efi/boot";
|
static const char* efi_dirname = "/efi/boot";
|
||||||
static const char* isolinux_name[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"};
|
static const char* isolinux_name[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"};
|
||||||
|
@ -123,9 +123,14 @@ static __inline BOOL check_iso_props(const char* psz_dirname, BOOL* is_syslinux_
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scan_only) {
|
if (scan_only) {
|
||||||
// Check for a "bootmgr" file in root (psz_path = "")
|
// Check for a "bootmgr(.efi)" file in root (psz_path = "")
|
||||||
if ((*psz_dirname == 0) && (safe_stricmp(psz_basename, bootmgr_name) == 0))
|
if (*psz_dirname == 0) {
|
||||||
iso_report.has_bootmgr = TRUE;
|
if (safe_strnicmp(psz_basename, bootmgr_efi_name, sizeof(bootmgr_efi_name)-4) == 0)
|
||||||
|
iso_report.has_bootmgr = TRUE;
|
||||||
|
if (safe_stricmp(psz_basename, bootmgr_efi_name) == 0) {
|
||||||
|
iso_report.has_win7_efi = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check for the EFI boot directory
|
// Check for the EFI boot directory
|
||||||
if (safe_stricmp(psz_dirname, efi_dirname) == 0)
|
if (safe_stricmp(psz_dirname, efi_dirname) == 0)
|
||||||
|
|
16
src/rufus.c
16
src/rufus.c
|
@ -491,7 +491,7 @@ static void SetFSFromISO(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Syslinux and EFI have precedence over bootmgr
|
// Syslinux and EFI have precedence over bootmgr
|
||||||
if ((iso_report.has_isolinux) || (iso_report.has_efi)) {
|
if ((iso_report.has_isolinux) || (IS_EFI(iso_report))) {
|
||||||
if (fs_mask & (1<<FS_FAT32)) {
|
if (fs_mask & (1<<FS_FAT32)) {
|
||||||
selected_fs = FS_FAT32;
|
selected_fs = FS_FAT32;
|
||||||
} else if (fs_mask & (1<<FS_FAT16)) {
|
} else if (fs_mask & (1<<FS_FAT16)) {
|
||||||
|
@ -633,7 +633,7 @@ const GUID PARTITION_BASIC_DATA_GUID = { 0xebd0a0a2, 0xb9e5, 0x4433, {0x87, 0xc0
|
||||||
#endif
|
#endif
|
||||||
BOOL CreatePartition(HANDLE hDrive)
|
BOOL CreatePartition(HANDLE hDrive)
|
||||||
{
|
{
|
||||||
CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {0}};
|
CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {{0}}};
|
||||||
DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0};
|
DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0};
|
||||||
BOOL r;
|
BOOL r;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
@ -1354,8 +1354,10 @@ DWORD WINAPI ISOScanThread(LPVOID param)
|
||||||
safe_free(iso_path);
|
safe_free(iso_path);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
uprintf("ISO label: '%s'\r\n Size: %lld bytes\r\n Has a >4GB file: %s\r\n Uses EFI: %s\r\n Uses Bootmgr: %s\r\n Uses WinPE: %s%s\r\n Uses isolinux: %s\n",
|
// TODO: 4GB and UEFI = BAD!!!
|
||||||
iso_report.label, iso_report.projected_size, iso_report.has_4GB_file?"Yes":"No", iso_report.has_efi?"Yes":"No", iso_report.has_bootmgr?"Yes":"No",
|
uprintf("ISO label: '%s'\r\n Size: %lld bytes\r\n Has a >4GB file: %s\r\n Uses EFI: %s%s\r\n Uses Bootmgr: %s\r\n Uses WinPE: %s%s\r\n Uses isolinux: %s\n",
|
||||||
|
iso_report.label, iso_report.projected_size, iso_report.has_4GB_file?"Yes":"No", (iso_report.has_efi || iso_report.has_win7_efi)?"Yes":"No",
|
||||||
|
(iso_report.has_win7_efi && (!iso_report.has_efi))?" (win7_x64)":"", iso_report.has_bootmgr?"Yes":"No",
|
||||||
IS_WINPE(iso_report.winpe)?"Yes":"No", (iso_report.uses_minint)?" (with /minint)":"", iso_report.has_isolinux?"Yes":"No");
|
IS_WINPE(iso_report.winpe)?"Yes":"No", (iso_report.uses_minint)?" (with /minint)":"", iso_report.has_isolinux?"Yes":"No");
|
||||||
if (iso_report.has_isolinux) {
|
if (iso_report.has_isolinux) {
|
||||||
for (i=0; i<NB_OLD_C32; i++) {
|
for (i=0; i<NB_OLD_C32; i++) {
|
||||||
|
@ -1922,7 +1924,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
}
|
}
|
||||||
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
|
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
|
||||||
pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme));
|
pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme));
|
||||||
if ((pt == PT_GPT) && ((!iso_report.has_efi) || ((fs > FS_FAT32)))) {
|
if ((pt == PT_GPT) && ((!IS_EFI(iso_report)) || ((fs > FS_FAT32)))) {
|
||||||
MessageBoxA(hMainDialog, "When using GPT, only EFI bootable ISOs are supported. "
|
MessageBoxA(hMainDialog, "When using GPT, only EFI bootable ISOs are supported. "
|
||||||
"Please select an EFI bootable ISO or change the Partition Scheme to MBR.", "Unsupported GPT ISO...", MB_OK|MB_ICONERROR);
|
"Please select an EFI bootable ISO or change the Partition Scheme to MBR.", "Unsupported GPT ISO...", MB_OK|MB_ICONERROR);
|
||||||
break;
|
break;
|
||||||
|
@ -1937,8 +1939,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && ((!iso_report.has_isolinux) && (pt != PT_GPT))) {
|
} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && ((!iso_report.has_isolinux) && (pt != PT_GPT))) {
|
||||||
MessageBoxA(hMainDialog, "Only 'isolinux' based ISO "
|
MessageBoxA(hMainDialog, "Only isolinux or EFI based ISO "
|
||||||
"images can currently be used with FAT.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
|
"images can currently be used with FAT/FAT32.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,6 +181,7 @@ typedef struct {
|
||||||
#define WINPE_MININT 0x2A
|
#define WINPE_MININT 0x2A
|
||||||
#define WINPE_I386 0x15
|
#define WINPE_I386 0x15
|
||||||
#define IS_WINPE(r) (((r&WINPE_MININT) == WINPE_MININT)||((r&WINPE_I386) == WINPE_I386))
|
#define IS_WINPE(r) (((r&WINPE_MININT) == WINPE_MININT)||((r&WINPE_I386) == WINPE_I386))
|
||||||
|
#define IS_EFI(r) ((r.has_efi) || (r.has_win7_efi))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char label[192]; /* 3*64 to account for UTF-8 */
|
char label[192]; /* 3*64 to account for UTF-8 */
|
||||||
|
@ -191,6 +192,7 @@ typedef struct {
|
||||||
BOOL has_4GB_file;
|
BOOL has_4GB_file;
|
||||||
BOOL has_bootmgr;
|
BOOL has_bootmgr;
|
||||||
BOOL has_efi;
|
BOOL has_efi;
|
||||||
|
BOOL has_win7_efi;
|
||||||
BOOL has_isolinux;
|
BOOL has_isolinux;
|
||||||
BOOL has_autorun;
|
BOOL has_autorun;
|
||||||
BOOL has_old_c32[NB_OLD_C32];
|
BOOL has_old_c32[NB_OLD_C32];
|
||||||
|
@ -296,6 +298,7 @@ extern char* get_token_data_buffer(const char* token, unsigned int n, const char
|
||||||
extern char* insert_section_data(const char* filename, const char* section, const char* data, BOOL dos2unix);
|
extern char* insert_section_data(const char* filename, const char* section, const char* data, BOOL dos2unix);
|
||||||
extern char* replace_in_token_data(const char* filename, const char* token, const char* src, const char* rep, BOOL dos2unix);
|
extern char* replace_in_token_data(const char* filename, const char* token, const char* src, const char* rep, BOOL dos2unix);
|
||||||
extern void parse_update(char* buf, size_t len);
|
extern void parse_update(char* buf, size_t len);
|
||||||
|
extern BOOL WIMExtractFile(const char* wim_image, int index, const char* src, const char* dst);
|
||||||
|
|
||||||
__inline static BOOL UnlockDrive(HANDLE hDrive)
|
__inline static BOOL UnlockDrive(HANDLE hDrive)
|
||||||
{
|
{
|
||||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -30,7 +30,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 206, 316
|
IDD_DIALOG DIALOGEX 12, 12, 206, 316
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_APPWINDOW
|
EXSTYLE WS_EX_APPWINDOW
|
||||||
CAPTION "Rufus v1.3.1.223"
|
CAPTION "Rufus v1.3.1.224"
|
||||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "Start",IDC_START,94,278,50,14
|
DEFPUSHBUTTON "Start",IDC_START,94,278,50,14
|
||||||
|
@ -274,8 +274,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,3,1,223
|
FILEVERSION 1,3,1,224
|
||||||
PRODUCTVERSION 1,3,1,223
|
PRODUCTVERSION 1,3,1,224
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -292,13 +292,13 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "1.3.1.223"
|
VALUE "FileVersion", "1.3.1.224"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "(c) 2011-2012 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "(c) 2011-2012 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
||||||
VALUE "OriginalFilename", "rufus.exe"
|
VALUE "OriginalFilename", "rufus.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "1.3.1.223"
|
VALUE "ProductVersion", "1.3.1.224"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
122
src/vhd.c
Normal file
122
src/vhd.c
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
* Rufus: The Reliable USB Formatting Utility
|
||||||
|
* Virtual Disk Handling functions
|
||||||
|
* Copyright (c) 2013 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rufus.h"
|
||||||
|
#include "msapi_utf8.h"
|
||||||
|
|
||||||
|
#define WIM_GENERIC_READ GENERIC_READ
|
||||||
|
#define WIM_OPEN_EXISTING OPEN_EXISTING
|
||||||
|
|
||||||
|
typedef HANDLE (WINAPI *WIMCreateFile_t)(
|
||||||
|
PWSTR pszWimPath,
|
||||||
|
DWORD dwDesiredAccess,
|
||||||
|
DWORD dwCreationDisposition,
|
||||||
|
DWORD dwFlagsAndAttributes,
|
||||||
|
DWORD dwCompressionType,
|
||||||
|
PDWORD pdwCreationResult
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *WIMSetTemporaryPath_t)(
|
||||||
|
HANDLE hWim,
|
||||||
|
PWSTR pszPath
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef HANDLE (WINAPI *WIMLoadImage_t)(
|
||||||
|
HANDLE hWim,
|
||||||
|
DWORD dwImageIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *WIMExtractImagePath_t)(
|
||||||
|
HANDLE hImage,
|
||||||
|
PWSTR pszImagePath,
|
||||||
|
PWSTR pszDestinationPath,
|
||||||
|
DWORD dwExtractFlags
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *WIMCloseHandle_t)(
|
||||||
|
HANDLE hObj
|
||||||
|
);
|
||||||
|
|
||||||
|
// Extract a file from a WIM image
|
||||||
|
// NB: Don't bother trying to get progress from a WIM callback - it doesn't work!
|
||||||
|
BOOL WIMExtractFile(const char* image, int index, const char* src, const char* dst)
|
||||||
|
{
|
||||||
|
BOOL r = FALSE;
|
||||||
|
DWORD dw = 0;
|
||||||
|
HANDLE hWim = NULL;
|
||||||
|
HANDLE hImage = NULL;
|
||||||
|
wchar_t wtemp[MAX_PATH] = {0};
|
||||||
|
wchar_t* wimage = utf8_to_wchar(image);
|
||||||
|
wchar_t* wsrc = utf8_to_wchar(src);
|
||||||
|
wchar_t* wdst = utf8_to_wchar(dst);
|
||||||
|
PF_DECL(WIMCreateFile);
|
||||||
|
PF_DECL(WIMSetTemporaryPath);
|
||||||
|
PF_DECL(WIMLoadImage);
|
||||||
|
PF_DECL(WIMExtractImagePath);
|
||||||
|
PF_DECL(WIMCloseHandle);
|
||||||
|
|
||||||
|
PF_INIT_OR_OUT(WIMCreateFile, wimgapi);
|
||||||
|
PF_INIT_OR_OUT(WIMSetTemporaryPath, wimgapi);
|
||||||
|
PF_INIT_OR_OUT(WIMLoadImage, wimgapi);
|
||||||
|
PF_INIT_OR_OUT(WIMExtractImagePath, wimgapi);
|
||||||
|
PF_INIT_OR_OUT(WIMCloseHandle, wimgapi);
|
||||||
|
|
||||||
|
// TODO: check for NULL and missing wimgapi.dll
|
||||||
|
|
||||||
|
if (GetTempPathW(ARRAYSIZE(wtemp), wtemp) == 0) {
|
||||||
|
uprintf("Could not fetch temp path: %s\n", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
uprintf("Opening: %s (index #%d)\n", image, index);
|
||||||
|
hWim = pfWIMCreateFile(wimage, WIM_GENERIC_READ, WIM_OPEN_EXISTING, 0, 0, &dw);
|
||||||
|
if (hWim == NULL) {
|
||||||
|
uprintf(" Error: '%s': %s\n", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pfWIMSetTemporaryPath(hWim, wtemp)) {
|
||||||
|
uprintf(" Error setting temp path: %s\n", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
hImage = pfWIMLoadImage(hWim, (DWORD)index);
|
||||||
|
if (hImage == NULL) {
|
||||||
|
uprintf(" Error setting index: %s.\n", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
uprintf("Extracting: %s (From \\%s)\n", dst, src);
|
||||||
|
if (!pfWIMExtractImagePath(hImage, wsrc, wdst, 0)) {
|
||||||
|
uprintf(" Could not extract file: %s.\n", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
r = TRUE;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if ((hImage != NULL) || (hWim != NULL)) {
|
||||||
|
uprintf("Closing: %s\n", image);
|
||||||
|
}
|
||||||
|
if (hImage != NULL) pfWIMCloseHandle(hImage);
|
||||||
|
if (hWim != NULL) pfWIMCloseHandle(hWim);
|
||||||
|
safe_free(wimage);
|
||||||
|
safe_free(wsrc);
|
||||||
|
safe_free(wdst);
|
||||||
|
return r;
|
||||||
|
}
|
Loading…
Reference in a new issue