wtsapi.c 27 KB

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