Skip to content
Permalink
Browse files

Fix issues with and cleanup code for xinput dll patching.

  • Loading branch information...
num0005 committed Mar 23, 2019
1 parent 4def1a9 commit 2e761c40f85af0fd983cab0313995d5d559767cf
Showing with 61 additions and 51 deletions.
  1. +61 −51 xlive/H2MOD/Modules/Startup/Startup.cpp
@@ -10,6 +10,7 @@
#include <sys/stat.h>
#include <string>
#include <sstream>
#include <io.h>
#include "Util\Hooks\Hook.h"
#include "Util\Debug\Debug.h"
#include "Util\hash.h"
@@ -83,7 +84,11 @@ void initInstanceNumber() {

wchar_t xinput_path[_MAX_PATH];

void configureXinput() {
bool configureXinput() {
auto report_error = [](const std::string &message) {
MessageBoxA(NULL, message.c_str(), "Xinput config error!", MB_OK);
};

if (!H2IsDediServer) {
if (H2GetInstanceId() > 1) {
swprintf(xinput_path, ARRAYSIZE(xinput_path), L"xinput/p%02d/xinput9_1_0.dll", H2GetInstanceId());
@@ -95,42 +100,52 @@ void configureXinput() {
char xinputdir[_MAX_PATH];
sprintf(xinputdir, "xinput/p%02d", H2GetInstanceId());
sprintf(xinputName, "%s/xinput9_1_0.dll", xinputdir);
CreateDirectoryA("xinput", NULL);
int fperrno1 = GetLastError();
if (!(fperrno1 == ERROR_ALREADY_EXISTS || fperrno1 == ERROR_SUCCESS)) {
fileFail(NULL);
MessageBoxA(NULL, "Error 7g546.", "Unknown Error", MB_OK);
exit(EXIT_FAILURE);
}
CreateDirectoryA(xinputdir, NULL);
int fperrno2 = GetLastError();
if (!(fperrno2 == ERROR_ALREADY_EXISTS || fperrno2 == ERROR_SUCCESS)) {
fileFail(NULL);
MessageBoxA(NULL, "Error 7g547.", "Unknown Error", MB_OK);
exit(EXIT_FAILURE);
}
if (FILE *file = fopen(xinputName, "r")) {
fclose(file);

/* Creates a directory and displays error if it fails */
auto create_dir = [=](const std::string &path) -> bool {
if (LOG_CHECK(!CreateDirectoryA(path.c_str(), NULL) && GetLastError() != ERROR_ALREADY_EXISTS))
{
report_error("Failed to create '" + path + "' directory, check logs!");
return false;
}
return true;
};

if (!create_dir("xinput") || !create_dir(xinputdir))
{
return false;
}
else {

TRACE_FUNC_N("xinput path: %s", xinputName);
if (_access_s(xinputName, 04))
{
if (errno == EACCES)
{
report_error("Can't access the xinput dll");
return false;
}
int xinput_index = -1;
char xinput_md5_durazno_0_6_0_0[] = "6140ae76b26a633ce2255f6fc88fbe34";
long xinput_offset_durazno_0_6_0_0 = 0x196de;
bool xinput_unicode_durazno_0_6_0_0 = true;
char xinput_md5_x360ce_3_3_1_444[] = "8f24e36d5f0a71c8a412cec6323cd781";
long xinput_offset_x360ce_3_3_1_444 = 0x1ea54;
bool xinput_unicode_x360ce_3_3_1_444 = true;
char xinput_md5_x360ce_3_4_1_1357[] = "5236623449893c0e1e98fc95f067fcff";
long xinput_offset_x360ce_3_4_1_1357 = 0x16110;
bool xinput_unicode_x360ce_3_4_1_1357 = false;
const int xinput_array_length = 3;
char* xinput_md5[xinput_array_length] = { xinput_md5_durazno_0_6_0_0, xinput_md5_x360ce_3_3_1_444, xinput_md5_x360ce_3_4_1_1357 };
long xinput_offset[xinput_array_length] = { xinput_offset_durazno_0_6_0_0, xinput_offset_x360ce_3_3_1_444, xinput_offset_x360ce_3_4_1_1357 };
bool xinput_unicode[xinput_array_length] = { xinput_unicode_durazno_0_6_0_0, xinput_unicode_x360ce_3_3_1_444, xinput_unicode_x360ce_3_4_1_1357 };
constexpr char xinput_md5_durazno_0_6_0_0[] = "6140ae76b26a633ce2255f6fc88fbe34";
constexpr long xinput_offset_durazno_0_6_0_0 = 0x196de;
constexpr bool xinput_unicode_durazno_0_6_0_0 = true;
constexpr char xinput_md5_x360ce_3_3_1_444[] = "8f24e36d5f0a71c8a412cec6323cd781";
constexpr long xinput_offset_x360ce_3_3_1_444 = 0x1ea54;
constexpr bool xinput_unicode_x360ce_3_3_1_444 = true;
constexpr char xinput_md5_x360ce_3_4_1_1357[] = "5236623449893c0e1e98fc95f067fcff";
constexpr long xinput_offset_x360ce_3_4_1_1357 = 0x16110;
constexpr bool xinput_unicode_x360ce_3_4_1_1357 = false;
constexpr int xinput_array_length = 3;
static const char* xinput_md5[xinput_array_length] = { xinput_md5_durazno_0_6_0_0, xinput_md5_x360ce_3_3_1_444, xinput_md5_x360ce_3_4_1_1357 };
static constexpr long xinput_offset[xinput_array_length] = { xinput_offset_durazno_0_6_0_0, xinput_offset_x360ce_3_3_1_444, xinput_offset_x360ce_3_4_1_1357 };
static constexpr bool xinput_unicode[xinput_array_length] = { xinput_unicode_durazno_0_6_0_0, xinput_unicode_x360ce_3_3_1_444, xinput_unicode_x360ce_3_4_1_1357 };
std::string available_xinput_md5;
int hasherr = hashes::calc_file_md5("xinput9_1_0.dll", available_xinput_md5);
FILE* file1 = NULL;
if (hasherr == 0 && (file1 = fopen("xinput9_1_0.dll", "rb"))) {
if (!hashes::calc_file_md5("xinput9_1_0.dll", available_xinput_md5))
{
report_error("Failed to hash original xinput9_1_0.dll");
return false;
}
FILE* xinput_original = NULL;
if (xinput_original = fopen("xinput9_1_0.dll", "rb")) {
for (int i = 0; i < xinput_array_length; i++) {
if (strcmp(xinput_md5[i], available_xinput_md5.c_str()) == 0) {
xinput_index = i;
@@ -143,25 +158,25 @@ void configureXinput() {
MessageBoxA(NULL, xinputError, "Incorrect DLL Error", MB_OK);
exit(EXIT_FAILURE);
}
FILE* file2 = fopen(xinputName, "wb");
if (!file2) {
fileFail(file2);
MessageBoxA(NULL, "Error bf58i.", "Unknown Error", MB_OK);
FILE* xinput_patched = fopen(xinputName, "wb");
if (!xinput_patched) {
fileFail(xinput_patched);
report_error("Can't open xinput file for patching.");
exit(EXIT_FAILURE);
}
char buffer[BUFSIZ];
size_t n;
while ((n = fread(buffer, sizeof(char), sizeof(buffer), file1)) > 0) {
if (fwrite(buffer, sizeof(char), n, file2) != n) {
while ((n = fread(buffer, sizeof(char), sizeof(buffer), xinput_original)) > 0) {
if (fwrite(buffer, sizeof(char), n, xinput_patched) != n) {
char xinputError[255];
sprintf(xinputError, "ERROR! Failed to write copied file: %s", xinputName);
addDebugText(xinputError);
MessageBoxA(NULL, xinputError, "DLL Copy Error", MB_OK);
exit(EXIT_FAILURE);
}
}
fclose(file1);
fclose(file2);
fclose(xinput_original);
fclose(xinput_patched);

FILE* file3 = fopen(xinputName, "r+b");
int len_to_write = 2;
@@ -184,23 +199,17 @@ void configureXinput() {
}
fclose(file3);
}
else if (hasherr == -1 || !file1) {
else {
char xinputError[] = "ERROR! An xinput9_1_0.dll does not exist in the local game directory!\nFor \'Split-screen\' play, any supported .dll is required.";
addDebugText(xinputError);
MessageBoxA(NULL, xinputError, "DLL Missing Error", MB_OK);
exit(EXIT_FAILURE);
}
else {
char xinputError[200];
snprintf(xinputError, 200, "Hash Error Num: %x - msg: %s", hasherr, available_xinput_md5.c_str());
addDebugText(xinputError);
MessageBoxA(NULL, xinputError, "MD5 Hash Error", MB_OK);
exit(EXIT_FAILURE);
}
}
}
}
addDebugText("Finished Processing Instance Number.");
return true;
}

void initLocalAppData() {
@@ -408,7 +417,8 @@ void InitH2Startup() {
#endif
InitH2Accounts();

configureXinput();
if (!configureXinput())
exit(EXIT_FAILURE);

//apply any network hooks
network->applyNetworkHooks();

0 comments on commit 2e761c4

Please sign in to comment.
You can’t perform that action at this time.