Exemplo n.º 1
0
HANDLE WINAPI FreeRDP_WTSVirtualChannelOpenEx(DWORD SessionId,
        LPSTR pVirtualName, DWORD flags)
{
	UINT32 index;
	wStream* s;
	rdpMcs* mcs;
	BOOL joined = FALSE;
	freerdp_peer* client;
	rdpPeerChannel* channel;
	ULONG written;
	WTSVirtualChannelManager* vcm;

	if (SessionId == WTS_CURRENT_SESSION)
		return NULL;

	vcm = (WTSVirtualChannelManager*) HashTable_GetItemValue(g_ServerHandles,
	        (void*)(UINT_PTR) SessionId);

	if (!vcm)
		return NULL;

	if (!(flags & WTS_CHANNEL_OPTION_DYNAMIC))
	{
		return FreeRDP_WTSVirtualChannelOpen((HANDLE) vcm, SessionId, pVirtualName);
	}

	client = vcm->client;
	mcs = client->context->rdp->mcs;

	for (index = 0; index < mcs->channelCount; index++)
	{
		if (mcs->channels[index].joined
		    && (strncmp(mcs->channels[index].Name, "drdynvc", 7) == 0))
		{
			joined = TRUE;
			break;
		}
	}

	if (!joined)
	{
		SetLastError(ERROR_NOT_FOUND);
		return NULL;
	}

	if (!vcm->drdynvc_channel || (vcm->drdynvc_state != DRDYNVC_STATE_READY))
	{
		SetLastError(ERROR_NOT_READY);
		return NULL;
	}

	channel = (rdpPeerChannel*) calloc(1, sizeof(rdpPeerChannel));

	if (!channel)
	{
		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
		return NULL;
	}

	channel->vcm = vcm;
	channel->client = client;
	channel->channelType = RDP_PEER_CHANNEL_TYPE_DVC;
	channel->receiveData = Stream_New(NULL,
	                                  client->settings->VirtualChannelChunkSize);

	if (!channel->receiveData)
	{
		WLog_ERR(TAG, "Stream_New failed!");
		goto error_receiveData;
	}

	channel->queue = MessageQueue_New(NULL);

	if (!channel->queue)
		goto error_queue;

	channel->channelId = InterlockedIncrement(&vcm->dvc_channel_id_seq);

	if (ArrayList_Add(vcm->dynamicVirtualChannels, channel) < 0)
		goto error_add;

	s = Stream_New(NULL, 64);

	if (!s)
		goto error_s;

	if (!wts_write_drdynvc_create_request(s, channel->channelId, pVirtualName))
		goto error_create;

	if (!WTSVirtualChannelWrite(vcm->drdynvc_channel, (PCHAR) Stream_Buffer(s),
	                            Stream_GetPosition(s), &written))
		goto error_create;

	Stream_Free(s, TRUE);
	return channel;
error_create:
	Stream_Free(s, TRUE);
error_s:
	ArrayList_Remove(vcm->dynamicVirtualChannels, channel);
error_add:
	MessageQueue_Free(channel->queue);
error_queue:
	Stream_Free(channel->receiveData, TRUE);
error_receiveData:
	free(channel);
	SetLastError(ERROR_NOT_ENOUGH_MEMORY);
	return NULL;
}
Exemplo n.º 2
0
void* WTSVirtualChannelOpenEx(
	/* __in */ WTSVirtualChannelManager* vcm,
	/* __in */ const char* pVirtualName,
	/* __in */ uint32 flags)
{
	int i;
	int len;
	rdpPeerChannel* channel;
	freerdp_peer* client = vcm->client;
	STREAM* s;

	if ((flags & WTS_CHANNEL_OPTION_DYNAMIC) != 0)
	{
		if (vcm->drdynvc_channel == NULL || vcm->drdynvc_state != DRDYNVC_STATE_READY)
		{
			DEBUG_DVC("Dynamic virtual channel not ready.");
			return NULL;
		}

		channel = xnew(rdpPeerChannel);
		channel->vcm = vcm;
		channel->client = client;
		channel->channel_type = RDP_PEER_CHANNEL_TYPE_DVC;
		channel->receive_data = stream_new(client->settings->vc_chunk_size);
		channel->receive_event = wait_obj_new();
		channel->receive_queue = list_new();
		channel->mutex = freerdp_mutex_new();

		freerdp_mutex_lock(vcm->mutex);
		channel->channel_id = vcm->dvc_channel_id_seq++;
		list_enqueue(vcm->dvc_channel_list, channel);
		freerdp_mutex_unlock(vcm->mutex);

		s = stream_new(64);
		wts_write_drdynvc_create_request(s, channel->channel_id, pVirtualName);
		WTSVirtualChannelWrite(vcm->drdynvc_channel, stream_get_head(s), stream_get_length(s), NULL);
		stream_free(s);

		DEBUG_DVC("ChannelId %d.%s (total %d)", channel->channel_id, pVirtualName, list_size(vcm->dvc_channel_list));
	}
	else
	{
		len = strlen(pVirtualName);
		if (len > 8)
			return NULL;

		for (i = 0; i < client->settings->num_channels; i++)
		{
			if (client->settings->channels[i].joined &&
				strncmp(client->settings->channels[i].name, pVirtualName, len) == 0)
			{
				break;
			}
		}
		if (i >= client->settings->num_channels)
			return NULL;

		channel = (rdpPeerChannel*) client->settings->channels[i].handle;
		if (channel == NULL)
		{
			channel = xnew(rdpPeerChannel);
			channel->vcm = vcm;
			channel->client = client;
			channel->channel_id = client->settings->channels[i].channel_id;
			channel->index = i;
			channel->channel_type = RDP_PEER_CHANNEL_TYPE_SVC;
			channel->receive_data = stream_new(client->settings->vc_chunk_size);
			channel->receive_event = wait_obj_new();
			channel->receive_queue = list_new();
			channel->mutex = freerdp_mutex_new();

			client->settings->channels[i].handle = channel;
		}
	}

	return channel;
}