Coverage Report

Created: 2023-11-19 06:16

/src/FreeRDP/winpr/libwinpr/wtsapi/wtsapi.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * WinPR: Windows Portable Runtime
3
 * Windows Terminal Services API
4
 *
5
 * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
7
 * Copyright 2015 Copyright 2015 Thincast Technologies GmbH
8
 *
9
 * Licensed under the Apache License, Version 2.0 (the "License");
10
 * you may not use this file except in compliance with the License.
11
 * You may obtain a copy of the License at
12
 *
13
 *     http://www.apache.org/licenses/LICENSE-2.0
14
 *
15
 * Unless required by applicable law or agreed to in writing, software
16
 * distributed under the License is distributed on an "AS IS" BASIS,
17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
 * See the License for the specific language governing permissions and
19
 * limitations under the License.
20
 */
21
22
#include <winpr/config.h>
23
24
#include <winpr/crt.h>
25
#include <winpr/ini.h>
26
#include <winpr/path.h>
27
#include <winpr/synch.h>
28
#include <winpr/library.h>
29
#include <winpr/environment.h>
30
31
#include <winpr/wtsapi.h>
32
33
#ifdef _WIN32
34
#include "wtsapi_win32.h"
35
#endif
36
37
#include "../log.h"
38
#define TAG WINPR_TAG("wtsapi")
39
40
/**
41
 * Remote Desktop Services API Functions:
42
 * http://msdn.microsoft.com/en-us/library/windows/desktop/aa383464/
43
 */
44
45
static HMODULE g_WtsApiModule = NULL;
46
47
static const WtsApiFunctionTable* g_WtsApi = NULL;
48
49
#if defined(_WIN32)
50
static HMODULE g_WtsApi32Module = NULL;
51
static WtsApiFunctionTable WtsApi32_WtsApiFunctionTable = { 0 };
52
53
#ifdef __MINGW32__
54
#define WTSAPI32_LOAD_PROC(NAME, TYPE) \
55
  WtsApi32_WtsApiFunctionTable.p##NAME = (TYPE)GetProcAddress(g_WtsApi32Module, "WTS" #NAME);
56
#else
57
#define WTSAPI32_LOAD_PROC(NAME, TYPE) \
58
  WtsApi32_WtsApiFunctionTable.p##NAME = (##TYPE)GetProcAddress(g_WtsApi32Module, "WTS" #NAME);
59
#endif
60
61
static BOOL WtsApi32_InitializeWtsApi(void)
62
{
63
  g_WtsApi32Module = LoadLibraryA("wtsapi32.dll");
64
65
  if (!g_WtsApi32Module)
66
    return FALSE;
67
68
  WTSAPI32_LOAD_PROC(StopRemoteControlSession, WTS_STOP_REMOTE_CONTROL_SESSION_FN);
69
  WTSAPI32_LOAD_PROC(StartRemoteControlSessionW, WTS_START_REMOTE_CONTROL_SESSION_FN_W);
70
  WTSAPI32_LOAD_PROC(StartRemoteControlSessionA, WTS_START_REMOTE_CONTROL_SESSION_FN_A);
71
  WTSAPI32_LOAD_PROC(ConnectSessionW, WTS_CONNECT_SESSION_FN_W);
72
  WTSAPI32_LOAD_PROC(ConnectSessionA, WTS_CONNECT_SESSION_FN_A);
73
  WTSAPI32_LOAD_PROC(EnumerateServersW, WTS_ENUMERATE_SERVERS_FN_W);
74
  WTSAPI32_LOAD_PROC(EnumerateServersA, WTS_ENUMERATE_SERVERS_FN_A);
75
  WTSAPI32_LOAD_PROC(OpenServerW, WTS_OPEN_SERVER_FN_W);
76
  WTSAPI32_LOAD_PROC(OpenServerA, WTS_OPEN_SERVER_FN_A);
77
  WTSAPI32_LOAD_PROC(OpenServerExW, WTS_OPEN_SERVER_EX_FN_W);
78
  WTSAPI32_LOAD_PROC(OpenServerExA, WTS_OPEN_SERVER_EX_FN_A);
79
  WTSAPI32_LOAD_PROC(CloseServer, WTS_CLOSE_SERVER_FN);
80
  WTSAPI32_LOAD_PROC(EnumerateSessionsW, WTS_ENUMERATE_SESSIONS_FN_W);
81
  WTSAPI32_LOAD_PROC(EnumerateSessionsA, WTS_ENUMERATE_SESSIONS_FN_A);
82
  WTSAPI32_LOAD_PROC(EnumerateSessionsExW, WTS_ENUMERATE_SESSIONS_EX_FN_W);
83
  WTSAPI32_LOAD_PROC(EnumerateSessionsExA, WTS_ENUMERATE_SESSIONS_EX_FN_A);
84
  WTSAPI32_LOAD_PROC(EnumerateProcessesW, WTS_ENUMERATE_PROCESSES_FN_W);
85
  WTSAPI32_LOAD_PROC(EnumerateProcessesA, WTS_ENUMERATE_PROCESSES_FN_A);
86
  WTSAPI32_LOAD_PROC(TerminateProcess, WTS_TERMINATE_PROCESS_FN);
87
  WTSAPI32_LOAD_PROC(QuerySessionInformationW, WTS_QUERY_SESSION_INFORMATION_FN_W);
88
  WTSAPI32_LOAD_PROC(QuerySessionInformationA, WTS_QUERY_SESSION_INFORMATION_FN_A);
89
  WTSAPI32_LOAD_PROC(QueryUserConfigW, WTS_QUERY_USER_CONFIG_FN_W);
90
  WTSAPI32_LOAD_PROC(QueryUserConfigA, WTS_QUERY_USER_CONFIG_FN_A);
91
  WTSAPI32_LOAD_PROC(SetUserConfigW, WTS_SET_USER_CONFIG_FN_W);
92
  WTSAPI32_LOAD_PROC(SetUserConfigA, WTS_SET_USER_CONFIG_FN_A);
93
  WTSAPI32_LOAD_PROC(SendMessageW, WTS_SEND_MESSAGE_FN_W);
94
  WTSAPI32_LOAD_PROC(SendMessageA, WTS_SEND_MESSAGE_FN_A);
95
  WTSAPI32_LOAD_PROC(DisconnectSession, WTS_DISCONNECT_SESSION_FN);
96
  WTSAPI32_LOAD_PROC(LogoffSession, WTS_LOGOFF_SESSION_FN);
97
  WTSAPI32_LOAD_PROC(ShutdownSystem, WTS_SHUTDOWN_SYSTEM_FN);
98
  WTSAPI32_LOAD_PROC(WaitSystemEvent, WTS_WAIT_SYSTEM_EVENT_FN);
99
  WTSAPI32_LOAD_PROC(VirtualChannelOpen, WTS_VIRTUAL_CHANNEL_OPEN_FN);
100
  WTSAPI32_LOAD_PROC(VirtualChannelOpenEx, WTS_VIRTUAL_CHANNEL_OPEN_EX_FN);
101
  WTSAPI32_LOAD_PROC(VirtualChannelClose, WTS_VIRTUAL_CHANNEL_CLOSE_FN);
102
  WTSAPI32_LOAD_PROC(VirtualChannelRead, WTS_VIRTUAL_CHANNEL_READ_FN);
103
  WTSAPI32_LOAD_PROC(VirtualChannelWrite, WTS_VIRTUAL_CHANNEL_WRITE_FN);
104
  WTSAPI32_LOAD_PROC(VirtualChannelPurgeInput, WTS_VIRTUAL_CHANNEL_PURGE_INPUT_FN);
105
  WTSAPI32_LOAD_PROC(VirtualChannelPurgeOutput, WTS_VIRTUAL_CHANNEL_PURGE_OUTPUT_FN);
106
  WTSAPI32_LOAD_PROC(VirtualChannelQuery, WTS_VIRTUAL_CHANNEL_QUERY_FN);
107
  WTSAPI32_LOAD_PROC(FreeMemory, WTS_FREE_MEMORY_FN);
108
  WTSAPI32_LOAD_PROC(RegisterSessionNotification, WTS_REGISTER_SESSION_NOTIFICATION_FN);
109
  WTSAPI32_LOAD_PROC(UnRegisterSessionNotification, WTS_UNREGISTER_SESSION_NOTIFICATION_FN);
110
  WTSAPI32_LOAD_PROC(RegisterSessionNotificationEx, WTS_REGISTER_SESSION_NOTIFICATION_EX_FN);
111
  WTSAPI32_LOAD_PROC(UnRegisterSessionNotificationEx, WTS_UNREGISTER_SESSION_NOTIFICATION_EX_FN);
112
  WTSAPI32_LOAD_PROC(QueryUserToken, WTS_QUERY_USER_TOKEN_FN);
113
  WTSAPI32_LOAD_PROC(FreeMemoryExW, WTS_FREE_MEMORY_EX_FN_W);
114
  WTSAPI32_LOAD_PROC(FreeMemoryExA, WTS_FREE_MEMORY_EX_FN_A);
115
  WTSAPI32_LOAD_PROC(EnumerateProcessesExW, WTS_ENUMERATE_PROCESSES_EX_FN_W);
116
  WTSAPI32_LOAD_PROC(EnumerateProcessesExA, WTS_ENUMERATE_PROCESSES_EX_FN_A);
117
  WTSAPI32_LOAD_PROC(EnumerateListenersW, WTS_ENUMERATE_LISTENERS_FN_W);
118
  WTSAPI32_LOAD_PROC(EnumerateListenersA, WTS_ENUMERATE_LISTENERS_FN_A);
119
  WTSAPI32_LOAD_PROC(QueryListenerConfigW, WTS_QUERY_LISTENER_CONFIG_FN_W);
120
  WTSAPI32_LOAD_PROC(QueryListenerConfigA, WTS_QUERY_LISTENER_CONFIG_FN_A);
121
  WTSAPI32_LOAD_PROC(CreateListenerW, WTS_CREATE_LISTENER_FN_W);
122
  WTSAPI32_LOAD_PROC(CreateListenerA, WTS_CREATE_LISTENER_FN_A);
123
  WTSAPI32_LOAD_PROC(SetListenerSecurityW, WTS_SET_LISTENER_SECURITY_FN_W);
124
  WTSAPI32_LOAD_PROC(SetListenerSecurityA, WTS_SET_LISTENER_SECURITY_FN_A);
125
  WTSAPI32_LOAD_PROC(GetListenerSecurityW, WTS_GET_LISTENER_SECURITY_FN_W);
126
  WTSAPI32_LOAD_PROC(GetListenerSecurityA, WTS_GET_LISTENER_SECURITY_FN_A);
127
  WTSAPI32_LOAD_PROC(EnableChildSessions, WTS_ENABLE_CHILD_SESSIONS_FN);
128
  WTSAPI32_LOAD_PROC(IsChildSessionsEnabled, WTS_IS_CHILD_SESSIONS_ENABLED_FN);
129
  WTSAPI32_LOAD_PROC(GetChildSessionId, WTS_GET_CHILD_SESSION_ID_FN);
130
  WTSAPI32_LOAD_PROC(GetActiveConsoleSessionId, WTS_GET_ACTIVE_CONSOLE_SESSION_ID_FN);
131
132
  Win32_InitializeWinSta(&WtsApi32_WtsApiFunctionTable);
133
134
  g_WtsApi = &WtsApi32_WtsApiFunctionTable;
135
136
  return TRUE;
137
}
138
#endif
139
140
/* WtsApi Functions */
141
142
static BOOL CALLBACK InitializeWtsApiStubs(PINIT_ONCE once, PVOID param, PVOID* context);
143
static INIT_ONCE wtsapiInitOnce = INIT_ONCE_STATIC_INIT;
144
145
#define WTSAPI_STUB_CALL_VOID(_name, ...)                                    \
146
0
  InitOnceExecuteOnce(&wtsapiInitOnce, InitializeWtsApiStubs, NULL, NULL); \
