Add DSCRemote
This commit is contained in:
@@ -23,6 +23,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShaderPatch", "source\plugi
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DivaWig", "source\plugins\DivaWig\DivaWig.vcxproj", "{2394C586-F73B-4EF2-BA3E-2A0FC3034B1A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DSCRemote", "source\plugins\DSCRemote\DSCRemote.vcxproj", "{8544C599-F73B-4EF2-BA3E-2A0FC3034B1A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -69,6 +71,10 @@ Global
|
||||
{2394C586-F73B-4EF2-BA3E-2A0FC3034B1A}.Debug|x64.Build.0 = Debug|x64
|
||||
{2394C586-F73B-4EF2-BA3E-2A0FC3034B1A}.Release|x64.ActiveCfg = Release|x64
|
||||
{2394C586-F73B-4EF2-BA3E-2A0FC3034B1A}.Release|x64.Build.0 = Release|x64
|
||||
{8544C599-F73B-4EF2-BA3E-2A0FC3034B1A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8544C599-F73B-4EF2-BA3E-2A0FC3034B1A}.Debug|x64.Build.0 = Debug|x64
|
||||
{8544C599-F73B-4EF2-BA3E-2A0FC3034B1A}.Release|x64.ActiveCfg = Release|x64
|
||||
{8544C599-F73B-4EF2-BA3E-2A0FC3034B1A}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -102,3 +102,4 @@ r.Height=1080
|
||||
|
||||
[plugins]
|
||||
DivaWig.dva=0
|
||||
DSCRemote.dva=0
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<?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>
|
||||
<ProjectGuid>{8544C599-F73B-4EF2-BA3E-2A0FC3034B1A}</ProjectGuid>
|
||||
<RootNamespace>DSCRemote</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>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</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'">
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\dependencies\detours\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>-d2FH4- %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>detours.lib;evr.lib;mfplat.lib;mfuuid.lib;strmiids.lib;syelog.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>-d2:-FH4- %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\dependencies\detours\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalOptions>-d2FH4- %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>detours.lib;evr.lib;mfplat.lib;mfuuid.lib;syelog.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>-d2:-FH4- %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="PluginConfigApi.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="PluginConfigApi.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,168 @@
|
||||
#pragma once
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
|
||||
// resolution class to store and sort the width and height easily
|
||||
class resolution
|
||||
{
|
||||
public:
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
|
||||
resolution()
|
||||
{
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
|
||||
resolution(unsigned int width, unsigned int height)
|
||||
{
|
||||
resolution::width = width;
|
||||
resolution::height = height;
|
||||
}
|
||||
|
||||
bool operator ==(const resolution &res2)
|
||||
{
|
||||
return width == res2.width && height == res2.height;
|
||||
}
|
||||
|
||||
// in comparisons width takes priority because it's usually displayed first
|
||||
bool operator <(const resolution &res2)
|
||||
{
|
||||
if (width == res2.width)
|
||||
return height < res2.height;
|
||||
else
|
||||
return width < res2.width;
|
||||
}
|
||||
bool operator >(const resolution &res2)
|
||||
{
|
||||
if (width == res2.width)
|
||||
return height > res2.height;
|
||||
else
|
||||
return width > res2.width;
|
||||
}
|
||||
};
|
||||
|
||||
namespace PluginConfig
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
enum ConfigType {
|
||||
CONFIG_BOOLEAN,
|
||||
CONFIG_NUMERIC,
|
||||
CONFIG_STRING,
|
||||
CONFIG_DROPDOWN_INDEX,
|
||||
CONFIG_DROPDOWN_TEXT,
|
||||
CONFIG_DROPDOWN_NUMBER,
|
||||
CONFIG_RESOLUTION,
|
||||
CONFIG_GROUP_START,
|
||||
CONFIG_GROUP_END,
|
||||
CONFIG_BUTTON,
|
||||
CONFIG_SPACER
|
||||
};
|
||||
|
||||
struct PluginConfigBooleanData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
bool defaultVal;
|
||||
bool saveAsString;
|
||||
};
|
||||
|
||||
struct PluginConfigNumericData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
int defaultVal;
|
||||
int minVal;
|
||||
int maxVal;
|
||||
};
|
||||
|
||||
struct PluginConfigStringData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
LPCWSTR defaultVal;
|
||||
bool useUtf8;
|
||||
};
|
||||
|
||||
struct PluginConfigDropdownIndexData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
int defaultVal;
|
||||
std::vector<LPCWSTR> valueStrings;
|
||||
};
|
||||
|
||||
struct PluginConfigDropdownTextData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
LPCWSTR defaultVal;
|
||||
std::vector<LPCWSTR> valueStrings;
|
||||
bool editable;
|
||||
bool useUtf8;
|
||||
};
|
||||
|
||||
struct PluginConfigDropdownNumberData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
int defaultVal;
|
||||
std::vector<int> valueInts;
|
||||
bool editable;
|
||||
};
|
||||
|
||||
struct PluginConfigResolutionData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniVarName2;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
resolution defaultVal;
|
||||
std::vector<resolution> valueResolutions;
|
||||
bool editable;
|
||||
};
|
||||
|
||||
struct PluginConfigGroupData
|
||||
{
|
||||
LPCWSTR name;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct PluginConfigButtonData {
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
void(*func)();
|
||||
};
|
||||
|
||||
struct PluginConfigSpacerData {
|
||||
int height;
|
||||
};
|
||||
|
||||
struct PluginConfigOption
|
||||
{
|
||||
ConfigType cfgType;
|
||||
void* data;
|
||||
};
|
||||
|
||||
struct PluginConfigArray
|
||||
{
|
||||
int len;
|
||||
PluginConfigOption* options;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
#include <WinSock2.h>
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
#include <detours.h>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include "framework.h"
|
||||
#include "PluginConfigApi.h"
|
||||
#include <iostream>
|
||||
|
||||
bool(__cdecl* DSC_EXECUTE_COMMAND)(__int64 dsc_address, float delta_time, __int64 start_time, void* wait_timer, int* a5, int a6, int a7)
|
||||
= (bool(__cdecl*)(__int64 dsc_address, float delta_time, __int64 start_time, void* wait_timer, int* a5, int a6, int a7))
|
||||
0x14011CBA0;
|
||||
bool hookedDSC_EXECUTE_COMMAND(__int64 dsc_address, float delta_time, __int64 start_time, void* wait_timer, int* a5, int a6, int a7);
|
||||
void serve();
|
||||
|
||||
bool debug = false;
|
||||
unsigned short port = 8139;
|
||||
|
||||
void loadConfig()
|
||||
{
|
||||
port = GetPrivateProfileIntW(L"general", L"port", 8139, CONFIG_FILE);
|
||||
debug = GetPrivateProfileIntW(L"general", L"debug", 0, CONFIG_FILE) > 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float last_delta_time = 0.0;
|
||||
__int64 last_start_time = 0i64;
|
||||
void* last_wait_timer = nullptr;
|
||||
int* last_a5 = nullptr;
|
||||
int last_a6 = 0;
|
||||
int last_a7 = 0;
|
||||
|
||||
bool hookedDSC_EXECUTE_COMMAND(__int64 dsc_address, float delta_time, __int64 start_time, void* wait_timer, int* a5, int a6, int a7)
|
||||
{
|
||||
last_delta_time = delta_time;
|
||||
last_start_time = start_time;
|
||||
last_wait_timer = wait_timer;
|
||||
last_a5 = a5;
|
||||
last_a6 = a6;
|
||||
last_a7 = a7;
|
||||
|
||||
return DSC_EXECUTE_COMMAND(dsc_address, delta_time, start_time, wait_timer, a5, a6, a7);
|
||||
}
|
||||
|
||||
void serve()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
cout << "[DSCRemote] Staring server..." << endl;
|
||||
|
||||
WSADATA wsadata;
|
||||
int result = WSAStartup(MAKEWORD(2, 2), &wsadata);
|
||||
if (result) // error
|
||||
{
|
||||
cout << "[DSCRemote] E: WSAStartup error " << result << '.' << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
SOCKET sock;
|
||||
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
if (result == INVALID_SOCKET)
|
||||
{
|
||||
cout << "[DSCRemote] E: Invalid socket." << endl;
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
sockaddr_in saddrin;
|
||||
saddrin.sin_family = AF_INET;
|
||||
saddrin.sin_addr.s_addr = 0;
|
||||
saddrin.sin_port = htons(port);
|
||||
|
||||
result = bind(sock, (sockaddr*)&saddrin, sizeof(sockaddr_in));
|
||||
if (result) // error
|
||||
{
|
||||
cout << "[DSCRemote] E: Couldn't bind port " << port << '.' << endl;
|
||||
closesocket(sock);
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
result = listen(sock, 1);
|
||||
if (result) // error
|
||||
{
|
||||
cout << "[DSCRemote] E: Couldn't listen." << endl;
|
||||
closesocket(sock);
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
cout << "[DSCRemote] Waiting for client..." << endl;
|
||||
SOCKET client_sock;
|
||||
client_sock = accept(sock, NULL, NULL);
|
||||
cout << "[DSCRemote] Client accepted." << endl;
|
||||
|
||||
char buff_recv[64];
|
||||
vector<int> cmdStack;
|
||||
do
|
||||
{
|
||||
result = recv(client_sock, buff_recv, sizeof(buff_recv), 0);
|
||||
if (result > 0)
|
||||
{
|
||||
if (debug) cout << "[DSCRemote] D: Received: " << buff_recv << endl;
|
||||
if (buff_recv[0] != 'i')
|
||||
{
|
||||
long stack = stol(buff_recv);
|
||||
for (int i = 0; i < sizeof(buff_recv); i++) buff_recv[i] = '\0';
|
||||
cmdStack.push_back(stack);
|
||||
const char buff_out[] = "Stacking command/parameter. Send 'i' to inject.";
|
||||
send(client_sock, buff_out, sizeof(buff_out), 0);
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < sizeof(buff_recv); i++) buff_recv[i] = '\0';
|
||||
|
||||
const char buff_out[] = "Injecting stack.";
|
||||
send(client_sock, buff_out, sizeof(buff_out), 0);
|
||||
|
||||
const int64_t dscbaseaddr = 0x140CDD978i64;
|
||||
int* currentpos = (int*)(dscbaseaddr + 0x2bf2c);
|
||||
int* command = (int*)(dscbaseaddr + 0xc);
|
||||
|
||||
int posbk = *currentpos;
|
||||
vector<int> cmdbk;
|
||||
for (int i=0; i<cmdStack.size(); i++)
|
||||
cmdbk.push_back(command[i]);
|
||||
|
||||
*currentpos = 0;
|
||||
|
||||
for (int i = 0; i < cmdStack.size(); i++)
|
||||
{
|
||||
if (debug) cout << "[DSCRemote] D: Injecting " << cmdStack.at(i) << endl;
|
||||
command[i] = cmdStack.at(i);
|
||||
}
|
||||
|
||||
cmdStack.clear();
|
||||
|
||||
DSC_EXECUTE_COMMAND(dscbaseaddr, last_delta_time, last_start_time, last_wait_timer, last_a5, last_a6, last_a7);
|
||||
|
||||
for (int i = 0; i < cmdbk.size(); i++)
|
||||
{
|
||||
if (debug) cout << "[DSCRemote] D: Restoring " << cmdbk.at(i) << endl;
|
||||
command[i] = cmdbk.at(i);
|
||||
}
|
||||
|
||||
cmdbk.clear();
|
||||
*currentpos = posbk;
|
||||
}
|
||||
} while (result > 0);
|
||||
closesocket(client_sock);
|
||||
cout << "[DSCRemote] Restarting..." << endl;
|
||||
}
|
||||
|
||||
cout << "[DSCRemote] Bye!" << endl;
|
||||
closesocket(sock);
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
|
||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
loadConfig();
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
cout << "[DSCRemote] Hooking functions..." << endl;
|
||||
DetourAttach(&(PVOID&)DSC_EXECUTE_COMMAND, (PVOID)hookedDSC_EXECUTE_COMMAND);
|
||||
cout << "[DSCRemote] Functions hooked." << endl;
|
||||
DetourTransactionCommit();
|
||||
|
||||
thread* server_thread = new thread(serve);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PluginConfig::PluginConfigOption config[] = {
|
||||
{ PluginConfig::CONFIG_NUMERIC, new PluginConfig::PluginConfigNumericData{ L"port", L"general", CONFIG_FILE, L"Port", L"TCP/IP port.", 8139, 1, USHRT_MAX } },
|
||||
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"debug", L"general", CONFIG_FILE, L"Debug", L"Print extra information.", false } },
|
||||
};
|
||||
|
||||
extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void)
|
||||
{
|
||||
return L"DSCRemote";
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void)
|
||||
{
|
||||
return L"Allows external applications to send DSC commands via TCP/IP.";
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) PluginConfig::PluginConfigArray GetPluginOptions(void)
|
||||
{
|
||||
return PluginConfig::PluginConfigArray{ _countof(config), config };
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
std::wstring ExePath() {
|
||||
WCHAR buffer[MAX_PATH];
|
||||
GetModuleFileNameW(NULL, buffer, MAX_PATH);
|
||||
return std::wstring(buffer);
|
||||
}
|
||||
|
||||
std::wstring DirPath() {
|
||||
std::wstring exepath = ExePath();
|
||||
std::wstring::size_type pos = exepath.find_last_of(L"\\/");
|
||||
return exepath.substr(0, pos);
|
||||
}
|
||||
|
||||
std::wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\DSCRemote.ini";
|
||||
LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str();
|
||||
Reference in New Issue
Block a user