[wue] add fallback to index 1 if boot.wim index 2 is not available

* Some "unofficial" Windows ISOs use a custom boot.wim that only includes the Setup
  image at index 1, rather than at index 2, after the PE image, for official ISOs.
* Also refactor to add a long needed vhd.h header.
* Also fix a MinGW warning.
This commit is contained in:
Pete Batard 2022-08-02 20:14:29 +01:00
parent eda1f59a38
commit fbad63666e
No known key found for this signature in database
GPG Key ID: 38E0CF5E69EDD671
11 changed files with 243 additions and 134 deletions

View File

@ -405,6 +405,7 @@
<ClInclude Include="..\src\dev.h" />
<ClInclude Include="..\src\ui.h" />
<ClInclude Include="..\src\ui_data.h" />
<ClInclude Include="..\src\vhd.h" />
<ClInclude Include="..\src\winio.h" />
<ClInclude Include="..\src\wue.h" />
</ItemGroup>

View File

@ -188,6 +188,9 @@
<ClInclude Include="..\src\wue.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\vhd.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\res\rufus.ico">

2
configure vendored
View File

@ -4726,7 +4726,7 @@ fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CFLAGS="${saved_CFLAGS}"
AM_CFLAGS="$AM_CFLAGS -DUNICODE -D_UNICODE -UNDEBUG -DCOBJMACROS -D__USE_MINGW_ANSI_STDIO=0 -std=gnu99 -Wshadow -Wall -Wformat-security -Wundef -Wunused -Wstrict-prototypes -Wno-restrict -Werror-implicit-function-declaration -Wbidi-chars=none $nopointersign_cflags"
AM_CFLAGS="$AM_CFLAGS -DUNICODE -D_UNICODE -UNDEBUG -DCOBJMACROS -D__USE_MINGW_ANSI_STDIO=0 -std=gnu99 -Wshadow -Wall -Wformat-security -Wundef -Wunused -Wstrict-prototypes -Wno-restrict -Wno-array-bounds -Werror-implicit-function-declaration -Wbidi-chars=none $nopointersign_cflags"

View File

@ -64,7 +64,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
[nopointersign_cflags="-Wno-pointer-sign"], [nopointersign_cflags=""])
CFLAGS="${saved_CFLAGS}"
AM_CFLAGS="$AM_CFLAGS -DUNICODE -D_UNICODE -UNDEBUG -DCOBJMACROS -D__USE_MINGW_ANSI_STDIO=0 -std=gnu99 -Wshadow -Wall -Wformat-security -Wundef -Wunused -Wstrict-prototypes -Wno-restrict -Werror-implicit-function-declaration -Wbidi-chars=none $nopointersign_cflags"
AM_CFLAGS="$AM_CFLAGS -DUNICODE -D_UNICODE -UNDEBUG -DCOBJMACROS -D__USE_MINGW_ANSI_STDIO=0 -std=gnu99 -Wshadow -Wall -Wformat-security -Wundef -Wunused -Wstrict-prototypes -Wno-restrict -Wno-array-bounds -Werror-implicit-function-declaration -Wbidi-chars=none $nopointersign_cflags"
AC_SUBST([VISIBILITY_CFLAGS])
AC_SUBST([AM_CFLAGS])

View File

@ -44,6 +44,7 @@
#include "localization.h"
#include "br.h"
#include "vhd.h"
#include "wue.h"
#include "fat16.h"
#include "fat32.h"

View File

@ -47,6 +47,7 @@
#include "ui.h"
#include "re.h"
#include "vhd.h"
#include "wue.h"
#include "drive.h"
#include "settings.h"
@ -3770,9 +3771,8 @@ relaunch:
// Ctrl-T => Alternate Test mode that doesn't require a full rebuild
if ((ctrl_without_focus || ((GetKeyState(VK_CONTROL) & 0x8000) && (msg.message == WM_KEYDOWN)))
&& (msg.wParam == 'T')) {
//extern int TestChecksum(void);
//TestChecksum();
ListVdsVolumes(FALSE);
int index = 2;
uprintf("Index %d is %s", index, WimIsValidIndex("C:\\tmp\\boot1.wim", index) ? "valid" : "invalid");
continue;
}
#endif

View File