147
0
  if (!g_WtsApi || !g_WtsApi->p##_name)                                    \
148
0
    return;                                                              \
149
0
  g_WtsApi->p##_name(__VA_ARGS__)
150
151
#define WTSAPI_STUB_CALL_BOOL(_name, ...)                                    \
152
0
  InitOnceExecuteOnce(&wtsapiInitOnce, InitializeWtsApiStubs, NULL, NULL); \
153
0
  if (!g_WtsApi || !g_WtsApi->p##_name)                                    \
154
0
    return FALSE;                                                        \
155
0
  return g_WtsApi->p##_name(__VA_ARGS__)
156
157
#define WTSAPI_STUB_CALL_HANDLE(_name, ...)                                  \
158
0
  InitOnceExecuteOnce(&wtsapiInitOnce, InitializeWtsApiStubs, NULL, NULL); \
159
0
  if (!g_WtsApi || !g_WtsApi->p##_name)                                    \
160
0
    return NULL;                                                         \
161
0
  return g_WtsApi->p##_name(__VA_ARGS__)
162
163
BOOL WINAPI WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId,
164
                                          BYTE HotkeyVk, USHORT HotkeyModifiers)
165
0
{
166
0
  WTSAPI_STUB_CALL_BOOL(StartRemoteControlSessionW, pTargetServerName, TargetLogonId, HotkeyVk,
167
0
                        HotkeyModifiers);
168
0
}
169
170
BOOL WINAPI WTSStartRemoteControlSessionA(LPSTR pTargetServerName, ULONG TargetLogonId,
171
                                          BYTE HotkeyVk, USHORT HotkeyModifiers)
172
0
{
173
0
  WTSAPI_STUB_CALL_BOOL(StartRemoteControlSessionA, pTargetServerName, TargetLogonId, HotkeyVk,
174
0
                        HotkeyModifiers);
175
0
}
176
177
BOOL WINAPI WTSStartRemoteControlSessionExW(LPWSTR pTargetServerName, ULONG TargetLogonId,
178
                                            BYTE HotkeyVk, USHORT HotkeyModifiers, DWORD flags)
179
0
{
180
0
  WTSAPI_STUB_CALL_BOOL(StartRemoteControlSessionExW, pTargetServerName, TargetLogonId, HotkeyVk,
181
0
                        HotkeyModifiers, flags);
182
0
}
183
184
BOOL WINAPI WTSStartRemoteControlSessionExA(LPSTR pTargetServerName, ULONG TargetLogonId,
185
                                            BYTE HotkeyVk, USHORT HotkeyModifiers, DWORD flags)
186
0
{
187
0
  WTSAPI_STUB_CALL_BOOL(StartRemoteControlSessionExA, pTargetServerName, TargetLogonId, HotkeyVk,
188
0
                        HotkeyModifiers, flags);
189
0
}
190
191
BOOL WINAPI WTSStopRemoteControlSession(ULONG LogonId)
192
0
{
193
0
  WTSAPI_STUB_CALL_BOOL(StopRemoteControlSession, LogonId);
194
0
}
195
196
BOOL WINAPI WTSConnectSessionW(ULONG LogonId, ULONG TargetLogonId, PWSTR pPassword, BOOL bWait)
197
0
{
198
0
  WTSAPI_STUB_CALL_BOOL(ConnectSessionW, LogonId, TargetLogonId, pPassword, bWait);
199
0
}
200
201
BOOL WINAPI WTSConnectSessionA(ULONG LogonId, ULONG TargetLogonId, PSTR pPassword, BOOL bWait)
202
0
{
203
0
  WTSAPI_STUB_CALL_BOOL(ConnectSessionA, LogonId, TargetLogonId, pPassword, bWait);
204
0
}
205
206
BOOL WINAPI WTSEnumerateServersW(LPWSTR pDomainName, DWORD Reserved, DWORD Version,
207
                                 PWTS_SERVER_INFOW* ppServerInfo, DWORD* pCount)
208
0
{
209
0
  WTSAPI_STUB_CALL_BOOL(EnumerateServersW, pDomainName, Reserved, Version, ppServerInfo, pCount);
210
0
}
211
212
BOOL WINAPI WTSEnumerateServersA(LPSTR pDomainName, DWORD Reserved, DWORD Version,
213
                                 PWTS_SERVER_INFOA* ppServerInfo, DWORD* pCount)
214
0
{
215
0
  WTSAPI_STUB_CALL_BOOL(EnumerateServersA, pDomainName, Reserved, Version, ppServerInfo, pCount);
216
0
}
217
218
HANDLE WINAPI WTSOpenServerW(LPWSTR pServerName)
219
0
{
220
0
  WTSAPI_STUB_CALL_HANDLE(OpenServerW, pServerName);
221
0
}
222
223
HANDLE WINAPI WTSOpenServerA(LPSTR pServerName)
224
0
{
225
0
  WTSAPI_STUB_CALL_HANDLE(OpenServerA, pServerName);
226
0
}
227
228
HANDLE WINAPI WTSOpenServerExW(LPWSTR pServerName)
229
0
{
230
0
  WTSAPI_STUB_CALL_HANDLE(OpenServerExW, pServerName);
231
0
}
232
233
HANDLE WINAPI WTSOpenServerExA(LPSTR pServerName)
234
0
{
235
0
  WTSAPI_STUB_CALL_HANDLE(OpenServerExA, pServerName);
236
0
}
237
238
VOID WINAPI WTSCloseServer(HANDLE hServer)
239
0
{
240
0
  WTSAPI_STUB_CALL_VOID(CloseServer, hServer);
241
0
}
242
243
BOOL WINAPI WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version,
244
                                  PWTS_SESSION_INFOW* ppSessionInfo, DWORD* pCount)
245
0
{
246
0
  WTSAPI_STUB_CALL_BOOL(EnumerateSessionsW, hServer, Reserved, Version, ppSessionInfo, pCount);
247
0
}
248
249
BOOL WINAPI WTSEnumerateSessionsA(HANDLE hServer, DWORD Reserved, DWORD Version,
250
                                  PWTS_SESSION_INFOA* ppSessionInfo, DWORD* pCount)
251
0
{
252
0
  WTSAPI_STUB_CALL_BOOL(EnumerateSessionsA, hServer, Reserved, Version, ppSessionInfo, pCount);
253
0
}
254
255
BOOL WINAPI WTSEnumerateSessionsExW(HANDLE hServer, DWORD* pLevel, DWORD Filter,
256
                                    PWTS_SESSION_INFO_1W* ppSessionInfo, DWORD* pCount)
257
0
{
258
0
  WTSAPI_STUB_CALL_BOOL(EnumerateSessionsExW, hServer, pLevel, Filter, ppSessionInfo, pCount);
259
0
}
260
261
BOOL WINAPI WTSEnumerateSessionsExA(HANDLE hServer, DWORD* pLevel, DWORD Filter,
262
                                    PWTS_SESSION_INFO_1A* ppSessionInfo, DWORD* pCount)
263
0
{
264
0
  WTSAPI_STUB_CALL_BOOL(EnumerateSessionsExA, hServer, pLevel, Filter, ppSessionInfo, pCount);
265
0
}
266
267
BOOL WINAPI WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version,
268
                                   PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount)
