4 Commits

Author SHA1 Message Date
9c66488906 added Move/Replace/Delete hooks
- fixes FGO not correctly switching `START UP MODE`
- fixes SWDC not correctly switching `CABINET SETTING`
2024-02-27 16:54:12 +01:00
f570869946 fixed AMFS path redirect with no E:/ drive present 2024-02-27 16:49:27 +01:00
629ded4018 added AimePay, E-MONEY DNS redirects 2024-02-25 19:03:05 +01:00
ca36a879cb updated README and added "AM Daemon" window name 2024-02-22 19:12:18 +01:00
7 changed files with 406 additions and 13 deletions

View File

@ -1,6 +1,6 @@
# Segatools # Segatools
Version: `2024-02-22` Version: `2024-02-27`
Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platforms. Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platforms.

View File

@ -129,12 +129,12 @@ path=
[io4] [io4]
; Input API selection for JVS input emulator. ; Input API selection for JVS input emulator.
; Test button virtual-key code. Default is the 1 key. ; Test button virtual-key code. Default is the F1 key.
test=0x31 test=0x70
; Service button virtual-key code. Default is the 2 key. ; Service button virtual-key code. Default is the F2 key.
service=0x32 service=0x71
; Keyboard button to increment coin counter. Default is the 3 key. ; Keyboard button to increment coin counter. Default is the F3 key.
coin=0x33 coin=0x72
; .·:'''''''''''''''''''''''''''''''''''''''''''''':·. ; .·:'''''''''''''''''''''''''''''''''''''''''''''':·.
; : : ______ / \ [] : : ; : : ______ / \ [] : :
@ -151,8 +151,8 @@ coin=0x33
; ;
; Only XInput is currently supported. ; Only XInput is currently supported.
; Controller Button ; XInput bindings
; ------------------------------------------------------- ;
; Left Stick Joystick ; Left Stick Joystick
; Left Stick Click Reset Camera ; Left Stick Click Reset Camera
; Left Trigger Dash ; Left Trigger Dash

View File

@ -63,7 +63,7 @@ enable=1
; Enable freeplay mode. This will disable the coin slot and set the game to ; Enable freeplay mode. This will disable the coin slot and set the game to
; freeplay. Keep in mind that some game modes (e.g. Freedom/Time Modes) will not ; freeplay. Keep in mind that some game modes (e.g. Freedom/Time Modes) will not
; allow you to start a game in freeplay mode. ; allow you to start a game in freeplay mode.
freeplay=0´ freeplay=0
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------
; Custom IO settings ; Custom IO settings

View File

@ -3,6 +3,7 @@
#include <windows.h> #include <windows.h>
#include <windns.h> #include <windns.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <winhttp.h>
#include <assert.h> #include <assert.h>
#include <stdbool.h> #include <stdbool.h>
@ -65,6 +66,12 @@ static int WSAAPI hook_getaddrinfo(
const char *pServiceName, const char *pServiceName,
const ADDRINFOA *pHints, const ADDRINFOA *pHints,
ADDRINFOA **ppResult); ADDRINFOA **ppResult);
static HINTERNET WINAPI hook_WinHttpConnect(
HINTERNET hSession,
const wchar_t *pwszServerName,
INTERNET_PORT nServerPort,
DWORD dwReserved);
/* Link pointers */ /* Link pointers */
@ -95,6 +102,12 @@ static int (WSAAPI *next_getaddrinfo)(
const ADDRINFOA *pHints, const ADDRINFOA *pHints,
ADDRINFOA **ppResult); ADDRINFOA **ppResult);
static HINTERNET (WINAPI *next_WinHttpConnect)(
HINTERNET hSession,
const wchar_t *pwszServerName,
INTERNET_PORT nServerPort,
DWORD dwReserved);
static const struct hook_symbol dns_hook_syms_dnsapi[] = { static const struct hook_symbol dns_hook_syms_dnsapi[] = {
{ {
.name = "DnsQuery_A", .name = "DnsQuery_A",
@ -120,6 +133,14 @@ static const struct hook_symbol dns_hook_syms_ws2[] = {
} }
}; };
static const struct hook_symbol dns_hook_syms_winhttp[] = {
{
.name = "WinHttpConnect",
.patch = hook_WinHttpConnect,
.link = (void **) &next_WinHttpConnect,
}
};
static bool dns_hook_initted; static bool dns_hook_initted;
static CRITICAL_SECTION dns_hook_lock; static CRITICAL_SECTION dns_hook_lock;
static struct dns_hook_entry *dns_hook_entries; static struct dns_hook_entry *dns_hook_entries;
@ -145,6 +166,12 @@ static void dns_hook_init(void)
"ws2_32.dll", "ws2_32.dll",
dns_hook_syms_ws2, dns_hook_syms_ws2,
_countof(dns_hook_syms_ws2)); _countof(dns_hook_syms_ws2));
hook_table_apply(
NULL,
"winhttp.dll",
dns_hook_syms_winhttp,
_countof(dns_hook_syms_winhttp));
} }
HRESULT dns_hook_push(const wchar_t *from_src, const wchar_t *to_src) HRESULT dns_hook_push(const wchar_t *from_src, const wchar_t *to_src)
@ -460,3 +487,38 @@ end:
return result; return result;
} }
static HINTERNET WINAPI hook_WinHttpConnect(
HINTERNET hSession,
const wchar_t *pwszServerName,
INTERNET_PORT nServerPort,
DWORD dwReserved)
{
const struct dns_hook_entry *pos;
size_t i;
if (pwszServerName == NULL) {
return NULL;
}
EnterCriticalSection(&dns_hook_lock);
for (i = 0 ; i < dns_hook_nentries ; i++) {
pos = &dns_hook_entries[i];
if (_wcsicmp(pwszServerName, pos->from) == 0) {
if(pos->to == NULL) {
LeaveCriticalSection(&dns_hook_lock);
return NULL;
}
pwszServerName = pos->to;
break;
}
}
LeaveCriticalSection(&dns_hook_lock);
return next_WinHttpConnect(hSession, pwszServerName, nServerPort, dwReserved);
}

