DisableJoyL3.zip/DisableJoyL3/main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <Windows.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#include <boost/version.hpp>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include "dll_hack_lib.h"
#include "main.h"
#pragma comment(lib, "dinput8.lib")
const IMAGE_DOS_HEADER &getDosHeader(const HMODULE hmod = ::GetModuleHandle(NULL)) {
const unsigned int base = reinterpret_cast<unsigned int>(hmod);
return *reinterpret_cast<const IMAGE_DOS_HEADER *>(base);
}
const IMAGE_NT_HEADERS &getNtHeader(const HMODULE hmod = ::GetModuleHandle(NULL)) {
const unsigned int base = reinterpret_cast<unsigned int>(hmod);
const IMAGE_DOS_HEADER &mz = getDosHeader(hmod);
return *reinterpret_cast<const IMAGE_NT_HEADERS *>(base + mz.e_lfanew);
}
bool ChangeIAT(const std::string &targetDllName, const std::string &targetFuncName, const FARPROC function) {
std::string targetDllNameLow;
targetDllNameLow.resize(targetDllName.size());
std::transform(targetDllName.begin(), targetDllName.end(), targetDllNameLow.begin(), ::tolower);
const HMODULE hmod = ::GetModuleHandle(NULL);
const IMAGE_NT_HEADERS &nt = getNtHeader(hmod);
const IMAGE_DATA_DIRECTORY &dir = nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
const IMAGE_IMPORT_DESCRIPTOR *desc = reinterpret_cast<const IMAGE_IMPORT_DESCRIPTOR *>(reinterpret_cast<unsigned int>(hmod) + dir.VirtualAddress);
for (; desc->OriginalFirstThunk != 0; desc++) {
const char * const dllName = reinterpret_cast<const char *>(reinterpret_cast<unsigned int>(hmod) + desc->Name);
const unsigned int dllNameLength = ::strlen(dllName);
std::string dllNameLow;
dllNameLow.resize(dllNameLength);
std::transform(&dllName[0], &dllName[dllNameLength], dllNameLow.begin(), ::tolower);
if (dllNameLow != targetDllNameLow) {
continue;
}
const IMAGE_THUNK_DATA *thunk = reinterpret_cast<const IMAGE_THUNK_DATA *>(reinterpret_cast<unsigned int>(hmod) + desc->OriginalFirstThunk);
const IMAGE_THUNK_DATA *outThunk = reinterpret_cast<const IMAGE_THUNK_DATA *>(reinterpret_cast<unsigned int>(hmod) + desc->FirstThunk);
for (;thunk->u1.AddressOfData != NULL; thunk++, outThunk++) {
if (!IMAGE_SNAP_BY_ORDINAL32(thunk->u1.Ordinal)) {
const char * const funcName = reinterpret_cast<const char *>(reinterpret_cast<unsigned int>(hmod) + thunk->u1.AddressOfData + 2);
if (targetFuncName == funcName) {
return org::click3::DllHackLib::WriteCode(NULL, reinterpret_cast<unsigned int>(outThunk), reinterpret_cast<const unsigned char *>(&function), sizeof(function));
}
}
}
}
return false;
}
HRESULT (__stdcall * p_GetDeviceState)(IDirectInputDevice *, DWORD, LPVOID) = NULL;
HRESULT __stdcall d_GetDeviceState(IDirectInputDevice *self, DWORD cbData, LPVOID lpvData) {
const HRESULT result = p_GetDeviceState(self, cbData, lpvData);
if (result == DI_OK && cbData == 0x50) {
reinterpret_cast<unsigned char *>(lpvData)[0x3A] = 0x00;
}
return result;
}
HRESULT (__stdcall * p_SetDataFormat)(IDirectInputDevice *, LPCDIDATAFORMAT) = NULL;
HRESULT __stdcall d_SetDataFormat(IDirectInputDevice *self, LPCDIDATAFORMAT lpdf) {
return p_SetDataFormat(self, lpdf);
}
HRESULT (__stdcall * p_CreateDevice)(IDirectInput8 *, REFGUID, LPDIRECTINPUTDEVICE *, LPUNKNOWN) = NULL;
HRESULT __stdcall d_CreateDevice(IDirectInput8 *self, REFGUID rguid, LPDIRECTINPUTDEVICE *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) {
const HRESULT result = p_CreateDevice(self, rguid, lplpDirectInputDevice, pUnkOuter);
if (result == S_OK) {
if (!org::click3::DllHackLib::ChangeVartualProcAddress(*lplpDirectInputDevice, reinterpret_cast<void **>(p_SetDataFormat == NULL ? &p_SetDataFormat : NULL), &IDirectInputDevice::SetDataFormat, d_SetDataFormat)) {
return DIERR_NOTINITIALIZED;
}
if (!org::click3::DllHackLib::ChangeVartualProcAddress(*lplpDirectInputDevice, reinterpret_cast<void **>(p_GetDeviceState == NULL ? &p_GetDeviceState : NULL), &IDirectInputDevice::GetDeviceState, d_GetDeviceState)) {
return DIERR_NOTINITIALIZED;
}
}
return result;
}
HRESULT __stdcall d_DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter) {
const HRESULT result = ::DirectInput8Create(hinst, dwVersion, riidltf, ppvOut, punkOuter);
if (result == DI_OK) {
if (ppvOut == NULL) {
return DIERR_INVALIDPARAM;
}
if (!org::click3::DllHackLib::ChangeVartualProcAddress(*ppvOut, reinterpret_cast<void **>(&p_CreateDevice), &IDirectInput8::CreateDevice, d_CreateDevice)) {
return DIERR_INVALIDPARAM;
}
}
return result;
}
void main() {
if (!ChangeIAT("dinput8.dll", "DirectInput8Create", reinterpret_cast<FARPROC>(d_DirectInput8Create))) {
return;
}
}