269
0
{
270
0
  WTSAPI_STUB_CALL_BOOL(EnumerateProcessesW, hServer, Reserved, Version, ppProcessInfo, pCount);
271
0
}
272
273
BOOL WINAPI WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version,
274
                                   PWTS_PROCESS_INFOA* ppProcessInfo, DWORD* pCount)
275
0
{
276
0
  WTSAPI_STUB_CALL_BOOL(EnumerateProcessesA, hServer, Reserved, Version, ppProcessInfo, pCount);
277
0
}
278
279
BOOL WINAPI WTSTerminateProcess(HANDLE hServer, DWORD ProcessId, DWORD ExitCode)
280
0
{
281
0
  WTSAPI_STUB_CALL_BOOL(TerminateProcess, hServer, ProcessId, ExitCode);
282
0
}
283
284
BOOL WINAPI WTSQuerySessionInformationW(HANDLE hServer, DWORD SessionId,
285
                                        WTS_INFO_CLASS WTSInfoClass, LPWSTR* ppBuffer,
286
                                        DWORD* pBytesReturned)
287
0
{
288
0
  WTSAPI_STUB_CALL_BOOL(QuerySessionInformationW, hServer, SessionId, WTSInfoClass, ppBuffer,
289
0
                        pBytesReturned);
290
0
}
291
292
BOOL WINAPI WTSQuerySessionInformationA(HANDLE hServer, DWORD SessionId,
293
                                        WTS_INFO_CLASS WTSInfoClass, LPSTR* ppBuffer,
294
                                        DWORD* pBytesReturned)
295
0
{
296
0
  WTSAPI_STUB_CALL_BOOL(QuerySessionInformationA, hServer, SessionId, WTSInfoClass, ppBuffer,
297
0
                        pBytesReturned);
298
0
}
299
300
BOOL WINAPI WTSQueryUserConfigW(LPWSTR pServerName, LPWSTR pUserName,
301
                                WTS_CONFIG_CLASS WTSConfigClass, LPWSTR* ppBuffer,
302
                                DWORD* pBytesReturned)
303
0
{
304
0
  WTSAPI_STUB_CALL_BOOL(QueryUserConfigW, pServerName, pUserName, WTSConfigClass, ppBuffer,
305
0
                        pBytesReturned);
306
0
}
307
308
BOOL WINAPI WTSQueryUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass,
309
                                LPSTR* ppBuffer, DWORD* pBytesReturned)
310
0
{
311
0
  WTSAPI_STUB_CALL_BOOL(QueryUserConfigA, pServerName, pUserName, WTSConfigClass, ppBuffer,
312
0
                        pBytesReturned);
313
0
}
314
315
BOOL WINAPI WTSSetUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass,
316
                              LPWSTR pBuffer, DWORD DataLength)
317
0
{
318
0
  WTSAPI_STUB_CALL_BOOL(SetUserConfigW, pServerName, pUserName, WTSConfigClass, pBuffer,
319
0
                        DataLength);
320
0
}
321
322
BOOL WINAPI WTSSetUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass,
323
                              LPSTR pBuffer, DWORD DataLength)
