mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-21 18:35:26 -04:00
[efi] add Windows 7 EFI support for XP and Vista
* Requires 7-Zip for WIM extraction as wimgapi.dll is not available * Also add more comprehensive choice between MBR/GPT and BIOS/UEFI
This commit is contained in:
parent
84e4aecfcd
commit
0196de6f4d
6 changed files with 233 additions and 88 deletions
126
src/vhd.c
126
src/vhd.c
|
@ -17,8 +17,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
|
||||
#include "rufus.h"
|
||||
#include "msapi_utf8.h"
|
||||
#include "registry.h"
|
||||
|
||||
static BOOL has_wimgapi = FALSE, has_7z = FALSE;
|
||||
|
||||
#define WIM_GENERIC_READ GENERIC_READ
|
||||
#define WIM_OPEN_EXISTING OPEN_EXISTING
|
||||
|
@ -53,9 +59,39 @@ typedef BOOL (WINAPI *WIMCloseHandle_t)(
|
|||
HANDLE hObj
|
||||
);
|
||||
|
||||
// Extract a file from a WIM image
|
||||
// WIM API Prototypes
|
||||
static PF_DECL(WIMCreateFile);
|
||||
static PF_DECL(WIMSetTemporaryPath);
|
||||
static PF_DECL(WIMLoadImage);
|
||||
static PF_DECL(WIMExtractImagePath);
|
||||
static PF_DECL(WIMCloseHandle);
|
||||
|
||||
// Find out if we have any way to extraxt WIM files on this platform
|
||||
BOOL WimExtractCheck(void)
|
||||
{
|
||||
char sevenzip_path[MAX_PATH];
|
||||
|
||||
PF_INIT(WIMCreateFile, wimgapi);
|
||||
PF_INIT(WIMSetTemporaryPath, wimgapi);
|
||||
PF_INIT(WIMLoadImage, wimgapi);
|
||||
PF_INIT(WIMExtractImagePath, wimgapi);
|
||||
PF_INIT(WIMCloseHandle, wimgapi);
|
||||
|
||||
has_wimgapi = (pfWIMCreateFile && pfWIMSetTemporaryPath && pfWIMLoadImage && pfWIMExtractImagePath && pfWIMCloseHandle);
|
||||
if (GetRegistryKeyStr("7-Zip\\Path", sevenzip_path, sizeof(sevenzip_path))) {
|
||||
safe_strcat(sevenzip_path, sizeof(sevenzip_path), "\\7z.exe");
|
||||
has_7z = (_access(sevenzip_path, 0) != -1);
|
||||
}
|
||||
|
||||
uprintf("WIM extraction method(s) supported: %s%s%s\n", has_7z?"7z":(has_wimgapi?"":"NONE"),
|
||||
(has_wimgapi && has_7z)?", ":"", has_wimgapi?"wimgapi.dll":"");
|
||||
return (has_wimgapi || has_7z);
|
||||
}
|
||||
|
||||
|
||||
// Extract a file from a WIM image using wimgapi.dll (Windows 7 or later)
|
||||
// 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)
|
||||
static BOOL WimExtractFile_API(const char* image, int index, const char* src, const char* dst)
|
||||
{
|
||||
BOOL r = FALSE;
|
||||
DWORD dw = 0;
|
||||
|
@ -65,11 +101,6 @@ BOOL WIMExtractFile(const char* image, int index, const char* src, const char* d
|
|||
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);
|
||||
|
@ -77,37 +108,36 @@ BOOL WIMExtractFile(const char* image, int index, const char* src, const char* d
|
|||
PF_INIT_OR_OUT(WIMExtractImagePath, wimgapi);
|
||||
PF_INIT_OR_OUT(WIMCloseHandle, wimgapi);
|
||||
|
||||
// TODO: check for NULL and missing wimgapi.dll
|
||||
|
||||
uprintf("Opening: %s:[%d] (API)\n", image, index);
|
||||
if (GetTempPathW(ARRAYSIZE(wtemp), wtemp) == 0) {
|
||||
uprintf("Could not fetch temp path: %s\n", WindowsErrorString());
|
||||
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());
|
||||
uprintf(" Could not access image: %s\n", WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!pfWIMSetTemporaryPath(hWim, wtemp)) {
|
||||
uprintf(" Error setting temp path: %s\n", WindowsErrorString());
|
||||
uprintf(" Could not set temp path: %s\n", WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
|
||||
hImage = pfWIMLoadImage(hWim, (DWORD)index);
|
||||
if (hImage == NULL) {
|
||||
uprintf(" Error setting index: %s.\n", WindowsErrorString());
|
||||
uprintf(" Could not set 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());
|
||||
uprintf(" Could not extract file: %s\n", WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
r = TRUE;
|
||||
UpdateProgress(OP_FINALIZE, -1.0f);
|
||||
|
||||
out:
|
||||
if ((hImage != NULL) || (hWim != NULL)) {
|
||||
|
@ -120,3 +150,69 @@ out:
|
|||
safe_free(wdst);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Extract a file from a WIM image using 7-Zip
|
||||
static BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char* dst)
|
||||
{
|
||||
size_t i;
|
||||
STARTUPINFOA si = {0};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
char sevenzip_path[MAX_PATH];
|
||||
char cmdline[MAX_PATH];
|
||||
char tmpdst[MAX_PATH];
|
||||
|
||||
uprintf("Opening: %s:[%d] (7-Zip)\n", image, index);
|
||||
if (!GetRegistryKeyStr("7-Zip\\Path", sevenzip_path, sizeof(sevenzip_path))) {
|
||||
uprintf(" Could not read 7-Zip path from registry\n");
|
||||
return FALSE;
|
||||
}
|
||||
safe_strcat(sevenzip_path, sizeof(sevenzip_path), "\\7z.exe");
|
||||
|
||||
if (_access(sevenzip_path, 0) == -1) {
|
||||
uprintf(" Could not locate 7z.exe at '%s'\n", sevenzip_path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
safe_strcpy(tmpdst, sizeof(tmpdst), dst);
|
||||
for (i=safe_strlen(tmpdst); i>0; i--) {
|
||||
if (tmpdst[i] == '\\')
|
||||
break;
|
||||
}
|
||||
tmpdst[i] = 0;
|
||||
|
||||
si.cb = sizeof(si);
|
||||
safe_sprintf(cmdline, sizeof(cmdline), "7z -y e \"%s\" %d\\Windows\\Boot\\EFI\\bootmgfw.efi", image, index);
|
||||
uprintf("Extracting: %s (From \\%s)\n", dst, src);
|
||||
if (!CreateProcessU(sevenzip_path, cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, tmpdst, &si, &pi)) {
|
||||
uprintf(" Could not launch 7z.exe: %s\n", WindowsErrorString());
|
||||
return FALSE;
|
||||
}
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
UpdateProgress(OP_FINALIZE, -1.0f);
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
safe_strcat(tmpdst, sizeof(tmpdst), "\\bootmgfw.efi");
|
||||
if (_access(tmpdst, 0) == -1) {
|
||||
uprintf(" 7z.exe did not extract %s\n", tmpdst);
|
||||
return FALSE;
|
||||
}
|
||||
if (rename(tmpdst, dst) != 0) {
|
||||
uprintf(" Could not rename %s to %s\n", tmpdst, dst);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Extract a file from a WIM image
|
||||
BOOL WimExtractFile(const char* image, int index, const char* src, const char* dst)
|
||||
{
|
||||
if ((!has_wimgapi) && (!has_7z) && (!WimExtractCheck()))
|
||||
return FALSE;
|
||||
|
||||
// Prefer 7-Zip as, unsurprisingly, it's faster than the Microsoft way,
|
||||
// but allow fallback if 7-Zip doesn't succeed
|
||||
return ( (has_7z && WimExtractFile_7z(image, index, src, dst))
|
||||
|| (has_wimgapi && WimExtractFile_API(image, index, src, dst)) );
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue