lolautoaccept/src/clientaccess_windows.cpp

115 lines
2.9 KiB
C++

#include "clientaccess.h"
#include <cstring>
# include <windows.h>
# include <tlhelp32.h>
# include <tchar.h>
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
#include <Log.h>
#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<ClientAccess> 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> 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<ClientAccess> out;
out = findUsingLockfile(pe32);
if(out) {
return out;
}
}
} while(Process32Next(hProcessSnap, &pe32));
return nullptr;
}