title: SetWindowsHookEx hooking into every running program
body: <p>I have written a small DLL that is being injected into a game to apply runtime fixes. I've decided to add some Keyboard Listeners:</p>
  <pre><code>while (1)
      if (AsyncKeyState(...)) (...)
  </code></pre>
  <p>However, this is taking up CPU usage, and introducing some noticeable stuttering. So I decided to use a callback methodology as suggested by MSDN via <code>SetWindowsHookExA</code> and a <code>KeyboardProc</code> callback. At first, I was running the method via <code>SetWindowsHookExA(WH_Keyboard, KeyboardProc, NULL, 0)</code> but was getting error code <code>ERROR_HOOK_NEEDS_HMOD (0x594)</code>. So I changed my code to become like this:</p>
  <pre><code>bool APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpRes)
  {
      HHOOK hook_ = nullptr;
      switch (reason)
      {
      case DLL_PROCESS_ATTACH:
          
          if (!(hook_ = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hModule, 0)))
          {
              char x[100];
              sprintf(x, &quot;Failed To Hook Keyboard FN: 0x%X&quot;, GetLastError());
              MessageBox(NULL, x, &quot;Error&quot;, MB_ICONERROR);
          }
          break;
      case DLL_THREAD_ATTACH:
      case DLL_THREAD_DETACH:
      case DLL_PROCESS_DETACH:
          UnhookWindowsHookEx(hook_);
          break;
      }
      return true;
  }
  </code></pre>
  <p>This was not giving the error anymore, and my hooking Keyboard function was working perfectly. However, a very unintended side-effect was that all keyboard captures from all running applications are being ignored.
  I noticed this quote from MSDN, so I added it to my code:</p>
  <blockquote>
  <p>If code is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_KEYBOARD hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.</p>
  </blockquote>
  <p>That fixed the keyboard issue, but now there's another issue, which is I'm unable to delete the DLL I created. When I attempt to delete it, it says &quot;dll is running in Explorer.exe&quot;. when I kill <code>explorer.exe</code>, it says &quot;dll is running in SteamHelper.exe&quot;. When I kill <code>steamhelper.exe</code>, it says &quot;dll is running in Chrome.exe&quot;. This shows me that I've somehow hooked into every running application?</p>
  <p>I'm unable to fix this issue, and I couldn't find any help on it. Any insight is greatly appreciated!</p>