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="..\stdlg.c" />
|
||||
<ClCompile Include="..\syslinux.c" />
|
||||
<ClCompile Include="..\vhd.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\badblocks.h" />
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
<ClCompile Include="..\net.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\vhd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\rufus.h">
|
||||
|
|
|
@ -41,4 +41,5 @@ SOURCES=rufus.c \
|
|||
badblocks.c \
|
||||
drive.c \
|
||||
syslinux.c \
|
||||
vhd.c \
|
||||
rufus.rc
|
||||
|
|
|
@ -9,7 +9,7 @@ pkg_v_rc_0 = @echo " RC $@";
|
|||
%_rc.o: %.rc
|
||||
$(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_LDFLAGS = $(AM_LDFLAGS) -mwindows
|
||||
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-dos.$(OBJEXT) rufus-dos_locale.$(OBJEXT) \
|
||||
rufus-badblocks.$(OBJEXT) rufus-syslinux.$(OBJEXT) \
|
||||
rufus-format.$(OBJEXT) rufus-stdio.$(OBJEXT) \
|
||||
rufus-stdlg.$(OBJEXT) rufus-rufus.$(OBJEXT)
|
||||
rufus-vhd.$(OBJEXT) rufus-format.$(OBJEXT) \
|
||||
rufus-stdio.$(OBJEXT) rufus-stdlg.$(OBJEXT) \
|
||||
rufus-rufus.$(OBJEXT)
|
||||
rufus_OBJECTS = $(am_rufus_OBJECTS)
|
||||
rufus_DEPENDENCIES = rufus_rc.o ms-sys/libmssys.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_$(AM_DEFAULT_VERBOSITY))
|
||||
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_LDFLAGS = $(AM_LDFLAGS) -mwindows
|
||||
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@
|
||||
$(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
|
||||
$(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
|
||||
|
|
21
src/format.c
21
src/format.c
|
@ -1122,6 +1122,8 @@ DWORD WINAPI FormatThread(LPVOID param)
|
|||
char drive_name[] = "?:\\";
|
||||
char bb_msg[512];
|
||||
char logfile[MAX_PATH], *userdir;
|
||||
char wim_image[] = "?:\\sources\\install.wim";
|
||||
char efi_dst[] = "?:\\efi\\boot\\bootx64.efi";
|
||||
FILE* log_fd;
|
||||
|
||||
hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE);
|
||||
|
@ -1250,7 +1252,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
|||
if (IsChecked(IDC_DOS)) {
|
||||
if (pt == PT_GPT) {
|
||||
// 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");
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INSTALL_FAILURE;
|
||||
goto out;
|
||||
|
@ -1310,6 +1312,23 @@ DWORD WINAPI FormatThread(LPVOID param)
|
|||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
|
||||
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)) ) {
|
||||
// Apply WinPe fixup
|
||||
|
|
11
src/iso.c
11
src/iso.c
|
@ -55,7 +55,7 @@ RUFUS_ISO_REPORT iso_report;
|
|||
int64_t iso_blocking_status = -1;
|
||||
#define ISO_BLOCKING(x) do {x; iso_blocking_status++; } while(0)
|
||||
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* efi_dirname = "/efi/boot";
|
||||
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) {
|
||||
// Check for a "bootmgr" file in root (psz_path = "")
|
||||
if ((*psz_dirname == 0) && (safe_stricmp(psz_basename, bootmgr_name) == 0))
|
||||
// Check for a "bootmgr(.efi)" file in root (psz_path = "")
|
||||
if (*psz_dirname == 0) {
|
||||
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
|
||||
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
|
||||
if ((iso_report.has_isolinux) || (iso_report.has_efi)) {
|
||||
if ((iso_report.has_isolinux) || (IS_EFI(iso_report))) {
|
||||
if (fs_mask & (1<<FS_FAT32)) {
|
||||
selected_fs = FS_FAT32;
|
||||
} else if (fs_mask & (1<<FS_FAT16)) {
|
||||
|
@ -633,7 +633,7 @@ const GUID PARTITION_BASIC_DATA_GUID = { 0xebd0a0a2, 0xb9e5, 0x4433, {0x87, 0xc0
|
|||
#endif
|
||||
BOOL CreatePartition(HANDLE hDrive)
|
||||
{
|
||||
CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {0}};
|
||||
CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {{0}}};
|
||||
DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0};
|
||||
BOOL r;
|
||||
DWORD size;
|
||||
|
@ -1354,8 +1354,10 @@ DWORD WINAPI ISOScanThread(LPVOID param)
|
|||
safe_free(iso_path);
|
||||
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",
|
||||
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",
|
||||
// TODO: 4GB and UEFI = BAD!!!
|
||||
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");
|
||||
if (iso_report.has_isolinux) {
|
||||
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));
|
||||
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. "
|
||||
"Please select an EFI bootable ISO or change the Partition Scheme to MBR.", "Unsupported GPT ISO...", MB_OK|MB_ICONERROR);
|
||||
break;
|
||||
|
@ -1937,8 +1939,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
}
|
||||
break;
|
||||
} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && ((!iso_report.has_isolinux) && (pt != PT_GPT))) {
|
||||
MessageBoxA(hMainDialog, "Only 'isolinux' based ISO "
|
||||
"images can currently be used with FAT.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
|
||||
MessageBoxA(hMainDialog, "Only isolinux or EFI based ISO "
|
||||
"images can currently be used with FAT/FAT32.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,6 +181,7 @@ typedef struct {
|
|||
#define WINPE_MININT 0x2A
|
||||
#define WINPE_I386 0x15
|
||||
#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 {
|
||||
char label[192]; /* 3*64 to account for UTF-8 */
|
||||
|
@ -191,6 +192,7 @@ typedef struct {
|
|||
BOOL has_4GB_file;
|
||||
BOOL has_bootmgr;
|
||||
BOOL has_efi;
|
||||
BOOL has_win7_efi;
|
||||
BOOL has_isolinux;
|
||||
BOOL has_autorun;
|
||||
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* 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 BOOL WIMExtractFile(const char* wim_image, int index, const char* src, const char* dst);
|
||||
|
||||
__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
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "Rufus v1.3.1.223"
|
||||
CAPTION "Rufus v1.3.1.224"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Start",IDC_START,94,278,50,14
|
||||
|
@ -274,8 +274,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,3,1,223
|
||||
PRODUCTVERSION 1,3,1,223
|
||||
FILEVERSION 1,3,1,224
|
||||
PRODUCTVERSION 1,3,1,224
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -292,13 +292,13 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
||||
VALUE "FileDescription", "Rufus"
|
||||
VALUE "FileVersion", "1.3.1.223"
|
||||
VALUE "FileVersion", "1.3.1.224"
|
||||
VALUE "InternalName", "Rufus"
|
||||
VALUE "LegalCopyright", "(c) 2011-2012 Pete Batard (GPL v3)"
|
||||
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
||||
VALUE "OriginalFilename", "rufus.exe"
|
||||
VALUE "ProductName", "Rufus"
|
||||
VALUE "ProductVersion", "1.3.1.223"
|
||||
VALUE "ProductVersion", "1.3.1.224"
|
||||
END
|
||||
END
|
||||
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