forked from Dniel97/segatools
platform/vfs.c: Redirect AppUser home dir
One less thing to require admin privileges.
This commit is contained in:
parent
3902757427
commit
29d9561a28
@ -16,9 +16,17 @@
|
||||
static void vfs_slashify(wchar_t *path, size_t max_count);
|
||||
static HRESULT vfs_mkdir_rec(const wchar_t *path);
|
||||
static HRESULT vfs_path_hook(const wchar_t *src, wchar_t *dest, size_t *count);
|
||||
static HRESULT vfs_path_hook_nthome(
|
||||
const wchar_t *src,
|
||||
wchar_t *dest,
|
||||
size_t *count);
|
||||
static HRESULT vfs_reg_read_amfs(void *bytes, uint32_t *nbytes);
|
||||
static HRESULT vfs_reg_read_appdata(void *bytes, uint32_t *nbytes);
|
||||
|
||||
static wchar_t vfs_nthome_real[MAX_PATH];
|
||||
static const wchar_t vfs_nthome[] = L"C:\\Documents and Settings\\AppUser\\";
|
||||
static const size_t vfs_nthome_len = _countof(vfs_nthome) - 1;
|
||||
|
||||
static const struct reg_hook_val vfs_reg_vals[] = {
|
||||
{
|
||||
.name = L"AMFS",
|
||||
@ -35,6 +43,9 @@ static struct vfs_config vfs_config;
|
||||
|
||||
HRESULT vfs_hook_init(const struct vfs_config *config)
|
||||
{
|
||||
wchar_t temp[MAX_PATH];
|
||||
size_t nthome_len;
|
||||
DWORD home_ok;
|
||||
HRESULT hr;
|
||||
|
||||
assert(config != NULL);
|
||||
@ -43,10 +54,24 @@ HRESULT vfs_hook_init(const struct vfs_config *config)
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
home_ok = GetEnvironmentVariableW(
|
||||
L"USERPROFILE",
|
||||
vfs_nthome_real,
|
||||
_countof(vfs_nthome_real));
|
||||
|
||||
if (!home_ok) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
dprintf("Vfs: Failed to query %%USERPROFILE%% env var: %x\n",
|
||||
(int) hr);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
memcpy(&vfs_config, config, sizeof(*config));
|
||||
|
||||
vfs_slashify(vfs_config.amfs, _countof(vfs_config.amfs));
|
||||
vfs_slashify(vfs_config.appdata, _countof(vfs_config.appdata));
|
||||
vfs_slashify(vfs_nthome_real, _countof(vfs_nthome_real));
|
||||
|
||||
hr = vfs_mkdir_rec(vfs_config.amfs);
|
||||
|
||||
@ -66,12 +91,30 @@ HRESULT vfs_hook_init(const struct vfs_config *config)
|
||||
dprintf("Vfs: NOTE: SEGA Y: drive APPDATA, not Windows %%APPDATA%%.\n");
|
||||
}
|
||||
|
||||
/* Need to create the temp subdirectory, not just nthome itself */
|
||||
|
||||
nthome_len = wcslen(vfs_nthome_real);
|
||||
wcscpy_s(temp, _countof(temp), vfs_nthome_real);
|
||||
wcscpy_s(temp + nthome_len, _countof(temp) - nthome_len, L"temp");
|
||||
|
||||
hr = vfs_mkdir_rec(temp);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Vfs: Failed to create %S: %x\n", temp, (int) hr);
|
||||
}
|
||||
|
||||
hr = path_hook_push(vfs_path_hook);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = path_hook_push(vfs_path_hook_nthome);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = reg_hook_push_key(
|
||||
HKEY_LOCAL_MACHINE,
|
||||
L"SYSTEM\\SEGA\\SystemProperty\\mount",
|
||||
@ -206,6 +249,42 @@ static HRESULT vfs_path_hook(const wchar_t *src, wchar_t *dest, size_t *count)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT vfs_path_hook_nthome(
|
||||
const wchar_t *src,
|
||||
wchar_t *dest,
|
||||
size_t *count)
|
||||
{
|
||||
size_t required;
|
||||
size_t redir_len;
|
||||
|
||||
assert(src != NULL);
|
||||
assert(count != NULL);
|
||||
|
||||
/* Case-insensitive check to see if src starts with vfs_nthome */
|
||||
|
||||
if (_wcsnicmp(src, vfs_nthome, vfs_nthome_len) != 0) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/* Cut off the matched prefix, add the replaced prefix, count NUL */
|
||||
|
||||
redir_len = wcslen(vfs_nthome_real);
|
||||
required = wcslen(src) - vfs_nthome_len + redir_len + 1;
|
||||
|
||||
if (dest != NULL) {
|
||||
if (required > *count) {
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
wcscpy_s(dest, *count, vfs_nthome_real);
|
||||
wcscpy_s(dest + redir_len, *count - redir_len, src + vfs_nthome_len);
|
||||
}
|
||||
|
||||
*count = required;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT vfs_reg_read_amfs(void *bytes, uint32_t *nbytes)
|
||||
{
|
||||
return reg_hook_read_wstr(bytes, nbytes, vfs_config.amfs);
|
||||
|
Loading…
Reference in New Issue
Block a user