Beispiel #1
0
static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s)
{
	UINT32 ChannelId;
	wStream* data_out;
	int value;
	int error;

	ChannelId = drdynvc_read_variable_uint(s, cbChId);
	DEBUG_DVC("ChannelId=%d", ChannelId);
	dvcman_close_channel(drdynvc->channel_mgr, ChannelId);
	
	data_out = Stream_New(NULL, 4);
	value = (CLOSE_REQUEST_PDU << 4) | (cbChId & 0x03);
	Stream_Write_UINT8(data_out, value);
	drdynvc_write_variable_uint(data_out, ChannelId);
	error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
	
	if (error != CHANNEL_RC_OK)
	{
		DEBUG_WARN("VirtualChannelWrite failed %d", error);
		return 1;
	}
	
	drdynvc->channel_error = error;

	return 0;
}
Beispiel #2
0
static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* data_in)
{
	uint32 ChannelId;

	ChannelId = drdynvc_read_variable_uint(data_in, cbChId);
	DEBUG_DVC("ChannelId=%d", ChannelId);
	dvcman_close_channel(drdynvc->channel_mgr, ChannelId);

	return 0;
}
Beispiel #3
0
static int
process_CLOSE_REQUEST_PDU(drdynvcPlugin * plugin, int Sp, int cbChId,
	char * data, int data_size)
{
	int pos;
	uint32 ChannelId;

	pos = 1;
	ChannelId = get_variable_uint(cbChId, data, &pos);
	LLOGLN(10, ("process_CLOSE_REQUEST_PDU: ChannelId=%d", ChannelId));
	dvcman_close_channel(plugin->channel_mgr, ChannelId);

	return 0;
}
Beispiel #4
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp,
        int cbChId, wStream* s)
{
	int value;
	UINT error;
	UINT32 ChannelId;
	wStream* data_out;

	if (Stream_GetRemainingLength(s) < drdynvc_cblen_to_bytes(cbChId))
		return ERROR_INVALID_DATA;

	ChannelId = drdynvc_read_variable_uint(s, cbChId);
	WLog_Print(drdynvc->log, WLOG_DEBUG, "process_close_request: Sp=%d cbChId=%d, ChannelId=%"PRIu32"",
	           Sp,
	           cbChId, ChannelId);

	if ((error = dvcman_close_channel(drdynvc->channel_mgr, ChannelId)))
	{
		WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_close_channel failed with error %"PRIu32"!", error);
		return error;
	}

	data_out = Stream_New(NULL, 4);

	if (!data_out)
	{
		WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	value = (CLOSE_REQUEST_PDU << 4) | (cbChId & 0x03);
	Stream_Write_UINT8(data_out, value);
	drdynvc_write_variable_uint(data_out, ChannelId);
	error = drdynvc_send(drdynvc, data_out);

	if (error)
		WLog_Print(drdynvc->log, WLOG_ERROR, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]",
		           WTSErrorToString(error), error);

	return error;
}
Beispiel #5
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp,
					  int cbChId, wStream* s)
{
	int value;
	UINT error;
	UINT32 ChannelId;
	wStream* data_out;

	ChannelId = drdynvc_read_variable_uint(s, cbChId);

	WLog_DBG(TAG, "process_close_request: Sp=%d cbChId=%d, ChannelId=%d", Sp, cbChId, ChannelId);

	if ((error = dvcman_close_channel(drdynvc->channel_mgr, ChannelId)))
	{
		WLog_ERR(TAG, "dvcman_close_channel failed with error %lu!", error);
		return error;
	}

	data_out = Stream_New(NULL, 4);

	if (!data_out)
	{
		WLog_ERR(TAG, "Stream_New failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	value = (CLOSE_REQUEST_PDU << 4) | (cbChId & 0x03);

	Stream_Write_UINT8(data_out, value);
	drdynvc_write_variable_uint(data_out, ChannelId);

	error = drdynvc_send(drdynvc, data_out);

	if (error)
		WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
				 WTSErrorToString(error), error);

	return error;
}
Beispiel #6
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp,
        int cbChId, wStream* s)
{
	size_t pos;
	UINT status;
	UINT32 ChannelId;
	wStream* data_out;
	UINT channel_status;
	char* name;
	size_t length;

	if (!drdynvc)
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;

	if (drdynvc->state == DRDYNVC_STATE_CAPABILITIES)
	{
		/**
		 * For some reason the server does not always send the
		 * capabilities pdu as it should. When this happens,
		 * send a capabilities response.
		 */
		drdynvc->version = 3;

		if ((status = drdynvc_send_capability_response(drdynvc)))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "drdynvc_send_capability_response failed!");
			return status;
		}

		drdynvc->state = DRDYNVC_STATE_READY;
	}

	if (Stream_GetRemainingLength(s) < drdynvc_cblen_to_bytes(cbChId))
		return ERROR_INVALID_DATA;

	ChannelId = drdynvc_read_variable_uint(s, cbChId);
	pos = Stream_GetPosition(s);
	name = (char*)Stream_Pointer(s);
	length = Stream_GetRemainingLength(s);

	if (strnlen(name, length) >= length)
		return ERROR_INVALID_DATA;

	WLog_Print(drdynvc->log, WLOG_DEBUG, "process_create_request: ChannelId=%"PRIu32" ChannelName=%s",
	           ChannelId, name);
	channel_status = dvcman_create_channel(drdynvc, drdynvc->channel_mgr, ChannelId, name);
	data_out = Stream_New(NULL, pos + 4);

	if (!data_out)
	{
		WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	Stream_Write_UINT8(data_out, 0x10 | cbChId);
	Stream_SetPosition(s, 1);
	Stream_Copy(s, data_out, pos - 1);

	if (channel_status == CHANNEL_RC_OK)
	{
		WLog_Print(drdynvc->log, WLOG_DEBUG, "channel created");
		Stream_Write_UINT32(data_out, 0);
	}
	else
	{
		WLog_Print(drdynvc->log, WLOG_DEBUG, "no listener");
		Stream_Write_UINT32(data_out, (UINT32)0xC0000001); /* same code used by mstsc */
	}

	status = drdynvc_send(drdynvc, data_out);

	if (status != CHANNEL_RC_OK)
	{
		WLog_Print(drdynvc->log, WLOG_ERROR, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]",
		           WTSErrorToString(status), status);
		return status;
	}

	if (channel_status == CHANNEL_RC_OK)
	{
		if ((status = dvcman_open_channel(drdynvc, drdynvc->channel_mgr, ChannelId)))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_open_channel failed with error %"PRIu32"!", status);
			return status;
		}
	}
	else
	{
		if ((status = dvcman_close_channel(drdynvc->channel_mgr, ChannelId)))
			WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_close_channel failed with error %"PRIu32"!", status);
	}

	return status;
}
Beispiel #7
0
static DWORD WINAPI drdynvc_virtual_channel_client_thread(LPVOID arg)
{
	wStream* data;
	wMessage message;
	UINT error = CHANNEL_RC_OK;
	drdynvcPlugin* drdynvc = (drdynvcPlugin*) arg;

	if (!drdynvc)
	{
		ExitThread((DWORD) CHANNEL_RC_BAD_CHANNEL_HANDLE);
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;
	}

	while (1)
	{
		if (!MessageQueue_Wait(drdynvc->queue))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_Wait failed!");
			error = ERROR_INTERNAL_ERROR;
			break;
		}

		if (!MessageQueue_Peek(drdynvc->queue, &message, TRUE))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_Peek failed!");
			error = ERROR_INTERNAL_ERROR;
			break;
		}

		if (message.id == WMQ_QUIT)
			break;

		if (message.id == 0)
		{
			data = (wStream*) message.wParam;

			if ((error = drdynvc_order_recv(drdynvc, data)))
			{
				Stream_Free(data, TRUE);
				WLog_Print(drdynvc->log, WLOG_ERROR, "drdynvc_order_recv failed with error %"PRIu32"!", error);
				break;
			}

			Stream_Free(data, TRUE);
		}
	}

	{
		/* Disconnect remaining dynamic channels that the server did not.
		* This is required to properly shut down channels by calling the appropriate
		* event handlers. */
		DVCMAN* drdynvcMgr = (DVCMAN*)drdynvc->channel_mgr;

		while (ArrayList_Count(drdynvcMgr->channels) > 0)
		{
			IWTSVirtualChannel* channel = (IWTSVirtualChannel*)
			                              ArrayList_GetItem(drdynvcMgr->channels, 0);
			const UINT32 ChannelId = drdynvc->channel_mgr->GetChannelId(channel);
			dvcman_close_channel(drdynvc->channel_mgr, ChannelId);
		}
	}

	if (error && drdynvc->rdpcontext)
		setChannelError(drdynvc->rdpcontext, error,
		                "drdynvc_virtual_channel_client_thread reported an error");

	ExitThread((DWORD) error);
	return error;
}
Beispiel #8
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp,
					   int cbChId, wStream* s)
{
	unsigned long pos;
	UINT status;
	UINT32 ChannelId;
	wStream* data_out;
	UINT channel_status;

	if (drdynvc->state == DRDYNVC_STATE_CAPABILITIES)
	{
		/**
		 * For some reason the server does not always send the
		 * capabilities pdu as it should. When this happens,
		 * send a capabilities response.
		 */

		drdynvc->version = 3;
		if ((status = drdynvc_send_capability_response(drdynvc)))
		{
			WLog_ERR(TAG, "drdynvc_send_capability_response failed!");
			return status;
		}
		drdynvc->state = DRDYNVC_STATE_READY;
	}

	ChannelId = drdynvc_read_variable_uint(s, cbChId);
	pos = Stream_GetPosition(s);
	WLog_DBG(TAG, "process_create_request: ChannelId=%d ChannelName=%s", ChannelId, Stream_Pointer(s));

	channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) Stream_Pointer(s));

	data_out = Stream_New(NULL, pos + 4);

	if (!s)
	{
		WLog_ERR(TAG, "Stream_New failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	Stream_Write_UINT8(data_out, 0x10 | cbChId);
	Stream_SetPosition(s, 1);
	Stream_Copy(s, data_out, pos - 1);

	if (channel_status == CHANNEL_RC_OK)
	{
		WLog_DBG(TAG, "channel created");
		Stream_Write_UINT32(data_out, 0);
	}
	else
	{
		WLog_DBG(TAG, "no listener");
		Stream_Write_UINT32(data_out, (UINT32) 0xC0000001); /* same code used by mstsc */
	}

	status = drdynvc_send(drdynvc, data_out);

	if (status != CHANNEL_RC_OK)
	{
		WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
				 WTSErrorToString(status), status);
		return status;
	}

	if (channel_status == CHANNEL_RC_OK)
	{
		if ((status = dvcman_open_channel(drdynvc->channel_mgr, ChannelId)))
		{
			WLog_ERR(TAG, "dvcman_open_channel failed with error %lu!", status);
			return status;
		}
	}
	else
	{
		if ((status = dvcman_close_channel(drdynvc->channel_mgr, ChannelId)))
			WLog_ERR(TAG, "dvcman_close_channel failed with error %lu!", status);
	}

	return status;
}