Blame libfreerdp/core/channels.c

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
}