21#include <freerdp/config.h>
30#include <winpr/assert.h>
31#include <winpr/stream.h>
32#include <winpr/wtsapi.h>
34#include <freerdp/freerdp.h>
35#include <freerdp/constants.h>
37#include <freerdp/log.h>
38#include <freerdp/svc.h>
39#include <freerdp/peer.h>
40#include <freerdp/addin.h>
42#include <freerdp/client/channels.h>
43#include <freerdp/client/drdynvc.h>
44#include <freerdp/channels/channels.h>
51#define TAG FREERDP_TAG("core.channels")
53BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channelId,
const BYTE* data,
size_t size)
58 rdpMcs* mcs =
nullptr;
59 const rdpMcsChannel* channel =
nullptr;
62 WINPR_ASSERT(data || (size == 0));
66 for (UINT32 i = 0; i < mcs->channelCount; i++)
68 const rdpMcsChannel* cur = &mcs->channels[i];
69 if (cur->ChannelId == channelId)
78 WLog_ERR(TAG,
"freerdp_channel_send: unknown channelId %" PRIu16
"", channelId);
82 flags = CHANNEL_FLAG_FIRST;
89 if (left > VCChunkSize)
91 chunkSize = VCChunkSize;
96 flags |= CHANNEL_FLAG_LAST;
99 if (!ServerMode && (channel->options & CHANNEL_OPTION_SHOW_PROTOCOL))
101 flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
104 if (!freerdp_channel_send_packet(rdp, channelId, size, flags, data, chunkSize))
115BOOL freerdp_channel_process(freerdp* instance,
wStream* s, UINT16 channelId,
size_t packetLength)
120 size_t chunkLength = 0;
122 WINPR_ASSERT(instance);
124 if (packetLength < 8)
126 WLog_ERR(TAG,
"Header length %" PRIuz
" bytes promised, none available", packetLength);
131 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
139 Stream_Read_UINT32(s, length);
140 Stream_Read_UINT32(s, flags);
141 chunkLength = Stream_GetRemainingLength(s);
142 if (packetLength != chunkLength)
144 WLog_ERR(TAG,
"Header length %" PRIuz
" != actual length %" PRIuz, packetLength,
149 IFCALLRET(instance->ReceiveChannelData, rc, instance, channelId, Stream_Pointer(s), chunkLength,
153 WLog_WARN(TAG,
"ReceiveChannelData returned %d", rc);
157 return Stream_SafeSeek(s, chunkLength);
160BOOL freerdp_channel_peer_process(freerdp_peer* client,
wStream* s, UINT16 channelId)
165 WINPR_ASSERT(client);
168 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
171 Stream_Read_UINT32(s, length);
172 Stream_Read_UINT32(s, flags);
173 const size_t chunkLength = Stream_GetRemainingLength(s);
174 if (chunkLength > UINT32_MAX)
177 if (client->VirtualChannelRead)
181 HANDLE hChannel =
nullptr;
182 rdpContext* context = client->context;
183 rdpMcs* mcs = context->rdp->mcs;
185 for (UINT32 index = 0; index < mcs->channelCount; index++)
187 const rdpMcsChannel* mcsChannel = &(mcs->channels[index]);
189 if (mcsChannel->ChannelId == channelId)
191 hChannel = (HANDLE)mcsChannel->handle;
200 rc = client->VirtualChannelRead(client, hChannel, Stream_Pointer(s), (UINT32)chunkLength);
204 else if (client->ReceiveChannelData)
206 BOOL rc = client->ReceiveChannelData(client, channelId, Stream_Pointer(s),
207 (UINT32)chunkLength, flags, length);
211 if (!Stream_SafeSeek(s, chunkLength))
213 WLog_WARN(TAG,
"Short PDU, need %" PRIuz
" bytes, got %" PRIuz, chunkLength,
214 Stream_GetRemainingLength(s));
224 FreeRDP_WTSStopRemoteControlSession,
225 FreeRDP_WTSStartRemoteControlSessionW,
226 FreeRDP_WTSStartRemoteControlSessionA,
227 FreeRDP_WTSConnectSessionW,
228 FreeRDP_WTSConnectSessionA,
229 FreeRDP_WTSEnumerateServersW,
230 FreeRDP_WTSEnumerateServersA,
231 FreeRDP_WTSOpenServerW,
232 FreeRDP_WTSOpenServerA,
233 FreeRDP_WTSOpenServerExW,
234 FreeRDP_WTSOpenServerExA,
235 FreeRDP_WTSCloseServer,
236 FreeRDP_WTSEnumerateSessionsW,
237 FreeRDP_WTSEnumerateSessionsA,
238 FreeRDP_WTSEnumerateSessionsExW,
239 FreeRDP_WTSEnumerateSessionsExA,
240 FreeRDP_WTSEnumerateProcessesW,
241 FreeRDP_WTSEnumerateProcessesA,
242 FreeRDP_WTSTerminateProcess,
243 FreeRDP_WTSQuerySessionInformationW,
244 FreeRDP_WTSQuerySessionInformationA,
245 FreeRDP_WTSQueryUserConfigW,
246 FreeRDP_WTSQueryUserConfigA,
247 FreeRDP_WTSSetUserConfigW,
248 FreeRDP_WTSSetUserConfigA,
249 FreeRDP_WTSSendMessageW,
250 FreeRDP_WTSSendMessageA,
251 FreeRDP_WTSDisconnectSession,
252 FreeRDP_WTSLogoffSession,
253 FreeRDP_WTSShutdownSystem,
254 FreeRDP_WTSWaitSystemEvent,
255 FreeRDP_WTSVirtualChannelOpen,
256 FreeRDP_WTSVirtualChannelOpenEx,
257 FreeRDP_WTSVirtualChannelClose,
258 FreeRDP_WTSVirtualChannelRead,
259 FreeRDP_WTSVirtualChannelWrite,
260 FreeRDP_WTSVirtualChannelPurgeInput,
261 FreeRDP_WTSVirtualChannelPurgeOutput,
262 FreeRDP_WTSVirtualChannelQuery,
263 FreeRDP_WTSFreeMemory,
264 FreeRDP_WTSRegisterSessionNotification,
265 FreeRDP_WTSUnRegisterSessionNotification,
266 FreeRDP_WTSRegisterSessionNotificationEx,
267 FreeRDP_WTSUnRegisterSessionNotificationEx,
268 FreeRDP_WTSQueryUserToken,
269 FreeRDP_WTSFreeMemoryExW,
270 FreeRDP_WTSFreeMemoryExA,
271 FreeRDP_WTSEnumerateProcessesExW,
272 FreeRDP_WTSEnumerateProcessesExA,
273 FreeRDP_WTSEnumerateListenersW,
274 FreeRDP_WTSEnumerateListenersA,
275 FreeRDP_WTSQueryListenerConfigW,
276 FreeRDP_WTSQueryListenerConfigA,
277 FreeRDP_WTSCreateListenerW,
278 FreeRDP_WTSCreateListenerA,
279 FreeRDP_WTSSetListenerSecurityW,
280 FreeRDP_WTSSetListenerSecurityA,
281 FreeRDP_WTSGetListenerSecurityW,
282 FreeRDP_WTSGetListenerSecurityA,
283 FreeRDP_WTSEnableChildSessions,
284 FreeRDP_WTSIsChildSessionsEnabled,
285 FreeRDP_WTSGetChildSessionId,
286 FreeRDP_WTSGetActiveConsoleSessionId,
287 FreeRDP_WTSLogonUser,
288 FreeRDP_WTSLogoffUser,
289 FreeRDP_WTSStartRemoteControlSessionExW,
290 FreeRDP_WTSStartRemoteControlSessionExA
295 return &FreeRDP_WtsApiFunctionTable;
298BOOL freerdp_channel_send_packet(rdpRdp* rdp, UINT16 channelId,
size_t totalSize, UINT32 flags,
299 const BYTE* data,
size_t chunkSize)
301 if (totalSize > UINT32_MAX)
304 UINT16 sec_flags = 0;
305 wStream* s = rdp_send_stream_init(rdp, &sec_flags);
310 if (!Stream_EnsureRemainingCapacity(s, chunkSize + 8))
316 Stream_Write_UINT32(s, (UINT32)totalSize);
317 Stream_Write_UINT32(s, flags);
319 Stream_Write(s, data, chunkSize);
322 return rdp_send(rdp, s, channelId, sec_flags);
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.