Skip to content

WM_DEVICECHANGE hook filters too many events, only DBT_DEVNODES_CHANGED is required. #1298

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Kaldaien opened this issue Apr 8, 2025 · 0 comments

Comments

@Kaldaien
Copy link

Kaldaien commented Apr 8, 2025

The recent update to REFramework that tries to filter device arrival/removal messages has two problems.

  1. It is incomplete in determining if the device is actually an input device in Arrival/Removal.
  2. Only DBT_DEVNODES_CHANGED causes the performance issues, and that is because the game re-enumerates all DirectInput devices immediately every time this is received and it's broadcast 5 or 6 times in a single frame sometimes.
          if (pDevHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
          {
            const auto pDevW =
              (DEV_BROADCAST_DEVICEINTERFACE_W *)pDevHdr;

            // Input Devices
            if (IsEqualGUID (pDevW->dbcc_classguid, GUID_DEVINTERFACE_HID)         ||
                IsEqualGUID (pDevW->dbcc_classguid, GUID_XUSB_INTERFACE_CLASS)     ||
                IsEqualGUID (pDevW->dbcc_classguid, GUID_DEVINTERFACE_KEYBOARD)    ||
                IsEqualGUID (pDevW->dbcc_classguid, GUID_DEVINTERFACE_MOUSE)       ||
                IsEqualGUID (pDevW->dbcc_classguid, GUID_BTHPORT_DEVICE_INTERFACE) ||
                IsEqualGUID (pDevW->dbcc_classguid, GUID_DEVCLASS_BLUETOOTH))
            {
              bIgnore = false;
            }

            // Audio Devices
            else if (IsEqualGUID (pDevW->dbcc_classguid, KSCATEGORY_CAPTURE)        ||
                     IsEqualGUID (pDevW->dbcc_classguid, KSCATEGORY_RENDER)         ||
                     IsEqualGUID (pDevW->dbcc_classguid, KSCATEGORY_MIXER)          ||
                     IsEqualGUID (pDevW->dbcc_classguid, KSCATEGORY_AUDIO)          ||
                     IsEqualGUID (pDevW->dbcc_classguid, DEVINTERFACE_AUDIO_RENDER) ||
                     IsEqualGUID (pDevW->dbcc_classguid, DEVINTERFACE_AUDIO_CAPTURE))
            {
              bIgnore = false;
            }

            // Display Hardware
            else if (IsEqualGUID (pDevW->dbcc_classguid, GUID_DEVINTERFACE_MONITOR) ||
                     IsEqualGUID (pDevW->dbcc_classguid, GUID_DEVINTERFACE_DISPLAY_ADAPTER))
            {
              bIgnore = false;
            }

            else
            {
              wchar_t                                 wszGUID [41] = { };
              StringFromGUID2 (pDevW->dbcc_classguid, wszGUID, 40);

              SK_LOGi0 (L" || Device=%ws", wszGUID);
            }
          }

The above code snippet correctly filters input devices and doesn't prevent the game from seeing display or audio changes. But frankly, that is a waste of time, only DBT_DEVNODES_CHANGED needs to be filtered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant