From d2e7e003c31db0951fdf88936ddaba64aa73568f Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Sat, 2 Feb 2013 16:57:46 +0000 Subject: [PATCH] [efi] check for 7-zip path in HKLM * Closes #121 * Also update registry handling * Issues reported by Ronny Kalusniok --- src/net.c | 14 +++++------ src/registry.h | 63 ++++++++++++++++++++++++++------------------------ src/rufus.c | 4 ++-- src/rufus.rc | 10 ++++---- src/stdlg.c | 22 +++++++++--------- src/vhd.c | 29 ++++++++++------------- 6 files changed, 70 insertions(+), 72 deletions(-) diff --git a/src/net.c b/src/net.c index f581c0d6..1084a08b 100644 --- a/src/net.c +++ b/src/net.c @@ -422,7 +422,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) BOOL is_x64 = FALSE, (__stdcall *pIsWow64Process)(HANDLE, PBOOL) = NULL; update_check_in_progress = TRUE; - verbose = ReadRegistryKey32(REGKEY_VERBOSE_UPDATES); + verbose = ReadRegistryKey32(REGKEY_HKCU, REGKEY_VERBOSE_UPDATES); // Unless the update was forced, wait a while before performing the update check if (!force_update_check) { // TODO: Also check on inactivity @@ -433,14 +433,14 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) Sleep(500); } while ((!force_update_check) && ((iso_op_in_progress || format_op_in_progress || (dialog_showing>0)))); if (!force_update_check) { - if ((ReadRegistryKey32(REGKEY_UPDATE_INTERVAL) == -1)) { + if ((ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == -1)) { vuprintf("Check for updates disabled, as per registry settings.\n"); goto out; } - reg_time = ReadRegistryKey64(REGKEY_LAST_UPDATE); - update_interval = (int64_t)ReadRegistryKey32(REGKEY_UPDATE_INTERVAL); + reg_time = ReadRegistryKey64(REGKEY_HKCU, REGKEY_LAST_UPDATE); + update_interval = (int64_t)ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL); if (update_interval == 0) { - WriteRegistryKey32(REGKEY_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL); + WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL); update_interval = DEFAULT_UPDATE_INTERVAL; } GetSystemTime(&LocalTime); @@ -488,7 +488,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) goto out; status++; // 2 - releases_only = !GetRegistryKeyBool(REGKEY_INCLUDE_BETAS); + releases_only = !GetRegistryKeyBool(REGKEY_HKCU, REGKEY_INCLUDE_BETAS); for (k=0; (k<(releases_only?1:(int)ARRAYSIZE(channel))) && (!found_new_version); k++) { uprintf("Checking %s channel...\n", channel[k]); @@ -554,7 +554,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) server_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000; vvuprintf("Server time: %" PRId64 "\n", server_time); // Always store the server response time - the only clock we trust! - WriteRegistryKey64(REGKEY_LAST_UPDATE, server_time); + WriteRegistryKey64(REGKEY_HKCU, REGKEY_LAST_UPDATE, server_time); // Might as well let the user know if (!force_update_check) { if (local_time > server_time + 600) { diff --git a/src/registry.h b/src/registry.h index fc280b27..c537dc24 100644 --- a/src/registry.h +++ b/src/registry.h @@ -26,6 +26,9 @@ extern "C" { #endif +#define REGKEY_HKCU HKEY_CURRENT_USER +#define REGKEY_HKLM HKEY_LOCAL_MACHINE + /* * List of registry keys used by this application * These keys go into HKCU\Software\COMPANY_NAME\APPLICATION_NAME\ @@ -36,14 +39,14 @@ extern "C" { #define REGKEY_INCLUDE_BETAS "CheckForBetas" #define REGKEY_COMM_CHECK "CommCheck" -/* Delete a registry key from HKCU\Software and all its values +/* Delete a registry key from \Software and all its values If the key has subkeys, this call will fail. */ -static __inline BOOL DeleteRegistryKey(const char* key_name) +static __inline BOOL DeleteRegistryKey(HKEY key_root, const char* key_name) { HKEY hSoftware = NULL; LONG s; - if (RegOpenKeyExA(HKEY_CURRENT_USER, "SOFTWARE", 0, KEY_READ|KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS) { + if (RegOpenKeyExA(key_root, "SOFTWARE", 0, KEY_READ|KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS) { return FALSE; } @@ -59,7 +62,7 @@ static __inline BOOL DeleteRegistryKey(const char* key_name) /* Read a generic registry key value. If a short key_name is used, assume that it belongs to the application and create the app subkey if required */ -static __inline BOOL _GetRegistryKey(const char* key_name, DWORD reg_type, LPBYTE dest, DWORD dest_size) +static __inline BOOL _GetRegistryKey(HKEY key_root, const char* key_name, DWORD reg_type, LPBYTE dest, DWORD dest_size) { BOOL r = FALSE; size_t i = 0; @@ -78,10 +81,10 @@ static __inline BOOL _GetRegistryKey(const char* key_name, DWORD reg_type, LPBYT safe_strcat(long_key_name, sizeof(long_key_name), key_name); long_key_name[sizeof("SOFTWARE\\") + i-1] = 0; i++; - if (RegOpenKeyExA(HKEY_CURRENT_USER, long_key_name, 0, KEY_READ, &hApp) != ERROR_SUCCESS) + if (RegOpenKeyExA(key_root, long_key_name, 0, KEY_READ, &hApp) != ERROR_SUCCESS) goto out; } else { - if ( (RegOpenKeyExA(HKEY_CURRENT_USER, "SOFTWARE", 0, KEY_READ|KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS) + if ( (RegOpenKeyExA(key_root, "SOFTWARE", 0, KEY_READ|KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS) || (RegCreateKeyExA(hSoftware, COMPANY_NAME "\\" APPLICATION_NAME, 0, NULL, 0, KEY_SET_VALUE|KEY_QUERY_VALUE|KEY_CREATE_SUB_KEY, NULL, &hApp, &dwDisp) != ERROR_SUCCESS) ) goto out; @@ -99,13 +102,13 @@ out: } /* Write a generic registry key value (create the key if it doesn't exist) */ -static __inline BOOL _SetRegistryKey(const char* key_name, DWORD reg_type, LPBYTE src, DWORD src_size) +static __inline BOOL _SetRegistryKey(HKEY key_root, 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) + if ( (RegOpenKeyExA(key_root, "SOFTWARE", 0, KEY_READ|KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS) || (RegCreateKeyExA(hSoftware, COMPANY_NAME "\\" APPLICATION_NAME, 0, NULL, 0, KEY_SET_VALUE|KEY_QUERY_VALUE|KEY_CREATE_SUB_KEY, NULL, &hApp, &dwDisp) != ERROR_SUCCESS) ) { goto out; @@ -120,52 +123,52 @@ out: } /* 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)) +#define GetRegistryKey64(root, key, pval) _GetRegistryKey(root, key, REG_QWORD, (LPBYTE)pval, sizeof(LONGLONG)) +#define SetRegistryKey64(root, key, val) _SetRegistryKey(root, 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) { +static __inline BOOL CheckRegistryKey64(HKEY root, const char* key) { LONGLONG val; - return GetRegistryKey64(key, &val); // && SetRegistryKey64(key, val)); + return GetRegistryKey64(root, key, &val); // && SetRegistryKey64(key, val)); } -static __inline int64_t ReadRegistryKey64(const char* key) { +static __inline int64_t ReadRegistryKey64(HKEY root, const char* key) { LONGLONG val; - GetRegistryKey64(key, &val); + GetRegistryKey64(root, key, &val); return (int64_t)val; } -static __inline BOOL WriteRegistryKey64(const char* key, int64_t val) { +static __inline BOOL WriteRegistryKey64(HKEY root, const char* key, int64_t val) { LONGLONG tmp = (LONGLONG)val; - return SetRegistryKey64(key, tmp); + return SetRegistryKey64(root, 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) { +#define GetRegistryKey32(root, key, pval) _GetRegistryKey(root, key, REG_DWORD, (LPBYTE)pval, sizeof(DWORD)) +#define SetRegistryKey32(root, key, val) _SetRegistryKey(root, key, REG_DWORD, (LPBYTE)&val, sizeof(DWORD)) +static __inline BOOL CheckRegistryKey32(HKEY root, const char* key) { DWORD val; - return (GetRegistryKey32(key, &val) && SetRegistryKey32(key, val)); + return (GetRegistryKey32(root, key, &val) && SetRegistryKey32(root, key, val)); } -static __inline int32_t ReadRegistryKey32(const char* key) { +static __inline int32_t ReadRegistryKey32(HKEY root, const char* key) { DWORD val; - GetRegistryKey32(key, &val); + GetRegistryKey32(root, key, &val); return (int32_t)val; } -static __inline BOOL WriteRegistryKey32(const char* key, int32_t val) { +static __inline BOOL WriteRegistryKey32(HKEY root, const char* key, int32_t val) { DWORD tmp = (DWORD)val; - return SetRegistryKey32(key, tmp); + return SetRegistryKey32(root, key, tmp); } /* Helpers for boolean registry operations */ -#define GetRegistryKeyBool(key) (ReadRegistryKey32(key) != 0) -#define SetRegistryKeyBool(key, b) WriteRegistryKey32(key, (b)?1:0) +#define GetRegistryKeyBool(root, key) (ReadRegistryKey32(root, key) != 0) +#define SetRegistryKeyBool(root, key, b) WriteRegistryKey32(root, key, (b)?1:0) #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)) +#define GetRegistryKeyStr(root, key, str, len) _GetRegistryKey(root, key, REG_SZ, (LPBYTE)str, (DWORD)len) +#define SetRegistryKeyStr(root, key, str) _SetRegistryKey(root, key, REG_SZ, (LPBYTE)str, safe_strlen(str)) // Use a static buffer - don't allocate -static __inline char* ReadRegistryKeyStr(const char* key) { +static __inline char* ReadRegistryKeyStr(HKEY root, const char* key) { static char str[512]; - _GetRegistryKey(key, REG_SZ, (LPBYTE)str, (DWORD)sizeof(str)-1); + _GetRegistryKey(root, key, REG_SZ, (LPBYTE)str, (DWORD)sizeof(str)-1); return str; } #define WriteRegistryKeyStr SetRegistryKeyStr diff --git a/src/rufus.c b/src/rufus.c index c4cfa90d..e8a7b8f0 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -1808,9 +1808,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine // Alt-R => Remove all the registry keys created by Rufus if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'R')) { PrintStatus(2000, FALSE, "Application registry key %s deleted.", - DeleteRegistryKey(COMPANY_NAME "\\" APPLICATION_NAME)?"successfully":"could not be"); + DeleteRegistryKey(REGKEY_HKCU, COMPANY_NAME "\\" APPLICATION_NAME)?"successfully":"could not be"); // Also try to delete the upper key (company name) if it's empty (don't care about the result) - DeleteRegistryKey(COMPANY_NAME); + DeleteRegistryKey(REGKEY_HKCU, COMPANY_NAME); continue; } TranslateMessage(&msg); diff --git a/src/rufus.rc b/src/rufus.rc index 147feaad..9cd5291a 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.3.3.234" +CAPTION "Rufus v1.3.3.235" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,94,278,50,14 @@ -274,8 +274,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,3,3,234 - PRODUCTVERSION 1,3,3,234 + FILEVERSION 1,3,3,235 + PRODUCTVERSION 1,3,3,235 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -292,13 +292,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.3.3.234" + VALUE "FileVersion", "1.3.3.235" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "(c) 2011-2013 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "1.3.3.234" + VALUE "ProductVersion", "1.3.3.235" END END BLOCK "VarFileInfo" diff --git a/src/stdlg.c b/src/stdlg.c index bf9831d3..18d96e3d 100644 --- a/src/stdlg.c +++ b/src/stdlg.c @@ -948,7 +948,7 @@ 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, "Weekly"), 604800)); IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Monthly"), 2629800)); - freq = ReadRegistryKey32(REGKEY_UPDATE_INTERVAL); + freq = ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL); EnableWindow(GetDlgItem(hDlg, IDC_CHECK_NOW), (freq != 0)); EnableWindow(hBeta, (freq >= 0)); switch(freq) { @@ -972,7 +972,7 @@ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM l } IGNORE_RETVAL(ComboBox_AddStringU(hBeta, "Yes")); IGNORE_RETVAL(ComboBox_AddStringU(hBeta, "No")); - IGNORE_RETVAL(ComboBox_SetCurSel(hBeta, GetRegistryKeyBool(REGKEY_INCLUDE_BETAS)?0:1)); + IGNORE_RETVAL(ComboBox_SetCurSel(hBeta, GetRegistryKeyBool(REGKEY_HKCU, REGKEY_INCLUDE_BETAS)?0:1)); hPolicy = GetDlgItem(hDlg, IDC_POLICY); SendMessage(hPolicy, EM_AUTOURLDETECT, 1, 0); SendMessageA(hPolicy, EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)update_policy); @@ -993,13 +993,13 @@ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM l if (HIWORD(wParam) != CBN_SELCHANGE) break; freq = (int32_t)ComboBox_GetItemData(hFrequency, ComboBox_GetCurSel(hFrequency)); - WriteRegistryKey32(REGKEY_UPDATE_INTERVAL, (DWORD)freq); + WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, (DWORD)freq); EnableWindow(hBeta, (freq >= 0)); return (INT_PTR)TRUE; case IDC_INCLUDE_BETAS: if (HIWORD(wParam) != CBN_SELCHANGE) break; - SetRegistryKeyBool(REGKEY_INCLUDE_BETAS, ComboBox_GetCurSel(hBeta) == 0); + SetRegistryKeyBool(REGKEY_HKCU, REGKEY_INCLUDE_BETAS, ComboBox_GetCurSel(hBeta) == 0); return (INT_PTR)TRUE; } break; @@ -1019,13 +1019,13 @@ BOOL SetUpdateCheck(void) size_t fn_len, exe_len; // Test if we have access to the registry. If not, forget it. - WriteRegistryKey32(REGKEY_COMM_CHECK, commcheck); - if (ReadRegistryKey32(REGKEY_COMM_CHECK) != commcheck) + WriteRegistryKey32(REGKEY_HKCU, REGKEY_COMM_CHECK, commcheck); + if (ReadRegistryKey32(REGKEY_HKCU, 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) { + if (ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == 0) { // Add a hack for people who'd prefer the app not to prompt about update settings on first run. // If the executable is called "rufus.exe", without version, we disable the prompt @@ -1040,13 +1040,13 @@ BOOL SetUpdateCheck(void) "Do you want to allow " APPLICATION_NAME " to check for application updates?\n"); } if (!enable_updates) { - WriteRegistryKey32(REGKEY_UPDATE_INTERVAL, -1); + WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, -1); 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); + if ( (ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == 0) || + ((ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == -1) && enable_updates) ) + WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, 86400); } return TRUE; } diff --git a/src/vhd.c b/src/vhd.c index 6467c1c7..8078da18 100644 --- a/src/vhd.c +++ b/src/vhd.c @@ -25,6 +25,7 @@ #include "registry.h" static BOOL has_wimgapi = FALSE, has_7z = FALSE; +static char sevenzip_path[MAX_PATH]; #define WIM_GENERIC_READ GENERIC_READ #define WIM_OPEN_EXISTING OPEN_EXISTING @@ -66,11 +67,19 @@ static PF_DECL(WIMLoadImage); static PF_DECL(WIMExtractImagePath); static PF_DECL(WIMCloseHandle); +static BOOL Get7ZipPath(void) +{ + if ( (GetRegistryKeyStr(REGKEY_HKCU, "7-Zip\\Path", sevenzip_path, sizeof(sevenzip_path))) + || (GetRegistryKeyStr(REGKEY_HKLM, "7-Zip\\Path", sevenzip_path, sizeof(sevenzip_path))) ) { + safe_strcat(sevenzip_path, sizeof(sevenzip_path), "\\7z.exe"); + return (_access(sevenzip_path, 0) != -1); + } + return FALSE; +} + // Find out if we have any way to extraxt WIM files on this platform BOOL WimExtractCheck(void) { - char sevenzip_path[MAX_PATH]; - PF_INIT(WIMCreateFile, wimgapi); PF_INIT(WIMSetTemporaryPath, wimgapi); PF_INIT(WIMLoadImage, wimgapi); @@ -78,10 +87,7 @@ BOOL WimExtractCheck(void) PF_INIT(WIMCloseHandle, wimgapi); has_wimgapi = (pfWIMCreateFile && pfWIMSetTemporaryPath && pfWIMLoadImage && pfWIMExtractImagePath && pfWIMCloseHandle); - if (GetRegistryKeyStr("7-Zip\\Path", sevenzip_path, sizeof(sevenzip_path))) { - safe_strcat(sevenzip_path, sizeof(sevenzip_path), "\\7z.exe"); - has_7z = (_access(sevenzip_path, 0) != -1); - } + has_7z = Get7ZipPath(); uprintf("WIM extraction method(s) supported: %s%s%s\n", has_7z?"7z":(has_wimgapi?"":"NONE"), (has_wimgapi && has_7z)?", ":"", has_wimgapi?"wimgapi.dll":""); @@ -162,17 +168,6 @@ static BOOL WimExtractFile_7z(const char* image, int index, const char* src, con char tmpdst[MAX_PATH]; uprintf("Opening: %s:[%d] (7-Zip)\n", image, index); - if (!GetRegistryKeyStr("7-Zip\\Path", sevenzip_path, sizeof(sevenzip_path))) { - uprintf(" Could not read 7-Zip path from registry\n"); - return FALSE; - } - safe_strcat(sevenzip_path, sizeof(sevenzip_path), "\\7z.exe"); - - if (_access(sevenzip_path, 0) == -1) { - uprintf(" Could not locate 7z.exe at '%s'\n", sevenzip_path); - return FALSE; - } - safe_strcpy(tmpdst, sizeof(tmpdst), dst); for (i=safe_strlen(tmpdst); i>0; i--) { if (tmpdst[i] == '\\')