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"