[net] Check for application update (part 8)

* Closes #102
* Add beta channel check
* Add version and min platform checks
* Also fixes update settings not reflecting the registry
This commit is contained in:
Pete Batard 2012-12-07 00:54:40 +00:00
parent b315805fa4
commit 2d53ea10ac
7 changed files with 195 additions and 130 deletions

View File

@ -388,16 +388,24 @@ HANDLE DownloadFileThreaded(const char* url, const char* file, HWND hProgressDia
return CreateThread(NULL, 0, _DownloadFileThread, NULL, 0, NULL); return CreateThread(NULL, 0, _DownloadFileThread, NULL, 0, NULL);
} }
static __inline uint64_t to_uint64_t(uint16_t x[4]) {
int i;
uint64_t ret = 0;
for (i=0; i<4; i++)
ret = (ret<<16) + x[i];
return ret;
}
/* /*
* Background thread to check for updates * Background thread to check for updates
*/ */
static DWORD WINAPI CheckForUpdatesThread(LPVOID param) static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
{ {
BOOL force = (BOOL)param; BOOL releases_only, force = (BOOL)param, found_new_version = FALSE;
const char* server_url = RUFUS_URL "/"; const char* server_url = RUFUS_URL "/";
int i, j, verbose = 2, verpos[4]; int i, j, k, verbose = 0, verpos[4];
static char* archname[] = {"win_x86", "win_x64"}; static const char* archname[] = {"win_x86", "win_x64"};
static const char* channel[] = {"release", "beta"}; // release channel
DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus; DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus;
char* buf = NULL; char* buf = NULL;
char agent[64], hostname[64], urlpath[128], mime[32]; char agent[64], hostname[64], urlpath[128], mime[32];
@ -415,11 +423,10 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
// Wait a while before checking for updates // Wait a while before checking for updates
// TODO: Also check on inactivity // TODO: Also check on inactivity
do { do {
Sleep(10000); Sleep(15000);
} while (iso_op_in_progress || format_op_in_progress); } while (iso_op_in_progress || format_op_in_progress || (dialog_showing>0));
// 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;
@ -471,14 +478,17 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
if (hConnection == NULL) if (hConnection == NULL)
goto out; goto out;
releases_only = !GetRegistryKeyBool(REGKEY_INCLUDE_BETAS);
for (k=0; (k<(releases_only?1:(int)ARRAYSIZE(channel))) && (!found_new_version); k++) {
uprintf("Checking %s channel...\n", channel[k]);
// At this stage we can query the server for various update version files. // At this stage we can query the server for various update version files.
// We first try to lookup for "<appname>_<os_arch>_<os_version_major>_<os_version_minor>.ver" // We first try to lookup for "<appname>_<os_arch>_<os_version_major>_<os_version_minor>.ver"
// and then remove each each of the <os_> components until we find our match. For instance, we may first // and then remove each each of the <os_> components until we find our match. For instance, we may first
// look for rufus_win_x64_6.2.ver (Win8 x64) but only get a match for rufus_win_x64_6.ver (Vista x64 or later) // look for rufus_win_x64_6.2.ver (Win8 x64) but only get a match for rufus_win_x64_6.ver (Vista x64 or later)
// This allows sunsetting OS versions (eg XP) or providing different downloads for different archs/groups. // This allows sunsetting OS versions (eg XP) or providing different downloads for different archs/groups.
safe_sprintf(urlpath, sizeof(urlpath), "%s%s%s_%s_%d.%d.ver", APPLICATION_NAME, (k==0)?"":"_",
safe_sprintf(urlpath, sizeof(urlpath), "%s_%s_%d.%d.ver", APPLICATION_NAME, (k==0)?"":channel[k], archname[is_x64?1:0], os_version.dwMajorVersion, os_version.dwMinorVersion);
archname[is_x64?1:0], os_version.dwMajorVersion, os_version.dwMinorVersion);
vuprintf("Base update check: %s\n", urlpath); vuprintf("Base update check: %s\n", urlpath);
for (i=0, j=(int)safe_strlen(urlpath)-5; (j>0)&&(i<ARRAYSIZE(verpos)); j--) { for (i=0, j=(int)safe_strlen(urlpath)-5; (j>0)&&(i<ARRAYSIZE(verpos)); j--) {
if ((urlpath[j] == '.') || (urlpath[j] == '_')) { if ((urlpath[j] == '.') || (urlpath[j] == '_')) {
@ -486,7 +496,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
} }
} }
if (i != ARRAYSIZE(verpos)) { if (i != ARRAYSIZE(verpos)) {
uprintf("Fix CheckForUpdatesThread()!\n"); uprintf("Broken code in CheckForUpdatesThread()!\n");
goto out; goto out;
} }
@ -511,8 +521,10 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
safe_strcpy(&urlpath[verpos[i]], 5, ".ver"); safe_strcpy(&urlpath[verpos[i]], 5, ".ver");
} }
if (dwStatus != 200) { if (dwStatus != 200) {
vuprintf("Could not find a version file on server %s", server_url); vuprintf("Could not find a %s version file on server %s", channel[k], server_url);
if ((releases_only) || (k+1 >= ARRAYSIZE(channel)))
goto out; goto out;
continue;
} }
vuprintf("Found match for %s on server %s.", urlpath, server_url); vuprintf("Found match for %s on server %s.", urlpath, server_url);
@ -520,6 +532,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_TYPE, (LPVOID)&mime, &dwSize, NULL); HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_TYPE, (LPVOID)&mime, &dwSize, NULL);
if (strcmp(mime, "text/plain") != 0) if (strcmp(mime, "text/plain") != 0)
goto out; goto out;
// We also get a date from Apache, which we'll use to avoid out of sync check, // 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. // 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. // On the other hand, if local clock is set way back in the past, we will never check.
@ -546,10 +559,11 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
if (!HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwTotalSize, &dwSize, NULL)) if (!HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwTotalSize, &dwSize, NULL))
goto out; goto out;
safe_free(buf);
// Make sure the file is NUL terminated // Make sure the file is NUL terminated
buf = (char*)calloc(dwTotalSize+1, 1); buf = (char*)calloc(dwTotalSize+1, 1);
if (buf == NULL) goto out; if (buf == NULL) goto out;
// This is a version file, so we should be able to do it in one go // This is a version file - we should be able to gulp it down in one go
if (!InternetReadFile(hRequest, buf, dwTotalSize, &dwDownloaded) || (dwDownloaded != dwTotalSize)) if (!InternetReadFile(hRequest, buf, dwTotalSize, &dwDownloaded) || (dwDownloaded != dwTotalSize))
goto out; goto out;
@ -557,11 +571,31 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
parse_update(buf, dwTotalSize+1); parse_update(buf, dwTotalSize+1);
vuprintf("UPDATE DATA:\n");
vuprintf(" version: %d.%d.%d.%d (%s)\n", update.version[0], update.version[1],
update.version[2], update.version[3], channel[k]);
vuprintf(" platform_min: %d.%d\n", update.platform_min[0], update.platform_min[1]);
vuprintf(" url: %s\n", update.download_url);
found_new_version = (to_uint64_t(update.version) > to_uint64_t(rufus_version))
&& ( (os_version.dwMajorVersion > update.platform_min[0])
|| ( (os_version.dwMajorVersion == update.platform_min[0]) && (os_version.dwMinorVersion >= update.platform_min[1])) );
uprintf("N%sew %s version found%c\n", found_new_version?"":"o n", channel[k], found_new_version?'!':'.');
}
out: out:
safe_free(buf); safe_free(buf);
if (hRequest) InternetCloseHandle(hRequest); if (hRequest) InternetCloseHandle(hRequest);
if (hConnection) InternetCloseHandle(hConnection); if (hConnection) InternetCloseHandle(hConnection);
if (hSession) InternetCloseHandle(hSession); if (hSession) InternetCloseHandle(hSession);
// Start the new download after cleanup
if (found_new_version) {
// User may have started an operation while we were checking
while (iso_op_in_progress || format_op_in_progress || (dialog_showing>0)) {
Sleep(3000);
}
DownloadNewVersion();
}
update_check_in_progress = FALSE; update_check_in_progress = FALSE;
ExitThread(0); ExitThread(0);
} }

