server: allow partial channel read (fix rdpsnd).

This commit is contained in:
Vic Lee 2014-07-14 20:00:38 +08:00
parent f01daa8d06
commit 29cb8680ce
8 changed files with 72 additions and 67 deletions

View File

@ -345,24 +345,16 @@ static void* audin_server_thread_func(void* arg)
Stream_SetPosition(s, 0);
WTSVirtualChannelRead(audin->audin_channel, 0, NULL, 0, &BytesReturned);
if (BytesReturned < 1)
continue;
Stream_EnsureRemainingCapacity(s, BytesReturned);
if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s),
Stream_Capacity(s), &BytesReturned) == FALSE)
{
if (BytesReturned == 0)
break;
Stream_EnsureRemainingCapacity(s, BytesReturned);
if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s),
Stream_Capacity(s), &BytesReturned) == FALSE)
{
break;
}
break;
}
if (BytesReturned < 1)
continue;
Stream_Read_UINT8(s, MessageId);
BytesReturned--;

View File

@ -431,15 +431,14 @@ static void* cliprdr_server_thread(void* arg)
break;
}
if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);
if (BytesReturned < 1)
continue;
Stream_EnsureRemainingCapacity(s, BytesReturned);
if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
{
if (BytesReturned)
Stream_Seek(s, BytesReturned);
}
else
{
Stream_EnsureRemainingCapacity(s, BytesReturned);
break;
}
if (Stream_GetPosition(s) >= CLIPRDR_HEADER_LENGTH)

View File

@ -67,15 +67,14 @@ static void* drdynvc_server_thread(void* arg)
break;
}
if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);
if (BytesReturned < 1)
continue;
Stream_EnsureRemainingCapacity(s, BytesReturned);
if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
{
if (BytesReturned)
Stream_Seek(s, BytesReturned);
}
else
{
Stream_EnsureRemainingCapacity(s, BytesReturned);
break;
}
}

View File

@ -72,15 +72,14 @@ static void* encomsp_server_thread(void* arg)
break;
}
if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);
if (BytesReturned < 1)
continue;
Stream_EnsureRemainingCapacity(s, BytesReturned);
if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
{
if (BytesReturned)
Stream_Seek(s, BytesReturned);
}
else
{
Stream_EnsureRemainingCapacity(s, BytesReturned);
break;
}
if (0)

View File

@ -598,15 +598,14 @@ static void* rdpdr_server_thread(void* arg)
break;
}
if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR) Stream_Pointer(s),
Stream_Capacity(s) - Stream_GetPosition(s), &BytesReturned))
WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);
if (BytesReturned < 1)
continue;
Stream_EnsureRemainingCapacity(s, BytesReturned);
if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
{
if (BytesReturned)
Stream_Seek(s, BytesReturned);
}
else
{
Stream_EnsureRemainingCapacity(s, BytesReturned);
break;
}
if (Stream_GetPosition(s) >= RDPDR_HEADER_LENGTH)

View File

@ -626,7 +626,7 @@ BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context)
RdpsndServerPrivate *priv = context->priv;
wStream *s = priv->input_stream;
if (!WTSVirtualChannelRead(priv->channelEvent, 0, (PCHAR)Stream_Pointer(s), priv->expectedBytes, &bytesReturned))
if (!WTSVirtualChannelRead(priv->ChannelHandle, 0, (PCHAR)Stream_Pointer(s), priv->expectedBytes, &bytesReturned))
{
if (GetLastError() == ERROR_NO_DATA)
return TRUE;

View File

@ -42,6 +42,15 @@
#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
struct _wtsChannelMessage
{
UINT16 channelId;
UINT16 reserved;
UINT32 length;
UINT32 offset;
};
typedef struct _wtsChannelMessage wtsChannelMessage;
static DWORD g_SessionId = 1;
static wHashTable* g_ServerHandles = NULL;
@ -75,15 +84,16 @@ static rdpPeerChannel* wts_get_dvc_channel_by_id(WTSVirtualChannelManager* vcm,
static void wts_queue_receive_data(rdpPeerChannel* channel, const BYTE* Buffer, UINT32 Length)
{
BYTE* buffer;
UINT32 length;
UINT16 channelId;
wtsChannelMessage* messageCtx;
length = Length;
buffer = (BYTE*) malloc(length);
CopyMemory(buffer, Buffer, length);
channelId = channel->channelId;
messageCtx = (wtsChannelMessage*) malloc(sizeof(wtsChannelMessage) + Length);
messageCtx->channelId = channel->channelId;
messageCtx->length = Length;
messageCtx->offset = 0;
buffer = (BYTE*) (messageCtx + 1);
CopyMemory(buffer, Buffer, Length);
MessageQueue_Post(channel->queue, (void*) (UINT_PTR) channelId, 0, (void*) buffer, (void*) (UINT_PTR) length);
MessageQueue_Post(channel->queue, messageCtx, 0, NULL, NULL);
}
static void wts_queue_send_item(rdpPeerChannel* channel, BYTE* Buffer, UINT32 Length)
@ -1027,28 +1037,35 @@ BOOL WINAPI FreeRDP_WTSVirtualChannelClose(HANDLE hChannelHandle)
BOOL WINAPI FreeRDP_WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead)
{
BYTE* buffer;
UINT32 length;
UINT16 channelId;
wMessage message;
wtsChannelMessage* messageCtx;
rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
if (!MessageQueue_Peek(channel->queue, &message, TRUE))
if (!MessageQueue_Peek(channel->queue, &message, FALSE))
{
SetLastError(ERROR_NO_DATA);
*pBytesRead = 0;
return TRUE;
return FALSE;
}
channelId = (UINT16) (UINT_PTR) message.context;
buffer = (BYTE*) message.wParam;
length = (UINT32) (UINT_PTR) message.lParam;
messageCtx = (wtsChannelMessage*) (UINT_PTR) message.context;
buffer = (BYTE*) (messageCtx + 1);
*pBytesRead = length;
*pBytesRead = messageCtx->length - messageCtx->offset;
if (Buffer == NULL || BufferSize == 0)
{
return TRUE;
}
if (*pBytesRead > BufferSize)
*pBytesRead = BufferSize;
if (length > BufferSize)
return FALSE;
CopyMemory(Buffer, buffer, length);
free(buffer);
CopyMemory(Buffer, buffer + messageCtx->offset, *pBytesRead);
messageCtx->offset += *pBytesRead;
if (messageCtx->offset >= messageCtx->length)
{
MessageQueue_Peek(channel->queue, &message, TRUE);
free(messageCtx);
}
return TRUE;
}

View File

@ -160,7 +160,7 @@ BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
context->rdpsnd->Activated = wf_peer_rdpsnd_activated;
context->rdpsnd->Initialize(context->rdpsnd);
context->rdpsnd->Initialize(context->rdpsnd, TRUE);
wf_rdpsnd_set_latest_peer(context);