|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* FreeRDP: A Remote Desktop Protocol Implementation
|
|
Packit |
1fb8d4 |
* Virtual Channels
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Copyright 2011 Vic Lee
|
|
Packit |
1fb8d4 |
* Copyright 2015 Copyright 2015 Thincast Technologies GmbH
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
Packit |
1fb8d4 |
* you may not use this file except in compliance with the License.
|
|
Packit |
1fb8d4 |
* You may obtain a copy of the License at
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Unless required by applicable law or agreed to in writing, software
|
|
Packit |
1fb8d4 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit |
1fb8d4 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit |
1fb8d4 |
* See the License for the specific language governing permissions and
|
|
Packit |
1fb8d4 |
* limitations under the License.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
1fb8d4 |
#include "config.h"
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <stdio.h>
|
|
Packit |
1fb8d4 |
#include <stdlib.h>
|
|
Packit |
1fb8d4 |
#include <string.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <winpr/crt.h>
|
|
Packit |
1fb8d4 |
#include <winpr/stream.h>
|
|
Packit |
1fb8d4 |
#include <winpr/wtsapi.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <freerdp/freerdp.h>
|
|
Packit |
1fb8d4 |
#include <freerdp/constants.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <freerdp/log.h>
|
|
Packit |
1fb8d4 |
#include <freerdp/svc.h>
|
|
Packit |
1fb8d4 |
#include <freerdp/peer.h>
|
|
Packit |
1fb8d4 |
#include <freerdp/addin.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <freerdp/client/channels.h>
|
|
Packit |
1fb8d4 |
#include <freerdp/client/drdynvc.h>
|
|
Packit |
1fb8d4 |
#include <freerdp/channels/channels.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include "rdp.h"
|
|
Packit |
1fb8d4 |
#include "client.h"
|
|
Packit |
1fb8d4 |
#include "server.h"
|
|
Packit |
1fb8d4 |
#include "channels.h"
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#define TAG FREERDP_TAG("core.channels")
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channelId, const BYTE* data, int size)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD i;
|
|
Packit |
1fb8d4 |
int left;
|
|
Packit |
1fb8d4 |
wStream* s;
|
|
Packit |
1fb8d4 |
UINT32 flags;
|
|
Packit |
1fb8d4 |
int chunkSize;
|
|
Packit |
1fb8d4 |
rdpMcs* mcs = rdp->mcs;
|
|
Packit |
1fb8d4 |
rdpMcsChannel* channel = NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (i = 0; i < mcs->channelCount; i++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (mcs->channels[i].ChannelId == channelId)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
channel = &mcs->channels[i];
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!channel)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "freerdp_channel_send: unknown channelId %"PRIu16"", channelId);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
flags = CHANNEL_FLAG_FIRST;
|
|
Packit |
1fb8d4 |
left = size;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
while (left > 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
s = rdp_send_stream_init(rdp);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!s)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (left > (int) rdp->settings->VirtualChannelChunkSize)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
chunkSize = rdp->settings->VirtualChannelChunkSize;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
chunkSize = left;
|
|
Packit |
1fb8d4 |
flags |= CHANNEL_FLAG_LAST;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if ((channel->options & CHANNEL_OPTION_SHOW_PROTOCOL))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
Stream_Write_UINT32(s, size);
|
|
Packit |
1fb8d4 |
Stream_Write_UINT32(s, flags);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!Stream_EnsureCapacity(s, chunkSize))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
Stream_Release(s);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
Stream_Write(s, data, chunkSize);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* WLog_DBG(TAG, "%s: sending data (flags=0x%x size=%d)", __FUNCTION__, flags, size); */
|
|
Packit |
1fb8d4 |
if (!rdp_send(rdp, s, channelId))
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
data += chunkSize;
|
|
Packit |
1fb8d4 |
left -= chunkSize;
|
|
Packit |
1fb8d4 |
flags = 0;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL freerdp_channel_process(freerdp* instance, wStream* s, UINT16 channelId)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
UINT32 length;
|
|
Packit |
1fb8d4 |
UINT32 flags;
|
|
Packit |
1fb8d4 |
int chunkLength;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (Stream_GetRemainingLength(s) < 8)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
Stream_Read_UINT32(s, length);
|
|
Packit |
1fb8d4 |
Stream_Read_UINT32(s, flags);
|
|
Packit |
1fb8d4 |
chunkLength = Stream_GetRemainingLength(s);
|
|
Packit |
1fb8d4 |
IFCALL(instance->ReceiveChannelData, instance,
|
|
Packit |
1fb8d4 |
channelId, Stream_Pointer(s), chunkLength, flags, length);
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL freerdp_channel_peer_process(freerdp_peer* client, wStream* s,
|
|
Packit |
1fb8d4 |
UINT16 channelId)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
UINT32 length;
|
|
Packit |
1fb8d4 |
UINT32 flags;
|
|
Packit |
1fb8d4 |
int chunkLength;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (Stream_GetRemainingLength(s) < 8)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
Stream_Read_UINT32(s, length);
|
|
Packit |
1fb8d4 |
Stream_Read_UINT32(s, flags);
|
|
Packit |
1fb8d4 |
chunkLength = Stream_GetRemainingLength(s);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (client->VirtualChannelRead)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
UINT32 index;
|
|
Packit |
1fb8d4 |
BOOL found = FALSE;
|
|
Packit |
1fb8d4 |
HANDLE hChannel = 0;
|
|
Packit |
1fb8d4 |
rdpContext* context = client->context;
|
|
Packit |
1fb8d4 |
rdpMcs* mcs = context->rdp->mcs;
|
|
Packit |
1fb8d4 |
rdpMcsChannel* mcsChannel = NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (index = 0; index < mcs->channelCount; index++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
mcsChannel = &(mcs->channels[index]);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (mcsChannel->ChannelId == channelId)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
hChannel = (HANDLE) mcsChannel->handle;
|
|
Packit |
1fb8d4 |
found = TRUE;
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!found)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
client->VirtualChannelRead(client, hChannel, Stream_Pointer(s),
|
|
Packit |
1fb8d4 |
Stream_GetRemainingLength(s));
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else if (client->ReceiveChannelData)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
client->ReceiveChannelData(client, channelId, Stream_Pointer(s), chunkLength,
|
|
Packit |
1fb8d4 |
flags, length);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static const WtsApiFunctionTable FreeRDP_WtsApiFunctionTable =
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
0, /* dwVersion */
|
|
Packit |
1fb8d4 |
0, /* dwFlags */
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
FreeRDP_WTSStopRemoteControlSession, /* StopRemoteControlSession */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSStartRemoteControlSessionW, /* StartRemoteControlSessionW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSStartRemoteControlSessionA, /* StartRemoteControlSessionA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSConnectSessionW, /* ConnectSessionW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSConnectSessionA, /* ConnectSessionA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnumerateServersW, /* EnumerateServersW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnumerateServersA, /* EnumerateServersA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSOpenServerW, /* OpenServerW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSOpenServerA, /* OpenServerA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSOpenServerExW, /* OpenServerExW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSOpenServerExA, /* OpenServerExA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSCloseServer, /* CloseServer */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnumerateSessionsW, /* EnumerateSessionsW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnumerateSessionsA, /* EnumerateSessionsA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnumerateSessionsExW, /* EnumerateSessionsExW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnumerateSessionsExA, /* EnumerateSessionsExA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnumerateProcessesW, /* EnumerateProcessesW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnumerateProcessesA, /* EnumerateProcessesA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSTerminateProcess, /* TerminateProcess */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSQuerySessionInformationW, /* QuerySessionInformationW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSQuerySessionInformationA, /* QuerySessionInformationA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSQueryUserConfigW, /* QueryUserConfigW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSQueryUserConfigA, /* QueryUserConfigA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSSetUserConfigW, /* SetUserConfigW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSSetUserConfigA, /* SetUserConfigA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSSendMessageW, /* SendMessageW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSSendMessageA, /* SendMessageA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSDisconnectSession, /* DisconnectSession */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSLogoffSession, /* LogoffSession */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSShutdownSystem, /* ShutdownSystem */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSWaitSystemEvent, /* WaitSystemEvent */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSVirtualChannelOpen, /* VirtualChannelOpen */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSVirtualChannelOpenEx, /* VirtualChannelOpenEx */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSVirtualChannelClose, /* VirtualChannelClose */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSVirtualChannelRead, /* VirtualChannelRead */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSVirtualChannelWrite, /* VirtualChannelWrite */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSVirtualChannelPurgeInput, /* VirtualChannelPurgeInput */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSVirtualChannelPurgeOutput, /* VirtualChannelPurgeOutput */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSVirtualChannelQuery, /* VirtualChannelQuery */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSFreeMemory, /* FreeMemory */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSRegisterSessionNotification, /* RegisterSessionNotification */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSUnRegisterSessionNotification, /* UnRegisterSessionNotification */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSRegisterSessionNotificationEx, /* RegisterSessionNotificationEx */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSUnRegisterSessionNotificationEx, /* UnRegisterSessionNotificationEx */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSQueryUserToken, /* QueryUserToken */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSFreeMemoryExW, /* FreeMemoryExW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSFreeMemoryExA, /* FreeMemoryExA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnumerateProcessesExW, /* EnumerateProcessesExW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnumerateProcessesExA, /* EnumerateProcessesExA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnumerateListenersW, /* EnumerateListenersW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnumerateListenersA, /* EnumerateListenersA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSQueryListenerConfigW, /* QueryListenerConfigW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSQueryListenerConfigA, /* QueryListenerConfigA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSCreateListenerW, /* CreateListenerW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSCreateListenerA, /* CreateListenerA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSSetListenerSecurityW, /* SetListenerSecurityW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSSetListenerSecurityA, /* SetListenerSecurityA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSGetListenerSecurityW, /* GetListenerSecurityW */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSGetListenerSecurityA, /* GetListenerSecurityA */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSEnableChildSessions, /* EnableChildSessions */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSIsChildSessionsEnabled, /* IsChildSessionsEnabled */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSGetChildSessionId, /* GetChildSessionId */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSGetActiveConsoleSessionId, /* GetActiveConsoleSessionId */
|
|
Packit |
1fb8d4 |
FreeRDP_WTSLogonUser,
|
|
Packit |
1fb8d4 |
FreeRDP_WTSLogoffUser,
|
|
Packit |
1fb8d4 |
FreeRDP_WTSStartRemoteControlSessionExW,
|
|
Packit |
1fb8d4 |
FreeRDP_WTSStartRemoteControlSessionExA
|
|
Packit |
1fb8d4 |
};
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
PWtsApiFunctionTable FreeRDP_InitWtsApi(void)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
return (PWtsApiFunctionTable)&FreeRDP_WtsApiFunctionTable;
|
|
Packit |
1fb8d4 |
}
|