diff --git a/src/.msvc/rufus.vcxproj b/src/.msvc/rufus.vcxproj
index bffa495e..f4b4a400 100644
--- a/src/.msvc/rufus.vcxproj
+++ b/src/.msvc/rufus.vcxproj
@@ -203,6 +203,7 @@
+
diff --git a/src/.msvc/rufus.vcxproj.filters b/src/.msvc/rufus.vcxproj.filters
index ca115177..04be5abb 100644
--- a/src/.msvc/rufus.vcxproj.filters
+++ b/src/.msvc/rufus.vcxproj.filters
@@ -128,6 +128,9 @@
Header Files
+
+ Header Files
+
diff --git a/src/iso.c b/src/iso.c
index 562e1cd2..ec58d930 100644
--- a/src/iso.c
+++ b/src/iso.c
@@ -120,7 +120,7 @@ static void log_handler (cdio_log_level_t level, const char *message)
{
switch(level) {
case CDIO_LOG_DEBUG:
- // TODO: use a registry key to enable libcdio debug?
+ // TODO: use a setting to enable libcdio debug?
return;
default:
uprintf("libcdio: %s\n", message);
diff --git a/src/net.c b/src/net.c
index 774ddbb6..7168b9b1 100644
--- a/src/net.c
+++ b/src/net.c
@@ -32,7 +32,7 @@
#include "msapi_utf8.h"
#include "rufus.h"
-#include "registry.h"
+#include "settings.h"
#include "resource.h"
#include "localization.h"
@@ -441,7 +441,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
int64_t local_time = 0, reg_time, server_time, update_interval;
update_check_in_progress = TRUE;
- verbose = ReadRegistryKey32(REGKEY_HKCU, REGKEY_VERBOSE_UPDATES);
+ verbose = ReadSetting32(SETTING_VERBOSE_UPDATES);
// Without this the FileDialog will produce error 0x8001010E when compiled for Vista or later
IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
// Unless the update was forced, wait a while before performing the update check
@@ -453,14 +453,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_HKCU, REGKEY_UPDATE_INTERVAL) == -1)) {
- vuprintf("Check for updates disabled, as per registry settings.\n");
+ if ((ReadSetting32(SETTING_UPDATE_INTERVAL) == -1)) {
+ vuprintf("Check for updates disabled, as per settings.\n");
goto out;
}
- reg_time = ReadRegistryKey64(REGKEY_HKCU, REGKEY_LAST_UPDATE);
- update_interval = (int64_t)ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL);
+ reg_time = ReadSetting64(SETTING_LAST_UPDATE);
+ update_interval = (int64_t)ReadSetting32(SETTING_UPDATE_INTERVAL);
if (update_interval == 0) {
- WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL);
+ WriteSetting32(SETTING_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL);
update_interval = DEFAULT_UPDATE_INTERVAL;
}
GetSystemTime(&LocalTime);
@@ -496,7 +496,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
goto out;
status++; // 2
- releases_only = !GetRegistryKeyBool(REGKEY_HKCU, REGKEY_INCLUDE_BETAS);
+ releases_only = !ReadSettingBool(SETTING_INCLUDE_BETAS);
for (k=0; (k<(releases_only?1:(int)ARRAYSIZE(channel))) && (!found_new_version); k++) {
uprintf("Checking %s channel...\n", channel[k]);
@@ -562,7 +562,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_HKCU, REGKEY_LAST_UPDATE, server_time);
+ WriteSetting64(SETTING_LAST_UPDATE, server_time);
// Might as well let the user know
if (!force_update_check) {
if ((local_time > server_time + 600) || (local_time < server_time - 600)) {
diff --git a/src/parser.c b/src/parser.c
index 570e7eb1..1f1ad6d1 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -37,6 +37,7 @@
static const char space[] = " \t";
static const wchar_t wspace[] = L" \t";
+static const char* conversion_error = "Could not convert '%s' to UTF-16";
const struct {char c; int flag;} attr_parse[] = {
{ 'r', LOC_RIGHT_TO_LEFT },
@@ -215,7 +216,7 @@ FILE* open_loc_file(const char* filename)
}
wfilename = utf8_to_wchar(filename);
if (wfilename == NULL) {
- uprintf("localization: could not convert '%s' filename to UTF-16\n", filename);
+ uprintf(conversion_error, filename);
goto out;
}
fd = _wfopen(wfilename, L"rb");
@@ -638,12 +639,12 @@ char* get_token_data_file(const char* token, const char* filename)
wfilename = utf8_to_wchar(filename);
if (wfilename == NULL) {
- uprintf("Could not convert '%s' to UTF-16\n", filename);
+ uprintf(conversion_error, filename);
goto out;
}
wtoken = utf8_to_wchar(token);
if (wfilename == NULL) {
- uprintf("Could not convert '%s' to UTF-16\n", token);
+ uprintf(conversion_error, token);
goto out;
}
fd = _wfopen(wfilename, L"r, ccs=UNICODE");
@@ -667,6 +668,159 @@ out:
return ret;
}
+/*
+ * replace or add 'data' for token 'token' in config file 'filename'
+ */
+char* set_token_data_file(const char* token, const char* data, const char* filename)
+{
+ const wchar_t* outmode[] = { L"w", L"w, ccs=UTF-8", L"w, ccs=UTF-16LE" };
+ wchar_t *wtoken = NULL, *wfilename = NULL, *wtmpname = NULL, *wdata = NULL, bom = 0;
+ wchar_t buf[1024];
+ FILE *fd_in = NULL, *fd_out = NULL;
+ size_t i, size;
+ int mode = 0;
+ char *ret = NULL, tmp[2];
+
+ if ((filename == NULL) || (token == NULL) || (data == NULL))
+ return NULL;
+ if ((filename[0] == 0) || (token[0] == 0) || (data[0] == 0))
+ return NULL;
+
+ wfilename = utf8_to_wchar(filename);
+ if (wfilename == NULL) {
+ uprintf(conversion_error, filename);
+ goto out;
+ }
+ wtoken = utf8_to_wchar(token);
+ if (wfilename == NULL) {
+ uprintf(conversion_error, token);
+ goto out;
+ }
+ wdata = utf8_to_wchar(data);
+ if (wdata == NULL) {
+ uprintf(conversion_error, data);
+ goto out;
+ }
+
+ fd_in = _wfopen(wfilename, L"r, ccs=UNICODE");
+ if (fd_in == NULL) {
+ uprintf("Could not open file '%s'\n", filename);
+ goto out;
+ }
+ // Check the input file's BOM and create an output file with the same
+ if (fread(&bom, sizeof(bom), 1, fd_in) == 1) {
+ switch(bom) {
+ case 0xFEFF:
+ mode = 2; // UTF-16 (LE)
+ break;
+ case 0xBBEF: // Yeah, the UTF-8 BOM is really 0xEF,0xBB,0xBF, but
+ mode = 1; // find me a non UTF-8 file that actually begins with "ï»"
+ break;
+ default:
+ mode = 0; // ANSI
+ break;
+ }
+ fseek(fd_in, 0, SEEK_SET);
+ }
+
+ wtmpname = (wchar_t*)calloc(wcslen(wfilename)+2, sizeof(wchar_t));
+ if (wtmpname == NULL) {
+ uprintf("Could not allocate space for temporary output name\n");
+ goto out;
+ }
+ wcscpy(wtmpname, wfilename);
+ wtmpname[wcslen(wtmpname)] = '~';
+
+ fd_out = _wfopen(wtmpname, outmode[mode]);
+ if (fd_out == NULL) {
+ uprintf("Could not open temporary output file '%s~'\n", filename);
+ goto out;
+ }
+
+ // Process individual lines. NUL is always appended.
+ while (fgetws(buf, ARRAYSIZE(buf), fd_in) != NULL) {
+
+ i = 0;
+
+ // Skip leading spaces
+ i += wcsspn(&buf[i], wspace);
+
+ // Ignore comments or section headers
+ if ((buf[i] == ';') || (buf[i] == '[')) {
+ fputws(buf, fd_out);
+ continue;
+ }
+
+ // Our token should begin a line
+ if (_wcsnicmp(&buf[i], wtoken, wcslen(wtoken)) != 0) {
+ fputws(buf, fd_out);
+ continue;
+ }
+
+ // Token was found, move past token
+ i += wcslen(wtoken);
+
+ // Skip spaces
+ i += wcsspn(&buf[i], wspace);
+
+ // Check for an equal sign
+ if (buf[i] != L'=') {
+ fputws(buf, fd_out);
+ continue;
+ }
+ i++;
+
+ // Skip spaces after equal sign
+ i += wcsspn(&buf[i], wspace);
+
+ // Output the token
+ buf[i] = 0;
+ fputws(buf, fd_out);
+
+ // Now output the new data
+ fwprintf(fd_out, L"%s\n", wdata);
+ ret = (char*)data;
+ }
+
+ if (ret == NULL) {
+ // Didn't find an existing token => append it
+ fwprintf(fd_out, L"%s = %s\n", wtoken, wdata);
+ ret = (char*)data;
+ }
+
+out:
+ if (fd_in != NULL) fclose(fd_in);
+ if (fd_out != NULL) fclose(fd_out);
+
+ // If an insertion occurred, delete existing file and use the new one
+ if (ret != NULL) {
+ // We're in Windows text mode => Remove CRs if requested
+ fd_in = _wfopen(wtmpname, L"rb");
+ fd_out = _wfopen(wfilename, L"wb");
+ // Don't check fds
+ if ((fd_in != NULL) && (fd_out != NULL)) {
+ size = (mode==2)?2:1;
+ while(fread(tmp, size, 1, fd_in) == 1)
+ fwrite(tmp, size, 1, fd_out);
+ fclose(fd_in);
+ fclose(fd_out);
+ } else {
+ uprintf("Could not write '%s' - original file has been left unmodified\n", filename);
+ ret = NULL;
+ if (fd_in != NULL) fclose(fd_in);
+ if (fd_out != NULL) fclose(fd_out);
+ }
+ }
+ if (wtmpname != NULL)
+ _wunlink(wtmpname);
+ safe_free(wfilename);
+ safe_free(wtmpname);
+ safe_free(wtoken);
+ safe_free(wdata);
+
+ return ret;
+}
+
/*
* Parse a buffer (ANSI or UTF-8) and return the data for the 'n'th occurrence of 'token'
* The returned string is UTF-8 and MUST be freed by the caller
@@ -806,17 +960,17 @@ char* insert_section_data(const char* filename, const char* section, const char*
wfilename = utf8_to_wchar(filename);
if (wfilename == NULL) {
- uprintf("Could not convert '%s' to UTF-16\n", filename);
+ uprintf(conversion_error, filename);
goto out;
}
wsection = utf8_to_wchar(section);
if (wfilename == NULL) {
- uprintf("Could not convert '%s' to UTF-16\n", section);
+ uprintf(conversion_error, section);
goto out;
}
wdata = utf8_to_wchar(data);
if (wdata == NULL) {
- uprintf("Could not convert '%s' to UTF-16\n", data);
+ uprintf(conversion_error, data);
goto out;
}
@@ -842,9 +996,8 @@ char* insert_section_data(const char* filename, const char* section, const char*
break;
}
fseek(fd_in, 0, SEEK_SET);
- duprintf("'%s' was detected as %s\n", filename,
- (mode==0)?"ANSI/UTF8 (no BOM)":((mode==1)?"UTF8 (with BOM)":"UTF16 (with BOM"));
-
+// duprintf("'%s' was detected as %s\n", filename,
+// (mode==0)?"ANSI/UTF8 (no BOM)":((mode==1)?"UTF8 (with BOM)":"UTF16 (with BOM"));
wtmpname = (wchar_t*)calloc(wcslen(wfilename)+2, sizeof(wchar_t));
if (wtmpname == NULL) {
@@ -941,22 +1094,22 @@ char* replace_in_token_data(const char* filename, const char* token, const char*
wfilename = utf8_to_wchar(filename);
if (wfilename == NULL) {
- uprintf("Could not convert '%s' to UTF-16\n", filename);
+ uprintf(conversion_error, filename);
goto out;
}
wtoken = utf8_to_wchar(token);
if (wfilename == NULL) {
- uprintf("Could not convert '%s' to UTF-16\n", token);
+ uprintf(conversion_error, token);
goto out;
}
wsrc = utf8_to_wchar(src);
if (wsrc == NULL) {
- uprintf("Could not convert '%s' to UTF-16\n", src);
+ uprintf(conversion_error, src);
goto out;
}
wrep = utf8_to_wchar(rep);
if (wsrc == NULL) {
- uprintf("Could not convert '%s' to UTF-16\n", rep);
+ uprintf(conversion_error, rep);
goto out;
}
@@ -1015,7 +1168,7 @@ char* replace_in_token_data(const char* filename, const char* token, const char*
}
// Token was found, move past token
- i += strlen(token);
+ i += wcslen(wtoken);
// Skip spaces
i += wcsspn(&buf[i], wspace);
diff --git a/src/registry.h b/src/registry.h
index 707b8eea..89dd7f62 100644
--- a/src/registry.h
+++ b/src/registry.h
@@ -29,17 +29,6 @@ extern "C" {
#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\
- */
-#define REGKEY_VERBOSE_UPDATES "VerboseUpdateCheck"
-#define REGKEY_LAST_UPDATE "LastUpdateCheck"
-#define REGKEY_UPDATE_INTERVAL "UpdateCheckInterval"
-#define REGKEY_INCLUDE_BETAS "CheckForBetas"
-#define REGKEY_COMM_CHECK "CommCheck"
-#define REGKEY_LOCALE "Locale"
-
/* Delete a registry key from \Software and all its values
If the key has subkeys, this call will fail. */
static __inline BOOL DeleteRegistryKey(HKEY key_root, const char* key_name)
@@ -144,7 +133,7 @@ out:
// Check that a key is accessible for R/W (will create a key if not already existing)
static __inline BOOL CheckRegistryKey64(HKEY root, const char* key) {
LONGLONG val;
- return GetRegistryKey64(root, key, &val); // && SetRegistryKey64(key, val));
+ return GetRegistryKey64(root, key, &val);
}
static __inline int64_t ReadRegistryKey64(HKEY root, const char* key) {
LONGLONG val;
@@ -174,8 +163,8 @@ static __inline BOOL WriteRegistryKey32(HKEY root, const char* key, int32_t val)
}
/* Helpers for boolean registry operations */
-#define GetRegistryKeyBool(root, key) (ReadRegistryKey32(root, key) != 0)
-#define SetRegistryKeyBool(root, key, b) WriteRegistryKey32(root, key, (b)?1:0)
+#define ReadRegistryKeyBool(root, key) (ReadRegistryKey32(root, key) != 0)
+#define WriteRegistryKeyBool(root, key, b) WriteRegistryKey32(root, key, (b)?1:0)
#define CheckRegistryKeyBool CheckRegistryKey32
/* Helpers for String registry operations */
diff --git a/src/rufus.c b/src/rufus.c
index 833890b5..c82556ed 100644
--- a/src/rufus.c
+++ b/src/rufus.c
@@ -39,7 +39,7 @@
#include "resource.h"
#include "rufus.h"
#include "drive.h"
-#include "registry.h"
+#include "settings.h"
#include "localization.h"
#include "bled/bled.h"
#include "../res/grub/grub_version.h"
@@ -110,7 +110,7 @@ static UINT_PTR UM_LANGUAGE_MENU_MAX = UM_LANGUAGE_MENU;
static RECT relaunch_rc = { -65536, -65536, 0, 0};
static UINT uBootChecked = BST_CHECKED, uQFChecked = BST_CHECKED, uMBRChecked = BST_UNCHECKED;
char ClusterSizeLabel[MAX_CLUSTER_SIZES][64];
-char msgbox[1024], msgbox_title[32];
+char msgbox[1024], msgbox_title[32], *ini_file = NULL;
/*
* Globals
@@ -1533,7 +1533,7 @@ void InitDialog(HWND hDlg)
static_sprintf(tmp, "%s%d.%d.%d.%d " APPLICATION_NAME, IsAlphaOrBeta(), rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]);
}
SetWindowTextU(hDlg, tmp);
- uprintf(APPLICATION_NAME " version: %d.%d.%d.%d%s\n", rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3], IsAlphaOrBeta());
+ uprintf(APPLICATION_NAME " version: %d.%d.%d.%d%s", rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3], IsAlphaOrBeta());
for (i=0; i go to basic mode
ToggleToGo();
@@ -2367,11 +2366,12 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
const char* rufus_loc = "rufus.loc";
const char* cmdline_hogger = "rufus.com";
int i, opt, option_index = 0, argc = 0, si = 0, lcid = GetUserDefaultUILanguage();
+ FILE* fd;
BOOL attached_console = FALSE, external_loc_file = FALSE, lgp_set = FALSE, automount;
BYTE *loc_data, *hog_data;
DWORD loc_size, hog_size, Size;
- char tmp_path[MAX_PATH] = "", loc_file[MAX_PATH] = "", *tmp, *locale_name = NULL;
- char** argv = NULL;
+ char tmp_path[MAX_PATH] = "", loc_file[MAX_PATH] = "", ini_path[MAX_PATH], ini_flags[] = "rb";
+ char *tmp, *locale_name = NULL, **argv = NULL;
wchar_t **wenv, **wargv;
PF_TYPE_DECL(CDECL, int, __wgetmainargs, (int*, wchar_t***, wchar_t***, int, int*));
HANDLE mutex = NULL, hogmutex = NULL, hFile = NULL;
@@ -2426,13 +2426,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
}
}
- // Use the Locale specified in the registry, if any
- tmp = ReadRegistryKeyStr(REGKEY_HKCU, REGKEY_LOCALE);
- if (tmp[0] != 0) {
- locale_name = safe_strdup(tmp);
- uprintf("found registry locale '%s'", locale_name);
- }
-
// We have to process the arguments before we acquire the lock and process the locale
PF_INIT(__wgetmainargs, Msvcrt);
if (pf__wgetmainargs != NULL) {
@@ -2445,6 +2438,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
wait_for_mutex = 150; // Try to acquire the mutex for 15 seconds
}
+ // If our application name contains a 'p' (for "portable") create a 'rufus.ini'
+ tmp = &argv[0][strlen(argv[0]) -1];
+ while ((((uintptr_t)tmp)>((uintptr_t)argv[0])) && (*tmp != '\\'))
+ tmp--;
+ if (strchr(tmp, 'p') != NULL)
+ ini_flags[0] = 'a';
+
while ((opt = getopt_long(argc, argv, "?fhi:w:l:", long_options, &option_index)) != EOF)
switch (opt) {
case 'f':
@@ -2482,6 +2482,22 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
// Retrieve the current application directory
GetCurrentDirectoryU(MAX_PATH, app_dir);
+ // Look for a .ini file in the current app directory
+ static_sprintf(ini_path, "%s\\rufus.ini", app_dir);
+ fd = fopenU(ini_path, ini_flags); // Will create the file if portable mode is requested
+ if (fd != NULL) {
+ ini_file = ini_path;
+ fclose(fd);
+ }
+ uprintf("Will use settings from %s", (ini_file != NULL)?"INI file":"registry");
+
+ // Use the locale specified by the settings, if any
+ tmp = ReadSettingStr(SETTING_LOCALE);
+ if (tmp[0] != 0) {
+ locale_name = safe_strdup(tmp);
+ uprintf("found locale '%s'", locale_name);
+ }
+
// Init localization
init_localization();
// Seek for a loc file in the current directory
@@ -2572,7 +2588,7 @@ relaunch:
right_to_left_mode = ((selected_locale->ctrl_id) & LOC_RIGHT_TO_LEFT);
SetProcessDefaultLayout(right_to_left_mode?LAYOUT_RTL:0);
if (get_loc_data_file(loc_file, selected_locale))
- WriteRegistryKeyStr(REGKEY_HKCU, REGKEY_LOCALE, selected_locale->txt[0]);
+ WriteSettingStr(SETTING_LOCALE, selected_locale->txt[0]);
/*
* Create the main Window
@@ -2692,7 +2708,7 @@ relaunch:
PrintStatus2000(lmprintf(MSG_260), enable_ntfs_compression);
continue;
}
- // Alt-R => Remove all the registry keys created by Rufus
+ // Alt-R => Remove all the registry keys that may have been created by Rufus
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'R')) {
PrintStatus(2000, DeleteRegistryKey(REGKEY_HKCU, COMPANY_NAME "\\" APPLICATION_NAME)?MSG_248:MSG_249);
// Also try to delete the upper key (company name) if it's empty (don't care about the result)
diff --git a/src/rufus.h b/src/rufus.h
index 1841ab60..860e14f6 100644
--- a/src/rufus.h
+++ b/src/rufus.h
@@ -409,6 +409,7 @@ extern BOOL CheckForUpdates(BOOL force);
extern void DownloadNewVersion(void);
extern BOOL IsShown(HWND hDlg);
extern char* get_token_data_file(const char* token, const char* filename);
+extern char* set_token_data_file(const char* token, const char* data, const char* filename);
extern char* get_token_data_buffer(const char* token, unsigned int n, const char* buffer, size_t buffer_size);
extern char* insert_section_data(const char* filename, const char* section, const char* data, BOOL dos2unix);
extern char* replace_in_token_data(const char* filename, const char* token, const char* src, const char* rep, BOOL dos2unix);
diff --git a/src/rufus.rc b/src/rufus.rc
index 765fb8a0..e5eee4e8 100644
--- a/src/rufus.rc
+++ b/src/rufus.rc
@@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Rufus 2.0.0.585"
+CAPTION "Rufus 2.0.0.586"
FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@@ -157,7 +157,7 @@ END
IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Rufus 2.0.0.585"
+CAPTION "Rufus 2.0.0.586"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@@ -283,7 +283,7 @@ END
IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
-CAPTION "Rufus 2.0.0.585"
+CAPTION "Rufus 2.0.0.586"
FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@@ -415,7 +415,7 @@ END
IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
-CAPTION "Rufus 2.0.0.585"
+CAPTION "Rufus 2.0.0.586"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@@ -671,8 +671,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,0,0,585
- PRODUCTVERSION 2,0,0,585
+ FILEVERSION 2,0,0,586
+ PRODUCTVERSION 2,0,0,586
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -689,13 +689,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
- VALUE "FileVersion", "2.0.0.585"
+ VALUE "FileVersion", "2.0.0.586"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
- VALUE "ProductVersion", "2.0.0.585"
+ VALUE "ProductVersion", "2.0.0.586"
END
END
BLOCK "VarFileInfo"
diff --git a/src/settings.h b/src/settings.h
new file mode 100644
index 00000000..e6c46dba
--- /dev/null
+++ b/src/settings.h
@@ -0,0 +1,125 @@
+/*
+ * Rufus: The Reliable USB Formatting Utility
+ * Settings access, through either registry or INI file
+ * Copyright © 2015 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
+#include "rufus.h"
+#include "registry.h"
+
+#pragma once
+extern char* ini_file;
+
+/*
+ * List of setting names used by this application
+ */
+#define SETTING_VERBOSE_UPDATES "VerboseUpdateCheck"
+#define SETTING_LAST_UPDATE "LastUpdateCheck"
+#define SETTING_UPDATE_INTERVAL "UpdateCheckInterval"
+#define SETTING_INCLUDE_BETAS "CheckForBetas"
+#define SETTING_COMM_CHECK "CommCheck"
+#define SETTING_LOCALE "Locale"
+#define SETTING_DISABLE_LGP "DisableLGP"
+
+static __inline BOOL CheckIniKey(const char* key) {
+ char* str = get_token_data_file(key, ini_file);
+ BOOL ret = (str != NULL);
+ safe_free(str);
+ return ret;
+}
+#define CheckIniKey64 CheckIniKey
+#define CheckIniKey32 CheckIniKey
+#define CheckIniKeyBool CheckIniKey
+#define CheckIniKeyStr CheckIniKey
+
+static __inline int64_t ReadIniKey64(const char* key) {
+ int64_t val = 0;
+ char* str = get_token_data_file(key, ini_file);
+ if (str != NULL) {
+ val = strtoll(str, NULL, 0);
+ free(str);
+ }
+ return val;
+}
+static __inline BOOL WriteIniKey64(const char* key, int64_t val) {
+ char str[24];
+ static_sprintf(str, "%lld", val);
+ return (set_token_data_file(key, str, ini_file) != NULL);
+}
+
+static __inline int32_t ReadIniKey32(const char* key) {
+ int32_t val = 0;
+ char* str = get_token_data_file(key, ini_file);
+ if (str != NULL) {
+ val = strtol(str, NULL, 0);
+ free(str);
+ }
+ return val;
+}
+static __inline BOOL WriteIniKey32(const char* key, int32_t val) {
+ char str[12];
+ static_sprintf(str, "%d", val);
+ return (set_token_data_file(key, str, ini_file) != NULL);
+}
+
+static __inline char* ReadIniKeyStr(const char* key) {
+ static char str[512];
+ char* val;
+ str[0] = 0;
+ val = get_token_data_file(key, ini_file);
+ if (val != NULL) {
+ safe_strcpy(str, sizeof(str), val);
+ free(val);
+ }
+ return str;
+}
+
+static __inline BOOL WriteIniKeyStr(const char* key, const char* val) {
+ return (set_token_data_file(key, val, ini_file) != NULL);
+}
+
+/* Helpers for boolean operations */
+#define ReadIniKeyBool(key) (ReadIniKey32(key) != 0)
+#define WriteIniKeyBool(key, b) WriteIniKey32(key, (b)?1:0)
+
+/*
+ * Read and store settings from/to ini file or registry
+ */
+static __inline int64_t ReadSetting64(const char* key) {
+ return (ini_file != NULL)?ReadIniKey64(key):ReadRegistryKey64(REGKEY_HKCU, key);
+}
+static __inline BOOL WriteSetting64(const char* key, int64_t val) {
+ return (ini_file != NULL)?WriteIniKey64(key, val):WriteRegistryKey64(REGKEY_HKCU, key, val);
+}
+static __inline int32_t ReadSetting32(const char* key) {
+ return (ini_file != NULL)?ReadIniKey32(key):ReadRegistryKey32(REGKEY_HKCU, key);
+}
+static __inline BOOL WriteSetting32(const char* key, int32_t val) {
+ return (ini_file != NULL)?WriteIniKey32(key, val):WriteRegistryKey32(REGKEY_HKCU, key, val);
+}
+static __inline BOOL ReadSettingBool(const char* key) {
+ return (ini_file != NULL)?ReadIniKeyBool(key):ReadRegistryKeyBool(REGKEY_HKCU, key);
+}
+static __inline BOOL WriteSettingBool(const char* key, BOOL val) {
+ return (ini_file != NULL)?WriteIniKeyBool(key, val):WriteRegistryKeyBool(REGKEY_HKCU, key, val);
+}
+static __inline char* ReadSettingStr(const char* key) {
+ return (ini_file != NULL)?ReadIniKeyStr(key):ReadRegistryKeyStr(REGKEY_HKCU, key);
+}
+static __inline BOOL WriteSettingStr(const char* key, char* val) {
+ return (ini_file != NULL)?WriteIniKeyStr(key, val):WriteRegistryKeyStr(REGKEY_HKCU, key, val);
+}
diff --git a/src/stdfn.c b/src/stdfn.c
index 2458e7fb..2a25c10b 100644
--- a/src/stdfn.c
+++ b/src/stdfn.c
@@ -27,6 +27,7 @@
#include "msapi_utf8.h"
#include "rufus.h"
#include "resource.h"
+#include "settings.h"
#include "localization.h"
int nWindowsVersion = WINDOWS_UNDEFINED;
diff --git a/src/stdlg.c b/src/stdlg.c
index 01cbeb16..48f6a40f 100644
--- a/src/stdlg.c
+++ b/src/stdlg.c
@@ -37,6 +37,7 @@
#include "rufus.h"
#include "msapi_utf8.h"
#include "registry.h"
+#include "settings.h"
#include "resource.h"
#include "license.h"
#include "localization.h"
@@ -58,7 +59,7 @@ static WNDPROC pOrgBrowseWndproc;
static const SETTEXTEX friggin_microsoft_unicode_amateurs = {ST_DEFAULT, CP_UTF8};
static BOOL notification_is_question;
static const notification_info* notification_more_info;
-static BOOL reg_commcheck = FALSE;
+static BOOL settings_commcheck = FALSE;
static WNDPROC original_wndproc = NULL;
/*
@@ -518,7 +519,7 @@ INT_PTR CALLBACK AboutCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
apply_localization(IDD_ABOUTBOX, hDlg);
SetTitleBarIcon(hDlg);
CenterDialog(hDlg);
- if (reg_commcheck)
+ if (settings_commcheck)
ShowWindow(GetDlgItem(hDlg, IDC_ABOUT_UPDATES), SW_SHOW);
safe_sprintf(about_blurb, sizeof(about_blurb), about_blurb_format, lmprintf(MSG_174),
lmprintf(MSG_175, rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]),
@@ -1021,7 +1022,7 @@ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM l
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, lmprintf(MSG_030, lmprintf(MSG_014))), 86400));
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, lmprintf(MSG_015)), 604800));
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, lmprintf(MSG_016)), 2629800));
- freq = ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL);
+ freq = ReadSetting32(SETTING_UPDATE_INTERVAL);
EnableWindow(GetDlgItem(hDlg, IDC_CHECK_NOW), (freq != 0));
EnableWindow(hBeta, (freq >= 0));
switch(freq) {
@@ -1045,7 +1046,7 @@ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM l
}
IGNORE_RETVAL(ComboBox_AddStringU(hBeta, lmprintf(MSG_008)));
IGNORE_RETVAL(ComboBox_AddStringU(hBeta, lmprintf(MSG_009)));
- IGNORE_RETVAL(ComboBox_SetCurSel(hBeta, GetRegistryKeyBool(REGKEY_HKCU, REGKEY_INCLUDE_BETAS)?0:1));
+ IGNORE_RETVAL(ComboBox_SetCurSel(hBeta, ReadSettingBool(SETTING_INCLUDE_BETAS)?0:1));
hPolicy = GetDlgItem(hDlg, IDC_POLICY);
SendMessage(hPolicy, EM_AUTOURLDETECT, 1, 0);
safe_sprintf(update_policy_text, sizeof(update_policy_text), update_policy, lmprintf(MSG_179),
@@ -1070,13 +1071,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_HKCU, REGKEY_UPDATE_INTERVAL, (DWORD)freq);
+ WriteSetting32(SETTING_UPDATE_INTERVAL, (DWORD)freq);
EnableWindow(hBeta, (freq >= 0));
return (INT_PTR)TRUE;
case IDC_INCLUDE_BETAS:
if (HIWORD(wParam) != CBN_SELCHANGE)
break;
- SetRegistryKeyBool(REGKEY_HKCU, REGKEY_INCLUDE_BETAS, ComboBox_GetCurSel(hBeta) == 0);
+ WriteSettingBool(SETTING_INCLUDE_BETAS, ComboBox_GetCurSel(hBeta) == 0);
return (INT_PTR)TRUE;
}
break;
@@ -1095,14 +1096,14 @@ BOOL SetUpdateCheck(void)
char filename[MAX_PATH] = "", exename[] = APPLICATION_NAME ".exe";
size_t fn_len, exe_len;
- // Test if we have access to the registry. If not, forget it.
- WriteRegistryKey32(REGKEY_HKCU, REGKEY_COMM_CHECK, commcheck);
- if (ReadRegistryKey32(REGKEY_HKCU, REGKEY_COMM_CHECK) != commcheck)
+ // Test if we can read and write settings. If not, forget it.
+ WriteSetting32(SETTING_COMM_CHECK, commcheck);
+ if (ReadSetting32(SETTING_COMM_CHECK) != commcheck)
return FALSE;
- reg_commcheck = TRUE;
+ settings_commcheck = TRUE;
// If the update interval is not set, this is the first time we run so prompt the user
- if (ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == 0) {
+ if (ReadSetting32(SETTING_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
@@ -1120,13 +1121,13 @@ BOOL SetUpdateCheck(void)
}
#endif
if (!enable_updates) {
- WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, -1);
+ WriteSetting32(SETTING_UPDATE_INTERVAL, -1);
return FALSE;
}
// If the user hasn't set the interval in the dialog, set to default
- if ( (ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == 0) ||
- ((ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == -1) && enable_updates) )
- WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, 86400);
+ if ( (ReadSetting32(SETTING_UPDATE_INTERVAL) == 0) ||
+ ((ReadSetting32(SETTING_UPDATE_INTERVAL) == -1) && enable_updates) )
+ WriteSetting32(SETTING_UPDATE_INTERVAL, 86400);
}
return TRUE;
}
diff --git a/src/usb.c b/src/usb.c
index 10c8874b..7561f1d3 100644
--- a/src/usb.c
+++ b/src/usb.c
@@ -107,7 +107,7 @@ out:
static __inline BOOL IsVHD(const char* buffer)
{
int i;
- // List of the Friendly Names of the VHD devices we know
+ // List of the Hardware IDs of the VHD devices we know
const char* vhd_name[] = {
"Arsenal_________Virtual_",
"KernSafeVirtual_________",