1
1
Fork 0
mirror of https://github.com/pbatard/rufus.git synced 2024-08-14 23:57:05 +00:00

[pe] initial WinPE support (BartPE, XP install disc)

* also switched MBR to Win7 one
* also switched version to rufus-next
This commit is contained in:
Pete Batard 2012-03-16 18:30:44 +00:00
parent c07832b090
commit 4bd017ff07
8 changed files with 285 additions and 43 deletions

20
configure vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.68 for rufus 1.1.5. # Generated by GNU Autoconf 2.68 for rufus 1.1.6.
# #
# Report bugs to <https://github.com/pbatard/rufus/issues>. # Report bugs to <https://github.com/pbatard/rufus/issues>.
# #
@ -559,8 +559,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='rufus' PACKAGE_NAME='rufus'
PACKAGE_TARNAME='rufus' PACKAGE_TARNAME='rufus'
PACKAGE_VERSION='1.1.5' PACKAGE_VERSION='1.1.6'
PACKAGE_STRING='rufus 1.1.5' PACKAGE_STRING='rufus 1.1.6'
PACKAGE_BUGREPORT='https://github.com/pbatard/rufus/issues' PACKAGE_BUGREPORT='https://github.com/pbatard/rufus/issues'
PACKAGE_URL='http://rufus.akeo.ie' PACKAGE_URL='http://rufus.akeo.ie'
@ -1204,7 +1204,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures rufus 1.1.5 to adapt to many kinds of systems. \`configure' configures rufus 1.1.6 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1270,7 +1270,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of rufus 1.1.5:";; short | recursive ) echo "Configuration of rufus 1.1.6:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1363,7 +1363,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
rufus configure 1.1.5 rufus configure 1.1.6
generated by GNU Autoconf 2.68 generated by GNU Autoconf 2.68
Copyright (C) 2010 Free Software Foundation, Inc. Copyright (C) 2010 Free Software Foundation, Inc.
@ -1418,7 +1418,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by rufus $as_me 1.1.5, which was It was created by rufus $as_me 1.1.6, which was
generated by GNU Autoconf 2.68. Invocation command line was generated by GNU Autoconf 2.68. Invocation command line was
$ $0 $@ $ $0 $@
@ -2233,7 +2233,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='rufus' PACKAGE='rufus'
VERSION='1.1.5' VERSION='1.1.6'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@ -4091,7 +4091,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by rufus $as_me 1.1.5, which was This file was extended by rufus $as_me 1.1.6, which was
generated by GNU Autoconf 2.68. Invocation command line was generated by GNU Autoconf 2.68. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -4145,7 +4145,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
rufus config.status 1.1.5 rufus config.status 1.1.6
configured by $0, generated by GNU Autoconf 2.68, configured by $0, generated by GNU Autoconf 2.68,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View file

@ -1,4 +1,4 @@
AC_INIT([rufus], [1.1.5], [https://github.com/pbatard/rufus/issues], [rufus], [http://rufus.akeo.ie]) AC_INIT([rufus], [1.1.6], [https://github.com/pbatard/rufus/issues], [rufus], [http://rufus.akeo.ie])
AM_INIT_AUTOMAKE([-Wno-portability foreign no-dist no-dependencies]) AM_INIT_AUTOMAKE([-Wno-portability foreign no-dist no-dependencies])
AC_CONFIG_SRCDIR([src/rufus.c]) AC_CONFIG_SRCDIR([src/rufus.c])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])

View file

@ -35,7 +35,6 @@
*/ */
RUFUS_DRIVE_INFO SelectedDrive; RUFUS_DRIVE_INFO SelectedDrive;
extern BOOL enable_fixed_disks; extern BOOL enable_fixed_disks;
extern char* get_token_data(const char* filename, const char* token);
/* /*
* Open a drive or volume with optional write and lock access * Open a drive or volume with optional write and lock access

View file

@ -464,7 +464,7 @@ static BOOL WriteMBR(HANDLE hPhysicalDrive)
if ((dt == DT_ISO) && ((fs == FS_FAT16) || (fs == FS_FAT32))) { if ((dt == DT_ISO) && ((fs == FS_FAT16) || (fs == FS_FAT32))) {
r = write_syslinux_mbr(&fake_fd); r = write_syslinux_mbr(&fake_fd);
} else { } else {
r = write_95b_mbr(&fake_fd); r = write_win7_mbr(&fake_fd);
} }
out: out:
@ -537,6 +537,229 @@ static BOOL WritePBR(HANDLE hLogicalVolume)
return FALSE; return FALSE;
} }
/*
* Setup WinPE for bootable USB
*/
// TODO: set FormatError
static BOOL SetupWinPE(char drive_letter)
{
char src[64], dst[32];
const char* basedir[] = { "i386", "minint" };
const char* patch_str_org[] = { "\\minint\\txtsetup.sif", "\\minint\\system32\\" };
const char* patch_str_rep[] = { "\\$\\i386\\txtsetup.sif", "\\$\\i386\\system32\\" };
const char *win_nt_bt_org = "$win_nt$.~bt", *win_nt_bt_rep = "$\\i386";
const char* winnt_sif = "[Data]\n msdosinitiated = \"1\"\n";
const wchar_t* win_nt_ls = L"$win_nt$.~ls";
STARTUPINFOA si;
PROCESS_INFORMATION pi;
HANDLE handle = INVALID_HANDLE_VALUE;
DWORD i, j, size, rw_size, index = 0, exit_code;
BOOL minint = FALSE, r = FALSE;
char* buf = NULL;
index = ((iso_report.winpe&WINPE_I386) == WINPE_I386)?0:1;
// Parse TXTSETUP.SIF to see if /minint was provided for OsLoadOptions
safe_sprintf(src, sizeof(src), "%c:\\%s\\txtsetup.sif", drive_letter, basedir[index]);
buf = get_token_data(src, "OsLoadOptions");
if (buf != NULL) {
for (i=0; i<strlen(buf); i++)
buf[i] = tolower(buf[i]);
uprintf("OsLoadOptions = %s\n", buf);
minint = (strstr(buf, "/minint") != NULL);
}
safe_free(buf);
// TODO: detect if overwrite?
safe_sprintf(src, sizeof(src), "%c:\\%s\\ntdetect.com", drive_letter, basedir[index]);
safe_sprintf(dst, sizeof(dst), "%c:\\ntdetect.com", drive_letter);
CopyFileA(src, dst, TRUE);
safe_sprintf(src, sizeof(src), "%c:\\%s\\setupldr.bin", drive_letter, basedir[index]);
safe_sprintf(dst, sizeof(dst), "%c:\\BOOTMGR", drive_letter);
CopyFileA(src, dst, TRUE);
// \minint with /minint option doesn't require further processing => return true
// \minint and no \i386 without /minint is unclear => return error
if (iso_report.winpe&WINPE_MININT) {
if (minint) {
uprintf("Detected \\minint directory with /minint option: nothing to patch\n");
r = TRUE;
} else if (!(iso_report.winpe&WINPE_I386)) {
uprintf("Detected \\minint directory only but no /minint option: not sure what to do\n");
}
goto out;
}
// At this stage we only handle \i386
handle = CreateFileA(dst, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE) {
uprintf("Could not open %s for patching: %s\n", dst, WindowsErrorString());
goto out;
}
size = GetFileSize(handle, NULL);
if (size == INVALID_FILE_SIZE) {
uprintf("Could not get size for file %s: %s\n", dst, WindowsErrorString());
goto out;
}
buf = (char*)malloc(size);
if (buf == NULL)
goto out;
if ((!ReadFile(handle, buf, size, &rw_size, NULL)) || (size != rw_size)) {
uprintf("Could not read file %s: %s\n", dst, WindowsErrorString());
goto out;
}
SetFilePointer(handle, 0, NULL, FILE_BEGIN);
/* Patch setupldr.bin so that [\$]\i386 can be used instead of \minint */
uprintf("Patching file %s\n", dst);
for (i=0; i<size-32; i++) {
for (j=0; j<ARRAYSIZE(patch_str_org); j++) {
if (safe_strnicmp(&buf[i], patch_str_org[j], strlen(patch_str_org[j])-1) == 0) {
uprintf(" 0x%08X: '%s' -> '%s'\n", i, &buf[i], &patch_str_rep[j][minint?2:0]);
strcpy(&buf[i], &patch_str_rep[j][minint?2:0]);
}
}
}
if (minint) {
if ((!WriteFile(handle, buf, size, &rw_size, NULL)) || (size != rw_size)) {
uprintf("Could not write patched file: %s\n", WindowsErrorString());
goto out;
}
}else {
// Finish patching \bootmgr
for (i=0; i<size-32; i++) {
if (safe_strnicmp(&buf[i], win_nt_bt_org, strlen(win_nt_bt_org)-1) == 0) {
uprintf(" 0x%08X: '%s' -> '%s%s'\n", i, &buf[i], win_nt_bt_rep, &buf[i+strlen(win_nt_bt_org)]);
strcpy(&buf[i], win_nt_bt_rep);
buf[i+strlen(win_nt_bt_rep)] = buf[i+strlen(win_nt_bt_org)];
buf[i+strlen(win_nt_bt_rep)+1] = 0;
}
}
if ((!WriteFile(handle, buf, size, &rw_size, NULL)) || (size != rw_size)) {
uprintf("Could not write patched file: %s\n", WindowsErrorString());
goto out;
}
safe_free(buf);
safe_closehandle(handle);
// Rename \i386 to \$\i386
safe_sprintf(src, sizeof(src), "%c:\\$", drive_letter);
if (!CreateDirectoryA(src, NULL)) {
uprintf("Could not create %s: %s\n", src, WindowsErrorString());
goto out;
}
safe_sprintf(src, sizeof(src), "%c:\\i386", drive_letter);
safe_sprintf(dst, sizeof(dst), "%c:\\$\\i386", drive_letter);
uprintf("Renaming '%s' to '%s'\n", src, dst);
if (!MoveFileA(src, dst)) {
uprintf(" failed: %s\n", WindowsErrorString());
goto out;
}
// Create a \$\i386\winnt.sif (avoids "Please insert" errors)
safe_sprintf(src, sizeof(src), "%c:\\$\\i386\\winnt.sif", drive_letter);
size = strlen(winnt_sif);
handle = CreateFileA(src, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE) {
uprintf("Could not create %s: %s\n", src, WindowsErrorString());
goto out;
}
if ((!WriteFile(handle, winnt_sif, size, &rw_size, NULL)) || (size != rw_size)) {
uprintf("Could not write %s: %s\n", src, WindowsErrorString());
goto out;
}
safe_closehandle(handle);
// Uncompress $\\i386\\setupdd.sy_
// Don't bother calling Extract() from cabinet.dll - calling expand.exe is much simpler
// TODO: factorize CreateProcess()?
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
memset(&pi, 0, sizeof(pi));
uprintf("Decompressing %c:\\$\\i386\\setupdd.sy_\n", drive_letter);
safe_sprintf(src, sizeof(src), "expand %c:\\$\\i386\\setupdd.sy_ %c:\\$\\i386\\setupdd.sys", drive_letter, drive_letter);
if (!CreateProcessA(NULL, src, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
uprintf("Could not launch command '%s': %s", src, WindowsErrorString());
goto out;
}
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, &exit_code);
safe_closehandle(pi.hProcess);
safe_closehandle(pi.hThread);
if (exit_code != 0) {
uprintf("Command '%s' failed with exit code: %d\n", src, exit_code);
goto out;
}
// Patch the uncompressed $\\i386\\setupdd.sys
safe_sprintf(dst, sizeof(dst), "%c:\\$\\i386\\setupdd.sys", drive_letter);
handle = CreateFileA(dst, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE) {
uprintf("Could not open %s for patching: %s\n", dst, WindowsErrorString());
goto out;
}
size = GetFileSize(handle, NULL);
if (size == INVALID_FILE_SIZE) {
uprintf("Could not get size for file %s: %s\n", dst, WindowsErrorString());
goto out;
}
buf = (char*)malloc(size);
if (buf == NULL)
goto out;
if ((!ReadFile(handle, buf, size, &rw_size, NULL)) || (size != rw_size)) {
uprintf("Could not read file %s: %s\n", dst, WindowsErrorString());
goto out;
}
SetFilePointer(handle, 0, NULL, FILE_BEGIN);
uprintf("Patching %s\n", dst);
for (i=0; i<size-32; i++) {
if (_wcsnicmp((wchar_t*)&buf[i], win_nt_ls, wcslen(win_nt_ls)-1) == 0) {
uprintf(" 0x%08X: '$win_nt$.~ls' -> '$'\n", i);
buf[i+2] = 0;
}
}
if ((!WriteFile(handle, buf, size, &rw_size, NULL)) || (size != rw_size)) {
uprintf("Could not write patched file: %s\n", WindowsErrorString());
goto out;
}
safe_closehandle(handle);
// Recompress to $\\i386\\setupdd.sy_
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
memset(&pi, 0, sizeof(pi));
uprintf("Compressing back %s\n", dst);
safe_sprintf(src, sizeof(src), "makecab %c:\\$\\i386\\setupdd.sys %c:\\$\\i386\\setupdd.sy_", drive_letter, drive_letter);
if (!CreateProcessA(NULL, src, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
uprintf("Could not launch command '%s': %s", src, WindowsErrorString());
goto out;
}
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, &exit_code);
safe_closehandle(pi.hProcess);
safe_closehandle(pi.hThread);
if (exit_code != 0) {
uprintf("Command '%s' failed with exit code: %d\n", src, exit_code);
goto out;
}
// Delete uncompressed file
_unlink(dst);
}
r = TRUE;
out:
safe_closehandle(handle);
safe_free(buf);
return r;
}
/* /*
* Issue a complete remount of the volume * Issue a complete remount of the volume
*/ */
@ -753,6 +976,10 @@ DWORD WINAPI FormatThread(LPVOID param)
goto out; goto out;
} }
} }
if (IS_WINPE(iso_report.winpe)) {
// Apply WinPe fixup
SetupWinPE(drive_name[0]);
}
} }
if (IsChecked(IDC_SET_ICON)) if (IsChecked(IDC_SET_ICON))
SetAutorun(drive_name); SetAutorun(drive_name);

View file

@ -47,25 +47,25 @@
#define FOUR_GIGABYTES 4294967296LL #define FOUR_GIGABYTES 4294967296LL
// Needed for UDF ISO access // Needed for UDF ISO access
CdIo_t* cdio_open (const char *psz_source, driver_id_t driver_id) {return NULL;} CdIo_t* cdio_open (const char* psz_source, driver_id_t driver_id) {return NULL;}
void cdio_destroy (CdIo_t *p_cdio) {} void cdio_destroy (CdIo_t* p_cdio) {}
RUFUS_ISO_REPORT iso_report; 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_name = "bootmgr";
static const char *ldlinux_name = "ldlinux.sys"; static const char* ldlinux_name = "ldlinux.sys";
static const char *isolinux_name[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"}; static const char* isolinux_name[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"};
static const char *vesamenu_name = "vesamenu.c32"; static const char* vesamenu_name = "vesamenu.c32";
static const char* pe_dirname[] = { "/i386", "/minint" };
static const char* pe_file[] = { "ntdetect.com", "setupldr.bin", "txtsetup.sif" };
static int64_t old_vesamenu_threshold = 145000; static int64_t old_vesamenu_threshold = 145000;
static uint8_t i_joliet_level = 0; static uint8_t i_joliet_level = 0;
static uint64_t total_blocks, nb_blocks; static uint64_t total_blocks, nb_blocks;
static BOOL scan_only = FALSE; static BOOL scan_only = FALSE;
static StrArray config_path; static StrArray config_path;
extern char* replace_in_token_data(const char* filename, const char* token, const char* src, const char* rep);
// TODO: Timestamp & permissions preservation // TODO: Timestamp & permissions preservation
// Convert a file size to human readable // Convert a file size to human readable
@ -101,28 +101,36 @@ static void log_handler (cdio_log_level_t level, const char *message)
* Scan and set ISO properties * Scan and set ISO properties
* Returns true if the the current file does not need to be processed further * Returns true if the the current file does not need to be processed further
*/ */
static __inline BOOL check_iso_props(BOOL is_root, BOOL* is_syslinux_cfg, BOOL* is_old_vesamenu, static __inline BOOL check_iso_props(const char* psz_dirname, BOOL* is_syslinux_cfg, BOOL* is_old_vesamenu,
int64_t i_file_length, const char* psz_basename, char* psz_fullpath) int64_t i_file_length, const char* psz_basename, const char* psz_fullpath)
{ {
size_t i; size_t i, j;
// Check for an isolinux/syslinux config file anywhere // Check for an isolinux/syslinux config file anywhere
*is_syslinux_cfg = FALSE; *is_syslinux_cfg = FALSE;
for (i=0; i<ARRAYSIZE(isolinux_name); i++) { for (i=0; i<ARRAYSIZE(isolinux_name); i++) {
if (_stricmp(psz_basename, isolinux_name[i]) == 0) if (safe_stricmp(psz_basename, isolinux_name[i]) == 0)
*is_syslinux_cfg = TRUE; *is_syslinux_cfg = TRUE;
} }
// Check for an old vesamenu.c32 file anywhere // Check for an old vesamenu.c32 file anywhere
*is_old_vesamenu = FALSE; *is_old_vesamenu = FALSE;
if ((_stricmp(psz_basename, vesamenu_name) == 0) && (i_file_length <= old_vesamenu_threshold)) { if ((safe_stricmp(psz_basename, vesamenu_name) == 0) && (i_file_length <= old_vesamenu_threshold)) {
*is_old_vesamenu = TRUE; *is_old_vesamenu = TRUE;
} }
if (scan_only) { if (scan_only) {
// Check for a "bootmgr" file in root (psz_path = "") // Check for a "bootmgr" file in root (psz_path = "")
if (is_root && (_stricmp(psz_basename, bootmgr_name) == 0)) if ((*psz_dirname == 0) && (safe_stricmp(psz_basename, bootmgr_name) == 0))
iso_report.has_bootmgr = TRUE; iso_report.has_bootmgr = TRUE;
// Check for PE (XP) specific files in "/i386" or "/minint"
for (i=0; i<ARRAYSIZE(pe_dirname); i++)
if (safe_stricmp(psz_dirname, pe_dirname[i]) == 0)
for (j=0; j<ARRAYSIZE(pe_file); j++)
if (safe_stricmp(psz_basename, pe_file[j]) == 0)
iso_report.winpe |= (1<<i)<<(ARRAYSIZE(pe_dirname)*j);
if (*is_syslinux_cfg) { if (*is_syslinux_cfg) {
iso_report.has_isolinux = TRUE; iso_report.has_isolinux = TRUE;
// Maintain a list of all the isolinux/syslinux configs identified so far // Maintain a list of all the isolinux/syslinux configs identified so far
@ -140,7 +148,7 @@ static __inline BOOL check_iso_props(BOOL is_root, BOOL* is_syslinux_cfg, BOOL*
return TRUE; return TRUE;
} }
// In case there's an ldlinux.sys on the ISO, prevent it from overwriting ours // In case there's an ldlinux.sys on the ISO, prevent it from overwriting ours
if (is_root && (safe_strcmp(psz_basename, ldlinux_name) == 0)) { if ((*psz_dirname == 0) && (safe_strcmp(psz_basename, ldlinux_name) == 0)) {
uprintf("skipping % file from ISO image\n", ldlinux_name); uprintf("skipping % file from ISO image\n", ldlinux_name);
return TRUE; return TRUE;
} }
@ -186,7 +194,7 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
} }
} else { } else {
i_file_length = udf_get_file_length(p_udf_dirent); i_file_length = udf_get_file_length(p_udf_dirent);
if (check_iso_props((*psz_path == 0), &is_syslinux_cfg, &is_old_vesamenu, i_file_length, psz_basename, psz_fullpath)) { if (check_iso_props(psz_path, &is_syslinux_cfg, &is_old_vesamenu, i_file_length, psz_basename, psz_fullpath)) {
safe_free(psz_fullpath); safe_free(psz_fullpath);
continue; continue;
} }
@ -300,7 +308,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
goto out; goto out;
} else { } else {
i_file_length = p_statbuf->size; i_file_length = p_statbuf->size;
if (check_iso_props((*psz_path == 0), &is_syslinux_cfg, &is_old_vesamenu, i_file_length, psz_basename, psz_fullpath)) { if (check_iso_props(psz_path, &is_syslinux_cfg, &is_old_vesamenu, i_file_length, psz_basename, psz_fullpath)) {
continue; continue;
} }
// Replace slashes with backslashes and append the size to the path for UI display // Replace slashes with backslashes and append the size to the path for UI display

View file

@ -1040,12 +1040,13 @@ DWORD WINAPI ISOScanThread(LPVOID param)
safe_free(iso_path); safe_free(iso_path);
goto out; goto out;
} }
uprintf("ISO label: '%s'\n size: %lld bytes, 4GB:%c, bootmgr:%c, isolinux:%c, old vesa:%c\n", uprintf("ISO label: '%s'\n size: %lld bytes, 4GB:%c, bootmgr:%c, winpe:%c, isolinux:%c, old vesa:%c\n",
iso_report.label, iso_report.projected_size, iso_report.has_4GB_file?'Y':'N', iso_report.label, iso_report.projected_size, iso_report.has_4GB_file?'Y':'N',
iso_report.has_bootmgr?'Y':'N', iso_report.has_isolinux?'Y':'N', iso_report.has_old_vesamenu?'Y':'N'); iso_report.has_bootmgr?'Y':'N', IS_WINPE(iso_report.winpe)?'Y':'N',
if ((!iso_report.has_bootmgr) && (!iso_report.has_isolinux)) { iso_report.has_isolinux?'Y':'N', iso_report.has_old_vesamenu?'Y':'N');
if ((!iso_report.has_bootmgr) && (!iso_report.has_isolinux) && (!IS_WINPE(iso_report.winpe))) {
MessageBoxU(hMainDialog, "This version of Rufus only supports bootable ISOs\n" MessageBoxU(hMainDialog, "This version of Rufus only supports bootable ISOs\n"
"based on 'bootmgr' or 'isolinux'.\n" "based on 'bootmgr/WinPE' or 'isolinux'.\n"
"This ISO image doesn't appear to use either...", "Unsupported ISO", MB_OK|MB_ICONINFORMATION); "This ISO image doesn't appear to use either...", "Unsupported ISO", MB_OK|MB_ICONINFORMATION);
safe_free(iso_path); safe_free(iso_path);
} else { } else {
@ -1427,8 +1428,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
break; break;
} }
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
if ((fs == FS_NTFS) && (!iso_report.has_bootmgr)) { if ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe))) {
MessageBoxA(hMainDialog, "Only 'bootmgr' based ISO " MessageBoxA(hMainDialog, "Only 'bootmgr' or 'WinPE' based ISO "
"images can currently be used with NTFS.", "Unsupported ISO...", MB_OK|MB_ICONERROR); "images can currently be used with NTFS.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
break; break;
} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && (!iso_report.has_isolinux)) { } else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && (!iso_report.has_isolinux)) {

View file

@ -58,6 +58,7 @@
#define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2)) #define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
#define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2)) #define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
#define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count) #define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count)
#define safe_strnicmp(str1, str2, count) _strnicmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count)
#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0) #define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
#define safe_unlockclose(h) do {if (h != INVALID_HANDLE_VALUE) {UnlockDrive(h); CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0) #define safe_unlockclose(h) do {if (h != INVALID_HANDLE_VALUE) {UnlockDrive(h); CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
#define safe_sprintf _snprintf #define safe_sprintf _snprintf
@ -141,11 +142,15 @@ typedef struct {
} RUFUS_DRIVE_INFO; } RUFUS_DRIVE_INFO;
/* ISO details that the application may want */ /* ISO details that the application may want */
#define WINPE_MININT 0x2A
#define WINPE_I386 0x15
#define IS_WINPE(r) (((r&WINPE_MININT) == WINPE_MININT)||((r&WINPE_I386)==WINPE_I386))
typedef struct { typedef struct {
char label[192]; /* 3*64 to account for UTF-8 */ char label[192]; /* 3*64 to account for UTF-8 */
char usb_label[192]; /* converted USB label for workaround */ char usb_label[192]; /* converted USB label for workaround */
char cfg_path[128]; /* path to the ISO's isolinux.cfg */ char cfg_path[128]; /* path to the ISO's isolinux.cfg */
uint64_t projected_size; uint64_t projected_size;
uint8_t winpe;
BOOL has_4GB_file; BOOL has_4GB_file;
BOOL has_bootmgr; BOOL has_bootmgr;
BOOL has_isolinux; BOOL has_isolinux;
@ -199,6 +204,8 @@ extern BOOL SetAutorun(const char* path);
extern char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_desc); extern char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_desc);
extern LONG GetEntryWidth(HWND hDropDown, const char* entry); extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
extern BOOL DownloadFile(const char* url, const char* file); extern BOOL DownloadFile(const char* url, const char* file);
extern char* get_token_data(const char* filename, const char* token);
extern char* replace_in_token_data(const char* filename, const char* token, const char* src, const char* rep);
__inline static BOOL UnlockDrive(HANDLE hDrive) __inline static BOOL UnlockDrive(HANDLE hDrive)
{ {

View file

@ -33,7 +33,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 206, 289 IDD_DIALOG DIALOGEX 12, 12, 206, 289
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.1.5.153" CAPTION "Rufus v1.1.6.154"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,248,50,14 DEFPUSHBUTTON "Start",IDC_START,94,248,50,14
@ -73,7 +73,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP
CONTROL "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL, CONTROL "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL,
"SysLink",WS_TABSTOP,46,47,114,9 "SysLink",WS_TABSTOP,46,47,114,9
LTEXT "Version 1.1.5 (Build 153)",IDC_STATIC,46,19,78,8 LTEXT "Version 1.1.6 (Build 154)",IDC_STATIC,46,19,78,8
PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP
EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL
LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8
@ -223,8 +223,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,1,5,153 FILEVERSION 1,1,6,154
PRODUCTVERSION 1,1,5,153 PRODUCTVERSION 1,1,6,154
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -241,13 +241,13 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "akeo.ie" VALUE "CompanyName", "akeo.ie"
VALUE "FileDescription", "Rufus" VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.1.5.153" VALUE "FileVersion", "1.1.6.154"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011 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.1.5.153" VALUE "ProductVersion", "1.1.6.154"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"