diff --git a/src/.msvc/rufus_2010.vcxproj b/src/.msvc/rufus_2010.vcxproj
index 8ef7be04..5645f939 100644
--- a/src/.msvc/rufus_2010.vcxproj
+++ b/src/.msvc/rufus_2010.vcxproj
@@ -83,7 +83,7 @@
..\msvc-missing;..\ms-sys\inc;..\syslinux\libinstaller;..\syslinux\libfat;..\libcdio;%(AdditionalIncludeDirectories)
- setupapi.lib;comctl32.lib;%(AdditionalDependencies)
+ setupapi.lib;comctl32.lib;wininet.lib;%(AdditionalDependencies)
HighestAvailable
true
Windows
@@ -106,7 +106,7 @@
ProgramDatabase
- setupapi.lib;comctl32.lib;%(AdditionalDependencies)
+ setupapi.lib;comctl32.lib;wininet.lib;%(AdditionalDependencies)
HighestAvailable
true
Windows
@@ -125,7 +125,7 @@
..\msvc-missing;..\ms-sys\inc;..\syslinux\libinstaller;..\syslinux\libfat;..\libcdio;%(AdditionalIncludeDirectories)
- setupapi.lib;comctl32.lib;%(AdditionalDependencies)
+ setupapi.lib;comctl32.lib;wininet.lib;%(AdditionalDependencies)
HighestAvailable
false
Windows
@@ -147,7 +147,7 @@
..\msvc-missing;..\ms-sys\inc;..\syslinux\libinstaller;..\syslinux\libfat;..\libcdio;%(AdditionalIncludeDirectories)
- setupapi.lib;comctl32.lib;%(AdditionalDependencies)
+ setupapi.lib;comctl32.lib;wininet.lib;%(AdditionalDependencies)
HighestAvailable
false
Windows
@@ -181,7 +181,7 @@
-
+
diff --git a/src/.msvc/rufus_2010.vcxproj.filters b/src/.msvc/rufus_2010.vcxproj.filters
index f1c28cb2..53302d1c 100644
--- a/src/.msvc/rufus_2010.vcxproj.filters
+++ b/src/.msvc/rufus_2010.vcxproj.filters
@@ -92,7 +92,7 @@
Header Files
-
+
Header Files
diff --git a/src/.msvc/rufus_sources b/src/.msvc/rufus_sources
index 83880acb..78a4486d 100644
--- a/src/.msvc/rufus_sources
+++ b/src/.msvc/rufus_sources
@@ -17,6 +17,7 @@ TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\ole32.lib \
$(SDK_LIB_PATH)\uuid.lib \
$(SDK_LIB_PATH)\shell32.lib \
+ $(SDK_LIB_PATH)\wininet.lib \
.\ms-sys\ms-sys.lib \
.\syslinux\libfat\libfat.lib \
.\syslinux\libinstaller\libinstaller.lib \
diff --git a/src/Makefile.am b/src/Makefile.am
index 0ec70283..cf181606 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,4 +13,4 @@ rufus_SOURCES = drive.c icon.c parser.c iso.c net.c dos.c dos_locale.c badblocks
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 \
- libcdio/iso9660/libiso9660.a libcdio/udf/libudf.a libcdio/driver/libdriver.a -lsetupapi -lole32 -lgdi32
+ libcdio/iso9660/libiso9660.a libcdio/udf/libudf.a libcdio/driver/libdriver.a -lsetupapi -lole32 -lgdi32 -lwininet
diff --git a/src/Makefile.in b/src/Makefile.in
index f01da21c..af1bdff2 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -187,7 +187,7 @@ rufus_SOURCES = drive.c icon.c parser.c iso.c net.c dos.c dos_locale.c badblocks
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 \
- libcdio/iso9660/libiso9660.a libcdio/udf/libudf.a libcdio/driver/libdriver.a -lsetupapi -lole32 -lgdi32
+ libcdio/iso9660/libiso9660.a libcdio/udf/libudf.a libcdio/driver/libdriver.a -lsetupapi -lole32 -lgdi32 -lwininet
all: all-recursive
diff --git a/src/net.c b/src/net.c
index e626e598..dfd0c0c4 100644
--- a/src/net.c
+++ b/src/net.c
@@ -1,6 +1,6 @@
/*
* Rufus: The Reliable USB Formatting Utility
- * Networking functionality (web file download, etc.)
+ * Networking functionality (web file download, check for update, etc.)
* Copyright (c) 2012 Pete Batard
*
* This program is free software: you can redistribute it and/or modify
@@ -24,169 +24,227 @@
#endif
#include
+#include
#include
+#include
#include
+#include
#include "msapi_utf8.h"
#include "rufus.h"
+#include "registry.h"
#include "resource.h"
-// winhttp.h is not available for WDK and MinGW32, so we have to use a replacement
-#include "net.h"
+
+/* Maximum download chunk size, in bytes */
+#define DOWNLOAD_BUFFER_SIZE 10240
+/* Default delay between update checks (1 day) */
+#define DEFAULT_UPDATE_INTERVAL (24*3600)
+
+
+/* Globals */
+DWORD error_code;
+
+/* MinGW is missing some of those */
+#if !defined(ERROR_INTERNET_DISCONNECTED)
+#define ERROR_INTERNET_DISCONNECTED (INTERNET_ERROR_BASE + 163)
+#endif
+#if !defined(ERROR_INTERNET_SERVER_UNREACHABLE)
+#define ERROR_INTERNET_SERVER_UNREACHABLE (INTERNET_ERROR_BASE + 164)
+#endif
+#if !defined(ERROR_INTERNET_PROXY_SERVER_UNREACHABLE)
+#define ERROR_INTERNET_PROXY_SERVER_UNREACHABLE (INTERNET_ERROR_BASE + 165)
+#endif
+#if !defined(ERROR_INTERNET_BAD_AUTO_PROXY_SCRIPT)
+#define ERROR_INTERNET_BAD_AUTO_PROXY_SCRIPT (INTERNET_ERROR_BASE + 166)
+#endif
+#if !defined(ERROR_INTERNET_UNABLE_TO_DOWNLOAD_SCRIPT)
+#define ERROR_INTERNET_UNABLE_TO_DOWNLOAD_SCRIPT (INTERNET_ERROR_BASE + 167)
+#endif
+#if !defined(ERROR_INTERNET_FAILED_DUETOSECURITYCHECK)
+#define ERROR_INTERNET_FAILED_DUETOSECURITYCHECK (INTERNET_ERROR_BASE + 171)
+#endif
+#if !defined(ERROR_INTERNET_NOT_INITIALIZED)
+#define ERROR_INTERNET_NOT_INITIALIZED (INTERNET_ERROR_BASE + 172)
+#endif
+#if !defined(ERROR_INTERNET_NEED_MSN_SSPI_PKG)
+#define ERROR_INTERNET_NEED_MSN_SSPI_PKG (INTERNET_ERROR_BASE + 173)
+#endif
+#if !defined(ERROR_INTERNET_LOGIN_FAILURE_DISPLAY_ENTITY_BODY)
+#define ERROR_INTERNET_LOGIN_FAILURE_DISPLAY_ENTITY_BODY (INTERNET_ERROR_BASE + 174)
+#endif
/*
- * FormatMessage does not handle WinHTTP
+ * FormatMessage does not handle internet errors
+ * http://support.microsoft.com/kb/193625
*/
-const char* WinHTTPErrorString(void)
+const char* WinInetErrorString(void)
{
- static char err_string[34];
- DWORD error_code;
+ static char error_string[256];
+ DWORD size = sizeof(error_string);
error_code = GetLastError();
- if ((error_code < WINHTTP_ERROR_BASE) || (error_code > WINHTTP_ERROR_LAST))
+ if ((error_code < INTERNET_ERROR_BASE) || (error_code > INTERNET_ERROR_LAST))
return WindowsErrorString();
switch(error_code) {
- case ERROR_WINHTTP_OUT_OF_HANDLES:
+ case ERROR_INTERNET_OUT_OF_HANDLES:
return "No more handles could be generated at this time.";
- case ERROR_WINHTTP_TIMEOUT:
+ case ERROR_INTERNET_TIMEOUT:
return "The request has timed out.";
- case ERROR_WINHTTP_INTERNAL_ERROR:
+ case ERROR_INTERNET_INTERNAL_ERROR:
return "An internal error has occurred.";
- case ERROR_WINHTTP_INVALID_URL:
+ case ERROR_INTERNET_INVALID_URL:
return "The URL is invalid.";
- case ERROR_WINHTTP_UNRECOGNIZED_SCHEME:
+ case ERROR_INTERNET_UNRECOGNIZED_SCHEME:
return "The URL scheme could not be recognized or is not supported.";
- case ERROR_WINHTTP_NAME_NOT_RESOLVED:
+ case ERROR_INTERNET_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:
+ case ERROR_INTERNET_PROTOCOL_NOT_FOUND:
+ return "The requested protocol could not be located.";
+ case ERROR_INTERNET_INVALID_OPTION:
+ return "A request specified an invalid option value.";
+ case ERROR_INTERNET_BAD_OPTION_LENGTH:
+ return "The length of an option supplied is incorrect for the type of option specified.";
+ case ERROR_INTERNET_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:
+ case ERROR_INTERNET_SHUTDOWN:
+ return "The Win32 Internet function support is being shut down or unloaded.";
+ case ERROR_INTERNET_INCORRECT_USER_NAME:
+ return "The request to connect and log on to an FTP server could not be completed because the supplied user name is incorrect.";
+ case ERROR_INTERNET_INCORRECT_PASSWORD:
+ return "The request to connect and log on to an FTP server could not be completed because the supplied password is incorrect.";
+ case ERROR_INTERNET_LOGIN_FAILURE:
+ return "The request to connect to and log on to an FTP server failed.";
+ case ERROR_INTERNET_INVALID_OPERATION:
+ return "The requested operation is invalid.";
+ case ERROR_INTERNET_OPERATION_CANCELLED:
+ return "The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed.";
+ case ERROR_INTERNET_INCORRECT_HANDLE_TYPE:
return "The type of handle supplied is incorrect for this operation.";
- case ERROR_WINHTTP_INCORRECT_HANDLE_STATE:
+ case ERROR_INTERNET_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:
+ case ERROR_INTERNET_NOT_PROXY_REQUEST:
+ return "The request cannot be made via a proxy.";
+ case ERROR_INTERNET_REGISTRY_VALUE_NOT_FOUND:
+ return "A required registry value could not be located.";
+ case ERROR_INTERNET_BAD_REGISTRY_PARAMETER:
+ return "A required registry value was located but is an incorrect type or has an invalid value.";
+ case ERROR_INTERNET_NO_DIRECT_ACCESS:
+ return "Direct network access cannot be made at this time.";
+ case ERROR_INTERNET_NO_CONTEXT:
+ return "An asynchronous request could not be made because a zero context value was supplied.";
+ case ERROR_INTERNET_NO_CALLBACK:
+ return "An asynchronous request could not be made because a callback function has not been set.";
+ case ERROR_INTERNET_REQUEST_PENDING:
+ return "The required operation could not be completed because one or more requests are pending.";
+ case ERROR_INTERNET_INCORRECT_FORMAT:
+ return "The format of the request is invalid.";
+ case ERROR_INTERNET_ITEM_NOT_FOUND:
+ return "The requested item could not be located.";
+ case ERROR_INTERNET_CANNOT_CONNECT:
return "The attempt to connect to the server failed.";
- case ERROR_WINHTTP_CONNECTION_ERROR:
+ case ERROR_INTERNET_CONNECTION_ABORTED:
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:
+ case ERROR_INTERNET_CONNECTION_RESET:
+ return "The connection with the server has been reset.";
+ case ERROR_INTERNET_FORCE_RETRY:
+ return "Calls for the Win32 Internet function to redo the request.";
+ case ERROR_INTERNET_INVALID_PROXY_REQUEST:
+ return "The request to the proxy was invalid.";
+ case ERROR_INTERNET_HANDLE_EXISTS:
+ return "The request failed because the handle already exists.";
+ case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
+ return "SSL certificate date that was received from the server is bad. The certificate is expired.";
+ case ERROR_INTERNET_SEC_CERT_CN_INVALID:
return "SSL certificate common name (host name field) is incorrect.";
- case ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED:
+ case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
+ return "The application is moving from a non-SSL to an SSL connection because of a redirect.";
+ case ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR:
+ return "The application is moving from an SSL to an non-SSL connection because of a redirect.";
+ case ERROR_INTERNET_MIXED_SECURITY:
+ return "Some of the content being viewed may have come from unsecured servers.";
+ case ERROR_INTERNET_CHG_POST_IS_NON_SECURE:
+ return "The application is posting and attempting to change multiple lines of text on a server that is not secure.";
+ case ERROR_INTERNET_POST_IS_NON_SECURE:
+ return "The application is posting data to a server that is not secure.";
+ case ERROR_FTP_TRANSFER_IN_PROGRESS:
+ return "The requested operation cannot be made on the FTP session handle because an operation is already in progress.";
+ case ERROR_FTP_DROPPED:
+ return "The FTP operation was not completed because the session was aborted.";
+ case ERROR_GOPHER_PROTOCOL_ERROR:
+ case ERROR_GOPHER_NOT_FILE:
+ case ERROR_GOPHER_DATA_ERROR:
+ case ERROR_GOPHER_END_OF_DATA:
+ case ERROR_GOPHER_INVALID_LOCATOR:
+ case ERROR_GOPHER_INCORRECT_LOCATOR_TYPE:
+ case ERROR_GOPHER_NOT_GOPHER_PLUS:
+ case ERROR_GOPHER_ATTRIBUTE_NOT_FOUND:
+ case ERROR_GOPHER_UNKNOWN_LOCATOR:
+ return "Gopher? Really??? What is this? 1994?";
+ case ERROR_HTTP_HEADER_NOT_FOUND:
+ return "The requested header could not be located.";
+ case ERROR_HTTP_DOWNLEVEL_SERVER:
+ return "The server did not return any headers.";
+ case ERROR_HTTP_INVALID_SERVER_RESPONSE:
+ return "The server response could not be parsed.";
+ case ERROR_HTTP_INVALID_HEADER:
+ return "The supplied header is invalid.";
+ case ERROR_HTTP_INVALID_QUERY_REQUEST:
+ return "The request made to HttpQueryInfo is invalid.";
+ case ERROR_HTTP_HEADER_ALREADY_EXISTS:
+ return "The header could not be added because it already exists.";
+ case ERROR_HTTP_REDIRECT_FAILED:
+ return "The redirection failed because either the scheme changed or all attempts made to redirect failed.";
+ case ERROR_INTERNET_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:
+ case ERROR_INTERNET_BAD_AUTO_PROXY_SCRIPT:
return "Bad auto proxy script.";
- case ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT:
+ case ERROR_INTERNET_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.";
+ case ERROR_INTERNET_NOT_INITIALIZED:
+ return "Internet has not be initialized.";
+ case ERROR_INTERNET_UNABLE_TO_CACHE_FILE:
+ return "Unable to cache the file.";
+ case ERROR_INTERNET_TCPIP_NOT_INSTALLED:
+ return "TPC/IP not installed.";
+ case ERROR_INTERNET_DISCONNECTED:
+ return "Internet is disconnected.";
+ case ERROR_INTERNET_SERVER_UNREACHABLE:
+ return "Server could not be reached.";
+ case ERROR_INTERNET_PROXY_SERVER_UNREACHABLE:
+ return "Proxy server could not be reached.";
+ case ERROR_INTERNET_FAILED_DUETOSECURITYCHECK:
+ return "A security check prevented internet connection.";
+ case ERROR_INTERNET_NEED_MSN_SSPI_PKG:
+ return "This connection requires an MSN Security Support Provider Interface package.";
+ case ERROR_INTERNET_LOGIN_FAILURE_DISPLAY_ENTITY_BODY:
+ return "Please ask Microsoft about that one!";
+ case ERROR_INTERNET_EXTENDED_ERROR:
+ InternetGetLastResponseInfoA(&error_code, error_string, &size);
+ return error_string;
default:
- safe_sprintf(err_string, sizeof(err_string), "WinHTTP unknown error 0x%08X", error_code);
- return err_string;
+ safe_sprintf(error_string, sizeof(error_string), "Unknown internet error 0x%08X", error_code);
+ return error_string;
}
}
/*
* Download a file from an URL
- * Mostly taken from http://msdn.microsoft.com/en-us/library/aa384270.aspx
+ * Mostly taken from http://support.microsoft.com/kb/234913
*/
BOOL DownloadFile(const char* url, const char* file)
{
- BOOL r=FALSE;
- DWORD dwSize, dwDownloaded, dwTotalSize, dwReadSize, dwTotalSizeSize = sizeof(dwTotalSize);
- FILE* fd = NULL;
+ BOOL r = FALSE;
+ DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus;
+ 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;
+ unsigned char buf[DOWNLOAD_BUFFER_SIZE];
+ char agent[64], hostname[64], urlpath[128];
+ HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL;
+ URL_COMPONENTSA UrlParts = {sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0,
+ hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1};
+ int i;
// We reuse the ISO progress dialog for download progress
SetWindowTextU(hISOProgressDlg, "Downloading file...");
@@ -200,111 +258,215 @@ BOOL DownloadFile(const char* url, const char* file)
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());
+ if (!InternetCrackUrlA(url, safe_strlen(url), 0, &UrlParts)) {
+ uprintf("Unable to decode URL: %s\n", WindowsErrorString());
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());
+ // Open an Internet session
+ for (i=5; (i>0) && (!InternetGetConnectedState(&dwFlags, 0)); i--) {
+ Sleep(1000);
+ }
+ if (i <= 0) {
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/aa384702.aspx is wrong...
+ SetLastError(ERROR_INTERNET_NOT_INITIALIZED);
+ uprintf("Network is unavailable: %s\n", WinInetErrorString());
+ goto out;
+ }
+ _snprintf(agent, ARRAYSIZE(agent), "Rufus/%d.%d.%d.%d", rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]);
+ hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
+ if (hSession == NULL) {
+ uprintf("Could not open internet session: %s\n", WinInetErrorString());
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());
+ hConnection = InternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL);
+ if (hConnection == NULL) {
+ uprintf("Could not connect to server %s:%d: %s\n", UrlParts.lpszHostName, UrlParts.nPort, WinInetErrorString());
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());
+ hRequest = HttpOpenRequestA(hConnection, "GET", UrlParts.lpszUrlPath, NULL, NULL, (const char**)"*/*\0",
+ INTERNET_FLAG_HYPERLINK|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS|INTERNET_FLAG_NO_COOKIES|
+ INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE, (DWORD_PTR)NULL);
+ if (hRequest == NULL) {
+ uprintf("Could not open url %s: %s\n", url, WindowsErrorString());
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());
+ if (!HttpSendRequest(hRequest, NULL, 0, NULL, 0)) {
+ uprintf("Unable to send request: %s\n", WinInetErrorString());
goto out;
}
- if (!pfWinHttpReceiveResponse(hRequest, NULL)) {
- uprintf("Failure to receive server response: %s\n", WinHTTPErrorString());
+ // Get the file size
+ dwSize = sizeof(dwStatus);
+ dwStatus = 404;
+ HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwStatus, &dwSize, NULL);
+ if (dwStatus != 200) {
+ error_code = ERROR_INTERNET_ITEM_NOT_FOUND;
+ uprintf("Unable to acess file. Server status %d\n", dwStatus);
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());
+ dwSize = sizeof(dwTotalSize);
+ if (!HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwTotalSize, &dwSize, NULL)) {
+ uprintf("Unable to retrieve file length: %s\n", WinInetErrorString());
goto out;
}
uprintf("File length: %d bytes\n", dwTotalSize);
fd = fopen(file, "wb");
if (fd == NULL) {
- uprintf("Unable to create file %s\n", file);
+ uprintf("Unable to create file %s: %s\n", file, WinInetErrorString());
goto out;
}
// Keep checking for data until there is nothing left.
- dwReadSize = 0;
- while(1) {
+ dwSize = 0;
+ while (1) {
if (IS_ERROR(FormatStatus))
goto out;
- dwSize = 0;
- if (!pfWinHttpQueryDataAvailable(hRequest, &dwSize))
- uprintf("Error in WinHttpQueryDataAvailable: %s\n", WinHTTPErrorString());
- if (dwSize <= 0)
+ if (!InternetReadFile(hRequest, buf, sizeof(buf), &dwDownloaded) || (dwDownloaded == 0))
break;
-
- // Allocate space for the buffer.
- buf = (unsigned char*)malloc(dwSize+1);
- if (buf == NULL) {
- uprintf("Could not allocate buffer for download.\n");
+ dwSize += dwDownloaded;
+ SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)(MAX_PROGRESS*((1.0f*dwSize)/(1.0f*dwTotalSize))), 0);
+ PrintStatus(0, FALSE, "Downloading %s: %0.1f%%\n", file, (100.0f*dwSize)/(1.0f*dwTotalSize));
+ if (fwrite(buf, 1, dwDownloaded, fd) != dwDownloaded) {
+ uprintf("Error writing file %s: %s\n", file, WinInetErrorString());
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)
+
+ if (dwSize != dwTotalSize) {
+ uprintf("Could not download complete file - read: %d bytes, expected: %d bytes\n", dwSize, dwTotalSize);
+ FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
+ goto out;
+ } else {
+ r = TRUE;
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(),
+ SetLastError(error_code);
+ MessageBoxA(hMainDialog, IS_ERROR(FormatStatus)?StrError(FormatStatus):WinInetErrorString(),
"File download", MB_OK|MB_ICONERROR);
}
- if (hRequest) pfWinHttpCloseHandle(hRequest);
- if (hConnect) pfWinHttpCloseHandle(hConnect);
- if (hSession) pfWinHttpCloseHandle(hSession);
+ if (hRequest) InternetCloseHandle(hRequest);
+ if (hConnection) InternetCloseHandle(hConnection);
+ if (hSession) InternetCloseHandle(hSession);
return r;
}
+
+#define uuprintf if(verbose) uprintf
+#define uuuprintf if(verbose>1) uprintf
+// TODO: call this from a thread that will launch the download if successful
+BOOL CheckForUpdates(const char* url)
+{
+ BOOL r = FALSE;
+ int verbose = 2;
+ DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus;
+ char* buf = NULL;
+ char agent[64], hostname[64], urlpath[128], mime[32];
+ HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL;
+ URL_COMPONENTSA UrlParts = {sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0,
+ hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1};
+ SYSTEMTIME ServerTime, LocalTime;
+ FILETIME FileTime;
+ int64_t local_time, reg_time, server_time, update_interval;
+
+ verbose = ReadRegistryKey32(REGKEY_VERBOSE_UPDATES);
+ if (GetRegistryKeyBool(REGKEY_DISABLE_UPDATES)) {
+ uuprintf("Check for updates disabled, as per registry settings.\n");
+ return FALSE;
+ }
+ reg_time = ReadRegistryKey64(REGKEY_LAST_UPDATE);
+ update_interval = (int64_t)ReadRegistryKey32(REGKEY_UPDATE_INTERVAL);
+ if (update_interval == 0) {
+ WriteRegistryKey32(REGKEY_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL);
+ update_interval = DEFAULT_UPDATE_INTERVAL;
+ }
+ GetSystemTime(&LocalTime);
+ if (!SystemTimeToFileTime(&LocalTime, &FileTime))
+ goto out;
+ local_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000;
+ uuuprintf("Local time: %" PRId64 "\n", local_time);
+ if (local_time < reg_time + update_interval) {
+ uuprintf("Next update check in %" PRId64 " seconds.\n", reg_time + update_interval - local_time);
+ return FALSE;
+ }
+
+ PrintStatus(3000, FALSE, "Checking for Rufus updates...\n");
+
+ if ((!InternetCrackUrlA(url, safe_strlen(url), 0, &UrlParts)) || (!InternetGetConnectedState(&dwFlags, 0)))
+ goto out;
+
+ _snprintf(agent, ARRAYSIZE(agent), "Rufus/%d.%d.%d.%d", rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]);
+ hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
+ if (hSession == NULL)
+ goto out;
+ hConnection = InternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL);
+ if (hConnection == NULL)
+ goto out;
+
+ hRequest = HttpOpenRequestA(hConnection, "GET", UrlParts.lpszUrlPath, NULL, NULL, (const char**)"*/*\0",
+ INTERNET_FLAG_HYPERLINK|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS|INTERNET_FLAG_NO_COOKIES|
+ INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE, (DWORD_PTR)NULL);
+ if ((hRequest == NULL) || (!HttpSendRequest(hRequest, NULL, 0, NULL, 0)))
+ goto out;
+
+ // Ensure that we get a text file
+ dwSize = sizeof(dwStatus);
+ dwStatus = 404;
+ HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwStatus, &dwSize, NULL);
+ if (dwStatus != 200) goto out;
+ dwSize = sizeof(mime);
+ HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_TYPE, (LPVOID)&mime, &dwSize, NULL);
+ if (strcmp(mime, "text/plain") != 0)
+ goto out;
+ // We also get a date from Apache, which we'll use to avoid out of sync check,
+ // in case some set their clock way into the future and back.
+ // On the other hand, if local clock is set way back in the past, we will never check.
+ dwSize = sizeof(ServerTime);
+ // If we can't get a date we can trust, don't bother...
+ if ( (!HttpQueryInfoA(hRequest, HTTP_QUERY_DATE|HTTP_QUERY_FLAG_SYSTEMTIME, (LPVOID)&ServerTime, &dwSize, NULL))
+ || (!SystemTimeToFileTime(&ServerTime, &FileTime)) )
+ goto out;
+ server_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000;
+ uuuprintf("Server time: %" PRId64 "\n", server_time);
+ // Always store the server response time - the only clock we trust!
+ WriteRegistryKey64(REGKEY_LAST_UPDATE, server_time);
+ // Might as well let the user know
+ if (local_time > server_time + 600) {
+ uprintf("Your local clock seems more than 10 minutes early - You probably want to fix that...\n");
+ }
+ if (local_time < server_time - 600) {
+ uprintf("Your local clock seems more than 10 minutes late - you probably want to fix that...\n");
+ }
+
+ dwSize = sizeof(dwTotalSize);
+ if (!HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwTotalSize, &dwSize, NULL))
+ goto out;
+
+ buf = (char*)calloc(dwTotalSize+1, 1);
+ // Our buffer is always supposed to be large enough, and our read is always supposed to be in one go
+ if (!InternetReadFile(hRequest, buf, dwTotalSize, &dwDownloaded) || (dwDownloaded != dwTotalSize))
+ goto out;
+
+ uuprintf("Successfully downloaded version file %s (%d bytes)\n", url, dwTotalSize);
+ uuprintf("%s\n", buf);
+ r = TRUE;
+
+out:
+ safe_free(buf);
+ if (hRequest) InternetCloseHandle(hRequest);
+ if (hConnection) InternetCloseHandle(hConnection);
+ if (hSession) InternetCloseHandle(hSession);
+ return r;
+}
diff --git a/src/net.h b/src/net.h
deleted file mode 100644
index 13e1aa44..00000000
--- a/src/net.h
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * 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/registry.h b/src/registry.h
new file mode 100644
index 00000000..8350a432
--- /dev/null
+++ b/src/registry.h
@@ -0,0 +1,144 @@
+/*
+ * Rufus: The Reliable USB Formatting Utility
+ * Registry access
+ * Copyright (c) 2012 Pete Batard
+ *
+ * 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
+#include
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Application root subkey, under HKCU\Software
+ * Typically "\"
+ */
+#define REGKEY_APPLICATION "Akeo Systems\\Rufus"
+
+/*
+ * List of registry keys used by this application
+ */
+// Dispa
+#define REGKEY_VERBOSE_UPDATES "VerboseUpdateCheck"
+#define REGKEY_DISABLE_UPDATES "DisableUpdateCheck"
+#define REGKEY_LAST_UPDATE "LastUpdateCheck"
+#define REGKEY_UPDATE_INTERVAL "UpdateCheckInterval"
+
+
+/* Read a generic registry key value (create the app key if it doesn't exist) */
+static __inline BOOL _GetRegistryKey(const char* key_name, DWORD reg_type, LPBYTE dest, DWORD dest_size)
+{
+ BOOL r = FALSE;
+ LONG s;
+ HKEY hSoftware = NULL, hApp = NULL;
+ DWORD dwDisp, dwType = -1, dwSize = dest_size;
+ memset(dest, 0, dest_size);
+
+ if ( (RegOpenKeyExA(HKEY_CURRENT_USER, "SOFTWARE", 0, KEY_READ|KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS)
+ || (RegCreateKeyExA(hSoftware, REGKEY_APPLICATION, 0, NULL, 0,
+ KEY_SET_VALUE|KEY_QUERY_VALUE|KEY_CREATE_SUB_KEY, NULL, &hApp, &dwDisp) != ERROR_SUCCESS) ) {
+ goto out;
+ }
+
+ s = RegQueryValueExA(hApp, key_name, NULL, &dwType, (LPBYTE)dest, &dwSize);
+ // No key means default value of 0 or empty string
+ if ((s == ERROR_FILE_NOT_FOUND) || ((s == ERROR_SUCCESS) && (dwType = reg_type) && (dwSize = dest_size))) {
+ r = TRUE;
+ }
+out:
+ RegCloseKey(hSoftware);
+ RegCloseKey(hApp);
+ return r;
+}
+
+/* Write a generic registry key value (create the app if it doesn't exist) */
+static __inline BOOL _SetRegistryKey(const char* key_name, DWORD reg_type, LPBYTE src, DWORD src_size)
+{
+ BOOL r = FALSE;
+ HKEY hSoftware = NULL, hApp = NULL;
+ DWORD dwDisp, dwType = reg_type;
+
+ if ( (RegOpenKeyExA(HKEY_CURRENT_USER, "SOFTWARE", 0, KEY_READ|KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS)
+ || (RegCreateKeyExA(hSoftware, REGKEY_APPLICATION, 0, NULL, 0,
+ KEY_SET_VALUE|KEY_QUERY_VALUE|KEY_CREATE_SUB_KEY, NULL, &hApp, &dwDisp) != ERROR_SUCCESS) ) {
+ goto out;
+ }
+
+ r = (RegSetValueExA(hApp, key_name, 0, dwType, src, src_size) == ERROR_SUCCESS);
+
+out:
+ RegCloseKey(hSoftware);
+ RegCloseKey(hApp);
+ return r;
+}
+
+/* Helpers for 64 bit registry operations */
+#define GetRegistryKey64(key, pval) _GetRegistryKey(key, REG_QWORD, (LPBYTE)pval, sizeof(LONGLONG))
+#define SetRegistryKey64(key, val) _SetRegistryKey(key, REG_QWORD, (LPBYTE)&val, sizeof(LONGLONG))
+// Check that a key is accessible for R/W (will create a key if not already existing)
+static __inline BOOL CheckRegistryKey64(const char* key) {
+ LONGLONG val;
+ return GetRegistryKey64(key, &val); // && SetRegistryKey64(key, val));
+}
+static __inline int64_t ReadRegistryKey64(const char* key) {
+ LONGLONG val;
+ GetRegistryKey64(key, &val);
+ return (int64_t)val;
+}
+static __inline void WriteRegistryKey64(const char* key, int64_t val) {
+ LONGLONG tmp = (LONGLONG)val;
+ SetRegistryKey64(key, tmp);
+}
+
+/* Helpers for 32 bit registry operations */
+#define GetRegistryKey32(key, pval) _GetRegistryKey(key, REG_DWORD, (LPBYTE)pval, sizeof(DWORD))
+#define SetRegistryKey32(key, val) _SetRegistryKey(key, REG_DWORD, (LPBYTE)&val, sizeof(DWORD))
+static __inline BOOL CheckRegistryKey32(const char* key) {
+ DWORD val;
+ return (GetRegistryKey32(key, &val) && SetRegistryKey32(key, val));
+}
+static __inline int32_t ReadRegistryKey32(const char* key) {
+ DWORD val;
+ GetRegistryKey32(key, &val);
+ return (int32_t)val;
+}
+static __inline void WriteRegistryKey32(const char* key, int32_t val) {
+ DWORD tmp = (DWORD)val;
+ SetRegistryKey32(key, tmp);
+}
+
+/* Helpers for boolean registry operations */
+#define GetRegistryKeyBool(key) (ReadRegistryKey32(key) != 0)
+#define SetRegistryKeyBool(key) WriteRegistryKey32(key, 1)
+#define CheckRegistryKeyBool CheckRegistryKey32
+
+/* Helpers for String registry operations */
+#define GetRegistryKeyStr(key, str, len) _GetRegistryKey(key, REG_SZ, (LPBYTE)str, (DWORD)len)
+#define SetRegistryKeyStr(key, str) _SetRegistryKey(key, REG_SZ, (LPBYTE)str, safe_strlen(str))
+// Use a static buffer - don't allocate
+static __inline char* ReadRegistryKeyStr(const char* key) {
+ static char str[512];
+ _GetRegistryKey(key, REG_SZ, (LPBYTE)str, (DWORD)sizeof(str)-1);
+ return str;
+}
+#define WriteRegistryKeyStr SetRegistryKeyStr
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/rufus.c b/src/rufus.c
index be793388..bc1460bd 100644
--- a/src/rufus.c
+++ b/src/rufus.c
@@ -1625,6 +1625,17 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
break;
#ifdef RUFUS_TEST
case IDC_TEST:
+ CheckForUpdates("http://rufus.akeo.ie/rufus.ver");
+/*
+ InitProgress();
+ if (!IsWindow(hISOProgressDlg)) {
+ hISOProgressDlg = CreateDialogA(hMainInstance, MAKEINTRESOURCEA(IDD_ISO_EXTRACT),
+ hDlg, (DLGPROC)ISOProc);
+ // The window is not visible by default but takes focus => restore it
+ SetFocus(hDlg);
+ }
+ DownloadFile("http://cloud.github.com/downloads/pbatard/rufus/vesamenu.c32", "vesamenu.c32");
+*/
break;
#endif
case IDC_ADVANCED:
diff --git a/src/rufus.h b/src/rufus.h
index 1997c327..56ca4c36 100644
--- a/src/rufus.h
+++ b/src/rufus.h
@@ -24,7 +24,7 @@
/* Program options */
#define RUFUS_DEBUG // print debug info to Debug facility
/* Features not ready for prime time and that may *DESTROY* your data - USE AT YOUR OWN RISKS! */
-//#define RUFUS_TEST
+#define RUFUS_TEST
#define STR_NO_LABEL "NO_LABEL"
#define RUFUS_CANCELBOX_TITLE "Rufus - Cancellation"
@@ -238,6 +238,7 @@ extern char* FileDialog(BOOL save, char* path, char* filename, char* ext, char*
extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size);
extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
extern BOOL DownloadFile(const char* url, const char* file);
+extern BOOL CheckForUpdates(const char* url);
extern BOOL IsShown(HWND hDlg);
extern char* get_token_data(const char* filename, const char* token);
extern char* insert_section_data(const char* filename, const char* section, const char* data, BOOL dos2unix);
diff --git a/src/rufus.rc b/src/rufus.rc
index 9791d097..2042e743 100644
--- a/src/rufus.rc
+++ b/src/rufus.rc
@@ -30,7 +30,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 206, 316
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
-CAPTION "Rufus v1.2.0.190"
+CAPTION "Rufus v1.2.0.191"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,278,50,14
@@ -77,7 +77,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.2.0 (Build 190)",IDC_STATIC,46,19,78,8
+ LTEXT "Version 1.2.0 (Build 191)",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
@@ -237,8 +237,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,2,0,190
- PRODUCTVERSION 1,2,0,190
+ FILEVERSION 1,2,0,191
+ PRODUCTVERSION 1,2,0,191
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -255,13 +255,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "akeo.ie"
VALUE "FileDescription", "Rufus"
- VALUE "FileVersion", "1.2.0.190"
+ VALUE "FileVersion", "1.2.0.191"
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.2.0.190"
+ VALUE "ProductVersion", "1.2.0.191"
END
END
BLOCK "VarFileInfo"