From 23cb561a53b647c5ea206ab3ccaa5125f43ccc1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 21 Mar 2014 10:27:11 -0400 Subject: [PATCH] libfreerdp-core: fix RDP4 compression --- libfreerdp/codec/mppc.c | 10 +++---- libfreerdp/codec/ncrush.c | 5 +--- libfreerdp/core/bulk.c | 57 +++++++++++++++++++++++--------------- libfreerdp/core/fastpath.c | 33 ++++++++++------------ 4 files changed, 55 insertions(+), 50 deletions(-) diff --git a/libfreerdp/codec/mppc.c b/libfreerdp/codec/mppc.c index cee62980b..2d1ace2ae 100644 --- a/libfreerdp/codec/mppc.c +++ b/libfreerdp/codec/mppc.c @@ -110,13 +110,8 @@ int mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** p if (!(flags & PACKET_COMPRESSED)) { - CopyMemory(HistoryPtr, pSrcData, SrcSize); - HistoryPtr += SrcSize; - HistoryOffset += SrcSize; - mppc->HistoryPtr = HistoryPtr; - mppc->HistoryOffset = HistoryOffset; - *ppDstData = HistoryPtr; *pDstSize = SrcSize; + *ppDstData = pSrcData; return 1; } @@ -532,6 +527,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE* pDst *pFlags |= PACKET_FLUSHED; ZeroMemory(HistoryBuffer, HistoryBufferSize); ZeroMemory(mppc->MatchBuffer, sizeof(mppc->MatchBuffer)); + *pDstSize = SrcSize; return 1; } @@ -582,6 +578,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE* pDst *pFlags = PACKET_FLUSHED; ZeroMemory(HistoryBuffer, HistoryBufferSize); ZeroMemory(mppc->MatchBuffer, sizeof(mppc->MatchBuffer)); + *pDstSize = SrcSize; return 1; } @@ -737,6 +734,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE* pDst *pFlags |= PACKET_FLUSHED; ZeroMemory(HistoryBuffer, HistoryBufferSize); ZeroMemory(mppc->MatchBuffer, sizeof(mppc->MatchBuffer)); + *pDstSize = SrcSize; return 1; } diff --git a/libfreerdp/codec/ncrush.c b/libfreerdp/codec/ncrush.c index 7769bf530..4b3c891fb 100644 --- a/libfreerdp/codec/ncrush.c +++ b/libfreerdp/codec/ncrush.c @@ -1167,10 +1167,7 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY if (!(flags & PACKET_COMPRESSED)) { - CopyMemory(HistoryPtr, pSrcData, SrcSize); - HistoryPtr += SrcSize; - ncrush->HistoryPtr = HistoryPtr; - *ppDstData = HistoryPtr; + *ppDstData = pSrcData; *pDstSize = SrcSize; return 1; } diff --git a/libfreerdp/core/bulk.c b/libfreerdp/core/bulk.c index e4883bec2..bb6b86885 100644 --- a/libfreerdp/core/bulk.c +++ b/libfreerdp/core/bulk.c @@ -46,29 +46,38 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD UINT32 UncompressedBytes; UINT32 type = flags & 0x0F; - switch (type) + if (flags & PACKET_COMPRESSED) { - case PACKET_COMPR_TYPE_8K: - mppc_set_compression_level(bulk->mppcRecv, 0); - status = mppc_decompress(bulk->mppcRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags); - break; + switch (type) + { + case PACKET_COMPR_TYPE_8K: + mppc_set_compression_level(bulk->mppcRecv, 0); + status = mppc_decompress(bulk->mppcRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags); + break; - case PACKET_COMPR_TYPE_64K: - mppc_set_compression_level(bulk->mppcRecv, 1); - status = mppc_decompress(bulk->mppcRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags); - break; + case PACKET_COMPR_TYPE_64K: + mppc_set_compression_level(bulk->mppcRecv, 1); + status = mppc_decompress(bulk->mppcRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags); + break; - case PACKET_COMPR_TYPE_RDP6: - status = ncrush_decompress(bulk->ncrushRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags); - break; + case PACKET_COMPR_TYPE_RDP6: + status = ncrush_decompress(bulk->ncrushRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags); + break; - case PACKET_COMPR_TYPE_RDP61: - status = -1; - break; + case PACKET_COMPR_TYPE_RDP61: + status = -1; + break; - case PACKET_COMPR_TYPE_RDP8: - status = -1; - break; + case PACKET_COMPR_TYPE_RDP8: + status = -1; + break; + } + } + else + { + *ppDstData = pSrcData; + *pDstSize = SrcSize; + status = 1; } if (status >= 0) @@ -87,8 +96,8 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD CompressionRatio = ((double) CompressedBytes) / ((double) UncompressedBytes); TotalCompressionRatio = ((double) bulk->TotalCompressedBytes) / ((double) bulk->TotalUncompressedBytes); - printf("Type: %d Compression Ratio: %f Total: %f %d / %d\n", - type, CompressionRatio, TotalCompressionRatio, CompressedBytes, UncompressedBytes); + printf("Type: %d Flags: 0x%04X Compression Ratio: %f Total: %f %d / %d\n", + type, flags, CompressionRatio, TotalCompressionRatio, CompressedBytes, UncompressedBytes); } #endif } @@ -102,6 +111,7 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags) { + UINT32 type; int status = -1; UINT32 CompressedBytes; UINT32 UncompressedBytes; @@ -113,7 +123,7 @@ int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstDat mppc_set_compression_level(bulk->mppcSend, bulk->CompressionLevel); status = mppc_compress(bulk->mppcSend, pSrcData, SrcSize, *ppDstData, pDstSize, pFlags); - if ((status >= 0) && (*pFlags & PACKET_COMPRESSED)) + if (status >= 0) { CompressedBytes = *pDstSize; UncompressedBytes = SrcSize; @@ -126,10 +136,13 @@ int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstDat double CompressionRatio; double TotalCompressionRatio; + type = bulk->CompressionLevel; + CompressionRatio = ((double) CompressedBytes) / ((double) UncompressedBytes); TotalCompressionRatio = ((double) bulk->TotalCompressedBytes) / ((double) bulk->TotalUncompressedBytes); - printf("Compression Ratio: %f Total: %f\n", CompressionRatio, TotalCompressionRatio); + printf("Type: %d Flags: 0x%04X Compression Ratio: %f Total: %f %d / %d\n", + type, *pFlags, CompressionRatio, TotalCompressionRatio, CompressedBytes, UncompressedBytes); } #endif } diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index 5174056bb..ba9af739a 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -342,6 +342,8 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) BYTE fragmentation; BYTE compression; BYTE compressionFlags; + UINT32 DstSize = 0; + BYTE* pDstData = NULL; rdpTransport* transport; status = 0; @@ -363,26 +365,20 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) cs = s; next_pos = Stream_GetPosition(s) + size; - if (compressionFlags & PACKET_COMPRESSED) + if (bulk_decompress(rdp->bulk, Stream_Pointer(s), size, &pDstData, &DstSize, compressionFlags)) { - UINT32 DstSize = 0; - BYTE* pDstData = NULL; + size = DstSize; + cs = StreamPool_Take(transport->ReceivePool, DstSize); - if (bulk_decompress(rdp->bulk, Stream_Pointer(s), size, &pDstData, &DstSize, compressionFlags)) - { - size = DstSize; - cs = StreamPool_Take(transport->ReceivePool, DstSize); - - Stream_SetPosition(cs, 0); - Stream_Write(cs, pDstData, DstSize); - Stream_SealLength(cs); - Stream_SetPosition(cs, 0); - } - else - { - fprintf(stderr, "bulk_decompress() failed\n"); - Stream_Seek(s, size); - } + Stream_SetPosition(cs, 0); + Stream_Write(cs, pDstData, DstSize); + Stream_SealLength(cs); + Stream_SetPosition(cs, 0); + } + else + { + fprintf(stderr, "bulk_decompress() failed\n"); + Stream_Seek(s, size); } if (fragmentation == FASTPATH_FRAGMENT_SINGLE) @@ -855,6 +851,7 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s { CompressionMaxSize = bulk_compression_max_size(rdp->bulk); maxLength = (maxLength < CompressionMaxSize) ? maxLength : CompressionMaxSize; + maxLength -= 20; } totalLength = Stream_GetPosition(s);