mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-20 19:14:39 +08:00
[fix] correct Windows remote control session routing and key mapping
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#define _INTERACTIVE_DESKTOP_H_
|
||||
|
||||
#include <Windows.h>
|
||||
#include <WtsApi32.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -33,6 +34,52 @@ inline std::wstring GetDesktopNameW(HDESK desktop) {
|
||||
return name;
|
||||
}
|
||||
|
||||
inline bool IsDesktopReceivingInput(HDESK desktop) {
|
||||
BOOL receiving_input = FALSE;
|
||||
return desktop != nullptr &&
|
||||
GetUserObjectInformationW(desktop, UOI_IO, &receiving_input,
|
||||
sizeof(receiving_input), nullptr) &&
|
||||
receiving_input != FALSE;
|
||||
}
|
||||
|
||||
inline bool IsCurrentProcessSession(DWORD session_id) {
|
||||
DWORD process_session_id = 0xFFFFFFFF;
|
||||
return session_id != 0xFFFFFFFF &&
|
||||
ProcessIdToSessionId(GetCurrentProcessId(), &process_session_id) &&
|
||||
session_id == process_session_id;
|
||||
}
|
||||
|
||||
inline bool IsCurrentSessionUnlocked() {
|
||||
DWORD session_id = 0xFFFFFFFF;
|
||||
if (!ProcessIdToSessionId(GetCurrentProcessId(), &session_id)) return false;
|
||||
PWTSINFOEXW info = nullptr;
|
||||
DWORD bytes = 0;
|
||||
if (!WTSQuerySessionInformationW(
|
||||
WTS_CURRENT_SERVER_HANDLE, session_id, WTSSessionInfoEx,
|
||||
reinterpret_cast<LPWSTR*>(&info), &bytes)) {
|
||||
return false;
|
||||
}
|
||||
const bool unlocked =
|
||||
info != nullptr && bytes >= sizeof(WTSINFOEXW) && info->Level == 1 &&
|
||||
info->Data.WTSInfoExLevel1.SessionState == WTSActive &&
|
||||
info->Data.WTSInfoExLevel1.SessionFlags == WTS_SESSIONSTATE_UNLOCK;
|
||||
if (info != nullptr) WTSFreeMemory(info);
|
||||
return unlocked;
|
||||
}
|
||||
|
||||
inline bool IsCurrentSessionUserDesktopActive() {
|
||||
// LockApp can be visible on Default while the session is still locked.
|
||||
if (!IsCurrentSessionUnlocked()) return false;
|
||||
HDESK desktop = OpenInputDesktop(0, FALSE, DESKTOP_READOBJECTS);
|
||||
if (desktop == nullptr) return false;
|
||||
// OpenInputDesktop also succeeds in disconnected RDP sessions. The name
|
||||
// alone does not tell us whether this desktop can currently receive input.
|
||||
const bool active = IsDesktopReceivingInput(desktop) &&
|
||||
_wcsicmp(GetDesktopNameW(desktop).c_str(), L"Default") == 0;
|
||||
CloseDesktop(desktop);
|
||||
return active;
|
||||
}
|
||||
|
||||
// Use only on worker threads without windows or hooks. Restore the original
|
||||
// desktop before closing the handle: Windows cannot close a desktop in use.
|
||||
class ScopedInteractiveDesktop {
|
||||
@@ -88,6 +135,10 @@ class ScopedInteractiveDesktop {
|
||||
return !name_.empty() && _wcsicmp(name_.c_str(), input_name.c_str()) == 0;
|
||||
}
|
||||
|
||||
bool IsReceivingInput() const {
|
||||
return IsDesktopReceivingInput(desktop_);
|
||||
}
|
||||
|
||||
const std::wstring& name() const { return name_; }
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user