mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-06-03 00:00:20 +00:00
server: allow partial channel read (fix rdpsnd).
This commit is contained in:
parent
f01daa8d06
commit
29cb8680ce
@ -345,24 +345,16 @@ static void* audin_server_thread_func(void* arg)
|
|||||||
|
|
||||||
Stream_SetPosition(s, 0);
|
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),
|
if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s),
|
||||||
Stream_Capacity(s), &BytesReturned) == FALSE)
|
Stream_Capacity(s), &BytesReturned) == FALSE)
|
||||||
{
|
{
|
||||||
if (BytesReturned == 0)
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
Stream_EnsureRemainingCapacity(s, BytesReturned);
|
|
||||||
|
|
||||||
if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s),
|
|
||||||
Stream_Capacity(s), &BytesReturned) == FALSE)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BytesReturned < 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Stream_Read_UINT8(s, MessageId);
|
Stream_Read_UINT8(s, MessageId);
|
||||||
BytesReturned--;
|
BytesReturned--;
|
||||||
|
|
||||||
|
@ -431,15 +431,14 @@ static void* cliprdr_server_thread(void* arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
|
WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);
|
||||||
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &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)
|
break;
|
||||||
Stream_Seek(s, BytesReturned);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Stream_EnsureRemainingCapacity(s, BytesReturned);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Stream_GetPosition(s) >= CLIPRDR_HEADER_LENGTH)
|
if (Stream_GetPosition(s) >= CLIPRDR_HEADER_LENGTH)
|
||||||
|
@ -67,15 +67,14 @@ static void* drdynvc_server_thread(void* arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
|
WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);
|
||||||
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &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)
|
break;
|
||||||
Stream_Seek(s, BytesReturned);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Stream_EnsureRemainingCapacity(s, BytesReturned);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,15 +72,14 @@ static void* encomsp_server_thread(void* arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
|
WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);
|
||||||
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &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)
|
break;
|
||||||
Stream_Seek(s, BytesReturned);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Stream_EnsureRemainingCapacity(s, BytesReturned);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0)
|
if (0)
|
||||||
|
@ -598,15 +598,14 @@ static void* rdpdr_server_thread(void* arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR) Stream_Pointer(s),
|
WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);
|
||||||
Stream_Capacity(s) - Stream_GetPosition(s), &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)
|
break;
|
||||||
Stream_Seek(s, BytesReturned);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Stream_EnsureRemainingCapacity(s, BytesReturned);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Stream_GetPosition(s) >= RDPDR_HEADER_LENGTH)
|
if (Stream_GetPosition(s) >= RDPDR_HEADER_LENGTH)
|
||||||
|
@ -626,7 +626,7 @@ BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context)
|
|||||||
RdpsndServerPrivate *priv = context->priv;
|
RdpsndServerPrivate *priv = context->priv;
|
||||||
wStream *s = priv->input_stream;
|
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)
|
if (GetLastError() == ERROR_NO_DATA)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -42,6 +42,15 @@
|
|||||||
#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct _wtsChannelMessage
|
||||||
|
{
|
||||||
|
UINT16 channelId;
|
||||||
|
UINT16 reserved;
|
||||||
|
UINT32 length;
|
||||||
|
UINT32 offset;
|
||||||
|
};
|
||||||
|
typedef struct _wtsChannelMessage wtsChannelMessage;
|
||||||
|
|
||||||
static DWORD g_SessionId = 1;
|
static DWORD g_SessionId = 1;
|
||||||
static wHashTable* g_ServerHandles = NULL;
|
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)
|
static void wts_queue_receive_data(rdpPeerChannel* channel, const BYTE* Buffer, UINT32 Length)
|
||||||
{
|
{
|
||||||
BYTE* buffer;
|
BYTE* buffer;
|
||||||
UINT32 length;
|
wtsChannelMessage* messageCtx;
|
||||||
UINT16 channelId;
|
|
||||||
|
|
||||||
length = Length;
|
messageCtx = (wtsChannelMessage*) malloc(sizeof(wtsChannelMessage) + Length);
|
||||||
buffer = (BYTE*) malloc(length);
|
messageCtx->channelId = channel->channelId;
|
||||||
CopyMemory(buffer, Buffer, length);
|
messageCtx->length = Length;
|
||||||
channelId = channel->channelId;
|
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)
|
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)
|
BOOL WINAPI FreeRDP_WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead)
|
||||||
{
|
{
|
||||||
BYTE* buffer;
|
BYTE* buffer;
|
||||||
UINT32 length;
|
|
||||||
UINT16 channelId;
|
|
||||||
wMessage message;
|
wMessage message;
|
||||||
|
wtsChannelMessage* messageCtx;
|
||||||
rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
|
rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
|
||||||
|
|
||||||
if (!MessageQueue_Peek(channel->queue, &message, TRUE))
|
if (!MessageQueue_Peek(channel->queue, &message, FALSE))
|
||||||
{
|
{
|
||||||
|
SetLastError(ERROR_NO_DATA);
|
||||||
*pBytesRead = 0;
|
*pBytesRead = 0;
|
||||||
return TRUE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
channelId = (UINT16) (UINT_PTR) message.context;
|
messageCtx = (wtsChannelMessage*) (UINT_PTR) message.context;
|
||||||
buffer = (BYTE*) message.wParam;
|
buffer = (BYTE*) (messageCtx + 1);
|
||||||
length = (UINT32) (UINT_PTR) message.lParam;
|
|
||||||
|
|
||||||
*pBytesRead = length;
|
*pBytesRead = messageCtx->length - messageCtx->offset;
|
||||||
|
if (Buffer == NULL || BufferSize == 0)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (*pBytesRead > BufferSize)
|
||||||
|
*pBytesRead = BufferSize;
|
||||||
|
|
||||||
if (length > BufferSize)
|
CopyMemory(Buffer, buffer + messageCtx->offset, *pBytesRead);
|
||||||
return FALSE;
|
messageCtx->offset += *pBytesRead;
|
||||||
|
if (messageCtx->offset >= messageCtx->length)
|
||||||
CopyMemory(Buffer, buffer, length);
|
{
|
||||||
free(buffer);
|
MessageQueue_Peek(channel->queue, &message, TRUE);
|
||||||
|
free(messageCtx);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
|
|||||||
|
|
||||||
context->rdpsnd->Activated = wf_peer_rdpsnd_activated;
|
context->rdpsnd->Activated = wf_peer_rdpsnd_activated;
|
||||||
|
|
||||||
context->rdpsnd->Initialize(context->rdpsnd);
|
context->rdpsnd->Initialize(context->rdpsnd, TRUE);
|
||||||
|
|
||||||
wf_rdpsnd_set_latest_peer(context);
|
wf_rdpsnd_set_latest_peer(context);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user