forked from TeamTofuShop/segatools
APMv3: add hook (#73)
This adds support for APMv3 I/O, menus and the launcher. * Added a apm3hook dll and I/O based on the usual layout. * Added C:\Mount\Apm to vfs. * Added the relevant .dlls to unityhook. * Added a hook for apmmount.dll that uses `CreateDosDevice` to mount decrypted data to the locations the launcher and games expect files to be. This will conflict with anything that is already at W:\ and X:\, but I do not have better solutions for this. * `launch.bat` is a bit more involved as it simulates the launcher loop. It can be broken by alt+f4ing or closing the launcher with "X". * An extra export was added, so rundll32 can be used to get rid of the dosdevices after the launcher was killed. * Since all the games do everything via `X:\lib\apm.dll`, no game hooks were needed in testing, therefore, `game.bat` files can be used as is. * Path hooks are applied correctly, so you can go correctly between games, launcher, sub system test mode and game test modes. A setup guide (some stuff specific to my server) can be found here: https://gmg.hopto.org:82/gmg/wiki/index.php/All.Net_P-ras_Multi_Menu Tested with the 2 APM sample apps, Blazblue, Puyo, Guilty Gear and some weird unity puzzle game whose name I forgot.   Reviewed-on: TeamTofuShop/segatools#73 Co-authored-by: kyoubate-haruka <46010460+kyoubate-haruka@users.noreply.github.com> Co-committed-by: kyoubate-haruka <46010460+kyoubate-haruka@users.noreply.github.com>
This commit is contained in:
@ -31,6 +31,10 @@ static HRESULT vfs_path_hook_option(
|
||||
const wchar_t *src,
|
||||
wchar_t *dest,
|
||||
size_t *count);
|
||||
static HRESULT vfs_path_hook_apm(
|
||||
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);
|
||||
|
||||
@ -64,6 +68,9 @@ static const size_t vfs_w10home_len = _countof(vfs_w10home) - 1;
|
||||
static const wchar_t vfs_option[] = L"C:\\Mount\\Option";
|
||||
static const size_t vfs_option_len = _countof(vfs_option) - 1;
|
||||
|
||||
static const wchar_t vfs_apm3[] = L"C:\\Mount\\Apm";
|
||||
static const size_t vfs_apm3_len = _countof(vfs_apm3) - 1;
|
||||
|
||||
static const struct reg_hook_val vfs_reg_vals[] = {
|
||||
{
|
||||
.name = L"AMFS",
|
||||
@ -199,6 +206,11 @@ HRESULT vfs_hook_init(const struct vfs_config *config, const char* game_id)
|
||||
if (vfs_config.option[0] != L'\0') {
|
||||
hr = path_hook_push(vfs_path_hook_option);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
hr = path_hook_push(vfs_path_hook_apm);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
@ -514,6 +526,53 @@ static HRESULT vfs_path_hook_option(
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT vfs_path_hook_apm(
|
||||
const wchar_t *src,
|
||||
wchar_t *dest,
|
||||
size_t *count)
|
||||
{
|
||||
size_t required;
|
||||
size_t redir_len;
|
||||
size_t shift;
|
||||
|
||||
assert(src != NULL);
|
||||
assert(count != NULL);
|
||||
|
||||
/* Case-insensitive check to see if src starts with vfs_apm */
|
||||
|
||||
if (path_compare_w(src, vfs_apm3, vfs_apm3_len) != 0) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/* Check if the character after vfs_nthome is a separator or the end of
|
||||
the string */
|
||||
|
||||
if (!path_is_separator_w(src[vfs_apm3_len]) &&
|
||||
src[vfs_apm3_len] != L'\0')
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/* Cut off the matched <prefix>\, add the replaced prefix, count NUL */
|
||||
|
||||
shift = path_is_separator_w(src[vfs_apm3_len]) ? 1 : 0;
|
||||
redir_len = wcslen(vfs_config.option);
|
||||
required = wcslen(src) - vfs_apm3_len - shift + redir_len + 1;
|
||||
|
||||
if (dest != NULL) {
|
||||
if (required > *count) {
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
wcscpy_s(dest, *count, vfs_config.option);
|
||||
wcscpy_s(dest + redir_len, *count - redir_len, src + vfs_apm3_len + shift);
|
||||
}
|
||||
|
||||
*count = required;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT vfs_reg_read_amfs(void *bytes, uint32_t *nbytes)
|
||||
{
|
||||
return reg_hook_read_wstr(bytes, nbytes, L"E:\\");
|
||||
|
Reference in New Issue
Block a user