diff options
author | BobTheBob <32057864+BobTheBob9@users.noreply.github.com> | 2022-01-02 22:32:36 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-02 22:32:36 +0000 |
commit | 3f629680f71b4694bd4eb78726537a91e10a2352 (patch) | |
tree | 137e44e28bbe372adeb616e3f20156ba23c08655 /loader_launcher_proxy | |
parent | ff875c0551c54bb187b5320b81029f8fe7f010fb (diff) | |
parent | f7b96d1048acddc343244ddec87a996ebaf7cb5b (diff) | |
download | NorthstarLauncher-3f629680f71b4694bd4eb78726537a91e10a2352.tar.gz NorthstarLauncher-3f629680f71b4694bd4eb78726537a91e10a2352.zip |
Merge pull request #19 from p0358/main
Big refactor of launching process
Diffstat (limited to 'loader_launcher_proxy')
-rw-r--r-- | loader_launcher_proxy/Memory.cpp | 84 | ||||
-rw-r--r-- | loader_launcher_proxy/Memory.h | 24 | ||||
-rw-r--r-- | loader_launcher_proxy/dllmain.cpp | 156 | ||||
-rw-r--r-- | loader_launcher_proxy/framework.h | 7 | ||||
-rw-r--r-- | loader_launcher_proxy/loader_launcher_proxy.vcxproj | 107 | ||||
-rw-r--r-- | loader_launcher_proxy/loader_launcher_proxy.vcxproj.filters | 33 | ||||
-rw-r--r-- | loader_launcher_proxy/pch.cpp | 5 | ||||
-rw-r--r-- | loader_launcher_proxy/pch.h | 13 |
8 files changed, 429 insertions, 0 deletions
diff --git a/loader_launcher_proxy/Memory.cpp b/loader_launcher_proxy/Memory.cpp new file mode 100644 index 00000000..f00c4d96 --- /dev/null +++ b/loader_launcher_proxy/Memory.cpp @@ -0,0 +1,84 @@ +#include "pch.h" + +extern HMODULE hTier0Module; +IMemAlloc** g_ppMemAllocSingleton; + +void LoadTier0Handle() +{ + if (!hTier0Module) hTier0Module = GetModuleHandleA("tier0.dll"); + if (!hTier0Module) return; + + g_ppMemAllocSingleton = (IMemAlloc**)GetProcAddress(hTier0Module, "g_pMemAllocSingleton"); +} + +const int STATIC_ALLOC_SIZE = 4096; + +size_t g_iStaticAllocated = 0; +void* g_pLastAllocated = nullptr; +char pStaticAllocBuf[STATIC_ALLOC_SIZE]; + +// they should never be used here, except in LibraryLoadError? + +void* malloc(size_t n) +{ + // allocate into static buffer + if (g_iStaticAllocated + n <= STATIC_ALLOC_SIZE) + { + void* ret = pStaticAllocBuf + g_iStaticAllocated; + g_iStaticAllocated += n; + return ret; + } + else + { + // try to fallback to g_pMemAllocSingleton + if (!hTier0Module || !g_ppMemAllocSingleton) LoadTier0Handle(); + if (g_ppMemAllocSingleton && *g_ppMemAllocSingleton) + return (*g_ppMemAllocSingleton)->m_vtable->Alloc(*g_ppMemAllocSingleton, n); + else + throw "Cannot allocate"; + } +} + +void free(void* p) +{ + // if it was allocated into the static buffer, just do nothing, safest way to deal with it + if (p >= pStaticAllocBuf && p <= pStaticAllocBuf + STATIC_ALLOC_SIZE) + return; + + if (g_ppMemAllocSingleton && *g_ppMemAllocSingleton) + (*g_ppMemAllocSingleton)->m_vtable->Free(*g_ppMemAllocSingleton, p); +} + +void* realloc(void* old_ptr, size_t size) { + // it was allocated into the static buffer + if (old_ptr >= pStaticAllocBuf && old_ptr <= pStaticAllocBuf + STATIC_ALLOC_SIZE) + { + if (g_pLastAllocated == old_ptr) + { + // nothing was allocated after this + size_t old_size = g_iStaticAllocated - ((size_t)g_pLastAllocated - (size_t)pStaticAllocBuf); + size_t diff = size - old_size; + if (diff > 0) + g_iStaticAllocated += diff; + return old_ptr; + } + else + { + return malloc(size); + } + } + + if (g_ppMemAllocSingleton && *g_ppMemAllocSingleton) + return (*g_ppMemAllocSingleton)->m_vtable->Realloc(*g_ppMemAllocSingleton, old_ptr, size); + return nullptr; +} + +void* operator new(size_t n) +{ + return malloc(n); +} + +void operator delete(void* p) +{ + return free(p); +} diff --git a/loader_launcher_proxy/Memory.h b/loader_launcher_proxy/Memory.h new file mode 100644 index 00000000..c983966c --- /dev/null +++ b/loader_launcher_proxy/Memory.h @@ -0,0 +1,24 @@ +#pragma once + +class IMemAlloc +{ +public: + struct VTable + { + void* unknown[1]; // alloc debug + void* (*Alloc) (IMemAlloc* memAlloc, size_t nSize); + void* unknown2[1]; // realloc debug + void* (*Realloc)(IMemAlloc* memAlloc, void* pMem, size_t nSize); + void* unknown3[1]; // free #1 + void (*Free) (IMemAlloc* memAlloc, void* pMem); + void* unknown4[2]; // nullsubs, maybe CrtSetDbgFlag + size_t(*GetSize) (IMemAlloc* memAlloc, void* pMem); + void* unknown5[9]; // they all do literally nothing + void (*DumpStats) (IMemAlloc* memAlloc); + void (*DumpStatsFileBase) (IMemAlloc* memAlloc, const char* pchFileBase); + void* unknown6[4]; + int (*heapchk) (IMemAlloc* memAlloc); + }; + + VTable* m_vtable; +}; diff --git a/loader_launcher_proxy/dllmain.cpp b/loader_launcher_proxy/dllmain.cpp new file mode 100644 index 00000000..cf69d63e --- /dev/null +++ b/loader_launcher_proxy/dllmain.cpp @@ -0,0 +1,156 @@ +#include "pch.h" +#include <stdio.h> +#include <string> +#include <system_error> +#include <Shlwapi.h> +#include <sstream> +#include <fstream> + +HMODULE hLauncherModule; +HMODULE hHookModule; +HMODULE hTier0Module; + +using CreateInterfaceFn = void* (*)(const char* pName, int* pReturnCode); + +// does not seem to ever be used +extern "C" _declspec(dllexport) void* __fastcall CreateInterface(const char* pName, int* pReturnCode) +{ + //AppSystemCreateInterfaceFn(pName, pReturnCode); + printf("external CreateInterface: name: %s\n", pName); + + static CreateInterfaceFn launcher_CreateInterface = (CreateInterfaceFn)GetProcAddress(hLauncherModule, "CreateInterface"); + auto res = launcher_CreateInterface(pName, pReturnCode); + + printf("external CreateInterface: return code: %p\n", res); + return res; +} + +bool GetExePathWide(wchar_t* dest, DWORD destSize) +{ + if (!dest) return NULL; + if (destSize < MAX_PATH) return NULL; + + DWORD length = GetModuleFileNameW(NULL, dest, destSize); + return length && PathRemoveFileSpecW(dest); +} + +FARPROC GetLauncherMain() +{ + static FARPROC Launcher_LauncherMain; + if (!Launcher_LauncherMain) + Launcher_LauncherMain = GetProcAddress(hLauncherModule, "LauncherMain"); + return Launcher_LauncherMain; +} + +void LibraryLoadError(DWORD dwMessageId, const wchar_t* libName, const wchar_t* location) +{ + char text[2048]; + std::string message = std::system_category().message(dwMessageId); + sprintf_s(text, "Failed to load the %ls at \"%ls\" (%lu):\n\n%hs", libName, location, dwMessageId, message.c_str()); + MessageBoxA(GetForegroundWindow(), text, "Northstar Launcher Proxy Error", 0); +} + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + +wchar_t exePath[4096]; +wchar_t dllPath[4096]; + +bool ShouldLoadNorthstar() +{ + bool loadNorthstar = !strstr(GetCommandLineA(), "-vanilla"); + + if (!loadNorthstar) + return loadNorthstar; + + auto runNorthstarFile = std::ifstream("run_northstar.txt"); + if (runNorthstarFile) + { + std::stringstream runNorthstarFileBuffer; + runNorthstarFileBuffer << runNorthstarFile.rdbuf(); + runNorthstarFile.close(); + if (runNorthstarFileBuffer.str()._Starts_with("0")) + loadNorthstar = false; + } + return loadNorthstar; +} + +bool LoadNorthstar() +{ + FARPROC Hook_Init = nullptr; + { + swprintf_s(dllPath, L"%s\\Northstar.dll", exePath); + hHookModule = LoadLibraryExW(dllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH); + if (hHookModule) Hook_Init = GetProcAddress(hHookModule, "InitialiseNorthstar"); + if (!hHookModule || Hook_Init == nullptr) + { + LibraryLoadError(GetLastError(), L"Northstar.dll", dllPath); + return false; + } + } + + ((bool (*)()) Hook_Init)(); + return true; +} + +extern "C" __declspec(dllexport) int LauncherMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + { + if (!GetExePathWide(exePath, 4096)) + { + MessageBoxA(GetForegroundWindow(), "Failed getting game directory.\nThe game cannot continue and has to exit.", "Northstar Launcher Proxy Error", 0); + return 1; + } + + bool loadNorthstar = ShouldLoadNorthstar(); + + if (loadNorthstar) + { + swprintf_s(dllPath, L"%s\\bin\\x64_retail\\tier0.dll", exePath); + hTier0Module = LoadLibraryExW(dllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH); + if (!hTier0Module) + { + LibraryLoadError(GetLastError(), L"tier0.dll", dllPath); + return 1; + } + + if (!LoadNorthstar()) + return 1; + } + //else printf("\n\n WILL !!!NOT!!! LOAD NORTHSTAR\n\n"); + + swprintf_s(dllPath, L"%s\\bin\\x64_retail\\launcher.org.dll", exePath); + hLauncherModule = LoadLibraryExW(dllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH); + if (!hLauncherModule) + { + LibraryLoadError(GetLastError(), L"launcher.org.dll", dllPath); + return 1; + } + } + + auto LauncherMain = GetLauncherMain(); + if (!LauncherMain) + MessageBoxA(GetForegroundWindow(), "Failed loading launcher.org.dll.\nThe game cannot continue and has to exit.", "Northstar Launcher Proxy Error", 0); + //auto result = ((__int64(__fastcall*)())LauncherMain)(); + //auto result = ((signed __int64(__fastcall*)(__int64))LauncherMain)(0i64); + return ((int(__fastcall*)(HINSTANCE, HINSTANCE, LPSTR, int))LauncherMain)(hInstance, hPrevInstance, lpCmdLine, nCmdShow); +} + +// doubt that will help us here (in launcher.dll) though +extern "C" { + __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; + __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; +} diff --git a/loader_launcher_proxy/framework.h b/loader_launcher_proxy/framework.h new file mode 100644 index 00000000..d1b49600 --- /dev/null +++ b/loader_launcher_proxy/framework.h @@ -0,0 +1,7 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#define WIN32_EXTRA_LEAN +#define VC_EXTRALEAN +// Windows Header Files +#include <Windows.h> diff --git a/loader_launcher_proxy/loader_launcher_proxy.vcxproj b/loader_launcher_proxy/loader_launcher_proxy.vcxproj new file mode 100644 index 00000000..24cdabc0 --- /dev/null +++ b/loader_launcher_proxy/loader_launcher_proxy.vcxproj @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>16.0</VCProjectVersion> + <Keyword>Win32Proj</Keyword> + <ProjectGuid>{f65c322d-66df-4af1-b650-70221de334c0}</ProjectGuid> + <RootNamespace>loaderlauncherproxy</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <TargetName>launcher</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <TargetName>launcher</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>_DEBUG;LOADERLAUNCHERPROXY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <PrecompiledHeader>Use</PrecompiledHeader> + <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableUAC>false</EnableUAC> + <AdditionalDependencies>shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>NDEBUG;LOADERLAUNCHERPROXY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <PrecompiledHeader>Use</PrecompiledHeader> + <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableUAC>false</EnableUAC> + <AdditionalOptions>/HIGHENTROPYVA:NO %(AdditionalOptions)</AdditionalOptions> + <AdditionalDependencies>shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="framework.h" /> + <ClInclude Include="pch.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="dllmain.cpp" /> + <ClCompile Include="pch.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> + </ClCompile> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/loader_launcher_proxy/loader_launcher_proxy.vcxproj.filters b/loader_launcher_proxy/loader_launcher_proxy.vcxproj.filters new file mode 100644 index 00000000..1e57c7b1 --- /dev/null +++ b/loader_launcher_proxy/loader_launcher_proxy.vcxproj.filters @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="framework.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pch.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="dllmain.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pch.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/loader_launcher_proxy/pch.cpp b/loader_launcher_proxy/pch.cpp new file mode 100644 index 00000000..64b7eef6 --- /dev/null +++ b/loader_launcher_proxy/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/loader_launcher_proxy/pch.h b/loader_launcher_proxy/pch.h new file mode 100644 index 00000000..885d5d62 --- /dev/null +++ b/loader_launcher_proxy/pch.h @@ -0,0 +1,13 @@ +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +// add headers that you want to pre-compile here +#include "framework.h" + +#endif //PCH_H |