Skip to content

Commit 48078ec

Browse files
authored
Merge pull request #1 from SAM1430B/WIP
Fix issues and add x64 version
2 parents 8bfc831 + 2365c4c commit 48078ec

4 files changed

Lines changed: 113 additions & 22 deletions

File tree

WinSplitPlusApp/WinSplitPlus.vcxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
7878
<LinkIncremental>true</LinkIncremental>
7979
<OutDir>$(SolutionDir)\Bin\$(Platform)\$(Configuration)\</OutDir>
80+
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
8081
</PropertyGroup>
8182
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
8283
<LinkIncremental>false</LinkIncremental>
@@ -85,6 +86,7 @@
8586
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
8687
<LinkIncremental>false</LinkIncremental>
8788
<OutDir>$(SolutionDir)\Bin\$(Platform)\$(Configuration)\</OutDir>
89+
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
8890
</PropertyGroup>
8991
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
9092
<ClCompile>
@@ -170,6 +172,10 @@ copy "$(ProjectDir)Examples\BatFileExample.txt" "$(TargetDir)"</Command>
170172
<AdditionalLibraryDirectories>$(SolutionDir)lib\EasyHook;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
171173
<AdditionalDependencies>EasyHook64.lib;%(AdditionalDependencies)</AdditionalDependencies>
172174
</Link>
175+
<PostBuildEvent>
176+
<Command>copy "$(SolutionDir)lib\EasyHook\EasyHook64.dll" "$(TargetDir)"
177+
copy "$(ProjectDir)Examples\BatFileExample.txt" "$(TargetDir)"</Command>
178+
</PostBuildEvent>
173179
</ItemDefinitionGroup>
174180
<ItemGroup>
175181
<ClCompile Include="PlayerInfo.cpp" />

WinSplitPlusApp/main.cpp

Lines changed: 99 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ int wmain(int argc, wchar_t* argv[])
4747
std::wstring gameArgs;
4848
std::wstring baseMutexName;
4949
int playerNumber = 1;
50+
bool changeWindowName = false;
5051

5152
if (argc < 2) {
5253
print_usage();
@@ -72,10 +73,11 @@ int wmain(int argc, wchar_t* argv[])
7273
}
7374
}
7475
else if (lower_arg == L"-winclass") {
75-
injectionInfo.injectionFlags = injectionInfo.injectionFlags | InjectionFlags::HOOK_WND_PROC;
76+
injectionInfo.injectionFlags = injectionInfo.injectionFlags | InjectionFlags::HOOK_WND_PROC | InjectionFlags::HOOK_CREATE_WINDOW;
7677
}
7778
else if (lower_arg == L"-winname") {
7879
injectionInfo.injectionFlags = injectionInfo.injectionFlags | InjectionFlags::HOOK_CREATE_WINDOW;
80+
changeWindowName = true;
7981
}
8082
else if (lower_arg == L"-mutex" && i + 1 < argc) {
8183
injectionInfo.injectionFlags = injectionInfo.injectionFlags | InjectionFlags::HOOK_CREATE_MUTEX;
@@ -120,7 +122,7 @@ int wmain(int argc, wchar_t* argv[])
120122
wcscpy_s(injectionInfo.windowClassName, CLASS_NAME_MAX_LENGTH, finalClassName.c_str());
121123
}
122124

123-
if ((injectionInfo.injectionFlags & InjectionFlags::HOOK_CREATE_WINDOW) == InjectionFlags::HOOK_CREATE_WINDOW) {
125+
if (changeWindowName) {
124126
std::wstring finalWindowName = L"WinSplitPlus " + std::to_wstring(playerNumber);
125127
wcscpy_s(injectionInfo.windowName, WINDOW_NAME_MAX_LENGTH, finalWindowName.c_str());
126128
}
@@ -136,30 +138,109 @@ int wmain(int argc, wchar_t* argv[])
136138
wcscpy_s(injectionInfo.mutexNewName, MUTEX_NAME_MAX_LENGTH, finalMutexName.c_str());
137139
}
138140

139-
if (injectionInfo.windowSizeX > 0 || injectionInfo.windowSizeY > 0 || injectionInfo.windowPosX > 0 || injectionInfo.windowPosY > 0) {
140-
injectionInfo.injectionFlags = injectionInfo.injectionFlags | InjectionFlags::HOOK_SET_WINDOW_POS;
141+
// Inject the DLL
142+
WCHAR exePath[MAX_PATH];
143+
GetModuleFileName(NULL, exePath, MAX_PATH);
144+
std::wstring exeDir = exePath;
145+
size_t lastSlash = exeDir.find_last_of(L"\\/");
146+
if (lastSlash != std::wstring::npos) {
147+
exeDir = exeDir.substr(0, lastSlash);
148+
}
149+
std::wstring pluginsDir = exeDir + L"\\plugins\\";
150+
151+
std::vector<std::wstring> dllsToInject;
152+
std::wstring searchPath = pluginsDir + L"*.dll";
153+
WIN32_FIND_DATA wfd;
154+
HANDLE hFind = FindFirstFile(searchPath.c_str(), &wfd);
155+
156+
if (hFind != INVALID_HANDLE_VALUE) {
157+
do {
158+
std::wstring dllName = wfd.cFileName;
159+
dllsToInject.push_back(pluginsDir + dllName);
160+
} while (FindNextFile(hFind, &wfd));
161+
FindClose(hFind);
141162
}
142163

143-
// Inject the DLL
144-
WCHAR dllToInject[] = L"WinSplitPlusIJ.dll";
145-
DWORD processId = 0;
164+
// 3. Check if we found any DLLs
165+
if (dllsToInject.empty()) {
166+
Sleep(7000);
167+
std::wcerr << L"Error: No .dll files found in " << pluginsDir << std::endl;
168+
std::wcerr << L"Please ensure a 'plugins' folder exists next to WinSplitPlus.exe and contains your hook DLLs." << std::endl;
169+
//system("pause");
170+
return 1;
171+
}
146172

147-
std::wcout << L"Launching game: " << gamePath << std::endl;
148-
std::wcout << L"Injecting with settings for Player " << playerNumber << L"..." << std::endl;
173+
std::wcout << L"Found " << dllsToInject.size() << L" plugin(s) to inject from " << pluginsDir << std::endl;
174+
for (const auto& dll : dllsToInject) {
175+
std::wcout << L" - " << dll << std::endl;
176+
}
177+
178+
// Suspended state is needed for Window hooks
179+
PROCESS_INFORMATION pi = {};
180+
STARTUPINFOW si = {};
181+
si.cb = sizeof(si);
182+
183+
std::wstring fullCommandLine = L"\"" + gamePath + L"\" " + gameArgs;
149184

150-
NTSTATUS nt = RhCreateAndInject(
151-
const_cast<wchar_t*>(gamePath.c_str()),
152-
gameArgs.empty() ? NULL : const_cast<wchar_t*>(gameArgs.c_str()),
153-
0, EASYHOOK_INJECT_DEFAULT, dllToInject, NULL,
154-
&injectionInfo, sizeof(InjectionInfo), &processId
155-
);
185+
std::wcout << L"Launching game suspended: " << gamePath << std::endl;
186+
std::wcout << L"Injecting with settings for Player " << playerNumber << L"..." << std::endl;
156187

157-
if (nt != 0) {
158-
std::wcerr << L"Failed to inject DLL: " << RtlGetLastErrorString() << std::endl;
159-
Sleep(5000);
188+
if (!CreateProcess(
189+
NULL,
190+
const_cast<wchar_t*>(fullCommandLine.c_str()), // Command line
191+
NULL,
192+
NULL,
193+
FALSE,
194+
CREATE_SUSPENDED,
195+
NULL,
196+
NULL,
197+
&si, // StartupInfo
198+
&pi // ProcessInfo
199+
)) {
200+
Sleep(7000);
201+
std::wcerr << L"Failed to create process: " << GetLastError() << std::endl;
202+
std::wcerr << L"Command: " << fullCommandLine << std::endl;
203+
//system("pause");
160204
return 1;
161205
}
162206

207+
DWORD processId = pi.dwProcessId;
208+
bool allInjectionsSucceeded = true;
209+
210+
for (const auto& dllPath : dllsToInject) {
211+
std::wcout << L"Injecting " << dllPath.substr(dllPath.find_last_of(L"\\/") + 1) << L" into process " << processId << L"..." << std::endl;
212+
213+
NTSTATUS nt = RhInjectLibrary(
214+
processId,
215+
0,
216+
EASYHOOK_INJECT_DEFAULT,
217+
const_cast<wchar_t*>(dllPath.c_str()),
218+
const_cast<wchar_t*>(dllPath.c_str()),
219+
&injectionInfo,
220+
sizeof(InjectionInfo)
221+
);
222+
223+
if (nt != 0) {
224+
std::wcerr << L"Failed to inject DLL " << dllPath << L": " << RtlGetLastErrorString() << std::endl;
225+
allInjectionsSucceeded = false;
226+
// We can choose to stop or continue; let's continue
227+
}
228+
}
229+
230+
if (!allInjectionsSucceeded) {
231+
Sleep(3000);
232+
std::wcerr << L"Warning: One or more DLLs failed to inject. Attempting to resume process anyway." << std::endl;
233+
}
234+
else {
235+
std::wcout << L"All injections successful." << std::endl;
236+
}
237+
238+
std::wcout << L"Resuming game process..." << std::endl;
239+
ResumeThread(pi.hThread);
240+
241+
CloseHandle(pi.hProcess);
242+
CloseHandle(pi.hThread);
243+
163244
std::wcout << L"Successfully launched and injected into process " << processId << L". The launcher will now exit." << std::endl;
164245

165246
return 0;

WinSplitPlusIJ/WinSplitPlusIJ.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,17 @@ HWND WINAPI CreateWindowExAHook(
108108
if (gInjectionInfo.windowClassName[0] != L'\0')
109109
{
110110
static char ansiClassName[CLASS_NAME_MAX_LENGTH];
111-
size_t convertedCount;
112-
wcstombs_s(&convertedCount, ansiClassName, CLASS_NAME_MAX_LENGTH, gInjectionInfo.windowClassName, CLASS_NAME_MAX_LENGTH);
111+
//size_t convertedCount;
112+
wcstombs_s(nullptr, ansiClassName, CLASS_NAME_MAX_LENGTH, gInjectionInfo.windowClassName, _TRUNCATE);
113113
finalClassName = ansiClassName;
114114
}
115115

116116
LPCSTR finalWindowName = lpWindowName;
117117
if (gInjectionInfo.windowName[0] != L'\0')
118118
{
119119
static char ansiWindowName[WINDOW_NAME_MAX_LENGTH];
120-
size_t convertedCount;
121-
wcstombs_s(&convertedCount, ansiWindowName, WINDOW_NAME_MAX_LENGTH, gInjectionInfo.windowName, WINDOW_NAME_MAX_LENGTH);
120+
//size_t convertedCount;
121+
wcstombs_s(nullptr, ansiWindowName, WINDOW_NAME_MAX_LENGTH, gInjectionInfo.windowName, _TRUNCATE);
122122
finalWindowName = ansiWindowName;
123123
}
124124

WinSplitPlusIJ/WinSplitPlusIJ.vcxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,23 @@
7373
<LinkIncremental>true</LinkIncremental>
7474
<IncludePath>$(IncludePath)</IncludePath>
7575
<OutDir>$(SolutionDir)\Bin\$(Platform)\$(Configuration)\</OutDir>
76+
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
7677
</PropertyGroup>
7778
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
7879
<LinkIncremental>true</LinkIncremental>
7980
<OutDir>$(SolutionDir)\Bin\$(Platform)\$(Configuration)\</OutDir>
81+
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
8082
</PropertyGroup>
8183
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
8284
<LinkIncremental>false</LinkIncremental>
8385
<IncludePath>$(IncludePath)</IncludePath>
8486
<OutDir>$(SolutionDir)\Bin\$(Platform)\$(Configuration)\</OutDir>
87+
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
8588
</PropertyGroup>
8689
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
8790
<LinkIncremental>false</LinkIncremental>
8891
<OutDir>$(SolutionDir)\Bin\$(Platform)\$(Configuration)\</OutDir>
92+
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
8993
</PropertyGroup>
9094
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
9195
<ClCompile>

0 commit comments

Comments
 (0)