@ -629,15 +629,6 @@ extern char* replace_in_token_data(const char* filename, const char* token, cons
extern char* replace_char(const char* src, const char c, const char* rep);
extern void parse_update(char* buf, size_t len);
extern void* get_data_from_asn1(const uint8_t* buf, size_t buf_len, const char* oid_str, uint8_t asn1_type, size_t* data_len);
extern uint8_t WimExtractCheck(BOOL bSilent);
extern BOOL WimExtractFile(const char* wim_image, int index, const char* src, const char* dst, BOOL bSilent);
extern BOOL WimExtractFile_API(const char* image, int index, const char* src, const char* dst, BOOL bSilent);
extern BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char* dst, BOOL bSilent);
extern BOOL WimApplyImage(const char* image, int index, const char* dst);
extern char* WimMountImage(const char* image, int index);
extern BOOL WimUnmountImage(const char* image, int index);
extern int8_t IsBootableImage(const char* path);
extern BOOL AppendVHDFooter(const char* vhd_path);
extern int IsHDD(DWORD DriveIndex, uint16_t vid, uint16_t pid, const char* strid);
extern char* GetSignatureName(const char* path, const char* country_code, BOOL bSilent);
extern uint64_t GetSignatureTimeStamp(const char* path);

View File

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES
CAPTION "Rufus 3.20.1927"
CAPTION "Rufus 3.20.1928"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -395,8 +395,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,20,1927,0
PRODUCTVERSION 3,20,1927,0
FILEVERSION 3,20,1928,0
PRODUCTVERSION 3,20,1928,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -414,13 +414,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "3.20.1927"
VALUE "FileVersion", "3.20.1928"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2022 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-3.20.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "3.20.1927"
VALUE "ProductVersion", "3.20.1928"
END
END
BLOCK "VarFileInfo"

179
src/vhd.c
View File

