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

[ui] Almost there: Check for application update (part 7)

* Add an abort during download
* Add automated launching of the new version
* Make DownloadFile() more generic with regards to progress indicators
This commit is contained in:
Pete Batard 2012-12-06 01:40:44 +00:00
parent 25e999ded9
commit b315805fa4
6 changed files with 182 additions and 83 deletions

133
src/net.c
View file

@ -42,7 +42,8 @@
/* Globals */ /* Globals */
DWORD error_code; static DWORD error_code;
static BOOL update_check_in_progress = FALSE;
/* MinGW is missing some of those */ /* MinGW is missing some of those */
#if !defined(ERROR_INTERNET_DISCONNECTED) #if !defined(ERROR_INTERNET_DISCONNECTED)
@ -232,9 +233,13 @@ const char* WinInetErrorString(void)
/* /*
* Download a file from an URL * Download a file from an URL
* Mostly taken from http://support.microsoft.com/kb/234913 * Mostly taken from http://support.microsoft.com/kb/234913
* If hProgressDialog is not NULL, this function will send INIT and EXIT messages
* to the dialog in question, with WPARAM being set to nonzero for EXIT on success
* and also attempt to indicate progress using an IDC_PROGRESS control
*/ */
BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog, HWND hProgressBar) BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog)
{ {
HWND hProgressBar = NULL;
BOOL r = FALSE; BOOL r = FALSE;
DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus; DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus;
FILE* fd = NULL; FILE* fd = NULL;
@ -246,16 +251,16 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog, HWND
hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1}; hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1};
int i; int i;
// We reuse the ISO progress dialog for download progress if (hProgressDialog != NULL) {
if (hProgressDialog != NULL) // Use the progress control provided, if any
SetWindowTextU(hProgressDialog, "Downloading file..."); hProgressBar = GetDlgItem(hProgressDialog, IDC_PROGRESS);
if (hProgressBar != NULL) { if (hProgressBar != NULL) {
progress_style = GetWindowLong(hProgressBar, GWL_STYLE); progress_style = GetWindowLong(hProgressBar, GWL_STYLE);
SetWindowLong(hProgressBar, GWL_STYLE, progress_style & (~PBS_MARQUEE)); SetWindowLong(hProgressBar, GWL_STYLE, progress_style & (~PBS_MARQUEE));
SendMessage(hProgressBar, PBM_SETPOS, 0, 0); SendMessage(hProgressBar, PBM_SETPOS, 0, 0);
} }
if (hProgressDialog != NULL)
SendMessage(hProgressDialog, UM_ISO_INIT, 0, 0); SendMessage(hProgressDialog, UM_ISO_INIT, 0, 0);
}
PrintStatus(0, FALSE, "Downloading %s: Connecting...\n", file); PrintStatus(0, FALSE, "Downloading %s: Connecting...\n", file);
uprintf("Downloading %s from %s\n", file, url); uprintf("Downloading %s from %s\n", file, url);
@ -333,7 +338,7 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog, HWND
break; break;
dwSize += dwDownloaded; dwSize += dwDownloaded;
SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)(MAX_PROGRESS*((1.0f*dwSize)/(1.0f*dwTotalSize))), 0); SendMessage(hProgressBar, 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)); PrintStatus(0, FALSE, "Downloading: %0.1f%%\n", (100.0f*dwSize)/(1.0f*dwTotalSize));
if (fwrite(buf, 1, dwDownloaded, fd) != dwDownloaded) { if (fwrite(buf, 1, dwDownloaded, fd) != dwDownloaded) {
uprintf("Error writing file %s: %s\n", file, WinInetErrorString()); uprintf("Error writing file %s: %s\n", file, WinInetErrorString());
goto out; goto out;
@ -351,7 +356,7 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog, HWND
out: out:
if (hProgressDialog != NULL) if (hProgressDialog != NULL)
SendMessage(hProgressDialog, UM_ISO_EXIT, 0, 0); SendMessage(hProgressDialog, UM_ISO_EXIT, (WPARAM)r, 0);
if (fd != NULL) fclose(fd); if (fd != NULL) fclose(fd);
if (!r) { if (!r) {
_unlink(file); _unlink(file);
@ -367,9 +372,29 @@ out:
return r; return r;
} }
// TODO: check that no format operation is occurring /* Threaded download */
DWORD WINAPI CheckForUpdatesThread(LPVOID param) static const char *_url, *_file;
static HWND _hProgressDialog;
static DWORD WINAPI _DownloadFileThread(LPVOID param)
{ {
ExitThread(DownloadFile(_url, _file, _hProgressDialog));
}
HANDLE DownloadFileThreaded(const char* url, const char* file, HWND hProgressDialog)
{
_url = url;
_file = file;
_hProgressDialog = hProgressDialog;
return CreateThread(NULL, 0, _DownloadFileThread, NULL, 0, NULL);
}
/*
* Background thread to check for updates
*/
static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
{
BOOL force = (BOOL)param;
const char* server_url = RUFUS_URL "/"; const char* server_url = RUFUS_URL "/";
int i, j, verbose = 2, verpos[4]; int i, j, verbose = 2, verpos[4];
static char* archname[] = {"win_x86", "win_x64"}; static char* archname[] = {"win_x86", "win_x64"};
@ -382,35 +407,38 @@ DWORD WINAPI CheckForUpdatesThread(LPVOID param)
hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1}; hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1};
SYSTEMTIME ServerTime, LocalTime; SYSTEMTIME ServerTime, LocalTime;
FILETIME FileTime; FILETIME FileTime;
int64_t local_time, reg_time, server_time, update_interval; int64_t local_time = 0, reg_time, server_time, update_interval;
BOOL is_x64 = FALSE, (__stdcall *pIsWow64Process)(HANDLE, PBOOL) = NULL; BOOL is_x64 = FALSE, (__stdcall *pIsWow64Process)(HANDLE, PBOOL) = NULL;
// Wait a while before checking for updates update_check_in_progress = TRUE;
// TODO: Also check on inactivity if (!force) {
do { // Wait a while before checking for updates
Sleep(10000); // TODO: Also check on inactivity
} while (iso_op_in_progress || format_op_in_progress); do {
Sleep(10000);
} while (iso_op_in_progress || format_op_in_progress);
// TODO: reenable this // TODO: reenable this
// verbose = ReadRegistryKey32(REGKEY_VERBOSE_UPDATES); // verbose = ReadRegistryKey32(REGKEY_VERBOSE_UPDATES);
if ((ReadRegistryKey32(REGKEY_UPDATE_INTERVAL) == -1)) { if ((ReadRegistryKey32(REGKEY_UPDATE_INTERVAL) == -1)) {
vuprintf("Check for updates disabled, as per registry settings.\n"); vuprintf("Check for updates disabled, as per registry settings.\n");
goto out; goto out;
} }
reg_time = ReadRegistryKey64(REGKEY_LAST_UPDATE); reg_time = ReadRegistryKey64(REGKEY_LAST_UPDATE);
update_interval = (int64_t)ReadRegistryKey32(REGKEY_UPDATE_INTERVAL); update_interval = (int64_t)ReadRegistryKey32(REGKEY_UPDATE_INTERVAL);
if (update_interval == 0) { if (update_interval == 0) {
WriteRegistryKey32(REGKEY_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL); WriteRegistryKey32(REGKEY_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL);
update_interval = DEFAULT_UPDATE_INTERVAL; update_interval = DEFAULT_UPDATE_INTERVAL;
} }
GetSystemTime(&LocalTime); GetSystemTime(&LocalTime);
if (!SystemTimeToFileTime(&LocalTime, &FileTime)) if (!SystemTimeToFileTime(&LocalTime, &FileTime))
goto out; goto out;
local_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000; local_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000;
vvuprintf("Local time: %" PRId64 "\n", local_time); vvuprintf("Local time: %" PRId64 "\n", local_time);
if (local_time < reg_time + update_interval) { if (local_time < reg_time + update_interval) {
vuprintf("Next update check in %" PRId64 " seconds.\n", reg_time + update_interval - local_time); vuprintf("Next update check in %" PRId64 " seconds.\n", reg_time + update_interval - local_time);
goto out; goto out;
}
} }
PrintStatus(3000, FALSE, "Checking for " APPLICATION_NAME " updates...\n"); PrintStatus(3000, FALSE, "Checking for " APPLICATION_NAME " updates...\n");
@ -505,11 +533,13 @@ DWORD WINAPI CheckForUpdatesThread(LPVOID param)
// Always store the server response time - the only clock we trust! // Always store the server response time - the only clock we trust!
WriteRegistryKey64(REGKEY_LAST_UPDATE, server_time); WriteRegistryKey64(REGKEY_LAST_UPDATE, server_time);
// Might as well let the user know // Might as well let the user know
if (local_time > server_time + 600) { if (!force) {
uprintf("Your local clock appears more than 10 minutes early - You ought to fix that...\n"); if (local_time > server_time + 600) {
} uprintf("Your local clock appears more than 10 minutes early - You ought to fix that...\n");
if (local_time < server_time - 600) { }
uprintf("Your local clock appears more than 10 minutes late - you ought to fix that...\n"); if (local_time < server_time - 600) {
uprintf("Your local clock appears more than 10 minutes late - you ought to fix that...\n");
}
} }
dwSize = sizeof(dwTotalSize); dwSize = sizeof(dwTotalSize);
@ -532,13 +562,18 @@ out:
if (hRequest) InternetCloseHandle(hRequest); if (hRequest) InternetCloseHandle(hRequest);
if (hConnection) InternetCloseHandle(hConnection); if (hConnection) InternetCloseHandle(hConnection);
if (hSession) InternetCloseHandle(hSession); if (hSession) InternetCloseHandle(hSession);
update_check_in_progress = FALSE;
ExitThread(0); ExitThread(0);
} }
BOOL CheckForUpdates(void) /*
* Initiate a check for updates. If force is true, ignore the wait period
*/
BOOL CheckForUpdates(BOOL force)
{ {
if (CreateThread(NULL, 0, CheckForUpdatesThread, NULL, 0, 0) == NULL) { if (update_check_in_progress)
return FALSE;
if (CreateThread(NULL, 0, CheckForUpdatesThread, (LPVOID)force, 0, NULL) == NULL) {
uprintf("Unable to start check for updates thread"); uprintf("Unable to start check for updates thread");
return FALSE; return FALSE;
} }

View file

@ -63,7 +63,6 @@
#define IDC_SELECT_ISO 1016 #define IDC_SELECT_ISO 1016
#define IDC_SET_ICON 1017 #define IDC_SET_ICON 1017
#define IDC_RUFUS_MBR 1018 #define IDC_RUFUS_MBR 1018
#define IDC_ISO_PROGRESS 1019
#define IDC_ISO_FILENAME 1020 #define IDC_ISO_FILENAME 1020
#define IDC_ISO_ABORT 1021 #define IDC_ISO_ABORT 1021
#define IDC_DISK_ID 1022 #define IDC_DISK_ID 1022
@ -89,7 +88,6 @@
#define IDC_INCLUDE_BETAS 1063 #define IDC_INCLUDE_BETAS 1063
#define IDC_RELEASE_NOTES 1064 #define IDC_RELEASE_NOTES 1064
#define IDC_DOWNLOAD 1065 #define IDC_DOWNLOAD 1065
#define IDC_UPDATE_PROGRESS 1066
#define IDC_WEBSITE 1067 #define IDC_WEBSITE 1067
#define IDC_YOUR_VERSION 1068 #define IDC_YOUR_VERSION 1068
#define IDC_LATEST_VERSION 1069 #define IDC_LATEST_VERSION 1069

View file

@ -1199,7 +1199,7 @@ BOOL CALLBACK ISOProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{ {
switch (message) { switch (message) {
case WM_INITDIALOG: case WM_INITDIALOG:
hISOProgressBar = GetDlgItem(hDlg, IDC_ISO_PROGRESS); hISOProgressBar = GetDlgItem(hDlg, IDC_PROGRESS);
hISOFileName = GetDlgItem(hDlg, IDC_ISO_FILENAME); hISOFileName = GetDlgItem(hDlg, IDC_ISO_FILENAME);
// Use maximum granularity for the progress bar // Use maximum granularity for the progress bar
SendMessage(hISOProgressBar, PBM_SETRANGE, 0, MAX_PROGRESS<<16); SendMessage(hISOProgressBar, PBM_SETRANGE, 0, MAX_PROGRESS<<16);
@ -1283,8 +1283,9 @@ DWORD WINAPI ISOScanThread(LPVOID param)
"Note: the file will be downloaded in the current directory. Once a\n" "Note: the file will be downloaded in the current directory. Once a\n"
"vesamenu.c32 exists there, it will always be used as replacement.\n", "Replace vesamenu.c32?", "vesamenu.c32 exists there, it will always be used as replacement.\n", "Replace vesamenu.c32?",
MB_YESNO|MB_ICONWARNING) == IDYES) { MB_YESNO|MB_ICONWARNING) == IDYES) {
SetWindowTextU(hISOProgressDlg, "Downloading file...");
SetWindowTextU(hISOFileName, VESAMENU_URL); SetWindowTextU(hISOFileName, VESAMENU_URL);
if (DownloadFile(VESAMENU_URL, vesamenu_filename, hISOProgressDlg, hISOProgressBar)) if (DownloadFile(VESAMENU_URL, vesamenu_filename, hISOProgressDlg))
use_own_vesamenu = TRUE; use_own_vesamenu = TRUE;
} }
} }
@ -1550,7 +1551,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
hLogDlg = CreateDialogA(hMainInstance, MAKEINTRESOURCEA(IDD_LOG), hDlg, (DLGPROC)LogProc); hLogDlg = CreateDialogA(hMainInstance, MAKEINTRESOURCEA(IDD_LOG), hDlg, (DLGPROC)LogProc);
InitDialog(hDlg); InitDialog(hDlg);
GetUSBDevices(0); GetUSBDevices(0);
CheckForUpdates(); CheckForUpdates(FALSE);
PostMessage(hMainDialog, UM_ISO_CREATE, 0, 0); PostMessage(hMainDialog, UM_ISO_CREATE, 0, 0);
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
@ -1774,7 +1775,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
selection_default = DT_ISO; selection_default = DT_ISO;
CreateTooltip(hSelectISO, iso_path, -1); CreateTooltip(hSelectISO, iso_path, -1);
FormatStatus = 0; FormatStatus = 0;
if (CreateThread(NULL, 0, ISOScanThread, NULL, 0, 0) == NULL) { if (CreateThread(NULL, 0, ISOScanThread, NULL, 0, NULL) == NULL) {
uprintf("Unable to start ISO scanning thread"); uprintf("Unable to start ISO scanning thread");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD);
} }
@ -1915,18 +1916,43 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
/* /*
* Application Entrypoint * Application Entrypoint
*/ */
// If we ever need to process more than one commandline arguments, uncomment the following parts
// typedef int (CDECL *__wgetmainargs_t)(int*, wchar_t***, wchar_t***, int, int*);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{ {
// int i, argc = 0, si = 0;
// char** argv = NULL;
// wchar_t **wenv, **wargv;
// PF_DECL(__wgetmainargs);
HANDLE mutex = NULL; HANDLE mutex = NULL;
HWND hDlg = NULL; HWND hDlg = NULL;
MSG msg; MSG msg;
int wait_for_mutex = 0;
uprintf("*** RUFUS INIT ***\n"); uprintf("*** RUFUS INIT ***\n");
// Prevent 2 applications from running at the same time // PF_INIT(__wgetmainargs, msvcrt);
// if (pf__wgetmainargs != NULL) {
// pf__wgetmainargs(&argc, &wargv, &wenv, 1, &si);
// argv = (char**)calloc(argc, sizeof(char*));
// for (i=0; i<argc; i++) {
// argv[i] = wchar_to_utf8(wargv[i]);
// }
// } else {
// uprintf("unable to access UTF-16 args");
// }
// Prevent 2 applications from running at the same time, unless "/W" is passed as an option
// in which case we wait for the mutex to be relinquished
if ((safe_strlen(lpCmdLine)==2) && (lpCmdLine[0] == '/') && (lpCmdLine[1] == 'W'))
wait_for_mutex = 150; // Try to acquire the mutex for 15 seconds
mutex = CreateMutexA(NULL, TRUE, "Global/RUFUS"); mutex = CreateMutexA(NULL, TRUE, "Global/RUFUS");
if ((mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) for (;(wait_for_mutex>0) && (mutex != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS); wait_for_mutex--) {
{ CloseHandle(mutex);
Sleep(100);
mutex = CreateMutexA(NULL, TRUE, "Global/RUFUS");
}
if ((mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) {
MessageBoxA(NULL, "Another Rufus application is running.\n" MessageBoxA(NULL, "Another Rufus application is running.\n"
"Please close the first application before running another one.", "Please close the first application before running another one.",
"Other instance detected", MB_ICONSTOP); "Other instance detected", MB_ICONSTOP);
@ -2009,6 +2035,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
DeleteRegistryKey(COMPANY_NAME); DeleteRegistryKey(COMPANY_NAME);
continue; continue;
} }
// Alt-U => Force an update check
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'U')) {
CheckForUpdates(TRUE);
continue;
}
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }

