mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[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:
parent
7b0a5abab1
commit
17872dc1de
13 changed files with 369 additions and 79 deletions
|
@ -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" />
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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);
|
||||
|
|
18
src/net.c
18
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)) {
|
||||
|
|
181
src/parser.c
181
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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
50
src/rufus.c
50
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<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)
|
||||
|
|
|
@ -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);
|
||||
|
|
16
src/rufus.rc
16
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"
|
||||
|
|
125
src/settings.h
Normal file
125
src/settings.h
Normal 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);
|
||||
}
|
|
@ -27,6 +27,7 @@
|
|||
#include "msapi_utf8.h"
|
||||
#include "rufus.h"
|
||||
#include "resource.h"
|
||||
#include "settings.h"
|
||||
#include "localization.h"
|
||||
|
||||
int nWindowsVersion = WINDOWS_UNDEFINED;
|
||||
|
|
31
src/stdlg.c
31
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;
|
||||
}
|
||||
|
|
|
@ -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_________",
|
||||
|
|
Loading…
Reference in a new issue