[core] add INI file/portable support

* Application will start in portable mode if its name contains a 'p'
  eg. "rufus_portable.exe" or "prufus.exe"
* Closes #264
* Also fix a couple smaller issues
This commit is contained in:
Pete Batard 2015-01-25 00:56:38 +00:00
parent 7b0a5abab1
commit 17872dc1de
13 changed files with 369 additions and 79 deletions

View File

@ -203,6 +203,7 @@
<ClInclude Include="..\drive.h" />
<ClInclude Include="..\format.h" />
<ClInclude Include="..\hdd_vs_ufd.h" />
<ClInclude Include="..\settings.h" />
<ClInclude Include="..\libcdio\cdio\cdio.h" />
<ClInclude Include="..\libcdio\cdio\iso9660.h" />
<ClInclude Include="..\libcdio\cdio\udf.h" />

View File

@ -128,6 +128,9 @@
<ClInclude Include="..\bled\bled.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\settings.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\res\rufus.ico">

View File

@ -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);

View File

@ -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)) {

View File

@ -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);

View File

@ -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 <key_root>\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 */

View File

@ -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<ARRAYSIZE(resource); i++) {
buf = (char*)GetResource(hMainInstance, resource[i], _RT_RCDATA, "ldlinux_sys", &len, TRUE);
if (buf == NULL) {
@ -1545,11 +1545,11 @@ void InitDialog(HWND hDlg)
free(buf);
}
}
uprintf("Windows version: %s", WindowsVersionStr);
uprintf("Syslinux versions: %s%s, %s%s", embedded_sl_version_str[0], embedded_sl_version_ext[0],
embedded_sl_version_str[1], embedded_sl_version_ext[1]);
uprintf("Grub versions: %s, %s", embedded_grub_version, embedded_grub2_version);
uprintf("Windows version: %s\n", WindowsVersionStr);
uprintf("Locale ID: 0x%04X\n", GetUserDefaultUILanguage());
uprintf("Locale ID: 0x%04X", GetUserDefaultUILanguage());
SetClusterSizeLabels();
@ -1661,7 +1661,6 @@ void InitDialog(HWND hDlg)
CreateTooltip(GetDlgItem(hDlg, IDC_ABOUT), lmprintf(MSG_172), -1);
CreateTooltip(GetDlgItem(hDlg, IDC_WINDOWS_INSTALL), lmprintf(MSG_199), -1);
CreateTooltip(GetDlgItem(hDlg, IDC_WINDOWS_TO_GO), lmprintf(MSG_200), -1);
// TODO: add new tooltips
ToggleAdvanced(); // We start in advanced mode => 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)

View File

@ -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);

View File

@ -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"

125
src/settings.h Normal file
View File

@ -0,0 +1,125 @@
/*
* Rufus: The Reliable USB Formatting Utility
* Settings access, through either registry or INI file
* Copyright © 2015 Pete Batard <pete@akeo.ie>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <windows.h>
#include <stdint.h>
#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);
}

View File

@ -27,6 +27,7 @@
#include "msapi_utf8.h"
#include "rufus.h"
#include "resource.h"
#include "settings.h"
#include "localization.h"
int nWindowsVersion = WINDOWS_UNDEFINED;

View File

@ -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;
}

View File

@ -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_________",