324
0
{
325
0
  WTSAPI_STUB_CALL_BOOL(SetUserConfigA, pServerName, pUserName, WTSConfigClass, pBuffer,
326
0
                        DataLength);
327
0
}
328
329
BOOL WINAPI WTSSendMessageW(HANDLE hServer, DWORD SessionId, LPWSTR pTitle, DWORD TitleLength,
330
                            LPWSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout,
331
                            DWORD* pResponse, BOOL bWait)
332
0
{
333
0
  WTSAPI_STUB_CALL_BOOL(SendMessageW, hServer, SessionId, pTitle, TitleLength, pMessage,
334
0
                        MessageLength, Style, Timeout, pResponse, bWait);
335
0
}
336
337
BOOL WINAPI WTSSendMessageA(HANDLE hServer, DWORD SessionId, LPSTR pTitle, DWORD TitleLength,
338
                            LPSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout,
339
                            DWORD* pResponse, BOOL bWait)
340
0
{
341
0
  WTSAPI_STUB_CALL_BOOL(SendMessageA, hServer, SessionId, pTitle, TitleLength, pMessage,
342
0
                        MessageLength, Style, Timeout, pResponse, bWait);
343
0
}
344
345
BOOL WINAPI WTSDisconnectSession(HANDLE hServer, DWORD SessionId, BOOL bWait)
346
0
{
347
0
  WTSAPI_STUB_CALL_BOOL(DisconnectSession, hServer, SessionId, bWait);
348
0
}
349
350
BOOL WINAPI WTSLogoffSession(HANDLE hServer, DWORD SessionId, BOOL bWait)
351
0
{
352
0
  WTSAPI_STUB_CALL_BOOL(LogoffSession, hServer, SessionId, bWait);
353
0
}
354
355
BOOL WINAPI WTSShutdownSystem(HANDLE hServer, DWORD ShutdownFlag)
356
0
{
357
0
  WTSAPI_STUB_CALL_BOOL(ShutdownSystem, hServer, ShutdownFlag);
358
0
}
359
360
BOOL WINAPI WTSWaitSystemEvent(HANDLE hServer, DWORD EventMask, DWORD* pEventFlags)
361
0
{
362
0
  WTSAPI_STUB_CALL_BOOL(WaitSystemEvent, hServer, EventMask, pEventFlags);
363
0
}
364
365
HANDLE WINAPI WTSVirtualChannelOpen(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName)
366
0
{
367
0
  WTSAPI_STUB_CALL_HANDLE(VirtualChannelOpen, hServer, SessionId, pVirtualName);
368
0
}
369
370
HANDLE WINAPI WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags)
371
0
{
372
0
  WTSAPI_STUB_CALL_HANDLE(VirtualChannelOpenEx, SessionId, pVirtualName, flags);
373
0
}
374
375
BOOL WINAPI WTSVirtualChannelClose(HANDLE hChannelHandle)
376
0
{
377
0
  WTSAPI_STUB_CALL_BOOL(VirtualChannelClose, hChannelHandle);
378
0
}
379
380
BOOL WINAPI WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer,
381
                                  ULONG BufferSize, PULONG pBytesRead)
382
0
{
383
0
  WTSAPI_STUB_CALL_BOOL(VirtualChannelRead, hChannelHandle, TimeOut, Buffer, BufferSize,
384
0
                        pBytesRead);
385
0
}
386
387
BOOL WINAPI WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length,
388
                                   PULONG pBytesWritten)
389
0
{
390
0
  WTSAPI_STUB_CALL_BOOL(VirtualChannelWrite, hChannelHandle, Buffer, Length, pBytesWritten);
391
0
}
392
393
BOOL WINAPI WTSVirtualChannelPurgeInput(HANDLE hChannelHandle)
394
0
{
395
0
  WTSAPI_STUB_CALL_BOOL(VirtualChannelPurgeInput, hChannelHandle);
396
0
}
397
398
BOOL WINAPI WTSVirtualChannelPurgeOutput(HANDLE hChannelHandle)
399
0
{
400
0
  WTSAPI_STUB_CALL_BOOL(VirtualChannelPurgeOutput, hChannelHandle);
401
0
}
402
403
BOOL WINAPI WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass,
404
                                   PVOID* ppBuffer, DWORD* pBytesReturned)
405
0
{
406
0
  WTSAPI_STUB_CALL_BOOL(VirtualChannelQuery, hChannelHandle, WtsVirtualClass, ppBuffer,
407
0
                        pBytesReturned);
408
0
}
409
410
VOID WINAPI WTSFreeMemory(PVOID pMemory)
411
0
{
412
0
  WTSAPI_STUB_CALL_VOID(FreeMemory, pMemory);
413
0
}
414
415
BOOL WINAPI WTSFreeMemoryExW(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries)
416
0
{
417
0
  WTSAPI_STUB_CALL_BOOL(FreeMemoryExW, WTSTypeClass, pMemory, NumberOfEntries);
418
0
}
419
420
BOOL WINAPI WTSFreeMemoryExA(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries)
421
0
{
422
0
  WTSAPI_STUB_CALL_BOOL(FreeMemoryExA, WTSTypeClass, pMemory, NumberOfEntries);
423
0
}
424
425
BOOL WINAPI WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags)
426
0
{
427
0
  WTSAPI_STUB_CALL_BOOL(RegisterSessionNotification, hWnd, dwFlags);
428
0
}
429
430
BOOL WINAPI WTSUnRegisterSessionNotification(HWND hWnd)
431
0
{
432
0
  WTSAPI_STUB_CALL_BOOL(UnRegisterSessionNotification, hWnd);
433
0
}
434
435
BOOL WINAPI WTSRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd, DWORD dwFlags)
436
0
{
437
0
  WTSAPI_STUB_CALL_BOOL(RegisterSessionNotificationEx, hServer, hWnd, dwFlags);
438
0
}
439
440
BOOL WINAPI WTSUnRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd)
441
0
{
442
0
  WTSAPI_STUB_CALL_BOOL(UnRegisterSessionNotificationEx, hServer, hWnd);
443
0
}
444
445
BOOL WINAPI WTSQueryUserToken(ULONG SessionId, PHANDLE phToken)
446
0
{
447
0
  WTSAPI_STUB_CALL_BOOL(QueryUserToken, SessionId, phToken);
448
0
}
449
450
BOOL WINAPI WTSEnumerateProcessesExW(HANDLE hServer, DWORD* pLevel, DWORD SessionId,
451
                                     LPWSTR* ppProcessInfo, DWORD* pCount)
