1
0
mirror of https://github.com/djhackersdev/bemanitools.git synced 2025-01-31 04:03:43 +01:00

iidxhook-util: Add option to configure path for storing settings

Additional flexibility to cover use-cases like storing this
data on a separate partition which keeps the game data folder
clean and read-only.
This commit is contained in:
icex2 2023-03-08 17:47:06 +01:00 committed by icex2
parent 5eb40bfad3
commit 722927caa7
2 changed files with 96 additions and 23 deletions

View File

@ -13,6 +13,7 @@
#include "util/defs.h"
#include "util/fs.h"
#include "util/log.h"
#include "util/mem.h"
#include "util/str.h"
/* ------------------------------------------------------------------------- */
@ -32,6 +33,24 @@ static const struct hook_symbol settings_hook_syms[] = {
};
static bool settings_folders_checked;
static char settings_path[MAX_PATH] = ".\\";
/* ------------------------------------------------------------------------- */
static void settings_build_new_path(const char* orig_path, char* new_path, size_t new_path_len)
{
size_t settings_path_len;
settings_path_len = strlen(settings_path);
log_assert(settings_path_len + strlen(orig_path) < new_path_len);
strcpy(new_path, settings_path);
strcat(new_path, orig_path);
/* Remove : of drive letter. Multiple \ are fine and handled by windows */
new_path[settings_path_len + 1] = '\\';
}
/* ------------------------------------------------------------------------- */
@ -44,8 +63,8 @@ BOOL WINAPI my_CreateDirectoryA(
lpPathName[1] == ':') {
char new_path[MAX_PATH];
strcpy(new_path, lpPathName);
new_path[1] = '\\';
settings_build_new_path(lpPathName, new_path, sizeof(new_path));
log_misc("(CreateDir) Remapped settings path %s", new_path);
return real_CreateDirectoryA(new_path, lpSecurityAttributes);
@ -61,43 +80,88 @@ void settings_hook_init(void)
hook_table_apply(
NULL, "kernel32.dll", settings_hook_syms, lengthof(settings_hook_syms));
log_info("Inserted settings hooks");
log_info("Inserted settings hooks, settings path: %s", settings_path);
}
void settings_hook_set_path(const char* path)
{
size_t len;
len = strlen(path);
log_assert(path > 0);
log_assert(len < MAX_PATH);
strcpy(settings_path, path);
/* Ensure trailing \\ to allow simple concatinations in hooks */
if (settings_path[len - 1] != '\\') {
log_assert(len + 1 < MAX_PATH);
settings_path[len] = '\\';
settings_path[len + 1] = '\0';
}
log_info("Settings path: %s", settings_path);
}
HRESULT
settings_hook_dispatch_irp(struct irp *irp)
{
if (irp->op == IRP_OP_OPEN &&
(irp->open_filename[0] == L'd' || irp->open_filename[0] == L'e' ||
irp->open_filename[0] == L'f') &&
irp->open_filename[1] == L':') {
char *log_str;
(irp->open_filename[0] == L'd' || irp->open_filename[0] == L'e' ||
irp->open_filename[0] == L'f') &&
irp->open_filename[1] == L':') {
HRESULT result;
char new_path[MAX_PATH];
const wchar_t *old_filename_wstr;
wchar_t *filename_wstr;
char *filename_cstr;
((wchar_t *) irp->open_filename)[1] = L'\\';
log_assert(wstr_narrow(irp->open_filename, &filename_cstr));
wstr_narrow(irp->open_filename, &log_str);
log_misc("Remapped settings path %s", log_str);
free(log_str);
settings_build_new_path(filename_cstr, new_path, sizeof(new_path));
/* Create local settings folders if not available */
free(filename_cstr);
log_misc("Remapped settings path to %s", new_path);
filename_wstr = str_widen(new_path);
/* Temporarily swap open_filename */
old_filename_wstr = irp->open_filename;
irp->open_filename = filename_wstr;
/* Create settings folders if not available */
if (!settings_folders_checked) {
settings_folders_checked = true;
for (char c = 'd'; c <= 'f'; c++) {
char str[3];
char new_path_folder[MAX_PATH];
size_t settings_path_len = strlen(settings_path);
str[0] = c;
str[1] = '\\';
str[2] = '\0';
log_assert(settings_path_len + 3 < MAX_PATH);
if (!path_exists(str)) {
log_misc("Creating local settings folder %s\\", str);
CreateDirectoryA(str, NULL);
strcpy(new_path_folder, settings_path);
new_path_folder[settings_path_len] = c;
new_path_folder[settings_path_len + 1] = '\\';
new_path_folder[settings_path_len + 2] = '\0';
if (!path_exists(new_path_folder)) {
log_misc("Creating local settings folder %s", new_path_folder);
CreateDirectoryA(new_path_folder, NULL);
}
}
}
return iohook_invoke_next(irp);
result = iohook_invoke_next(irp);
/* Revert to original irp */
irp->open_filename = old_filename_wstr;
free(filename_wstr);
return result;
}
return iohook_invoke_next(irp);

View File

@ -4,12 +4,21 @@
#include "hook/iohook.h"
/**
* Remaps the paths for the settings drives d:\, e:\ and f:\
* to local folders e\ and f\.
* Needed on IIDX 9th to Sirius.
* Remaps the paths for storing "settings data" that are usually stored on the
* drives d:\, e:\ and f:\ by the game. This defaults to the local folders
* d\, e\ and f\.
*
* Required hook for 9th to Lincle.
*/
void settings_hook_init(void);
/**
* Change the path where settings file are stored.
*
* @param path Destination path for storage, relative or absolute.
*/
void settings_hook_set_path(const char* path);
/**
* iohook dispatch function
*/