View File

@ -227,32 +227,26 @@ void parse_update(char* buf, size_t len)
} }
} }
for (i=0; i<4; i++) update.version[i] = 0; for (i=0; i<4; i++)
update.version[i] = 0;
update.platform_min[0] = 5;
update.platform_min[1] = 2; // XP or later
safe_free(update.download_url);
safe_free(update.release_notes);
if ((data = get_sanitized_token_data_buffer("version", 1, buf, len)) != NULL) { if ((data = get_sanitized_token_data_buffer("version", 1, buf, len)) != NULL) {
for (i=0; (i<4) && ((token = strtok((i==0)?data:NULL, ".")) != NULL); i++) { for (i=0; (i<4) && ((token = strtok((i==0)?data:NULL, ".")) != NULL); i++) {
update.version[i] = (uint8_t)atoi(token); update.version[i] = (uint16_t)atoi(token);
}
safe_free(data);
}
if ((data = get_sanitized_token_data_buffer("platform_min", 1, buf, len)) != NULL) {
for (i=0; (i<2) && ((token = strtok((i==0)?data:NULL, ".")) != NULL); i++) {
update.platform_min[i] = (uint32_t)atoi(token);
} }
safe_free(data); safe_free(data);
} }
update.type = get_sanitized_token_data_buffer("type", 1, buf, len);
update.platform = get_sanitized_token_data_buffer("platform", 1, buf, len);
update.platform_arch = get_sanitized_token_data_buffer("platform_arch", 1, buf, len);
update.platform_min = get_sanitized_token_data_buffer("platform_min", 1, buf, len);
update.download_url = get_sanitized_token_data_buffer("download_url", 1, buf, len); update.download_url = get_sanitized_token_data_buffer("download_url", 1, buf, len);
update.release_notes = get_sanitized_token_data_buffer("release_notes", 1, buf, len); update.release_notes = get_sanitized_token_data_buffer("release_notes", 1, buf, len);
uprintf("UPDATE DATA:\n");
uprintf(" version: %d.%d.%d.%d\n", update.version[0], update.version[1], update.version[2], update.version[3]);
uprintf(" platform: %s\r\n platform_arch: %s\r\n platform_min: %s\n", update.platform, update.platform_arch, update.platform_min);
uprintf(" url: %s\n", update.download_url);
uprintf("RELEASE NOTES:\r\n%s\n", update.release_notes);
// User may have started formatting while we were checking
while (iso_op_in_progress || format_op_in_progress) {
Sleep(3000);
}
DownloadNewVersion();
// TODO: free all these strings!
} }
// Insert entry 'data' under section 'section' of a config file // Insert entry 'data' under section 'section' of a config file

