Merge pull request #83 from diamante0018/containers-are-lovely
feat: containers!
This commit is contained in:
commit
9adedb4062
@ -245,8 +245,6 @@ namespace Components
|
|||||||
|
|
||||||
const char* FastFiles::GetZoneLocation(const char* file)
|
const char* FastFiles::GetZoneLocation(const char* file)
|
||||||
{
|
{
|
||||||
const auto* dir = (*Game::fs_basepath)->current.string;
|
|
||||||
|
|
||||||
std::vector<std::string> paths;
|
std::vector<std::string> paths;
|
||||||
const std::string fsGame = (*Game::fs_gameDirVar)->current.string;
|
const std::string fsGame = (*Game::fs_gameDirVar)->current.string;
|
||||||
|
|
||||||
@ -270,6 +268,7 @@ namespace Components
|
|||||||
Utils::String::Replace(zone, "_load", "");
|
Utils::String::Replace(zone, "_load", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only check for usermaps on our working directory
|
||||||
if (Utils::IO::FileExists(std::format("usermaps\\{}\\{}.ff", zone, filename)))
|
if (Utils::IO::FileExists(std::format("usermaps\\{}\\{}.ff", zone, filename)))
|
||||||
{
|
{
|
||||||
return Utils::String::Format("usermaps\\{}\\", zone);
|
return Utils::String::Format("usermaps\\{}\\", zone);
|
||||||
@ -280,6 +279,7 @@ namespace Components
|
|||||||
|
|
||||||
for (auto& path : paths)
|
for (auto& path : paths)
|
||||||
{
|
{
|
||||||
|
const auto* dir = (*Game::fs_basepath)->current.string;
|
||||||
auto absoluteFile = std::format("{}\\{}{}", dir, path, file);
|
auto absoluteFile = std::format("{}\\{}{}", dir, path, file);
|
||||||
|
|
||||||
// No ".ff" appended, append it manually
|
// No ".ff" appended, append it manually
|
||||||
@ -506,11 +506,74 @@ namespace Components
|
|||||||
return Utils::Hook::Call<void(int, int)>(0x004925B0)(atStreamStart, surface->numsurfs);
|
return Utils::Hook::Call<void(int, int)>(0x004925B0)(atStreamStart, surface->numsurfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FastFiles::DB_BuildOSPath_FromSource_Default(const char* zoneName, Game::FF_DIR source, unsigned int size, char* filename)
|
||||||
|
{
|
||||||
|
// TODO: this is where user map and mod.ff check should happen
|
||||||
|
if (source == Game::FFD_DEFAULT)
|
||||||
|
{
|
||||||
|
(void)sprintf_s(filename, size, "%s\\%s%s.ff", FileSystem::Sys_DefaultInstallPath_Hk(), GetZoneLocation(zoneName), zoneName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FastFiles::DB_BuildOSPath_FromSource_Custom(const char* zoneName, Game::FF_DIR source, unsigned int size, char* filename)
|
||||||
|
{
|
||||||
|
// TODO: this is where user map and mod.ff check should happen
|
||||||
|
if (source == Game::FFD_DEFAULT)
|
||||||
|
{
|
||||||
|
(void)sprintf_s(filename, size, "%s\\%s%s.ff", FileSystem::Sys_HomePath_Hk(), GetZoneLocation(zoneName), zoneName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FastFiles::DB_FileExists_Hk(const char* zoneName, Game::FF_DIR source)
|
||||||
|
{
|
||||||
|
char filename[256]{};
|
||||||
|
|
||||||
|
DB_BuildOSPath_FromSource_Default(zoneName, source, sizeof(filename), filename);
|
||||||
|
if (auto zoneFile = Game::Sys_OpenFileReliable(filename); zoneFile != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
CloseHandle(zoneFile);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DB_BuildOSPath_FromSource_Custom(zoneName, source, sizeof(filename), filename);
|
||||||
|
if (auto zoneFile = Game::Sys_OpenFileReliable(filename); zoneFile != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
CloseHandle(zoneFile);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::Sys_File FastFiles::Sys_CreateFile_Stub(const char* dir, const char* filename)
|
||||||
|
{
|
||||||
|
static_assert(sizeof(Game::Sys_File) == 4);
|
||||||
|
|
||||||
|
auto file = Game::Sys_CreateFile(dir, filename);
|
||||||
|
|
||||||
|
static const std::filesystem::path home = FileSystem::Sys_HomePath_Hk();
|
||||||
|
if (file.handle == INVALID_HANDLE_VALUE && !home.empty())
|
||||||
|
{
|
||||||
|
file.handle = Game::Sys_OpenFileReliable(Utils::String::VA("%s\\%s%s", FileSystem::Sys_HomePath_Hk(), dir, filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.handle == INVALID_HANDLE_VALUE && ZoneBuilder::IsEnabled())
|
||||||
|
{
|
||||||
|
file = Game::Sys_CreateFile("zone\\zonebuilder\\", filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
FastFiles::FastFiles()
|
FastFiles::FastFiles()
|
||||||
{
|
{
|
||||||
Dvar::Register<bool>("ui_zoneDebug", false, Game::DVAR_ARCHIVE, "Display current loaded zone.");
|
Dvar::Register<bool>("ui_zoneDebug", false, Game::DVAR_ARCHIVE, "Display current loaded zone.");
|
||||||
g_loadingInitialZones = Dvar::Register<bool>("g_loadingInitialZones", true, Game::DVAR_NONE, "Is loading initial zones");
|
g_loadingInitialZones = Dvar::Register<bool>("g_loadingInitialZones", true, Game::DVAR_NONE, "Is loading initial zones");
|
||||||
|
|
||||||
|
Utils::Hook(0x5BC832, Sys_CreateFile_Stub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
Utils::Hook(0x4CCDF0, DB_FileExists_Hk, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
// Fix XSurface assets
|
// Fix XSurface assets
|
||||||
Utils::Hook(0x0048E8A5, FastFiles::Load_XSurfaceArray, HOOK_CALL).install()->quick();
|
Utils::Hook(0x0048E8A5, FastFiles::Load_XSurfaceArray, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
@ -70,5 +70,9 @@ namespace Components
|
|||||||
|
|
||||||
static void Load_XSurfaceArray(int atStreamStart, int count);
|
static void Load_XSurfaceArray(int atStreamStart, int count);
|
||||||
|
|
||||||
|
static void DB_BuildOSPath_FromSource_Default(const char* zoneName, Game::FF_DIR source, unsigned int size, char* filename);
|
||||||
|
static void DB_BuildOSPath_FromSource_Custom(const char* zoneName, Game::FF_DIR source, unsigned int size, char* filename);
|
||||||
|
static Game::Sys_File Sys_CreateFile_Stub(const char* dir, const char* filename);
|
||||||
|
static bool DB_FileExists_Hk(const char* zoneName, Game::FF_DIR source);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ namespace Components
|
|||||||
int FileSystem::Cmd_Exec_f_Stub(const char* s0, [[maybe_unused]] const char* s1)
|
int FileSystem::Cmd_Exec_f_Stub(const char* s0, [[maybe_unused]] const char* s1)
|
||||||
{
|
{
|
||||||
int f;
|
int f;
|
||||||
auto len = Game::FS_FOpenFileByMode(s0, &f, Game::FS_READ);
|
const auto len = Game::FS_FOpenFileByMode(s0, &f, Game::FS_READ);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
{
|
{
|
||||||
return 1; // Not found
|
return 1; // Not found
|
||||||
@ -336,6 +336,39 @@ namespace Components
|
|||||||
return current_path.data();
|
return current_path.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILE* FileSystem::FS_FileOpenReadText_Hk(const char* file)
|
||||||
|
{
|
||||||
|
const auto path = Utils::GetBaseFilesLocation();
|
||||||
|
if (!path.empty() && Utils::IO::FileExists((path / file).string()))
|
||||||
|
{
|
||||||
|
return Game::FS_FileOpenReadText((path / file).string().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Game::FS_FileOpenReadText(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* FileSystem::Sys_DefaultCDPath_Hk()
|
||||||
|
{
|
||||||
|
return Sys_DefaultInstallPath_Hk();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* FileSystem::Sys_HomePath_Hk()
|
||||||
|
{
|
||||||
|
const auto path = Utils::GetBaseFilesLocation();
|
||||||
|
if (!path.empty())
|
||||||
|
{
|
||||||
|
static auto current_path = path.string();
|
||||||
|
return current_path.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* FileSystem::Sys_Cwd_Hk()
|
||||||
|
{
|
||||||
|
return Sys_DefaultInstallPath_Hk();
|
||||||
|
}
|
||||||
|
|
||||||
FileSystem::FileSystem()
|
FileSystem::FileSystem()
|
||||||
{
|
{
|
||||||
// Thread safe file system interaction
|
// Thread safe file system interaction
|
||||||
@ -383,6 +416,21 @@ namespace Components
|
|||||||
|
|
||||||
// Set the working dir based on info from the Xlabs launcher
|
// Set the working dir based on info from the Xlabs launcher
|
||||||
Utils::Hook(0x4326E0, Sys_DefaultInstallPath_Hk, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x4326E0, Sys_DefaultInstallPath_Hk, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
// Make the exe run from a folder other than the game folder
|
||||||
|
Utils::Hook(0x406D26, FS_FileOpenReadText_Hk, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
// Make the exe run from a folder other than the game folder
|
||||||
|
Utils::Hook::Nop(0x4290D8, 5); // FS_IsBasePathValid
|
||||||
|
Utils::Hook::Set<uint8_t>(0x4290DF, 0xEB);
|
||||||
|
// ^^ This check by the game above is super redundant, IW4x has other checks in place to make sure we
|
||||||
|
// are running from a properly installed directory. This only breaks the containerized patch and we don't need it
|
||||||
|
|
||||||
|
// Patch FS dvar values
|
||||||
|
Utils::Hook(0x643194, Sys_DefaultCDPath_Hk, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x643232, Sys_HomePath_Hk, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x6431B6, Sys_Cwd_Hk, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x51C29A, Sys_Cwd_Hk, HOOK_CALL).install()->quick();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystem::~FileSystem()
|
FileSystem::~FileSystem()
|
||||||
|
@ -99,6 +99,16 @@ namespace Components
|
|||||||
static std::vector<std::string> GetSysFileList(const std::string& path, const std::string& extension, bool folders = false);
|
static std::vector<std::string> GetSysFileList(const std::string& path, const std::string& extension, bool folders = false);
|
||||||
static bool _DeleteFile(const std::string& folder, const std::string& file);
|
static bool _DeleteFile(const std::string& folder, const std::string& file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The game will check in FS_Startup if homepath != default(base) path
|
||||||
|
* If they differ which will happen when IW4x is containerized it will register two brand new search paths:
|
||||||
|
* one for the container and one where the game files are. Pretty cool!
|
||||||
|
*/
|
||||||
|
static const char* Sys_DefaultInstallPath_Hk();
|
||||||
|
static const char* Sys_DefaultCDPath_Hk();
|
||||||
|
static const char* Sys_HomePath_Hk();
|
||||||
|
static const char* Sys_Cwd_Hk();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::mutex Mutex;
|
static std::mutex Mutex;
|
||||||
static std::recursive_mutex FSMutex;
|
static std::recursive_mutex FSMutex;
|
||||||
@ -122,6 +132,6 @@ namespace Components
|
|||||||
|
|
||||||
static void IwdFreeStub(Game::iwd_t* iwd);
|
static void IwdFreeStub(Game::iwd_t* iwd);
|
||||||
|
|
||||||
static const char* Sys_DefaultInstallPath_Hk();
|
static FILE* FS_FileOpenReadText_Hk(const char* file);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1115,18 +1115,6 @@ namespace Components
|
|||||||
sound->info.data_ptr = allocatedSpace;
|
sound->info.data_ptr = allocatedSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::Sys_File ZoneBuilder::Sys_CreateFile_Stub(const char* dir, const char* filename)
|
|
||||||
{
|
|
||||||
auto file = Game::Sys_CreateFile(dir, filename);
|
|
||||||
|
|
||||||
if (file.handle == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
file = Game::Sys_CreateFile("zone\\zonebuilder\\", filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
iw4of::params_t ZoneBuilder::GetExporterAPIParams()
|
iw4of::params_t ZoneBuilder::GetExporterAPIParams()
|
||||||
{
|
{
|
||||||
iw4of::params_t params{};
|
iw4of::params_t params{};
|
||||||
@ -1345,8 +1333,6 @@ namespace Components
|
|||||||
// Prevent loading textures (preserves loaddef)
|
// Prevent loading textures (preserves loaddef)
|
||||||
//Utils::Hook::Set<BYTE>(Game::Load_Texture, 0xC3);
|
//Utils::Hook::Set<BYTE>(Game::Load_Texture, 0xC3);
|
||||||
|
|
||||||
Utils::Hook(0x5BC832, Sys_CreateFile_Stub, HOOK_CALL).install()->quick();
|
|
||||||
|
|
||||||
// Store the loaddef
|
// Store the loaddef
|
||||||
Utils::Hook(Game::Load_Texture, StoreTexture, HOOK_JUMP).install()->quick();
|
Utils::Hook(Game::Load_Texture, StoreTexture, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ namespace Game
|
|||||||
FS_FOpenFileAppend_t FS_FOpenFileAppend = FS_FOpenFileAppend_t(0x410BB0);
|
FS_FOpenFileAppend_t FS_FOpenFileAppend = FS_FOpenFileAppend_t(0x410BB0);
|
||||||
FS_FOpenFileWrite_t FS_FOpenFileWrite = FS_FOpenFileWrite_t(0x4BA530);
|
FS_FOpenFileWrite_t FS_FOpenFileWrite = FS_FOpenFileWrite_t(0x4BA530);
|
||||||
FS_FOpenTextFileWrite_t FS_FOpenTextFileWrite = FS_FOpenTextFileWrite_t(0x43FD90);
|
FS_FOpenTextFileWrite_t FS_FOpenTextFileWrite = FS_FOpenTextFileWrite_t(0x43FD90);
|
||||||
|
FS_FileOpenReadText_t FS_FileOpenReadText = FS_FileOpenReadText_t(0x446B60);
|
||||||
FS_FOpenFileRead_t FS_FOpenFileRead = FS_FOpenFileRead_t(0x46CBF0);
|
FS_FOpenFileRead_t FS_FOpenFileRead = FS_FOpenFileRead_t(0x46CBF0);
|
||||||
FS_FOpenFileReadDatabase_t FS_FOpenFileReadDatabase = FS_FOpenFileReadDatabase_t(0x42ECA0);
|
FS_FOpenFileReadDatabase_t FS_FOpenFileReadDatabase = FS_FOpenFileReadDatabase_t(0x42ECA0);
|
||||||
FS_FOpenFileReadForThread_t FS_FOpenFileReadForThread = FS_FOpenFileReadForThread_t(0x643270);
|
FS_FOpenFileReadForThread_t FS_FOpenFileReadForThread = FS_FOpenFileReadForThread_t(0x643270);
|
||||||
|
@ -26,6 +26,9 @@ namespace Game
|
|||||||
typedef int(*FS_FOpenFileRead_t)(const char* filename, int* file);
|
typedef int(*FS_FOpenFileRead_t)(const char* filename, int* file);
|
||||||
extern FS_FOpenFileRead_t FS_FOpenFileRead;
|
extern FS_FOpenFileRead_t FS_FOpenFileRead;
|
||||||
|
|
||||||
|
typedef FILE*(*FS_FileOpenReadText_t)(const char* filename);
|
||||||
|
extern FS_FileOpenReadText_t FS_FileOpenReadText;
|
||||||
|
|
||||||
typedef int(*FS_FOpenFileReadDatabase_t)(const char* filename, int* file);
|
typedef int(*FS_FOpenFileReadDatabase_t)(const char* filename, int* file);
|
||||||
extern FS_FOpenFileReadDatabase_t FS_FOpenFileReadDatabase;
|
extern FS_FOpenFileReadDatabase_t FS_FOpenFileReadDatabase;
|
||||||
|
|
||||||
|
@ -11079,6 +11079,13 @@ namespace Game
|
|||||||
huff_t compressDecompress;
|
huff_t compressDecompress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum FF_DIR
|
||||||
|
{
|
||||||
|
FFD_DEFAULT = 0x0,
|
||||||
|
FFD_MOD_DIR = 0x1,
|
||||||
|
FFD_USER_MAP = 0x2,
|
||||||
|
};
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#ifndef IDA
|
#ifndef IDA
|
||||||
|
@ -56,4 +56,10 @@ namespace Game
|
|||||||
|
|
||||||
return TryEnterCriticalSection(&s_criticalSection[critSect]) != FALSE;
|
return TryEnterCriticalSection(&s_criticalSection[critSect]) != FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HANDLE Sys_OpenFileReliable(const char* filename)
|
||||||
|
{
|
||||||
|
return CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
|
||||||
|
FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,8 @@ namespace Game
|
|||||||
|
|
||||||
extern bool Sys_TryEnterCriticalSection(CriticalSection critSect);
|
extern bool Sys_TryEnterCriticalSection(CriticalSection critSect);
|
||||||
|
|
||||||
|
extern HANDLE Sys_OpenFileReliable(const char* filename);
|
||||||
|
|
||||||
class Sys
|
class Sys
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -25,8 +25,10 @@ namespace Utils
|
|||||||
|
|
||||||
void OutputDebugLastError()
|
void OutputDebugLastError()
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
DWORD errorMessageID = ::GetLastError();
|
DWORD errorMessageID = ::GetLastError();
|
||||||
OutputDebugStringA(Utils::String::VA("Last error code: 0x%08X (%s)\n", errorMessageID, GetLastWindowsError().data()));
|
OutputDebugStringA(String::VA("Last error code: 0x%08X (%s)\n", errorMessageID, GetLastWindowsError().data()));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetLastWindowsError()
|
std::string GetLastWindowsError()
|
||||||
@ -85,8 +87,7 @@ namespace Utils
|
|||||||
if (!ntdll) return nullptr;
|
if (!ntdll) return nullptr;
|
||||||
|
|
||||||
|
|
||||||
static uint8_t ntQueryInformationThread[] = { 0xB1, 0x8B, 0xAE, 0x8A, 0x9A, 0x8D, 0x86, 0xB6, 0x91, 0x99, 0x90, 0x8D, 0x92, 0x9E, 0x8B, 0x96, 0x90, 0x91, 0xAB, 0x97, 0x8D, 0x9A, 0x9E, 0x9B }; // NtQueryInformationThread
|
NtQueryInformationThread_t NtQueryInformationThread = NtQueryInformationThread_t(GetProcAddress(ntdll, "NtQueryInformationThread"));
|
||||||
NtQueryInformationThread_t NtQueryInformationThread = NtQueryInformationThread_t(GetProcAddress(ntdll, String::XOR(std::string(reinterpret_cast<char*>(ntQueryInformationThread), sizeof ntQueryInformationThread), -1).data()));
|
|
||||||
if (!NtQueryInformationThread) return nullptr;
|
if (!NtQueryInformationThread) return nullptr;
|
||||||
|
|
||||||
HANDLE dupHandle, currentProcess = GetCurrentProcess();
|
HANDLE dupHandle, currentProcess = GetCurrentProcess();
|
||||||
@ -116,11 +117,15 @@ namespace Utils
|
|||||||
SetCurrentDirectoryW(binaryPath);
|
SetCurrentDirectoryW(binaryPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IW4x_INSTALL should point to where the IW4x rawfiles/client files are
|
||||||
|
* or the current working dir
|
||||||
|
*/
|
||||||
void SetEnvironment()
|
void SetEnvironment()
|
||||||
{
|
{
|
||||||
char* buffer{};
|
char* buffer{};
|
||||||
std::size_t size{};
|
std::size_t size{};
|
||||||
if (_dupenv_s(&buffer, &size, "MW2_INSTALL") != 0 || buffer == nullptr)
|
if (_dupenv_s(&buffer, &size, "IW4x_INSTALL") != 0 || buffer == nullptr)
|
||||||
{
|
{
|
||||||
SetLegacyEnvironment();
|
SetLegacyEnvironment();
|
||||||
return;
|
return;
|
||||||
@ -132,10 +137,35 @@ namespace Utils
|
|||||||
SetDllDirectoryA(buffer);
|
SetDllDirectoryA(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points to where the Modern Warfare 2 folder is
|
||||||
|
*/
|
||||||
|
std::filesystem::path GetBaseFilesLocation()
|
||||||
|
{
|
||||||
|
char* buffer{};
|
||||||
|
std::size_t size{};
|
||||||
|
if (_dupenv_s(&buffer, &size, "BASE_INSTALL") != 0 || buffer == nullptr)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto _0 = gsl::finally([&] { std::free(buffer); });
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::filesystem::path result = buffer;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
printf("Failed to convert '%s' to native file system path. Got error '%s'\n", buffer, ex.what());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HMODULE GetNTDLL()
|
HMODULE GetNTDLL()
|
||||||
{
|
{
|
||||||
static uint8_t ntdll[] = { 0x91, 0x8B, 0x9B, 0x93, 0x93, 0xD1, 0x9B, 0x93, 0x93 }; // ntdll.dll
|
return GetModuleHandleA("ntdll.dll");
|
||||||
return GetModuleHandleA(Utils::String::XOR(std::string(reinterpret_cast<char*>(ntdll), sizeof ntdll), -1).data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SafeShellExecute(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd)
|
void SafeShellExecute(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd)
|
||||||
|
@ -20,6 +20,7 @@ namespace Utils
|
|||||||
HMODULE GetNTDLL();
|
HMODULE GetNTDLL();
|
||||||
|
|
||||||
void SetEnvironment();
|
void SetEnvironment();
|
||||||
|
std::filesystem::path GetBaseFilesLocation();
|
||||||
|
|
||||||
void OpenUrl(const std::string& url);
|
void OpenUrl(const std::string& url);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user