diff --git a/NorthstarDLL/NorthstarDLL.vcxproj b/NorthstarDLL/NorthstarDLL.vcxproj index 782f6161a..6aa584bc9 100644 --- a/NorthstarDLL/NorthstarDLL.vcxproj +++ b/NorthstarDLL/NorthstarDLL.vcxproj @@ -249,6 +249,7 @@ IF EXIST "$(SolutionDir)..\NorthstarCN_Binaries\Northstar.dll" del "$(SolutionDi + @@ -365,7 +366,7 @@ IF EXIST "$(SolutionDir)..\NorthstarCN_Binaries\Northstar.dll" del "$(SolutionDi - + diff --git a/NorthstarDLL/NorthstarDLL.vcxproj.filters b/NorthstarDLL/NorthstarDLL.vcxproj.filters index d081c4c46..bb8b8b5e3 100644 --- a/NorthstarDLL/NorthstarDLL.vcxproj.filters +++ b/NorthstarDLL/NorthstarDLL.vcxproj.filters @@ -381,6 +381,9 @@ Header Files\client\igig + + Header Files\shared + @@ -695,7 +698,7 @@ Source Files\client\igig - + Source Files\shared diff --git a/NorthstarDLL/core/tier0.cpp b/NorthstarDLL/core/tier0.cpp index cbad3ec0d..31c877753 100644 --- a/NorthstarDLL/core/tier0.cpp +++ b/NorthstarDLL/core/tier0.cpp @@ -1,4 +1,5 @@ #include "tier0.h" +#include "shared/cmimalloc.h" // use the Tier0 namespace for tier0 funcs namespace Tier0 @@ -14,6 +15,8 @@ namespace Tier0 typedef Tier0::IMemAlloc* (*CreateGlobalMemAllocType)(); CreateGlobalMemAllocType CreateGlobalMemAlloc; +std::mutex mmMutex; + // needs to be a seperate function, since memalloc.cpp calls it void TryCreateGlobalMemAlloc() { @@ -23,8 +26,17 @@ void TryCreateGlobalMemAlloc() Tier0::g_pMemAllocSingleton = CreateGlobalMemAlloc(); // if it already exists, this returns the preexisting IMemAlloc instance } +AUTOHOOK_INIT() + +AUTOHOOK(CGMA, tier0.dll + 0x17B60, void*, __fastcall, ()) +{ + return new CMiMalloc(); +} + ON_DLL_LOAD("tier0.dll", Tier0GameFuncs, (CModule module)) { + AUTOHOOK_DISPATCH(); + // shouldn't be necessary, but do this just in case TryCreateGlobalMemAlloc(); diff --git a/NorthstarDLL/pch.h b/NorthstarDLL/pch.h index b3fc15f5c..b4672892a 100644 --- a/NorthstarDLL/pch.h +++ b/NorthstarDLL/pch.h @@ -8,18 +8,19 @@ #define _WINSOCK_DEPRECATED_NO_WARNINGS // temp because i'm very lazy and want to use inet_addr, remove later #define RAPIDJSON_HAS_STDSTRING 1 -// add headers that you want to pre-compile here -#include "core/memalloc.h" - #include #include #include #include #include #include - namespace fs = std::filesystem; +#include "core/memory.h" + +// add headers that you want to pre-compile here +#include "core/memalloc.h" + // clang-format off #define assert_msg(exp, msg) assert((exp, msg)) //clang-format on @@ -33,6 +34,5 @@ namespace fs = std::filesystem; #include "MinHook.h" #include "curl/curl.h" #include "core/hooks.h" -#include "core/memory.h" #endif diff --git a/NorthstarDLL/shared/cmimalloc.cpp b/NorthstarDLL/shared/cmimalloc.cpp new file mode 100644 index 000000000..d72c5ce78 --- /dev/null +++ b/NorthstarDLL/shared/cmimalloc.cpp @@ -0,0 +1,224 @@ +#include "cmimalloc.h" +#include + +void* CMiMalloc::AllocDebug(size_t nSize) +{ + return mi_malloc(nSize); +} + +void* CMiMalloc::Alloc(size_t nSize) +{ + return mi_malloc(nSize); +} + +void* CMiMalloc::ReallocDebug(void* pMem, size_t nSize) +{ + return mi_realloc(pMem, nSize); +} + +void* CMiMalloc::Realloc(void* pMem, size_t nSize) +{ + return mi_realloc(pMem, nSize); +} + +void CMiMalloc::FreeDebug(void* pMem) +{ + return mi_free(pMem); +} + +void CMiMalloc::Free(void* pMem) +{ + return mi_free(pMem); +} + +void* CMiMalloc::Expand_NoLongerSupportedDebug(void* pMem, size_t nSize) +{ + return nullptr; +} + +void* CMiMalloc::Expand_NoLongerSupported(void* pMem, size_t nSize) +{ + return nullptr; +} + +size_t CMiMalloc::GetSize(void* pMem) +{ + return mi_usable_size(pMem); +} + +void CMiMalloc::PushAllocDbgInfo(const char* pFileName, int nLine) {} + +void CMiMalloc::PopAllocDbgInfo() {} + +__int32 CMiMalloc::CrtSetBreakAlloc(__int32 lNewBreakAlloc) +{ + return 0; +} + +int CMiMalloc::CrtSetReportMode(int nReportType, int nReportMode) +{ + return 0; +} + +int CMiMalloc::CrtIsValidHeapPointer(const void* pMem) +{ + return 1; +} + +int CMiMalloc::CrtIsValidPointer(const void* pMem, unsigned int size, int access) +{ + return 1; +} + +int CMiMalloc::CrtCheckMemory() +{ + return 1; +} + +int CMiMalloc::CrtSetDbgFlag(int nNewFlag) +{ + return 0; +} + +void CMiMalloc::CrtMemCheckpoint(_CrtMemState* pState) {} + +void CMiMalloc::DumpStats() +{ + return mi_stats_print(NULL); +} + +void PrintToFile(const char* msg, void* arg) { + FILE* fp = (FILE*)arg; + fprintf_s(fp, msg); +} + +void CMiMalloc::DumpStatsFileBase(char const* pchFileBase) +{ + std::string filename(pchFileBase); + filename.append(".txt"); + FILE* fp; + errno_t err = fopen_s(&fp, filename.c_str(), "w+"); + if (err != 0) + { + return; + } + mi_stats_print_out(PrintToFile, fp); +} + +size_t CMiMalloc::ComputeMemoryUsedBy(char const* pchSubStr) +{ + return 0; +} + +__int64 CMiMalloc::nullsub_1() +{ + return 0xDC00000; +} + +void* CMiMalloc::CrtSetReportFile(int nRptType, void* hFile) +{ + return nullptr; +} + +void* CMiMalloc::CrtSetReportHook(void* pfnNewHook) +{ + return nullptr; +} + +int CMiMalloc::CrtDbgReport(int nRptType, const char* szFile, int nLine, const char* szModule, const char* pMsg) +{ + return 0; +} + +int CMiMalloc::heapchk() +{ + return _HEAPOK; +} + +bool CMiMalloc::IsDebugHeap() +{ + return false; +} + +void CMiMalloc::GetActualDbgInfo(const char*& pFileName, int& nLine) {} + +void CMiMalloc::RegisterAllocation(const char* pFileName, int nLine, size_t nLogicalSize, size_t nActualSize, unsigned nTime) {} + +void CMiMalloc::RegisterDeallocation(const char* pFileName, int nLine, size_t nLogicalSize, size_t nActualSize, unsigned nTime) {} + +int CMiMalloc::GetVersion() +{ + return 1; +} + +void CMiMalloc::CompactHeap() +{ + return mi_collect(false); +} + +MemAllocFailHandler_t CMiMalloc::SetAllocFailHandler(MemAllocFailHandler_t pfnMemAllocFailHandler) +{ + auto old = m_pfnFailHandler; + m_pfnFailHandler = pfnMemAllocFailHandler; + return old; +} + +void CMiMalloc::DumpBlockStats(void* pMem) {} + +void CMiMalloc::SetStatsExtraInfo(const char* pMapName, const char* pComment) {} + +size_t CMiMalloc::MemoryAllocFailed() +{ + return m_sMemoryAllocFailed; +} + +void CMiMalloc::CompactIncremental() {} + +void CMiMalloc::OutOfMemory(size_t nBytesAttempted) {} + +void* CMiMalloc::RegionAllocDebug(int region, size_t nSize) +{ + return mi_malloc(nSize); +} + +void* CMiMalloc::RegionAlloc(int region, size_t nSize) +{ + return mi_malloc(nSize); +} + +void CMiMalloc::GlobalMemoryStatus(size_t* pUsedMemory, size_t* pFreeMemory) +{ + if (pUsedMemory && pFreeMemory) + { + *pUsedMemory = 0; + *pFreeMemory = 0; + } +} + +__int64 CMiMalloc::AllocateVirtualMemorySection(size_t numMaxBytes) +{ + return 0; +} + +int CMiMalloc::GetGenericMemoryStats(GenericMemoryStat_t** ppMemoryStats) +{ + if (ppMemoryStats) + { + *ppMemoryStats = nullptr; + } + + return 0; +} + +CMiMalloc::~CMiMalloc() {} + +CMiMalloc* CMiMalloc::instance() +{ + return nullptr; +} + + + + + + diff --git a/NorthstarDLL/shared/cmimalloc.h b/NorthstarDLL/shared/cmimalloc.h new file mode 100644 index 000000000..544591c27 --- /dev/null +++ b/NorthstarDLL/shared/cmimalloc.h @@ -0,0 +1,64 @@ +#pragma once + +typedef size_t (*MemAllocFailHandler_t)(size_t); + +struct GenericMemoryStat_t +{ + const char* name; + int value; +}; + +class CMiMalloc +{ + public: + virtual void* AllocDebug(size_t nSize); + virtual void* Alloc(size_t nSize); + virtual void* ReallocDebug(void* pMem, size_t nSize); + virtual void* Realloc(void* pMem, size_t nSize); + virtual void FreeDebug(void* pMem); + virtual void Free(void* pMem); + virtual void* Expand_NoLongerSupportedDebug(void* pMem, size_t nSize); + virtual void* Expand_NoLongerSupported(void* pMem, size_t nSize); + virtual size_t GetSize(void* pMem); + virtual void PushAllocDbgInfo(const char* pFileName, int nLine); + virtual void PopAllocDbgInfo(); + virtual __int32 CrtSetBreakAlloc(__int32 lNewBreakAlloc); + virtual int CrtSetReportMode(int nReportType, int nReportMode); + virtual int CrtIsValidHeapPointer(const void* pMem); + virtual int CrtIsValidPointer(const void* pMem, unsigned int size, int access); + virtual int CrtCheckMemory(); + virtual int CrtSetDbgFlag(int nNewFlag); + virtual void CrtMemCheckpoint(_CrtMemState* pState); + virtual void DumpStats(); + virtual void DumpStatsFileBase(char const* pchFileBase); + virtual size_t ComputeMemoryUsedBy(char const* pchSubStr); + virtual __int64 nullsub_1(); + virtual void* CrtSetReportFile(int nRptType, void* hFile); + virtual void* CrtSetReportHook(void* pfnNewHook); + virtual int CrtDbgReport(int nRptType, const char* szFile, int nLine, const char* szModule, const char* pMsg); + virtual int heapchk(); + virtual bool IsDebugHeap(); + virtual void GetActualDbgInfo(const char*& pFileName, int& nLine); + virtual void RegisterAllocation(const char* pFileName, int nLine, size_t nLogicalSize, size_t nActualSize, unsigned nTime); + virtual void RegisterDeallocation(const char* pFileName, int nLine, size_t nLogicalSize, size_t nActualSize, unsigned nTime); + virtual int GetVersion(); + virtual void CompactHeap(); + virtual MemAllocFailHandler_t SetAllocFailHandler(MemAllocFailHandler_t pfnMemAllocFailHandler); + virtual void DumpBlockStats(void* pMem); + virtual void SetStatsExtraInfo(const char* pMapName, const char* pComment); + virtual size_t MemoryAllocFailed(); + virtual void CompactIncremental(); + virtual void OutOfMemory(size_t nBytesAttempted = 0); + virtual void* RegionAllocDebug(int region, size_t nSize); + virtual void* RegionAlloc(int region, size_t nSize); + virtual void GlobalMemoryStatus(size_t* pUsedMemory, size_t* pFreeMemory); + virtual __int64 AllocateVirtualMemorySection(size_t numMaxBytes); + virtual int GetGenericMemoryStats(GenericMemoryStat_t** ppMemoryStats); + virtual ~CMiMalloc(); + + static CMiMalloc* instance(); + + private: + MemAllocFailHandler_t m_pfnFailHandler; + size_t m_sMemoryAllocFailed = 0; +}; diff --git a/NorthstarDLL/shared/mimalloc.cpp b/NorthstarDLL/shared/mimalloc.cpp deleted file mode 100644 index 63d36e82e..000000000 --- a/NorthstarDLL/shared/mimalloc.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#include - -typedef size_t (*MemAllocFailHandler_t)(size_t); - -struct GenericMemoryStat_t -{ - const char* name; - int value; -}; - -struct CMiMalloc -{ - virtual void* AllocDebug(size_t nSize) - { - return mi_malloc(nSize); - } - virtual void* Alloc(size_t nSize) - { - return mi_malloc(nSize); - } - - virtual void* ReallocDebug(void* pMem, size_t nSize) - { - return mi_realloc(pMem, nSize); - } - virtual void* Realloc(void* pMem, size_t nSize) - { - return mi_realloc(pMem, nSize); - } - - virtual void FreeDebug(void* pMem) - { - return mi_free(pMem); - } - virtual void Free(void* pMem) - { - return mi_free(pMem); - } - - virtual void* Expand_NoLongerSupportedDebug(void* pMem, size_t nSize) - { - return 0; - } - virtual void* Expand_NoLongerSupported(void* pMem, size_t nSize) - { - return 0; - } - - virtual size_t GetSize(void* pMem) - { - return mi_usable_size(pMem); - } - - virtual void PushAllocDbgInfo(const char* pFileName, int nLine) {} - virtual void PopAllocDbgInfo() {} - - virtual __int32 CrtSetBreakAlloc(__int32 lNewBreakAlloc) - { - return 0; - } - - virtual int CrtSetReportMode(int nReportType, int nReportMode) - { - return 0; - } - - virtual int CrtIsValidHeapPointer(const void* pMem) - { - return 1; - } - - virtual int CrtIsValidPointer(const void* pMem, unsigned int size, int access) - { - return 1; - } - - virtual int CrtCheckMemory() - { - return 1; - } - - virtual int CrtSetDbgFlag(int nNewFlag) - { - return 0; - } - - virtual void CrtMemCheckpoint(_CrtMemState* pState) {} - - // TODO 1 - virtual void DumpStats() {} - virtual void DumpStatsFileBase(char const* pchFileBase) {} - - virtual size_t ComputeMemoryUsedBy(char const* pchSubStr) - { - return 0; - } - - virtual __int64 nullsub_1() - { - return 0xDC00000; - } - - virtual void* CrtSetReportFile(int nRptType, void* hFile) - { - return 0; - } - - virtual void* CrtSetReportHook(void* pfnNewHook) - { - return 0; - } - - virtual int CrtDbgReport(int nRptType, const char* szFile, int nLine, const char* szModule, const char* pMsg) - { - return 0; - } - - // TODO 2 - virtual int heapchk() {} - - virtual bool IsDebugHeap() - { - return false; - } - - virtual void GetActualDbgInfo(const char*& pFileName, int& nLine) {} - virtual void RegisterAllocation(const char* pFileName, int nLine, size_t nLogicalSize, size_t nActualSize, unsigned nTime) {} - virtual void RegisterDeallocation(const char* pFileName, int nLine, size_t nLogicalSize, size_t nActualSize, unsigned nTime) {} - - virtual int GetVersion() - { - return 1; - } - - // TODO 3 - virtual void CompactHeap() {} - - virtual MemAllocFailHandler_t SetAllocFailHandler(MemAllocFailHandler_t pfnMemAllocFailHandler) - { - MemAllocFailHandler_t old = m_pfnFailHandler; - m_pfnFailHandler = pfnMemAllocFailHandler; - return old; - } - - // TODO 4 - virtual void DumpBlockStats(void* pMem) {} - - virtual void SetStatsExtraInfo(const char* pMapName, const char* pComment) {} - - virtual size_t MemoryAllocFailed() - { - return m_sMemoryAllocFailed; - } - - // TODO 5 - virtual void CompactIncremental() {} - - virtual void OutOfMemory(size_t nBytesAttempted = 0) {} - - // TODO 6 - virtual void* RegionAllocDebug(int region, size_t nSize) {} - virtual void* RegionAlloc(int region, size_t nSize) {} - - virtual void GlobalMemoryStatus(size_t* pUsedMemory, size_t* pFreeMemory) {} - - virtual __int64 AllocateVirtualMemorySection(size_t numMaxBytes) - { - return 0; - } - - virtual int GetGenericMemoryStats(GenericMemoryStat_t** ppMemoryStats) {} - - virtual ~CMiMalloc() {}; - - MemAllocFailHandler_t m_pfnFailHandler; - size_t m_sMemoryAllocFailed; -};