/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 | } |