@ -23,6 +23,7 @@
#include <rpc.h>
#include <time.h>
#include "vhd.h"
#include "rufus.h"
#include "missing.h"
#include "resource.h"
@ -32,110 +33,7 @@
#include "registry.h"
#include "bled/bled.h"
#define VHD_FOOTER_COOKIE { 'c', 'o', 'n', 'e', 'c', 't', 'i', 'x' }
#define VHD_FOOTER_FEATURES_NONE 0x00000000
#define VHD_FOOTER_FEATURES_TEMPORARY 0x00000001
#define VHD_FOOTER_FEATURES_RESERVED 0x00000002
#define VHD_FOOTER_FILE_FORMAT_V1_0 0x00010000
#define VHD_FOOTER_DATA_OFFSET_FIXED_DISK 0xFFFFFFFFFFFFFFFFULL
#define VHD_FOOTER_CREATOR_HOST_OS_WINDOWS { 'W', 'i', '2', 'k' }
#define VHD_FOOTER_CREATOR_HOST_OS_MAC { 'M', 'a', 'c', ' ' }
#define VHD_FOOTER_TYPE_FIXED_HARD_DISK 0x00000002
#define VHD_FOOTER_TYPE_DYNAMIC_HARD_DISK 0x00000003
#define VHD_FOOTER_TYPE_DIFFER_HARD_DISK 0x00000004
#define WIM_MAGIC 0x0000004D4957534DULL // "MSWIM\0\0\0"
#define WIM_HAS_API_EXTRACT 1
#define WIM_HAS_7Z_EXTRACT 2
#define WIM_HAS_API_APPLY 4
#define WIM_HAS_EXTRACT(r) (r & (WIM_HAS_API_EXTRACT|WIM_HAS_7Z_EXTRACT))
#define SECONDS_SINCE_JAN_1ST_2000 946684800
#define INVALID_CALLBACK_VALUE 0xFFFFFFFF
#define WIM_FLAG_RESERVED 0x00000001
#define WIM_FLAG_VERIFY 0x00000002
#define WIM_FLAG_INDEX 0x00000004
#define WIM_FLAG_NO_APPLY 0x00000008
#define WIM_FLAG_NO_DIRACL 0x00000010
#define WIM_FLAG_NO_FILEACL 0x00000020
#define WIM_FLAG_SHARE_WRITE 0x00000040
#define WIM_FLAG_FILEINFO 0x00000080
#define WIM_FLAG_NO_RP_FIX 0x00000100
// Bitmask for the kind of progress we want to report in the WIM progress callback
#define WIM_REPORT_PROGRESS 0x00000001
#define WIM_REPORT_PROCESS 0x00000002
#define WIM_REPORT_FILEINFO 0x00000004
// From https://docs.microsoft.com/en-us/previous-versions/msdn10/dd834960(v=msdn.10)
// as well as https://msfn.org/board/topic/150700-wimgapi-wimmountimage-progressbar/
enum WIMMessage {
WIM_MSG = WM_APP + 0x1476,
WIM_MSG_TEXT,
WIM_MSG_PROGRESS, // Indicates an update in the progress of an image application.
WIM_MSG_PROCESS, // Enables the caller to prevent a file or a directory from being captured or applied.
WIM_MSG_SCANNING, // Indicates that volume information is being gathered during an image capture.
WIM_MSG_SETRANGE, // Indicates the number of files that will be captured or applied.
WIM_MSG_SETPOS, // Indicates the number of files that have been captured or applied.
WIM_MSG_STEPIT, // Indicates that a file has been either captured or applied.
WIM_MSG_COMPRESS, // Enables the caller to prevent a file resource from being compressed during a capture.
WIM_MSG_ERROR, // Alerts the caller that an error has occurred while capturing or applying an image.
WIM_MSG_ALIGNMENT, // Enables the caller to align a file resource on a particular alignment boundary.
WIM_MSG_RETRY, // Sent when the file is being reapplied because of a network timeout.
WIM_MSG_SPLIT, // Enables the caller to align a file resource on a particular alignment boundary.
WIM_MSG_FILEINFO, // Used in conjunction with WimApplyImages()'s WIM_FLAG_FILEINFO flag to provide detailed file info.
WIM_MSG_INFO, // Sent when an info message is available.
WIM_MSG_WARNING, // Sent when a warning message is available.
WIM_MSG_CHK_PROCESS,
WIM_MSG_SUCCESS = 0,
WIM_MSG_ABORT_IMAGE = -1
};
/*
* VHD Fixed HD footer (Big Endian)
* http://download.microsoft.com/download/f/f/e/ffef50a5-07dd-4cf8-aaa3-442c0673a029/Virtual%20Hard%20Disk%20Format%20Spec_10_18_06.doc
* NB: If a dymamic implementation is needed, check the GPL v3 compatible C++ implementation from:
* https://sourceforge.net/p/urbackup/backend/ci/master/tree/fsimageplugin/
*/
#pragma pack(push, 1)
typedef struct vhd_footer {
char cookie[8];
uint32_t features;
uint32_t file_format_version;
uint64_t data_offset;
uint32_t timestamp;
char creator_app[4];
uint32_t creator_version;
char creator_host_os[4];
uint64_t original_size;
uint64_t current_size;
union {
uint32_t geometry;
struct {
uint16_t cylinders;
uint8_t heads;
uint8_t sectors;
} chs;
} disk_geometry;
uint32_t disk_type;
uint32_t checksum;
uuid_t unique_id;
uint8_t saved_state;
uint8_t reserved[427];
} vhd_footer;
#pragma pack(pop)
// WIM API Prototypes
#define WIM_GENERIC_READ GENERIC_READ
#define WIM_OPEN_EXISTING OPEN_EXISTING
#define WIM_UNDOCUMENTED_BULLSHIT 0x20000000
PF_TYPE_DECL(WINAPI, HANDLE, WIMCreateFile, (PWSTR, DWORD, DWORD, DWORD, DWORD, PDWORD));
PF_TYPE_DECL(WINAPI, BOOL, WIMSetTemporaryPath, (HANDLE, PWSTR));
PF_TYPE_DECL(WINAPI, HANDLE, WIMLoadImage, (HANDLE, DWORD));
@ -287,8 +185,7 @@ static comp_assoc file_assoc[] = {
};
// For now we consider that an image that matches a known extension is bootable
#define MBR_SIZE 512 // Might need to review this once we see bootable 4k systems
BOOL IsCompressedBootableImage(const char* path)
static BOOL IsCompressedBootableImage(const char* path)
{
char *p;
unsigned char *buf = NULL;
@ -566,7 +463,7 @@ static DWORD WINAPI WimMountImageThread(LPVOID param)
uprintf("Could not mount '%S [%d]' on '%S': %s", wimage, _index, wmount_path, WindowsErrorString());
goto out;
}
uprintf("mounted '%S [%d]' on '%S'", wimage, _index, wmount_path);
uprintf("Mounted '%S [%d]' on '%S'", wimage, _index, wmount_path);
out:
if (!r) {
@ -677,11 +574,11 @@ BOOL WimExtractFile_API(const char* image, int index, const char* src, const cha
HANDLE hWim = NULL;
HANDLE hImage = NULL;
HANDLE hFile = NULL;
wchar_t wtemp[MAX_PATH] = {0};
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);
char* wim_info;
wchar_t* wim_info;
PF_INIT_OR_OUT(WIMCreateFile, Wimgapi);
PF_INIT_OR_OUT(WIMSetTemporaryPath, Wimgapi);
@ -713,7 +610,7 @@ BOOL WimExtractFile_API(const char* image, int index, const char* src, const cha
suprintf("Extracting: %s (From %s)", dst, src);
if (safe_strcmp(src, index_name) == 0) {
if (!pfWIMGetImageInformation(hWim, &wim_info, &dw)) {
if (!pfWIMGetImageInformation(hWim, &wim_info, &dw) || (dw == 0)) {
uprintf(" Could not access WIM info: %s", WindowsErrorString());
goto out;
}
@ -823,6 +720,70 @@ BOOL WimExtractFile(const char* image, int index, const char* src, const char* d
|| ((wim_flags & WIM_HAS_API_EXTRACT) && WimExtractFile_API(image, index, src, dst, bSilent)) );
}
/// <summary>
/// Find if a specific index belongs to a WIM image.
/// </summary>
/// <param name="image">The path to the WIM file.</param>
/// <param name="index">The (non-zero) value of the index to check.</param>
/// <returns>TRUE if the index was found in the image, FALSE otherwise.</returns>
BOOL WimIsValidIndex(const char* image, int index)
{
int i = 1;
BOOL r = FALSE;
DWORD dw = 0;
HANDLE hWim = NULL;
HANDLE hFile = NULL;
char xml_file[MAX_PATH] = { 0 };
char* str;
wchar_t* wimage = utf8_to_wchar(image);
wchar_t* wim_info;
PF_INIT_OR_OUT(WIMCreateFile, Wimgapi);
PF_INIT_OR_OUT(WIMGetImageInformation, Wimgapi);
PF_INIT_OR_OUT(WIMCloseHandle, Wimgapi);
// Zero indexes are invalid
if (index == 0)
return FALSE;
hWim = pfWIMCreateFile(wimage, WIM_GENERIC_READ, WIM_OPEN_EXISTING,
(img_report.wininst_version >= SPECIAL_WIM_VERSION) ? WIM_UNDOCUMENTED_BULLSHIT : 0, 0, NULL);
if (hWim == NULL) {
uprintf(" Could not access image: %s", WindowsErrorString());
goto out;
}
if (!pfWIMGetImageInformation(hWim, &wim_info, &dw) || (dw == 0)) {
uprintf(" Could not access WIM info: %s", WindowsErrorString());
goto out;
}
if ((GetTempFileNameU(temp_dir, APPLICATION_NAME, 0, xml_file) == 0) || (xml_file[0] == 0))
static_strcpy(xml_file, ".\\RufVXml.tmp");
DeleteFileU(xml_file);
hFile = CreateFileU(xml_file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if ((hFile == INVALID_HANDLE_VALUE) || (!WriteFile(hFile, wim_info, dw, &dw, NULL)))
goto out;
while ((str = get_token_data_file_indexed("IMAGE INDEX", xml_file, i)) != NULL) {
if (atoi(str) == index) {
r = TRUE;
break;
}
i++;
}
out:
if (hWim != NULL)
pfWIMCloseHandle(hWim);
safe_closehandle(hFile);
if (xml_file[0] != 0)
DeleteFileU(xml_file);
safe_free(wimage);
return r;
}
// Apply a WIM image using wimgapi.dll (Windows 7 or later)
// https://docs.microsoft.com/en-us/previous-versions/msdn10/dd851944(v=msdn.10)
// To get progress, we must run this call within its own thread

141
src/vhd.h Normal file
View File

@ -0,0 +1,141 @@
/*
* Rufus: The Reliable USB Formatting Utility
* Virtual Disk Handling definitions and prototypes
* Copyright © 2022 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 <stdint.h>
#include <windows.h>
#pragma once
#define VHD_FOOTER_COOKIE { 'c', 'o', 'n', 'e', 'c', 't', 'i', 'x' }
#define VHD_FOOTER_FEATURES_NONE 0x00000000
#define VHD_FOOTER_FEATURES_TEMPORARY 0x00000001
#define VHD_FOOTER_FEATURES_RESERVED 0x00000002
#define VHD_FOOTER_FILE_FORMAT_V1_0 0x00010000
#define VHD_FOOTER_DATA_OFFSET_FIXED_DISK 0xFFFFFFFFFFFFFFFFULL
#define VHD_FOOTER_CREATOR_HOST_OS_WINDOWS { 'W', 'i', '2', 'k' }
#define VHD_FOOTER_CREATOR_HOST_OS_MAC { 'M', 'a', 'c', ' ' }
#define VHD_FOOTER_TYPE_FIXED_HARD_DISK 0x00000002
#define VHD_FOOTER_TYPE_DYNAMIC_HARD_DISK 0x00000003
#define VHD_FOOTER_TYPE_DIFFER_HARD_DISK 0x00000004
#define WIM_MAGIC 0x0000004D4957534DULL // "MSWIM\0\0\0"
#define WIM_HAS_API_EXTRACT 1
#define WIM_HAS_7Z_EXTRACT 2
#define WIM_HAS_API_APPLY 4
#define WIM_HAS_EXTRACT(r) (r & (WIM_HAS_API_EXTRACT|WIM_HAS_7Z_EXTRACT))
#define SECONDS_SINCE_JAN_1ST_2000 946684800
#define INVALID_CALLBACK_VALUE 0xFFFFFFFF
#define WIM_FLAG_RESERVED 0x00000001
#define WIM_FLAG_VERIFY 0x00000002
#define WIM_FLAG_INDEX 0x00000004
#define WIM_FLAG_NO_APPLY 0x00000008
#define WIM_FLAG_NO_DIRACL 0x00000010
#define WIM_FLAG_NO_FILEACL 0x00000020
#define WIM_FLAG_SHARE_WRITE 0x00000040
#define WIM_FLAG_FILEINFO 0x00000080
#define WIM_FLAG_NO_RP_FIX 0x00000100
// Bitmask for the kind of progress we want to report in the WIM progress callback
#define WIM_REPORT_PROGRESS 0x00000001
#define WIM_REPORT_PROCESS 0x00000002
#define WIM_REPORT_FILEINFO 0x00000004
#define WIM_GENERIC_READ GENERIC_READ
#define WIM_OPEN_EXISTING OPEN_EXISTING
#define WIM_UNDOCUMENTED_BULLSHIT 0x20000000
#define MBR_SIZE 512 // Might need to review this once we see bootable 4k systems
// From https://docs.microsoft.com/en-us/previous-versions/msdn10/dd834960(v=msdn.10)
// as well as https://msfn.org/board/topic/150700-wimgapi-wimmountimage-progressbar/
enum WIMMessage {
WIM_MSG = WM_APP + 0x1476,
WIM_MSG_TEXT,
WIM_MSG_PROGRESS, // Indicates an update in the progress of an image application.
WIM_MSG_PROCESS, // Enables the caller to prevent a file or a directory from being captured or applied.
WIM_MSG_SCANNING, // Indicates that volume information is being gathered during an image capture.
WIM_MSG_SETRANGE, // Indicates the number of files that will be captured or applied.
WIM_MSG_SETPOS, // Indicates the number of files that have been captured or applied.
WIM_MSG_STEPIT, // Indicates that a file has been either captured or applied.
WIM_MSG_COMPRESS, // Enables the caller to prevent a file resource from being compressed during a capture.
WIM_MSG_ERROR, // Alerts the caller that an error has occurred while capturing or applying an image.
WIM_MSG_ALIGNMENT, // Enables the caller to align a file resource on a particular alignment boundary.
WIM_MSG_RETRY, // Sent when the file is being reapplied because of a network timeout.
WIM_MSG_SPLIT, // Enables the caller to align a file resource on a particular alignment boundary.
WIM_MSG_FILEINFO, // Used in conjunction with WimApplyImages()'s WIM_FLAG_FILEINFO flag to provide detailed file info.
WIM_MSG_INFO, // Sent when an info message is available.
WIM_MSG_WARNING, // Sent when a warning message is available.
WIM_MSG_CHK_PROCESS,
WIM_MSG_SUCCESS = 0,
WIM_MSG_ABORT_IMAGE = -1
};
/*
* VHD Fixed HD footer (Big Endian)
* http://download.microsoft.com/download/f/f/e/ffef50a5-07dd-4cf8-aaa3-442c0673a029/Virtual%20Hard%20Disk%20Format%20Spec_10_18_06.doc
* NB: If a dymamic implementation is needed, check the GPL v3 compatible C++ implementation from:
* https://sourceforge.net/p/urbackup/backend/ci/master/tree/fsimageplugin/
*/
#pragma pack(push, 1)
typedef struct vhd_footer {
char cookie[8];
uint32_t features;
uint32_t file_format_version;
uint64_t data_offset;
uint32_t timestamp;
char creator_app[4];
uint32_t creator_version;
char creator_host_os[4];
uint64_t original_size;
uint64_t current_size;
union {
uint32_t geometry;
struct {
uint16_t cylinders;
uint8_t heads;
uint8_t sectors;
} chs;
} disk_geometry;
uint32_t disk_type;
uint32_t checksum;
uuid_t unique_id;
uint8_t saved_state;
uint8_t reserved[427];
} vhd_footer;
#pragma pack(pop)
extern uint8_t WimExtractCheck(BOOL bSilent);
extern BOOL WimExtractFile(const char* wim_image, int index, const char* src, const char* dst, BOOL bSilent);
extern BOOL WimExtractFile_API(const char* image, int index, const char* src, const char* dst, BOOL bSilent);
extern BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char* dst, BOOL bSilent);
extern BOOL WimApplyImage(const char* image, int index, const char* dst);
extern char* WimMountImage(const char* image, int index);
extern BOOL WimUnmountImage(const char* image, int index);
extern BOOL WimIsValidIndex(const char* image, int index);
extern int8_t IsBootableImage(const char* path);
extern BOOL AppendVHDFooter(const char* vhd_path);

View File

@ -24,6 +24,7 @@
#include <assert.h>
#include "rufus.h"
#include "vhd.h"
#include "drive.h"
#include "format.h"
#include "missing.h"
@ -359,7 +360,7 @@ out:
/// <returns>-2 on user cancel, -1 on other error, >=0 on success.</returns>
int SetWinToGoIndex(void)
{
char* mounted_iso, * val, mounted_image_path[128];
char* mounted_iso, *val, mounted_image_path[128];
char xml_file[MAX_PATH] = "";
char* install_names[MAX_WININST];
StrArray version_name, version_index;
@ -619,8 +620,7 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags)
// NB: Work with a copy of unattend_xml_flags as a paremeter since we will modify it.
{
BOOL r = FALSE, is_hive_mounted = FALSE;
int i;
const int wim_index = 2;
int i, wim_index = 2;
const char* offline_hive_name = "RUFUS_OFFLINE_HIVE";
char boot_wim_path[] = "?:\\sources\\boot.wim", key_path[64];
char appraiserres_dll_src[] = "?:\\sources\\appraiserres.dll";
@ -653,12 +653,16 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags)
// appraiserres.dll otherwise setup.exe extracts its own.
appraiserres_dll_src[0] = drive_letter;
appraiserres_dll_dst[0] = drive_letter;
if (!MoveFileExU(appraiserres_dll_src, appraiserres_dll_dst, MOVEFILE_REPLACE_EXISTING))
if (!MoveFileExU(appraiserres_dll_src, appraiserres_dll_dst, MOVEFILE_REPLACE_EXISTING)
&& GetLastError() != ERROR_FILE_NOT_FOUND) {
uprintf("Could not rename '%s': %s", appraiserres_dll_src, WindowsErrorString());
else
} else {
if (GetLastError() == ERROR_SUCCESS)
uprintf("Renamed '%s' → '%s'", appraiserres_dll_src, appraiserres_dll_dst);
CloseHandle(CreateFileU(appraiserres_dll_src, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
uprintf("Renamed '%s' → '%s'", appraiserres_dll_src, appraiserres_dll_dst);
uprintf("Created '%s' placeholder", appraiserres_dll_src);
}
}
UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 0, PATCH_PROGRESS_TOTAL);
@ -666,6 +670,13 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags)
// not, we can just copy our unattend.xml in \sources\$OEM$\$$\Panther\.
if (flags & UNATTEND_WINPE_SETUP_MASK) {
uprintf("Mounting '%s'...", boot_wim_path);
// Some "unofficial" ISOs have a modified boot.wim that doesn't have Windows Setup at index 2...
if (!WimIsValidIndex(boot_wim_path, wim_index)) {
uprintf("WARNING: This image appears to be an UNOFFICIAL Windows ISO!");
uprintf("Rufus recommends that you only use OFFICIAL retail Microsoft Windows images, such as");
uprintf("the ones that can be downloaded through the download facility of this application.");
wim_index = 1;
}
mount_path = WimMountImage(boot_wim_path, wim_index);
if (mount_path == NULL)
goto out;