Fix packet decoding logic

This patch totally reworks the logic of the packet decoding for the
server-side sound channel.
This commit is contained in:
Hardening 2014-06-19 10:06:37 +02:00
parent f33f755635
commit 11f8e40d50

View File

@ -195,37 +195,41 @@ static void* rdpsnd_server_thread(void* arg)
UINT16 BodySize;
HANDLE events[8];
HANDLE ChannelEvent;
DWORD BytesReturned;
DWORD bytesReturned;
RdpsndServerContext* context;
BOOL doRun;
BOOL waitingHeader;
DWORD expectedBytes;
context = (RdpsndServerContext *)arg;
buffer = NULL;
BytesReturned = 0;
ChannelEvent = NULL;
bytesReturned = 0;
s = Stream_New(NULL, 4096);
if (!s)
return NULL;
if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned))
if (!WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &bytesReturned) || (bytesReturned != sizeof(HANDLE)))
{
if (BytesReturned == sizeof(HANDLE))
CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));
WTSFreeMemory(buffer);
fprintf(stderr, "%s: error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned size(%d)\n",
__FUNCTION__, bytesReturned);
return NULL;
}
CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));
WTSFreeMemory(buffer);
nCount = 0;
if (ChannelEvent)
events[nCount++] = ChannelEvent;
events[nCount++] = ChannelEvent;
events[nCount++] = context->priv->StopEvent;
if (!rdpsnd_server_send_formats(context, s))
goto out;
doRun = TRUE;
waitingHeader = TRUE;
expectedBytes = 4;
while (doRun)
{
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
@ -233,31 +237,34 @@ static void* rdpsnd_server_thread(void* arg)
if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0)
break;
Stream_SetPosition(s, 0);
if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR)Stream_Buffer(s),
Stream_Capacity(s), &BytesReturned))
if (!WTSVirtualChannelRead(ChannelEvent, 0, (PCHAR)Stream_Pointer(s), expectedBytes, &bytesReturned))
{
if (!BytesReturned)
break;
fprintf(stderr, "%s: channel connection closed\n", __FUNCTION__);
break;
}
expectedBytes -= bytesReturned;
Stream_Seek(s, bytesReturned);
Stream_EnsureRemainingCapacity(s, BytesReturned);
if (expectedBytes)
continue;
if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR)Stream_Buffer(s),
Stream_Capacity(s), &BytesReturned))
break;
Stream_SetPosition(s, 0);
if (waitingHeader)
{
/* header case */
Stream_Read_UINT8(s, msgType);
Stream_Seek_UINT8(s); /* bPad */
Stream_Read_UINT16(s, BodySize);
expectedBytes = BodySize;
waitingHeader = FALSE;
Stream_SetPosition(s, 0);
Stream_EnsureCapacity(s, BodySize);
if (expectedBytes)
continue;
}
if (Stream_GetRemainingLength(s) < 4)
break;
Stream_Read_UINT8(s, msgType);
Stream_Seek_UINT8(s); /* bPad */
Stream_Read_UINT16(s, BodySize);
if (Stream_GetRemainingLength(s) < BodySize)
break;
/* when here we have the header + the body */
switch (msgType)
{
case SNDC_WAVECONFIRM:
@ -280,6 +287,10 @@ static void* rdpsnd_server_thread(void* arg)
fprintf(stderr, "%s: UNKOWN MESSAGE TYPE!! (%#0X)\n\n", __FUNCTION__, msgType);
break;
}
expectedBytes = 4;
waitingHeader = TRUE;
Stream_SetPosition(s, 0);
}
out: