21 #include <freerdp/config.h>
29 #include <winpr/crt.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")
53 BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channelId,
const BYTE* data,
size_t size)
59 const rdpMcsChannel* channel = NULL;
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;
87 if (left > rdp->settings->VCChunkSize)
89 chunkSize = rdp->settings->VCChunkSize;
94 flags |= CHANNEL_FLAG_LAST;
97 if (!rdp->settings->ServerMode && (channel->options & CHANNEL_OPTION_SHOW_PROTOCOL))
99 flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
102 if (!freerdp_channel_send_packet(rdp, channelId, size, flags, data, chunkSize))
113 BOOL freerdp_channel_process(freerdp* instance,
wStream* s, UINT16 channelId,
size_t packetLength)
118 size_t chunkLength = 0;
120 WINPR_ASSERT(instance);
122 if (packetLength < 8)
124 WLog_ERR(TAG,
"Header length %" PRIdz
" bytes promised, none available", packetLength);
129 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
137 Stream_Read_UINT32(s, length);
138 Stream_Read_UINT32(s, flags);
139 chunkLength = Stream_GetRemainingLength(s);
140 if (packetLength != chunkLength)
142 WLog_ERR(TAG,
"Header length %" PRIdz
" != actual length %" PRIdz, packetLength,
147 IFCALLRET(instance->ReceiveChannelData, rc, instance, channelId, Stream_Pointer(s), chunkLength,
151 WLog_WARN(TAG,
"ReceiveChannelData returned %d", rc);
155 return Stream_SafeSeek(s, chunkLength);
158 BOOL freerdp_channel_peer_process(freerdp_peer* client,
wStream* s, UINT16 channelId)
163 WINPR_ASSERT(client);
166 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
169 Stream_Read_UINT32(s, length);
170 Stream_Read_UINT32(s, flags);
171 const size_t chunkLength = Stream_GetRemainingLength(s);
172 if (chunkLength > UINT32_MAX)
175 if (client->VirtualChannelRead)
180 rdpContext* context = client->context;
181 rdpMcs* mcs = context->rdp->mcs;
183 for (UINT32 index = 0; index < mcs->channelCount; index++)
185 const rdpMcsChannel* mcsChannel = &(mcs->channels[index]);
187 if (mcsChannel->ChannelId == channelId)
189 hChannel = (HANDLE)mcsChannel->handle;
198 rc = client->VirtualChannelRead(client, hChannel, Stream_Pointer(s), (UINT32)chunkLength);
202 else if (client->ReceiveChannelData)
204 BOOL rc = client->ReceiveChannelData(client, channelId, Stream_Pointer(s),
205 (UINT32)chunkLength, flags, length);
209 if (!Stream_SafeSeek(s, chunkLength))
211 WLog_WARN(TAG,
"Short PDU, need %" PRIuz
" bytes, got %" PRIuz, chunkLength,
212 Stream_GetRemainingLength(s));
222 FreeRDP_WTSStopRemoteControlSession,
223 FreeRDP_WTSStartRemoteControlSessionW,
224 FreeRDP_WTSStartRemoteControlSessionA,
225 FreeRDP_WTSConnectSessionW,
226 FreeRDP_WTSConnectSessionA,
227 FreeRDP_WTSEnumerateServersW,
228 FreeRDP_WTSEnumerateServersA,
229 FreeRDP_WTSOpenServerW,
230 FreeRDP_WTSOpenServerA,
231 FreeRDP_WTSOpenServerExW,
232 FreeRDP_WTSOpenServerExA,
233 FreeRDP_WTSCloseServer,
234 FreeRDP_WTSEnumerateSessionsW,
235 FreeRDP_WTSEnumerateSessionsA,
236 FreeRDP_WTSEnumerateSessionsExW,
237 FreeRDP_WTSEnumerateSessionsExA,
238 FreeRDP_WTSEnumerateProcessesW,
239 FreeRDP_WTSEnumerateProcessesA,
240 FreeRDP_WTSTerminateProcess,
241 FreeRDP_WTSQuerySessionInformationW,
242 FreeRDP_WTSQuerySessionInformationA,
243 FreeRDP_WTSQueryUserConfigW,
244 FreeRDP_WTSQueryUserConfigA,
245 FreeRDP_WTSSetUserConfigW,
246 FreeRDP_WTSSetUserConfigA,
247 FreeRDP_WTSSendMessageW,
248 FreeRDP_WTSSendMessageA,
249 FreeRDP_WTSDisconnectSession,
250 FreeRDP_WTSLogoffSession,
251 FreeRDP_WTSShutdownSystem,
252 FreeRDP_WTSWaitSystemEvent,
253 FreeRDP_WTSVirtualChannelOpen,
254 FreeRDP_WTSVirtualChannelOpenEx,
255 FreeRDP_WTSVirtualChannelClose,
256 FreeRDP_WTSVirtualChannelRead,
257 FreeRDP_WTSVirtualChannelWrite,
258 FreeRDP_WTSVirtualChannelPurgeInput,
259 FreeRDP_WTSVirtualChannelPurgeOutput,
260 FreeRDP_WTSVirtualChannelQuery,
261 FreeRDP_WTSFreeMemory,
262 FreeRDP_WTSRegisterSessionNotification,
263 FreeRDP_WTSUnRegisterSessionNotification,
264 FreeRDP_WTSRegisterSessionNotificationEx,
265 FreeRDP_WTSUnRegisterSessionNotificationEx,
266 FreeRDP_WTSQueryUserToken,
267 FreeRDP_WTSFreeMemoryExW,
268 FreeRDP_WTSFreeMemoryExA,
269 FreeRDP_WTSEnumerateProcessesExW,
270 FreeRDP_WTSEnumerateProcessesExA,
271 FreeRDP_WTSEnumerateListenersW,
272 FreeRDP_WTSEnumerateListenersA,
273 FreeRDP_WTSQueryListenerConfigW,
274 FreeRDP_WTSQueryListenerConfigA,
275 FreeRDP_WTSCreateListenerW,
276 FreeRDP_WTSCreateListenerA,
277 FreeRDP_WTSSetListenerSecurityW,
278 FreeRDP_WTSSetListenerSecurityA,
279 FreeRDP_WTSGetListenerSecurityW,
280 FreeRDP_WTSGetListenerSecurityA,
281 FreeRDP_WTSEnableChildSessions,
282 FreeRDP_WTSIsChildSessionsEnabled,
283 FreeRDP_WTSGetChildSessionId,
284 FreeRDP_WTSGetActiveConsoleSessionId,
285 FreeRDP_WTSLogonUser,
286 FreeRDP_WTSLogoffUser,
287 FreeRDP_WTSStartRemoteControlSessionExW,
288 FreeRDP_WTSStartRemoteControlSessionExA
293 return &FreeRDP_WtsApiFunctionTable;
296 BOOL freerdp_channel_send_packet(rdpRdp* rdp, UINT16 channelId,
size_t totalSize, UINT32 flags,
297 const BYTE* data,
size_t chunkSize)
299 if (totalSize > UINT32_MAX)
302 wStream* s = rdp_send_stream_init(rdp);
307 Stream_Write_UINT32(s, (UINT32)totalSize);
308 Stream_Write_UINT32(s, flags);
310 if (!Stream_EnsureCapacity(s, chunkSize))
316 Stream_Write(s, data, chunkSize);
319 return rdp_send(rdp, s, channelId);