View File

@ -101,6 +101,40 @@ static BOOL WINAPI hook_PathFileExistsA(LPCSTR pszPath);
static BOOL WINAPI hook_PathFileExistsW(LPCWSTR pszPath); static BOOL WINAPI hook_PathFileExistsW(LPCWSTR pszPath);
static BOOL WINAPI hook_MoveFileA(
const char *lpExistingFileName,
const char *lpNewFileName);
static BOOL WINAPI hook_MoveFileW(
const wchar_t *lpExistingFileName,
const wchar_t *lpNewFileName);
static BOOL WINAPI hook_MoveFileExA(
const char *lpExistingFileName,
const char *lpNewFileName,
uint32_t dwFlags);
static BOOL WINAPI hook_ReplaceFileA(
const char *lpReplacedFileName,
const char *lpReplacementFileName,
const char *lpBackupFileName,
uint32_t dwReplaceFlags,
void *lpExclude,
void *lpReserved);
static BOOL WINAPI hook_ReplaceFileW(
const wchar_t *lpReplacedFileName,
const wchar_t *lpReplacementFileName,
const wchar_t *lpBackupFileName,
uint32_t dwReplaceFlags,
void *lpExclude,
void *lpReserved);
static BOOL WINAPI hook_DeleteFileA(const char *lpFileName);
static BOOL WINAPI hook_DeleteFileW(const wchar_t *lpFileName);
/* Link pointers */ /* Link pointers */
static BOOL (WINAPI *next_CreateDirectoryA)( static BOOL (WINAPI *next_CreateDirectoryA)(
@ -185,6 +219,39 @@ static BOOL (WINAPI *next_PathFileExistsA)(LPCSTR pszPath);
static BOOL (WINAPI *next_PathFileExistsW)(LPCWSTR pszPath); static BOOL (WINAPI *next_PathFileExistsW)(LPCWSTR pszPath);
static BOOL (WINAPI *next_MoveFileA)(
const char *lpExistingFileName,
const char *lpNewFileName);
static BOOL (WINAPI *next_MoveFileW)(
const wchar_t *lpExistingFileName,
const wchar_t *lpNewFileName);
static BOOL (WINAPI *next_MoveFileExA)(
const char *lpExistingFileName,
const char *lpNewFileName,
uint32_t dwFlags);
static BOOL (WINAPI *next_ReplaceFileA)(
const char *lpReplacedFileName,
const char *lpReplacementFileName,
const char *lpBackupFileName,
uint32_t dwReplaceFlags,
void *lpExclude,
void *lpReserved);
static BOOL (WINAPI *next_ReplaceFileW)(
const wchar_t *lpReplacedFileName,
const wchar_t *lpReplacementFileName,
const wchar_t *lpBackupFileName,
uint32_t dwReplaceFlags,
void *lpExclude,
void *lpReserved);
static BOOL (WINAPI *next_DeleteFileA)(const char *lpFileName);
static BOOL (WINAPI *next_DeleteFileW)(const wchar_t *lpFileName);
/* Hook table */ /* Hook table */
static const struct hook_symbol path_hook_syms[] = { static const struct hook_symbol path_hook_syms[] = {
@ -260,6 +327,34 @@ static const struct hook_symbol path_hook_syms[] = {
.name = "PathFileExistsW", .name = "PathFileExistsW",
.patch = hook_PathFileExistsW, .patch = hook_PathFileExistsW,
.link = (void **) &next_PathFileExistsW, .link = (void **) &next_PathFileExistsW,
}, {
.name = "MoveFileA",
.patch = hook_MoveFileA,
.link = (void **) &next_MoveFileA,
}, {
.name = "MoveFileW",
.patch = hook_MoveFileW,
.link = (void **) &next_MoveFileW,
}, {
.name = "MoveFileExA",
.patch = hook_MoveFileExA,
.link = (void **) &next_MoveFileExA,
}, {
.name = "ReplaceFileA",
.patch = hook_ReplaceFileA,
.link = (void **) &next_ReplaceFileA,
}, {
.name = "ReplaceFileW",
.patch = hook_ReplaceFileW,
.link = (void **) &next_ReplaceFileW,
}, {
.name = "DeleteFileA",
.patch = hook_DeleteFileA,
.link = (void **) &next_DeleteFileA,
}, {
.name = "DeleteFileW",
.patch = hook_DeleteFileW,
.link = (void **) &next_DeleteFileW,
} }
}; };
@ -906,3 +1001,213 @@ static BOOL WINAPI hook_PathFileExistsW(LPCWSTR pszPath)
return ok; return ok;
} }
static BOOL WINAPI hook_MoveFileA(
const char *lpExistingFileName,
const char *lpNewFileName)
{
char *oldTrans;
char *newTrans;
BOOL ok;
ok = path_transform_a(&oldTrans, lpExistingFileName);
if (!ok) {
return FALSE;
}
ok = path_transform_a(&newTrans, lpNewFileName);
if (!ok) {
free(oldTrans);
return FALSE;
}
ok = next_MoveFileA(
oldTrans ? oldTrans : lpExistingFileName,
newTrans ? newTrans : lpNewFileName);
free(oldTrans);
free(newTrans);
return ok;
}
static BOOL WINAPI hook_MoveFileW(
const wchar_t *lpExistingFileName,
const wchar_t *lpNewFileName)
{
wchar_t *oldTrans;
wchar_t *newTrans;
BOOL ok;
ok = path_transform_w(&oldTrans, lpExistingFileName);
if (!ok) {
return FALSE;
}
ok = path_transform_w(&newTrans, lpNewFileName);
if (!ok) {
free(oldTrans);
return FALSE;
}
ok = next_MoveFileW(
oldTrans ? oldTrans : lpExistingFileName,
newTrans ? newTrans : lpNewFileName);
free(oldTrans);
free(newTrans);
return ok;
}
static BOOL WINAPI hook_MoveFileExA(
const char *lpExistingFileName,
const char *lpNewFileName,
uint32_t dwFlags)
{
char *oldTrans;
char *newTrans;
BOOL ok;
ok = path_transform_a(&oldTrans, lpExistingFileName);
if (!ok) {
return FALSE;
}
ok = path_transform_a(&newTrans, lpNewFileName);
if (!ok) {
free(oldTrans);
return FALSE;
}
ok = next_MoveFileExA(
oldTrans ? oldTrans : lpExistingFileName,
newTrans ? newTrans : lpNewFileName,
dwFlags);
free(oldTrans);
free(newTrans);
return ok;
}
static BOOL WINAPI hook_ReplaceFileA(
const char *lpReplacedFileName,
const char *lpReplacementFileName,
const char *lpBackupFileName,
uint32_t dwReplaceFlags,
void *lpExclude,
void *lpReserved)
{
char *oldTrans;
char *newTrans;
BOOL ok;
ok = path_transform_a(&oldTrans, lpReplacedFileName);
if (!ok) {
return FALSE;
}
ok = path_transform_a(&newTrans, lpReplacementFileName);
if (!ok) {
free(oldTrans);
return FALSE;
}
ok = next_ReplaceFileA(
oldTrans ? oldTrans : lpReplacedFileName,
newTrans ? newTrans : lpReplacementFileName,
lpBackupFileName,
dwReplaceFlags,
lpExclude,
lpReserved);
free(oldTrans);
free(newTrans);
return ok;
}
static BOOL WINAPI hook_ReplaceFileW(
const wchar_t *lpReplacedFileName,
const wchar_t *lpReplacementFileName,
const wchar_t *lpBackupFileName,
uint32_t dwReplaceFlags,
void *lpExclude,
void *lpReserved)
{
wchar_t *oldTrans;
wchar_t *newTrans;
BOOL ok;
ok = path_transform_w(&oldTrans, lpReplacedFileName);
if (!ok) {
return FALSE;
}
ok = path_transform_w(&newTrans, lpReplacementFileName);
if (!ok) {
free(oldTrans);
return FALSE;
}
ok = next_ReplaceFileW(
oldTrans ? oldTrans : lpReplacedFileName,
newTrans ? newTrans : lpReplacementFileName,
lpBackupFileName,
dwReplaceFlags,
lpExclude,
lpReserved);
free(oldTrans);
free(newTrans);
return ok;
}
static BOOL WINAPI hook_DeleteFileA(const char *lpFileName)
{
char *trans;
BOOL ok;
ok = path_transform_a(&trans, lpFileName);
if (!ok) {
return FALSE;
}
ok = next_DeleteFileA(trans ? trans: lpFileName);
return ok;
}
static BOOL WINAPI hook_DeleteFileW(const wchar_t *lpFileName)
{
wchar_t *trans;
BOOL ok;
ok = path_transform_w(&trans, lpFileName);
if (!ok) {
return FALSE;
}
ok = next_DeleteFileW(trans ? trans: lpFileName);
return ok;
}

