vfs: dongle folder redirection
This commit is contained in:
@ -66,11 +66,12 @@ void vfs_config_load(struct vfs_config *cfg, const wchar_t *filename)
|
||||
}
|
||||
|
||||
wcscpy_s(cfg->d, sizeof(cfg->d), cfg->path);
|
||||
wcscpy_s(cfg->e, sizeof(cfg->d), cfg->path);
|
||||
wcscpy_s(cfg->f, sizeof(cfg->d), cfg->path);
|
||||
wcscpy_s(cfg->g, sizeof(cfg->d), cfg->path);
|
||||
wcscpy_s(cfg->h, sizeof(cfg->d), cfg->path);
|
||||
wcscpy_s(cfg->j, sizeof(cfg->d), cfg->path);
|
||||
wcscpy_s(cfg->e, sizeof(cfg->e), cfg->path);
|
||||
wcscpy_s(cfg->f, sizeof(cfg->f), cfg->path);
|
||||
wcscpy_s(cfg->g, sizeof(cfg->g), cfg->path);
|
||||
wcscpy_s(cfg->h, sizeof(cfg->h), cfg->path);
|
||||
wcscpy_s(cfg->j, sizeof(cfg->j), cfg->path);
|
||||
wcscpy_s(cfg->dongle, sizeof(cfg->dongle), cfg->path);
|
||||
|
||||
StringCbCatW(cfg->d, sizeof(cfg->d), L"d\0");
|
||||
StringCbCatW(cfg->e, sizeof(cfg->e), L"e\0");
|
||||
@ -78,6 +79,7 @@ void vfs_config_load(struct vfs_config *cfg, const wchar_t *filename)
|
||||
StringCbCatW(cfg->g, sizeof(cfg->g), L"g\0");
|
||||
StringCbCatW(cfg->h, sizeof(cfg->h), L"h\0");
|
||||
StringCbCatW(cfg->j, sizeof(cfg->j), L"j\0");
|
||||
StringCbCatW(cfg->dongle, sizeof(cfg->dongle), L"k\0");
|
||||
}
|
||||
|
||||
void clock_config_load(struct clock_config *cfg, const wchar_t *filename)
|
||||
|
@ -8,11 +8,16 @@
|
||||
|
||||
#include "hooklib/path.h"
|
||||
#include "hooklib/reg.h"
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "platform/vfs.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
static DWORD my_GetLogicalDrives();
|
||||
static UINT my_GetDriveTypeA(LPCSTR lpRootPathName);
|
||||
static DWORD (*next_GetLogicalDrives)();
|
||||
static UINT (*next_GetDriveTypeA)(LPCSTR lpRootPathName);
|
||||
static void vfs_fixup_path(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);
|
||||
@ -28,6 +33,19 @@ static HRESULT vfs_path_hook_option(
|
||||
|
||||
static struct vfs_config vfs_config;
|
||||
|
||||
static const struct hook_symbol k32_syms[] = {
|
||||
{
|
||||
.name = "GetLogicalDrives",
|
||||
.patch = my_GetLogicalDrives,
|
||||
.link = (void **) &next_GetLogicalDrives,
|
||||
},
|
||||
{
|
||||
.name = "GetDriveTypeA",
|
||||
.patch = my_GetDriveTypeA,
|
||||
.link = (void **) &next_GetDriveTypeA,
|
||||
},
|
||||
};
|
||||
|
||||
HRESULT vfs_hook_init(const struct vfs_config *config)
|
||||
{
|
||||
HRESULT hr;
|
||||
@ -47,6 +65,7 @@ HRESULT vfs_hook_init(const struct vfs_config *config)
|
||||
vfs_fixup_path(vfs_config.g, _countof(vfs_config.g));
|
||||
vfs_fixup_path(vfs_config.h, _countof(vfs_config.h));
|
||||
vfs_fixup_path(vfs_config.j, _countof(vfs_config.j));
|
||||
vfs_fixup_path(vfs_config.dongle, _countof(vfs_config.dongle));
|
||||
|
||||
hr = vfs_mkdir_rec(vfs_config.path);
|
||||
|
||||
@ -111,6 +130,15 @@ HRESULT vfs_hook_init(const struct vfs_config *config)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hr = vfs_mkdir_rec(vfs_config.dongle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Vfs: Failed to create dir %S: %x\n",
|
||||
vfs_config.dongle,
|
||||
(int) hr);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* Not auto-creating option directory as it is normally a read-only mount */
|
||||
|
||||
hr = path_hook_push(vfs_path_hook);
|
||||
@ -119,9 +147,55 @@ HRESULT vfs_hook_init(const struct vfs_config *config)
|
||||
return hr;
|
||||
}
|
||||
|
||||
hook_table_apply(
|
||||
NULL,
|
||||
"kernel32.dll",
|
||||
k32_syms,
|
||||
_countof(k32_syms));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static DWORD my_GetLogicalDrives()
|
||||
{
|
||||
dprintf("vfs: GetLogicalDrives\n");
|
||||
// X KJIHGFEDC
|
||||
return 0b100000000000011111111100;
|
||||
}
|
||||
|
||||
static UINT my_GetDriveTypeA(LPCSTR lpRootPathName)
|
||||
{
|
||||
dprintf("vfs: GetDriveType %s\n", lpRootPathName);
|
||||
switch (lpRootPathName[0]) {
|
||||
case 'c':
|
||||
case 'C':
|
||||
case 'd':
|
||||
case 'D':
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
case 'F':
|
||||
case 'g':
|
||||
case 'G':
|
||||
case 'h':
|
||||
case 'H':
|
||||
case 'i': // Update partition, shows as RAW fs but I believe still returns fixed here
|
||||
case 'I':
|
||||
case 'j':
|
||||
case 'J':
|
||||
case 'x': // Unsure what mounted VHDs actually show as, but I don't think it matters
|
||||
case 'X':
|
||||
return DRIVE_FIXED;
|
||||
|
||||
case 'k': // Dongle
|
||||
case 'K':
|
||||
return DRIVE_REMOVABLE;
|
||||
|
||||
default:
|
||||
return DRIVE_NO_ROOT_DIR;
|
||||
}
|
||||
}
|
||||
|
||||
static void vfs_fixup_path(wchar_t *path, size_t max_count)
|
||||
{
|
||||
size_t count;
|
||||
@ -262,6 +336,11 @@ static HRESULT vfs_path_hook(const wchar_t *src, wchar_t *dest, size_t *count)
|
||||
redir = vfs_config.j;
|
||||
break;
|
||||
|
||||
case L'k':
|
||||
case L'K':
|
||||
redir = vfs_config.dongle;
|
||||
break;
|
||||
|
||||
default:
|
||||
return S_FALSE;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ struct vfs_config {
|
||||
wchar_t g[MAX_PATH];
|
||||
wchar_t h[MAX_PATH];
|
||||
wchar_t j[MAX_PATH];
|
||||
wchar_t dongle[MAX_PATH];
|
||||
};
|
||||
|
||||
HRESULT vfs_hook_init(const struct vfs_config *config);
|
||||
|
Reference in New Issue
Block a user