I'm working on an application that runs with SYSTEM level privileges and is created by the SYSTEM user. I need to track foreground activities for the currently logged-in user. I'm using SetWinEventHook for the same. It works fine when I run the application from my current user. But if I started the application with the SYSTEM user, it was unable to receive events. Is there any workaround to trigger this with user context?
Edit: g_hook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, NULL, focusChangeCallbackHandle, 0, 0, WINEVENT_OUTOFCONTEXT); focusChangeCallbackHandle is a in same namespace as the caller function
Edit 2:
Adding my boilerplate code here: I'm using pstools to run the binary with the SYSTEM user. Also not sure why but after running any of the getter/setters of ThreadDesktop and WindowStation my application stop printing on the console.
void ForegroundCheck() {
printf("In thread \n");
HWINSTA orgWS = GetProcessWindowStation();
printf("Done GetProcessWindowStation \n");
if (orgWS) {
printf("In GetProcessWindowStation \n");
HWINSTA itrWS = OpenWindowStation(TEXT("WinSta0"), true, GENERIC_ALL);
if (itrWS) {
printf("In OpenWindowStation \n");
if (SetProcessWindowStation(itrWS)) {
printf("In SetProcessWindowStation \n");
HDESK iD = OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, true, GENERIC_ALL);
if (iD) {
if (!SetThreadDesktop(iD)) {
printf("SetThreadDesktop failed: %lu \n", GetLastError());
} else {
printf("setting hoook");
// SetWinEventHook sets the hook for the mentioned event.
// In current case EVENT_SYSTEM_FOREGROUND. When ever EVENT_SYSTEM_FOREGROUND is triggerd HandleWinEvent will be called
g_hook = SetWinEventHook(
EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, // Range of events (4 to 5).
NULL, // Handle to DLL.
HandleWinEvent, // The callback.
0, 0, // Process and thread IDs of interest (0 = all)
WINEVENT_OUTOFCONTEXT);
MSG msg;
//GetMessage(&msg, NULL, 0, 0);
while (WaitMessage() && set) {
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
}
}
} else {
printf("OpenInputDesktop failed: %lu \n", GetLastError());
}
SetProcessWindowStation(orgWS);
} else {
printf("SetProcessWindowStation failed: %lu \n", GetLastError());
}
CloseWindowStation(itrWS);
} else {
printf("OpenWindowStation failed: %lu \n", GetLastError());
}
} else {
printf("GetProcessWindowStation failed: %lu \n", GetLastError());
}
}
int main() {
bool retVal = false;
printf("In Main \n");
CoInitialize(NULL);
std::thread t(ForegroundCheck);
printf("In thread started \n");
std::cin.get();
// Deinit
UnhookWinEvent(g_hook);
set = false;
t.join();
CoUninitialize();
return 0;
}
Thanks