Skip to content

Commit

Permalink
Merge pull request #1105 from MainMemory/master
Browse files Browse the repository at this point in the history
Panacea Fix
  • Loading branch information
shananas authored Aug 30, 2024
2 parents 48cee8e + 9905201 commit f56dd1c
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 5 deletions.
6 changes: 6 additions & 0 deletions OpenKh.Research.Panacea/KingdomApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ PFN_DEFINE(Axa_FreeAllPackages);
PFN_DEFINE(Axa_CFileMan_GetRemasteredCount);
PFN_DEFINE(Axa_CFileMan_GetRemasteredEntry);
PFN_DEFINE(Axa_PackageFile_GetRemasteredAsset);
PFN_DEFINE(Axa_PackageFile_OpenFileImpl);
PFN_DEFINE(Axa_AxaSoundStream__threadProc);
PFN_DEFINE(Axa_OpenFile);
PFN_DEFINE(Axa_DebugPrint);
Expand Down Expand Up @@ -81,6 +82,11 @@ void* Axa::PackageFile::GetRemasteredAsset(Axa::PackageFile* a1, unsigned int* a
return pfn_Axa_PackageFile_GetRemasteredAsset(a1, assetSizePtr, assetNum);
}

bool Axa::PackageFile::OpenFileImpl(Axa::PackageFile* a1, const char* filePath, const char* altBasePath)
{
return pfn_Axa_PackageFile_OpenFileImpl(a1, filePath, altBasePath);
}

__int64 Axa::AxaSoundStream::_threadProc(unsigned int* instance)
{
return pfn_Axa_AxaSoundStream__threadProc(instance);
Expand Down
2 changes: 2 additions & 0 deletions OpenKh.Research.Panacea/KingdomApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ namespace Axa
char CurrentFileName[260]{};
int unk3 = 0;
void* GetRemasteredAsset(Axa::PackageFile* a1, unsigned int* assetSizePtr, int assetNum);
static bool OpenFileImpl(Axa::PackageFile* a1, const char* filePath, const char* altBasePath);
};

class CFileMan
Expand Down Expand Up @@ -132,6 +133,7 @@ PFN_DECLARE(void, Axa_FreeAllPackages, ());
PFN_DECLARE(__int64, Axa_CFileMan_GetRemasteredCount, ());
PFN_DECLARE(Axa::RemasteredEntry*, Axa_CFileMan_GetRemasteredEntry, (Axa::CFileMan* a1, int* origOffsetPtr, int assetNum));
PFN_DECLARE(void*, Axa_PackageFile_GetRemasteredAsset, (Axa::PackageFile* a1, unsigned int* assetSizePtr, int assetNum));
PFN_DECLARE(bool, Axa_PackageFile_OpenFileImpl, (Axa::PackageFile* a1, const char* filePath, const char* altBasePath));
PFN_DECLARE(__int64, Axa_AxaSoundStream__threadProc, (unsigned int* instance));
PFN_DECLARE(int, Axa_OpenFile, (const char* Format, int OFlag));
PFN_DECLARE(void, Axa_DebugPrint, (const char* Format, ...));
Expand Down
8 changes: 7 additions & 1 deletion OpenKh.Research.Panacea/OpenKH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ void Hook()
Hook(pfn_Axa_CFileMan_GetRemasteredCount, "\x48\x63\x05\x00\x00\x00\x00\x48\x8D\x0D\x00\x00\x00\x00\x48\x8B\x04\xC1\x8B\x80", "xxx????xxx????xxxxxx");
Hook(pfn_Axa_CFileMan_GetRemasteredEntry, "\x48\x63\x05\x00\x00\x00\x00\x4C\x8D\x0D\x00\x00\x00\x00\x4D\x8B\x0C\xC1\x4D\x8B", "xxx????xxx????xxxxxx");
Hook(pfn_Axa_PackageFile_GetRemasteredAsset, "\x40\x53\x56\x48\x83\xEC\x28\x48\x8B\xD9\x48\x8B\xF2\x48\x8B\x89", "xxxxxxxxxxxxxxxx");
Hook(pfn_Axa_PackageFile_OpenFileImpl, "\x40\x53\x55\x56\x57\x41\x57\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x33\xC4\x48\x89\x84\x24\x00\x00\x00\x00\x48", "xxxxxxxxxx????xxx????xxxxxxx????x");
Hook(pfn_Axa_AxaSoundStream__threadProc, "\x48\x8B\xC4\x57\x48\x83\xEC\x60\x48\xC7\x40\x00\x00\x00\x00\x00\x48\x89\x58\x10\x48\x89\x68\x18\x48\x89\x70\x20\x48\x8B\xD9\x33\xED\x83\xB9", "xxxxxxxxxxx?????xxxxxxxxxxxxxxxxxxx");
Hook(pfn_Axa_OpenFile, "\x40\x53\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x33\xC4\x48\x89\x84\x24\x00\x00\x00\x00\x8B\xDA\x48\x8B\xD1\x48\x8D\x4C\x24", "xxxxx????xxx????xxxxxxx????xxxxxxxxx");
Hook(pfn_Axa_DebugPrint, "\x48\x89\x54\x24\x00\x4C\x89\x44\x24\x00\x4C\x89\x4C\x24\x00\xC3", "xxxx?xxxx?xxxx?x");
Expand Down Expand Up @@ -116,6 +117,7 @@ std::wstring OpenKH::m_ExtractPath = L"";
bool OpenKH::m_ShowConsole = false;
bool OpenKH::m_DebugLog = false;
bool OpenKH::m_EnableCache = true;
bool OpenKH::m_SoundDebug = false;
bool QuickMenu = false;
const uint8_t quickmenupat[] = { 0xB1, 0x01, 0x90 };
const std::wstring gamefolders[] = {
Expand Down Expand Up @@ -204,6 +206,8 @@ void OpenKH::Initialize()
fputs("debug_log=true\n", f);
if (m_EnableCache)
fputs("enable_cache=true\n", f);
if (m_SoundDebug)
fputs("sound_debug=true\n", f);
if (QuickMenu)
fputs("quick_menu=true\n", f);
fclose(f);
Expand Down Expand Up @@ -235,7 +239,7 @@ void OpenKH::Initialize()
m_DevPath.append(gamefolders[(int)m_GameID]);
if (m_ExtractPath.size() > 0)
m_ExtractPath.append(gamefolders[(int)m_GameID]);

Hook();
Panacea::Initialize();

Expand Down Expand Up @@ -293,6 +297,8 @@ void OpenKH::ReadSettings(const char* filename)
parseBool(value, m_DebugLog);
else if (!strncmp(key, "enable_cache", sizeof(buf)))
parseBool(value, m_EnableCache);
else if (!strncmp(key, "sound_debug", sizeof(buf)))
parseBool(value, m_SoundDebug);
else if (!strncmp(key, "quick_launch", sizeof(buf)))
{
if (!_stricmp(value, "kh1") || !_stricmp(value, "kh3d"))
Expand Down
1 change: 1 addition & 0 deletions OpenKh.Research.Panacea/OpenKH.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace OpenKH
extern bool m_ShowConsole;
extern bool m_DebugLog;
extern bool m_EnableCache;
extern bool m_SoundDebug;

void Initialize();

Expand Down
34 changes: 30 additions & 4 deletions OpenKh.Research.Panacea/Panacea.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ Hook<PFN_Axa_CFileMan_GetFileSize>* Hook_Axa_CFileMan_GetFileSize;
Hook<PFN_Axa_CFileMan_GetRemasteredCount>* Hook_Axa_CFileMan_GetRemasteredCount;
Hook<PFN_Axa_CFileMan_GetRemasteredEntry>* Hook_Axa_CFileMan_GetRemasteredEntry;
Hook<PFN_Axa_PackageFile_GetRemasteredAsset>* Hook_Axa_PackageFile_GetRemasteredAsset;
Hook<PFN_Axa_PackageFile_OpenFileImpl>* Hook_Axa_PackageFile_OpenFileImpl;
Hook<PFN_VAG_STREAM_play>* Hook_VAG_STREAM_play;
Hook<PFN_VAG_STREAM_fadeOut>* Hook_VAG_STREAM_fadeOut;
Hook<PFN_VAG_STREAM_setVolume>* Hook_VAG_STREAM_setVolume;
Expand Down Expand Up @@ -318,6 +319,7 @@ void Panacea::Initialize()
Hook_Axa_CFileMan_GetRemasteredCount = NewHook(pfn_Axa_CFileMan_GetRemasteredCount, Panacea::GetRemasteredCount, "Axa::CFileMan::GetRemasteredCount");
Hook_Axa_CFileMan_GetRemasteredEntry = NewHook(pfn_Axa_CFileMan_GetRemasteredEntry, Panacea::GetRemasteredEntry, "Axa::CFileMan::GetRemasteredEntry");
Hook_Axa_PackageFile_GetRemasteredAsset = NewHook(pfn_Axa_PackageFile_GetRemasteredAsset, Panacea::GetRemasteredAsset, "Axa::PackageFile::GetRemasteredAsset");
Hook_Axa_PackageFile_OpenFileImpl = NewHook(pfn_Axa_PackageFile_OpenFileImpl, Panacea::OpenFileImpl, "Axa::PackageFile::OpenFileImpl");
Hook_VAG_STREAM_play = NewHook(pfn_VAG_STREAM_play, Panacea::VAG_STREAM::play, "VAG_STREAM::play");
Hook_VAG_STREAM_fadeOut = NewHook(pfn_VAG_STREAM_fadeOut, Panacea::VAG_STREAM::fadeOut, "VAG_STREAM::fadeOut");
Hook_VAG_STREAM_setVolume = NewHook(pfn_VAG_STREAM_setVolume, Panacea::VAG_STREAM::setVolume, "VAG_STREAM::setVolume");
Expand Down Expand Up @@ -798,6 +800,15 @@ void GetRemasteredFiles(Axa::PackageFile* fileinfo, const wchar_t* path, void* a
}
}

bool Panacea::OpenFileImpl(Axa::PackageFile* a1, const char* filePath, const char* altBasePath)
{
auto ret = Hook_Axa_PackageFile_OpenFileImpl->Unpatch()(a1, filePath, altBasePath);
Hook_Axa_PackageFile_OpenFileImpl->Patch();
if (ret)
strcpy_s(a1->CurrentFileName, filePath);
return ret;
}

long __cdecl Panacea::LoadFile(Axa::CFileMan* _this, const char* filename, void* addr, bool useHdAsset)
{
wchar_t path[MAX_PATH];
Expand Down Expand Up @@ -1006,7 +1017,7 @@ void* __cdecl Panacea::LoadFileWithMalloc(Axa::CFileMan* _this, const char* file
{
if (OpenKH::m_DebugLog)
fwprintf(stdout, L"LoadFileWithMalloc(\"%ls\", %d, \"%hs\")\n", path, useHdAsset, filename2);
auto fileinfo = Axa::PackageMan::GetFileInfo(filename, 0);
auto fileinfo = Axa::PackageMan::GetFileInfo(filename, filename2);
if (*sizePtr == -1)
return nullptr;
FILE* file = _wfopen(path, L"rb");
Expand Down Expand Up @@ -1167,10 +1178,15 @@ long __cdecl Panacea::GetFileSize(Axa::CFileMan* _this, const char* filename)

__int64 __cdecl Panacea::GetRemasteredCount()
{
__int64 count;
auto found = RemasteredData.find(PackageFiles[LastOpenedPackage]->CurrentFileName);
if (found != RemasteredData.end())
return found->second.size();
return PackageFiles[LastOpenedPackage]->CurrentFileData.remasteredCount;
count = found->second.size();
else
count = PackageFiles[LastOpenedPackage]->CurrentFileData.remasteredCount;
if (OpenKH::m_DebugLog)
fwprintf(stdout, L"GetRemasteredCount() = %lld\n", count);
return count;
}

Axa::RemasteredEntry* Panacea::GetRemasteredEntry(Axa::CFileMan* a1, int* origOffsetPtr, int assetNum)
Expand All @@ -1181,10 +1197,14 @@ Axa::RemasteredEntry* Panacea::GetRemasteredEntry(Axa::CFileMan* a1, int* origOf
if (assetNum >= found->second.size())
return nullptr;
*origOffsetPtr = found->second[assetNum].origOffset;
if (OpenKH::m_DebugLog)
fprintf(stdout, "GetRemasteredEntry(%d) = \"%s\"\n", assetNum, found->second[assetNum].name);
return &found->second[assetNum];
}
auto ret = Hook_Axa_CFileMan_GetRemasteredEntry->Unpatch()(a1, origOffsetPtr, assetNum);
Hook_Axa_CFileMan_GetRemasteredEntry->Patch();
if (OpenKH::m_DebugLog)
fprintf(stdout, "GetRemasteredEntry(%d) = \"%s\"\n", assetNum, ret->name);
return ret;
}

Expand All @@ -1207,6 +1227,8 @@ void* Panacea::GetRemasteredAsset(Axa::PackageFile* a1, unsigned int* assetSizeP
wchar_t path[MAX_PATH];
if (GetRawFile(path, sizeof(path), a1->CurrentFileName))
{
if (OpenKH::m_DebugLog)
fwprintf(stdout, L"GetRemasteredAsset(%d) = \"%ls\"\n", assetNum, path);
FILE* file = _wfopen(path, L"rb");
Axa::PkgEntry pkgent;
fread(&pkgent, sizeof(pkgent), 1, file);
Expand Down Expand Up @@ -1254,6 +1276,8 @@ void* Panacea::GetRemasteredAsset(Axa::PackageFile* a1, unsigned int* assetSizeP
}
if (GetFileAttributesW(remastered) != INVALID_FILE_ATTRIBUTES)
{
if (OpenKH::m_DebugLog)
fwprintf(stdout, L"GetRemasteredAsset(%d) = \"%ls\"\n", assetNum, remastered);
FILE* file = _wfopen(remastered, L"rb");
fseek(file, 0, SEEK_END);
*assetSizePtr = ftell(file);
Expand All @@ -1269,6 +1293,8 @@ void* Panacea::GetRemasteredAsset(Axa::PackageFile* a1, unsigned int* assetSizeP
fclose(file);
return addr;
}
if (OpenKH::m_DebugLog)
fwprintf(stdout, L"GetRemasteredAsset(%d)\n", assetNum);
auto ret = Hook_Axa_PackageFile_GetRemasteredAsset->Unpatch()(a1, assetSizePtr, assetNum);
Hook_Axa_PackageFile_GetRemasteredAsset->Patch();
return ret;
Expand Down Expand Up @@ -1372,7 +1398,7 @@ void Panacea::VAG_STREAM::exit()

void Panacea::DebugPrint(const char* format, ...)
{
if (OpenKH::m_DebugLog)
if (OpenKH::m_DebugLog && OpenKH::m_SoundDebug)
{
va_list args;
va_start(args, format);
Expand Down
1 change: 1 addition & 0 deletions OpenKh.Research.Panacea/Panacea.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace Panacea
__int64 __cdecl GetRemasteredCount();
Axa::RemasteredEntry* __cdecl GetRemasteredEntry(Axa::CFileMan* a1, int* origOffsetPtr, int assetNum);
void* GetRemasteredAsset(Axa::PackageFile* a1, unsigned int* assetSizePtr, int assetNum);
bool OpenFileImpl(Axa::PackageFile* a1, const char* filePath, const char* altBasePath);
namespace VAG_STREAM
{
void play(const char* fileName, int volume, int fadeVolume, int time);
Expand Down
114 changes: 114 additions & 0 deletions OpenKh.Research.Panacea/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <Shlwapi.h>
#include "OpenKH.h"
#include <filesystem>
#include <sstream>

typedef BOOL(WINAPI* PFN_MiniDumpWriteDump)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
PFN_MiniDumpWriteDump MiniDumpWriteDumpPtr;
Expand Down Expand Up @@ -69,6 +70,33 @@ void HookVersion()
assert(hModule != nullptr);
}

void LogTerminate()
{
std::exception_ptr exptr = std::current_exception();
if (exptr)
{
try
{
std::rethrow_exception(exptr);
}
catch (const std::exception& ex)
{
// NOTE: We can only really rely on the Win32 API in here, the stdlib might be hosed.
HANDLE stdErr = GetStdHandle(STD_ERROR_HANDLE);
if (stdErr != NULL && stdErr != INVALID_HANDLE_VALUE)
{
DWORD written = 0;
const char* message = ex.what();
WriteConsoleA(stdErr, message, strlen(message), &written, NULL);

Check warning on line 90 in OpenKh.Research.Panacea/dllmain.cpp

View workflow job for this annotation

GitHub Actions / build

'argument': conversion from 'size_t' to 'DWORD', possible loss of data
}
if (IsDebuggerPresent())
DebugBreak();
}
}
std::abort();
}

LONG WINAPI HandleException(struct _EXCEPTION_POINTERS* apExceptionInfo);
BOOL APIENTRY DllMain(
HMODULE hModule,
DWORD ul_reason_for_call,
Expand All @@ -84,6 +112,8 @@ BOOL APIENTRY DllMain(
case DLL_PROCESS_ATTACH:
HookVersion();
HookDbgHelp();
SetUnhandledExceptionFilter(HandleException);
std::set_terminate(LogTerminate);
OpenKH::Initialize();
break;
case DLL_THREAD_ATTACH:
Expand Down Expand Up @@ -115,3 +145,87 @@ extern "C" __declspec(dllexport) BOOL WINAPI VerQueryValueW(LPCVOID pBlock, LPCW
if (!VerQueryValueWPtr) HookVersion();
return VerQueryValueWPtr(pBlock, lpSubBlock, lplpBuffer, puLen);
}

static std::wstring getCurrentDate() {
auto now = std::chrono::system_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
std::tm* ptm = std::localtime(&now_c);

// Format date with '_' separators
std::wostringstream ss;
ss << std::setfill(L'0') << std::setw(2) << ptm->tm_mday << L"_"
<< std::setfill(L'0') << std::setw(2) << (ptm->tm_mon + 1) << L"_"
<< (ptm->tm_year + 1900);

return ss.str();
}

static std::wstring getCurrentTime() {
auto now = std::chrono::system_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
std::tm* ptm = std::localtime(&now_c);

// Format time with '_' separators
std::wostringstream ss;
ss << std::setfill(L'0') << std::setw(2) << ptm->tm_hour << L"_"
<< std::setfill(L'0') << std::setw(2) << ptm->tm_min << L"_"
<< std::setfill(L'0') << std::setw(2) << ptm->tm_sec;

return ss.str();
}

#pragma comment(lib, "dbghelp.lib")
#pragma comment(lib, "Psapi.lib")
LONG WINAPI HandleException(struct _EXCEPTION_POINTERS* apExceptionInfo)
{
std::wstring dateStr = getCurrentDate();
std::wstring timeStr = getCurrentTime();

std::wstring curCrashDumpFolder = L"CrashDump\\" + dateStr;

std::filesystem::create_directories(curCrashDumpFolder);

std::wstring fileName = timeStr + L"_" + L"Dump.dmp";

std::wstring crashDumpFile = curCrashDumpFolder + L"\\" + fileName;

MINIDUMP_EXCEPTION_INFORMATION info = { NULL, NULL, NULL };
try
{
//generate crash dump
HANDLE hFile = CreateFileW(
crashDumpFile.c_str(),
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
CREATE_ALWAYS,
0,
NULL
);

HANDLE hProcess = GetCurrentProcess();

if (hFile != NULL)
{
info =
{
GetCurrentThreadId(),
apExceptionInfo,
TRUE
};

MiniDumpWriteDump(hProcess, GetCurrentProcessId(),
hFile, MiniDumpWithIndirectlyReferencedMemory,
&info, NULL, NULL
);

CloseHandle(hFile);

}
}
catch (const std::exception& e)

Check warning on line 226 in OpenKh.Research.Panacea/dllmain.cpp

View workflow job for this annotation

GitHub Actions / build

'e': unreferenced local variable
{
}

return EXCEPTION_EXECUTE_HANDLER;
}

0 comments on commit f56dd1c

Please sign in to comment.