mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-01 22:30:42 -07:00
sdvx: prevent the game from trying a random ASIO driver (#488)
## Link to GitHub Issue, if one exists n/a ## Description of change SDVX EG final started to pick an ASIO driver at random and tries to open it, which causes crashes / hangs if the driver is not compatible (ASIO4ALL in particular) Only allow the game to access `HKLM\SOFTWARE\ASIO` if the user has a Xonar AE, or if ASIO was configured using -sdvxasio. ## Testing Tested year 1 data and EG final.
This commit is contained in:
@@ -48,7 +48,7 @@ namespace games::sdvx {
|
|||||||
SdvxOverlayPosition OVERLAY_POS = SDVX_OVERLAY_BOTTOM;
|
SdvxOverlayPosition OVERLAY_POS = SDVX_OVERLAY_BOTTOM;
|
||||||
bool ENABLE_COM_PORT_SCAN_HOOK = false;
|
bool ENABLE_COM_PORT_SCAN_HOOK = false;
|
||||||
|
|
||||||
std::optional<std::string> SOUND_OUTPUT_DEVICE = std::nullopt;
|
bool USE_ASIO = false;
|
||||||
std::optional<std::string> ASIO_DRIVER = std::nullopt;
|
std::optional<std::string> ASIO_DRIVER = std::nullopt;
|
||||||
|
|
||||||
// states
|
// states
|
||||||
@@ -57,13 +57,22 @@ namespace games::sdvx {
|
|||||||
static HKEY real_asio_device_reg_handle = nullptr;
|
static HKEY real_asio_device_reg_handle = nullptr;
|
||||||
|
|
||||||
static LONG WINAPI RegOpenKeyA_hook(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult) {
|
static LONG WINAPI RegOpenKeyA_hook(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult) {
|
||||||
if (lpSubKey != nullptr && phkResult != nullptr) {
|
if (lpSubKey != nullptr &&
|
||||||
if (hKey == HKEY_LOCAL_MACHINE &&
|
phkResult != nullptr &&
|
||||||
ASIO_DRIVER.has_value() &&
|
hKey == HKEY_LOCAL_MACHINE &&
|
||||||
_stricmp(lpSubKey, "software\\asio") == 0)
|
_stricmp(lpSubKey, "software\\asio") == 0) {
|
||||||
{
|
|
||||||
*phkResult = PARENT_ASIO_REG_HANDLE;
|
|
||||||
|
|
||||||
|
// prevent the game from randomly picking an ASIO device
|
||||||
|
if (!USE_ASIO) {
|
||||||
|
log_info(
|
||||||
|
"sdvx::asio",
|
||||||
|
"game tried to access HKLM\\SOFTWARE\\ASIO but ASIO is disabled; "
|
||||||
|
"access prevented, ASIO init will fail");
|
||||||
|
return ERROR_FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
// convince the game to use our hook (so we can swap in the preferred device)
|
||||||
|
if (ASIO_DRIVER.has_value()) {
|
||||||
|
*phkResult = PARENT_ASIO_REG_HANDLE;
|
||||||
return RegOpenKeyA_orig(hKey, lpSubKey, &real_asio_reg_handle);
|
return RegOpenKeyA_orig(hKey, lpSubKey, &real_asio_reg_handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,7 +119,7 @@ namespace games::sdvx {
|
|||||||
lpSubKey != nullptr && phkResult != nullptr &&
|
lpSubKey != nullptr && phkResult != nullptr &&
|
||||||
_stricmp(lpSubKey, "HARDWARE\\DEVICEMAP\\SERIALCOMM") == 0) {
|
_stricmp(lpSubKey, "HARDWARE\\DEVICEMAP\\SERIALCOMM") == 0) {
|
||||||
log_info("sdvx::io", "hook access to HKLM\\HARDWARE\\DEVICEMAP\\SERIALCOMM to force COM1 ICCA");
|
log_info("sdvx::io", "hook access to HKLM\\HARDWARE\\DEVICEMAP\\SERIALCOMM to force COM1 ICCA");
|
||||||
return 2; // ERROR_FILE_NOT_FOUND
|
return ERROR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RegOpenKeyExA_orig(hKey, lpSubKey, ulOptions, samDesired, phkResult);
|
return RegOpenKeyExA_orig(hKey, lpSubKey, ulOptions, samDesired, phkResult);
|
||||||
@@ -230,6 +239,32 @@ namespace games::sdvx {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDVXGame::detect_sound_output_device() {
|
||||||
|
USE_ASIO = false;
|
||||||
|
// if the user specified a value for -sdvxasio, use asio
|
||||||
|
if (ASIO_DRIVER.has_value()) {
|
||||||
|
log_misc(
|
||||||
|
"sdvx",
|
||||||
|
"-sdvxasio is set to \"{}\"", ASIO_DRIVER.value());
|
||||||
|
USE_ASIO = true;
|
||||||
|
} else {
|
||||||
|
// see if XONAR AE is present; if so, use that
|
||||||
|
HKEY subkey;
|
||||||
|
LSTATUS result;
|
||||||
|
result = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\ASIO\\XONAR SOUND CARD(64)", &subkey);
|
||||||
|
if (result == ERROR_SUCCESS) {
|
||||||
|
RegCloseKey(subkey);
|
||||||
|
USE_ASIO = true;
|
||||||
|
log_misc(
|
||||||
|
"sdvx",
|
||||||
|
"found HKLM\\SOFTWARE\\ASIO\\XONAR SOUND CARD(64)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!USE_ASIO) {
|
||||||
|
log_misc("sdvx", "asio not configured");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typedef void **(__fastcall *volume_set_t)(uint64_t, uint64_t, uint64_t);
|
typedef void **(__fastcall *volume_set_t)(uint64_t, uint64_t, uint64_t);
|
||||||
static volume_set_t volume_set_orig = nullptr;
|
static volume_set_t volume_set_orig = nullptr;
|
||||||
static void **__fastcall volume_set_hook(uint64_t vol_sound, uint64_t vol_woofer, uint64_t vol_headphone) {
|
static void **__fastcall volume_set_hook(uint64_t vol_sound, uint64_t vol_woofer, uint64_t vol_headphone) {
|
||||||
@@ -323,6 +358,10 @@ namespace games::sdvx {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SPICE64
|
||||||
|
this->detect_sound_output_device();
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDVXGame::attach() {
|
void SDVXGame::attach() {
|
||||||
|
|||||||
@@ -39,5 +39,6 @@ namespace games::sdvx {
|
|||||||
// not depend on the fact that SDVX module is active (since it can be
|
// not depend on the fact that SDVX module is active (since it can be
|
||||||
// inactive on cabs or partial I/O setup)
|
// inactive on cabs or partial I/O setup)
|
||||||
bool VALKYRIE_MODEL = false;
|
bool VALKYRIE_MODEL = false;
|
||||||
|
void detect_sound_output_device();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user