View File

@ -82,6 +82,26 @@ HRESULT dns_platform_hook_init(const struct dns_config *cfg)
return hr; return hr;
} }
// AimePay
hr = dns_hook_push(L"api-aime.am-all.net", cfg->startup);
if (FAILED(hr)) {
return hr;
}
// E-MONEY
hr = dns_hook_push(L"tasms-api-basis.thincacloud.com", cfg->startup);
if (FAILED(hr)) {
return hr;
}
hr = dns_hook_push(L"shop.tfps.thincacloud.com", cfg->startup);
if (FAILED(hr)) {
return hr;
}
// if your ISP resolves bad domains, it will kill the network. These 2 // if your ISP resolves bad domains, it will kill the network. These 2
// *cannot* resolve // *cannot* resolve

View File

@ -277,11 +277,12 @@ static HRESULT vfs_path_hook(const wchar_t *src, wchar_t *dest, size_t *count)
const wchar_t *redir; const wchar_t *redir;
size_t required; size_t required;
size_t redir_len; size_t redir_len;
size_t src_len;
assert(src != NULL); assert(src != NULL);
assert(count != NULL); assert(count != NULL);
if (src[0] == L'\0' || src[1] != L':' || !path_is_separator_w(src[2])) { if (src[0] == L'\0' || src[1] != L':') {
return S_FALSE; return S_FALSE;
} }
@ -304,10 +305,15 @@ static HRESULT vfs_path_hook(const wchar_t *src, wchar_t *dest, size_t *count)
return S_FALSE; return S_FALSE;
} }
/* GetFileAttributesW would request the src "E:", so fix the src_len in
in order to redirect the drive letter successfully */
src_len = path_is_separator_w(src[2]) ? 3 : 2;
/* Cut off <prefix>\, replace with redir path, count NUL terminator */ /* Cut off <prefix>\, replace with redir path, count NUL terminator */
redir_len = wcslen(redir); redir_len = wcslen(redir);
required = wcslen(src) - 3 + redir_len + 1; required = wcslen(src) - src_len + redir_len + 1;
if (dest != NULL) { if (dest != NULL) {
if (required > *count) { if (required > *count) {
@ -315,7 +321,7 @@ static HRESULT vfs_path_hook(const wchar_t *src, wchar_t *dest, size_t *count)
} }
wcscpy_s(dest, *count, redir); wcscpy_s(dest, *count, redir);
wcscpy_s(dest + redir_len, *count - redir_len, src + 3); wcscpy_s(dest + redir_len, *count - redir_len, src + src_len);
} }
*count = required; *count = required;