|
|
|
@ -43,7 +43,7 @@ DEFINE_GUID(GUID_DEVINTERFACE_XUSB, 0xEC87F1E3, 0xC13B, 0x4100, 0xB5, 0xF7, 0x8B
|
|
|
|
|
// {00000000-0000-0000-FFFF-FFFFFFFFFFFF} the system container id
|
|
|
|
|
DEFINE_GUID(GUID_CONTAINER_ID_SYSTEM, 0x00000000, 0x0000, 0x0000, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
|
|
|
|
|
|
|
|
|
|
HidHide::HidHide() = default;
|
|
|
|
|
HidHide::HidHide(){};
|
|
|
|
|
|
|
|
|
|
void HidHide::openCtrlDevice()
|
|
|
|
|
{
|
|
|
|
@ -68,6 +68,8 @@ void HidHide::closeCtrlDevice()
|
|
|
|
|
|
|
|
|
|
void HidHide::hideDevices(const std::filesystem::path& steam_path)
|
|
|
|
|
{
|
|
|
|
|
UnPatchValveHooks();
|
|
|
|
|
|
|
|
|
|
openCtrlDevice();
|
|
|
|
|
auto active = getActive();
|
|
|
|
|
if (active) {
|
|
|
|
@ -109,14 +111,18 @@ void HidHide::hideDevices(const std::filesystem::path& steam_path)
|
|
|
|
|
if (std::ranges::none_of(blacklisted_devices_, [&dev](const auto& blackdev) {
|
|
|
|
|
return blackdev == dev.device_instance_path || blackdev == dev.base_container_device_instance_path;
|
|
|
|
|
})) {
|
|
|
|
|
if (!dev.device_instance_path.empty()) {
|
|
|
|
|
blacklisted_devices_.push_back(dev.device_instance_path);
|
|
|
|
|
}
|
|
|
|
|
if (!dev.device_instance_path.empty()) {
|
|
|
|
|
blacklisted_devices_.push_back(dev.base_container_device_instance_path);
|
|
|
|
|
// Valve emulated gamepad PID/VID; mirrord by ViGEm
|
|
|
|
|
if (!(dev.vendor_id == 0x28de && dev.product_id == 0x11FF)) {
|
|
|
|
|
if (!dev.device_instance_path.empty()) {
|
|
|
|
|
blacklisted_devices_.push_back(dev.device_instance_path);
|
|
|
|
|
}
|
|
|
|
|
if (!dev.device_instance_path.empty()) {
|
|
|
|
|
blacklisted_devices_.push_back(dev.base_container_device_instance_path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// TODO: remove all vigem controllers added by GlosSI
|
|
|
|
|
setBlacklistDevices(blacklisted_devices_);
|
|
|
|
|
setActive(true);
|
|
|
|
|
closeCtrlDevice();
|
|
|
|
@ -132,6 +138,110 @@ void HidHide::disableHidHide()
|
|
|
|
|
spdlog::info("Un-hid Gaming Devices");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HidHide::UnPatchValveHooks()
|
|
|
|
|
{
|
|
|
|
|
spdlog::debug("Unpatching Valve HID hooks...");
|
|
|
|
|
// need to load addresses that way.. Otherwise we land before some jumps...
|
|
|
|
|
auto setupapidll = GetModuleHandle(L"setupapi.dll");
|
|
|
|
|
if (setupapidll) {
|
|
|
|
|
BYTE* addr = reinterpret_cast<BYTE*>(GetProcAddress(setupapidll, "SetupDiEnumDeviceInfo"));
|
|
|
|
|
if (addr) {
|
|
|
|
|
UnPatchHook(addr, SETUP_DI_ENUM_DEV_INFO_ORIG_BYTES);
|
|
|
|
|
spdlog::trace("Unpatched SetupDiEnumDeviceInfo");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
spdlog::error("failed to unpatch SetupDiEnumDeviceInfo");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
auto hiddll = GetModuleHandle(L"hid.dll");
|
|
|
|
|
if (hiddll) {
|
|
|
|
|
BYTE* addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidD_GetPreparsedData"));
|
|
|
|
|
if (addr) {
|
|
|
|
|
UnPatchHook(addr, HID_GETPREPARSED_ORIG_BYTES);
|
|
|
|
|
spdlog::trace("Unpatched HidD_GetPreparsedData");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
spdlog::error("failed to unpatch HidD_GetPreparsedData");
|
|
|
|
|
}
|
|
|
|
|
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidP_GetCaps"));
|
|
|
|
|
if (addr) {
|
|
|
|
|
UnPatchHook(addr, HID_GETCAPS_ORIG_BYTES);
|
|
|
|
|
spdlog::trace("Unpatched HidP_GetCaps");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
spdlog::error("failed to unpatch HidP_GetCaps");
|
|
|
|
|
}
|
|
|
|
|
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidD_GetAttributes"));
|
|
|
|
|
if (addr) {
|
|
|
|
|
UnPatchHook(addr, HID_GETATTRS_ORIG_BYTES);
|
|
|
|
|
spdlog::trace("Unpatched HidD_GetAttributes");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
spdlog::error("failed to unpatch HidD_GetAttributes");
|
|
|
|
|
}
|
|
|
|
|
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidD_GetProductString"));
|
|
|
|
|
if (addr) {
|
|
|
|
|
UnPatchHook(addr, HID_GETPRODSTR_ORIG_BYTES);
|
|
|
|
|
spdlog::trace("Unpatched HidD_GetProductString");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
spdlog::error("failed to unpatch HidD_GetProductString");
|
|
|
|
|
}
|
|
|
|
|
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidP_GetUsages"));
|
|
|
|
|
if (addr) {
|
|
|
|
|
UnPatchHook(addr, HID_GETUSAGE_ORIG_BYTES);
|
|
|
|
|
spdlog::trace("Unpatched HidP_GetUsages");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
spdlog::error("failed to unpatch HidP_GetUsages");
|
|
|
|
|
}
|
|
|
|
|
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidP_GetData"));
|
|
|
|
|
if (addr) {
|
|
|
|
|
UnPatchHook(addr, HID_GETDATA_ORIG_BYTES);
|
|
|
|
|
spdlog::trace("Unpatched HidP_GetData");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
spdlog::error("failed to unpatch HidP_GetData");
|
|
|
|
|
}
|
|
|
|
|
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidP_GetValueCaps"));
|
|
|
|
|
if (addr) {
|
|
|
|
|
UnPatchHook(addr, HID_GETVALUECAPS_ORIG_BYTES);
|
|
|
|
|
spdlog::trace("Unpatched HidP_GetValueCaps");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
spdlog::error("failed to unpatch HidP_GetValueCaps");
|
|
|
|
|
}
|
|
|
|
|
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidP_GetUsageValue"));
|
|
|
|
|
if (addr) {
|
|
|
|
|
UnPatchHook(addr, HID_GETUSAGE_VAL_ORIG_BYTES);
|
|
|
|
|
spdlog::trace("Unpatched HidP_GetUsageValue");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
spdlog::error("failed to unpatch HidP_GetUsageValue");
|
|
|
|
|
}
|
|
|
|
|
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidP_GetButtonCaps"));
|
|
|
|
|
if (addr) {
|
|
|
|
|
UnPatchHook(addr, HID_GETBTNCAPS_VAL_ORIG_BYTES);
|
|
|
|
|
spdlog::trace("Unpatched HidP_GetButtonCaps");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
spdlog::error("failed to unpatch HidP_GetButtonCaps");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HidHide::UnPatchHook(BYTE* address, const std::string& bytes)
|
|
|
|
|
{
|
|
|
|
|
DWORD dw_old_protect, dw_bkup;
|
|
|
|
|
const auto len = bytes.size();
|
|
|
|
|
VirtualProtect(address, len, PAGE_EXECUTE_READWRITE, &dw_old_protect); //Change permissions of memory..
|
|
|
|
|
for (DWORD i = 0; i < len; i++) //unpatch Valve's hook
|
|
|
|
|
{
|
|
|
|
|
*(address + i) = bytes[i];
|
|
|
|
|
}
|
|
|
|
|
VirtualProtect(address, len, dw_old_protect, &dw_bkup); //Revert permission change...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HidHide::enableOverlayElement()
|
|
|
|
|
{
|
|
|
|
|
Overlay::AddOverlayElem([this]() {
|
|
|
|
@ -329,6 +439,7 @@ std::vector<HidHide::SmallHidInfo> HidHide::GetHidDeviceList()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto device_instance_paths = BufferToStringVec(buffer);
|
|
|
|
|
|
|
|
|
|
device_instance_paths.erase(
|
|
|
|
|
std::ranges::remove_if(
|
|
|
|
|
device_instance_paths,
|
|
|
|
@ -419,6 +530,8 @@ HidHide::SmallHidInfo HidHide::GetDeviceInfo(const DeviceInstancePath& instance_
|
|
|
|
|
}
|
|
|
|
|
res.base_container_device_instance_path = BaseContainerDeviceInstancePath(instance_path);
|
|
|
|
|
res.gaming_device = IsGamingDevice(attributes, capabilities);
|
|
|
|
|
res.vendor_id = attributes.VendorID;
|
|
|
|
|
res.product_id = attributes.ProductID;
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|