diff --git a/src/license.h b/src/license.h index d186879a..d2baad9e 100644 --- a/src/license.h +++ b/src/license.h @@ -85,8 +85,20 @@ const char* additional_copyrights = "All other references can be found in the source.\\line\n}"; const char* update_policy = -"{\\rtf1\\ansi\n" -"Hey sexy mama, Wanna kill all humans?}"; +"{\\rtf1\\ansi{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil\\fcharset2 Symbol;}}\n" +"\\fs16\\b Update Policy\\b0\\line\\line\n" +"If you choose to allow update checks, you agree that the following information may be collected on our server(s):\\par\n" +"\\pard{\\pntext\\f1\\'B7\\tab}{\\*\\pn\\pnlvlblt\\pnf2\\pnindent0{\\pntxtb\\'B7}}\\fi-150\\li220 Your Operating System's architecture and version\\par\n" +"{\\pntext\\f1\\'B7\\tab}The version of the application\\par\n" +"{\\pntext\\f1\\'B7\\tab}Your IP address\\line\\pard\n" +"\\line\n" +"\\b None\\b0 of the data above will be disclosed to third parties.\\line\n" +"However we reserve the right to keep the information collected, for at most a year, \n" +"for the purpose of generating private usage statistics.\\line\n\\line\n" +"\\b Update Process\\b0\\line\\line\n" +APPLICATION_NAME " does not install or run any background services, therefore update checks are only performed when the main application is running. \n" +"Internet access is required when checking for new versions.\n" +"}"; const char* gplv3 = " GNU GENERAL PUBLIC LICENSE\r\n" diff --git a/src/net.c b/src/net.c index 0db97278..c2f78f27 100644 --- a/src/net.c +++ b/src/net.c @@ -387,10 +387,11 @@ DWORD WINAPI CheckForUpdatesThread(LPVOID param) // Sleep(15000); // verbose = ReadRegistryKey32(REGKEY_VERBOSE_UPDATES); - if (GetRegistryKeyBool(REGKEY_DISABLE_UPDATES)) { - vuprintf("Check for updates disabled, as per registry settings.\n"); - return FALSE; - } +// TODO: reenable this +// if (GetRegistryKeyBool(REGKEY_DISABLE_UPDATES)) { +// vuprintf("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) { diff --git a/src/registry.h b/src/registry.h index 2ad6e947..d5bdafcd 100644 --- a/src/registry.h +++ b/src/registry.h @@ -31,12 +31,13 @@ extern "C" { * These keys go into HKCU\Software\COMPANY_NAME\APPLICATION_NAME\ */ #define REGKEY_VERBOSE_UPDATES "VerboseUpdateCheck" -#define REGKEY_DISABLE_UPDATES "DisableUpdateCheck" #define REGKEY_LAST_UPDATE "LastUpdateCheck" #define REGKEY_UPDATE_INTERVAL "UpdateCheckInterval" #define REGKEY_LAST_VERSION_SEEN "LastVersionSeen" +#define REGKEY_INCLUDE_BETAS "CheckForBetas" +#define REGKEY_COMM_CHECK "CommCheck" -/* Delete a registry key from HKCU\Software and all its subkeys +/* Delete a registry key from HKCU\Software and all its values If the key has subkeys, this call will fail. */ static __inline BOOL DeleteRegistryKey(const char* key_name) { @@ -117,9 +118,9 @@ static __inline int64_t ReadRegistryKey64(const char* key) { GetRegistryKey64(key, &val); return (int64_t)val; } -static __inline void WriteRegistryKey64(const char* key, int64_t val) { +static __inline BOOL WriteRegistryKey64(const char* key, int64_t val) { LONGLONG tmp = (LONGLONG)val; - SetRegistryKey64(key, tmp); + return SetRegistryKey64(key, tmp); } /* Helpers for 32 bit registry operations */ @@ -134,14 +135,14 @@ static __inline int32_t ReadRegistryKey32(const char* key) { GetRegistryKey32(key, &val); return (int32_t)val; } -static __inline void WriteRegistryKey32(const char* key, int32_t val) { +static __inline BOOL WriteRegistryKey32(const char* key, int32_t val) { DWORD tmp = (DWORD)val; - SetRegistryKey32(key, tmp); + return SetRegistryKey32(key, tmp); } /* Helpers for boolean registry operations */ #define GetRegistryKeyBool(key) (ReadRegistryKey32(key) != 0) -#define SetRegistryKeyBool(key) WriteRegistryKey32(key, 1) +#define SetRegistryKeyBool(key, b) WriteRegistryKey32(key, (b)?1:0) #define CheckRegistryKeyBool CheckRegistryKey32 /* Helpers for String registry operations */ diff --git a/src/resource.h b/src/resource.h index 5b2156d2..f02b2c7c 100644 --- a/src/resource.h +++ b/src/resource.h @@ -69,6 +69,7 @@ #define IDC_EXTRA_PARTITION 1023 #define IDC_ABOUT_LICENSE 1030 #define IDC_ABOUT_ICON 1031 +#define IDC_ABOUT_UPDATES 1032 #define IDC_ABOUT_COPYRIGHTS 1033 #define IDC_LICENSE_TEXT 1036 #define IDC_NOTIFICATION_ICON 1040 @@ -81,7 +82,7 @@ #define IDC_LOG_SAVE 1051 #define IDC_LOG_CLEAR 1052 #define IDC_MORE_INFO 1060 -#define IDC_UPDATES_POLICY 1061 +#define IDC_POLICY 1061 #define IDC_UPDATE_FREQUENCY 1062 #define IDC_INCLUDE_BETAS 1063 #define IDC_ABOUT_BLURB 1064 diff --git a/src/rufus.c b/src/rufus.c index 481c4e0d..82d6b6be 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -1496,7 +1496,7 @@ void InitDialog(HWND hDlg) CreateTooltip(hClusterSize, "Minimum size that each data block occupies", -1); CreateTooltip(hLabel, "Use this field to set the drive label\nInternational characters are accepted", -1); CreateTooltip(GetDlgItem(hDlg, IDC_ADVANCED), "Toggle advanced options", -1); - CreateTooltip(GetDlgItem(hDlg, IDC_BADBLOCKS), "Test the device for bad blocks using a set byte pattern", -1); + CreateTooltip(GetDlgItem(hDlg, IDC_BADBLOCKS), "Test the device for bad blocks using a byte pattern", -1); CreateTooltip(GetDlgItem(hDlg, IDC_QUICKFORMAT), "Unchek this box to use the \"slow\" format method", -1); CreateTooltip(hDOS, "Check this box to make the USB drive bootable", -1); CreateTooltip(hDOSType, "Boot method", -1); @@ -1528,6 +1528,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA wchar_t wtmp[128], wstr[MAX_PATH]; static UINT uDOSChecked = BST_CHECKED, uQFChecked; static BOOL first_log_display = TRUE, user_changed_label = FALSE; + notification_info more_info = { IDD_UPDATE_POLICY, UpdateCallback }; switch (message) { @@ -1541,6 +1542,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA break; case WM_INITDIALOG: + SetUpdateCheck(); // Create the log window (hidden) hLogDlg = CreateDialogA(hMainInstance, MAKEINTRESOURCEA(IDD_LOG), hDlg, (DLGPROC)LogProc); InitDialog(hDlg); @@ -1627,20 +1629,6 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA break; #ifdef RUFUS_TEST case IDC_TEST: - testme = Notification(MSG_QUESTION, IDD_UPDATE_POLICY, UpdateCallback, - "Rufus updates", "Do you want to allow " APPLICATION_NAME " to check for updates?\n"); - uprintf("User said %s\n", testme?"YES":"NO"); -// CheckForUpdates(); -/* - 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: @@ -1904,12 +1892,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_PAUSED, 0); SetTaskbarProgressState(TASKBAR_PAUSED); PrintStatus(0, FALSE, "Cancelled"); - Notification(MSG_INFO, 0, NULL, "Cancelled", "Operation cancelled by the user."); + Notification(MSG_INFO, NULL, "Cancelled", "Operation cancelled by the user."); } else { SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_ERROR, 0); SetTaskbarProgressState(TASKBAR_ERROR); PrintStatus(0, FALSE, "FAILED"); - Notification(MSG_ERROR, 0, NULL, "Error", "Error: %s.%s", StrError(FormatStatus), + Notification(MSG_ERROR, NULL, "Error", "Error: %s.%s", StrError(FormatStatus), (strchr(StrError(FormatStatus), '\n') != NULL)?"":"\nFor more information, please check the log."); } return (INT_PTR)TRUE; @@ -1944,17 +1932,17 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine // Initialize COM for folder selection CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - // Retrieve the current application directory - GetCurrentDirectoryU(MAX_PATH, app_dir); - - // Set the Windows version - DetectWindowsVersion(); - // Some dialogs have Rich Edit controls and won't display without this if (LoadLibraryA("Riched20.dll") == NULL) { uprintf("Could not load RichEdit library - some dialogs may not display: %s\n", WindowsErrorString()); } + // Retrieve the current application directory + GetCurrentDirectoryU(MAX_PATH, app_dir); + + // Set the Windows version + nWindowsVersion = DetectWindowsVersion(); + // We use local group policies rather than direct registry manipulation // 0x9e disables removable and fixed drive notifications SetLGP(FALSE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0x9e); diff --git a/src/rufus.h b/src/rufus.h index ed31b071..586e6f2f 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 APPLICATION_NAME "Rufus" #define COMPANY_NAME "Akeo Consulting" @@ -96,6 +96,10 @@ enum notification_type { MSG_QUESTION, }; typedef INT_PTR (CALLBACK *Callback_t)(HWND, UINT, WPARAM, LPARAM); +typedef struct { + WORD id; + Callback_t callback; +} notification_info; // To provide a "More info..." on notifications /* Timers used throughout the program */ enum timer_type { @@ -182,12 +186,12 @@ typedef enum TASKBAR_PROGRESS_FLAGS enum WindowsVersion { WINDOWS_UNDEFINED, WINDOWS_UNSUPPORTED, - WINDOWS_2K, WINDOWS_XP, - WINDOWS_2003_XP64, + WINDOWS_2003, WINDOWS_VISTA, WINDOWS_7, - WINDOWS_8 + WINDOWS_8, + WINDOWS_9 }; /* @@ -212,7 +216,7 @@ extern enum WindowsVersion nWindowsVersion; /* * Shared prototypes */ -extern void DetectWindowsVersion(void); +extern enum WindowsVersion DetectWindowsVersion(void); extern const char *WindowsErrorString(void); extern void DumpBufferHex(void *buf, size_t size); extern void PrintStatus(unsigned int duration, BOOL debug, const char *format, ...); @@ -227,7 +231,7 @@ extern INT_PTR CreateAboutBox(void); extern BOOL CreateTooltip(HWND hControl, const char* message, int duration); extern void DestroyTooltip(HWND hWnd); extern void DestroyAllTooltips(void); -extern BOOL Notification(int type, WORD extra_id, Callback_t extra_callback, char* title, char* format, ...); +extern BOOL Notification(int type, const notification_info* more_info, char* title, char* format, ...); extern BOOL Question(char* title, char* format, ...); extern BOOL ExtractDOS(const char* path); extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan); @@ -245,6 +249,7 @@ 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 INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +extern BOOL SetUpdateCheck(void); extern BOOL CheckForUpdates(void); extern BOOL IsShown(HWND hDlg); extern char* get_token_data_file(const char* token, const char* filename); diff --git a/src/rufus.rc b/src/rufus.rc index cc318420..80dddc1f 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.1.200" +CAPTION "Rufus v1.2.1.201" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,94,278,50,14 @@ -73,9 +73,10 @@ FONT 8, "Microsoft Sans Serif", 400, 0, 0x0 BEGIN ICON IDI_ICON,IDC_ABOUT_ICON,11,8,20,20 DEFPUSHBUTTON "OK",IDOK,231,181,50,14,WS_GROUP - PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,181,50,14,WS_GROUP - CONTROL "",IDC_ABOUT_COPYRIGHTS,"RichEdit20W",WS_VSCROLL | 0x804,46,101,235,74,WS_EX_STATICEDGE - CONTROL "",IDC_ABOUT_BLURB,"RichEdit20W",WS_TABSTOP | 0x884,46,7,235,93 + PUSHBUTTON "License",IDC_ABOUT_LICENSE,46,181,50,14,WS_GROUP + CONTROL "",IDC_ABOUT_COPYRIGHTS,"RichEdit20W",ES_MULTILINE | ES_READONLY | WS_VSCROLL,46,101,235,74,WS_EX_STATICEDGE + CONTROL "",IDC_ABOUT_BLURB,"RichEdit20W",ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | WS_TABSTOP,46,7,235,93 + PUSHBUTTON "Updates",IDC_ABOUT_UPDATES,100,181,50,14,NOT WS_VISIBLE | WS_GROUP END IDD_ISO_EXTRACT DIALOGEX 0, 0, 262, 66 @@ -117,24 +118,24 @@ BEGIN CONTROL "",IDC_STATIC,"Static",SS_WHITERECT,0,0,263,38 ICON 32516,IDC_NOTIFICATION_ICON,6,6,20,20 LTEXT "",IDC_NOTIFICATION_TEXT,35,10,219,20 - DEFPUSHBUTTON "No",IDNO,211,44,50,14 + DEFPUSHBUTTON "No",IDNO,206,44,50,14 DEFPUSHBUTTON "More info...",IDC_MORE_INFO,8,44,50,14,NOT WS_VISIBLE - DEFPUSHBUTTON "Yes",IDYES,159,44,50,14,NOT WS_VISIBLE + DEFPUSHBUTTON "Yes",IDYES,154,44,50,14,NOT WS_VISIBLE END -IDD_UPDATE_POLICY DIALOGEX 0, 0, 287, 195 +IDD_UPDATE_POLICY DIALOGEX 0, 0, 287, 198 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Update policy and settings" FONT 8, "Microsoft Sans Serif", 400, 0, 0x0 BEGIN - ICON IDI_ICON,IDC_ABOUT_ICON,11,8,20,20 - DEFPUSHBUTTON "OK",IDOK,231,166,50,14,WS_GROUP - CONTROL "",IDC_UPDATES_POLICY,"RichEdit20W",ES_MULTILINE | ES_READONLY | WS_VSCROLL,46,8,235,130,WS_EX_STATICEDGE - COMBOBOX IDC_UPDATE_FREQUENCY,121,150,66,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Check for updates:",IDC_STATIC,52,152,61,11 - LTEXT "Include beta versions:",IDC_STATIC,52,168,75,11 - COMBOBOX IDC_INCLUDE_BETAS,151,166,36,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Settings",IDC_STATIC,46,140,149,43 + ICON IDI_ICON,IDC_ABOUT_ICON,11,8,21,20 + DEFPUSHBUTTON "Close",IDCLOSE,229,176,50,14,WS_GROUP + 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 + LTEXT "Check for updates (at most):",IDC_STATIC,52,157,92,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 + GROUPBOX "Settings",IDC_STATIC,46,145,173,45 END @@ -248,8 +249,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,1,200 - PRODUCTVERSION 1,2,1,200 + FILEVERSION 1,2,1,201 + PRODUCTVERSION 1,2,1,201 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -266,13 +267,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.2.1.200" + VALUE "FileVersion", "1.2.1.201" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "(c) 2011-2012 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "1.2.1.200" + VALUE "ProductVersion", "1.2.1.201" END END BLOCK "VarFileInfo" diff --git a/src/stdlg.c b/src/stdlg.c index 253e16be..ae9a848f 100644 --- a/src/stdlg.c +++ b/src/stdlg.c @@ -37,6 +37,7 @@ #include "rufus.h" #include "msapi_utf8.h" +#include "registry.h" #include "resource.h" #include "license.h" @@ -60,41 +61,43 @@ static LPITEMIDLIST (WINAPI *pSHSimpleIDListFromPath)(PCWSTR pszPath) = NULL; static HICON hMessageIcon = (HICON)INVALID_HANDLE_VALUE; static char* szMessageText = NULL; static char* szMessageTitle = NULL; -enum WindowsVersion nWindowsVersion = WINDOWS_UNSUPPORTED; +enum WindowsVersion nWindowsVersion = WINDOWS_UNDEFINED; static HWND hBrowseEdit; static WNDPROC pOrgBrowseWndproc; static const SETTEXTEX friggin_microsoft_unicode_amateurs = {ST_DEFAULT, CP_UTF8}; static BOOL notification_is_question; -static WORD notification_info_id; -static Callback_t notification_info_callback; +static const notification_info* notification_more_info; +static BOOL reg_commcheck = FALSE; /* * Detect Windows version */ -void DetectWindowsVersion(void) +enum WindowsVersion DetectWindowsVersion(void) { OSVERSIONINFO OSVersion; memset(&OSVersion, 0, sizeof(OSVERSIONINFO)); OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - nWindowsVersion = WINDOWS_UNSUPPORTED; - if ((GetVersionEx(&OSVersion) != 0) && (OSVersion.dwPlatformId == VER_PLATFORM_WIN32_NT)) { - if ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 0)) { - nWindowsVersion = WINDOWS_2K; - } else if ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 1)) { - nWindowsVersion = WINDOWS_XP; - } else if ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 2)) { - nWindowsVersion = WINDOWS_2003_XP64; - } else if (OSVersion.dwMajorVersion == 6) { - if (OSVersion.dwBuildNumber < 7000) { - nWindowsVersion = WINDOWS_VISTA; - } else { - nWindowsVersion = WINDOWS_7; - } - } else if (OSVersion.dwMajorVersion >= 8) { - nWindowsVersion = WINDOWS_8; - } - } + if (GetVersionEx(&OSVersion) == 0) + return WINDOWS_UNDEFINED; + if (OSVersion.dwPlatformId != VER_PLATFORM_WIN32_NT) + return WINDOWS_UNSUPPORTED; + // See the Remarks section from http://msdn.microsoft.com/en-us/library/windows/desktop/ms724833.aspx + if ((OSVersion.dwMajorVersion < 5) || ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 0))) + return WINDOWS_UNSUPPORTED; // Win2k or earlier + if ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 1)) + return WINDOWS_XP; + if ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 2)) + return WINDOWS_2003; + if ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion == 0)) + return WINDOWS_VISTA; + if ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion == 1)) + return WINDOWS_7; + if ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion == 2)) + return WINDOWS_8; + if ((OSVersion.dwMajorVersion > 6) || ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion >= 3))) + return WINDOWS_9; + return WINDOWS_UNSUPPORTED; } /* @@ -660,6 +663,8 @@ INT_PTR CALLBACK AboutCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP switch (message) { case WM_INITDIALOG: CenterDialog(hDlg); + if (reg_commcheck) + ShowWindow(GetDlgItem(hDlg, IDC_ABOUT_UPDATES), SW_SHOW); safe_sprintf(about_blurb, sizeof(about_blurb), about_blurb_format, rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]); for (i=0; icallback != NULL)) { ShowWindow(GetDlgItem(hDlg, IDC_MORE_INFO), SW_SHOW); } // Set the control text @@ -773,7 +781,9 @@ INT_PTR CALLBACK NotificationCallback(HWND hDlg, UINT message, WPARAM wParam, LP EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; case IDC_MORE_INFO: - DialogBoxA(hMainInstance, MAKEINTRESOURCEA(notification_info_id), hDlg, notification_info_callback); + if (notification_more_info != NULL) + DialogBoxA(hMainInstance, MAKEINTRESOURCEA(notification_more_info->id), + hDlg, notification_more_info->callback); break; } break; @@ -784,7 +794,7 @@ INT_PTR CALLBACK NotificationCallback(HWND hDlg, UINT message, WPARAM wParam, LP /* * Display a custom notification */ -BOOL Notification(int type, WORD extra_id, Callback_t extra_callback, char* title, char* format, ...) +BOOL Notification(int type, const notification_info* more_info, char* title, char* format, ...) { BOOL ret; va_list args; @@ -795,8 +805,7 @@ BOOL Notification(int type, WORD extra_id, Callback_t extra_callback, char* titl safe_vsnprintf(szMessageText, MAX_PATH-1, format, args); va_end(args); szMessageText[MAX_PATH-1] = 0; - notification_info_callback = extra_callback; - notification_info_id = extra_id; + notification_more_info = more_info; notification_is_question = FALSE; switch(type) { @@ -1104,22 +1113,24 @@ BOOL SetTaskbarProgressValue(ULONGLONG ullCompleted, ULONGLONG ullTotal) */ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND hPolicy, hCombo; + HWND hPolicy; + static HWND hFrequency, hBeta; + DWORD frequency = -1; switch (message) { case WM_INITDIALOG: CenterDialog(hDlg); - hCombo = GetDlgItem(hDlg, IDC_UPDATE_FREQUENCY); - IGNORE_RETVAL(ComboBox_SetItemData(hCombo, ComboBox_AddStringU(hCombo, "Disabled"), -1)); - IGNORE_RETVAL(ComboBox_SetItemData(hCombo, ComboBox_AddStringU(hCombo, "Daily (Default)"), 86400)); - IGNORE_RETVAL(ComboBox_SetItemData(hCombo, ComboBox_AddStringU(hCombo, "Weekly"), 604800)); - IGNORE_RETVAL(ComboBox_SetItemData(hCombo, ComboBox_AddStringU(hCombo, "Monthly"), 2629800)); - IGNORE_RETVAL(ComboBox_SetCurSel(hCombo, 1)); - hCombo = GetDlgItem(hDlg, IDC_INCLUDE_BETAS); - IGNORE_RETVAL(ComboBox_AddStringU(hCombo, "No")); - IGNORE_RETVAL(ComboBox_AddStringU(hCombo, "Yes")); - IGNORE_RETVAL(ComboBox_SetCurSel(hCombo, 0)); - hPolicy = GetDlgItem(hDlg, IDC_UPDATES_POLICY); + hFrequency = GetDlgItem(hDlg, IDC_UPDATE_FREQUENCY); + IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Disabled"), -1)); + 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, "Monthly"), 2629800)); + IGNORE_RETVAL(ComboBox_SetCurSel(hFrequency, 1)); + hBeta = GetDlgItem(hDlg, IDC_INCLUDE_BETAS); + IGNORE_RETVAL(ComboBox_AddStringU(hBeta, "Yes")); + IGNORE_RETVAL(ComboBox_AddStringU(hBeta, "No")); + IGNORE_RETVAL(ComboBox_SetCurSel(hBeta, 1)); + hPolicy = GetDlgItem(hDlg, IDC_POLICY); SendMessage(hPolicy, EM_AUTOURLDETECT, 1, 0); SendMessageA(hPolicy, EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)update_policy); SendMessage(hPolicy, EM_SETSEL, -1, -1); @@ -1128,12 +1139,55 @@ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM l break; case WM_COMMAND: switch (LOWORD(wParam)) { - case IDOK: + case IDCLOSE: case IDCANCEL: EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; + case IDC_UPDATE_FREQUENCY: + if (HIWORD(wParam) != CBN_SELCHANGE) + break; + WriteRegistryKey32(REGKEY_UPDATE_INTERVAL, (DWORD)ComboBox_GetItemData(hFrequency, ComboBox_GetCurSel(hFrequency))); + return (INT_PTR)TRUE; + case IDC_INCLUDE_BETAS: + if (HIWORD(wParam) != CBN_SELCHANGE) + break; + SetRegistryKeyBool(REGKEY_INCLUDE_BETAS, ComboBox_GetCurSel(hBeta) == 0); + return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; } + +/* + * Initial update check setup + */ +BOOL SetUpdateCheck(void) +{ + BOOL enable_updates; + DWORD commcheck = GetTickCount(); + notification_info more_info = { IDD_UPDATE_POLICY, UpdateCallback }; + + // Test if we have access to the registry. If not, forget it. + WriteRegistryKey32(REGKEY_COMM_CHECK, commcheck); + if (ReadRegistryKey32(REGKEY_COMM_CHECK) != commcheck) + return FALSE; + reg_commcheck = TRUE; + + // If the update interval is not set, this is the first time we run so prompt the user + if (ReadRegistryKey32(REGKEY_UPDATE_INTERVAL) == 0) { + enable_updates = Notification(MSG_QUESTION, &more_info, + APPLICATION_NAME " updates", "Do you want to allow " APPLICATION_NAME " to check for updates?\n"); + if (!enable_updates) { + WriteRegistryKey32(REGKEY_UPDATE_INTERVAL, -1); // large enough + return FALSE; + } + // If the user hasn't set the interval in the dialog, set to default + if ( (ReadRegistryKey32(REGKEY_UPDATE_INTERVAL) == 0) || + ((ReadRegistryKey32(REGKEY_UPDATE_INTERVAL) == -1) && enable_updates) ) + 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; +}