diff --git a/src/.msvc/rufus_2010.vcxproj b/src/.msvc/rufus_2010.vcxproj
index ba941f03..15f1ed88 100644
--- a/src/.msvc/rufus_2010.vcxproj
+++ b/src/.msvc/rufus_2010.vcxproj
@@ -165,6 +165,7 @@
+
@@ -181,6 +182,7 @@
+
diff --git a/src/.msvc/rufus_2010.vcxproj.filters b/src/.msvc/rufus_2010.vcxproj.filters
index 9777c4de..9627380e 100644
--- a/src/.msvc/rufus_2010.vcxproj.filters
+++ b/src/.msvc/rufus_2010.vcxproj.filters
@@ -51,6 +51,9 @@
Source Files
+
+ Source Files
+
@@ -92,6 +95,9 @@
Header Files
+
+ Header Files
+
diff --git a/src/.msvc/rufus_sources b/src/.msvc/rufus_sources
index 3f9490b3..83880acb 100644
--- a/src/.msvc/rufus_sources
+++ b/src/.msvc/rufus_sources
@@ -15,7 +15,6 @@ TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\user32.lib \
$(SDK_LIB_PATH)\setupapi.lib \
$(SDK_LIB_PATH)\ole32.lib \
- $(SDK_LIB_PATH)\version.lib \
$(SDK_LIB_PATH)\uuid.lib \
$(SDK_LIB_PATH)\shell32.lib \
.\ms-sys\ms-sys.lib \
@@ -34,6 +33,7 @@ SOURCES=rufus.c \
stdlg.c \
icon.c \
parser.c \
+ net.c \
iso.c \
dos.c \
dos_locale.c \
diff --git a/src/Makefile.am b/src/Makefile.am
index 6f0f6471..0ec70283 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -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 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 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 \
diff --git a/src/Makefile.in b/src/Makefile.in
index 94bd6cc4..ec099e89 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -44,11 +44,11 @@ CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am_rufus_OBJECTS = rufus-drive.$(OBJEXT) rufus-icon.$(OBJEXT) \
- rufus-parser.$(OBJEXT) rufus-iso.$(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-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_OBJECTS = $(am_rufus_OBJECTS)
rufus_DEPENDENCIES = rufus_rc.o ms-sys/libmssys.a \
syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
@@ -185,7 +185,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 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 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 \
@@ -278,6 +278,14 @@ rufus-iso.obj: iso.c
$(AM_V_CC) @AM_BACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-iso.obj `if test -f 'iso.c'; then $(CYGPATH_W) 'iso.c'; else $(CYGPATH_W) '$(srcdir)/iso.c'; fi`
+rufus-net.o: net.c
+ $(AM_V_CC) @AM_BACKSLASH@
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-net.o `test -f 'net.c' || echo '$(srcdir)/'`net.c
+
+rufus-net.obj: net.c
+ $(AM_V_CC) @AM_BACKSLASH@
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-net.obj `if test -f 'net.c'; then $(CYGPATH_W) 'net.c'; else $(CYGPATH_W) '$(srcdir)/net.c'; fi`
+
rufus-dos.o: dos.c
$(AM_V_CC) @AM_BACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-dos.o `test -f 'dos.c' || echo '$(srcdir)/'`dos.c
diff --git a/src/format.c b/src/format.c
index 756e7c15..7edb6982 100644
--- a/src/format.c
+++ b/src/format.c
@@ -760,11 +760,12 @@ DWORD WINAPI FormatThread(LPVOID param)
// Issue another complete remount before we exit, to ensure we're clean
RemountVolume(drive_name[0]);
// NTFS fixup (WinPE/AIK images don't seem to boot without an extra checkdisk)
- if ((dt == DT_ISO) && (fs = FS_NTFS))
+ if ((dt == DT_ISO) && (fs == FS_NTFS))
CheckDisk(drive_name[0]);
}
out:
+ SendMessage(hISOProgressDlg, UM_ISO_EXIT, 0, 0);
safe_unlockclose(hLogicalVolume);
safe_unlockclose(hPhysicalDrive);
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
diff --git a/src/format.h b/src/format.h
index 54f28c89..948efae5 100644
--- a/src/format.h
+++ b/src/format.h
@@ -21,31 +21,6 @@
#pragma once
-/*
- * typedefs for the function prototypes. Use the something like:
- * PF_DECL(FormatEx);
- * which translates to:
- * FormatEx_t pfFormatEx = NULL;
- * in your code, to declare the entrypoint and then use:
- * PF_INIT(FormatEx, fmifs);
- * which translates to:
- * pfFormatEx = (FormatEx_t) GetProcAddress(GetDLLHandle("fmifs"), "FormatEx");
- * to make it accessible.
- */
-static __inline HMODULE GetDLLHandle(char* szDLLName)
-{
- HMODULE h = NULL;
- if ((h = GetModuleHandleA(szDLLName)) == NULL)
- h = LoadLibraryA(szDLLName);
- return h;
-}
-#define PF_DECL(proc) proc##_t pf##proc = NULL
-#define PF_INIT(proc, dllname) pf##proc = (proc##_t) GetProcAddress(GetDLLHandle(#dllname), #proc)
-#define PF_INIT_OR_OUT(proc, dllname) \
- PF_INIT(proc, dllname); if (pf##proc == NULL) { \
- uprintf("unable to access %s DLL: %s", #dllname, \
- WindowsErrorString()); goto out; }
-
/* Callback command types (some errorcode were filled from HPUSBFW V2.2.3 and their
designation from msdn.microsoft.com/en-us/library/windows/desktop/aa819439.aspx */
typedef enum {
diff --git a/src/icon.c b/src/icon.c
index 29ad3615..1e821bee 100644
--- a/src/icon.c
+++ b/src/icon.c
@@ -17,6 +17,12 @@
* along with this program. If not, see .
*/
+/* Memory leaks detection - define _CRTDBG_MAP_ALLOC as preprocessor macro */
+#ifdef _CRTDBG_MAP_ALLOC
+#include
+#include
+#endif
+
#include
#include
#include
diff --git a/src/iso.c b/src/iso.c
index f344d032..c94fd622 100644
--- a/src/iso.c
+++ b/src/iso.c
@@ -41,15 +41,6 @@
#include "msapi_utf8.h"
#include "resource.h"
-#ifndef MIN
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-#ifndef PBS_MARQUEE
-#define PBS_MARQUEE 0x08
-#endif
-#ifndef PBM_SETMARQUEE
-#define PBM_SETMARQUEE (WM_USER+10)
-#endif
// How often should we update the progress bar (in 2K blocks) as updating
// the progress bar for every block will bring extraction to a crawl
#define PROGRESS_THRESHOLD 1024
@@ -66,6 +57,8 @@ static const char *psz_extract_dir;
static const char *bootmgr_name = "bootmgr";
static const char *ldlinux_name = "ldlinux.sys";
static const char *isolinux_name[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"};
+static const char *vesamenu_name = "vesamenu.c32";
+static int64_t old_vesamenu_threshold = 145000;
static uint8_t i_joliet_level = 0;
static uint64_t total_blocks, nb_blocks;
static BOOL scan_only = FALSE;
@@ -108,8 +101,8 @@ static void log_handler (cdio_log_level_t level, const char *message)
* Scan and set ISO properties
* 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, int64_t i_file_length,
- const char* psz_basename, char* psz_fullpath)
+static __inline BOOL check_iso_props(BOOL is_root, BOOL* is_syslinux_cfg, BOOL* is_old_vesamenu,
+ int64_t i_file_length, const char* psz_basename, char* psz_fullpath)
{
size_t i;
@@ -120,6 +113,12 @@ static __inline BOOL check_iso_props(BOOL is_root, BOOL* is_syslinux_cfg, int64_
*is_syslinux_cfg = TRUE;
}
+ // Check for an old vesamenu.c32 file anywhere
+ *is_old_vesamenu = FALSE;
+ if ((_stricmp(psz_basename, vesamenu_name) == 0) && (i_file_length <= old_vesamenu_threshold)) {
+ *is_old_vesamenu = TRUE;
+ }
+
if (scan_only) {
// Check for a "bootmgr" file in root (psz_path = "")
if (is_root && (_stricmp(psz_basename, bootmgr_name) == 0))
@@ -129,6 +128,8 @@ static __inline BOOL check_iso_props(BOOL is_root, BOOL* is_syslinux_cfg, int64_
// Maintain a list of all the isolinux/syslinux configs identified so far
StrArrayAdd(&config_path, psz_fullpath);
}
+ if (*is_old_vesamenu)
+ iso_report.has_old_vesamenu = TRUE;
if (i_file_length >= FOUR_GIGABYTES)
iso_report.has_4GB_file = TRUE;
// Compute projected size needed
@@ -151,7 +152,7 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
{
HANDLE file_handle = NULL;
DWORD buf_size, wr_size;
- BOOL r, is_syslinux_cfg;
+ BOOL r, is_syslinux_cfg, is_old_vesamenu;
int i_length;
size_t i, nul_pos;
char* psz_fullpath = NULL;
@@ -185,7 +186,7 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
}
} else {
i_file_length = udf_get_file_length(p_udf_dirent);
- if (check_iso_props((*psz_path == 0), &is_syslinux_cfg, i_file_length, psz_basename, psz_fullpath)) {
+ if (check_iso_props((*psz_path == 0), &is_syslinux_cfg, &is_old_vesamenu, i_file_length, psz_basename, psz_fullpath)) {
safe_free(psz_fullpath);
continue;
}
@@ -197,6 +198,13 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
SetWindowTextU(hISOFileName, psz_fullpath);
// Remove the appended size for extraction
psz_fullpath[nul_pos] = 0;
+ if (is_old_vesamenu && use_own_vesamenu) {
+ if (CopyFileA("vesamenu.c32", psz_fullpath, FALSE)) {
+ uprintf(" Replaced with local version\n");
+ continue;
+ }
+ uprintf(" Could not replace file: %s\n", WindowsErrorString());
+ }
file_handle = CreateFileU(psz_fullpath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE) {
@@ -252,7 +260,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
{
HANDLE file_handle = NULL;
DWORD buf_size, wr_size;
- BOOL s, is_syslinux_cfg;
+ BOOL s, is_syslinux_cfg, is_old_vesamenu;
int i_length, r = 1;
char psz_fullpath[1024], *psz_basename;
const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)];
@@ -292,7 +300,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
goto out;
} else {
i_file_length = p_statbuf->size;
- if (check_iso_props((*psz_path == 0), &is_syslinux_cfg, i_file_length, psz_basename, psz_fullpath)) {
+ if (check_iso_props((*psz_path == 0), &is_syslinux_cfg, &is_old_vesamenu, i_file_length, psz_basename, psz_fullpath)) {
continue;
}
// Replace slashes with backslashes and append the size to the path for UI display
@@ -304,6 +312,13 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
// ISO9660 cannot handle backslashes
for (i=0; i
+ *
+ * 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 .
+ */
+
+/* Memory leaks detection - define _CRTDBG_MAP_ALLOC as preprocessor macro */
+#ifdef _CRTDBG_MAP_ALLOC
+#include
+#include
+#endif
+
+#include
+#include
+#include
+
+#include "msapi_utf8.h"
+#include "rufus.h"
+#include "resource.h"
+// winhttp.h is not available for WDK and MinGW32, so we have to use a replacement
+#include "net.h"
+
+/*
+ * FormatMessage does not handle WinHTTP
+ */
+const char* WinHTTPErrorString(void)
+{
+ static char err_string[34];
+ DWORD error_code;
+
+ error_code = GetLastError();
+
+ if ((error_code < WINHTTP_ERROR_BASE) || (error_code > WINHTTP_ERROR_LAST))
+ return WindowsErrorString();
+
+ switch(error_code) {
+ case ERROR_WINHTTP_OUT_OF_HANDLES:
+ return "No more handles could be generated at this time.";
+ case ERROR_WINHTTP_TIMEOUT:
+ return "The request has timed out.";
+ case ERROR_WINHTTP_INTERNAL_ERROR:
+ return "An internal error has occurred.";
+ case ERROR_WINHTTP_INVALID_URL:
+ return "The URL is invalid.";
+ case ERROR_WINHTTP_UNRECOGNIZED_SCHEME:
+ return "The URL scheme could not be recognized or is not supported.";
+ case ERROR_WINHTTP_NAME_NOT_RESOLVED:
+ return "The server name could not be resolved.";
+ case ERROR_WINHTTP_INVALID_OPTION:
+ return "The request specified an invalid option value.";
+ case ERROR_WINHTTP_OPTION_NOT_SETTABLE:
+ return "The request option cannot be set, only queried.";
+ case ERROR_WINHTTP_SHUTDOWN:
+ return "The Win32 HTTP function support is being shut down or unloaded.";
+ case ERROR_WINHTTP_LOGIN_FAILURE:
+ return "The request to connect and log on to the server failed.";
+ case ERROR_WINHTTP_OPERATION_CANCELLED:
+ return "The operation was canceled";
+ case ERROR_WINHTTP_INCORRECT_HANDLE_TYPE:
+ return "The type of handle supplied is incorrect for this operation.";
+ case ERROR_WINHTTP_INCORRECT_HANDLE_STATE:
+ return "The requested operation cannot be carried out because the handle supplied is not in the correct state.";
+ case ERROR_WINHTTP_CANNOT_CONNECT:
+ return "The attempt to connect to the server failed.";
+ case ERROR_WINHTTP_CONNECTION_ERROR:
+ return "The connection with the server has been terminated.";
+ case ERROR_WINHTTP_RESEND_REQUEST:
+ return "The Win32 HTTP function needs to redo the request.";
+ case ERROR_WINHTTP_SECURE_CERT_DATE_INVALID:
+ return "SSL certificate date indicates that the certificate is expired.";
+ case ERROR_WINHTTP_SECURE_CERT_CN_INVALID:
+ return "SSL certificate common name (host name field) is incorrect.";
+ case ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED:
+ return "Client Authentication certificate needed";
+ case ERROR_WINHTTP_SECURE_INVALID_CA:
+ return "SSL certificate has been issued by an invalid Certification Authority.";
+ case ERROR_WINHTTP_SECURE_CERT_REV_FAILED:
+ return "SSL certificate revocation check failed.";
+ case ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN:
+ return "Cannot use this call before WinHttpOpen";
+ case ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND:
+ return "Cannot use this call before WinHttpSend";
+ case ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND:
+ return "Cannot use this call after WinHttpSend";
+ case ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN:
+ return "Cannot use this call after WinHttpOpen";
+ case ERROR_WINHTTP_HEADER_NOT_FOUND:
+ return "HTTP header was not found.";
+ case ERROR_WINHTTP_INVALID_SERVER_RESPONSE:
+ return "Invalid HTTP server response.";
+ case ERROR_WINHTTP_INVALID_HEADER:
+ return "Invalid HTTP header.";
+ case ERROR_WINHTTP_INVALID_QUERY_REQUEST:
+ return "Invalid HTTP query request.";
+ case ERROR_WINHTTP_HEADER_ALREADY_EXISTS:
+ return "HTTP header already exists.";
+ case ERROR_WINHTTP_REDIRECT_FAILED:
+ return "HTTP redirect failed.";
+ case ERROR_WINHTTP_SECURE_CHANNEL_ERROR:
+ return "Unnable to establish secure HTTP channel.";
+ case ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT:
+ return "Bad auto proxy script.";
+ case ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT:
+ return "Unable to download script.";
+ case ERROR_WINHTTP_SECURE_INVALID_CERT:
+ return "SSL certificate is invalid.";
+ case ERROR_WINHTTP_SECURE_CERT_REVOKED:
+ return "SSL certificate has been revoked.";
+ case ERROR_WINHTTP_NOT_INITIALIZED:
+ return "WinHTTP has not be initialized.";
+ case ERROR_WINHTTP_SECURE_FAILURE:
+ return "SSL failure.";
+ case ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR:
+ return "Auto proxy service error.";
+ case ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE:
+ return "Wrong SSL certificate usage.";
+ case ERROR_WINHTTP_AUTODETECTION_FAILED:
+ return "HTTP autodetection failed.";
+ case ERROR_WINHTTP_HEADER_COUNT_EXCEEDED:
+ return "HTTP header count exceeded.";
+ case ERROR_WINHTTP_HEADER_SIZE_OVERFLOW:
+ return "HTTP header size overflow.";
+ case ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW:
+ return "Chunked encoding HTTP header size overflow.";
+ case ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW:
+ return "Response drain overflow.";
+ case ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY:
+ return "Certificate does not contain a private key.";
+ case ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY:
+ return "Unable to access client certificate's private key.";
+ default:
+ safe_sprintf(err_string, sizeof(err_string), "WinHTTP unknown error 0x%08X", error_code);
+ return err_string;
+ }
+}
+
+/*
+ * Download a file from an URL
+ * Mostly taken from http://msdn.microsoft.com/en-us/library/aa384270.aspx
+ */
+BOOL DownloadFile(const char* url, const char* file)
+{
+ BOOL r=FALSE;
+ DWORD dwSize, dwDownloaded, dwTotalSize, dwReadSize, dwTotalSizeSize = sizeof(dwTotalSize);
+ FILE* fd = NULL;
+ LONG progress_style;
+ unsigned char* buf = NULL;
+ wchar_t wAgent[64], *wUrl = NULL, wHostName[64], wUrlPath[128];
+ HINTERNET hSession=NULL, hConnect=NULL, hRequest=NULL;
+ URL_COMPONENTSW UrlParts = {sizeof(URL_COMPONENTSW), NULL, 1, (INTERNET_SCHEME)0,
+ wHostName, ARRAYSIZE(wHostName), INTERNET_DEFAULT_PORT, NULL, 1, wUrlPath, ARRAYSIZE(wUrlPath), NULL, 1};
+
+ PF_DECL(WinHttpCrackUrl);
+ PF_DECL(WinHttpOpen);
+ PF_DECL(WinHttpConnect);
+ PF_DECL(WinHttpOpenRequest);
+ PF_DECL(WinHttpSendRequest);
+ PF_DECL(WinHttpReceiveResponse);
+ PF_DECL(WinHttpQueryHeaders);
+ PF_DECL(WinHttpQueryDataAvailable);
+ PF_DECL(WinHttpReadData);
+ PF_DECL(WinHttpCloseHandle);
+
+ PF_INIT_OR_OUT(WinHttpCrackUrl, winhttp);
+ PF_INIT_OR_OUT(WinHttpOpen, winhttp);
+ PF_INIT_OR_OUT(WinHttpConnect, winhttp);
+ PF_INIT_OR_OUT(WinHttpOpenRequest, winhttp);
+ PF_INIT_OR_OUT(WinHttpSendRequest, winhttp);
+ PF_INIT_OR_OUT(WinHttpReceiveResponse, winhttp);
+ PF_INIT_OR_OUT(WinHttpQueryHeaders, winhttp);
+ PF_INIT_OR_OUT(WinHttpQueryDataAvailable, winhttp);
+ PF_INIT_OR_OUT(WinHttpReadData, winhttp);
+ PF_INIT_OR_OUT(WinHttpCloseHandle, winhttp);
+
+ wUrl = utf8_to_wchar(url);
+ if (wUrl == NULL) goto out;
+
+ // We reuse the ISO progress dialog for download progress
+ SetWindowTextU(hISOProgressDlg, "Downloading file...");
+ SetWindowTextU(hISOFileName, url);
+ progress_style = GetWindowLong(hISOProgressBar, GWL_STYLE);
+ SetWindowLong(hISOProgressBar, GWL_STYLE, progress_style & (~PBS_MARQUEE));
+ SendMessage(hISOProgressBar, PBM_SETPOS, 0, 0);
+ ShowWindow(hISOProgressDlg, SW_SHOW);
+ UpdateWindow(hISOProgressDlg);
+// Sleep(3000);
+
+ PrintStatus(0, FALSE, "Downloading %s: Connecting...\n", file);
+ uprintf("Downloading %s from %s\n", file, url);
+
+ if (!pfWinHttpCrackUrl(wUrl, 0, 0, &UrlParts)) {
+ uprintf("Unable to decode URL: %s\n", WinHTTPErrorString());
+ goto out;
+ }
+
+ _snwprintf(wAgent, ARRAYSIZE(wAgent), L"Rufus/%d.%d.%d.%d", rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]);
+ // Use WinHttpOpen to obtain a session handle.
+ hSession = pfWinHttpOpen(wAgent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
+ if (!hSession) {
+ uprintf("Could not open HTTP session: %s\n", WinHTTPErrorString());
+ goto out;
+ }
+
+ // Specify an HTTP server.
+ hConnect = pfWinHttpConnect(hSession, UrlParts.lpszHostName, UrlParts.nPort, 0);
+ if (!hConnect) {
+ uprintf("Could not connect to HTTP server: %s\n", WinHTTPErrorString());
+ goto out;
+ }
+
+ // Create an HTTP request handle.
+ hRequest = pfWinHttpOpenRequest(hConnect, L"GET", UrlParts.lpszUrlPath,
+ NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES,
+ (UrlParts.nScheme == INTERNET_SCHEME_HTTPS)?WINHTTP_FLAG_SECURE:0);
+ if (!hRequest) {
+ uprintf("Could not create server request: %s\n", WinHTTPErrorString());
+ goto out;
+ }
+
+ if (!pfWinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0 )) {
+ uprintf("Could not send server request: %s\n", WinHTTPErrorString());
+ goto out;
+ }
+
+ if (!pfWinHttpReceiveResponse(hRequest, NULL)) {
+ uprintf("Failure to receive server response: %s\n", WinHTTPErrorString());
+ goto out;
+ }
+
+ if (!pfWinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH|WINHTTP_QUERY_FLAG_NUMBER,
+ WINHTTP_HEADER_NAME_BY_INDEX, &dwTotalSize, &dwTotalSizeSize, WINHTTP_NO_HEADER_INDEX)) {
+ uprintf("Could not retreive file length: %s\n", WinHTTPErrorString());
+ goto out;
+ }
+ uprintf("File length: %d bytes\n", dwTotalSize);
+
+ fd = fopen(file, "wb");
+ if (fd == NULL) {
+ uprintf("Unable to create file %s\n", file);
+ goto out;
+ }
+
+ // Keep checking for data until there is nothing left.
+ dwReadSize = 0;
+ while(1) {
+ if (IS_ERROR(FormatStatus))
+ goto out;
+
+ Sleep(250);
+
+ dwSize = 0;
+ if (!pfWinHttpQueryDataAvailable(hRequest, &dwSize))
+ uprintf("Error in WinHttpQueryDataAvailable: %s\n", WinHTTPErrorString());
+ if (dwSize <= 0)
+ break;
+
+ // Allocate space for the buffer.
+ buf = (unsigned char*)malloc(dwSize+1);
+ if (buf == NULL) {
+ uprintf("Could not allocate buffer for download.\n");
+ goto out;
+ }
+ if (!pfWinHttpReadData(hRequest, (LPVOID)buf, dwSize, &dwDownloaded)) {
+ uprintf("Error in WinHttpReadData: %s\n", WinHTTPErrorString());
+ goto out;
+ }
+ if (dwDownloaded != dwSize) {
+ uprintf("Error: expected %d bytes by received %d\n", dwSize, dwDownloaded);
+ goto out;
+ }
+ dwReadSize += dwDownloaded;
+ SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)(MAX_PROGRESS*((1.0f*dwReadSize)/(1.0f*dwTotalSize))), 0);
+ PrintStatus(0, FALSE, "Downloading %s: %0.1f%%\n", file, (100.0f*dwReadSize)/(1.0f*dwTotalSize));
+ if (fwrite(buf, 1, dwSize, fd) != dwSize) {
+ uprintf("Error writing file %s\n", file);
+ goto out;
+ }
+ safe_free(buf);
+ }
+ r = (dwReadSize == dwTotalSize);
+ if (r)
+ uprintf("Successfully downloaded %s\n", file);
+
+out:
+ ShowWindow(hISOProgressDlg, SW_HIDE);
+ safe_free(wUrl);
+ safe_free(buf);
+ if (fd != NULL) fclose(fd);
+ if (!r) {
+ _unlink(file);
+ PrintStatus(0, FALSE, "Failed to download file.");
+ MessageBoxA(hMainDialog, IS_ERROR(FormatStatus)?StrError(FormatStatus):WinHTTPErrorString(),
+ "File download", MB_OK|MB_ICONERROR);
+ }
+ if (hRequest) pfWinHttpCloseHandle(hRequest);
+ if (hConnect) pfWinHttpCloseHandle(hConnect);
+ if (hSession) pfWinHttpCloseHandle(hSession);
+
+ return r;
+}
diff --git a/src/net.h b/src/net.h
new file mode 100644
index 00000000..13e1aa44
--- /dev/null
+++ b/src/net.h
@@ -0,0 +1,571 @@
+/*
+ * Rufus: The Reliable USB Formatting Utility
+ * Networking functionality (web file download, etc.)
+ * Copyright (c) 2012 Pete Batard
+ * based on winhttp.h from the Wine project
+ * Copyright (C) 2007 Francois Gouget
+ *
+ * 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 .
+ */
+
+#include
+
+#define WINHTTPAPI
+#define BOOLAPI WINHTTPAPI BOOL WINAPI
+
+typedef LPVOID HINTERNET;
+typedef HINTERNET *LPHINTERNET;
+
+#define INTERNET_DEFAULT_PORT 0
+#define INTERNET_DEFAULT_HTTP_PORT 80
+#define INTERNET_DEFAULT_HTTPS_PORT 443
+typedef WORD INTERNET_PORT;
+typedef INTERNET_PORT *LPINTERNET_PORT;
+
+#define INTERNET_SCHEME_HTTP 1
+#define INTERNET_SCHEME_HTTPS 2
+typedef int INTERNET_SCHEME, *LPINTERNET_SCHEME;
+
+#define ICU_ESCAPE 0x80000000
+
+/* flags for WinHttpOpen */
+#define WINHTTP_FLAG_ASYNC 0x10000000
+
+/* flags for WinHttpOpenRequest */
+#define WINHTTP_FLAG_ESCAPE_PERCENT 0x00000004
+#define WINHTTP_FLAG_NULL_CODEPAGE 0x00000008
+#define WINHTTP_FLAG_ESCAPE_DISABLE 0x00000040
+#define WINHTTP_FLAG_ESCAPE_DISABLE_QUERY 0x00000080
+#define WINHTTP_FLAG_BYPASS_PROXY_CACHE 0x00000100
+#define WINHTTP_FLAG_REFRESH WINHTTP_FLAG_BYPASS_PROXY_CACHE
+#define WINHTTP_FLAG_SECURE 0x00800000
+
+#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0
+#define WINHTTP_ACCESS_TYPE_NO_PROXY 1
+#define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3
+
+#define WINHTTP_NO_PROXY_NAME NULL
+#define WINHTTP_NO_PROXY_BYPASS NULL
+
+#define WINHTTP_NO_REFERER NULL
+#define WINHTTP_DEFAULT_ACCEPT_TYPES NULL
+
+#define WINHTTP_NO_ADDITIONAL_HEADERS NULL
+#define WINHTTP_NO_REQUEST_DATA NULL
+
+#define WINHTTP_HEADER_NAME_BY_INDEX NULL
+#define WINHTTP_NO_OUTPUT_BUFFER NULL
+#define WINHTTP_NO_HEADER_INDEX NULL
+
+#define WINHTTP_ADDREQ_INDEX_MASK 0x0000FFFF
+#define WINHTTP_ADDREQ_FLAGS_MASK 0xFFFF0000
+#define WINHTTP_ADDREQ_FLAG_ADD_IF_NEW 0x10000000
+#define WINHTTP_ADDREQ_FLAG_ADD 0x20000000
+#define WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA 0x40000000
+#define WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON 0x01000000
+#define WINHTTP_ADDREQ_FLAG_COALESCE WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
+#define WINHTTP_ADDREQ_FLAG_REPLACE 0x80000000
+
+#define WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH 0
+
+/* flags for WinHttp{Set/Query}Options */
+#define WINHTTP_FIRST_OPTION WINHTTP_OPTION_CALLBACK
+#define WINHTTP_OPTION_CALLBACK 1
+#define WINHTTP_OPTION_RESOLVE_TIMEOUT 2
+#define WINHTTP_OPTION_CONNECT_TIMEOUT 3
+#define WINHTTP_OPTION_CONNECT_RETRIES 4
+#define WINHTTP_OPTION_SEND_TIMEOUT 5
+#define WINHTTP_OPTION_RECEIVE_TIMEOUT 6
+#define WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT 7
+#define WINHTTP_OPTION_HANDLE_TYPE 9
+#define WINHTTP_OPTION_READ_BUFFER_SIZE 12
+#define WINHTTP_OPTION_WRITE_BUFFER_SIZE 13
+#define WINHTTP_OPTION_PARENT_HANDLE 21
+#define WINHTTP_OPTION_EXTENDED_ERROR 24
+#define WINHTTP_OPTION_SECURITY_FLAGS 31
+#define WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT 32
+#define WINHTTP_OPTION_URL 34
+#define WINHTTP_OPTION_SECURITY_KEY_BITNESS 36
+#define WINHTTP_OPTION_PROXY 38
+#define WINHTTP_OPTION_USER_AGENT 41
+#define WINHTTP_OPTION_CONTEXT_VALUE 45
+#define WINHTTP_OPTION_CLIENT_CERT_CONTEXT 47
+#define WINHTTP_OPTION_REQUEST_PRIORITY 58
+#define WINHTTP_OPTION_HTTP_VERSION 59
+#define WINHTTP_OPTION_DISABLE_FEATURE 63
+#define WINHTTP_OPTION_CODEPAGE 68
+#define WINHTTP_OPTION_MAX_CONNS_PER_SERVER 73
+#define WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER 74
+#define WINHTTP_OPTION_AUTOLOGON_POLICY 77
+#define WINHTTP_OPTION_SERVER_CERT_CONTEXT 78
+#define WINHTTP_OPTION_ENABLE_FEATURE 79
+#define WINHTTP_OPTION_WORKER_THREAD_COUNT 80
+#define WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT 81
+#define WINHTTP_OPTION_PASSPORT_COBRANDING_URL 82
+#define WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH 83
+#define WINHTTP_OPTION_SECURE_PROTOCOLS 84
+#define WINHTTP_OPTION_ENABLETRACING 85
+#define WINHTTP_OPTION_PASSPORT_SIGN_OUT 86
+#define WINHTTP_OPTION_PASSPORT_RETURN_URL 87
+#define WINHTTP_OPTION_REDIRECT_POLICY 88
+#define WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS 89
+#define WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE 90
+#define WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE 91
+#define WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE 92
+#define WINHTTP_OPTION_CONNECTION_INFO 93
+#define WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST 94
+#define WINHTTP_OPTION_SPN 96
+#define WINHTTP_OPTION_GLOBAL_PROXY_CREDS 97
+#define WINHTTP_OPTION_GLOBAL_SERVER_CREDS 98
+#define WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT 99
+#define WINHTTP_OPTION_REJECT_USERPWD_IN_URL 100
+#define WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS 101
+#define WINHTTP_LAST_OPTION WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS
+#define WINHTTP_OPTION_USERNAME 0x1000
+#define WINHTTP_OPTION_PASSWORD 0x1001
+#define WINHTTP_OPTION_PROXY_USERNAME 0x1002
+#define WINHTTP_OPTION_PROXY_PASSWORD 0x1003
+
+#define WINHTTP_CONNS_PER_SERVER_UNLIMITED 0xFFFFFFFF
+
+#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM 0
+#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW 1
+#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH 2
+#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_DEFAULT WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM
+
+#define WINHTTP_OPTION_REDIRECT_POLICY_NEVER 0
+#define WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP 1
+#define WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS 2
+#define WINHTTP_OPTION_REDIRECT_POLICY_LAST WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
+#define WINHTTP_OPTION_REDIRECT_POLICY_DEFAULT WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP
+
+#define WINHTTP_DISABLE_PASSPORT_AUTH 0x00000000
+#define WINHTTP_ENABLE_PASSPORT_AUTH 0x10000000
+#define WINHTTP_DISABLE_PASSPORT_KEYRING 0x20000000
+#define WINHTTP_ENABLE_PASSPORT_KEYRING 0x40000000
+
+#define WINHTTP_DISABLE_COOKIES 0x00000001
+#define WINHTTP_DISABLE_REDIRECTS 0x00000002
+#define WINHTTP_DISABLE_AUTHENTICATION 0x00000004
+#define WINHTTP_DISABLE_KEEP_ALIVE 0x00000008
+#define WINHTTP_ENABLE_SSL_REVOCATION 0x00000001
+#define WINHTTP_ENABLE_SSL_REVERT_IMPERSONATION 0x00000002
+#define WINHTTP_DISABLE_SPN_SERVER_PORT 0x00000000
+#define WINHTTP_ENABLE_SPN_SERVER_PORT 0x00000001
+#define WINHTTP_OPTION_SPN_MASK WINHTTP_ENABLE_SPN_SERVER_PORT
+
+/* Options for WinHttpOpenRequest */
+#define WINHTTP_NO_REFERER NULL
+#define WINHTTP_DEFAULT_ACCEPT_TYPES NULL
+
+/* Options for WinHttpSendRequest */
+#define WINHTTP_NO_ADDITIONAL_HEADERS NULL
+#define WINHTTP_NO_REQUEST_DATA NULL
+
+/* WinHTTP error codes */
+#define WINHTTP_ERROR_BASE 12000
+#define ERROR_WINHTTP_OUT_OF_HANDLES (WINHTTP_ERROR_BASE + 1)
+#define ERROR_WINHTTP_TIMEOUT (WINHTTP_ERROR_BASE + 2)
+#define ERROR_WINHTTP_INTERNAL_ERROR (WINHTTP_ERROR_BASE + 4)
+#define ERROR_WINHTTP_INVALID_URL (WINHTTP_ERROR_BASE + 5)
+#define ERROR_WINHTTP_UNRECOGNIZED_SCHEME (WINHTTP_ERROR_BASE + 6)
+#define ERROR_WINHTTP_NAME_NOT_RESOLVED (WINHTTP_ERROR_BASE + 7)
+#define ERROR_WINHTTP_INVALID_OPTION (WINHTTP_ERROR_BASE + 9)
+#define ERROR_WINHTTP_OPTION_NOT_SETTABLE (WINHTTP_ERROR_BASE + 11)
+#define ERROR_WINHTTP_SHUTDOWN (WINHTTP_ERROR_BASE + 12)
+#define ERROR_WINHTTP_LOGIN_FAILURE (WINHTTP_ERROR_BASE + 15)
+#define ERROR_WINHTTP_OPERATION_CANCELLED (WINHTTP_ERROR_BASE + 17)
+#define ERROR_WINHTTP_INCORRECT_HANDLE_TYPE (WINHTTP_ERROR_BASE + 18)
+#define ERROR_WINHTTP_INCORRECT_HANDLE_STATE (WINHTTP_ERROR_BASE + 19)
+#define ERROR_WINHTTP_CANNOT_CONNECT (WINHTTP_ERROR_BASE + 29)
+#define ERROR_WINHTTP_CONNECTION_ERROR (WINHTTP_ERROR_BASE + 30)
+#define ERROR_WINHTTP_RESEND_REQUEST (WINHTTP_ERROR_BASE + 32)
+#define ERROR_WINHTTP_SECURE_CERT_DATE_INVALID (WINHTTP_ERROR_BASE + 37)
+#define ERROR_WINHTTP_SECURE_CERT_CN_INVALID (WINHTTP_ERROR_BASE + 38)
+#define ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED (WINHTTP_ERROR_BASE + 44)
+#define ERROR_WINHTTP_SECURE_INVALID_CA (WINHTTP_ERROR_BASE + 45)
+#define ERROR_WINHTTP_SECURE_CERT_REV_FAILED (WINHTTP_ERROR_BASE + 57)
+#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN (WINHTTP_ERROR_BASE + 100)
+#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND (WINHTTP_ERROR_BASE + 101)
+#define ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND (WINHTTP_ERROR_BASE + 102)
+#define ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN (WINHTTP_ERROR_BASE + 103)
+#define ERROR_WINHTTP_HEADER_NOT_FOUND (WINHTTP_ERROR_BASE + 150)
+#define ERROR_WINHTTP_INVALID_SERVER_RESPONSE (WINHTTP_ERROR_BASE + 152)
+#define ERROR_WINHTTP_INVALID_HEADER (WINHTTP_ERROR_BASE + 153)
+#define ERROR_WINHTTP_INVALID_QUERY_REQUEST (WINHTTP_ERROR_BASE + 154)
+#define ERROR_WINHTTP_HEADER_ALREADY_EXISTS (WINHTTP_ERROR_BASE + 155)
+#define ERROR_WINHTTP_REDIRECT_FAILED (WINHTTP_ERROR_BASE + 156)
+#define ERROR_WINHTTP_SECURE_CHANNEL_ERROR (WINHTTP_ERROR_BASE + 157)
+#define ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT (WINHTTP_ERROR_BASE + 166)
+#define ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT (WINHTTP_ERROR_BASE + 167)
+#define ERROR_WINHTTP_SECURE_INVALID_CERT (WINHTTP_ERROR_BASE + 169)
+#define ERROR_WINHTTP_SECURE_CERT_REVOKED (WINHTTP_ERROR_BASE + 170)
+#define ERROR_WINHTTP_NOT_INITIALIZED (WINHTTP_ERROR_BASE + 172)
+#define ERROR_WINHTTP_SECURE_FAILURE (WINHTTP_ERROR_BASE + 175)
+#define ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR (WINHTTP_ERROR_BASE + 178)
+#define ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE (WINHTTP_ERROR_BASE + 179)
+#define ERROR_WINHTTP_AUTODETECTION_FAILED (WINHTTP_ERROR_BASE + 180)
+#define ERROR_WINHTTP_HEADER_COUNT_EXCEEDED (WINHTTP_ERROR_BASE + 181)
+#define ERROR_WINHTTP_HEADER_SIZE_OVERFLOW (WINHTTP_ERROR_BASE + 182)
+#define ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW (WINHTTP_ERROR_BASE + 183)
+#define ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW (WINHTTP_ERROR_BASE + 184)
+#define ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY (WINHTTP_ERROR_BASE + 185)
+#define ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY (WINHTTP_ERROR_BASE + 186)
+#define WINHTTP_ERROR_LAST (WINHTTP_ERROR_BASE + 186)
+
+/* WinHttp status codes */
+#define HTTP_STATUS_CONTINUE 100
+#define HTTP_STATUS_SWITCH_PROTOCOLS 101
+#define HTTP_STATUS_OK 200
+#define HTTP_STATUS_CREATED 201
+#define HTTP_STATUS_ACCEPTED 202
+#define HTTP_STATUS_PARTIAL 203
+#define HTTP_STATUS_NO_CONTENT 204
+#define HTTP_STATUS_RESET_CONTENT 205
+#define HTTP_STATUS_PARTIAL_CONTENT 206
+#define HTTP_STATUS_WEBDAV_MULTI_STATUS 207
+#define HTTP_STATUS_AMBIGUOUS 300
+#define HTTP_STATUS_MOVED 301
+#define HTTP_STATUS_REDIRECT 302
+#define HTTP_STATUS_REDIRECT_METHOD 303
+#define HTTP_STATUS_NOT_MODIFIED 304
+#define HTTP_STATUS_USE_PROXY 305
+#define HTTP_STATUS_REDIRECT_KEEP_VERB 307
+#define HTTP_STATUS_BAD_REQUEST 400
+#define HTTP_STATUS_DENIED 401
+#define HTTP_STATUS_PAYMENT_REQ 402
+#define HTTP_STATUS_FORBIDDEN 403
+#define HTTP_STATUS_NOT_FOUND 404
+#define HTTP_STATUS_BAD_METHOD 405
+#define HTTP_STATUS_NONE_ACCEPTABLE 406
+#define HTTP_STATUS_PROXY_AUTH_REQ 407
+#define HTTP_STATUS_REQUEST_TIMEOUT 408
+#define HTTP_STATUS_CONFLICT 409
+#define HTTP_STATUS_GONE 410
+#define HTTP_STATUS_LENGTH_REQUIRED 411
+#define HTTP_STATUS_PRECOND_FAILED 412
+#define HTTP_STATUS_REQUEST_TOO_LARGE 413
+#define HTTP_STATUS_URI_TOO_LONG 414
+#define HTTP_STATUS_UNSUPPORTED_MEDIA 415
+#define HTTP_STATUS_RETRY_WITH 449
+#define HTTP_STATUS_SERVER_ERROR 500
+#define HTTP_STATUS_NOT_SUPPORTED 501
+#define HTTP_STATUS_BAD_GATEWAY 502
+#define HTTP_STATUS_SERVICE_UNAVAIL 503
+#define HTTP_STATUS_GATEWAY_TIMEOUT 504
+#define HTTP_STATUS_VERSION_NOT_SUP 505
+#define HTTP_STATUS_FIRST HTTP_STATUS_CONTINUE
+#define HTTP_STATUS_LAST HTTP_STATUS_VERSION_NOT_SUP
+
+#define SECURITY_FLAG_IGNORE_UNKNOWN_CA 0x00000100
+#define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID 0x00002000
+#define SECURITY_FLAG_IGNORE_CERT_CN_INVALID 0x00001000
+#define SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE 0x00000200
+#define SECURITY_FLAG_SECURE 0x00000001
+#define SECURITY_FLAG_STRENGTH_WEAK 0x10000000
+#define SECURITY_FLAG_STRENGTH_MEDIUM 0x40000000
+#define SECURITY_FLAG_STRENGTH_STRONG 0x20000000
+
+#define ICU_NO_ENCODE 0x20000000
+#define ICU_DECODE 0x10000000
+#define ICU_NO_META 0x08000000
+#define ICU_ENCODE_SPACES_ONLY 0x04000000
+#define ICU_BROWSER_MODE 0x02000000
+#define ICU_ENCODE_PERCENT 0x00001000
+
+/* Query flags */
+#define WINHTTP_QUERY_MIME_VERSION 0
+#define WINHTTP_QUERY_CONTENT_TYPE 1
+#define WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING 2
+#define WINHTTP_QUERY_CONTENT_ID 3
+#define WINHTTP_QUERY_CONTENT_DESCRIPTION 4
+#define WINHTTP_QUERY_CONTENT_LENGTH 5
+#define WINHTTP_QUERY_CONTENT_LANGUAGE 6
+#define WINHTTP_QUERY_ALLOW 7
+#define WINHTTP_QUERY_PUBLIC 8
+#define WINHTTP_QUERY_DATE 9
+#define WINHTTP_QUERY_EXPIRES 10
+#define WINHTTP_QUERY_LAST_MODIFIED 11
+#define WINHTTP_QUERY_MESSAGE_ID 12
+#define WINHTTP_QUERY_URI 13
+#define WINHTTP_QUERY_DERIVED_FROM 14
+#define WINHTTP_QUERY_COST 15
+#define WINHTTP_QUERY_LINK 16
+#define WINHTTP_QUERY_PRAGMA 17
+#define WINHTTP_QUERY_VERSION 18
+#define WINHTTP_QUERY_STATUS_CODE 19
+#define WINHTTP_QUERY_STATUS_TEXT 20
+#define WINHTTP_QUERY_RAW_HEADERS 21
+#define WINHTTP_QUERY_RAW_HEADERS_CRLF 22
+#define WINHTTP_QUERY_CONNECTION 23
+#define WINHTTP_QUERY_ACCEPT 24
+#define WINHTTP_QUERY_ACCEPT_CHARSET 25
+#define WINHTTP_QUERY_ACCEPT_ENCODING 26
+#define WINHTTP_QUERY_ACCEPT_LANGUAGE 27
+#define WINHTTP_QUERY_AUTHORIZATION 28
+#define WINHTTP_QUERY_CONTENT_ENCODING 29
+#define WINHTTP_QUERY_FORWARDED 30
+#define WINHTTP_QUERY_FROM 31
+#define WINHTTP_QUERY_IF_MODIFIED_SINCE 32
+#define WINHTTP_QUERY_LOCATION 33
+#define WINHTTP_QUERY_ORIG_URI 34
+#define WINHTTP_QUERY_REFERER 35
+#define WINHTTP_QUERY_RETRY_AFTER 36
+#define WINHTTP_QUERY_SERVER 37
+#define WINHTTP_QUERY_TITLE 38
+#define WINHTTP_QUERY_USER_AGENT 39
+#define WINHTTP_QUERY_WWW_AUTHENTICATE 40
+#define WINHTTP_QUERY_PROXY_AUTHENTICATE 41
+#define WINHTTP_QUERY_ACCEPT_RANGES 42
+#define WINHTTP_QUERY_SET_COOKIE 43
+#define WINHTTP_QUERY_COOKIE 44
+#define WINHTTP_QUERY_REQUEST_METHOD 45
+#define WINHTTP_QUERY_REFRESH 46
+#define WINHTTP_QUERY_CONTENT_DISPOSITION 47
+#define WINHTTP_QUERY_AGE 48
+#define WINHTTP_QUERY_CACHE_CONTROL 49
+#define WINHTTP_QUERY_CONTENT_BASE 50
+#define WINHTTP_QUERY_CONTENT_LOCATION 51
+#define WINHTTP_QUERY_CONTENT_MD5 52
+#define WINHTTP_QUERY_CONTENT_RANGE 53
+#define WINHTTP_QUERY_ETAG 54
+#define WINHTTP_QUERY_HOST 55
+#define WINHTTP_QUERY_IF_MATCH 56
+#define WINHTTP_QUERY_IF_NONE_MATCH 57
+#define WINHTTP_QUERY_IF_RANGE 58
+#define WINHTTP_QUERY_IF_UNMODIFIED_SINCE 59
+#define WINHTTP_QUERY_MAX_FORWARDS 60
+#define WINHTTP_QUERY_PROXY_AUTHORIZATION 61
+#define WINHTTP_QUERY_RANGE 62
+#define WINHTTP_QUERY_TRANSFER_ENCODING 63
+#define WINHTTP_QUERY_UPGRADE 64
+#define WINHTTP_QUERY_VARY 65
+#define WINHTTP_QUERY_VIA 66
+#define WINHTTP_QUERY_WARNING 67
+#define WINHTTP_QUERY_EXPECT 68
+#define WINHTTP_QUERY_PROXY_CONNECTION 69
+#define WINHTTP_QUERY_UNLESS_MODIFIED_SINCE 70
+#define WINHTTP_QUERY_PROXY_SUPPORT 75
+#define WINHTTP_QUERY_AUTHENTICATION_INFO 76
+#define WINHTTP_QUERY_PASSPORT_URLS 77
+#define WINHTTP_QUERY_PASSPORT_CONFIG 78
+#define WINHTTP_QUERY_MAX 78
+#define WINHTTP_QUERY_CUSTOM 65535
+#define WINHTTP_QUERY_FLAG_REQUEST_HEADERS 0x80000000
+#define WINHTTP_QUERY_FLAG_SYSTEMTIME 0x40000000
+#define WINHTTP_QUERY_FLAG_NUMBER 0x20000000
+
+/* Callback options */
+#define WINHTTP_CALLBACK_STATUS_RESOLVING_NAME 0x00000001
+#define WINHTTP_CALLBACK_STATUS_NAME_RESOLVED 0x00000002
+#define WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER 0x00000004
+#define WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER 0x00000008
+#define WINHTTP_CALLBACK_STATUS_SENDING_REQUEST 0x00000010
+#define WINHTTP_CALLBACK_STATUS_REQUEST_SENT 0x00000020
+#define WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE 0x00000040
+#define WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED 0x00000080
+#define WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION 0x00000100
+#define WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED 0x00000200
+#define WINHTTP_CALLBACK_STATUS_HANDLE_CREATED 0x00000400
+#define WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING 0x00000800
+#define WINHTTP_CALLBACK_STATUS_DETECTING_PROXY 0x00001000
+#define WINHTTP_CALLBACK_STATUS_REDIRECT 0x00004000
+#define WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE 0x00008000
+#define WINHTTP_CALLBACK_STATUS_SECURE_FAILURE 0x00010000
+#define WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE 0x00020000
+#define WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE 0x00040000
+#define WINHTTP_CALLBACK_STATUS_READ_COMPLETE 0x00080000
+#define WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE 0x00100000
+#define WINHTTP_CALLBACK_STATUS_REQUEST_ERROR 0x00200000
+#define WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE 0x00400000
+#define WINHTTP_CALLBACK_FLAG_RESOLVE_NAME (WINHTTP_CALLBACK_STATUS_RESOLVING_NAME | WINHTTP_CALLBACK_STATUS_NAME_RESOLVED)
+#define WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER (WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER | WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER)
+#define WINHTTP_CALLBACK_FLAG_SEND_REQUEST (WINHTTP_CALLBACK_STATUS_SENDING_REQUEST | WINHTTP_CALLBACK_STATUS_REQUEST_SENT)
+#define WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE (WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE | WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED)
+#define WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION (WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION | WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED)
+#define WINHTTP_CALLBACK_FLAG_HANDLES (WINHTTP_CALLBACK_STATUS_HANDLE_CREATED | WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING)
+#define WINHTTP_CALLBACK_FLAG_DETECTING_PROXY WINHTTP_CALLBACK_STATUS_DETECTING_PROXY
+#define WINHTTP_CALLBACK_FLAG_REDIRECT WINHTTP_CALLBACK_STATUS_REDIRECT
+#define WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE
+#define WINHTTP_CALLBACK_FLAG_SECURE_FAILURE WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
+#define WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE
+#define WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE
+#define WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
+#define WINHTTP_CALLBACK_FLAG_READ_COMPLETE WINHTTP_CALLBACK_STATUS_READ_COMPLETE
+#define WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE
+#define WINHTTP_CALLBACK_FLAG_REQUEST_ERROR WINHTTP_CALLBACK_STATUS_REQUEST_ERROR
+#define WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS (WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE | WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE \
+ | WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE | WINHTTP_CALLBACK_STATUS_READ_COMPLETE \
+ | WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE | WINHTTP_CALLBACK_STATUS_REQUEST_ERROR)
+#define WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS 0xffffffff
+#define WINHTTP_INVALID_STATUS_CALLBACK ((WINHTTP_STATUS_CALLBACK)(-1L))
+
+#define API_RECEIVE_RESPONSE (1)
+#define API_QUERY_DATA_AVAILABLE (2)
+#define API_READ_DATA (3)
+#define API_WRITE_DATA (4)
+#define API_SEND_REQUEST (5)
+
+#define WINHTTP_HANDLE_TYPE_SESSION 1
+#define WINHTTP_HANDLE_TYPE_CONNECT 2
+#define WINHTTP_HANDLE_TYPE_REQUEST 3
+
+#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED 0x00000001
+#define WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT 0x00000002
+#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED 0x00000004
+#define WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA 0x00000008
+#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID 0x00000010
+#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID 0x00000020
+#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE 0x00000040
+#define WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR 0x80000000
+
+#define WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 0x00000008
+#define WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 0x00000020
+#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 0x00000080
+#define WINHTTP_FLAG_SECURE_PROTOCOL_ALL (WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 | WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1)
+
+#define WINHTTP_AUTH_SCHEME_BASIC 0x00000001
+#define WINHTTP_AUTH_SCHEME_NTLM 0x00000002
+#define WINHTTP_AUTH_SCHEME_PASSPORT 0x00000004
+#define WINHTTP_AUTH_SCHEME_DIGEST 0x00000008
+#define WINHTTP_AUTH_SCHEME_NEGOTIATE 0x00000010
+
+#define WINHTTP_AUTH_TARGET_SERVER 0x00000000
+#define WINHTTP_AUTH_TARGET_PROXY 0x00000001
+
+#define WINHTTP_TIME_FORMAT_BUFSIZE 62
+
+typedef struct
+{
+ DWORD dwStructSize;
+ LPWSTR lpszScheme;
+ DWORD dwSchemeLength;
+ INTERNET_SCHEME nScheme;
+ LPWSTR lpszHostName;
+ DWORD dwHostNameLength;
+ INTERNET_PORT nPort;
+ LPWSTR lpszUserName;
+ DWORD dwUserNameLength;
+ LPWSTR lpszPassword;
+ DWORD dwPasswordLength;
+ LPWSTR lpszUrlPath;
+ DWORD dwUrlPathLength;
+ LPWSTR lpszExtraInfo;
+ DWORD dwExtraInfoLength;
+} URL_COMPONENTS, *LPURL_COMPONENTS;
+typedef URL_COMPONENTS URL_COMPONENTSW;
+typedef LPURL_COMPONENTS LPURL_COMPONENTSW;
+
+typedef struct
+{
+ DWORD_PTR dwResult;
+ DWORD dwError;
+} WINHTTP_ASYNC_RESULT, *LPWINHTTP_ASYNC_RESULT;
+
+typedef struct
+{
+ FILETIME ftExpiry;
+ FILETIME ftStart;
+ LPWSTR lpszSubjectInfo;
+ LPWSTR lpszIssuerInfo;
+ LPWSTR lpszProtocolName;
+ LPWSTR lpszSignatureAlgName;
+ LPWSTR lpszEncryptionAlgName;
+ DWORD dwKeySize;
+} WINHTTP_CERTIFICATE_INFO;
+
+typedef struct
+{
+ DWORD dwAccessType;
+ LPCWSTR lpszProxy;
+ LPCWSTR lpszProxyBypass;
+} WINHTTP_PROXY_INFO, *LPWINHTTP_PROXY_INFO;
+typedef WINHTTP_PROXY_INFO WINHTTP_PROXY_INFOW;
+typedef LPWINHTTP_PROXY_INFO LPWINHTTP_PROXY_INFOW;
+
+typedef struct
+{
+ BOOL fAutoDetect;
+ LPWSTR lpszAutoConfigUrl;
+ LPWSTR lpszProxy;
+ LPWSTR lpszProxyBypass;
+} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG;
+
+typedef VOID (CALLBACK *WINHTTP_STATUS_CALLBACK)(HINTERNET,DWORD_PTR,DWORD,LPVOID,DWORD);
+
+typedef struct
+{
+ DWORD dwFlags;
+ DWORD dwAutoDetectFlags;
+ LPCWSTR lpszAutoConfigUrl;
+ LPVOID lpvReserved;
+ DWORD dwReserved;
+ BOOL fAutoLogonIfChallenged;
+} WINHTTP_AUTOPROXY_OPTIONS;
+
+typedef struct
+{
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+} HTTP_VERSION_INFO, *LPHTTP_VERSION_INFO;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+BOOL WINAPI WinHttpAddRequestHeaders(HINTERNET,LPCWSTR,DWORD,DWORD);
+BOOL WINAPI WinHttpDetectAutoProxyConfigUrl(DWORD,LPWSTR*);
+BOOL WINAPI WinHttpCheckPlatform(void);
+BOOL WINAPI WinHttpCloseHandle(HINTERNET);
+HINTERNET WINAPI WinHttpConnect(HINTERNET,LPCWSTR,INTERNET_PORT,DWORD);
+BOOL WINAPI WinHttpCrackUrl(LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS);
+BOOL WINAPI WinHttpCreateUrl(LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD);
+BOOL WINAPI WinHttpGetDefaultProxyConfiguration(WINHTTP_PROXY_INFO*);
+BOOL WINAPI WinHttpGetIEProxyConfigForCurrentUser(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG*);
+BOOL WINAPI WinHttpGetProxyForUrl(HINTERNET,LPCWSTR,WINHTTP_AUTOPROXY_OPTIONS*,WINHTTP_PROXY_INFO*);
+HINTERNET WINAPI WinHttpOpen(LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD);
+HINTERNET WINAPI WinHttpOpenRequest(HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD);
+BOOL WINAPI WinHttpQueryAuthParams(HINTERNET,DWORD,LPVOID*);
+BOOL WINAPI WinHttpQueryAuthSchemes(HINTERNET,LPDWORD,LPDWORD,LPDWORD);
+BOOL WINAPI WinHttpQueryDataAvailable(HINTERNET,LPDWORD);
+BOOL WINAPI WinHttpQueryHeaders(HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD);
+BOOL WINAPI WinHttpQueryOption(HINTERNET,DWORD,LPVOID,LPDWORD);
+BOOL WINAPI WinHttpReadData(HINTERNET,LPVOID,DWORD,LPDWORD);
+BOOL WINAPI WinHttpReceiveResponse(HINTERNET,LPVOID);
+BOOL WINAPI WinHttpSendRequest(HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR);
+BOOL WINAPI WinHttpSetDefaultProxyConfiguration(WINHTTP_PROXY_INFO*);
+BOOL WINAPI WinHttpSetCredentials(HINTERNET,DWORD,DWORD,LPCWSTR,LPCWSTR,LPVOID);
+BOOL WINAPI WinHttpSetOption(HINTERNET,DWORD,LPVOID,DWORD);
+WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback(HINTERNET,WINHTTP_STATUS_CALLBACK,DWORD,DWORD_PTR);
+BOOL WINAPI WinHttpSetTimeouts(HINTERNET,int,int,int,int);
+BOOL WINAPI WinHttpTimeFromSystemTime(CONST SYSTEMTIME *,LPWSTR);
+BOOL WINAPI WinHttpTimeToSystemTime(LPCWSTR,SYSTEMTIME*);
+BOOL WINAPI WinHttpWriteData(HINTERNET,LPCVOID,DWORD,LPDWORD);
+
+// These are the function calls we'll need for Rufus without going through an import lib
+typedef BOOL (WINAPI *WinHttpCrackUrl_t)(LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS);
+typedef HINTERNET (WINAPI *WinHttpOpen_t)(LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD);
+typedef HINTERNET (WINAPI *WinHttpConnect_t)(HINTERNET,LPCWSTR,INTERNET_PORT,DWORD);
+typedef HINTERNET (WINAPI *WinHttpOpenRequest_t)(HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD);
+typedef BOOL (WINAPI *WinHttpSendRequest_t)(HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR);
+typedef BOOL (WINAPI *WinHttpReceiveResponse_t)(HINTERNET,LPVOID);
+typedef BOOL (WINAPI *WinHttpQueryHeaders_t)(HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD);
+typedef BOOL (WINAPI *WinHttpQueryDataAvailable_t)(HINTERNET,LPDWORD);
+typedef BOOL (WINAPI *WinHttpReadData_t)(HINTERNET,LPVOID,DWORD,LPDWORD);
+typedef BOOL (WINAPI *WinHttpCloseHandle_t)(HINTERNET);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/rufus.c b/src/rufus.c
index 6ea4327e..6e9539a5 100644
--- a/src/rufus.c
+++ b/src/rufus.c
@@ -60,7 +60,8 @@ float fScale = 1.0f;
int default_fs;
HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses;
HWND hISOProgressDlg = NULL, hISOProgressBar, hISOFileName;
-BOOL bWithFreeDOS;
+BOOL bWithFreeDOS, use_own_vesamenu = FALSE;
+int rufus_version[4];
extern char szStatusMessage[256];
static HANDLE format_thid = NULL;
@@ -1008,7 +1009,8 @@ BOOL CALLBACK ISOProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
PrintStatus(0, FALSE, "Cancelling - Please wait...");
uprintf("Cancelling (from ISO proc.)\n");
EnableWindow(GetDlgItem(hISOProgressDlg, IDC_ISO_ABORT), FALSE);
- EnableWindow(GetDlgItem(hMainDialog, IDCANCEL), FALSE);
+ if (format_thid != NULL)
+ EnableWindow(GetDlgItem(hMainDialog, IDCANCEL), FALSE);
// Start a timer to detect blocking operations during ISO file extraction
if (iso_blocking_status >= 0) {
last_iso_blocking_status = iso_blocking_status;
@@ -1020,30 +1022,58 @@ BOOL CALLBACK ISOProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
return TRUE;
}
return FALSE;
-}
+}
// The scanning process can be blocking for message processing => use a thread
DWORD WINAPI ISOScanThread(LPVOID param)
{
int i;
+ FILE* fd;
+ const char* vesamenu_filename = "vesamenu.c32";
if (iso_path == NULL)
goto out;
PrintStatus(0, TRUE, "Scanning ISO image...\n");
if (!ExtractISO(iso_path, "", TRUE)) {
+ SendMessage(hISOProgressDlg, UM_ISO_EXIT, 0, 0);
PrintStatus(0, TRUE, "Failed to scan ISO image.");
safe_free(iso_path);
goto out;
}
- uprintf("ISO label: '%s'\n size: %lld bytes, 4GB:%c, bootmgr:%c, isolinux:%c\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');
+ uprintf("ISO label: '%s'\n size: %lld bytes, 4GB:%c, bootmgr:%c, isolinux:%c, old vesa:%c\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');
if ((!iso_report.has_bootmgr) && (!iso_report.has_isolinux)) {
MessageBoxU(hMainDialog, "This version of Rufus only supports bootable ISOs\n"
"based on 'bootmgr' or 'isolinux'.\n"
"This ISO image doesn't appear to use either...", "Unsupported ISO", MB_OK|MB_ICONINFORMATION);
safe_free(iso_path);
} else {
+ if (iso_report.has_old_vesamenu) {
+ fd = fopen(vesamenu_filename, "rb");
+ if (fd != NULL) {
+ // If a file already exists in the current directory, use that one
+ uprintf("Will replace obsolete '%s' from ISO with the one found in current directory\n", vesamenu_filename);
+ fclose(fd);
+ use_own_vesamenu = TRUE;
+ } else {
+ PrintStatus(0, FALSE, "Obsolete vesamenu.c32 detected");
+ if (MessageBoxA(hMainDialog,
+ "This ISO image seems to use an obsolete version of vesamenu.c32\n"
+ "that may prevent boot menus from displaying properly...\n\n"
+ "Rufus can fix this issue by downloading a newer version for you:\n"
+ "- Select 'Yes' to connect to the internet and replace the file.\n"
+ "- Select 'No' to leave the existing ISO file unmodified.\n"
+ "If you don't know what to do, you should select 'Yes'.\n\n"
+ "Note: the file will be downloaded in the current directory. Once a\n"
+ "vesamenu.c32 exists there, it will always be used as replacement.\n", "Replace vesamenu.c32?",
+ MB_YESNO|MB_ICONWARNING) == IDYES) {
+ if (DownloadFile(VESAMENU_URL, vesamenu_filename))
+ use_own_vesamenu = TRUE;
+ }
+ }
+ }
+
// Enable DOS, set DOS Type to ISO (last item) and set FS accordingly
CheckDlgButton(hMainDialog, IDC_DOS, BST_CHECKED);
SetFSFromISO();
@@ -1061,18 +1091,10 @@ DWORD WINAPI ISOScanThread(LPVOID param)
}
out:
+ SendMessage(hISOProgressDlg, UM_ISO_EXIT, 0, 0);
ExitThread(0);
}
-// Helper function to obtain a handle to a DLL
-static __inline HMODULE GetDLLHandle(char* szDLLName)
-{
- HMODULE h = NULL;
- if ((h = GetModuleHandleA(szDLLName)) == NULL)
- h = LoadLibraryA(szDLLName);
- return h;
-}
-
void InitDialog(HWND hDlg)
{
// MinGW fails to link those
@@ -1097,9 +1119,9 @@ void InitDialog(HWND hDlg)
} bi = {0}; // BUTTON_IMAGELIST
HINSTANCE hDllInst;
HDC hDC;
- int i16;
+ int i, i16;
HICON hSmallIcon, hBigIcon;
- char tmp[128];
+ char tmp[128], *token;
#ifdef RUFUS_TEST
ShowWindow(GetDlgItem(hDlg, IDC_TEST), SW_SHOW);
@@ -1129,6 +1151,13 @@ void InitDialog(HWND hDlg)
SendMessage (hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hSmallIcon);
hBigIcon = (HICON)LoadImage(hMainInstance, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 32, 32, 0);
SendMessage (hDlg, WM_SETICON, ICON_BIG, (LPARAM)hBigIcon);
+ GetWindowTextA(hDlg, tmp, sizeof(tmp));
+ // Count of Microsoft for making it more attractive to read a
+ // version using strtok() than using GetFileVersionInfo()
+ token = strtok(tmp, "v");
+ for (i=0; (i<4) && ((token = strtok(NULL, ".")) != NULL); i++)
+ rufus_version[i] = atoi(token);
+
// Update the title if we have FreeDOS support
if (bWithFreeDOS) {
GetWindowTextA(hDlg, &tmp[15], sizeof(tmp)-15);
diff --git a/src/rufus.h b/src/rufus.h
index 391f1075..f253a59c 100644
--- a/src/rufus.h
+++ b/src/rufus.h
@@ -40,6 +40,7 @@
#define SEPARATOR_GREY RGB(223,223,223)
#define RUFUS_URL "http://rufus.akeo.ie"
#define BUG_URL "https://github.com/pbatard/rufus/issues"
+#define VESAMENU_URL "http://cloud.github.com/downloads/pbatard/rufus/vesamenu.c32"
#define IGNORE_RETVAL(expr) do { (void)(expr); } while(0)
#ifndef ARRAYSIZE
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
@@ -149,6 +150,7 @@ typedef struct {
BOOL has_bootmgr;
BOOL has_isolinux;
BOOL has_autorun;
+ BOOL has_old_vesamenu;
} RUFUS_ISO_REPORT;
/*
@@ -164,9 +166,10 @@ extern char* iso_path;
extern DWORD FormatStatus;
extern RUFUS_DRIVE_INFO SelectedDrive;
extern const int nb_steps[FS_MAX];
-extern BOOL bWithFreeDOS;
+extern BOOL bWithFreeDOS, use_own_vesamenu;
extern RUFUS_ISO_REPORT iso_report;
extern int64_t iso_blocking_status;
+extern int rufus_version[4];
/*
* Shared prototypes
@@ -194,7 +197,8 @@ extern BOOL UnmountDrive(HANDLE hDrive);
extern BOOL CreateProgress(void);
extern BOOL SetAutorun(const char* path);
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);
__inline static BOOL UnlockDrive(HANDLE hDrive)
{
@@ -213,7 +217,30 @@ extern void StrArrayAdd(StrArray* arr, const char* str);
extern void StrArrayClear(StrArray* arr);
extern void StrArrayDestroy(StrArray* arr);
-
+/*
+ * typedefs for the function prototypes. Use the something like:
+ * PF_DECL(FormatEx);
+ * which translates to:
+ * FormatEx_t pfFormatEx = NULL;
+ * in your code, to declare the entrypoint and then use:
+ * PF_INIT(FormatEx, fmifs);
+ * which translates to:
+ * pfFormatEx = (FormatEx_t) GetProcAddress(GetDLLHandle("fmifs"), "FormatEx");
+ * to make it accessible.
+ */
+static __inline HMODULE GetDLLHandle(char* szDLLName)
+{
+ HMODULE h = NULL;
+ if ((h = GetModuleHandleA(szDLLName)) == NULL)
+ h = LoadLibraryA(szDLLName);
+ return h;
+}
+#define PF_DECL(proc) proc##_t pf##proc = NULL
+#define PF_INIT(proc, dllname) pf##proc = (proc##_t) GetProcAddress(GetDLLHandle(#dllname), #proc)
+#define PF_INIT_OR_OUT(proc, dllname) \
+ PF_INIT(proc, dllname); if (pf##proc == NULL) { \
+ uprintf("unable to access %s DLL: %s", #dllname, \
+ WindowsErrorString()); goto out; }
/* Clang/MinGW32 has an issue with intptr_t */
#ifndef _UINTPTR_T_DEFINED
@@ -232,7 +259,6 @@ typedef struct {
ULONG PartitionNumber;
} STORAGE_DEVICE_NUMBER_REDEF;
-
/* Custom application errors */
#define FAC(f) (f<<16)
#define APPERR(err) (APPLICATION_ERROR_MASK|err)
@@ -245,3 +271,14 @@ typedef struct {
#define ERROR_ISO_SCAN 0x1207
#define ERROR_ISO_EXTRACT 0x1208
#define ERROR_CANT_REMOUNT_VOLUME 0x1209
+
+/* More niceties */
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef PBS_MARQUEE
+#define PBS_MARQUEE 0x08
+#endif
+#ifndef PBM_SETMARQUEE
+#define PBM_SETMARQUEE (WM_USER+10)
+#endif
\ No newline at end of file
diff --git a/src/rufus.rc b/src/rufus.rc
index 65d7a2c5..771bec22 100644
--- a/src/rufus.rc
+++ b/src/rufus.rc
@@ -33,7 +33,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 206, 289
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
-CAPTION "Rufus v1.1.5.151"
+CAPTION "Rufus v1.1.5.152"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,248,50,14
@@ -73,7 +73,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP
CONTROL "http://rufus.akeo.ie",IDC_ABOUT_RUFUS_URL,
"SysLink",WS_TABSTOP,46,47,114,9
- LTEXT "Version 1.1.5 (Build 151)",IDC_STATIC,46,19,78,8
+ LTEXT "Version 1.1.5 (Build 152)",IDC_STATIC,46,19,78,8
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
LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8
@@ -223,8 +223,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,1,5,151
- PRODUCTVERSION 1,1,5,151
+ FILEVERSION 1,1,5,152
+ PRODUCTVERSION 1,1,5,152
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -241,13 +241,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "akeo.ie"
VALUE "FileDescription", "Rufus"
- VALUE "FileVersion", "1.1.5.151"
+ VALUE "FileVersion", "1.1.5.152"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
- VALUE "ProductVersion", "1.1.5.151"
+ VALUE "ProductVersion", "1.1.5.152"
END
END
BLOCK "VarFileInfo"
diff --git a/src/stdio.c b/src/stdio.c
index d4f4169e..060ed838 100644
--- a/src/stdio.c
+++ b/src/stdio.c
@@ -108,7 +108,7 @@ static char err_string[256];
safe_sprintf(err_string, sizeof(err_string), "[0x%08X] ", error_code);
- size = FormatMessageU(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
+ size = FormatMessageU(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[strlen(err_string)],
sizeof(err_string)-(DWORD)strlen(err_string), NULL);
if (size == 0) {
diff --git a/src/stdlg.c b/src/stdlg.c
index 6539b753..2ac69f6c 100644
--- a/src/stdlg.c
+++ b/src/stdlg.c
@@ -104,7 +104,6 @@ void DetectWindowsVersion(void)
}
}
-
/*
* String array manipulation
*/