refactor(win32): update MSWindowsSession and MsWindowsWatchdog to use MsWindowsHandle
This commit is contained in:
parent
d372462378
commit
6212f9bec6
2 changed files with 38 additions and 21 deletions
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "arch/win32/XArchWindows.h"
|
#include "arch/win32/XArchWindows.h"
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
|
#include "platform/MSWindowsHandle.h"
|
||||||
|
|
||||||
#include <Wtsapi32.h>
|
#include <Wtsapi32.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
@ -19,8 +20,8 @@ MSWindowsSession::MSWindowsSession() : m_activeSessionId(-1)
|
||||||
bool MSWindowsSession::isProcessInSession(const wchar_t *name, PHANDLE process = nullptr)
|
bool MSWindowsSession::isProcessInSession(const wchar_t *name, PHANDLE process = nullptr)
|
||||||
{
|
{
|
||||||
// first we need to take a snapshot of the running processes
|
// first we need to take a snapshot of the running processes
|
||||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
MSWindowsHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
|
||||||
if (snapshot == INVALID_HANDLE_VALUE) {
|
if (snapshot.get() == INVALID_HANDLE_VALUE) {
|
||||||
LOG_ERR("could not get process snapshot");
|
LOG_ERR("could not get process snapshot");
|
||||||
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
||||||
}
|
}
|
||||||
|
|
@ -30,7 +31,7 @@ bool MSWindowsSession::isProcessInSession(const wchar_t *name, PHANDLE process =
|
||||||
|
|
||||||
// get the first process, and if we can't do that then it's
|
// get the first process, and if we can't do that then it's
|
||||||
// unlikely we can go any further
|
// unlikely we can go any further
|
||||||
BOOL gotEntry = Process32First(snapshot, &entry);
|
BOOL gotEntry = Process32First(snapshot.get(), &entry);
|
||||||
if (!gotEntry) {
|
if (!gotEntry) {
|
||||||
LOG_ERR("could not get first process entry");
|
LOG_ERR("could not get first process entry");
|
||||||
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
||||||
|
|
@ -55,7 +56,7 @@ bool MSWindowsSession::isProcessInSession(const wchar_t *name, PHANDLE process =
|
||||||
LOG_VERBOSE(
|
LOG_VERBOSE(
|
||||||
"could not get session id for process: %i %s, code=%i", entry.th32ProcessID, entry.szExeFile, GetLastError()
|
"could not get session id for process: %i %s, code=%i", entry.th32ProcessID, entry.szExeFile, GetLastError()
|
||||||
);
|
);
|
||||||
gotEntry = nextProcessEntry(snapshot, &entry);
|
gotEntry = nextProcessEntry(snapshot.get(), &entry);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// only pay attention to processes in the active session
|
// only pay attention to processes in the active session
|
||||||
|
|
@ -72,7 +73,7 @@ bool MSWindowsSession::isProcessInSession(const wchar_t *name, PHANDLE process =
|
||||||
}
|
}
|
||||||
|
|
||||||
// now move on to the next entry (if we're not at the end)
|
// now move on to the next entry (if we're not at the end)
|
||||||
gotEntry = nextProcessEntry(snapshot, &entry);
|
gotEntry = nextProcessEntry(snapshot.get(), &entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring nameListJoin;
|
std::wstring nameListJoin;
|
||||||
|
|
@ -83,13 +84,15 @@ bool MSWindowsSession::isProcessInSession(const wchar_t *name, PHANDLE process =
|
||||||
|
|
||||||
LOG_VERBOSE("processes in session %d: %s", m_activeSessionId, nameListJoin.c_str());
|
LOG_VERBOSE("processes in session %d: %s", m_activeSessionId, nameListJoin.c_str());
|
||||||
|
|
||||||
CloseHandle(snapshot);
|
|
||||||
|
|
||||||
if (pid) {
|
if (pid) {
|
||||||
if (process != nullptr) {
|
if (process != nullptr) {
|
||||||
// now get the process, which we'll use to get the process token.
|
// now get the process, which we'll use to get the process token.
|
||||||
LOG_DEBUG("found %s in session %i", name, m_activeSessionId);
|
LOG_DEBUG("found %s in session %i", name, m_activeSessionId);
|
||||||
*process = OpenProcess(MAXIMUM_ALLOWED, FALSE, pid);
|
*process = OpenProcess(MAXIMUM_ALLOWED, FALSE, pid);
|
||||||
|
if (*process == nullptr) {
|
||||||
|
LOG_WARN("found %s in session %i but could not open process handle", name, m_activeSessionId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -111,11 +114,12 @@ MSWindowsSession::getUserToken(LPSECURITY_ATTRIBUTES security)
|
||||||
if (!DuplicateTokenEx(
|
if (!DuplicateTokenEx(
|
||||||
sourceToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, security, SecurityImpersonation, TokenPrimary, &newToken
|
sourceToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, security, SecurityImpersonation, TokenPrimary, &newToken
|
||||||
)) {
|
)) {
|
||||||
|
CloseHandle(sourceToken);
|
||||||
LOG_ERR("could not duplicate token");
|
LOG_ERR("could not duplicate token");
|
||||||
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CloseHandle(sourceToken);
|
||||||
LOG_DEBUG("duplicated, new token: %i", newToken);
|
LOG_DEBUG("duplicated, new token: %i", newToken);
|
||||||
return newToken;
|
return newToken;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,14 @@ HANDLE openProcessForKill(const PROCESSENTRY32 &entry)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
|
const DWORD desiredAccess = PROCESS_TERMINATE | PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE;
|
||||||
|
HANDLE handle = OpenProcess(desiredAccess, FALSE, entry.th32ProcessID);
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
LOG_ERR("could not open process handle for kill");
|
LOG_WARN(
|
||||||
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
"could not open process handle for kill, pid=%u, error=%s", entry.th32ProcessID,
|
||||||
|
windowsErrorToString(GetLastError()).c_str()
|
||||||
|
);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// only shut down if not current process (daemon is now the same unified binary).
|
// only shut down if not current process (daemon is now the same unified binary).
|
||||||
|
|
@ -116,10 +120,12 @@ MSWindowsWatchdog::duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES s
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!duplicateRet) {
|
if (!duplicateRet) {
|
||||||
|
CloseHandle(sourceToken);
|
||||||
LOG_ERR("could not duplicate token %i", sourceToken);
|
LOG_ERR("could not duplicate token %i", sourceToken);
|
||||||
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CloseHandle(sourceToken);
|
||||||
LOG_DEBUG("duplicated, new token: %i", newToken);
|
LOG_DEBUG("duplicated, new token: %i", newToken);
|
||||||
return newToken;
|
return newToken;
|
||||||
}
|
}
|
||||||
|
|
@ -137,13 +143,22 @@ MSWindowsWatchdog::getUserToken(LPSECURITY_ATTRIBUTES security, bool elevatedTok
|
||||||
if (!m_session.isProcessInSession(L"winlogon.exe", &process)) {
|
if (!m_session.isProcessInSession(L"winlogon.exe", &process)) {
|
||||||
throw std::runtime_error("cannot get user token without winlogon.exe");
|
throw std::runtime_error("cannot get user token without winlogon.exe");
|
||||||
}
|
}
|
||||||
|
if (process == nullptr) {
|
||||||
|
throw std::runtime_error("found winlogon.exe but failed to open process handle");
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return duplicateProcessToken(process, security);
|
HANDLE token = duplicateProcessToken(process, security);
|
||||||
} catch (std::runtime_error &e) {
|
if (process != nullptr) {
|
||||||
|
CloseHandle(process);
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
} catch (...) {
|
||||||
LOG_ERR("failed to duplicate user token from winlogon.exe");
|
LOG_ERR("failed to duplicate user token from winlogon.exe");
|
||||||
CloseHandle(process);
|
if (process != nullptr) {
|
||||||
throw e;
|
CloseHandle(process);
|
||||||
|
}
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("getting non-elevated token");
|
LOG_DEBUG("getting non-elevated token");
|
||||||
|
|
@ -371,8 +386,8 @@ void MSWindowsWatchdog::shutdownExistingProcesses()
|
||||||
const auto kAllProcesses = 0;
|
const auto kAllProcesses = 0;
|
||||||
|
|
||||||
// first we need to take a snapshot of the running processes
|
// first we need to take a snapshot of the running processes
|
||||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, kAllProcesses);
|
MSWindowsHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, kAllProcesses));
|
||||||
if (snapshot == INVALID_HANDLE_VALUE) {
|
if (snapshot.get() == INVALID_HANDLE_VALUE) {
|
||||||
LOG_ERR("could not get process snapshot");
|
LOG_ERR("could not get process snapshot");
|
||||||
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
||||||
}
|
}
|
||||||
|
|
@ -382,7 +397,7 @@ void MSWindowsWatchdog::shutdownExistingProcesses()
|
||||||
|
|
||||||
// get the first process, and if we can't do that then it's
|
// get the first process, and if we can't do that then it's
|
||||||
// unlikely we can go any further
|
// unlikely we can go any further
|
||||||
BOOL gotEntry = Process32First(snapshot, &entry);
|
BOOL gotEntry = Process32First(snapshot.get(), &entry);
|
||||||
if (!gotEntry) {
|
if (!gotEntry) {
|
||||||
LOG_ERR("could not get first process entry");
|
LOG_ERR("could not get first process entry");
|
||||||
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
throw std::runtime_error(windowsErrorToString(GetLastError()));
|
||||||
|
|
@ -398,7 +413,7 @@ void MSWindowsWatchdog::shutdownExistingProcesses()
|
||||||
}
|
}
|
||||||
|
|
||||||
// now move on to the next entry (if we're not at the end)
|
// now move on to the next entry (if we're not at the end)
|
||||||
gotEntry = Process32Next(snapshot, &entry);
|
gotEntry = Process32Next(snapshot.get(), &entry);
|
||||||
if (!gotEntry) {
|
if (!gotEntry) {
|
||||||
|
|
||||||
DWORD err = GetLastError();
|
DWORD err = GetLastError();
|
||||||
|
|
@ -410,8 +425,6 @@ void MSWindowsWatchdog::shutdownExistingProcesses()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(snapshot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MSWindowsWatchdog::ProcessState MSWindowsWatchdog::handleStartError(const std::string_view &message)
|
MSWindowsWatchdog::ProcessState MSWindowsWatchdog::handleStartError(const std::string_view &message)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue