20#include <freerdp/config.h>
22#include <winpr/assert.h>
23#include <winpr/error.h>
24#include <winpr/synch.h>
25#include <winpr/thread.h>
26#include <winpr/wlog.h>
28#include <freerdp/log.h>
31#define TAG CLIENT_TAG("common.windowinfo")
48 return s->detached ? nullptr : &s->source;
55 CWindowInfoService* s = (CWindowInfoService*)This;
60 HRESULT hr = E_UNEXPECTED;
61 EnterCriticalSection(&s->lock);
65 memset(windowInfo, 0,
sizeof(*windowInfo));
66 hr = src->GetWindowInfo(src->custom, remoteHwnd, windowInfo);
68 LeaveCriticalSection(&s->lock);
78 *processId = GetCurrentProcessId();
85 CWindowInfoService* s = (CWindowInfoService*)This;
89 HRESULT hr = E_UNEXPECTED;
90 EnterCriticalSection(&s->lock);
94 *sessionType = src->GetSessionType(src->custom);
97 LeaveCriticalSection(&s->lock);
101static HRESULT
WINPR_COM_CALL CWindowInfoService_SubscribeWindowChanged(
104 CWindowInfoService* s = (CWindowInfoService*)This;
105 WINPR_UNUSED(remoteHwnd);
110 EnterCriticalSection(&s->lock);
113 else if (s->subscriber)
114 hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
117 WINPR_COM_ADDREF(callback);
118 s->subscriber = callback;
120 LeaveCriticalSection(&s->lock);
127 CWindowInfoService* s = (CWindowInfoService*)This;
129 EnterCriticalSection(&s->lock);
131 s->subscriber =
nullptr;
132 LeaveCriticalSection(&s->lock);
135 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
136 WINPR_COM_RELEASE(callback);
142 .GetWindowInfo = CWindowInfoService_GetWindowInfo,
143 .GetProcessId = CWindowInfoService_GetProcessId,
144 .GetRdpSessionType = CWindowInfoService_GetRdpSessionType,
145 .SubscribeWindowChanged = CWindowInfoService_SubscribeWindowChanged,
146 .UnsubscribeWindowChanged = CWindowInfoService_UnsubscribeWindowChanged,
149static void CWindowInfoService_free(wComBase*
object)
151 CWindowInfoService* s = (CWindowInfoService*)
object;
153 WINPR_COM_RELEASE(s->subscriber);
154 DeleteCriticalSection(&s->lock);
160 WINPR_ASSERT(source);
164 CWindowInfoService* s = calloc(1,
sizeof(*s));
167 if (!InitializeCriticalSectionAndSpinCount(&s->lock, 4000))
173 CWindowInfoService_free);
180 CWindowInfoService* s = (CWindowInfoService*)service;
186 EnterCriticalSection(&s->lock);
188 if (src && s->subscriber && SUCCEEDED(src->GetWindowInfo(src->custom, remoteHwnd, &info)))
190 callback = s->subscriber;
191 WINPR_COM_ADDREF(callback);
193 LeaveCriticalSection(&s->lock);
198 const HRESULT hr = callback->lpVtbl->OnWindowChanged(callback, &info);
200 WLog_DBG(TAG,
"OnWindowChanged failed: 0x%08" PRIX32, (UINT32)hr);
201 WINPR_COM_RELEASE(callback);
206 CWindowInfoService* s = (CWindowInfoService*)service;
209 EnterCriticalSection(&s->lock);
211 LeaveCriticalSection(&s->lock);
WINPR_API void winpr_com_base_init(wComBase *object, const char *className, const wIUnknownVtbl *vtbl, pfnwComBaseFree Free)
sets the vtable and the reference count to 1, the caller owns that first reference.
#define WINPR_COM_IUNKNOWN_THUNKS(prefix, iid)
WINPR_COM_REFCOUNT_THUNKS plus prefix_QueryInterface answering IUnknown and iid (a const IID*,...
#define WINPR_COM_IUNKNOWN_ENTRIES(prefix)
the initializer of a wIUnknownVtbl from prefix_QueryInterface (the thunk above or the object's own),...
#define WINPR_COM_CALL
the calling convention of COM methods (STDMETHODCALLTYPE)
what the client gives the service to answer from
UINT32(* GetSessionType)(void *custom)
a WTS_RDP_SESSION_TYPE. Called from any thread.
HRESULT(* GetWindowInfo)(void *custom, UINT64 remoteHwnd, WTS_WINDOW_INFO *info)
fills info as Microsoft's client does (see WTS_WINDOW_INFO): for a desktop session the window showing...