Skip to content

Commit eceb3d1

Browse files
committed
Move game argument parsing to WinMain level
Separate Syringe arguments from target game arguments at the earliest stage by splitting on `--` delimiter in `GetArguments()`. This prevents the shell argument parser from interpreting game arguments, allowing them to be passed through as-is to the target process. Changes: - Add `Arguments` struct containing both Syringe and game arguments - Split command line on ` -- ` in `GetArguments()` before parsing - Remove `--` delimiter handling from `parse_command_line()` - Remove `game_arguments` field from `argument_set` struct - Convert game arguments directly from wide string to UTF-8 - Preserve exact game argument formatting without shell interpretation Signed-off-by: 舰队的偶像-岛风酱 <frg2089@outlook.com>
1 parent 83e3ec6 commit eceb3d1

2 files changed

Lines changed: 38 additions & 31 deletions

File tree

Main.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,29 @@
88
#include <commctrl.h>
99
#include <shellapi.h>
1010

11-
std::vector<std::string> GetArguments()
11+
struct Arguments {
12+
std::vector<std::string> syringe_args;
13+
std::string game_args;
14+
};
15+
16+
Arguments GetArguments()
1217
{
18+
std::wstring wszSyringeArgs;
19+
std::wstring wszGameArgs;
20+
std::wstring lpCmdLine = GetCommandLineW();
21+
auto separator = lpCmdLine.find(L" -- ");
22+
if (separator == std::wstring::npos) {
23+
wszSyringeArgs = lpCmdLine.substr(0, separator);
24+
wszGameArgs = lpCmdLine.substr(separator + 4);
25+
}
26+
else {
27+
wszSyringeArgs = lpCmdLine;
28+
wszGameArgs = L"";
29+
}
30+
1331
// Get argc, argv in wide chars
1432
int argc = 0;
15-
LPWSTR* argvW = CommandLineToArgvW(GetCommandLineW(), &argc);
33+
LPWSTR* argvW = CommandLineToArgvW(wszSyringeArgs.c_str(), &argc);
1634

1735
// Convert to UTF-8. Skip the first argument as it contains the path to Syringe itself
1836
std::vector<std::string> argv(argc - 1);
@@ -25,10 +43,18 @@ std::vector<std::string> GetArguments()
2543

2644
LocalFree(argvW);
2745

28-
return argv;
46+
47+
int len = WideCharToMultiByte(CP_UTF8, 0, wszGameArgs.c_str(), -1, nullptr, 0, nullptr, nullptr);
48+
std::string gameArgs = std::string(len - 1, '\0');
49+
WideCharToMultiByte(CP_UTF8, 0, wszGameArgs.c_str(), -1, gameArgs.data(), len, nullptr, nullptr);
50+
51+
return {
52+
argv,
53+
gameArgs,
54+
};
2955
}
3056

31-
int Run(const std::vector<std::string>& arguments)
57+
int Run(const Arguments& arguments)
3258
{
3359
constexpr auto const VersionString = "SyringeEx " SYRINGEEX_VER_TEXT ", based on Syringe 0.7.2.0";
3460

@@ -39,14 +65,14 @@ int Run(const std::vector<std::string>& arguments)
3965
Log::WriteLine(VersionString);
4066
Log::WriteLine("===============");
4167
Log::WriteLine();
42-
Log::WriteLine("WinMain: arguments = \"%.*s\"", printable(arguments));
68+
Log::WriteLine("WinMain: arguments = \"%.*s\"", printable(arguments.syringe_args));
4369

4470
auto failure = "Could not load executable.";
4571
auto exit_code = ERROR_ERRORS_ENCOUNTERED;
4672

4773
try
4874
{
49-
auto const command = parse_command_line(arguments);
75+
auto const command = parse_command_line(arguments.syringe_args);
5076

5177
Log::WriteLine(
5278
"WinMain: Trying to load executable file \"%.*s\"...",
@@ -62,10 +88,10 @@ int Run(const std::vector<std::string>& arguments)
6288

6389
Log::WriteLine(
6490
"WinMain: SyringeDebugger::Run(\"%.*s\");",
65-
printable(command.game_arguments));
91+
printable(arguments.game_args));
6692
Log::WriteLine();
6793

68-
Debugger.Run(command.game_arguments);
94+
Debugger.Run(arguments.game_args);
6995
Log::WriteLine("WinMain: SyringeDebugger::Run finished.");
7096
Log::WriteLine("WinMain: Exiting on success.");
7197
return ERROR_SUCCESS;

Support.h

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ inline auto parse_command_line(const std::vector<std::string>& arguments)
3232
{
3333
std::vector<std::string> syringe_arguments;
3434
std::string executable_name;
35-
std::string game_arguments;
3635
};
3736

3837
if (arguments.empty())
@@ -43,8 +42,6 @@ inline auto parse_command_line(const std::vector<std::string>& arguments)
4342
// First non-flag argument becomes executable name
4443
bool exe_found = false;
4544

46-
bool exe_arguments = false;
47-
4845
for (const auto& arg : arguments)
4946
{
5047
// executable name: first argument not starting with '-'
@@ -59,32 +56,16 @@ inline auto parse_command_line(const std::vector<std::string>& arguments)
5956
continue;
6057
}
6158

62-
if (arg == "--")
63-
{
64-
exe_arguments = true;
65-
continue;
66-
}
67-
68-
if (exe_arguments)
69-
{
70-
// game arguments
71-
ret.game_arguments += " ";
72-
ret.game_arguments += arg;
73-
}
59+
// Syringe arguments
60+
if (arg.starts_with("-i=\"") && arg.ends_with('"'))
61+
ret.syringe_arguments.push_back("-i=" + arg.substr(4, arg.length() - 5));
7462
else
75-
{
76-
// Syringe arguments
77-
if (arg.starts_with("-i=\"") && arg.ends_with('"'))
78-
ret.syringe_arguments.push_back("-i=" + arg.substr(4, arg.length() - 5));
79-
else
80-
ret.syringe_arguments.push_back(arg);
81-
}
63+
ret.syringe_arguments.push_back(arg);
8264
}
8365

8466
if (!exe_found || ret.executable_name.empty())
8567
throw invalid_command_arguments{};
8668

87-
ret.game_arguments = ret.game_arguments.substr(1);
8869

8970
return ret;
9071
}

0 commit comments

Comments
 (0)