View File

@ -33,7 +33,6 @@ extern "C" {
#define REGKEY_VERBOSE_UPDATES "VerboseUpdateCheck" #define REGKEY_VERBOSE_UPDATES "VerboseUpdateCheck"
#define REGKEY_LAST_UPDATE "LastUpdateCheck" #define REGKEY_LAST_UPDATE "LastUpdateCheck"
#define REGKEY_UPDATE_INTERVAL "UpdateCheckInterval" #define REGKEY_UPDATE_INTERVAL "UpdateCheckInterval"
#define REGKEY_LAST_VERSION_SEEN "LastVersionSeen"
#define REGKEY_INCLUDE_BETAS "CheckForBetas" #define REGKEY_INCLUDE_BETAS "CheckForBetas"
#define REGKEY_COMM_CHECK "CommCheck" #define REGKEY_COMM_CHECK "CommCheck"

View File

@ -105,8 +105,9 @@ HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPas
HWND hISOProgressDlg = NULL, hLogDlg = NULL, hISOProgressBar, hISOFileName, hDiskID; HWND hISOProgressDlg = NULL, hLogDlg = NULL, hISOProgressBar, hISOFileName, hDiskID;
BOOL use_own_vesamenu = FALSE, detect_fakes = TRUE, mbr_selected_by_user = FALSE; BOOL use_own_vesamenu = FALSE, detect_fakes = TRUE, mbr_selected_by_user = FALSE;
BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE; BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE;
int rufus_version[4]; int dialog_showing = 0;
RUFUS_UPDATE update; uint16_t rufus_version[4];
RUFUS_UPDATE update = { {0,0,0,0}, {0,0}, NULL, NULL};
extern char szStatusMessage[256]; extern char szStatusMessage[256];
static HANDLE format_thid = NULL; static HANDLE format_thid = NULL;
@ -1426,7 +1427,7 @@ void InitDialog(HWND hDlg)
// version using strtok() than using GetFileVersionInfo() // version using strtok() than using GetFileVersionInfo()
token = strtok(tmp, "v"); token = strtok(tmp, "v");
for (i=0; (i<4) && ((token = strtok(NULL, ".")) != NULL); i++) for (i=0; (i<4) && ((token = strtok(NULL, ".")) != NULL); i++)
rufus_version[i] = atoi(token); rufus_version[i] = (uint16_t)atoi(token);
uprintf("Rufus version %d.%d.%d.%d\n", rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]); uprintf("Rufus version %d.%d.%d.%d\n", rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]);
// Prefer FreeDOS to MS-DOS // Prefer FreeDOS to MS-DOS
@ -2048,6 +2049,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
out: out:
DestroyAllTooltips(); DestroyAllTooltips();
safe_free(iso_path); safe_free(iso_path);
safe_free(update.download_url);
safe_free(update.release_notes);
SetLGP(TRUE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0); SetLGP(TRUE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0);
CloseHandle(mutex); CloseHandle(mutex);
uprintf("*** RUFUS EXIT ***\n"); uprintf("*** RUFUS EXIT ***\n");

