#include "clientaccess.h" #include # include # include # include #include #include #include #include #include #include #include "defer.h" static const QString CLIENTNAME = "LeagueClientUx.exe"; static QString narrow(WCHAR* str, size_t len) { QString out; out.reserve(len); for(uint32_t i = 0; i < len && str[i]; ++i) { out.append(1, (char) str[i]); } return out; } static QString getProcessPath(DWORD dwPID) { // Take a snapshot of all modules in the specified process. HANDLE hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID ); if(hModuleSnap == INVALID_HANDLE_VALUE) { qCritical() << "CreateToolhelp32Snapshot (of modules) failed"; return {}; // empty string } defer( CloseHandle(hModuleSnap) ); // Set the size of the structure before using it. MODULEENTRY32 me32; me32.dwSize = sizeof(MODULEENTRY32); // Retrieve information about the first module, // and exit if unsuccessful if( !Module32First( hModuleSnap, &me32 ) ) { qCritical() << "Module32First"; return {}; } return narrow((WCHAR*) me32.szExePath, sizeof(me32.szExePath)); } static std::shared_ptr findUsingLockfile(PROCESSENTRY32& proc) { const QString exepath = getProcessPath(proc.th32ProcessID); Log::note << "exepath: " << exepath; // lockfile path const QString lockfilepath = exepath.substr(0, exepath.rfind('\\')+1) + "lockfile"; // possible out of bounds qDebug() << "Lockfile: " << lockfilepath; std::ifstream lockfile(lockfilepath); if(!lockfile) { qCritical() << "lockfile could not be opend"; return nullptr; } return createFromLockfile(lockfile); } std::shared_ptr ClientAccess::find() { // example code: https://docs.microsoft.com/de-de/windows/win32/toolhelp/taking-a-snapshot-and-viewing-processes // Take a snapshot of all processes in the system. HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == INVALID_HANDLE_VALUE) { qCritical() << "CreateToolhelp32Snapshot (of processes) failed"; return nullptr; } defer( CloseHandle(hProcessSnap) ); PROCESSENTRY32 pe32; // Set the size of the structure before using it. pe32.dwSize = sizeof(PROCESSENTRY32); // Retrieve information about the first process, // and exit if unsuccessful if (!Process32First(hProcessSnap, &pe32)) { qCritical() << "Process32First failed"; // show cause of failure return nullptr; } // Now walk the snapshot of processes, and // display information about each process in turn do { QString exename = narrow((WCHAR*) pe32.szExeFile, sizeof(pe32.szExeFile)); // Log::note << "found process: " << exename; if(exename == CLIENTNAME) { qInfo() << CLIENTNAME << " found"; std::shared_ptr out; out = findUsingLockfile(pe32); if(out) { return out; } } } while(Process32Next(hProcessSnap, &pe32)); return nullptr; }