452
0
{
453
0
  WTSAPI_STUB_CALL_BOOL(EnumerateProcessesExW, hServer, pLevel, SessionId, ppProcessInfo, pCount);
454
0
}
455
456
BOOL WINAPI WTSEnumerateProcessesExA(HANDLE hServer, DWORD* pLevel, DWORD SessionId,
457
                                     LPSTR* ppProcessInfo, DWORD* pCount)
458
0
{
459
0
  WTSAPI_STUB_CALL_BOOL(EnumerateProcessesExA, hServer, pLevel, SessionId, ppProcessInfo, pCount);
460
0
}
461
462
BOOL WINAPI WTSEnumerateListenersW(HANDLE hServer, PVOID pReserved, DWORD Reserved,
463
                                   PWTSLISTENERNAMEW pListeners, DWORD* pCount)
464
0
{
465
0
  WTSAPI_STUB_CALL_BOOL(EnumerateListenersW, hServer, pReserved, Reserved, pListeners, pCount);
466
0
}
467
468
BOOL WINAPI WTSEnumerateListenersA(HANDLE hServer, PVOID pReserved, DWORD Reserved,
469
                                   PWTSLISTENERNAMEA pListeners, DWORD* pCount)
470
0
{
471
0
  WTSAPI_STUB_CALL_BOOL(EnumerateListenersA, hServer, pReserved, Reserved, pListeners, pCount);
472
0
}
473
474
BOOL WINAPI WTSQueryListenerConfigW(HANDLE hServer, PVOID pReserved, DWORD Reserved,
475
                                    LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer)
476
0
{
477
0
  WTSAPI_STUB_CALL_BOOL(QueryListenerConfigW, hServer, pReserved, Reserved, pListenerName,
478
0
                        pBuffer);
479
0
}
480
481
BOOL WINAPI WTSQueryListenerConfigA(HANDLE hServer, PVOID pReserved, DWORD Reserved,
482
                                    LPSTR pListenerName, PWTSLISTENERCONFIGA pBuffer)
483
0
{
484
0
  WTSAPI_STUB_CALL_BOOL(QueryListenerConfigA, hServer, pReserved, Reserved, pListenerName,
485
0
                        pBuffer);
486
0
}
487
488
BOOL WINAPI WTSCreateListenerW(HANDLE hServer, PVOID pReserved, DWORD Reserved,
489
                               LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer, DWORD flag)
490
0
{
491
0
  WTSAPI_STUB_CALL_BOOL(CreateListenerW, hServer, pReserved, Reserved, pListenerName, pBuffer,
492
0
                        flag);
493
0
}
494
495
BOOL WINAPI WTSCreateListenerA(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPSTR pListenerName,
496
                               PWTSLISTENERCONFIGA pBuffer, DWORD flag)
497
0
{
498
0
  WTSAPI_STUB_CALL_BOOL(CreateListenerA, hServer, pReserved, Reserved, pListenerName, pBuffer,
499
0
                        flag);
500
0
}
501
502
BOOL WINAPI WTSSetListenerSecurityW(HANDLE hServer, PVOID pReserved, DWORD Reserved,
503
                                    LPWSTR pListenerName, SECURITY_INFORMATION SecurityInformation,
504
                                    PSECURITY_DESCRIPTOR pSecurityDescriptor)
505
0
{
506
0
  WTSAPI_STUB_CALL_BOOL(SetListenerSecurityW, hServer, pReserved, Reserved, pListenerName,
507
0
                        SecurityInformation, pSecurityDescriptor);
508
0
}
509
510
BOOL WINAPI WTSSetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved,
511
                                    LPSTR pListenerName, SECURITY_INFORMATION SecurityInformation,
512
                                    PSECURITY_DESCRIPTOR pSecurityDescriptor)
513
0
{
514
0
  WTSAPI_STUB_CALL_BOOL(SetListenerSecurityA, hServer, pReserved, Reserved, pListenerName,
515
0
                        SecurityInformation, pSecurityDescriptor);
516
0
}
517
518
BOOL WINAPI WTSGetListenerSecurityW(HANDLE hServer, PVOID pReserved, DWORD Reserved,
519
                                    LPWSTR pListenerName, SECURITY_INFORMATION SecurityInformation,
520
                                    PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength,
521
                                    LPDWORD lpnLengthNeeded)
522
0
{
523
0
  WTSAPI_STUB_CALL_BOOL(GetListenerSecurityW, hServer, pReserved, Reserved, pListenerName,
524
0
                        SecurityInformation, pSecurityDescriptor, nLength, lpnLengthNeeded);
525
0
}
526
527
BOOL WINAPI WTSGetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved,
528
                                    LPSTR pListenerName, SECURITY_INFORMATION SecurityInformation,