View File

@ -176,11 +176,8 @@ typedef struct {
} RUFUS_ISO_REPORT; } RUFUS_ISO_REPORT;
typedef struct { typedef struct {
uint8_t version[4]; uint16_t version[4];
char* type; // "release", "beta", "notice" uint32_t platform_min[2]; // minimum platform version required
char* platform; // target platform ("windows", "linux", etc.)
char* platform_arch; // "x86", "x64", "arm"
char* platform_min; // minimum platform version required
char* download_url; char* download_url;
char* release_notes; char* release_notes;
} RUFUS_UPDATE; } RUFUS_UPDATE;
@ -223,9 +220,10 @@ extern const int nb_steps[FS_MAX];
extern BOOL use_own_vesamenu, detect_fakes, iso_op_in_progress, format_op_in_progress; extern BOOL use_own_vesamenu, detect_fakes, iso_op_in_progress, format_op_in_progress;
extern RUFUS_ISO_REPORT iso_report; extern RUFUS_ISO_REPORT iso_report;
extern int64_t iso_blocking_status; extern int64_t iso_blocking_status;
extern int rufus_version[4]; extern uint16_t rufus_version[4];
extern enum WindowsVersion nWindowsVersion; extern enum WindowsVersion nWindowsVersion;
extern RUFUS_UPDATE update; extern RUFUS_UPDATE update;
extern int dialog_showing;
/* /*
* Shared prototypes * Shared prototypes

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.204" CAPTION "Rufus v1.2.1.205"
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
@ -128,14 +128,14 @@ STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Update policy and settings" CAPTION "Update policy and settings"
FONT 8, "Microsoft Sans Serif", 400, 0, 0x0 FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
BEGIN BEGIN
ICON IDI_ICON,IDC_ABOUT_ICON,11,8,21,20 ICON IDI_ICON,IDC_ABOUT_ICON,11,8,20,20
DEFPUSHBUTTON "Close",IDCANCEL,229,176,50,14,WS_GROUP DEFPUSHBUTTON "Close",IDCANCEL,224,176,50,14,WS_GROUP
CONTROL "",IDC_POLICY,"RichEdit20W",WS_VSCROLL | 0x804,46,8,235,130,WS_EX_STATICEDGE CONTROL "",IDC_POLICY,"RichEdit20W",ES_MULTILINE | ES_READONLY | WS_VSCROLL,46,8,235,130,WS_EX_STATICEDGE
COMBOBOX IDC_UPDATE_FREQUENCY,145,155,66,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_UPDATE_FREQUENCY,133,155,66,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Check for updates (at most):",IDC_STATIC,52,157,92,11 LTEXT "Check for updates:",IDC_STATIC,52,157,72,11
LTEXT "Include beta versions:",IDC_STATIC,52,173,93,11 LTEXT "Include beta versions:",IDC_STATIC,52,173,93,11
COMBOBOX IDC_INCLUDE_BETAS,145,171,36,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_INCLUDE_BETAS,133,171,36,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Settings",IDC_STATIC,46,145,173,45 GROUPBOX "Settings",IDC_STATIC,46,145,161,45
END END
IDD_NEW_VERSION DIALOGEX 0, 0, 384, 268 IDD_NEW_VERSION DIALOGEX 0, 0, 384, 268
@ -272,8 +272,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,2,1,204 FILEVERSION 1,2,1,205
PRODUCTVERSION 1,2,1,204 PRODUCTVERSION 1,2,1,205
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.204" VALUE "FileVersion", "1.2.1.205"
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.204" VALUE "ProductVersion", "1.2.1.205"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -277,6 +277,7 @@ void BrowseForFolder(void) {
WCHAR *fname; WCHAR *fname;
char* tmp_path = NULL; char* tmp_path = NULL;
dialog_showing++;
// Even if we have Vista support with the compiler, // Even if we have Vista support with the compiler,
// it does not mean we have the Vista API available // it does not mean we have the Vista API available
INIT_VISTA_SHELL32; INIT_VISTA_SHELL32;
@ -340,12 +341,15 @@ void BrowseForFolder(void) {
goto fallback; goto fallback;
} }
pfod->lpVtbl->Release(pfod); pfod->lpVtbl->Release(pfod);
dialog_showing--;
return; return;
} }
fallback: fallback:
if (pfod != NULL) { if (pfod != NULL) {
pfod->lpVtbl->Release(pfod); pfod->lpVtbl->Release(pfod);
} }
#else
dialog_showing++;
#endif #endif
INIT_XP_SHELL32; INIT_XP_SHELL32;
memset(&bi, 0, sizeof(BROWSEINFOW)); memset(&bi, 0, sizeof(BROWSEINFOW));
@ -359,6 +363,7 @@ fallback:
if (pidl != NULL) { if (pidl != NULL) {
CoTaskMemFree(pidl); CoTaskMemFree(pidl);
} }
dialog_showing--;
} }
/* /*
@ -455,6 +460,7 @@ char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_des
wchar_t *wpath = NULL, *wfilename = NULL; wchar_t *wpath = NULL, *wfilename = NULL;
IShellItem *si_path = NULL; // Automatically freed IShellItem *si_path = NULL; // Automatically freed
dialog_showing++;
INIT_VISTA_SHELL32; INIT_VISTA_SHELL32;
if (IS_VISTA_SHELL32_AVAILABLE) { if (IS_VISTA_SHELL32_AVAILABLE) {
// Setup the file extension filter table // Setup the file extension filter table
@ -519,6 +525,7 @@ char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_des
goto fallback; goto fallback;
} }
pfd->lpVtbl->Release(pfd); pfd->lpVtbl->Release(pfd);
dialog_showing--;
return filepath; return filepath;
} }
@ -526,6 +533,8 @@ fallback:
if (pfd != NULL) { if (pfd != NULL) {
pfd->lpVtbl->Release(pfd); pfd->lpVtbl->Release(pfd);
} }
#else
dialog_showing++;
#endif #endif
memset(&ofn, 0, sizeof(ofn)); memset(&ofn, 0, sizeof(ofn));
@ -564,6 +573,7 @@ fallback:
} }
} }
safe_free(ext_string); safe_free(ext_string);
dialog_showing--;
return filepath; return filepath;
} }
@ -715,7 +725,11 @@ INT_PTR CALLBACK AboutCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
INT_PTR CreateAboutBox(void) INT_PTR CreateAboutBox(void)
{ {
return DialogBoxA(hMainInstance, MAKEINTRESOURCEA(IDD_ABOUTBOX), hMainDialog, AboutCallback); INT_PTR r;
dialog_showing++;
r = DialogBoxA(hMainInstance, MAKEINTRESOURCEA(IDD_ABOUTBOX), hMainDialog, AboutCallback);
dialog_showing--;
return r;
} }
/* /*
@ -800,6 +814,8 @@ BOOL Notification(int type, const notification_info* more_info, char* title, cha
{ {
BOOL ret; BOOL ret;
va_list args; va_list args;
dialog_showing++;
szMessageText = (char*)malloc(MAX_PATH); szMessageText = (char*)malloc(MAX_PATH);
if (szMessageText == NULL) return FALSE; if (szMessageText == NULL) return FALSE;
szMessageTitle = title; szMessageTitle = title;
@ -828,6 +844,7 @@ BOOL Notification(int type, const notification_info* more_info, char* title, cha
} }
ret = (DialogBox(hMainInstance, MAKEINTRESOURCE(IDD_NOTIFICATION), hMainDialog, NotificationCallback) == IDYES); ret = (DialogBox(hMainInstance, MAKEINTRESOURCE(IDD_NOTIFICATION), hMainDialog, NotificationCallback) == IDYES);
safe_free(szMessageText); safe_free(szMessageText);
dialog_showing--;
return ret; return ret;
} }
@ -1117,6 +1134,7 @@ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM l
{ {
HWND hPolicy; HWND hPolicy;
static HWND hFrequency, hBeta; static HWND hFrequency, hBeta;
uint32_t freq;
switch (message) { switch (message) {
case WM_INITDIALOG: case WM_INITDIALOG:
@ -1127,11 +1145,30 @@ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM l
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Daily (Default)"), 86400)); IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Daily (Default)"), 86400));
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Weekly"), 604800)); IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Weekly"), 604800));
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Monthly"), 2629800)); IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Monthly"), 2629800));
freq = ReadRegistryKey32(REGKEY_UPDATE_INTERVAL);
switch(freq) {
case -1:
IGNORE_RETVAL(ComboBox_SetCurSel(hFrequency, 0));
break;
case 0:
case 86400:
IGNORE_RETVAL(ComboBox_SetCurSel(hFrequency, 1)); IGNORE_RETVAL(ComboBox_SetCurSel(hFrequency, 1));
break;
case 604800:
IGNORE_RETVAL(ComboBox_SetCurSel(hFrequency, 2));
break;
case 2629800:
IGNORE_RETVAL(ComboBox_SetCurSel(hFrequency, 3));
break;
default:
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Custom"), freq));
IGNORE_RETVAL(ComboBox_SetCurSel(hFrequency, 4));
break;
}
hBeta = GetDlgItem(hDlg, IDC_INCLUDE_BETAS); hBeta = GetDlgItem(hDlg, IDC_INCLUDE_BETAS);
IGNORE_RETVAL(ComboBox_AddStringU(hBeta, "Yes")); IGNORE_RETVAL(ComboBox_AddStringU(hBeta, "Yes"));
IGNORE_RETVAL(ComboBox_AddStringU(hBeta, "No")); IGNORE_RETVAL(ComboBox_AddStringU(hBeta, "No"));
IGNORE_RETVAL(ComboBox_SetCurSel(hBeta, 1)); IGNORE_RETVAL(ComboBox_SetCurSel(hBeta, GetRegistryKeyBool(REGKEY_INCLUDE_BETAS)?0:1));
hPolicy = GetDlgItem(hDlg, IDC_POLICY); hPolicy = GetDlgItem(hDlg, IDC_POLICY);
SendMessage(hPolicy, EM_AUTOURLDETECT, 1, 0); SendMessage(hPolicy, EM_AUTOURLDETECT, 1, 0);
SendMessageA(hPolicy, EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)update_policy); SendMessageA(hPolicy, EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)update_policy);