From 8799fc8c22f4d161353af6fa823a1b6e8b86cd3c Mon Sep 17 00:00:00 2001 From: Hay1tsme Date: Sun, 30 Mar 2025 04:29:48 -0400 Subject: [PATCH] vfs: dongle folder redirection --- platform/config.c | 12 ++++--- platform/vfs.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++ platform/vfs.h | 1 + 3 files changed, 87 insertions(+), 5 deletions(-) diff --git a/platform/config.c b/platform/config.c index cc26ca1..956fb0e 100644 --- a/platform/config.c +++ b/platform/config.c @@ -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) diff --git a/platform/vfs.c b/platform/vfs.c index 32b1171..d74172c 100644 --- a/platform/vfs.c +++ b/platform/vfs.c @@ -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; } diff --git a/platform/vfs.h b/platform/vfs.h index a0d12b0..56146d6 100644 --- a/platform/vfs.h +++ b/platform/vfs.h @@ -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);