529
                                    PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength,
530
                                    LPDWORD lpnLengthNeeded)
531
0
{
532
0
  WTSAPI_STUB_CALL_BOOL(GetListenerSecurityA, hServer, pReserved, Reserved, pListenerName,
533
0
                        SecurityInformation, pSecurityDescriptor, nLength, lpnLengthNeeded);
534
0
}
535
536
BOOL CDECL WTSEnableChildSessions(BOOL bEnable)
537
0
{
538
0
  WTSAPI_STUB_CALL_BOOL(EnableChildSessions, bEnable);
539
0
}
540
541
BOOL CDECL WTSIsChildSessionsEnabled(PBOOL pbEnabled)
542
0
{
543
0
  WTSAPI_STUB_CALL_BOOL(IsChildSessionsEnabled, pbEnabled);
544
0
}
545
546
BOOL CDECL WTSGetChildSessionId(PULONG pSessionId)
547
0
{
548
0
  WTSAPI_STUB_CALL_BOOL(GetChildSessionId, pSessionId);
549
0
}
550
551
BOOL CDECL WTSLogonUser(HANDLE hServer, LPCSTR username, LPCSTR password, LPCSTR domain)
552
0
{
553
0
  WTSAPI_STUB_CALL_BOOL(LogonUser, hServer, username, password, domain);
554
0
}
555
556
BOOL CDECL WTSLogoffUser(HANDLE hServer)
557
0
{
558
0
  WTSAPI_STUB_CALL_BOOL(LogoffUser, hServer);
559
0
}
560
561
#ifndef _WIN32
562
563
/**
564
 * WTSGetActiveConsoleSessionId is declared in WinBase.h and exported by kernel32.dll
565
 */
