mirror of
https://github.com/LIV2/WinUAE.git
synced 2025-12-06 00:12:52 +00:00
471 lines
9.7 KiB
C++
471 lines
9.7 KiB
C++
|
|
#include "sysconfig.h"
|
|
#include "sysdeps.h"
|
|
|
|
#include <windows.h>
|
|
#include <shlwapi.h>
|
|
#include "win32.h"
|
|
#include "registry.h"
|
|
#include "ini.h"
|
|
|
|
static int inimode = 0;
|
|
static TCHAR *inipath;
|
|
|
|
#define ROOT_TREE _T("WinUAE")
|
|
|
|
static struct ini_data *inidata;
|
|
|
|
static HKEY gr (UAEREG *root)
|
|
{
|
|
if (!root)
|
|
return hWinUAEKey;
|
|
return root->fkey;
|
|
}
|
|
static const TCHAR *gs (UAEREG *root)
|
|
{
|
|
if (!root)
|
|
return ROOT_TREE;
|
|
return root->inipath;
|
|
}
|
|
static TCHAR *gsn (UAEREG *root, const TCHAR *name)
|
|
{
|
|
const TCHAR *r;
|
|
TCHAR *s;
|
|
if (!root)
|
|
return my_strdup (name);
|
|
r = gs (root);
|
|
s = xmalloc (TCHAR, _tcslen (r) + 1 + _tcslen (name) + 1);
|
|
_stprintf (s, _T("%s/%s"), r, name);
|
|
return s;
|
|
}
|
|
|
|
int regsetstr (UAEREG *root, const TCHAR *name, const TCHAR *str)
|
|
{
|
|
if (inimode) {
|
|
int ret = ini_addstring(inidata, gs(root), name, str);
|
|
return ret;
|
|
} else {
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
return RegSetValueEx (rk, name, 0, REG_SZ, (CONST BYTE *)str, (uaetcslen(str) + 1) * sizeof (TCHAR)) == ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
int regsetint (UAEREG *root, const TCHAR *name, int val)
|
|
{
|
|
if (inimode) {
|
|
int ret;
|
|
TCHAR tmp[100];
|
|
_stprintf (tmp, _T("%d"), val);
|
|
ret = ini_addstring(inidata, gs(root), name, tmp);
|
|
return ret;
|
|
} else {
|
|
DWORD v = val;
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
return RegSetValueEx(rk, name, 0, REG_DWORD, (CONST BYTE*)&v, sizeof (DWORD)) == ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
int regqueryint (UAEREG *root, const TCHAR *name, int *val)
|
|
{
|
|
if (inimode) {
|
|
int ret = 0;
|
|
TCHAR *tmp = NULL;
|
|
if (ini_getstring(inidata, gs(root), name, &tmp)) {
|
|
*val = _tstol (tmp);
|
|
ret = 1;
|
|
}
|
|
xfree(tmp);
|
|
return ret;
|
|
} else {
|
|
DWORD dwType = REG_DWORD;
|
|
DWORD size = sizeof (int);
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
return RegQueryValueEx (rk, name, 0, &dwType, (LPBYTE)val, &size) == ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
int regsetlonglong (UAEREG *root, const TCHAR *name, ULONGLONG val)
|
|
{
|
|
if (inimode) {
|
|
int ret;
|
|
TCHAR tmp[100];
|
|
_stprintf (tmp, _T("%I64d"), val);
|
|
ret = ini_addstring(inidata, gs(root), name, tmp);
|
|
return ret;
|
|
} else {
|
|
ULONGLONG v = val;
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
return RegSetValueEx(rk, name, 0, REG_QWORD, (CONST BYTE*)&v, sizeof (ULONGLONG)) == ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
int regquerylonglong (UAEREG *root, const TCHAR *name, ULONGLONG *val)
|
|
{
|
|
*val = 0;
|
|
if (inimode) {
|
|
int ret = 0;
|
|
TCHAR *tmp = NULL;
|
|
if (ini_getstring(inidata, gs(root), name, &tmp)) {
|
|
*val = _tstoi64 (tmp);
|
|
ret = 1;
|
|
}
|
|
xfree(tmp);
|
|
return ret;
|
|
} else {
|
|
DWORD dwType = REG_QWORD;
|
|
DWORD size = sizeof (ULONGLONG);
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
return RegQueryValueEx (rk, name, 0, &dwType, (LPBYTE)val, &size) == ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
int regquerystr (UAEREG *root, const TCHAR *name, TCHAR *str, int *size)
|
|
{
|
|
if (inimode) {
|
|
int ret = 0;
|
|
TCHAR *tmp = NULL;
|
|
if (ini_getstring(inidata, gs(root), name, &tmp)) {
|
|
if (_tcslen(tmp) >= *size)
|
|
tmp[(*size) - 1] = 0;
|
|
_tcscpy (str, tmp);
|
|
*size = uaetcslen(str);
|
|
ret = 1;
|
|
}
|
|
xfree (tmp);
|
|
return ret;
|
|
} else {
|
|
DWORD size2 = *size * sizeof (TCHAR);
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
int v = RegQueryValueEx (rk, name, 0, NULL, (LPBYTE)str, &size2) == ERROR_SUCCESS;
|
|
*size = size2 / sizeof (TCHAR);
|
|
return v;
|
|
}
|
|
}
|
|
|
|
int regenumstr (UAEREG *root, int idx, TCHAR *name, int *nsize, TCHAR *str, int *size)
|
|
{
|
|
name[0] = 0;
|
|
str[0] = 0;
|
|
if (inimode) {
|
|
TCHAR *name2 = NULL;
|
|
TCHAR *str2 = NULL;
|
|
int ret = ini_getsectionstring(inidata, gs(root), idx, &name2, &str2);
|
|
if (ret) {
|
|
if (_tcslen(name2) >= *nsize) {
|
|
name2[(*nsize) - 1] = 0;
|
|
}
|
|
if (_tcslen(str2) >= *size) {
|
|
str2[(*size) - 1] = 0;
|
|
}
|
|
_tcscpy(name, name2);
|
|
_tcscpy(str, str2);
|
|
}
|
|
xfree(str2);
|
|
xfree(name2);
|
|
return ret;
|
|
} else {
|
|
DWORD nsize2 = *nsize;
|
|
DWORD size2 = *size;
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
int v = RegEnumValue (rk, idx, name, &nsize2, NULL, NULL, (LPBYTE)str, &size2) == ERROR_SUCCESS;
|
|
*nsize = nsize2;
|
|
*size = size2;
|
|
return v;
|
|
}
|
|
}
|
|
|
|
int regquerydatasize (UAEREG *root, const TCHAR *name, int *size)
|
|
{
|
|
if (inimode) {
|
|
int ret = 0;
|
|
int csize = 65536;
|
|
TCHAR *tmp = xmalloc (TCHAR, csize);
|
|
if (regquerystr (root, name, tmp, &csize)) {
|
|
*size = uaetcslen (tmp) / 2;
|
|
ret = 1;
|
|
}
|
|
xfree (tmp);
|
|
return ret;
|
|
} else {
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
DWORD size2 = *size;
|
|
int v = RegQueryValueEx(rk, name, 0, NULL, NULL, &size2) == ERROR_SUCCESS;
|
|
*size = size2;
|
|
return v;
|
|
}
|
|
}
|
|
|
|
int regsetdata (UAEREG *root, const TCHAR *name, const void *str, int size)
|
|
{
|
|
if (inimode) {
|
|
uae_u8 *in = (uae_u8*)str;
|
|
int ret;
|
|
TCHAR *tmp = xmalloc (TCHAR, size * 2 + 1);
|
|
for (int i = 0; i < size; i++)
|
|
_stprintf (tmp + i * 2, _T("%02X"), in[i]);
|
|
ret = ini_addstring(inidata, gs(root), name, tmp);
|
|
xfree (tmp);
|
|
return ret;
|
|
} else {
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
return RegSetValueEx(rk, name, 0, REG_BINARY, (BYTE*)str, size) == ERROR_SUCCESS;
|
|
}
|
|
}
|
|
int regquerydata (UAEREG *root, const TCHAR *name, void *str, int *size)
|
|
{
|
|
if (inimode) {
|
|
int csize = (*size) * 2 + 1;
|
|
int i, j;
|
|
int ret = 0;
|
|
TCHAR *tmp = xmalloc (TCHAR, csize);
|
|
uae_u8 *out = (uae_u8*)str;
|
|
|
|
if (!regquerystr (root, name, tmp, &csize))
|
|
goto err;
|
|
j = 0;
|
|
for (i = 0; i < _tcslen (tmp); i += 2) {
|
|
TCHAR c1 = _totupper(tmp[i + 0]);
|
|
TCHAR c2 = _totupper(tmp[i + 1]);
|
|
if (c1 >= 'A')
|
|
c1 -= 'A' - 10;
|
|
else if (c1 >= '0')
|
|
c1 -= '0';
|
|
if (c1 > 15)
|
|
goto err;
|
|
if (c2 >= 'A')
|
|
c2 -= 'A' - 10;
|
|
else if (c2 >= '0')
|
|
c2 -= '0';
|
|
if (c2 > 15)
|
|
goto err;
|
|
out[j++] = c1 * 16 + c2;
|
|
}
|
|
ret = 1;
|
|
err:
|
|
xfree (tmp);
|
|
return ret;
|
|
} else {
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
DWORD size2 = *size;
|
|
int v = RegQueryValueEx(rk, name, 0, NULL, (LPBYTE)str, &size2) == ERROR_SUCCESS;
|
|
*size = size2;
|
|
return v;
|
|
}
|
|
}
|
|
|
|
int regdelete (UAEREG *root, const TCHAR *name)
|
|
{
|
|
if (inimode) {
|
|
ini_delete(inidata, gs(root), name);
|
|
return 1;
|
|
} else {
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
return RegDeleteValue (rk, name) == ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
int regexists (UAEREG *root, const TCHAR *name)
|
|
{
|
|
if (inimode) {
|
|
if (!inidata)
|
|
return 0;
|
|
int ret = ini_getstring(inidata, gs(root), name, NULL);
|
|
return ret;
|
|
} else {
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
return RegQueryValueEx(rk, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
void regdeletetree (UAEREG *root, const TCHAR *name)
|
|
{
|
|
if (inimode) {
|
|
TCHAR *s = gsn (root, name);
|
|
if (!s)
|
|
return;
|
|
ini_delete(inidata, s, NULL);
|
|
xfree (s);
|
|
} else {
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return;
|
|
SHDeleteKey (rk, name);
|
|
}
|
|
}
|
|
|
|
int regexiststree (UAEREG *root, const TCHAR *name)
|
|
{
|
|
if (inimode) {
|
|
int ret = 0;
|
|
TCHAR *s = gsn (root, name);
|
|
if (!s)
|
|
return 0;
|
|
ret = ini_getstring(inidata, s, NULL, NULL);
|
|
xfree (s);
|
|
return ret;
|
|
} else {
|
|
int ret = 0;
|
|
HKEY k = NULL;
|
|
HKEY rk = gr (root);
|
|
if (!rk)
|
|
return 0;
|
|
if (RegOpenKeyEx (rk , name, 0, KEY_READ, &k) == ERROR_SUCCESS)
|
|
ret = 1;
|
|
if (k)
|
|
RegCloseKey (k);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
UAEREG *regcreatetree (UAEREG *root, const TCHAR *name)
|
|
{
|
|
UAEREG *fkey;
|
|
HKEY rkey;
|
|
|
|
if (inimode) {
|
|
TCHAR *ininame;
|
|
if (!root) {
|
|
if (!name)
|
|
ininame = my_strdup (gs (NULL));
|
|
else
|
|
ininame = my_strdup (name);
|
|
} else {
|
|
ininame = xmalloc (TCHAR, _tcslen (root->inipath) + 1 + _tcslen (name) + 1);
|
|
_stprintf (ininame, _T("%s/%s"), root->inipath, name);
|
|
}
|
|
fkey = xcalloc (UAEREG, 1);
|
|
fkey->inipath = ininame;
|
|
} else {
|
|
DWORD err;
|
|
HKEY rk = gr (root);
|
|
if (!rk) {
|
|
rk = HKEY_CURRENT_USER;
|
|
name = _T("Software\\Arabuusimiehet\\WinUAE");
|
|
} else if (!name) {
|
|
name = _T("");
|
|
}
|
|
err = RegCreateKeyEx (rk, name, 0, NULL, REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE, NULL, &rkey, NULL);
|
|
if (err != ERROR_SUCCESS)
|
|
return 0;
|
|
fkey = xcalloc (UAEREG, 1);
|
|
fkey->fkey = rkey;
|
|
}
|
|
return fkey;
|
|
}
|
|
|
|
void regclosetree (UAEREG *key)
|
|
{
|
|
if (inimode) {
|
|
if (inidata->modified) {
|
|
ini_save(inidata, inipath);
|
|
}
|
|
}
|
|
if (!key)
|
|
return;
|
|
if (key->fkey)
|
|
RegCloseKey (key->fkey);
|
|
xfree (key->inipath);
|
|
xfree (key);
|
|
}
|
|
|
|
int reginitializeinit (TCHAR **pppath)
|
|
{
|
|
UAEREG *r = NULL;
|
|
TCHAR path[MAX_DPATH], fpath[MAX_DPATH];
|
|
FILE *f;
|
|
TCHAR *ppath = *pppath;
|
|
|
|
inimode = 0;
|
|
if (!ppath) {
|
|
int ok = 0;
|
|
TCHAR *posn;
|
|
path[0] = 0;
|
|
GetFullPathName (executable_path, sizeof path / sizeof (TCHAR), path, NULL);
|
|
if (_tcslen (path) > 4 && !_tcsicmp (path + _tcslen (path) - 4, _T(".exe"))) {
|
|
_tcscpy (path + _tcslen (path) - 3, _T("ini"));
|
|
if (GetFileAttributes (path) != INVALID_FILE_ATTRIBUTES)
|
|
ok = 1;
|
|
}
|
|
if (!ok) {
|
|
path[0] = 0;
|
|
GetFullPathName (executable_path, sizeof path / sizeof (TCHAR), path, NULL);
|
|
if((posn = _tcsrchr (path, '\\')))
|
|
posn[1] = 0;
|
|
_tcscat (path, _T("winuae.ini"));
|
|
}
|
|
if (GetFileAttributes (path) == INVALID_FILE_ATTRIBUTES)
|
|
return 0;
|
|
} else {
|
|
_tcscpy (path, ppath);
|
|
}
|
|
|
|
fpath[0] = 0;
|
|
GetFullPathName (path, sizeof fpath / sizeof (TCHAR), fpath, NULL);
|
|
if (_tcslen (fpath) < 5 || _tcsicmp (fpath + _tcslen (fpath) - 4, _T(".ini")))
|
|
return 0;
|
|
|
|
inimode = 1;
|
|
inipath = my_strdup (fpath);
|
|
inidata = ini_load(inipath, true);
|
|
if (!regexists (NULL, _T("Version")))
|
|
goto fail;
|
|
return 1;
|
|
fail:
|
|
regclosetree (r);
|
|
if (GetFileAttributes (path) != INVALID_FILE_ATTRIBUTES)
|
|
DeleteFile (path);
|
|
if (GetFileAttributes (path) != INVALID_FILE_ATTRIBUTES)
|
|
goto end;
|
|
f = _tfopen (path, _T("wb"));
|
|
if (f) {
|
|
uae_u8 bom[3] = { 0xef, 0xbb, 0xbf };
|
|
fwrite (bom, sizeof (bom), 1, f);
|
|
fclose (f);
|
|
}
|
|
if (*pppath == NULL)
|
|
*pppath = my_strdup (path);
|
|
return 1;
|
|
end:
|
|
inimode = 0;
|
|
xfree (inipath);
|
|
return 0;
|
|
}
|
|
|
|
void regstatus (void)
|
|
{
|
|
if (inimode)
|
|
write_log (_T("'%s' enabled\n"), inipath);
|
|
}
|
|
|
|
const TCHAR *getregmode (void)
|
|
{
|
|
if (!inimode)
|
|
return NULL;
|
|
return inipath;
|
|
}
|