View file

@ -262,10 +262,11 @@ extern BOOL SetAutorun(const char* path);
extern char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_desc); extern char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_desc);
extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size); extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size);
extern LONG GetEntryWidth(HWND hDropDown, const char* entry); extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
extern BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog, HWND hProgressBar); extern BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog);
extern HANDLE DownloadFileThreaded(const char* url, const char* file, HWND hProgressDialog);
extern INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); extern INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
extern BOOL SetUpdateCheck(void); extern BOOL SetUpdateCheck(void);
extern BOOL CheckForUpdates(void); extern BOOL CheckForUpdates(BOOL force);
extern void DownloadNewVersion(void); extern void DownloadNewVersion(void);
extern BOOL IsShown(HWND hDlg); extern BOOL IsShown(HWND hDlg);
extern char* get_token_data_file(const char* token, const char* filename); extern char* get_token_data_file(const char* token, const char* filename);

View file

@ -30,7 +30,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 206, 316 IDD_DIALOG DIALOGEX 12, 12, 206, 316
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW EXSTYLE WS_EX_APPWINDOW
CAPTION "Rufus v1.2.1.203" CAPTION "Rufus v1.2.1.204"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,278,50,14 DEFPUSHBUTTON "Start",IDC_START,94,278,50,14
@ -85,7 +85,7 @@ CAPTION "Copying ISO files..."
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
LTEXT "Opening ISO image - please wait...",IDC_ISO_FILENAME,8,10,246,13,SS_PATHELLIPSIS LTEXT "Opening ISO image - please wait...",IDC_ISO_FILENAME,8,10,246,13,SS_PATHELLIPSIS
CONTROL "",IDC_ISO_PROGRESS,"msctls_progress32",WS_BORDER,7,26,247,8 CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,7,26,247,8
PUSHBUTTON "Cancel",IDC_ISO_ABORT,111,43,50,14 PUSHBUTTON "Cancel",IDC_ISO_ABORT,111,43,50,14
END END
@ -146,7 +146,7 @@ BEGIN
PUSHBUTTON "Close",IDCANCEL,167,244,50,14,WS_GROUP PUSHBUTTON "Close",IDCANCEL,167,244,50,14,WS_GROUP
CONTROL "",IDC_RELEASE_NOTES,"RichEdit20W",ES_MULTILINE | ES_READONLY | WS_VSCROLL,15,77,352,88,WS_EX_STATICEDGE CONTROL "",IDC_RELEASE_NOTES,"RichEdit20W",ES_MULTILINE | ES_READONLY | WS_VSCROLL,15,77,352,88,WS_EX_STATICEDGE
DEFPUSHBUTTON "Download",IDC_DOWNLOAD,293,211,74,14,WS_GROUP DEFPUSHBUTTON "Download",IDC_DOWNLOAD,293,211,74,14,WS_GROUP
CONTROL "",IDC_UPDATE_PROGRESS,"msctls_progress32",WS_BORDER,15,212,270,11 CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,15,212,270,11
GROUPBOX "Release Notes",IDC_STATIC,8,63,367,111 GROUPBOX "Release Notes",IDC_STATIC,8,63,367,111
LTEXT "A newer version is available. Please download the latest version!",IDC_STATIC,10,32,229,8 LTEXT "A newer version is available. Please download the latest version!",IDC_STATIC,10,32,229,8
LTEXT "[...]",IDC_YOUR_VERSION,10,8,124,8 LTEXT "[...]",IDC_YOUR_VERSION,10,8,124,8
@ -272,8 +272,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,2,1,203 FILEVERSION 1,2,1,204
PRODUCTVERSION 1,2,1,203 PRODUCTVERSION 1,2,1,204
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -290,13 +290,13 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus" VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.2.1.203" VALUE "FileVersion", "1.2.1.204"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "(c) 2011-2012 Pete Batard (GPL v3)" VALUE "LegalCopyright", "(c) 2011-2012 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe" VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus" VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "1.2.1.203" VALUE "ProductVersion", "1.2.1.204"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -1189,8 +1189,6 @@ BOOL SetUpdateCheck(void)
((ReadRegistryKey32(REGKEY_UPDATE_INTERVAL) == -1) && enable_updates) ) ((ReadRegistryKey32(REGKEY_UPDATE_INTERVAL) == -1) && enable_updates) )
WriteRegistryKey32(REGKEY_UPDATE_INTERVAL, 86400); WriteRegistryKey32(REGKEY_UPDATE_INTERVAL, 86400);
} }
// TODO: check for lastcheck + interval & launch the background thread here?
// TODO: make sure we check for updates if user just accepted
return TRUE; return TRUE;
} }
@ -1205,11 +1203,14 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR
ENLINK* enl; ENLINK* enl;
wchar_t wUrl[256]; wchar_t wUrl[256];
char tmp[128]; char tmp[128];
char* filepath; static char* filepath = NULL;
static BOOL was_downloaded = FALSE; static int download_status = 0;
STARTUPINFOA si;
PROCESS_INFORMATION pi;
switch (message) { switch (message) {
case WM_INITDIALOG: case WM_INITDIALOG:
download_status = 0;
SetTitleBarIcon(hDlg); SetTitleBarIcon(hDlg);
CenterDialog(hDlg); CenterDialog(hDlg);
hNotes = GetDlgItem(hDlg, IDC_RELEASE_NOTES); hNotes = GetDlgItem(hDlg, IDC_RELEASE_NOTES);
@ -1224,7 +1225,9 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR
update.version[0], update.version[1], update.version[2], update.version[3]); update.version[0], update.version[1], update.version[2], update.version[3]);
SetWindowTextA(GetDlgItem(hDlg, IDC_LATEST_VERSION), tmp); SetWindowTextA(GetDlgItem(hDlg, IDC_LATEST_VERSION), tmp);
SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD_URL), update.download_url); SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD_URL), update.download_url);
SendMessage(GetDlgItem(hDlg, IDC_UPDATE_PROGRESS), PBM_SETRANGE, 0, MAX_PROGRESS<<16); SendMessage(GetDlgItem(hDlg, IDC_PROGRESS), PBM_SETRANGE, 0, MAX_PROGRESS<<16);
if (update.download_url == NULL)
EnableWindow(GetDlgItem(hDlg, IDC_DOWNLOAD), FALSE);
break; break;
case WM_NOTIFY: case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code) { switch (((LPNMHDR)lParam)->code) {
@ -1250,24 +1253,55 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR
switch (LOWORD(wParam)) { switch (LOWORD(wParam)) {
case IDCLOSE: case IDCLOSE:
case IDCANCEL: case IDCANCEL:
safe_free(filepath);
EndDialog(hDlg, LOWORD(wParam)); EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
case IDC_DOWNLOAD: case IDC_DOWNLOAD: // Also doubles as abort and laucnh function
if (update.download_url == NULL) switch(download_status) {
return (INT_PTR)TRUE; case 1: // Abort
for (i=(int)safe_strlen(update.download_url); (i>0)&&(update.download_url[i]!='/'); i--); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED;
filepath = FileDialog(TRUE, app_dir, (char*)&update.download_url[i+1], "exe", "Application"); break;
if (filepath != NULL) { case 2: // Launch newer version and close this one
if (DownloadFile(update.download_url, filepath, NULL, GetDlgItem(hDlg, IDC_UPDATE_PROGRESS))) { for (i=(int)safe_strlen(filepath); (i>0)&&(filepath[i]!='\\'); i--);
// TODO: create a thread and allow aborts + invoke a launcher when successful safe_strcpy(tmp, sizeof(tmp), &filepath[i+1]);
SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD), "Done"); safe_strcat(tmp, sizeof(tmp), " /W");
EnableWindow(GetDlgItem(hDlg, IDC_DOWNLOAD), FALSE); filepath[i] = 0;
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
si.cb = sizeof(si);
if (!CreateProcessU(NULL, tmp, NULL, NULL, FALSE, 0, NULL, filepath, &si, &pi)) {
PrintStatus(0, FALSE, "Failed to launch new application");
uprintf("Failed to launch new application: %s\n", WindowsErrorString());
} else {
PrintStatus(0, FALSE, "Launching new application...");
PostMessage(hDlg, WM_COMMAND, (WPARAM)IDCLOSE, 0);
PostMessage(hMainDialog, WM_CLOSE, 0, 0);
} }
safe_free(filepath); break;
default: // Download
for (i=(int)safe_strlen(update.download_url); (i>0)&&(update.download_url[i]!='/'); i--);
filepath = FileDialog(TRUE, app_dir, (char*)&update.download_url[i+1], "exe", "Application");
if (filepath != NULL)
DownloadFileThreaded(update.download_url, filepath, hDlg);
break;
} }
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
} }
break; break;
case UM_ISO_INIT:
FormatStatus = 0;
download_status = 1;
SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD), "Abort");
return (INT_PTR)TRUE;
case UM_ISO_EXIT:
if (wParam) {
SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD), "Launch");
download_status = 2;
} else {
SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD), "Download");
download_status = 0;
}
return (INT_PTR)TRUE;
} }
return (INT_PTR)FALSE; return (INT_PTR)FALSE;
} }