566
567
DWORD WINAPI WTSGetActiveConsoleSessionId(void)
568
0
{
569
0
  InitOnceExecuteOnce(&wtsapiInitOnce, InitializeWtsApiStubs, NULL, NULL);
570
571
0
  if (!g_WtsApi || !g_WtsApi->pGetActiveConsoleSessionId)
572
0
    return 0xFFFFFFFF;
573
574
0
  return g_WtsApi->pGetActiveConsoleSessionId();
575
0
}
576
577
#endif
578
579
const CHAR* WTSErrorToString(UINT error)
580
0
{
581
0
  switch (error)
582
0
  {
583
0
    case CHANNEL_RC_OK:
584
0
      return "CHANNEL_RC_OK";
585
586
0
    case CHANNEL_RC_ALREADY_INITIALIZED:
587
0
      return "CHANNEL_RC_ALREADY_INITIALIZED";
588
589
0
    case CHANNEL_RC_NOT_INITIALIZED:
590
0
      return "CHANNEL_RC_NOT_INITIALIZED";
591
592
0
    case CHANNEL_RC_ALREADY_CONNECTED:
593
0
      return "CHANNEL_RC_ALREADY_CONNECTED";
594
595
0
    case CHANNEL_RC_NOT_CONNECTED:
596
0
      return "CHANNEL_RC_NOT_CONNECTED";
597
598
0
    case CHANNEL_RC_TOO_MANY_CHANNELS:
599
0
      return "CHANNEL_RC_TOO_MANY_CHANNELS";
600
601
0
    case CHANNEL_RC_BAD_CHANNEL:
602
0
      return "CHANNEL_RC_BAD_CHANNEL";
603
604
0
    case CHANNEL_RC_BAD_CHANNEL_HANDLE:
605
0
      return "CHANNEL_RC_BAD_CHANNEL_HANDLE";
606
607
0
    case CHANNEL_RC_NO_BUFFER:
608
0
      return "CHANNEL_RC_NO_BUFFER";
609
610
0
    case CHANNEL_RC_BAD_INIT_HANDLE:
611
0
      return "CHANNEL_RC_BAD_INIT_HANDLE";
612
613
0
    case CHANNEL_RC_NOT_OPEN:
614
0
      return "CHANNEL_RC_NOT_OPEN";
615
616
0
    case CHANNEL_RC_BAD_PROC:
617
0
      return "CHANNEL_RC_BAD_PROC";
618
619
0
    case CHANNEL_RC_NO_MEMORY:
620
0
      return "CHANNEL_RC_NO_MEMORY";
621
622
0
    case CHANNEL_RC_UNKNOWN_CHANNEL_NAME:
623
0
      return "CHANNEL_RC_UNKNOWN_CHANNEL_NAME";
624
625
0
    case CHANNEL_RC_ALREADY_OPEN:
626
0
      return "CHANNEL_RC_ALREADY_OPEN";
627
628
0
    case CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY:
629
0
      return "CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY";
630
631
0
    case CHANNEL_RC_NULL_DATA:
632
0
      return "CHANNEL_RC_NULL_DATA";
633
634
0
    case CHANNEL_RC_ZERO_LENGTH:
635
0
      return "CHANNEL_RC_ZERO_LENGTH";
636
637
0
    case CHANNEL_RC_INVALID_INSTANCE:
638
0
      return "CHANNEL_RC_INVALID_INSTANCE";
639
640
0
    case CHANNEL_RC_UNSUPPORTED_VERSION:
641
0
      return "CHANNEL_RC_UNSUPPORTED_VERSION";
642
643
0
    case CHANNEL_RC_INITIALIZATION_ERROR:
644
0
      return "CHANNEL_RC_INITIALIZATION_ERROR";
645
646
0
    default:
647
0
      return "UNKNOWN";
648
0
  }
649
0
}
650
651
const CHAR* WTSSessionStateToString(WTS_CONNECTSTATE_CLASS state)
652
0
{
653
0
  switch (state)
654
0
  {
655
0
    case WTSActive:
656
0
      return "WTSActive";
657
0
    case WTSConnected:
658
0
      return "WTSConnected";
659
0
    case WTSConnectQuery:
660
0
      return "WTSConnectQuery";
661
0
    case WTSShadow:
662
0
      return "WTSShadow";
663
0
    case WTSDisconnected:
664
0
      return "WTSDisconnected";
665
0
    case WTSIdle:
666
0
      return "WTSIdle";
667
0
    case WTSListen:
668
0
      return "WTSListen";
669
0
    case WTSReset:
670
0
      return "WTSReset";
671
0
    case WTSDown:
672
0
      return "WTSDown";
673
0
    case WTSInit:
674
0
      return "WTSInit";
675
0
  }
676
0
  return "INVALID_STATE";
677
0
}
678
679
BOOL WTSRegisterWtsApiFunctionTable(const WtsApiFunctionTable* table)
680
0
{
681
  /* Use InitOnceExecuteOnce here as well - otherwise a table set with this
682
     function is overriden on the first use of a WTS* API call (due to
683
     wtsapiInitOnce not being set). */
684
0
  union
685
0
  {
686
0
    const void* cpv;
687
0
    void* pv;
688
0
  } cnv;
689
0
  cnv.cpv = table;
690
0
  InitOnceExecuteOnce(&wtsapiInitOnce, InitializeWtsApiStubs, cnv.pv, NULL);
691
0
  if (!g_WtsApi)
692
0
    return FALSE;
693
0
  return TRUE;
694
0
}
695
696
static BOOL LoadAndInitialize(char* library)
697
0
{
698
0
  INIT_WTSAPI_FN pInitWtsApi;
699
0
  g_WtsApiModule = LoadLibraryX(library);
700
701
0
  if (!g_WtsApiModule)
702
0
    return FALSE;
703
704
0
  pInitWtsApi = (INIT_WTSAPI_FN)GetProcAddress(g_WtsApiModule, "InitWtsApi");
705
706
0
  if (!pInitWtsApi)
707
0
  {
708
0
    return FALSE;
709
0
  }
710
711
0
  g_WtsApi = pInitWtsApi();
712
0
  return TRUE;
713
0
}
714
715
static void InitializeWtsApiStubs_Env(void)
716
0
{
717
0
  DWORD nSize;
718
0
  char* env = NULL;
719
0
  LPCSTR wts = "WTSAPI_LIBRARY";
720
721
0
  if (g_WtsApi)
722
0
    return;
723
724
0
  nSize = GetEnvironmentVariableA(wts, NULL, 0);
725
726
0
  if (!nSize)
727
0
    return;
728
729
0
  env = (LPSTR)malloc(nSize);
730
0
  if (env)
731
0
  {
732
0
    if (GetEnvironmentVariableA(wts, env, nSize) == nSize - 1)
733
0
      LoadAndInitialize(env);
734
0
    free(env);
735
0
  }
736
0
}
737
738
0
#define FREERDS_LIBRARY_NAME "libfreerds-fdsapi.so"
739
740
static void InitializeWtsApiStubs_FreeRDS(void)
741
0
{
742
0
  wIniFile* ini;
743
0
  const char* prefix;
744
0
  const char* libdir;
745
746
0
  if (g_WtsApi)
747
0
    return;
748
749
0
  ini = IniFile_New();
750
751
0
  if (IniFile_ReadFile(ini, "/var/run/freerds.instance") < 0)
752
0
  {
753
0
    IniFile_Free(ini);
754
0
    WLog_ERR(TAG, "failed to parse freerds.instance");
755
0
    LoadAndInitialize(FREERDS_LIBRARY_NAME);
756
0
    return;
757
0
  }
758
759
0
  prefix = IniFile_GetKeyValueString(ini, "FreeRDS", "prefix");
760
0
  libdir = IniFile_GetKeyValueString(ini, "FreeRDS", "libdir");
761
0
  WLog_INFO(TAG, "FreeRDS (prefix / libdir): %s / %s", prefix, libdir);
762
763
0
  if (prefix && libdir)
764
0
  {
765
0
    char* prefix_libdir;
766
0
    char* wtsapi_library;
767
0
    prefix_libdir = GetCombinedPath(prefix, libdir);
768
0
    wtsapi_library = GetCombinedPath(prefix_libdir, FREERDS_LIBRARY_NAME);
769
770
0
    if (wtsapi_library)
771
0
    {
772
0
      LoadAndInitialize(wtsapi_library);
773
0
    }
774
775
0
    free(prefix_libdir);
776
0
    free(wtsapi_library);
777
0
  }
778
779
0
  IniFile_Free(ini);
780
0
}
781
782
static BOOL CALLBACK InitializeWtsApiStubs(PINIT_ONCE once, PVOID param, PVOID* context)
783
0
{
784
0
  WINPR_UNUSED(once);
785
0
  WINPR_UNUSED(context);
786
0
  if (param)
787
0
  {
788
0
    g_WtsApi = (const WtsApiFunctionTable*)param;
789
0
    return TRUE;
790
0
  }
791
792
0
  InitializeWtsApiStubs_Env();
793
794
#ifdef _WIN32
795
  WtsApi32_InitializeWtsApi();
796
#endif
797
798
0
  if (!g_WtsApi)
799
0
    InitializeWtsApiStubs_FreeRDS();
800
801
0
  return TRUE;
802
0
}