// Optional lab-only focus handling. Named Win32 imports, no engine offsets. // Window-procedure approach also used by araghon007/NoFocusLoss (Unlicense). #define WIN32_LEAN_AND_MEAN #define NOMINMAX #include #include #include static std::atomic gameWindow{nullptr}; static WNDPROC previousProc = nullptr; static decltype(&CreateWindowExA) createWindow = nullptr; static decltype(&GetForegroundWindow) foreground = nullptr; static decltype(&SetCursorPos) cursorPos = nullptr; static decltype(&ClipCursor) clipCursor = nullptr; static decltype(&SetCapture) setCapture = nullptr; static decltype(&SetForegroundWindow) setForeground = nullptr; static decltype(&GetAsyncKeyState) asyncKey = nullptr; static HANDLE logFile = INVALID_HANDLE_VALUE; static LONG focusLosses = 0; struct ImportHook { void** slot; void* original; void* replacement; }; static ImportHook hooks[8]{}; static int hookCount = 0; static void Log(const char* text) { if (logFile != INVALID_HANDLE_VALUE) { DWORD written; WriteFile(logFile,text,static_cast(std::strlen(text)),&written,nullptr); } } static bool Hidden() { HWND w=gameWindow.load(); return w && foreground && foreground()!=w; } static bool HookImport(const char* dll, const char* name, WORD ordinal, void* replacement, void** original) { auto base = reinterpret_cast(GetModuleHandleW(nullptr)); auto dos = reinterpret_cast(base); if (dos->e_magic != IMAGE_DOS_SIGNATURE) return false; auto pe = reinterpret_cast(base + dos->e_lfanew); if (pe->Signature != IMAGE_NT_SIGNATURE || pe->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) return false; auto directory = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; if (!directory.VirtualAddress || directory.VirtualAddress >= pe->OptionalHeader.SizeOfImage) return false; auto imports = reinterpret_cast(base + directory.VirtualAddress); for (; imports->Name; ++imports) { if (_stricmp(reinterpret_cast(base + imports->Name), dll)) continue; if (!imports->OriginalFirstThunk) return false; auto lookup = reinterpret_cast(base + imports->OriginalFirstThunk); auto target = reinterpret_cast(base + imports->FirstThunk); for (; lookup->u1.AddressOfData; ++lookup, ++target) { bool match = IMAGE_SNAP_BY_ORDINAL64(lookup->u1.Ordinal) ? ordinal && IMAGE_ORDINAL64(lookup->u1.Ordinal) == ordinal : name && !std::strcmp(reinterpret_cast(base + lookup->u1.AddressOfData)->Name, name); if (!match) continue; DWORD protection; if (!VirtualProtect(&target->u1.Function, sizeof(void*), PAGE_READWRITE, &protection)) return false; *original = reinterpret_cast(target->u1.Function); hooks[hookCount++] = {reinterpret_cast(&target->u1.Function), *original, replacement}; InterlockedExchangePointer(reinterpret_cast(&target->u1.Function), replacement); DWORD unused; VirtualProtect(&target->u1.Function, sizeof(void*), protection, &unused); return true; } } return false; } static LRESULT CALLBACK WindowProc(HWND window, UINT message, WPARAM wp, LPARAM lp) { // Keep the engine active without moving OS focus or exposing other apps' input. if ((message==WM_ACTIVATE && LOWORD(wp)==WA_INACTIVE) || (message==WM_ACTIVATEAPP && !wp) || message==WM_KILLFOCUS || (message==WM_IME_SETCONTEXT && !wp)) { if (InterlockedIncrement(&focusLosses)<=16) Log("suppressed focus loss\n"); if (clipCursor) clipCursor(nullptr); ReleaseCapture(); return 0; } if (message==WM_NCACTIVATE && !wp) return DefWindowProcA(window,message,wp,lp); if (Hidden() && ((message>=WM_KEYFIRST && message<=WM_KEYLAST) || (message>=WM_MOUSEFIRST && message<=WM_MOUSELAST) || message==WM_INPUT)) return DefWindowProcA(window,message,wp,lp); auto result=CallWindowProcA(previousProc,window,message,wp,lp); if (message==WM_NCDESTROY) gameWindow.store(nullptr); return result; } static HWND WINAPI Create(DWORD ex,LPCSTR klass,LPCSTR title,DWORD style,int x,int y,int width,int height,HWND parent,HMENU menu,HINSTANCE instance,LPVOID param) { HWND window=createWindow(ex,klass,title,style,x,y,width,height,parent,menu,instance,param); if (window && !parent && title && reinterpret_cast(title)>65535 && !std::strcmp(title,"The Witcher 3") && !gameWindow.load()) { previousProc=reinterpret_cast(GetWindowLongPtrA(window,GWLP_WNDPROC)); gameWindow.store(window); SetLastError(0); auto old=SetWindowLongPtrA(window,GWLP_WNDPROC,reinterpret_cast(WindowProc)); if (!old && GetLastError()) { gameWindow.store(nullptr); Log("ERROR window subclass failed\n"); } else { previousProc=reinterpret_cast(old); Log("main window subclass installed\n"); // A pinned window can launch without ever receiving OS activation. CallWindowProcA(previousProc,window,WM_ACTIVATEAPP,TRUE,0); CallWindowProcA(previousProc,window,WM_ACTIVATE,WA_ACTIVE,0); CallWindowProcA(previousProc,window,WM_SETFOCUS,0,0); } } return window; } static HWND WINAPI Foreground() { auto window=gameWindow.load(); return window ? window : foreground(); } static BOOL WINAPI CursorPos(int x,int y) { return Hidden() ? TRUE : cursorPos(x,y); } static BOOL WINAPI Clip(const RECT* rect) { return clipCursor(Hidden() ? nullptr : rect); } static HWND WINAPI Capture(HWND window) { return Hidden() ? nullptr : setCapture(window); } static BOOL WINAPI Activate(HWND window) { return Hidden() && window==gameWindow.load() ? FALSE : setForeground(window); } static SHORT WINAPI Key(int key) { return Hidden() ? 0 : asyncKey(key); } BOOL WINAPI DllMain(HINSTANCE module,DWORD reason,LPVOID) { if (reason==DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(module); char path[MAX_PATH]{};GetModuleFileNameA(module,path,MAX_PATH); char* dot=std::strrchr(path,'.');if(dot)std::strcpy(dot,".log"); logFile=CreateFileA(path,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,nullptr,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,nullptr); bool ok=HookImport("USER32.dll","GetForegroundWindow",0,reinterpret_cast(Foreground),reinterpret_cast(&foreground)) && HookImport("USER32.dll","SetCursorPos",0,reinterpret_cast(CursorPos),reinterpret_cast(&cursorPos)) && HookImport("USER32.dll","ClipCursor",0,reinterpret_cast(Clip),reinterpret_cast(&clipCursor)) && HookImport("USER32.dll","SetCapture",0,reinterpret_cast(Capture),reinterpret_cast(&setCapture)) && HookImport("USER32.dll","SetForegroundWindow",0,reinterpret_cast(Activate),reinterpret_cast(&setForeground)) && HookImport("USER32.dll","GetAsyncKeyState",0,reinterpret_cast(Key),reinterpret_cast(&asyncKey)) && HookImport("USER32.dll","CreateWindowExA",0,reinterpret_cast(Create),reinterpret_cast(&createWindow)); if(!ok) { for(int i=hookCount-1;i>=0;--i) { DWORD protection; if(VirtualProtect(hooks[i].slot,sizeof(void*),PAGE_READWRITE,&protection)) { *hooks[i].slot=hooks[i].original; DWORD unused;VirtualProtect(hooks[i].slot,sizeof(void*),protection,&unused); } } Log("ERROR import set incomplete; rolled back\n"); } else Log("seven named imports installed\n"); } // Never unload dynamically; uninstall requires game closed. Process teardown // owns its address space and avoids racing a live window callback. return TRUE; }