3 #include <ail/arguments.hpp>
4 #include "arguments.hpp"
10 incremental_window_title
,
28 std::string socks_server
;
31 char * command_line_arguments
;
33 std::string
key_string(std::string
const & key
)
36 return "Key has not been specified";
38 return "A custom key has been specified";
41 char * patched_GetCommandLineA()
43 return command_line_arguments
;
46 bool install_command_line_patch(string_vector
const & parsed_arguments
)
48 OSVERSIONINFOEX version
;
49 ZeroMemory(&version
, sizeof(OSVERSIONINFOEX
));
50 version
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOEX
);
51 if(!GetVersionEx(reinterpret_cast<OSVERSIONINFO
*>(&version
)))
53 last_error("GetVersionEx failed");
57 if(version
.dwMajorVersion
== 6 && version
.dwMinorVersion
== 1 && version
.wProductType
== VER_NT_WORKSTATION
)
59 kernel
= "kernelbase.dll";
61 write_line("Windows 7 detected, using module " + kernel
+ " for the commandline patch");
65 kernel
= "kernel32.dll";
67 write_line("Pre Windows 7 OS detected, using module " + kernel
+ " for the commandline patch");
71 if(!procedure_lookup(kernel
.c_str(), "GetCommandLineA", address
))
73 error("Unable to look up the address for the command line patch");
77 std::string new_arguments
= "\"" + parsed_arguments
[0] + "\" " + d2_arguments
;
78 command_line_arguments
= new char[new_arguments
.size() + 1];
79 std::strcpy(command_line_arguments
, new_arguments
.c_str());
81 char * byte_pointer
= reinterpret_cast<char *>(address
);
82 uchar first_byte
= *reinterpret_cast<uchar
*>(byte_pointer
);
83 if(first_byte
== 0xa1)
85 char * & string_pointer
= **reinterpret_cast<char ***>(byte_pointer
+ 1);
86 string_pointer
= command_line_arguments
;
89 write_line("Successfully installed the command line patch");
95 error("The format of your kernel32.dll!GetCommandlineA is unknown to the patcher: " + ail::hex_string_8(first_byte
));
100 bool get_arguments(string_vector
& output
)
102 std::string input
= GetCommandLine();
103 for(std::size_t i
= 0; i
< input
.size(); i
++)
109 char current_char
= input
[i
];
110 if(current_char
== '"')
113 end
= input
.find('"', start
);
114 if(end
== std::string::npos
)
116 error("Invalid commandline detected (check your quotes)");
123 end
= input
.find(' ', start
);
124 if(end
== std::string::npos
)
128 std::string argument
= input
.substr(start
, end
- start
);
129 output
.push_back(argument
);
136 void process_command_line()
138 ail::argument_parser argument_parser
;
140 argument_parser
.flag("console_output", console_output
).default_flag(true);
141 argument_parser
.flag("incremental_window_title", incremental_window_title
).default_flag(false);
142 argument_parser
.flag("verbose", verbose
).default_flag(false);
143 argument_parser
.flag("prompt", prompt_mode
).default_flag(false);
144 argument_parser
.flag("patch_system_modules", patch_system_modules
).default_flag(true);
145 argument_parser
.flag("do_not_hide_window", do_not_hide_window
).default_flag(false);
147 argument_parser
.string("window_title", window_title
).default_string("Diablo II");
148 argument_parser
.string("classic_key", classic_key
);
149 argument_parser
.string("expansion_key", expansion_key
);
150 argument_parser
.string("d2_arguments", d2_arguments
).default_string("-w");
151 argument_parser
.string("python_script", python_script
);
152 argument_parser
.string("hide_modules_file", hide_modules_file
);
153 argument_parser
.string("bncache_directory", bncache_directory
);
154 argument_parser
.string("socks", socks
);
156 string_vector arguments
;
157 if(!get_arguments(arguments
))
165 argument_parser
.parse(arguments
);
169 write_line("Window title: " + window_title
);
170 write_line("Classic key: " + key_string(classic_key
));
171 write_line("Expansion key: " + key_string(expansion_key
));
174 use_custom_keys
= !classic_key
.empty() && !expansion_key
.empty();
179 write_line("Using the specified custom keys");
181 write_line("Not using a custom pair of keys");
184 install_command_line_patch(arguments
);
186 catch(ail::exception
& exception
)
188 error("Argument parser error: " + exception
.get_message());
194 string_vector tokens
= ail::tokenise(socks
, ":");
195 if(tokens
.size() != 2)
197 error("Invalid SOCKS5 server address specified, should be \"host:port\", encountered \"" + socks
+ "\"");
202 socks_server
= tokens
[0];
203 std::string
const & socks_port_string
= tokens
[1];
204 if(!ail::string_to_number(socks_port_string
, socks_port
))
206 error("Invalid SOCKS5 server port specified: " + socks_port_string
);