From 84d008940192f612506b62837f561fc20e5f8423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Tue, 8 Jul 2014 16:32:28 -0400 Subject: [PATCH 01/35] Added KeyboardHook to settings --- client/common/file.c | 5 +++++ include/freerdp/settings.h | 9 ++++++++- libfreerdp/common/settings.c | 8 ++++++++ libfreerdp/core/settings.c | 1 + 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/client/common/file.c b/client/common/file.c index c4937343a..0642384b0 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -1013,6 +1013,11 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* freerdp_set_param_bool(settings, FreeRDP_RedirectDrives, TRUE); } + if (~file->KeyboardHook) + { + freerdp_set_param_uint32(settings, FreeRDP_KeyboardHook, file->KeyboardHook); + } + if (file->argc > 1) { char* ConnectionFile = settings->ConnectionFile; diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 07fc0d354..dbc09f9fc 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -222,6 +222,11 @@ #define LB_CLIENT_TSV_URL 0x00001000 #define LB_SERVER_TSV_CAPABLE 0x00002000 +/* Keyboard Hook */ +#define KEYBOARD_HOOK_LOCAL 0 +#define KEYBOARD_HOOK_REMOTE 1 +#define KEYBOARD_HOOK_FULLSCREEN_ONLY 2 + struct _TARGET_NET_ADDRESS { UINT32 Length; @@ -725,6 +730,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_FastPathInput 2630 #define FreeRDP_MultiTouchInput 2631 #define FreeRDP_MultiTouchGestures 2632 +#define FreeRDP_KeyboardHook 2633 #define FreeRDP_BrushSupportLevel 2688 #define FreeRDP_GlyphSupportLevel 2752 #define FreeRDP_GlyphCache 2753 @@ -1174,7 +1180,8 @@ struct rdp_settings ALIGN64 BOOL FastPathInput; /* 2630 */ ALIGN64 BOOL MultiTouchInput; /* 2631 */ ALIGN64 BOOL MultiTouchGestures; /* 2632 */ - UINT64 padding2688[2688 - 2633]; /* 2633 */ + ALIGN64 UINT32 KeyboardHook; /* 2633 */ + UINT64 padding2688[2688 - 2634]; /* 2634 */ /* Brush Capabilities */ ALIGN64 UINT32 BrushSupportLevel; /* 2688 */ diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 97df29b15..e07bde9cf 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -1870,6 +1870,10 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id) return settings->KeyboardFunctionKey; break; + case FreeRDP_KeyboardHook: + return settings->KeyboardHook; + break; + case FreeRDP_BrushSupportLevel: return settings->BrushSupportLevel; break; @@ -2179,6 +2183,10 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param) settings->KeyboardFunctionKey = param; break; + case FreeRDP_KeyboardHook: + settings->KeyboardHook = param; + break; + case FreeRDP_BrushSupportLevel: settings->BrushSupportLevel = param; break; diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index fc40a0633..c58245fb1 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -557,6 +557,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings) _settings->KeyboardType = settings->KeyboardType; /* 2625 */ _settings->KeyboardSubType = settings->KeyboardSubType; /* 2626 */ _settings->KeyboardFunctionKey = settings->KeyboardFunctionKey; /* 2627 */ + _settings->KeyboardHook = settings->KeyboardHook; /* 2633 */ _settings->BrushSupportLevel = settings->BrushSupportLevel; /* 2688 */ _settings->GlyphSupportLevel = settings->GlyphSupportLevel; /* 2752 */ _settings->OffscreenSupportLevel = settings->OffscreenSupportLevel; /* 2816 */ From f7e5365719b114701cfa9e9da2707baf679b9f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 8 Jul 2014 17:16:13 -0400 Subject: [PATCH 02/35] libfreerdp-codec: add more gfx H264 debug output --- channels/rdpgfx/client/rdpgfx_codec.c | 60 +++++++++++++++++++++++++++ channels/rdpgfx/client/rdpgfx_main.c | 3 ++ include/freerdp/channels/rdpgfx.h | 21 ++++++++++ libfreerdp/codec/h264.c | 11 +++-- 4 files changed, 92 insertions(+), 3 deletions(-) diff --git a/channels/rdpgfx/client/rdpgfx_codec.c b/channels/rdpgfx/client/rdpgfx_codec.c index 961dce410..74d0a0dcc 100644 --- a/channels/rdpgfx/client/rdpgfx_codec.c +++ b/channels/rdpgfx/client/rdpgfx_codec.c @@ -24,6 +24,8 @@ #include #include +#include "rdpgfx_common.h" + #include "rdpgfx_codec.h" int rdpgfx_decode_uncompressed(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) @@ -46,8 +48,66 @@ int rdpgfx_decode_planar(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) return 1; } +int rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s) +{ + UINT32 index; + RDPGFX_RECT16* regionRect; + RDPGFX_H264_METABLOCK metablock; + RDPGFX_H264_QUANT_QUALITY* quantQualityVal; + + Stream_Read_UINT32(s, metablock.numRegionRects); /* numRegionRects (4 bytes) */ + + metablock.regionRects = (RDPGFX_RECT16*) malloc(metablock.numRegionRects * sizeof(RDPGFX_RECT16)); + + if (!metablock.regionRects) + return -1; + + metablock.quantQualityVals = (RDPGFX_H264_QUANT_QUALITY*) malloc(metablock.numRegionRects * sizeof(RDPGFX_H264_QUANT_QUALITY)); + + if (!metablock.quantQualityVals) + return -1; + + printf("H264_METABLOCK: numRegionRects: %d\n", (int) metablock.numRegionRects); + + for (index = 0; index < metablock.numRegionRects; index++) + { + regionRect = &(metablock.regionRects[index]); + rdpgfx_read_rect16(s, regionRect); + + printf("regionRects[%d]: left: %d top: %d right: %d bottom: %d\n", + index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom); + } + + for (index = 0; index < metablock.numRegionRects; index++) + { + quantQualityVal = &(metablock.quantQualityVals[index]); + Stream_Read_UINT8(s, quantQualityVal->qpVal); /* qpVal (1 byte) */ + Stream_Read_UINT8(s, quantQualityVal->qualityVal); /* qualityVal (1 byte) */ + + quantQualityVal->qp = quantQualityVal->qpVal & 0x3F; + quantQualityVal->r = (quantQualityVal->qpVal >> 6) & 1; + quantQualityVal->p = (quantQualityVal->qpVal >> 7) & 1; + + printf("quantQualityVals[%d]: qp: %d r: %d p: %d qualityVal: %d\n", + index, quantQualityVal->qp, quantQualityVal->r, quantQualityVal->p, quantQualityVal->qualityVal); + } + + free(metablock.regionRects); + free(metablock.quantQualityVals); + + return 1; +} + int rdpgfx_decode_h264(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) { + wStream* s; + + s = Stream_New(cmd->data, cmd->length); + + rdpgfx_read_h264_metablock(gfx, s); + + Stream_Free(s, FALSE); + return 1; } diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index f50010f93..b91ed88cf 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -426,6 +426,9 @@ int rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream cmd.length = pdu.bitmapDataLength; cmd.data = pdu.bitmapData; + if (cmd.codecId == RDPGFX_CODECID_H264) + rdpgfx_decode(gfx, &cmd); + if (context && context->SurfaceCommand) { context->SurfaceCommand(context, &cmd); diff --git a/include/freerdp/channels/rdpgfx.h b/include/freerdp/channels/rdpgfx.h index e4070194b..f0bdbc4ce 100644 --- a/include/freerdp/channels/rdpgfx.h +++ b/include/freerdp/channels/rdpgfx.h @@ -332,5 +332,26 @@ struct _RDPGFX_MAP_SURFACE_TO_WINDOW_PDU }; typedef struct _RDPGFX_MAP_SURFACE_TO_WINDOW_PDU RDPGFX_MAP_SURFACE_TO_WINDOW_PDU; +/* H264 */ + +struct _RDPGFX_H264_QUANT_QUALITY +{ + BYTE qpVal; + BYTE qualityVal; + + BYTE qp; + BYTE r; + BYTE p; +}; +typedef struct _RDPGFX_H264_QUANT_QUALITY RDPGFX_H264_QUANT_QUALITY; + +struct _RDPGFX_H264_METABLOCK +{ + UINT32 numRegionRects; + RDPGFX_RECT16* regionRects; + RDPGFX_H264_QUANT_QUALITY* quantQualityVals; +}; +typedef struct _RDPGFX_H264_METABLOCK RDPGFX_H264_METABLOCK; + #endif /* FREERDP_CHANNEL_RDPGFX_H */ diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index f690b3f23..ba5992670 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -171,7 +171,7 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, if (!h264 || !h264->pDecoder) return -1; -#if 0 +#if 1 printf("h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, DstFormat=%lx, nDstStep=%d, nXDst=%d, nYDst=%d, nWidth=%d, nHeight=%d)\n", pSrcData, SrcSize, *ppDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight); #endif @@ -214,7 +214,7 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, pSystemBuffer = &sBufferInfo.UsrData.sSystemBuffer; -#if 0 +#if 1 printf("h264_decompress: state=%u, pYUVData=[%p,%p,%p], bufferStatus=%d, width=%d, height=%d, format=%d, stride=[%d,%d]\n", state, pYUVData[0], pYUVData[1], pYUVData[2], sBufferInfo.iBufferStatus, pSystemBuffer->iWidth, pSystemBuffer->iHeight, pSystemBuffer->iFormat, @@ -314,8 +314,12 @@ H264_CONTEXT* h264_context_new(BOOL Compressor) } ZeroMemory(&sDecParam, sizeof(sDecParam)); - sDecParam.iOutputColorFormat = videoFormatARGB; + sDecParam.iOutputColorFormat = videoFormatI420; + sDecParam.uiEcActiveFlag = 1; + sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT; + status = (*h264->pDecoder)->Initialize(h264->pDecoder, &sDecParam); + if (status != 0) { printf("Failed to initialize OpenH264 decoder (status=%ld)\n", status); @@ -323,6 +327,7 @@ H264_CONTEXT* h264_context_new(BOOL Compressor) } status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_DATAFORMAT, &videoFormat); + if (status != 0) { printf("Failed to set data format option on OpenH264 decoder (status=%ld)\n", status); From 6f1acb01dd860c60cf8d2fd3980db04a37d60c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 8 Jul 2014 17:37:29 -0400 Subject: [PATCH 03/35] channels/rdpgfx: parse H264 bitmap stream and meta block --- channels/rdpgfx/client/rdpgfx_codec.c | 63 +++++++++++++++++++-------- channels/rdpgfx/client/rdpgfx_main.c | 12 +++-- client/X11/xf_gfx.c | 8 +++- include/freerdp/channels/rdpgfx.h | 9 ++++ 4 files changed, 69 insertions(+), 23 deletions(-) diff --git a/channels/rdpgfx/client/rdpgfx_codec.c b/channels/rdpgfx/client/rdpgfx_codec.c index 74d0a0dcc..4881db399 100644 --- a/channels/rdpgfx/client/rdpgfx_codec.c +++ b/channels/rdpgfx/client/rdpgfx_codec.c @@ -48,39 +48,47 @@ int rdpgfx_decode_planar(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) return 1; } -int rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s) +int rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, RDPGFX_H264_METABLOCK* meta) { UINT32 index; RDPGFX_RECT16* regionRect; - RDPGFX_H264_METABLOCK metablock; RDPGFX_H264_QUANT_QUALITY* quantQualityVal; - Stream_Read_UINT32(s, metablock.numRegionRects); /* numRegionRects (4 bytes) */ - - metablock.regionRects = (RDPGFX_RECT16*) malloc(metablock.numRegionRects * sizeof(RDPGFX_RECT16)); - - if (!metablock.regionRects) + if (Stream_GetRemainingLength(s) < 4) return -1; - metablock.quantQualityVals = (RDPGFX_H264_QUANT_QUALITY*) malloc(metablock.numRegionRects * sizeof(RDPGFX_H264_QUANT_QUALITY)); + Stream_Read_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */ - if (!metablock.quantQualityVals) + if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 8)) return -1; - printf("H264_METABLOCK: numRegionRects: %d\n", (int) metablock.numRegionRects); + meta->regionRects = (RDPGFX_RECT16*) malloc(meta->numRegionRects * sizeof(RDPGFX_RECT16)); - for (index = 0; index < metablock.numRegionRects; index++) + if (!meta->regionRects) + return -1; + + meta->quantQualityVals = (RDPGFX_H264_QUANT_QUALITY*) malloc(meta->numRegionRects * sizeof(RDPGFX_H264_QUANT_QUALITY)); + + if (!meta->quantQualityVals) + return -1; + + printf("H264_METABLOCK: numRegionRects: %d\n", (int) meta->numRegionRects); + + for (index = 0; index < meta->numRegionRects; index++) { - regionRect = &(metablock.regionRects[index]); + regionRect = &(meta->regionRects[index]); rdpgfx_read_rect16(s, regionRect); printf("regionRects[%d]: left: %d top: %d right: %d bottom: %d\n", index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom); } - for (index = 0; index < metablock.numRegionRects; index++) + if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 2)) + return -1; + + for (index = 0; index < meta->numRegionRects; index++) { - quantQualityVal = &(metablock.quantQualityVals[index]); + quantQualityVal = &(meta->quantQualityVals[index]); Stream_Read_UINT8(s, quantQualityVal->qpVal); /* qpVal (1 byte) */ Stream_Read_UINT8(s, quantQualityVal->qualityVal); /* qualityVal (1 byte) */ @@ -92,22 +100,41 @@ int rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s) index, quantQualityVal->qp, quantQualityVal->r, quantQualityVal->p, quantQualityVal->qualityVal); } - free(metablock.regionRects); - free(metablock.quantQualityVals); - return 1; } int rdpgfx_decode_h264(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) { + int status; wStream* s; + RDPGFX_H264_BITMAP_STREAM h264; + RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; s = Stream_New(cmd->data, cmd->length); - rdpgfx_read_h264_metablock(gfx, s); + if (!s) + return -1; + + status = rdpgfx_read_h264_metablock(gfx, s, &(h264.meta)); + + if (status < 0) + return -1; + + h264.data = Stream_Pointer(s); + h264.length = (UINT32) Stream_GetRemainingLength(s); Stream_Free(s, FALSE); + cmd->extra = (void*) &h264; + + if (context && context->SurfaceCommand) + { + context->SurfaceCommand(context, cmd); + } + + free(h264.meta.regionRects); + free(h264.meta.quantQualityVals); + return 1; } diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index b91ed88cf..f778e163b 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -427,11 +427,15 @@ int rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream cmd.data = pdu.bitmapData; if (cmd.codecId == RDPGFX_CODECID_H264) - rdpgfx_decode(gfx, &cmd); - - if (context && context->SurfaceCommand) { - context->SurfaceCommand(context, &cmd); + rdpgfx_decode(gfx, &cmd); + } + else + { + if (context && context->SurfaceCommand) + { + context->SurfaceCommand(context, &cmd); + } } return 1; diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index 69dacdaee..7778d18a1 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -339,6 +339,12 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ BYTE* DstData = NULL; xfGfxSurface* surface; RECTANGLE_16 invalidRect; + RDPGFX_H264_BITMAP_STREAM* h264; + + h264 = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra; + + if (!h264) + return -1; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); @@ -348,7 +354,7 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ DstData = surface->data; #if 1 - status = h264_decompress(xfc->h264, cmd->data, cmd->length, &DstData, + status = h264_decompress(xfc->h264, h264->data, h264->length, &DstData, PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height); #else status = -1; diff --git a/include/freerdp/channels/rdpgfx.h b/include/freerdp/channels/rdpgfx.h index f0bdbc4ce..24943ff5f 100644 --- a/include/freerdp/channels/rdpgfx.h +++ b/include/freerdp/channels/rdpgfx.h @@ -179,6 +179,7 @@ struct _RDPGFX_SURFACE_COMMAND UINT32 height; UINT32 length; BYTE* data; + void* extra; }; typedef struct _RDPGFX_SURFACE_COMMAND RDPGFX_SURFACE_COMMAND; @@ -353,5 +354,13 @@ struct _RDPGFX_H264_METABLOCK }; typedef struct _RDPGFX_H264_METABLOCK RDPGFX_H264_METABLOCK; +struct _RDPGFX_H264_BITMAP_STREAM +{ + RDPGFX_H264_METABLOCK meta; + UINT32 length; + BYTE* data; +}; +typedef struct _RDPGFX_H264_BITMAP_STREAM RDPGFX_H264_BITMAP_STREAM; + #endif /* FREERDP_CHANNEL_RDPGFX_H */ From 3e817090b9bb97bb2e2c6e08c3c7b33353c3ed1d Mon Sep 17 00:00:00 2001 From: Mike McDonald Date: Tue, 8 Jul 2014 17:45:48 -0400 Subject: [PATCH 04/35] Added SetOption calls to enable trace logging in OpenH264. --- libfreerdp/codec/h264.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index f690b3f23..510811d5b 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -30,6 +30,7 @@ #define USE_GRAY_SCALE 0 #define USE_UPCONVERT 0 +#define USE_TRACE 1 static BYTE clip(int x) { @@ -152,6 +153,13 @@ static BYTE* convert_420_to_444(BYTE* chroma420, int chroma420Width, int chroma4 } #endif +#if USE_TRACE +static void trace_callback(H264_CONTEXT* h264, int level, const char* message) +{ + printf("%d - %s\n", level, message); +} +#endif + int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight) { @@ -302,6 +310,11 @@ H264_CONTEXT* h264_context_new(BOOL Compressor) { static EVideoFormatType videoFormat = videoFormatI420; +#if USE_TRACE + static int traceLevel = WELS_LOG_DEBUG; + static WelsTraceCallback traceCallback = trace_callback; +#endif + SDecodingParam sDecParam; long status; @@ -327,6 +340,26 @@ H264_CONTEXT* h264_context_new(BOOL Compressor) { printf("Failed to set data format option on OpenH264 decoder (status=%ld)\n", status); } + +#if USE_TRACE + status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_LEVEL, &traceLevel); + if (status != 0) + { + printf("Failed to set trace level option on OpenH264 decoder (status=%ld)\n", status); + } + + status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_CALLBACK, &traceCallback); + if (status != 0) + { + printf("Failed to set trace callback option on OpenH264 decoder (status=%ld)\n", status); + } + + status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_CALLBACK_CONTEXT, &h264); + if (status != 0) + { + printf("Failed to set trace callback context option on OpenH264 decoder (status=%ld)\n", status); + } +#endif } #endif From 10f8a0a45bfb347111b8a6d0035e4e7b83f4703b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 8 Jul 2014 18:04:24 -0400 Subject: [PATCH 05/35] xfreerdp: start using regionRects in egfx h264 decoding --- client/X11/xf_gfx.c | 65 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index 7778d18a1..78f1caed6 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -336,9 +336,19 @@ int xf_SurfaceCommand_Planar(xfContext* xfc, RdpgfxClientContext* context, RDPGF int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; + UINT32 i, j; + int nXDst, nYDst; + int nWidth, nHeight; + int nbUpdateRects; BYTE* DstData = NULL; + RDPGFX_RECT16* rect; xfGfxSurface* surface; - RECTANGLE_16 invalidRect; + REGION16 updateRegion; + RECTANGLE_16 updateRect; + RECTANGLE_16* updateRects; + REGION16 clippingRects; + RECTANGLE_16 clippingRect; + RDPGFX_H264_METABLOCK* meta; RDPGFX_H264_BITMAP_STREAM* h264; h264 = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra; @@ -346,6 +356,8 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ if (!h264) return -1; + meta = &(h264->meta); + surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) @@ -353,15 +365,51 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ DstData = surface->data; -#if 1 status = h264_decompress(xfc->h264, h264->data, h264->length, &DstData, PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height); -#else - status = -1; -#endif printf("xf_SurfaceCommand_H264: status: %d\n", status); + if (status < 0) + return -1; + + region16_init(&clippingRects); + + for (i = 0; i < meta->numRegionRects; i++) + { + rect = &(meta->regionRects[i]); + + clippingRect.left = cmd->left + rect->left; + clippingRect.top = cmd->top + rect->top; + clippingRect.right = cmd->right + (rect->right - rect->left); + clippingRect.bottom = cmd->bottom + (rect->bottom - rect->top); + + region16_union_rect(&clippingRects, &clippingRects, &clippingRect); + } + + updateRect.left = cmd->left; + updateRect.top = cmd->top; + updateRect.right = cmd->right; + updateRect.bottom = cmd->bottom; + + region16_init(&updateRegion); + region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); + updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); + + for (j = 0; j < nbUpdateRects; j++) + { + nXDst = updateRects[j].left; + nYDst = updateRects[j].top; + nWidth = updateRects[j].right - updateRects[j].left; + nHeight = updateRects[j].bottom - updateRects[j].top; + + /* update region from decoded H264 buffer */ + + region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &updateRects[j]); + } + + region16_uninit(&updateRegion); + #if 0 /* fill with red for now to distinguish from the rest */ @@ -369,13 +417,6 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ cmd->left, cmd->top, cmd->width, cmd->height, 0xFF0000); #endif - invalidRect.left = cmd->left; - invalidRect.top = cmd->top; - invalidRect.right = cmd->right; - invalidRect.bottom = cmd->bottom; - - region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect); - if (!xfc->inGfxFrame) xf_OutputUpdate(xfc); From 03c91a92d1bde2061af51dfc79b7ab3e891ebfbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 9 Jul 2014 16:41:36 -0400 Subject: [PATCH 06/35] libfreerdp-codec: add more egfx h264 debugging --- client/X11/xf_gfx.c | 31 +++++-- include/freerdp/codec/h264.h | 6 ++ libfreerdp/codec/h264.c | 165 +++++++++++++++++++++++++++++++++-- 3 files changed, 188 insertions(+), 14 deletions(-) diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index 78f1caed6..bf04042f6 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -342,6 +342,7 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ int nbUpdateRects; BYTE* DstData = NULL; RDPGFX_RECT16* rect; + H264_CONTEXT* h264; xfGfxSurface* surface; REGION16 updateRegion; RECTANGLE_16 updateRect; @@ -349,14 +350,16 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ REGION16 clippingRects; RECTANGLE_16 clippingRect; RDPGFX_H264_METABLOCK* meta; - RDPGFX_H264_BITMAP_STREAM* h264; + RDPGFX_H264_BITMAP_STREAM* bs; - h264 = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra; + h264 = xfc->h264; - if (!h264) + bs = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra; + + if (!bs) return -1; - meta = &(h264->meta); + meta = &(bs->meta); surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); @@ -365,7 +368,7 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ DstData = surface->data; - status = h264_decompress(xfc->h264, h264->data, h264->length, &DstData, + status = h264_decompress(xfc->h264, bs->data, bs->length, &DstData, PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height); printf("xf_SurfaceCommand_H264: status: %d\n", status); @@ -379,10 +382,10 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ { rect = &(meta->regionRects[i]); - clippingRect.left = cmd->left + rect->left; - clippingRect.top = cmd->top + rect->top; - clippingRect.right = cmd->right + (rect->right - rect->left); - clippingRect.bottom = cmd->bottom + (rect->bottom - rect->top); + clippingRect.left = rect->left; + clippingRect.top = rect->top; + clippingRect.right = rect->right; + clippingRect.bottom = rect->bottom; region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } @@ -396,6 +399,8 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); + printf("numRegionRects: %d nbUpdateRects: %d\n", meta->numRegionRects, nbUpdateRects); + for (j = 0; j < nbUpdateRects; j++) { nXDst = updateRects[j].left; @@ -405,6 +410,14 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ /* update region from decoded H264 buffer */ + printf("nXDst: %d nYDst: %d nWidth: %d nHeight: %d decoded: width: %d height: %d cmd: left: %d top: %d right: %d bottom: %d\n", + nXDst, nYDst, nWidth, nHeight, h264->width, h264->height, + cmd->left, cmd->top, cmd->right, cmd->bottom); + + freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, + nXDst, nYDst, nWidth, nHeight, + h264->data, PIXEL_FORMAT_XRGB32, h264->scanline, nXDst, nYDst); + region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &updateRects[j]); } diff --git a/include/freerdp/codec/h264.h b/include/freerdp/codec/h264.h index f7f6a1377..8ca83bcc0 100644 --- a/include/freerdp/codec/h264.h +++ b/include/freerdp/codec/h264.h @@ -32,6 +32,12 @@ struct _H264_CONTEXT { BOOL Compressor; + BYTE* data; + UINT32 size; + UINT32 width; + UINT32 height; + int scanline; + #ifdef WITH_OPENH264 ISVCDecoder* pDecoder; #endif diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index f3398e2e3..4b0d1de68 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -28,8 +28,8 @@ #include #include -#define USE_GRAY_SCALE 0 -#define USE_UPCONVERT 0 +#define USE_GRAY_SCALE 1 +#define USE_UPCONVERT 0 #define USE_TRACE 1 static BYTE clip(int x) @@ -160,6 +160,107 @@ static void trace_callback(H264_CONTEXT* h264, int level, const char* message) } #endif +static int g_H264FrameId = 0; +static BOOL g_H264DumpFrames = FALSE; + +int h264_prepare_rgb_buffer(H264_CONTEXT* h264, int width, int height) +{ + UINT32 size; + + h264->width = width; + h264->height = height; + h264->scanline = h264->width * 4; + size = h264->scanline * h264->height; + + if (size > h264->size) + { + h264->size = size; + h264->data = (BYTE*) realloc(h264->data, h264->size); + } + + if (!h264->data) + return -1; + + return 1; +} + +int freerdp_image_copy_yuv420p_to_xrgb(BYTE* pDstData, int nDstStep, int nXDst, int nYDst, + int nWidth, int nHeight, BYTE* pSrcData[3], int nSrcStep[2], int nXSrc, int nYSrc) +{ + int x, y; + BYTE* pDstPixel8; + BYTE *pY, *pU, *pV; + + pY = pSrcData[0]; + pU = pSrcData[1]; + pV = pSrcData[0]; + + pDstPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; + + for (y = 0; y < nHeight; y++) + { + for (x = 0; x < nWidth; x++) + { + *((UINT32*) pDstPixel8) = RGB32(*pY, *pY, *pY); + pDstPixel8 += 4; + pY++; + } + + pDstPixel8 += (nDstStep - (nWidth * 4)); + pY += (nSrcStep[0] - nWidth); + } + + return 1; +} + +BYTE* h264_strip_nal_unit_au_delimiter(BYTE* pSrcData, UINT32* pSrcSize) +{ + BYTE* data = pSrcData; + UINT32 size = *pSrcSize; + BYTE forbidden_zero_bit = 0; + BYTE nal_ref_idc = 0; + BYTE nal_unit_type = 0; + + /* ITU-T H.264 B.1.1 Byte stream NAL unit syntax */ + + while (size > 0) + { + if (*data) + break; + + data++; + size--; + } + + if (*data != 1) + return pSrcData; + + data++; + size--; + + forbidden_zero_bit = (data[0] >> 7); + nal_ref_idc = (data[0] >> 5); + nal_unit_type = (data[0] & 0x1F); + + if (forbidden_zero_bit) + return pSrcData; /* invalid */ + + if (nal_unit_type == 9) + { + /* NAL Unit AU Delimiter */ + + printf("NAL Unit AU Delimiter: idc: %d\n", nal_ref_idc); + + data += 2; + size -= 2; + + *pSrcSize = size; + return data; + } + + return pSrcData; +} + int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight) { @@ -179,9 +280,11 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, if (!h264 || !h264->pDecoder) return -1; + pSrcData = h264_strip_nal_unit_au_delimiter(pSrcData, &SrcSize); + #if 1 - printf("h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, DstFormat=%lx, nDstStep=%d, nXDst=%d, nYDst=%d, nWidth=%d, nHeight=%d)\n", - pSrcData, SrcSize, *ppDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight); + printf("h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, nDstStep=%d, nXDst=%d, nYDst=%d, nWidth=%d, nHeight=%d)\n", + pSrcData, SrcSize, *ppDstData, nDstStep, nXDst, nYDst, nWidth, nHeight); #endif /* Allocate a destination buffer (if needed). */ @@ -203,6 +306,18 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, *ppDstData = pDstData; } + if (g_H264DumpFrames) + { + FILE* fp; + char buf[4096]; + + snprintf(buf, sizeof(buf), "/tmp/wlog/bs_%d.h264", g_H264FrameId); + fp = fopen(buf, "wb"); + fwrite(pSrcData, 1, SrcSize, fp); + fflush(fp); + fclose(fp); + } + /* * Decompress the image. The RDP host only seems to send I420 format. */ @@ -247,6 +362,41 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, pU = pYUVData[1]; pV = pYUVData[2]; + if (g_H264DumpFrames) + { + FILE* fp; + BYTE* srcp; + char buf[4096]; + + snprintf(buf, sizeof(buf), "/tmp/wlog/H264_%d.ppm", g_H264FrameId); + fp = fopen(buf, "wb"); + fwrite("P5\n", 1, 3, fp); + snprintf(buf, sizeof(buf), "%d %d\n", pSystemBuffer->iWidth, pSystemBuffer->iHeight); + fwrite(buf, 1, strlen(buf), fp); + fwrite("255\n", 1, 4, fp); + + srcp = pY; + + for (j = 0; j < pSystemBuffer->iHeight; j++) + { + fwrite(srcp, 1, pSystemBuffer->iWidth, fp); + srcp += pSystemBuffer->iStride[0]; + } + + fflush(fp); + fclose(fp); + } + + g_H264FrameId++; + + if (h264_prepare_rgb_buffer(h264, pSystemBuffer->iWidth, pSystemBuffer->iHeight) < 0) + return -1; + + freerdp_image_copy_yuv420p_to_xrgb(h264->data, h264->scanline, 0, 0, + h264->width, h264->height, pYUVData, pSystemBuffer->iStride, 0, 0); + + return 1; + #if USE_UPCONVERT /* Convert 4:2:0 YUV to 4:4:4 YUV. */ pU = convert_420_to_444(pU, pSystemBuffer->iWidth / 2, pSystemBuffer->iHeight / 2, pSystemBuffer->iStride[1]); @@ -306,13 +456,16 @@ H264_CONTEXT* h264_context_new(BOOL Compressor) { h264->Compressor = Compressor; + if (h264_prepare_rgb_buffer(h264, 256, 256) < 0) + return NULL; + #ifdef WITH_OPENH264 { static EVideoFormatType videoFormat = videoFormatI420; #if USE_TRACE static int traceLevel = WELS_LOG_DEBUG; - static WelsTraceCallback traceCallback = trace_callback; + static WelsTraceCallback traceCallback = (WelsTraceCallback) trace_callback; #endif SDecodingParam sDecParam; @@ -390,6 +543,8 @@ void h264_context_free(H264_CONTEXT* h264) { if (h264) { + free(h264->data); + #ifdef WITH_OPENH264 if (h264->pDecoder) { From 1087b50e92758d582b94e00867be16ac1215a73b Mon Sep 17 00:00:00 2001 From: Mike McDonald Date: Wed, 9 Jul 2014 19:56:05 -0400 Subject: [PATCH 07/35] Added use of U/V planes to freerdp_image_copy_yuv420p_to_xrgb function. --- libfreerdp/codec/h264.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index 4b0d1de68..c1a2be91c 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -28,8 +28,8 @@ #include #include -#define USE_GRAY_SCALE 1 -#define USE_UPCONVERT 0 +#define USE_GRAY_SCALE 0 +#define USE_UPCONVERT 0 #define USE_TRACE 1 static BYTE clip(int x) @@ -191,17 +191,25 @@ int freerdp_image_copy_yuv420p_to_xrgb(BYTE* pDstData, int nDstStep, int nXDst, BYTE* pDstPixel8; BYTE *pY, *pU, *pV; - pY = pSrcData[0]; - pU = pSrcData[1]; - pV = pSrcData[0]; + pY = pSrcData[0] + (nYSrc * nSrcStep[0]) + nXSrc; pDstPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; for (y = 0; y < nHeight; y++) { + pU = pSrcData[1] + ((nYSrc + y) >> 1) * nSrcStep[1]; + pV = pSrcData[2] + ((nYSrc + y) >> 1) * nSrcStep[1]; + for (x = 0; x < nWidth; x++) { - *((UINT32*) pDstPixel8) = RGB32(*pY, *pY, *pY); + BYTE Y, U, V; + + Y = *pY; + U = pU[(nXSrc + x) >> 1]; + V = pV[(nXSrc + x) >> 1]; + + *((UINT32*) pDstPixel8) = YUV_to_RGB(Y, U, V); + pDstPixel8 += 4; pY++; } From 4370c26e0d06d1d51a5ac6ec992360270f03cf04 Mon Sep 17 00:00:00 2001 From: Mike McDonald Date: Mon, 14 Jul 2014 09:59:57 -0400 Subject: [PATCH 08/35] Added the ability to decode H.264 frames using libavcodec and refactored code to make it a little cleaner. --- include/freerdp/codec/h264.h | 18 ++ libfreerdp/codec/CMakeLists.txt | 10 +- libfreerdp/codec/h264.c | 535 +++++++++++++++++++++----------- 3 files changed, 376 insertions(+), 187 deletions(-) diff --git a/include/freerdp/codec/h264.h b/include/freerdp/codec/h264.h index 8ca83bcc0..3c445d61a 100644 --- a/include/freerdp/codec/h264.h +++ b/include/freerdp/codec/h264.h @@ -23,11 +23,22 @@ #include #include +#ifdef WITH_LIBAVCODEC +#ifdef WITH_OPENH264 +#undef WITH_OPENH264 +#endif +#endif + #ifdef WITH_OPENH264 #include "wels/codec_def.h" #include "wels/codec_api.h" #endif +#ifdef WITH_LIBAVCODEC +#include +#include +#endif + struct _H264_CONTEXT { BOOL Compressor; @@ -41,6 +52,13 @@ struct _H264_CONTEXT #ifdef WITH_OPENH264 ISVCDecoder* pDecoder; #endif + +#ifdef WITH_LIBAVCODEC + AVCodec* codec; + AVCodecContext* codecContext; + AVCodecParserContext* codecParser; + AVFrame* videoFrame; +#endif }; typedef struct _H264_CONTEXT H264_CONTEXT; diff --git a/libfreerdp/codec/CMakeLists.txt b/libfreerdp/codec/CMakeLists.txt index 17f23d99f..36bcbc041 100644 --- a/libfreerdp/codec/CMakeLists.txt +++ b/libfreerdp/codec/CMakeLists.txt @@ -93,6 +93,13 @@ if(WITH_OPENH264) set(FREERDP_OPENH264_LIBS ${OPENH264_LIBRARIES}) endif() +if(WITH_LIBAVCODEC) + add_definitions(-DWITH_LIBAVCODEC) + find_library(LIBAVCODEC_LIB avcodec) + find_library(LIBAVUTIL_LIB avutil) + set(FREERDP_LIBAVCODEC_LIBS ${LIBAVCODEC_LIB} ${LIBAVUTIL_LIB}) +endif() + add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT" MONOLITHIC ${MONOLITHIC_BUILD} SOURCES ${${MODULE_PREFIX}_SRCS} @@ -102,7 +109,8 @@ set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVER set(${MODULE_PREFIX}_LIBS ${FREERDP_JPEG_LIBS} - ${FREERDP_OPENH264_LIBS}) + ${FREERDP_OPENH264_LIBS} + ${FREERDP_LIBAVCODEC_LIBS}) set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index c1a2be91c..c407b6238 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -30,7 +30,6 @@ #define USE_GRAY_SCALE 0 #define USE_UPCONVERT 0 -#define USE_TRACE 1 static BYTE clip(int x) { @@ -103,7 +102,7 @@ static UINT32 YUV_to_RGB(BYTE Y, BYTE U, BYTE V) } #if USE_UPCONVERT -static BYTE* convert_420_to_444(BYTE* chroma420, int chroma420Width, int chroma420Height, int chroma420Stride) +static BYTE* h264_convert_420_to_444(BYTE* chroma420, int chroma420Width, int chroma420Height, int chroma420Stride) { BYTE *chroma444, *src, *dst; int chroma444Width; @@ -153,16 +152,47 @@ static BYTE* convert_420_to_444(BYTE* chroma420, int chroma420Width, int chroma4 } #endif -#if USE_TRACE -static void trace_callback(H264_CONTEXT* h264, int level, const char* message) -{ - printf("%d - %s\n", level, message); -} -#endif - static int g_H264FrameId = 0; static BOOL g_H264DumpFrames = FALSE; +static void h264_dump_h264_data(BYTE* data, int size) +{ + FILE* fp; + char buf[4096]; + + snprintf(buf, sizeof(buf), "/tmp/wlog/bs_%d.h264", g_H264FrameId); + fp = fopen(buf, "wb"); + fwrite(data, 1, size, fp); + fflush(fp); + fclose(fp); +} + +static void h264_dump_yuv_data(BYTE* yuv[], int width, int height, int stride[]) +{ + FILE* fp; + BYTE* srcp; + char buf[4096]; + int j; + + snprintf(buf, sizeof(buf), "/tmp/wlog/H264_%d.ppm", g_H264FrameId); + fp = fopen(buf, "wb"); + fwrite("P5\n", 1, 3, fp); + snprintf(buf, sizeof(buf), "%d %d\n", width, height); + fwrite(buf, 1, strlen(buf), fp); + fwrite("255\n", 1, 4, fp); + + srcp = yuv[0]; + + for (j = 0; j < height; j++) + { + fwrite(srcp, 1, width, fp); + srcp += stride[0]; + } + + fflush(fp); + fclose(fp); +} + int h264_prepare_rgb_buffer(H264_CONTEXT* h264, int width, int height) { UINT32 size; @@ -176,6 +206,7 @@ int h264_prepare_rgb_buffer(H264_CONTEXT* h264, int width, int height) { h264->size = size; h264->data = (BYTE*) realloc(h264->data, h264->size); + memset(h264->data, 0, h264->size); } if (!h264->data) @@ -190,6 +221,17 @@ int freerdp_image_copy_yuv420p_to_xrgb(BYTE* pDstData, int nDstStep, int nXDst, int x, y; BYTE* pDstPixel8; BYTE *pY, *pU, *pV; + int shift = 1; + +#if USE_UPCONVERT + /* Convert 4:2:0 YUV to 4:4:4 YUV. */ + pSrcData[1] = h264_convert_420_to_444(pSrcData[1], nWidth / 2, nHeight / 2, nSrcStep[1]); + pSrcData[2] = h264_convert_420_to_444(pSrcData[2], nWidth / 2, nHeight / 2, nSrcStep[1]); + + nSrcStep[1] = nWidth; + + shift = 0; +#endif pY = pSrcData[0] + (nYSrc * nSrcStep[0]) + nXSrc; @@ -197,16 +239,16 @@ int freerdp_image_copy_yuv420p_to_xrgb(BYTE* pDstData, int nDstStep, int nXDst, for (y = 0; y < nHeight; y++) { - pU = pSrcData[1] + ((nYSrc + y) >> 1) * nSrcStep[1]; - pV = pSrcData[2] + ((nYSrc + y) >> 1) * nSrcStep[1]; + pU = pSrcData[1] + ((nYSrc + y) >> shift) * nSrcStep[1]; + pV = pSrcData[2] + ((nYSrc + y) >> shift) * nSrcStep[1]; for (x = 0; x < nWidth; x++) - { + { BYTE Y, U, V; Y = *pY; - U = pU[(nXSrc + x) >> 1]; - V = pV[(nXSrc + x) >> 1]; + U = pU[(nXSrc + x) >> shift]; + V = pV[(nXSrc + x) >> shift]; *((UINT32*) pDstPixel8) = YUV_to_RGB(Y, U, V); @@ -218,6 +260,11 @@ int freerdp_image_copy_yuv420p_to_xrgb(BYTE* pDstData, int nDstStep, int nXDst, pY += (nSrcStep[0] - nWidth); } +#if USE_UPCONVERT + free(pSrcData[1]); + free(pSrcData[2]); +#endif + return 1; } @@ -269,63 +316,34 @@ BYTE* h264_strip_nal_unit_au_delimiter(BYTE* pSrcData, UINT32* pSrcSize) return pSrcData; } -int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, - BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight) -{ + + +/************************************************* + * + * OpenH264 Implementation + * + ************************************************/ + #ifdef WITH_OPENH264 + +static BOOL g_openh264_trace_enabled = TRUE; + +static void openh264_trace_callback(H264_CONTEXT* h264, int level, const char* message) +{ + printf("%d - %s\n", level, message); +} + +static int openh264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, + BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight) +{ DECODING_STATE state; SBufferInfo sBufferInfo; SSysMEMBuffer* pSystemBuffer; - UINT32 UncompressedSize; - BYTE* pDstData; BYTE* pYUVData[3]; - BYTE* pY; - BYTE* pU; - BYTE* pV; - int Y, U, V; - int i, j; - if (!h264 || !h264->pDecoder) + if (!h264->pDecoder) return -1; - pSrcData = h264_strip_nal_unit_au_delimiter(pSrcData, &SrcSize); - -#if 1 - printf("h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, nDstStep=%d, nXDst=%d, nYDst=%d, nWidth=%d, nHeight=%d)\n", - pSrcData, SrcSize, *ppDstData, nDstStep, nXDst, nYDst, nWidth, nHeight); -#endif - - /* Allocate a destination buffer (if needed). */ - - UncompressedSize = nWidth * nHeight * 4; - - if (UncompressedSize == 0) - return -1; - - pDstData = *ppDstData; - - if (!pDstData) - { - pDstData = (BYTE*) malloc(UncompressedSize); - - if (!pDstData) - return -1; - - *ppDstData = pDstData; - } - - if (g_H264DumpFrames) - { - FILE* fp; - char buf[4096]; - - snprintf(buf, sizeof(buf), "/tmp/wlog/bs_%d.h264", g_H264FrameId); - fp = fopen(buf, "wb"); - fwrite(pSrcData, 1, SrcSize, fp); - fflush(fp); - fclose(fp); - } - /* * Decompress the image. The RDP host only seems to send I420 format. */ @@ -366,33 +384,9 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, /* Convert I420 (same as IYUV) to XRGB. */ - pY = pYUVData[0]; - pU = pYUVData[1]; - pV = pYUVData[2]; - if (g_H264DumpFrames) { - FILE* fp; - BYTE* srcp; - char buf[4096]; - - snprintf(buf, sizeof(buf), "/tmp/wlog/H264_%d.ppm", g_H264FrameId); - fp = fopen(buf, "wb"); - fwrite("P5\n", 1, 3, fp); - snprintf(buf, sizeof(buf), "%d %d\n", pSystemBuffer->iWidth, pSystemBuffer->iHeight); - fwrite(buf, 1, strlen(buf), fp); - fwrite("255\n", 1, 4, fp); - - srcp = pY; - - for (j = 0; j < pSystemBuffer->iHeight; j++) - { - fwrite(srcp, 1, pSystemBuffer->iWidth, fp); - srcp += pSystemBuffer->iStride[0]; - } - - fflush(fp); - fclose(fp); + h264_dump_yuv_data(pYUVData, pSystemBuffer->iWidth, pSystemBuffer->iHeight, pSystemBuffer->iStride); } g_H264FrameId++; @@ -404,41 +398,269 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, h264->width, h264->height, pYUVData, pSystemBuffer->iStride, 0, 0); return 1; +} -#if USE_UPCONVERT - /* Convert 4:2:0 YUV to 4:4:4 YUV. */ - pU = convert_420_to_444(pU, pSystemBuffer->iWidth / 2, pSystemBuffer->iHeight / 2, pSystemBuffer->iStride[1]); - pV = convert_420_to_444(pV, pSystemBuffer->iWidth / 2, pSystemBuffer->iHeight / 2, pSystemBuffer->iStride[1]); -#endif - - for (j = 0; j < nHeight; j++) +static void openh264_free(H264_CONTEXT* h264) +{ + if (h264->pDecoder) { - BYTE *pXRGB = pDstData + ((nYDst + j) * nDstStep) + (nXDst * 4); - int y = nYDst + j; + (*h264->pDecoder)->Uninitialize(h264->pDecoder); + WelsDestroyDecoder(h264->pDecoder); + h264->pDecoder = NULL; + } +} - for (i = 0; i < nWidth; i++) +static BOOL openh264_init(H264_CONTEXT* h264) +{ + static EVideoFormatType videoFormat = videoFormatI420; + + static int traceLevel = WELS_LOG_DEBUG; + static WelsTraceCallback traceCallback = (WelsTraceCallback) openh264_trace_callback; + + SDecodingParam sDecParam; + long status; + + WelsCreateDecoder(&h264->pDecoder); + + if (!h264->pDecoder) + { + printf("Failed to create OpenH264 decoder\n"); + goto EXCEPTION; + } + + ZeroMemory(&sDecParam, sizeof(sDecParam)); + sDecParam.iOutputColorFormat = videoFormatI420; + sDecParam.uiEcActiveFlag = 1; + sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT; + + status = (*h264->pDecoder)->Initialize(h264->pDecoder, &sDecParam); + + if (status != 0) + { + printf("Failed to initialize OpenH264 decoder (status=%ld)\n", status); + goto EXCEPTION; + } + + status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_DATAFORMAT, &videoFormat); + + if (status != 0) + { + printf("Failed to set data format option on OpenH264 decoder (status=%ld)\n", status); + } + + if (g_openh264_trace_enabled) + { + status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_LEVEL, &traceLevel); + if (status != 0) { - int x = nXDst + i; + printf("Failed to set trace level option on OpenH264 decoder (status=%ld)\n", status); + } - Y = pY[(y * pSystemBuffer->iStride[0]) + x]; -#if USE_UPCONVERT - U = pU[(y * pSystemBuffer->iWidth) + x]; - V = pV[(y * pSystemBuffer->iWidth) + x]; -#else - U = pU[(y/2) * pSystemBuffer->iStride[1] + (x/2)]; - V = pV[(y/2) * pSystemBuffer->iStride[1] + (x/2)]; -#endif + status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_CALLBACK, &traceCallback); + if (status != 0) + { + printf("Failed to set trace callback option on OpenH264 decoder (status=%ld)\n", status); + } - *(UINT32*)pXRGB = YUV_to_RGB(Y, U, V); - - pXRGB += 4; + status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_CALLBACK_CONTEXT, &h264); + if (status != 0) + { + printf("Failed to set trace callback context option on OpenH264 decoder (status=%ld)\n", status); } } -#if USE_UPCONVERT - free(pU); - free(pV); + return TRUE; + +EXCEPTION: + openh264_free(h264); + + return FALSE; +} + #endif + + + +/************************************************* + * + * libavcodec Implementation + * + ************************************************/ + +#ifdef WITH_LIBAVCODEC + +static int libavcodec_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, + BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight) +{ + AVPacket packet; + int gotFrame = 0; + int status; + + av_init_packet(&packet); + + packet.data = pSrcData; + packet.size = SrcSize; + + status = avcodec_decode_video2(h264->codecContext, h264->videoFrame, &gotFrame, &packet); + + if (status < 0) + { + printf("Failed to decode video frame (status=%d)\n", status); + return -1; + } + + printf("libavcodec_decompress: frame decoded (status=%d, gotFrame=%d, width=%d, height=%d, Y=[%p,%d], U=[%p,%d], V=[%p,%d])\n", + status, gotFrame, h264->videoFrame->width, h264->videoFrame->height, + h264->videoFrame->data[0], h264->videoFrame->linesize[0], + h264->videoFrame->data[1], h264->videoFrame->linesize[1], + h264->videoFrame->data[2], h264->videoFrame->linesize[2]); + fflush(stdout); + + if (gotFrame) + { + if (g_H264DumpFrames) + { + h264_dump_yuv_data(h264->videoFrame->data, h264->videoFrame->width, h264->videoFrame->height, h264->videoFrame->linesize); + } + + if (h264_prepare_rgb_buffer(h264, h264->videoFrame->width, h264->videoFrame->height) < 0) + return -1; + + freerdp_image_copy_yuv420p_to_xrgb(h264->data, h264->scanline, 0, 0, + h264->width, h264->height, h264->videoFrame->data, h264->videoFrame->linesize, 0, 0); + } + + return 1; +} + +static void libavcodec_free(H264_CONTEXT* h264) +{ + if (h264->videoFrame) + { + av_free(h264->videoFrame); + } + + if (h264->codecParser) + { + av_parser_close(h264->codecParser); + } + + if (h264->codecContext) + { + avcodec_close(h264->codecContext); + av_free(h264->codecContext); + } +} + +static BOOL libavcodec_init(H264_CONTEXT* h264) +{ + avcodec_register_all(); + + h264->codec = avcodec_find_decoder(CODEC_ID_H264); + if (!h264->codec) + { + printf("Failed to find libav H.264 codec\n"); + goto EXCEPTION; + } + + h264->codecContext = avcodec_alloc_context3(h264->codec); + if (!h264->codecContext) + { + printf("Failed to allocate libav codec context\n"); + goto EXCEPTION; + } + + if (h264->codec->capabilities & CODEC_CAP_TRUNCATED) + { + h264->codecContext->flags |= CODEC_FLAG_TRUNCATED; + } + + if (avcodec_open2(h264->codecContext, h264->codec, NULL) < 0) + { + printf("Failed to open libav codec\n"); + goto EXCEPTION; + } + + h264->codecParser = av_parser_init(CODEC_ID_H264); + if (!h264->codecParser) + { + printf("Failed to initialize libav parser\n"); + goto EXCEPTION; + } + + h264->videoFrame = avcodec_alloc_frame(); + if (!h264->videoFrame) + { + printf("Failed to allocate libav frame\n"); + goto EXCEPTION; + } + + return TRUE; + +EXCEPTION: + libavcodec_free(h264); + + return FALSE; +} + +#endif + + + +int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, + BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight) +{ + UINT32 UncompressedSize; + BYTE* pDstData; + + if (!h264) + return -1; + +#if 0 + pSrcData = h264_strip_nal_unit_au_delimiter(pSrcData, &SrcSize); +#endif + +#if 1 + printf("h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, nDstStep=%d, nXDst=%d, nYDst=%d, nWidth=%d, nHeight=%d)\n", + pSrcData, SrcSize, *ppDstData, nDstStep, nXDst, nYDst, nWidth, nHeight); +#endif + + /* Allocate a destination buffer (if needed). */ + + UncompressedSize = nWidth * nHeight * 4; + + if (UncompressedSize == 0) + return -1; + + pDstData = *ppDstData; + + if (!pDstData) + { + pDstData = (BYTE*) malloc(UncompressedSize); + + if (!pDstData) + return -1; + + *ppDstData = pDstData; + } + + if (g_H264DumpFrames) + { + h264_dump_h264_data(pSrcData, SrcSize); + } + +#ifdef WITH_OPENH264 + return openh264_decompress( + h264, pSrcData, SrcSize, + pDstData, DstFormat, nDstStep, + nXDst, nYDst, nWidth, nHeight); +#endif + +#ifdef WITH_LIBAVCODEC + return libavcodec_decompress( + h264, pSrcData, SrcSize, + pDstData, DstFormat, nDstStep, + nXDst, nYDst, nWidth, nHeight); #endif return 1; @@ -451,7 +673,6 @@ int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppD void h264_context_reset(H264_CONTEXT* h264) { - } H264_CONTEXT* h264_context_new(BOOL Compressor) @@ -468,64 +689,18 @@ H264_CONTEXT* h264_context_new(BOOL Compressor) return NULL; #ifdef WITH_OPENH264 + if (!openh264_init(h264)) { - static EVideoFormatType videoFormat = videoFormatI420; - -#if USE_TRACE - static int traceLevel = WELS_LOG_DEBUG; - static WelsTraceCallback traceCallback = (WelsTraceCallback) trace_callback; + free(h264); + return NULL; + } #endif - SDecodingParam sDecParam; - long status; - - WelsCreateDecoder(&h264->pDecoder); - - if (!h264->pDecoder) - { - printf("Failed to create OpenH264 decoder\n"); - goto EXCEPTION; - } - - ZeroMemory(&sDecParam, sizeof(sDecParam)); - sDecParam.iOutputColorFormat = videoFormatI420; - sDecParam.uiEcActiveFlag = 1; - sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT; - - status = (*h264->pDecoder)->Initialize(h264->pDecoder, &sDecParam); - - if (status != 0) - { - printf("Failed to initialize OpenH264 decoder (status=%ld)\n", status); - goto EXCEPTION; - } - - status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_DATAFORMAT, &videoFormat); - - if (status != 0) - { - printf("Failed to set data format option on OpenH264 decoder (status=%ld)\n", status); - } - -#if USE_TRACE - status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_LEVEL, &traceLevel); - if (status != 0) - { - printf("Failed to set trace level option on OpenH264 decoder (status=%ld)\n", status); - } - - status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_CALLBACK, &traceCallback); - if (status != 0) - { - printf("Failed to set trace callback option on OpenH264 decoder (status=%ld)\n", status); - } - - status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_CALLBACK_CONTEXT, &h264); - if (status != 0) - { - printf("Failed to set trace callback context option on OpenH264 decoder (status=%ld)\n", status); - } -#endif +#ifdef WITH_LIBAVCODEC + if (!libavcodec_init(h264)) + { + free(h264); + return NULL; } #endif @@ -533,18 +708,6 @@ H264_CONTEXT* h264_context_new(BOOL Compressor) } return h264; - -EXCEPTION: -#ifdef WITH_OPENH264 - if (h264->pDecoder) - { - WelsDestroyDecoder(h264->pDecoder); - } -#endif - - free(h264); - - return NULL; } void h264_context_free(H264_CONTEXT* h264) @@ -554,11 +717,11 @@ void h264_context_free(H264_CONTEXT* h264) free(h264->data); #ifdef WITH_OPENH264 - if (h264->pDecoder) - { - (*h264->pDecoder)->Uninitialize(h264->pDecoder); - WelsDestroyDecoder(h264->pDecoder); - } + openh264_free(h264); +#endif + +#ifdef WITH_LIBAVCODEC + libavcodec_free(h264); #endif free(h264); From 625f7c3c22bb94e0908cd96a12974ec0f67685a5 Mon Sep 17 00:00:00 2001 From: Daniel Bungert Date: Thu, 17 Jul 2014 06:59:06 -0600 Subject: [PATCH 09/35] Add arguments for managing tls ciphers & netmon This adds 2 arguments: /tls-ciphers List of permitted openssl ciphers - see ciphers(1) /tls-ciphers-netmon Use tls ciphers that netmon can parse With KB2919355, client/server negotiate the use of TLS cipher TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, which works fine except that netmon can't parse it. By adding commandline /tls-ciphers-netmon, we restrict the available ciphers to a list that netmon can deal with. Also adds /tls-ciphers, which accepts a string arg, for further customization. --- client/common/cmdline.c | 10 ++++++++++ include/freerdp/settings.h | 3 ++- libfreerdp/core/settings.c | 1 + libfreerdp/crypto/tls.c | 7 +++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 18c180c87..44c153779 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -127,6 +127,8 @@ COMMAND_LINE_ARGUMENT_A args[] = { "sec-tls", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "tls protocol security" }, { "sec-nla", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "nla protocol security" }, { "sec-ext", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "nla extended protocol security" }, + { "tls-ciphers", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "List of permitted openssl ciphers - see ciphers(1)" }, + { "tls-ciphers-netmon", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Use tls ciphers that netmon can parse" }, { "cert-name", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "certificate name" }, { "cert-ignore", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "ignore certificate" }, { "pcb", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Preconnection Blob" }, @@ -1753,6 +1755,14 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, { settings->ExtSecurity = arg->Value ? TRUE : FALSE; } + CommandLineSwitchCase(arg, "tls-ciphers") + { + settings->PermittedTLSCiphers = _strdup(arg->Value); + } + CommandLineSwitchCase(arg, "tls-ciphers-netmon") + { + settings->PermittedTLSCiphers = arg->Value ? _strdup("ALL:!ECDH") : NULL; + } CommandLineSwitchCase(arg, "cert-name") { settings->CertificateName = _strdup(arg->Value); diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 7fa967525..dd4b49d93 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -974,7 +974,8 @@ struct rdp_settings ALIGN64 char* AuthenticationServiceClass; /* 1098 */ ALIGN64 BOOL DisableCredentialsDelegation; /* 1099 */ ALIGN64 BOOL AuthenticationLevel; /* 1100 */ - UINT64 padding1152[1152 - 1101]; /* 1101 */ + ALIGN64 char* PermittedTLSCiphers; /* 1101 */ + UINT64 padding1152[1152 - 1102]; /* 1102 */ /* Connection Cookie */ ALIGN64 BOOL MstscCookieMode; /* 1152 */ diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 04f92caa9..124c6d2a0 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -825,6 +825,7 @@ void freerdp_settings_free(rdpSettings* settings) free(settings->MonitorDefArray); free(settings->ClientAddress); free(settings->ClientDir); + free(settings->PermittedTLSCiphers); free(settings->CertificateFile); free(settings->PrivateKeyFile); free(settings->ConnectionFile); diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 967bf1586..b22e94a0e 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -591,6 +591,13 @@ BOOL tls_prepare(rdpTls* tls, BIO *underlying, const SSL_METHOD *method, int opt SSL_CTX_set_options(tls->ctx, options); SSL_CTX_set_read_ahead(tls->ctx, 1); + if (tls->settings->PermittedTLSCiphers) { + if(!SSL_CTX_set_cipher_list(tls->ctx, tls->settings->PermittedTLSCiphers)) { + fprintf(stderr, "SSL_CTX_set_cipher_list %s failed\n", tls->settings->PermittedTLSCiphers); + return FALSE; + } + } + tls->bio = BIO_new_rdp_tls(tls->ctx, clientMode); if (BIO_get_ssl(tls->bio, &tls->ssl) < 0) From 19c25cf2b49e4a8c24017b35d004cf337ce0f9f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 17 Jul 2014 17:34:51 -0400 Subject: [PATCH 10/35] winpr-pool: fix header on non-Windows --- winpr/include/winpr/pool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winpr/include/winpr/pool.h b/winpr/include/winpr/pool.h index c9b1727b3..8dc335084 100644 --- a/winpr/include/winpr/pool.h +++ b/winpr/include/winpr/pool.h @@ -120,7 +120,7 @@ typedef struct _TP_WAIT TP_WAIT, *PTP_WAIT; typedef struct _TP_IO TP_IO, *PTP_IO; -#if (defined(_WIN32) && (_WIN32_WINNT < 0x0601)) +#if !defined(_WIN32) || (defined(_WIN32) && (_WIN32_WINNT < 0x0601)) typedef TP_CALLBACK_ENVIRON_V1 TP_CALLBACK_ENVIRON, *PTP_CALLBACK_ENVIRON; #endif From ae1fdf6153bcd194194fcc1ea74c43afe866e9c0 Mon Sep 17 00:00:00 2001 From: Mike Gilbert Date: Sun, 20 Jul 2014 00:52:35 -0400 Subject: [PATCH 11/35] Remove execute bit from many files --- .gitignore | 0 CMakeLists.txt | 0 .../res/drawable-hdpi/sym_keyboard_delete.png | Bin .../drawable-hdpi/sym_keyboard_feedback_delete.png | Bin .../drawable-hdpi/sym_keyboard_feedback_return.png | Bin .../res/drawable-hdpi/sym_keyboard_return.png | Bin .../FreeRDPCore/res/drawable-mdpi/icon_star_off.png | Bin .../FreeRDPCore/res/drawable-mdpi/icon_star_on.png | Bin .../res/drawable/sym_keyboard_arrows.png | Bin .../res/drawable/sym_keyboard_arrows_black.png | Bin .../res/drawable/sym_keyboard_down_arrow.png | Bin .../res/drawable/sym_keyboard_down_arrow_black.png | Bin .../res/drawable/sym_keyboard_left_arrow.png | Bin .../res/drawable/sym_keyboard_left_arrow_black.png | Bin .../FreeRDPCore/res/drawable/sym_keyboard_menu.png | Bin .../res/drawable/sym_keyboard_menu_black.png | Bin .../res/drawable/sym_keyboard_right_arrow.png | Bin .../res/drawable/sym_keyboard_right_arrow_black.png | Bin .../res/drawable/sym_keyboard_up_arrow.png | Bin .../res/drawable/sym_keyboard_up_arrow_black.png | Bin .../res/drawable/sym_keyboard_winkey.png | Bin .../res/drawable/sym_keyboard_winkey_black.png | Bin .../res/drawable/touch_pointer_active.png | Bin client/Mac/CMakeLists.txt | 0 client/Mac/Credits.rtf | 0 client/Mac/MRDPView.h | 0 client/Mac/cli/MainMenu.xib | 0 client/Mac/mf_client.h | 0 client/Mac/mf_client.m | 0 client/iOS/FreeRDP/ios_freerdp_events.h | 0 client/iOS/FreeRDP/ios_freerdp_events.m | 0 client/iOS/Misc/Reachability.h | 0 client/iOS/Misc/Reachability.m | 0 client/iOS/Misc/SFHFKeychainUtils.h | 0 client/iOS/Misc/SFHFKeychainUtils.m | 0 client/iOS/Resources/Default-568h@2x.png | Bin client/iOS/Resources/Default-Landscape@2x~ipad.png | Bin client/iOS/Resources/Default-Landscape~ipad.png | Bin client/iOS/Resources/Default-Portrait@2x~ipad.png | Bin client/iOS/Resources/Default-Portrait~ipad.png | Bin client/iOS/Resources/Default.png | Bin client/iOS/Resources/Default@2x.png | Bin client/iOS/Resources/Icon-72.png | Bin client/iOS/Resources/Icon-72@2x.png | Bin client/iOS/Resources/Icon.png | Bin client/iOS/Resources/Icon@2x.png | Bin client/iOS/Resources/about_page/FreeRDP_Logo.png | Bin client/iOS/Resources/about_page/about.html | 0 client/iOS/Resources/about_page/about_phone.html | 0 client/iOS/Resources/about_page/back.jpg | Bin .../Resources/about_page/background_transparent.png | Bin client/iOS/Resources/help_page/back.jpg | Bin client/iOS/Resources/help_page/gestures.html | 0 client/iOS/Resources/help_page/gestures.png | Bin client/iOS/Resources/help_page/gestures_phone.html | 0 client/iOS/Resources/help_page/gestures_phone.png | Bin client/iOS/Resources/help_page/nav_gestures.png | Bin client/iOS/Resources/help_page/nav_toolbar.png | Bin .../iOS/Resources/help_page/nav_touch_pointer.png | Bin client/iOS/Resources/help_page/toolbar.html | 0 client/iOS/Resources/help_page/toolbar.png | Bin client/iOS/Resources/help_page/toolbar_phone.html | 0 client/iOS/Resources/help_page/toolbar_phone.png | Bin client/iOS/Resources/help_page/touch_pointer.html | 0 client/iOS/Resources/help_page/touch_pointer.png | Bin .../Resources/help_page/touch_pointer_phone.html | 0 .../iOS/Resources/help_page/touch_pointer_phone.png | Bin client/iOS/Resources/icon_accessory_star_off.png | Bin client/iOS/Resources/icon_accessory_star_on.png | Bin client/iOS/Resources/icon_key_arrow_down.png | Bin client/iOS/Resources/icon_key_arrow_left.png | Bin client/iOS/Resources/icon_key_arrow_right.png | Bin client/iOS/Resources/icon_key_arrow_up.png | Bin client/iOS/Resources/icon_key_arrows.png | Bin client/iOS/Resources/icon_key_backspace.png | Bin client/iOS/Resources/icon_key_menu.png | Bin client/iOS/Resources/icon_key_return.png | Bin client/iOS/Resources/icon_key_win.png | Bin client/iOS/Resources/keyboard_button_background.png | Bin client/iOS/Resources/tabbar_icon_about.png | Bin client/iOS/Resources/tabbar_icon_help.png | Bin client/iOS/Resources/tabbar_icon_settings.png | Bin client/iOS/Resources/toolbar_icon_disconnect.png | Bin client/iOS/Resources/toolbar_icon_extkeyboad.png | Bin client/iOS/Resources/toolbar_icon_home.png | Bin client/iOS/Resources/toolbar_icon_keyboard.png | Bin client/iOS/Resources/toolbar_icon_touchpointer.png | Bin client/iOS/Resources/toolbar_icon_win.png | Bin client/iOS/Resources/touch_pointer_active.png | Bin client/iOS/Resources/touch_pointer_default.png | Bin client/iOS/Resources/touch_pointer_extkeyboard.png | Bin client/iOS/Resources/touch_pointer_keyboard.png | Bin client/iOS/Resources/touch_pointer_lclick.png | Bin client/iOS/Resources/touch_pointer_rclick.png | Bin client/iOS/Resources/touch_pointer_reset.png | Bin client/iOS/Resources/touch_pointer_scroll.png | Bin client/iOS/Views/BlockAlertView.h | 0 client/iOS/Views/BlockAlertView.m | 0 config.h.in | 0 include/freerdp/error.h | 0 100 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 .gitignore mode change 100755 => 100644 CMakeLists.txt mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_delete.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_delete.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_return.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_return.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_off.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_on.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows_black.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow_black.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow_black.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu_black.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow_black.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow_black.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey_black.png mode change 100755 => 100644 client/Android/FreeRDPCore/res/drawable/touch_pointer_active.png mode change 100755 => 100644 client/Mac/CMakeLists.txt mode change 100755 => 100644 client/Mac/Credits.rtf mode change 100755 => 100644 client/Mac/MRDPView.h mode change 100755 => 100644 client/Mac/cli/MainMenu.xib mode change 100755 => 100644 client/Mac/mf_client.h mode change 100755 => 100644 client/Mac/mf_client.m mode change 100755 => 100644 client/iOS/FreeRDP/ios_freerdp_events.h mode change 100755 => 100644 client/iOS/FreeRDP/ios_freerdp_events.m mode change 100755 => 100644 client/iOS/Misc/Reachability.h mode change 100755 => 100644 client/iOS/Misc/Reachability.m mode change 100755 => 100644 client/iOS/Misc/SFHFKeychainUtils.h mode change 100755 => 100644 client/iOS/Misc/SFHFKeychainUtils.m mode change 100755 => 100644 client/iOS/Resources/Default-568h@2x.png mode change 100755 => 100644 client/iOS/Resources/Default-Landscape@2x~ipad.png mode change 100755 => 100644 client/iOS/Resources/Default-Landscape~ipad.png mode change 100755 => 100644 client/iOS/Resources/Default-Portrait@2x~ipad.png mode change 100755 => 100644 client/iOS/Resources/Default-Portrait~ipad.png mode change 100755 => 100644 client/iOS/Resources/Default.png mode change 100755 => 100644 client/iOS/Resources/Default@2x.png mode change 100755 => 100644 client/iOS/Resources/Icon-72.png mode change 100755 => 100644 client/iOS/Resources/Icon-72@2x.png mode change 100755 => 100644 client/iOS/Resources/Icon.png mode change 100755 => 100644 client/iOS/Resources/Icon@2x.png mode change 100755 => 100644 client/iOS/Resources/about_page/FreeRDP_Logo.png mode change 100755 => 100644 client/iOS/Resources/about_page/about.html mode change 100755 => 100644 client/iOS/Resources/about_page/about_phone.html mode change 100755 => 100644 client/iOS/Resources/about_page/back.jpg mode change 100755 => 100644 client/iOS/Resources/about_page/background_transparent.png mode change 100755 => 100644 client/iOS/Resources/help_page/back.jpg mode change 100755 => 100644 client/iOS/Resources/help_page/gestures.html mode change 100755 => 100644 client/iOS/Resources/help_page/gestures.png mode change 100755 => 100644 client/iOS/Resources/help_page/gestures_phone.html mode change 100755 => 100644 client/iOS/Resources/help_page/gestures_phone.png mode change 100755 => 100644 client/iOS/Resources/help_page/nav_gestures.png mode change 100755 => 100644 client/iOS/Resources/help_page/nav_toolbar.png mode change 100755 => 100644 client/iOS/Resources/help_page/nav_touch_pointer.png mode change 100755 => 100644 client/iOS/Resources/help_page/toolbar.html mode change 100755 => 100644 client/iOS/Resources/help_page/toolbar.png mode change 100755 => 100644 client/iOS/Resources/help_page/toolbar_phone.html mode change 100755 => 100644 client/iOS/Resources/help_page/toolbar_phone.png mode change 100755 => 100644 client/iOS/Resources/help_page/touch_pointer.html mode change 100755 => 100644 client/iOS/Resources/help_page/touch_pointer.png mode change 100755 => 100644 client/iOS/Resources/help_page/touch_pointer_phone.html mode change 100755 => 100644 client/iOS/Resources/help_page/touch_pointer_phone.png mode change 100755 => 100644 client/iOS/Resources/icon_accessory_star_off.png mode change 100755 => 100644 client/iOS/Resources/icon_accessory_star_on.png mode change 100755 => 100644 client/iOS/Resources/icon_key_arrow_down.png mode change 100755 => 100644 client/iOS/Resources/icon_key_arrow_left.png mode change 100755 => 100644 client/iOS/Resources/icon_key_arrow_right.png mode change 100755 => 100644 client/iOS/Resources/icon_key_arrow_up.png mode change 100755 => 100644 client/iOS/Resources/icon_key_arrows.png mode change 100755 => 100644 client/iOS/Resources/icon_key_backspace.png mode change 100755 => 100644 client/iOS/Resources/icon_key_menu.png mode change 100755 => 100644 client/iOS/Resources/icon_key_return.png mode change 100755 => 100644 client/iOS/Resources/icon_key_win.png mode change 100755 => 100644 client/iOS/Resources/keyboard_button_background.png mode change 100755 => 100644 client/iOS/Resources/tabbar_icon_about.png mode change 100755 => 100644 client/iOS/Resources/tabbar_icon_help.png mode change 100755 => 100644 client/iOS/Resources/tabbar_icon_settings.png mode change 100755 => 100644 client/iOS/Resources/toolbar_icon_disconnect.png mode change 100755 => 100644 client/iOS/Resources/toolbar_icon_extkeyboad.png mode change 100755 => 100644 client/iOS/Resources/toolbar_icon_home.png mode change 100755 => 100644 client/iOS/Resources/toolbar_icon_keyboard.png mode change 100755 => 100644 client/iOS/Resources/toolbar_icon_touchpointer.png mode change 100755 => 100644 client/iOS/Resources/toolbar_icon_win.png mode change 100755 => 100644 client/iOS/Resources/touch_pointer_active.png mode change 100755 => 100644 client/iOS/Resources/touch_pointer_default.png mode change 100755 => 100644 client/iOS/Resources/touch_pointer_extkeyboard.png mode change 100755 => 100644 client/iOS/Resources/touch_pointer_keyboard.png mode change 100755 => 100644 client/iOS/Resources/touch_pointer_lclick.png mode change 100755 => 100644 client/iOS/Resources/touch_pointer_rclick.png mode change 100755 => 100644 client/iOS/Resources/touch_pointer_reset.png mode change 100755 => 100644 client/iOS/Resources/touch_pointer_scroll.png mode change 100755 => 100644 client/iOS/Views/BlockAlertView.h mode change 100755 => 100644 client/iOS/Views/BlockAlertView.m mode change 100755 => 100644 config.h.in mode change 100755 => 100644 include/freerdp/error.h diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_delete.png b/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_delete.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_delete.png b/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_delete.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_return.png b/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_return.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_return.png b/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_return.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_off.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_off.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_on.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_on.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows_black.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow_black.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow_black.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu_black.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow_black.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow_black.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey_black.png old mode 100755 new mode 100644 diff --git a/client/Android/FreeRDPCore/res/drawable/touch_pointer_active.png b/client/Android/FreeRDPCore/res/drawable/touch_pointer_active.png old mode 100755 new mode 100644 diff --git a/client/Mac/CMakeLists.txt b/client/Mac/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/client/Mac/Credits.rtf b/client/Mac/Credits.rtf old mode 100755 new mode 100644 diff --git a/client/Mac/MRDPView.h b/client/Mac/MRDPView.h old mode 100755 new mode 100644 diff --git a/client/Mac/cli/MainMenu.xib b/client/Mac/cli/MainMenu.xib old mode 100755 new mode 100644 diff --git a/client/Mac/mf_client.h b/client/Mac/mf_client.h old mode 100755 new mode 100644 diff --git a/client/Mac/mf_client.m b/client/Mac/mf_client.m old mode 100755 new mode 100644 diff --git a/client/iOS/FreeRDP/ios_freerdp_events.h b/client/iOS/FreeRDP/ios_freerdp_events.h old mode 100755 new mode 100644 diff --git a/client/iOS/FreeRDP/ios_freerdp_events.m b/client/iOS/FreeRDP/ios_freerdp_events.m old mode 100755 new mode 100644 diff --git a/client/iOS/Misc/Reachability.h b/client/iOS/Misc/Reachability.h old mode 100755 new mode 100644 diff --git a/client/iOS/Misc/Reachability.m b/client/iOS/Misc/Reachability.m old mode 100755 new mode 100644 diff --git a/client/iOS/Misc/SFHFKeychainUtils.h b/client/iOS/Misc/SFHFKeychainUtils.h old mode 100755 new mode 100644 diff --git a/client/iOS/Misc/SFHFKeychainUtils.m b/client/iOS/Misc/SFHFKeychainUtils.m old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/Default-568h@2x.png b/client/iOS/Resources/Default-568h@2x.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/Default-Landscape@2x~ipad.png b/client/iOS/Resources/Default-Landscape@2x~ipad.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/Default-Landscape~ipad.png b/client/iOS/Resources/Default-Landscape~ipad.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/Default-Portrait@2x~ipad.png b/client/iOS/Resources/Default-Portrait@2x~ipad.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/Default-Portrait~ipad.png b/client/iOS/Resources/Default-Portrait~ipad.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/Default.png b/client/iOS/Resources/Default.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/Default@2x.png b/client/iOS/Resources/Default@2x.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/Icon-72.png b/client/iOS/Resources/Icon-72.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/Icon-72@2x.png b/client/iOS/Resources/Icon-72@2x.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/Icon.png b/client/iOS/Resources/Icon.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/Icon@2x.png b/client/iOS/Resources/Icon@2x.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/about_page/FreeRDP_Logo.png b/client/iOS/Resources/about_page/FreeRDP_Logo.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/about_page/about.html b/client/iOS/Resources/about_page/about.html old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/about_page/about_phone.html b/client/iOS/Resources/about_page/about_phone.html old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/about_page/back.jpg b/client/iOS/Resources/about_page/back.jpg old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/about_page/background_transparent.png b/client/iOS/Resources/about_page/background_transparent.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/back.jpg b/client/iOS/Resources/help_page/back.jpg old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/gestures.html b/client/iOS/Resources/help_page/gestures.html old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/gestures.png b/client/iOS/Resources/help_page/gestures.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/gestures_phone.html b/client/iOS/Resources/help_page/gestures_phone.html old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/gestures_phone.png b/client/iOS/Resources/help_page/gestures_phone.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/nav_gestures.png b/client/iOS/Resources/help_page/nav_gestures.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/nav_toolbar.png b/client/iOS/Resources/help_page/nav_toolbar.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/nav_touch_pointer.png b/client/iOS/Resources/help_page/nav_touch_pointer.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/toolbar.html b/client/iOS/Resources/help_page/toolbar.html old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/toolbar.png b/client/iOS/Resources/help_page/toolbar.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/toolbar_phone.html b/client/iOS/Resources/help_page/toolbar_phone.html old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/toolbar_phone.png b/client/iOS/Resources/help_page/toolbar_phone.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/touch_pointer.html b/client/iOS/Resources/help_page/touch_pointer.html old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/touch_pointer.png b/client/iOS/Resources/help_page/touch_pointer.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/touch_pointer_phone.html b/client/iOS/Resources/help_page/touch_pointer_phone.html old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/help_page/touch_pointer_phone.png b/client/iOS/Resources/help_page/touch_pointer_phone.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/icon_accessory_star_off.png b/client/iOS/Resources/icon_accessory_star_off.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/icon_accessory_star_on.png b/client/iOS/Resources/icon_accessory_star_on.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/icon_key_arrow_down.png b/client/iOS/Resources/icon_key_arrow_down.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/icon_key_arrow_left.png b/client/iOS/Resources/icon_key_arrow_left.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/icon_key_arrow_right.png b/client/iOS/Resources/icon_key_arrow_right.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/icon_key_arrow_up.png b/client/iOS/Resources/icon_key_arrow_up.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/icon_key_arrows.png b/client/iOS/Resources/icon_key_arrows.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/icon_key_backspace.png b/client/iOS/Resources/icon_key_backspace.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/icon_key_menu.png b/client/iOS/Resources/icon_key_menu.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/icon_key_return.png b/client/iOS/Resources/icon_key_return.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/icon_key_win.png b/client/iOS/Resources/icon_key_win.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/keyboard_button_background.png b/client/iOS/Resources/keyboard_button_background.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/tabbar_icon_about.png b/client/iOS/Resources/tabbar_icon_about.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/tabbar_icon_help.png b/client/iOS/Resources/tabbar_icon_help.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/tabbar_icon_settings.png b/client/iOS/Resources/tabbar_icon_settings.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/toolbar_icon_disconnect.png b/client/iOS/Resources/toolbar_icon_disconnect.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/toolbar_icon_extkeyboad.png b/client/iOS/Resources/toolbar_icon_extkeyboad.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/toolbar_icon_home.png b/client/iOS/Resources/toolbar_icon_home.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/toolbar_icon_keyboard.png b/client/iOS/Resources/toolbar_icon_keyboard.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/toolbar_icon_touchpointer.png b/client/iOS/Resources/toolbar_icon_touchpointer.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/toolbar_icon_win.png b/client/iOS/Resources/toolbar_icon_win.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/touch_pointer_active.png b/client/iOS/Resources/touch_pointer_active.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/touch_pointer_default.png b/client/iOS/Resources/touch_pointer_default.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/touch_pointer_extkeyboard.png b/client/iOS/Resources/touch_pointer_extkeyboard.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/touch_pointer_keyboard.png b/client/iOS/Resources/touch_pointer_keyboard.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/touch_pointer_lclick.png b/client/iOS/Resources/touch_pointer_lclick.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/touch_pointer_rclick.png b/client/iOS/Resources/touch_pointer_rclick.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/touch_pointer_reset.png b/client/iOS/Resources/touch_pointer_reset.png old mode 100755 new mode 100644 diff --git a/client/iOS/Resources/touch_pointer_scroll.png b/client/iOS/Resources/touch_pointer_scroll.png old mode 100755 new mode 100644 diff --git a/client/iOS/Views/BlockAlertView.h b/client/iOS/Views/BlockAlertView.h old mode 100755 new mode 100644 diff --git a/client/iOS/Views/BlockAlertView.m b/client/iOS/Views/BlockAlertView.m old mode 100755 new mode 100644 diff --git a/config.h.in b/config.h.in old mode 100755 new mode 100644 diff --git a/include/freerdp/error.h b/include/freerdp/error.h old mode 100755 new mode 100644 From 2bb0659fb487c8e78146542a8f8f0f94cf53efb4 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Thu, 24 Jul 2014 16:29:46 +0200 Subject: [PATCH 12/35] core: improve fast-path multifragment handling * make sure fast-path packages are not fragmented if no multifragment support was announced * handle special server side case where the multifragment size received from the client is smaller than one maximum fast-path PDU size --- libfreerdp/core/capabilities.c | 15 ++++++++++++++- libfreerdp/core/fastpath.c | 1 - libfreerdp/core/fastpath.h | 16 ++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index b4e2fca57..c3725353d 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -22,6 +22,7 @@ #endif #include "capabilities.h" +#include "fastpath.h" #include #include @@ -2287,6 +2288,17 @@ BOOL rdp_read_multifragment_update_capability_set(wStream* s, UINT16 length, rdp if (settings->ServerMode) { + /* + * Special case: The client announces multifragment update support but sets the maximum request size + * to something smaller than maximum size for *one* fast-path PDU. + * In this case behave like no multifragment updates were supported and make sure no + * fragmentation happens by setting FASTPATH_FRAGMENT_SAFE_SIZE. + * + * This behaviour was observed with some windows ce rdp clients. + */ + if (multifragMaxRequestSize < FASTPATH_MAX_PACKET_SIZE) + multifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE; + if (settings->RemoteFxCodec) { /** @@ -3669,7 +3681,8 @@ BOOL rdp_recv_confirm_active(rdpRdp* rdp, wStream* s) if (!settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE]) { - /* client does not support multi fragment updates */ + /* client does not support multi fragment updates - make sure packages are not fragmented */ + settings->MultifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE; } if (!settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER]) diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index c88e5c762..417770cdc 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -48,7 +48,6 @@ * two less significant bits of the first byte. */ -#define FASTPATH_MAX_PACKET_SIZE 0x3FFF #ifdef WITH_DEBUG_RDP static const char* const FASTPATH_UPDATETYPE_STRINGS[] = diff --git a/libfreerdp/core/fastpath.h b/libfreerdp/core/fastpath.h index af570f7b6..7f1c59cab 100644 --- a/libfreerdp/core/fastpath.h +++ b/libfreerdp/core/fastpath.h @@ -20,6 +20,22 @@ #ifndef __FASTPATH_H #define __FASTPATH_H +/* + * Fast-Path has 15 bits available for length information which would lead to a + * maximal pdu size of 0x8000. However in practice only 14 bits are used + * this isn't documented anywhere but it looks like most implementations will + * fail if fast-path packages > 0x3FFF arrive. + */ +#define FASTPATH_MAX_PACKET_SIZE 0x3FFF + +/* + * The following size guarantees that no fast-path PDU fragmentation occurs. + * It was calculated by subtracting 128 from FASTPATH_MAX_PACKET_SIZE. + * 128 was chosen because it includes all required and optional headers as well as + * possible paddings and some extra bytes for safety. + */ +#define FASTPATH_FRAGMENT_SAFE_SIZE 0x3F80 + typedef struct rdp_fastpath rdpFastPath; #include "rdp.h" From 47dd22ba87a0e1807c8f72d6e61c14b1d4ae1c2d Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Tue, 22 Jul 2014 11:19:38 +0200 Subject: [PATCH 13/35] transport refactor rename transport_read to transport_read_pdu. This name is more descriptive what the function actually does. --- libfreerdp/core/nego.c | 2 +- libfreerdp/core/nla.c | 2 +- libfreerdp/core/transport.c | 4 ++-- libfreerdp/core/transport.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index c250b4be9..09d63065a 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -503,7 +503,7 @@ BOOL nego_recv_response(rdpNego* nego) if (!s) return FALSE; - status = transport_read(nego->transport, s); + status = transport_read_pdu(nego->transport, s); if (status < 0) { Stream_Free(s, TRUE); diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index f1573a5a0..22df71edb 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -1198,7 +1198,7 @@ int credssp_recv(rdpCredssp* credssp) s = Stream_New(NULL, 4096); - status = transport_read(credssp->transport, s); + status = transport_read_pdu(credssp->transport, s); Stream_Length(s) = status; if (status < 0) diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 3f214e5ad..476930c8b 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -721,7 +721,7 @@ int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes) return read; } -int transport_read(rdpTransport* transport, wStream* s) +int transport_read_pdu(rdpTransport* transport, wStream* s) { int status; int position; @@ -847,7 +847,7 @@ static int transport_read_nonblocking(rdpTransport* transport) { int status; - status = transport_read(transport, transport->ReceiveBuffer); + status = transport_read_pdu(transport, transport->ReceiveBuffer); if (status <= 0) return status; diff --git a/libfreerdp/core/transport.h b/libfreerdp/core/transport.h index 3a4a41753..142d350f3 100644 --- a/libfreerdp/core/transport.h +++ b/libfreerdp/core/transport.h @@ -96,7 +96,7 @@ BOOL transport_accept_rdp(rdpTransport* transport); BOOL transport_accept_tls(rdpTransport* transport); BOOL transport_accept_nla(rdpTransport* transport); void transport_stop(rdpTransport* transport); -int transport_read(rdpTransport* transport, wStream* s); +int transport_read_pdu(rdpTransport* transport, wStream* s); int transport_write(rdpTransport* transport, wStream* s); void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount); int transport_check_fds(rdpTransport* transport); From bdad9524dc5822be8a09e5fd161c05ef1bb6425e Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Tue, 22 Jul 2014 19:14:43 +0200 Subject: [PATCH 14/35] refactor transport_read_pdu and check_fds transport_check_fds and transport_read_pdu had almost the same functionality: reading and validating one pdu at a time. Now transport_read_pdu reads one pdu from the transport layer and verifies that the pdu data is valid - as before. transport_read_pdu also ensures that the stream is sealed and rewound when the pdu is received completely. transport_check_fds just uses transport_read_pdu and does *not* do the verification a second time based on the stream. Besides the clean up this fixes the following problems: * transport_read always read 4 bytes. Fast-path input synchronize pdus are only 3 bytes long. In this case on byte got lost in the stream buffer which lead to "de-synchronization" of server and client. * Size check in tpdu_read_connection_confirm - already read bytes weren't taken into account. --- libfreerdp/core/nla.c | 1 - libfreerdp/core/tpdu.c | 15 +- libfreerdp/core/transport.c | 297 ++++++++++++------------------------ 3 files changed, 109 insertions(+), 204 deletions(-) diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 22df71edb..5b7a77a18 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -1199,7 +1199,6 @@ int credssp_recv(rdpCredssp* credssp) s = Stream_New(NULL, 4096); status = transport_read_pdu(credssp->transport, s); - Stream_Length(s) = status; if (status < 0) { diff --git a/libfreerdp/core/tpdu.c b/libfreerdp/core/tpdu.c index e9b3ba35b..310c35f52 100644 --- a/libfreerdp/core/tpdu.c +++ b/libfreerdp/core/tpdu.c @@ -157,6 +157,11 @@ void tpdu_write_connection_request(wStream* s, UINT16 length) BOOL tpdu_read_connection_confirm(wStream* s, BYTE* li) { BYTE code; + int position; + int bytes_read = 0; + + /* save the position to determine the number of bytes read */ + position = Stream_GetPosition(s); if (!tpdu_read_header(s, &code, li)) return FALSE; @@ -166,8 +171,16 @@ BOOL tpdu_read_connection_confirm(wStream* s, BYTE* li) fprintf(stderr, "Error: expected X224_TPDU_CONNECTION_CONFIRM\n"); return FALSE; } + /* + * To ensure that there are enough bytes remaining for processing + * check against the length indicator (li). Already read bytes need + * to be taken into account. + * The -1 is because li was read but isn't included in the TPDU size. + * For reference see ITU-T Rec. X.224 - 13.2.1 + */ + bytes_read = (Stream_GetPosition(s) - position) - 1; - return (Stream_GetRemainingLength(s) >= *li); + return (Stream_GetRemainingLength(s) >= (*li - bytes_read)); } /** diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 476930c8b..9ab96288a 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -576,68 +576,6 @@ BOOL transport_accept_nla(rdpTransport* transport) return TRUE; } -BOOL nla_verify_header(wStream* s) -{ - if ((Stream_Pointer(s)[0] == 0x30) && (Stream_Pointer(s)[1] & 0x80)) - return TRUE; - - return FALSE; -} - -UINT32 nla_read_header(wStream* s) -{ - UINT32 length = 0; - - if (Stream_Pointer(s)[1] & 0x80) - { - if ((Stream_Pointer(s)[1] & ~(0x80)) == 1) - { - length = Stream_Pointer(s)[2]; - length += 3; - Stream_Seek(s, 3); - } - else if ((Stream_Pointer(s)[1] & ~(0x80)) == 2) - { - length = (Stream_Pointer(s)[2] << 8) | Stream_Pointer(s)[3]; - length += 4; - Stream_Seek(s, 4); - } - else - { - fprintf(stderr, "Error reading TSRequest!\n"); - } - } - else - { - length = Stream_Pointer(s)[1]; - length += 2; - Stream_Seek(s, 2); - } - - return length; -} - -UINT32 nla_header_length(wStream* s) -{ - UINT32 length = 0; - - if (Stream_Pointer(s)[1] & 0x80) - { - if ((Stream_Pointer(s)[1] & ~(0x80)) == 1) - length = 3; - else if ((Stream_Pointer(s)[1] & ~(0x80)) == 2) - length = 4; - else - fprintf(stderr, "Error reading TSRequest!\n"); - } - else - { - length = 2; - } - - return length; -} - static int transport_wait_for_read(rdpTransport* transport) { rdpTcp *tcpIn = transport->TcpIn; @@ -721,17 +659,53 @@ int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes) return read; } + +/** + * @brief Tries to read toRead bytes from the specified transport + * + * Try to read toRead bytes from the transport to the stream. + * In case it was not possible to read toRead bytes 0 is returned. The stream is always advanced by the + * number of bytes read. + * + * The function assumes that the stream has enought capacity to hold the dat.a + * + * @param[in] transport rdpTransport + * @param[in] s wStream + * @param[in] toRead number of bytes to read + * @return < 0 on error; 0 if not enought data is available (non blocking mode); 1 toRead bytes read + */ +static int transport_read_layer_bytes(rdpTransport* transport, wStream* s, unsigned int toRead) +{ + int status; + status = transport_read_layer(transport, Stream_Pointer(s), toRead); + if (status <= 0) + return status; + + Stream_Seek(s, status); + return status == toRead ? 1 : 0; +} + +/** + * @brief Try to read a complete PDU (NLA, fast-path or tpkt) from the underlaying transport. + * + * If possible a complete PDU is read, in case of non blocking transport this might not succeed. + * Except in case of an error the passed stream will point to the last byte read (correct + * position). When the pdu read is completed the stream is sealed and the pointer set to 0 + * + * @param[in] transport rdpTransport + * @param[in] s wStream + * @return < 0 on error; 0 if not enought data is available (non blocking mode); > 0 number of + * bytes of the *complete* pdu read + */ int transport_read_pdu(rdpTransport* transport, wStream* s) { int status; int position; int pduLength; BYTE *header; - int transport_status; position = 0; pduLength = 0; - transport_status = 0; if (!transport) return -1; @@ -739,44 +713,44 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) if (!s) return -1; - /* first check if we have header */ position = Stream_GetPosition(s); - if (position < 4) + /* Make sure there is enought space for the longest header within the stream */ + Stream_EnsureCapacity(s, 4); + + /* Make sure at least two bytes are read for futher processing */ + if (position < 2 && (status = transport_read_layer_bytes(transport, s, 2 - position)) != 1) { - Stream_EnsureCapacity(s, 4); - status = transport_read_layer(transport, Stream_Buffer(s) + position, 4 - position); - - if (status < 0) - return status; - - transport_status += status; - - if ((status + position) < 4) - return transport_status; - - position += status; + /* No data available at the moment */ + return status; } header = Stream_Buffer(s); - /* if header is present, read exactly one PDU */ - if (transport->NlaMode) { + /* + * In case NlaMode is set we TSRequest package(s) are expected + * 0x30 = DER encoded data with these bits set: + * bit 6 P/C constructed + * bit 5 tag number - sequence + */ if (header[0] == 0x30) { /* TSRequest (NLA) */ - if (header[1] & 0x80) { if ((header[1] & ~(0x80)) == 1) { + if ((status = transport_read_layer_bytes(transport, s, 1)) != 1) + return status; pduLength = header[2]; pduLength += 3; } else if ((header[1] & ~(0x80)) == 2) { + if ((status = transport_read_layer_bytes(transport, s, 2)) != 1) + return status; pduLength = (header[2] << 8) | header[3]; pduLength += 4; } @@ -798,63 +772,67 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) if (header[0] == 0x03) { /* TPKT header */ + if ((status = transport_read_layer_bytes(transport, s, 2)) != 1) + return status; pduLength = (header[2] << 8) | header[3]; + + /* min and max values according to ITU-T Rec. T.123 (01/2007) section 8 */ + if (pduLength < 7 || pduLength > 0xFFFF) + { + fprintf(stderr, "%s: tpkt - invalid pduLength: %d\n", __FUNCTION__, pduLength); + return -1; + } } else { /* Fast-Path Header */ - - if (header[1] & 0x80) + if (header[1] & 0x80) { + if ((status = transport_read_layer_bytes(transport, s, 1)) != 1) + return status; pduLength = ((header[1] & 0x7F) << 8) | header[2]; + } else pduLength = header[1]; + + /* + * fast-path has 7 bits for length so the maximum size, including headers is 0x8000 + * The theoretical minimum fast-path PDU consists only of two header bytes plus one + * byte for data (e.g. fast-path input synchronize pdu) + */ + if (pduLength < 3 || pduLength > 0x8000) + { + fprintf(stderr, "%s: fast path - invalid pduLength: %d\n", __FUNCTION__, pduLength); + return -1; + } } } - if (pduLength < 0 || pduLength > 0xFFFF) - { - fprintf(stderr, "%s: invalid pduLength: %d\n", __FUNCTION__, pduLength); - return -1; - } - Stream_EnsureCapacity(s, pduLength); - status = transport_read_layer(transport, Stream_Buffer(s) + position, pduLength - position); + Stream_EnsureCapacity(s, Stream_GetPosition(s) + pduLength); - if (status < 0) + status = transport_read_layer_bytes(transport, s, pduLength - Stream_GetPosition(s)); + + if (status != 1) return status; - transport_status += status; - #ifdef WITH_DEBUG_TRANSPORT /* dump when whole PDU is read */ - if (position + status >= pduLength) + if (Stream_GetPosition >= pduLength) { fprintf(stderr, "Local < Remote\n"); winpr_HexDump(Stream_Buffer(s), pduLength); } #endif - if (position + status >= pduLength) + if (Stream_GetPosition(s) >= pduLength) { WLog_Packet(transport->log, WLOG_TRACE, Stream_Buffer(s), pduLength, WLOG_PACKET_INBOUND); } - return transport_status; -} - -static int transport_read_nonblocking(rdpTransport* transport) -{ - int status; - - status = transport_read_pdu(transport, transport->ReceiveBuffer); - - if (status <= 0) - return status; - - Stream_Seek(transport->ReceiveBuffer, status); - - return status; + Stream_SealLength(s); + Stream_SetPosition(s, 0); + return Stream_Length(s); } BOOL transport_bio_buffered_drain(BIO *bio); @@ -1048,9 +1026,7 @@ int tranport_drain_output_buffer(rdpTransport* transport) int transport_check_fds(rdpTransport* transport) { - int pos; int status; - int length; int recv_status; wStream* received; @@ -1072,105 +1048,22 @@ int transport_check_fds(rdpTransport* transport) for (;;) { /** - * Note: transport_read_nonblocking() reads max 1 additional PDU from - * the layer. Also note that transport_read_nonblocking() is also called - * outside of this function in transport_write()! This means that when - * entering transport_check_fds it is possible that the stream position - * of transport->ReceiveBuffer position is > 0. We must process this data - * even if transport_read_nonblocking() returns 0. + * Note: transport_read_pdu tries to read one PDU from + * the transport layer. + * The ReceiveBuffer mit have a position > 0 in case of a non blocking + * transport. If transport_read_pdu returns 0 the pdu couldn't be read at + * this point. * Note that transport->ReceiveBuffer is replaced after each iteration * of this loop with a fresh stream instance from a pool. */ - if ((status = transport_read_nonblocking(transport)) < 0) + if ((status = transport_read_pdu(transport, transport->ReceiveBuffer)) <= 0) + { return status; - - if ((pos = Stream_GetPosition(transport->ReceiveBuffer)) < 2) - return 0; - - Stream_SetPosition(transport->ReceiveBuffer, 0); - length = 0; - - if (transport->NlaMode) - { - if (nla_verify_header(transport->ReceiveBuffer)) - { - /* TSRequest */ - - /* Ensure the TSRequest header is available. */ - if (pos <= 4) - { - Stream_SetPosition(transport->ReceiveBuffer, pos); - return 0; - } - - /* TSRequest header can be 2, 3 or 4 bytes long */ - length = nla_header_length(transport->ReceiveBuffer); - - if (pos < length) - { - Stream_SetPosition(transport->ReceiveBuffer, pos); - return 0; - } - - length = nla_read_header(transport->ReceiveBuffer); - } - } - else - { - if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */ - { - /* Ensure the TPKT header is available. */ - if (pos <= 4) - { - Stream_SetPosition(transport->ReceiveBuffer, pos); - return 0; - } - - length = tpkt_read_header(transport->ReceiveBuffer); - } - else /* Fast Path */ - { - /* Ensure the Fast Path header is available. */ - if (pos <= 2) - { - Stream_SetPosition(transport->ReceiveBuffer, pos); - return 0; - } - - /* Fastpath header can be two or three bytes long. */ - length = fastpath_header_length(transport->ReceiveBuffer); - - if (pos < length) - { - Stream_SetPosition(transport->ReceiveBuffer, pos); - return 0; - } - - length = fastpath_read_header(NULL, transport->ReceiveBuffer); - } - } - - if (length == 0) - { - fprintf(stderr, "transport_check_fds: protocol error, not a TPKT or Fast Path header.\n"); - winpr_HexDump(Stream_Buffer(transport->ReceiveBuffer), pos); - return -1; - } - - if (pos < length) - { - Stream_SetPosition(transport->ReceiveBuffer, pos); - return 0; /* Packet is not yet completely received. */ } received = transport->ReceiveBuffer; transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0); - - Stream_SetPosition(received, length); - Stream_SealLength(received); - Stream_SetPosition(received, 0); - /** * status: * -1: error From fae8f6fbf2dabef83091f82df0134c26182bdd1b Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Thu, 24 Jul 2014 21:07:44 +0200 Subject: [PATCH 15/35] winpr/sync: Added InitOnceExecuteOnce plus CTest --- winpr/include/winpr/interlocked.h | 2 + winpr/include/winpr/synch.h | 42 ++++--- winpr/libwinpr/interlocked/interlocked.c | 11 +- winpr/libwinpr/synch/init.c | 59 +++++++-- winpr/libwinpr/synch/test/CMakeLists.txt | 1 + winpr/libwinpr/synch/test/TestSynchInit.c | 146 ++++++++++++++++++++++ 6 files changed, 236 insertions(+), 25 deletions(-) create mode 100644 winpr/libwinpr/synch/test/TestSynchInit.c diff --git a/winpr/include/winpr/interlocked.h b/winpr/include/winpr/interlocked.h index 8e27f83cc..83c462568 100644 --- a/winpr/include/winpr/interlocked.h +++ b/winpr/include/winpr/interlocked.h @@ -154,6 +154,8 @@ WINPR_API LONG InterlockedExchangeAdd(LONG volatile *Addend, LONG Value); WINPR_API LONG InterlockedCompareExchange(LONG volatile *Destination, LONG Exchange, LONG Comperand); +WINPR_API PVOID InterlockedCompareExchangePointer(PVOID volatile *Destination, PVOID Exchange, PVOID Comperand); + #endif /* _WIN32 */ #if (!defined(_WIN32) || (defined(_WIN32) && (_WIN32_WINNT < 0x0502))) diff --git a/winpr/include/winpr/synch.h b/winpr/include/winpr/synch.h index 75213a8fe..fce97e9a5 100644 --- a/winpr/include/winpr/synch.h +++ b/winpr/include/winpr/synch.h @@ -3,6 +3,8 @@ * Synchronization Functions * * Copyright 2012 Marc-Andre Moreau + * Copyright 2014 Thincast Technologies GmbH + * Copyright 2014 Norbert Federa * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -102,22 +104,6 @@ WINPR_API BOOL ResetEvent(HANDLE hEvent); #define OpenEvent OpenEventA #endif -/* One-Time Initialization */ - -typedef union _RTL_RUN_ONCE -{ - PVOID Ptr; -} RTL_RUN_ONCE, *PRTL_RUN_ONCE; - -typedef PRTL_RUN_ONCE PINIT_ONCE; -typedef PRTL_RUN_ONCE LPINIT_ONCE; -typedef BOOL CALLBACK (*PINIT_ONCE_FN) (PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context); - -WINPR_API BOOL InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL fPending, LPVOID* lpContext); -WINPR_API BOOL InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpContext); -WINPR_API BOOL InitOnceExecuteOnce(PINIT_ONCE InitOnce, PINIT_ONCE_FN InitFn, PVOID Parameter, LPVOID* Context); -WINPR_API VOID InitOnceInitialize(PINIT_ONCE InitOnce); - /* Slim Reader/Writer (SRW) Lock */ typedef PVOID RTL_SRWLOCK; @@ -303,6 +289,30 @@ WINPR_API BOOL InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, #endif +#if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0600)) + +/* One-Time Initialization */ + +typedef struct _RTL_RUN_ONCE +{ + PVOID Ptr; +} RTL_RUN_ONCE, *PRTL_RUN_ONCE; + +#define RTL_RUN_ONCE_INIT { 0 } +#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT + +typedef RTL_RUN_ONCE INIT_ONCE; +typedef PRTL_RUN_ONCE PINIT_ONCE; +typedef PRTL_RUN_ONCE LPINIT_ONCE; +typedef BOOL CALLBACK (*PINIT_ONCE_FN) (PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context); + +WINPR_API BOOL InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL fPending, LPVOID* lpContext); +WINPR_API BOOL InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpContext); +WINPR_API BOOL InitOnceExecuteOnce(PINIT_ONCE InitOnce, PINIT_ONCE_FN InitFn, PVOID Parameter, LPVOID* Context); +WINPR_API VOID InitOnceInitialize(PINIT_ONCE InitOnce); + +#endif + /* Extended API */ WINPR_API VOID USleep(DWORD dwMicroseconds); diff --git a/winpr/libwinpr/interlocked/interlocked.c b/winpr/libwinpr/interlocked/interlocked.c index 13b597f8b..0b8c0d45a 100644 --- a/winpr/libwinpr/interlocked/interlocked.c +++ b/winpr/libwinpr/interlocked/interlocked.c @@ -234,6 +234,15 @@ LONG InterlockedCompareExchange(LONG volatile *Destination, LONG Exchange, LONG #endif } +PVOID InterlockedCompareExchangePointer(PVOID volatile *Destination, PVOID Exchange, PVOID Comperand) +{ +#ifdef __GNUC__ + return __sync_val_compare_and_swap(Destination, Comperand, Exchange); +#else + return 0; +#endif +} + #endif /* _WIN32 */ #if defined(_WIN32) && !defined(WINPR_INTERLOCKED_COMPARE_EXCHANGE64) @@ -249,7 +258,7 @@ int static_mutex_lock(volatile HANDLE* static_mutex) if (*static_mutex == NULL) { HANDLE handle = CreateMutex(NULL, FALSE, NULL); - + if (InterlockedCompareExchangePointer((PVOID*) static_mutex, (PVOID) handle, NULL) != NULL) CloseHandle(handle); } diff --git a/winpr/libwinpr/synch/init.c b/winpr/libwinpr/synch/init.c index 88d32c27c..89c6427aa 100644 --- a/winpr/libwinpr/synch/init.c +++ b/winpr/libwinpr/synch/init.c @@ -3,6 +3,8 @@ * Synchronization Functions * * Copyright 2012 Marc-Andre Moreau + * Copyright 2014 Thincast Technologies GmbH + * Copyright 2014 Norbert Federa * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,27 +24,68 @@ #endif #include +#include -#ifndef _WIN32 +#if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0600)) BOOL InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL fPending, LPVOID* lpContext) { - return TRUE; + fprintf(stderr, "%s: not implemented\n", __FUNCTION__); + return FALSE; } BOOL InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpContext) { - return TRUE; -} - -BOOL InitOnceExecuteOnce(PINIT_ONCE InitOnce, PINIT_ONCE_FN InitFn, PVOID Parameter, LPVOID* Context) -{ - return TRUE; + fprintf(stderr, "%s: not implemented\n", __FUNCTION__); + return FALSE; } VOID InitOnceInitialize(PINIT_ONCE InitOnce) { + fprintf(stderr, "%s: not implemented\n", __FUNCTION__); +} +BOOL InitOnceExecuteOnce(PINIT_ONCE InitOnce, PINIT_ONCE_FN InitFn, PVOID Parameter, LPVOID* Context) +{ + for (;;) + { + switch((ULONG_PTR)InitOnce->Ptr & 3) + { + case 2: + /* already completed successfully */ + return TRUE; + + case 0: + /* first time */ + if (InterlockedCompareExchangePointer(&InitOnce->Ptr, (PVOID)1, (PVOID)0) != (PVOID)0) + { + /* some other thread was faster */ + break; + } + + /* it's our job to call the init function */ + if (InitFn(InitOnce, Parameter, Context)) + { + /* success */ + InitOnce->Ptr = (PVOID)2; + return TRUE; + } + + /* the init function returned an error, reset the status */ + InitOnce->Ptr = (PVOID)0; + return FALSE; + + case 1: + /* in progress */ + break; + + default: + fprintf(stderr, "%s: internal error\n", __FUNCTION__); + return FALSE; + } + + Sleep(5); + } } #endif diff --git a/winpr/libwinpr/synch/test/CMakeLists.txt b/winpr/libwinpr/synch/test/CMakeLists.txt index 34d7d3a68..0309fb910 100644 --- a/winpr/libwinpr/synch/test/CMakeLists.txt +++ b/winpr/libwinpr/synch/test/CMakeLists.txt @@ -5,6 +5,7 @@ set(MODULE_PREFIX "TEST_SYNCH") set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) set(${MODULE_PREFIX}_TESTS + TestSynchInit.c TestSynchEvent.c TestSynchMutex.c TestSynchCritical.c diff --git a/winpr/libwinpr/synch/test/TestSynchInit.c b/winpr/libwinpr/synch/test/TestSynchInit.c new file mode 100644 index 000000000..efcd9c3af --- /dev/null +++ b/winpr/libwinpr/synch/test/TestSynchInit.c @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include + +#define TEST_NUM_THREADS 100 +#define TEST_NUM_FAILURES 10 + +INIT_ONCE initOnceTest = INIT_ONCE_STATIC_INIT; + +HANDLE hStartEvent = NULL; +LONG *pErrors = NULL; +LONG *pTestThreadFunctionCalls = NULL; +LONG *pTestOnceFunctionCalls = NULL; +LONG *pInitOnceExecuteOnceCalls = NULL; + + +BOOL CALLBACK TestOnceFunction(PINIT_ONCE once, PVOID param, PVOID *context) +{ + LONG calls = InterlockedIncrement(pTestOnceFunctionCalls) - 1; + + /* simulate execution time */ + Sleep(100 + rand() % 400); + + if (calls < TEST_NUM_FAILURES) + { + /* simulated error */ + return FALSE; + } + if (calls == TEST_NUM_FAILURES) + { + return TRUE; + } + fprintf(stderr, "%s: error: called again after success\n", __FUNCTION__); + InterlockedIncrement(pErrors); + return FALSE; +} + +DWORD WINAPI TestThreadFunction(LPVOID lpParam) +{ + LONG calls; + BOOL ok; + InterlockedIncrement(pTestThreadFunctionCalls); + if (WaitForSingleObject(hStartEvent, INFINITE) != WAIT_OBJECT_0) + { + fprintf(stderr, "%s: error: failed to wait for start event\n", __FUNCTION__); + InterlockedIncrement(pErrors); + return 0; + } + + ok = InitOnceExecuteOnce(&initOnceTest, TestOnceFunction, NULL, NULL); + calls = InterlockedIncrement(pInitOnceExecuteOnceCalls); + if (!ok && calls > TEST_NUM_FAILURES) + { + fprintf(stderr, "%s: InitOnceExecuteOnce failed unexpectedly\n", __FUNCTION__); + InterlockedIncrement(pErrors); + } + return 0; +} + +int TestSynchInit(int argc, char* argv[]) +{ + HANDLE hThreads[TEST_NUM_THREADS]; + DWORD dwCreatedThreads = 0; + DWORD i; + BOOL result = FALSE; + + pErrors = _aligned_malloc(sizeof(LONG), sizeof(LONG)); + pTestThreadFunctionCalls = _aligned_malloc(sizeof(LONG), sizeof(LONG)); + pTestOnceFunctionCalls = _aligned_malloc(sizeof(LONG), sizeof(LONG)); + pInitOnceExecuteOnceCalls = _aligned_malloc(sizeof(LONG), sizeof(LONG)); + + if (!pErrors || !pTestThreadFunctionCalls || !pTestOnceFunctionCalls || !pInitOnceExecuteOnceCalls) + { + fprintf(stderr, "error: _aligned_malloc failed\n"); + goto out; + } + + *pErrors = 0; + *pTestThreadFunctionCalls = 0; + *pTestOnceFunctionCalls = 0; + *pInitOnceExecuteOnceCalls = 0; + + if (!(hStartEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + fprintf(stderr, "error creating start event\n"); + InterlockedIncrement(pErrors); + goto out; + } + + for (i = 0; i < TEST_NUM_THREADS; i++) + { + if (!(hThreads[i] = CreateThread(NULL, 0, TestThreadFunction, NULL, 0, NULL))) + { + fprintf(stderr, "error creating thread #%d\n", i); + InterlockedIncrement(pErrors); + goto out; + } + dwCreatedThreads++; + } + + Sleep(100); + SetEvent(hStartEvent); + + for (i = 0; i < dwCreatedThreads; i++) + { + if (WaitForSingleObject(hThreads[i], INFINITE) != WAIT_OBJECT_0) + { + fprintf(stderr, "error: error waiting for thread #%d\n", i); + InterlockedIncrement(pErrors); + goto out; + } + } + + if (*pErrors == 0 && + *pTestThreadFunctionCalls == TEST_NUM_THREADS && + *pInitOnceExecuteOnceCalls == TEST_NUM_THREADS && + *pTestOnceFunctionCalls == TEST_NUM_FAILURES + 1) + { + result = TRUE; + } + +out: + fprintf(stderr, "Test result: %s\n", result ? "OK" : "ERROR"); + fprintf(stderr, "Error count: %d\n", pErrors ? *pErrors : -1); + fprintf(stderr, "Threads created: %u\n", dwCreatedThreads); + fprintf(stderr, "TestThreadFunctionCalls: %d\n", pTestThreadFunctionCalls ? *pTestThreadFunctionCalls : -1); + fprintf(stderr, "InitOnceExecuteOnceCalls: %d\n", pInitOnceExecuteOnceCalls ? *pInitOnceExecuteOnceCalls : -1); + fprintf(stderr, "TestOnceFunctionCalls: %d\n", pTestOnceFunctionCalls ? *pTestOnceFunctionCalls : -1); + + _aligned_free(pErrors); + _aligned_free(pTestThreadFunctionCalls); + _aligned_free(pTestOnceFunctionCalls); + _aligned_free(pInitOnceExecuteOnceCalls); + + CloseHandle(hStartEvent); + + + for (i = 0; i < dwCreatedThreads; i++) + { + CloseHandle(hThreads[i]); + } + + return (result ? 0 : 1); +} From 2e859a5d142e33bb29928c229a8c37f1f8f4ad4e Mon Sep 17 00:00:00 2001 From: Justin DeFields Date: Thu, 24 Jul 2014 16:07:14 -0400 Subject: [PATCH 16/35] Removed GatewayUseSameCredentials logic from cmdline.c, and placed it after both cmdline and rpd file have been parsed. This provides proper GatewayUseSameCredentials support for the rdp file --- client/common/client.c | 26 ++++++++++++++++++++++++++ client/common/cmdline.c | 15 --------------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/client/common/client.c b/client/common/client.c index c3fea6fb2..532d0ddb3 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -123,10 +123,36 @@ int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc, { status = freerdp_client_settings_parse_assistance_file(settings, settings->AssistanceFile); } + + /* This function will call logic that is applicable to the settings + * from command line parsing AND the rdp file parsing */ + status = freerdp_client_combined_logic(settings); return status; } +int freerdp_client_combined_logic(rdpSettings* settings) +{ + /* Moved GatewayUseSameCredentials logic outside of cmdline.c, so + * that the rdp file also triggers this functionality */ + if (settings->GatewayEnabled) + { + if (settings->GatewayUseSameCredentials) + { + if (settings->Username) + settings->GatewayUsername = _strdup(settings->Username); + + if (settings->Domain) + settings->GatewayDomain = _strdup(settings->Domain); + + if (settings->Password) + settings->GatewayPassword = _strdup(settings->Password); + } + } + + return 0; +} + int freerdp_client_settings_parse_connection_file(rdpSettings* settings, const char* filename) { rdpFile* file; diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 44c153779..bd8e909f9 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1905,21 +1905,6 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, freerdp_performance_flags_make(settings); - if (settings->GatewayEnabled) - { - if (settings->GatewayUseSameCredentials) - { - if (settings->Username) - settings->GatewayUsername = _strdup(settings->Username); - - if (settings->Domain) - settings->GatewayDomain = _strdup(settings->Domain); - - if (settings->Password) - settings->GatewayPassword = _strdup(settings->Password); - } - } - if (settings->SupportGraphicsPipeline) { settings->FastPathOutput = TRUE; From 2036b443ebdbfa76686e2ebcefdd98af74a03a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 26 Jul 2014 15:23:39 -0400 Subject: [PATCH 17/35] libwinpr-wtsapi: fix WtsApi32.dll dynamic loading on Windows --- client/common/client.c | 44 ++++----- winpr/libwinpr/wtsapi/wtsapi.c | 161 ++++++++++++++++++++++++++++++++- 2 files changed, 182 insertions(+), 23 deletions(-) diff --git a/client/common/client.c b/client/common/client.c index 532d0ddb3..68d051d52 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -102,6 +102,28 @@ HANDLE freerdp_client_get_thread(rdpContext* context) return ((rdpClientContext*) context)->thread; } +int freerdp_client_combined_logic(rdpSettings* settings) +{ + /* Moved GatewayUseSameCredentials logic outside of cmdline.c, so + * that the rdp file also triggers this functionality */ + if (settings->GatewayEnabled) + { + if (settings->GatewayUseSameCredentials) + { + if (settings->Username) + settings->GatewayUsername = _strdup(settings->Username); + + if (settings->Domain) + settings->GatewayDomain = _strdup(settings->Domain); + + if (settings->Password) + settings->GatewayPassword = _strdup(settings->Password); + } + } + + return 0; +} + int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc, char** argv) { int status; @@ -131,28 +153,6 @@ int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc, return status; } -int freerdp_client_combined_logic(rdpSettings* settings) -{ - /* Moved GatewayUseSameCredentials logic outside of cmdline.c, so - * that the rdp file also triggers this functionality */ - if (settings->GatewayEnabled) - { - if (settings->GatewayUseSameCredentials) - { - if (settings->Username) - settings->GatewayUsername = _strdup(settings->Username); - - if (settings->Domain) - settings->GatewayDomain = _strdup(settings->Domain); - - if (settings->Password) - settings->GatewayPassword = _strdup(settings->Password); - } - } - - return 0; -} - int freerdp_client_settings_parse_connection_file(rdpSettings* settings, const char* filename) { rdpFile* file; diff --git a/winpr/libwinpr/wtsapi/wtsapi.c b/winpr/libwinpr/wtsapi/wtsapi.c index 02cf985cb..4fdb1f75b 100644 --- a/winpr/libwinpr/wtsapi/wtsapi.c +++ b/winpr/libwinpr/wtsapi/wtsapi.c @@ -44,6 +44,159 @@ static HMODULE g_WtsApiModule = NULL; static PWtsApiFunctionTable g_WtsApi = NULL; +static HMODULE g_WtsApi32Module = NULL; + +static WtsApiFunctionTable WtsApi32_WtsApiFunctionTable = +{ + 0, /* dwVersion */ + 0, /* dwFlags */ + + NULL, /* StopRemoteControlSession */ + NULL, /* StartRemoteControlSessionW */ + NULL, /* StartRemoteControlSessionA */ + NULL, /* ConnectSessionW */ + NULL, /* ConnectSessionA */ + NULL, /* EnumerateServersW */ + NULL, /* EnumerateServersA */ + NULL, /* OpenServerW */ + NULL, /* OpenServerA */ + NULL, /* OpenServerExW */ + NULL, /* OpenServerExA */ + NULL, /* CloseServer */ + NULL, /* EnumerateSessionsW */ + NULL, /* EnumerateSessionsA */ + NULL, /* EnumerateSessionsExW */ + NULL, /* EnumerateSessionsExA */ + NULL, /* EnumerateProcessesW */ + NULL, /* EnumerateProcessesA */ + NULL, /* TerminateProcess */ + NULL, /* QuerySessionInformationW */ + NULL, /* QuerySessionInformationA */ + NULL, /* QueryUserConfigW */ + NULL, /* QueryUserConfigA */ + NULL, /* SetUserConfigW */ + NULL, /* SetUserConfigA */ + NULL, /* SendMessageW */ + NULL, /* SendMessageA */ + NULL, /* DisconnectSession */ + NULL, /* LogoffSession */ + NULL, /* ShutdownSystem */ + NULL, /* WaitSystemEvent */ + NULL, /* VirtualChannelOpen */ + NULL, /* VirtualChannelOpenEx */ + NULL, /* VirtualChannelClose */ + NULL, /* VirtualChannelRead */ + NULL, /* VirtualChannelWrite */ + NULL, /* VirtualChannelPurgeInput */ + NULL, /* VirtualChannelPurgeOutput */ + NULL, /* VirtualChannelQuery */ + NULL, /* FreeMemory */ + NULL, /* RegisterSessionNotification */ + NULL, /* UnRegisterSessionNotification */ + NULL, /* RegisterSessionNotificationEx */ + NULL, /* UnRegisterSessionNotificationEx */ + NULL, /* QueryUserToken */ + NULL, /* FreeMemoryExW */ + NULL, /* FreeMemoryExA */ + NULL, /* EnumerateProcessesExW */ + NULL, /* EnumerateProcessesExA */ + NULL, /* EnumerateListenersW */ + NULL, /* EnumerateListenersA */ + NULL, /* QueryListenerConfigW */ + NULL, /* QueryListenerConfigA */ + NULL, /* CreateListenerW */ + NULL, /* CreateListenerA */ + NULL, /* SetListenerSecurityW */ + NULL, /* SetListenerSecurityA */ + NULL, /* GetListenerSecurityW */ + NULL, /* GetListenerSecurityA */ + NULL, /* EnableChildSessions */ + NULL, /* IsChildSessionsEnabled */ + NULL, /* GetChildSessionId */ + NULL /* GetActiveConsoleSessionId */ +}; + +#define WTSAPI32_LOAD_PROC(_name, _type) \ + WtsApi32_WtsApiFunctionTable.p ## _name = (## _type) GetProcAddress(g_WtsApi32Module, "WTS" #_name); + +int WtsApi32_InitializeWtsApi(void) +{ + g_WtsApi32Module = LoadLibraryA("wtsapi32.dll"); + + if (!g_WtsApi32Module) + return -1; + + WTSAPI32_LOAD_PROC(StopRemoteControlSession, WTS_STOP_REMOTE_CONTROL_SESSION_FN); + WTSAPI32_LOAD_PROC(StartRemoteControlSessionW, WTS_START_REMOTE_CONTROL_SESSION_FN_W); + WTSAPI32_LOAD_PROC(StartRemoteControlSessionA, WTS_START_REMOTE_CONTROL_SESSION_FN_A); + WTSAPI32_LOAD_PROC(ConnectSessionW, WTS_CONNECT_SESSION_FN_W); + WTSAPI32_LOAD_PROC(ConnectSessionA, WTS_CONNECT_SESSION_FN_A); + WTSAPI32_LOAD_PROC(EnumerateServersW, WTS_ENUMERATE_SERVERS_FN_W); + WTSAPI32_LOAD_PROC(EnumerateServersA, WTS_ENUMERATE_SERVERS_FN_A); + WTSAPI32_LOAD_PROC(OpenServerW, WTS_OPEN_SERVER_FN_W); + WTSAPI32_LOAD_PROC(OpenServerA, WTS_OPEN_SERVER_FN_A); + WTSAPI32_LOAD_PROC(OpenServerExW, WTS_OPEN_SERVER_EX_FN_W); + WTSAPI32_LOAD_PROC(OpenServerExA, WTS_OPEN_SERVER_EX_FN_A); + WTSAPI32_LOAD_PROC(CloseServer, WTS_CLOSE_SERVER_FN); + WTSAPI32_LOAD_PROC(EnumerateSessionsW, WTS_ENUMERATE_SESSIONS_FN_W); + WTSAPI32_LOAD_PROC(EnumerateSessionsA, WTS_ENUMERATE_SESSIONS_FN_A); + WTSAPI32_LOAD_PROC(EnumerateSessionsExW, WTS_ENUMERATE_SESSIONS_EX_FN_W); + WTSAPI32_LOAD_PROC(EnumerateSessionsExA, WTS_ENUMERATE_SESSIONS_EX_FN_A); + WTSAPI32_LOAD_PROC(EnumerateProcessesW, WTS_ENUMERATE_PROCESSES_FN_W); + WTSAPI32_LOAD_PROC(EnumerateProcessesA, WTS_ENUMERATE_PROCESSES_FN_A); + WTSAPI32_LOAD_PROC(TerminateProcess, WTS_TERMINATE_PROCESS_FN); + WTSAPI32_LOAD_PROC(QuerySessionInformationW, WTS_QUERY_SESSION_INFORMATION_FN_W); + WTSAPI32_LOAD_PROC(QuerySessionInformationA, WTS_QUERY_SESSION_INFORMATION_FN_A); + WTSAPI32_LOAD_PROC(QueryUserConfigW, WTS_QUERY_USER_CONFIG_FN_W); + WTSAPI32_LOAD_PROC(QueryUserConfigA, WTS_QUERY_USER_CONFIG_FN_A); + WTSAPI32_LOAD_PROC(SetUserConfigW, WTS_SET_USER_CONFIG_FN_W); + WTSAPI32_LOAD_PROC(SetUserConfigA, WTS_SET_USER_CONFIG_FN_A); + WTSAPI32_LOAD_PROC(SendMessageW, WTS_SEND_MESSAGE_FN_W); + WTSAPI32_LOAD_PROC(SendMessageA, WTS_SEND_MESSAGE_FN_A); + WTSAPI32_LOAD_PROC(DisconnectSession, WTS_DISCONNECT_SESSION_FN); + WTSAPI32_LOAD_PROC(LogoffSession, WTS_LOGOFF_SESSION_FN); + WTSAPI32_LOAD_PROC(ShutdownSystem, WTS_SHUTDOWN_SYSTEM_FN); + WTSAPI32_LOAD_PROC(WaitSystemEvent, WTS_WAIT_SYSTEM_EVENT_FN); + WTSAPI32_LOAD_PROC(VirtualChannelOpen, WTS_VIRTUAL_CHANNEL_OPEN_FN); + WTSAPI32_LOAD_PROC(VirtualChannelOpenEx, WTS_VIRTUAL_CHANNEL_OPEN_EX_FN); + WTSAPI32_LOAD_PROC(VirtualChannelClose, WTS_VIRTUAL_CHANNEL_CLOSE_FN); + WTSAPI32_LOAD_PROC(VirtualChannelRead, WTS_VIRTUAL_CHANNEL_READ_FN); + WTSAPI32_LOAD_PROC(VirtualChannelWrite, WTS_VIRTUAL_CHANNEL_WRITE_FN); + WTSAPI32_LOAD_PROC(VirtualChannelPurgeInput, WTS_VIRTUAL_CHANNEL_PURGE_INPUT_FN); + WTSAPI32_LOAD_PROC(VirtualChannelPurgeOutput, WTS_VIRTUAL_CHANNEL_PURGE_OUTPUT_FN); + WTSAPI32_LOAD_PROC(VirtualChannelQuery, WTS_VIRTUAL_CHANNEL_QUERY_FN); + WTSAPI32_LOAD_PROC(FreeMemory, WTS_FREE_MEMORY_FN); + WTSAPI32_LOAD_PROC(RegisterSessionNotification, WTS_REGISTER_SESSION_NOTIFICATION_FN); + WTSAPI32_LOAD_PROC(UnRegisterSessionNotification, WTS_UNREGISTER_SESSION_NOTIFICATION_FN); + WTSAPI32_LOAD_PROC(RegisterSessionNotificationEx, WTS_REGISTER_SESSION_NOTIFICATION_EX_FN); + WTSAPI32_LOAD_PROC(UnRegisterSessionNotificationEx, WTS_UNREGISTER_SESSION_NOTIFICATION_EX_FN); + WTSAPI32_LOAD_PROC(QueryUserToken, WTS_QUERY_USER_TOKEN_FN); + WTSAPI32_LOAD_PROC(FreeMemoryExW, WTS_FREE_MEMORY_EX_FN_W); + WTSAPI32_LOAD_PROC(FreeMemoryExA, WTS_FREE_MEMORY_EX_FN_A); + WTSAPI32_LOAD_PROC(EnumerateProcessesExW, WTS_ENUMERATE_PROCESSES_EX_FN_W); + WTSAPI32_LOAD_PROC(EnumerateProcessesExA, WTS_ENUMERATE_PROCESSES_EX_FN_A); + WTSAPI32_LOAD_PROC(EnumerateListenersW, WTS_ENUMERATE_LISTENERS_FN_W); + WTSAPI32_LOAD_PROC(EnumerateListenersA, WTS_ENUMERATE_LISTENERS_FN_A); + WTSAPI32_LOAD_PROC(QueryListenerConfigW, WTS_QUERY_LISTENER_CONFIG_FN_W); + WTSAPI32_LOAD_PROC(QueryListenerConfigA, WTS_QUERY_LISTENER_CONFIG_FN_A); + WTSAPI32_LOAD_PROC(CreateListenerW, WTS_CREATE_LISTENER_FN_W); + WTSAPI32_LOAD_PROC(CreateListenerA, WTS_CREATE_LISTENER_FN_A); + WTSAPI32_LOAD_PROC(SetListenerSecurityW, WTS_SET_LISTENER_SECURITY_FN_W); + WTSAPI32_LOAD_PROC(SetListenerSecurityA, WTS_SET_LISTENER_SECURITY_FN_A); + WTSAPI32_LOAD_PROC(GetListenerSecurityW, WTS_GET_LISTENER_SECURITY_FN_W); + WTSAPI32_LOAD_PROC(GetListenerSecurityA, WTS_GET_LISTENER_SECURITY_FN_A); + WTSAPI32_LOAD_PROC(EnableChildSessions, WTS_ENABLE_CHILD_SESSIONS_FN); + WTSAPI32_LOAD_PROC(IsChildSessionsEnabled, WTS_IS_CHILD_SESSIONS_ENABLED_FN); + WTSAPI32_LOAD_PROC(GetChildSessionId, WTS_GET_CHILD_SESSION_ID_FN); + WTSAPI32_LOAD_PROC(GetActiveConsoleSessionId, WTS_GET_ACTIVE_CONSOLE_SESSION_ID_FN); + + g_WtsApi = &WtsApi32_WtsApiFunctionTable; + + return 1; +} + +/* WtsApi Functions */ + BOOL WINAPI WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers) { WTSAPI_STUB_CALL_BOOL(StartRemoteControlSessionW, pTargetServerName, TargetLogonId, HotkeyVk, HotkeyModifiers); @@ -432,11 +585,13 @@ void InitializeWtsApiStubs_Env() env = (LPSTR) malloc(nSize); nSize = GetEnvironmentVariableA("WTSAPI_LIBRARY", env, nSize); + if (env) LoadAndInitialize(env); } #define FREERDS_LIBRARY_NAME "libfreerds-fdsapi.so" + void InitializeWtsApiStubs_FreeRDS() { char* prefix; @@ -489,7 +644,11 @@ void InitializeWtsApiStubs(void) g_Initialized = TRUE; InitializeWtsApiStubs_Env(); - + +#ifdef _WIN32 + WtsApi32_InitializeWtsApi(); +#endif + if (!g_WtsApi) InitializeWtsApiStubs_FreeRDS(); From b17045ddd851b19d893d6a1ab79a5ec3b1d106a2 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 28 Jul 2014 13:12:01 +0200 Subject: [PATCH 18/35] fix: typos and formating --- libfreerdp/core/transport.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 9ab96288a..bacf194d5 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -667,12 +667,12 @@ int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes) * In case it was not possible to read toRead bytes 0 is returned. The stream is always advanced by the * number of bytes read. * - * The function assumes that the stream has enought capacity to hold the dat.a + * The function assumes that the stream has enough capacity to hold the data. * * @param[in] transport rdpTransport * @param[in] s wStream * @param[in] toRead number of bytes to read - * @return < 0 on error; 0 if not enought data is available (non blocking mode); 1 toRead bytes read + * @return < 0 on error; 0 if not enough data is available (non blocking mode); 1 toRead bytes read */ static int transport_read_layer_bytes(rdpTransport* transport, wStream* s, unsigned int toRead) { @@ -686,7 +686,7 @@ static int transport_read_layer_bytes(rdpTransport* transport, wStream* s, unsig } /** - * @brief Try to read a complete PDU (NLA, fast-path or tpkt) from the underlaying transport. + * @brief Try to read a complete PDU (NLA, fast-path or tpkt) from the underlying transport. * * If possible a complete PDU is read, in case of non blocking transport this might not succeed. * Except in case of an error the passed stream will point to the last byte read (correct @@ -694,7 +694,7 @@ static int transport_read_layer_bytes(rdpTransport* transport, wStream* s, unsig * * @param[in] transport rdpTransport * @param[in] s wStream - * @return < 0 on error; 0 if not enought data is available (non blocking mode); > 0 number of + * @return < 0 on error; 0 if not enough data is available (non blocking mode); > 0 number of * bytes of the *complete* pdu read */ int transport_read_pdu(rdpTransport* transport, wStream* s) @@ -715,7 +715,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) position = Stream_GetPosition(s); - /* Make sure there is enought space for the longest header within the stream */ + /* Make sure there is enough space for the longest header within the stream */ Stream_EnsureCapacity(s, 4); /* Make sure at least two bytes are read for futher processing */ @@ -730,7 +730,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) if (transport->NlaMode) { /* - * In case NlaMode is set we TSRequest package(s) are expected + * In case NlaMode is set TSRequest package(s) are expected * 0x30 = DER encoded data with these bits set: * bit 6 P/C constructed * bit 5 tag number - sequence @@ -787,7 +787,8 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) else { /* Fast-Path Header */ - if (header[1] & 0x80) { + if (header[1] & 0x80) + { if ((status = transport_read_layer_bytes(transport, s, 1)) != 1) return status; pduLength = ((header[1] & 0x7F) << 8) | header[2]; @@ -818,7 +819,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) #ifdef WITH_DEBUG_TRANSPORT /* dump when whole PDU is read */ - if (Stream_GetPosition >= pduLength) + if (Stream_GetPosition(s) >= pduLength) { fprintf(stderr, "Local < Remote\n"); winpr_HexDump(Stream_Buffer(s), pduLength); @@ -826,9 +827,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) #endif if (Stream_GetPosition(s) >= pduLength) - { WLog_Packet(transport->log, WLOG_TRACE, Stream_Buffer(s), pduLength, WLOG_PACKET_INBOUND); - } Stream_SealLength(s); Stream_SetPosition(s, 0); @@ -1050,7 +1049,7 @@ int transport_check_fds(rdpTransport* transport) /** * Note: transport_read_pdu tries to read one PDU from * the transport layer. - * The ReceiveBuffer mit have a position > 0 in case of a non blocking + * The ReceiveBuffer might have a position > 0 in case of a non blocking * transport. If transport_read_pdu returns 0 the pdu couldn't be read at * this point. * Note that transport->ReceiveBuffer is replaced after each iteration From f06490b426d221781b82aaaeda40975a2c0a636e Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 28 Jul 2014 17:52:40 +0200 Subject: [PATCH 19/35] fix freerdp_client_settings_post_processing --- client/common/client.c | 61 ++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/client/common/client.c b/client/common/client.c index 532d0ddb3..94d5d2ab7 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -102,6 +102,38 @@ HANDLE freerdp_client_get_thread(rdpContext* context) return ((rdpClientContext*) context)->thread; } +static BOOL freerdp_client_settings_post_process(rdpSettings* settings) +{ + /* Moved GatewayUseSameCredentials logic outside of cmdline.c, so + * that the rdp file also triggers this functionality */ + if (settings->GatewayEnabled) + { + if (settings->GatewayUseSameCredentials) + { + if (settings->Username) + { + settings->GatewayUsername = _strdup(settings->Username); + if (!settings->GatewayUsername) + return FALSE; + } + if (settings->Domain) + { + settings->GatewayDomain = _strdup(settings->Domain); + if (!settings->GatewayDomain) + return FALSE; + } + if (settings->Password) + { + settings->GatewayPassword = _strdup(settings->Password); + if (!settings->GatewayPassword) + return FALSE; + } + } + } + return TRUE; +} + + int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc, char** argv) { int status; @@ -124,35 +156,18 @@ int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc, status = freerdp_client_settings_parse_assistance_file(settings, settings->AssistanceFile); } + /* Only call post processing if no status/error was returned*/ + if (status < 0) + return status; + /* This function will call logic that is applicable to the settings * from command line parsing AND the rdp file parsing */ - status = freerdp_client_combined_logic(settings); + if(!freerdp_client_settings_post_process(settings)) + return -1; return status; } -int freerdp_client_combined_logic(rdpSettings* settings) -{ - /* Moved GatewayUseSameCredentials logic outside of cmdline.c, so - * that the rdp file also triggers this functionality */ - if (settings->GatewayEnabled) - { - if (settings->GatewayUseSameCredentials) - { - if (settings->Username) - settings->GatewayUsername = _strdup(settings->Username); - - if (settings->Domain) - settings->GatewayDomain = _strdup(settings->Domain); - - if (settings->Password) - settings->GatewayPassword = _strdup(settings->Password); - } - } - - return 0; -} - int freerdp_client_settings_parse_connection_file(rdpSettings* settings, const char* filename) { rdpFile* file; From 32bb18152a5cb60b810ae5c927fa1aa0053a0ab8 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 28 Jul 2014 17:57:51 +0200 Subject: [PATCH 20/35] cmdline post: cleanup in case of oom --- client/common/client.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/client/common/client.c b/client/common/client.c index 94d5d2ab7..baa6d5b89 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -114,23 +114,29 @@ static BOOL freerdp_client_settings_post_process(rdpSettings* settings) { settings->GatewayUsername = _strdup(settings->Username); if (!settings->GatewayUsername) - return FALSE; + goto out_error; } if (settings->Domain) { settings->GatewayDomain = _strdup(settings->Domain); if (!settings->GatewayDomain) - return FALSE; + goto out_error; } if (settings->Password) { settings->GatewayPassword = _strdup(settings->Password); if (!settings->GatewayPassword) - return FALSE; + goto out_error; } } } return TRUE; + +out_error: + free(settings->GatewayUsername); + free(settings->GatewayDomain); + free(settings->GatewayPassword); + return FALSE; } From ff26a904899f05ffaeab0f063cf6a35b2d4be27f Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 28 Jul 2014 18:49:18 +0200 Subject: [PATCH 21/35] return status instead of returning directly --- client/common/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/common/client.c b/client/common/client.c index baa6d5b89..3f2da9a88 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -169,7 +169,7 @@ int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc, /* This function will call logic that is applicable to the settings * from command line parsing AND the rdp file parsing */ if(!freerdp_client_settings_post_process(settings)) - return -1; + status = -1; return status; } From 65aab2569d23bb9cc636cb04deb0987596cd5bcd Mon Sep 17 00:00:00 2001 From: Justin DeFields Date: Mon, 28 Jul 2014 15:24:48 -0400 Subject: [PATCH 22/35] Move multimon/span logic from cmdline.c to client.c post processing --- client/common/client.c | 13 +++++++++++++ client/common/cmdline.c | 4 ---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/client/common/client.c b/client/common/client.c index 3f2da9a88..35fedb8dc 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -130,6 +130,19 @@ static BOOL freerdp_client_settings_post_process(rdpSettings* settings) } } } + + /* Moved logic for Multimon and Span monitors to force fullscreen, so + * that the rdp file also triggers this functionality */ + if (settings->SpanMonitors) + { + settings->UseMultimon = TRUE; + settings->Fullscreen = TRUE; + } + else if (settings->UseMultimon) + { + settings->Fullscreen = TRUE; + } + return TRUE; out_error: diff --git a/client/common/cmdline.c b/client/common/cmdline.c index bd8e909f9..480f9f21b 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1281,8 +1281,6 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, CommandLineSwitchCase(arg, "multimon") { settings->UseMultimon = TRUE; - settings->SpanMonitors = FALSE; - settings->Fullscreen = TRUE; if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) { @@ -1294,9 +1292,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "span") { - settings->UseMultimon = TRUE; settings->SpanMonitors = TRUE; - settings->Fullscreen = TRUE; } CommandLineSwitchCase(arg, "workarea") { From cdcdec99bcd64bb4ba45168c8fd859252e7f42f9 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Mon, 28 Jul 2014 21:55:57 +0200 Subject: [PATCH 23/35] OpenSSL thread safety freerdp/winpr had the following issues: * The non reentrant SSL_library_init() was called concurrently (crash) * Missing code/api to set the eventually required OpenSSL static and dynamic locking callbacks * Missing code/api to free the application-global or thread-local OpenSSL data and tables This commit creates two new winpr functions: BOOL winpr_InitializeSSL(DWORD flags): Use the flag WINPR_SSL_INIT_ALREADY_INITIALIZED if you want to tell winpr that your application has already initialized OpenSSL. If required use the flag WINPR_SSL_INIT_ENABLE_LOCKING to tell winpr that it should set the OpenSSL static and dynamic locking callbacks. Otherwise just call it with the flag WINPR_SSL_INIT_DEFAULT. The recommended way is that your application calls this function once before any threads are created. However, in order to support lazy OpenSSL library initialization winpr_InitializeSSL() can also safely be called multiple times and concurrently because it uses the new InitOnceExecuteOnce() function to guarantee that the initialization is only performed successfully once during the life time of the calling process. BOOL winpr_CleanupSSL(DWORD flags): If you create a thread that uses SSL you should call this function before the thread returns using the flag WINPR_SSL_CLEANUP_THREAD in order to clean up the thread-local OpenSSL data and tables. Call the function with the flag WINPR_SSL_CLEANUP_GLOBAL before terminating your application. Note: This commit only replaced the current occurences of the SSL_load_error_strings(); SSL_library_init(); pairs in the freerdp source with winpr_InitializeSSL(). None of the server or client applications has been changed according to the recommended usage described above (TBDL). --- libfreerdp/crypto/tls.c | 4 +- winpr/include/winpr/ssl.h | 45 +++ winpr/include/winpr/synch.h | 2 +- .../libwinpr/sspi/Schannel/schannel_openssl.c | 6 +- winpr/libwinpr/sspi/sspi_winpr.c | 4 +- winpr/libwinpr/synch/init.c | 2 +- winpr/libwinpr/utils/CMakeLists.txt | 3 +- winpr/libwinpr/utils/ssl.c | 275 ++++++++++++++++++ 8 files changed, 330 insertions(+), 11 deletions(-) create mode 100644 winpr/include/winpr/ssl.h create mode 100644 winpr/libwinpr/utils/ssl.c diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index b22e94a0e..fd857b9b0 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -1343,8 +1344,7 @@ rdpTls* tls_new(rdpSettings* settings) if (!tls) return NULL; - SSL_load_error_strings(); - SSL_library_init(); + winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT); tls->settings = settings; tls->certificate_store = certificate_store_new(settings); diff --git a/winpr/include/winpr/ssl.h b/winpr/include/winpr/ssl.h new file mode 100644 index 000000000..647c0e478 --- /dev/null +++ b/winpr/include/winpr/ssl.h @@ -0,0 +1,45 @@ +/** + * WinPR: Windows Portable Runtime + * OpenSSL Library Initialization + * + * Copyright 2014 Thincast Technologies GmbH + * Copyright 2014 Norbert Federa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_SSL_H +#define WINPR_SSL_H + +#include + +#define WINPR_SSL_INIT_DEFAULT 0x00 +#define WINPR_SSL_INIT_ALREADY_INITIALIZED 0x01 +#define WINPR_SSL_INIT_ENABLE_LOCKING 0x2 + +#define WINPR_SSL_CLEANUP_GLOBAL 0x01 +#define WINPR_SSL_CLEANUP_THREAD 0x02 + +#ifdef __cplusplus +extern "C" { +#endif + +WINPR_API BOOL winpr_InitializeSSL(DWORD flags); +WINPR_API BOOL winpr_CleanupSSL(DWORD flags); + +#ifdef __cplusplus +} +#endif + +#endif /* WINPR_SSL_H */ + diff --git a/winpr/include/winpr/synch.h b/winpr/include/winpr/synch.h index fce97e9a5..04f4268e4 100644 --- a/winpr/include/winpr/synch.h +++ b/winpr/include/winpr/synch.h @@ -3,7 +3,7 @@ * Synchronization Functions * * Copyright 2012 Marc-Andre Moreau - * Copyright 2014 Thincast Technologies GmbH + * Copyright 2014 Thincast Technologies GmbH * Copyright 2014 Norbert Federa * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/winpr/libwinpr/sspi/Schannel/schannel_openssl.c b/winpr/libwinpr/sspi/Schannel/schannel_openssl.c index 5ad6e600e..6f7abe806 100644 --- a/winpr/libwinpr/sspi/Schannel/schannel_openssl.c +++ b/winpr/libwinpr/sspi/Schannel/schannel_openssl.c @@ -23,6 +23,7 @@ #include #include +#include #include #include "schannel_openssl.h" @@ -456,10 +457,7 @@ SCHANNEL_OPENSSL* schannel_openssl_new() if (context != NULL) { ZeroMemory(context, sizeof(SCHANNEL_OPENSSL)); - - SSL_load_error_strings(); - SSL_library_init(); - + winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT); context->connected = FALSE; } diff --git a/winpr/libwinpr/sspi/sspi_winpr.c b/winpr/libwinpr/sspi/sspi_winpr.c index dee803b6b..dcfb4e2b2 100644 --- a/winpr/libwinpr/sspi/sspi_winpr.c +++ b/winpr/libwinpr/sspi/sspi_winpr.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -463,8 +464,7 @@ void sspi_GlobalInit() { if (!sspi_initialized) { - SSL_load_error_strings(); - SSL_library_init(); + winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT); sspi_ContextBufferAllocTableNew(); sspi_initialized = TRUE; diff --git a/winpr/libwinpr/synch/init.c b/winpr/libwinpr/synch/init.c index 89c6427aa..5f81cf802 100644 --- a/winpr/libwinpr/synch/init.c +++ b/winpr/libwinpr/synch/init.c @@ -3,7 +3,7 @@ * Synchronization Functions * * Copyright 2012 Marc-Andre Moreau - * Copyright 2014 Thincast Technologies GmbH + * Copyright 2014 Thincast Technologies GmbH * Copyright 2014 Norbert Federa * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/winpr/libwinpr/utils/CMakeLists.txt b/winpr/libwinpr/utils/CMakeLists.txt index 9756a61f4..d8b758bbe 100644 --- a/winpr/libwinpr/utils/CMakeLists.txt +++ b/winpr/libwinpr/utils/CMakeLists.txt @@ -77,7 +77,8 @@ set(${MODULE_PREFIX}_SRCS ntlm.c print.c stream.c - cmdline.c) + cmdline.c + ssl.c) winpr_module_add(${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_COLLECTIONS_SRCS} diff --git a/winpr/libwinpr/utils/ssl.c b/winpr/libwinpr/utils/ssl.c new file mode 100644 index 000000000..2a0463977 --- /dev/null +++ b/winpr/libwinpr/utils/ssl.c @@ -0,0 +1,275 @@ +/** + * WinPR: Windows Portable Runtime + * OpenSSL Library Initialization + * + * Copyright 2014 Thincast Technologies GmbH + * Copyright 2014 Norbert Federa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include + +static int g_winpr_openssl_num_locks = 0; +static HANDLE* g_winpr_openssl_locks = NULL; +static BOOL g_winpr_openssl_initialized_by_winpr = FALSE; + +struct CRYPTO_dynlock_value +{ + HANDLE mutex; +}; + + +#if (OPENSSL_VERSION_NUMBER < 0x10000000L) +static unsigned long _winpr_openssl_id() +{ + return (unsigned long)GetCurrentThreadId(); +} +#endif + +static void _winpr_openssl_locking(int mode, int type, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) + { + WaitForSingleObject(g_winpr_openssl_locks[type], INFINITE); + } + else + { + ReleaseMutex(g_winpr_openssl_locks[type]); + } +} + +static struct CRYPTO_dynlock_value *_winpr_openssl_dynlock_create(const char *file, int line) +{ + struct CRYPTO_dynlock_value *dynlock = (struct CRYPTO_dynlock_value *) + malloc(sizeof(struct CRYPTO_dynlock_value)); + + if (dynlock) { + dynlock->mutex = CreateMutex(NULL, FALSE, NULL); + } + + return dynlock; +} + +static void _winpr_openssl_dynlock_lock(int mode, struct CRYPTO_dynlock_value *dynlock, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) + { + WaitForSingleObject(dynlock->mutex, INFINITE); + } + else + { + ReleaseMutex(dynlock->mutex); + } +} + +static void _winpr_openssl_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock, const char *file, int line) +{ + CloseHandle(dynlock->mutex); + free(dynlock); +} + +static BOOL _winpr_openssl_initialize_locking() +{ + int i, count; + + /* OpenSSL static locking */ + + if (CRYPTO_get_locking_callback()) + { + fprintf(stderr, "%s: warning: OpenSSL static locking callback is already set\n", __FUNCTION__); + } + else + { + if ((count = CRYPTO_num_locks()) > 0) + { + HANDLE *locks; + if (!(locks = calloc(count, sizeof(HANDLE)))) + { + fprintf(stderr, "%s: error allocating lock table\n", __FUNCTION__); + return FALSE; + } + + for (i = 0; i < count; i++) + { + if (!(locks[i] = CreateMutex(NULL, FALSE, NULL))) + { + fprintf(stderr, "%s: error creating lock #%d\n", __FUNCTION__, i); + while (i--) + { + CloseHandle(g_winpr_openssl_locks[i]); + } + free(locks); + return FALSE; + } + } + + g_winpr_openssl_locks = locks; + g_winpr_openssl_num_locks = count; + + CRYPTO_set_locking_callback(_winpr_openssl_locking); + } + } + + + /* OpenSSL dynamic locking */ + + if (CRYPTO_get_dynlock_create_callback() || + CRYPTO_get_dynlock_lock_callback() || + CRYPTO_get_dynlock_destroy_callback()) + { + fprintf(stderr, "%s: warning: dynamic locking callbacks are already set\n", __FUNCTION__); + } + else + { + CRYPTO_set_dynlock_create_callback(_winpr_openssl_dynlock_create); + CRYPTO_set_dynlock_lock_callback(_winpr_openssl_dynlock_lock); + CRYPTO_set_dynlock_destroy_callback(_winpr_openssl_dynlock_destroy); + } + + + /* Use the deprecated CRYPTO_get_id_callback() if building against OpenSSL < 1.0.0 */ + +#if (OPENSSL_VERSION_NUMBER < 0x10000000L) + if (CRYPTO_get_id_callback()) + { + fprintf(stderr, "%s: warning OpenSSL id_callback is already set\n", __FUNCTION__); + } + else + { + CRYPTO_set_id_callback(_winpr_openssl_id); + } +#endif + + return TRUE; +} + +static BOOL _winpr_openssl_cleanup_locking() +{ + /* undo our static locking modifications */ + + if (CRYPTO_get_locking_callback() == _winpr_openssl_locking) + { + int i; + + CRYPTO_set_locking_callback(NULL); + + for (i = 0; i < g_winpr_openssl_num_locks; i++) + { + CloseHandle(g_winpr_openssl_locks[i]); + } + + g_winpr_openssl_num_locks = 0; + free(g_winpr_openssl_locks); + g_winpr_openssl_locks = NULL; + } + + + /* unset our dynamic locking callbacks */ + + if (CRYPTO_get_dynlock_create_callback() == _winpr_openssl_dynlock_create) + { + CRYPTO_set_dynlock_create_callback(NULL); + } + + if (CRYPTO_get_dynlock_lock_callback() == _winpr_openssl_dynlock_lock) + { + CRYPTO_set_dynlock_lock_callback(NULL); + } + + if (CRYPTO_get_dynlock_destroy_callback() == _winpr_openssl_dynlock_destroy) + { + CRYPTO_set_dynlock_destroy_callback(NULL); + } + + +#if (OPENSSL_VERSION_NUMBER < 0x10000000L) + if (CRYPTO_get_id_callback() == _winpr_openssl_id) + { + CRYPTO_set_id_callback(NULL); + } +#endif + + return TRUE; +} + +static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVOID *context) +{ + DWORD flags = param ? *(PDWORD)param : WINPR_SSL_INIT_DEFAULT; + + if (flags & WINPR_SSL_INIT_ALREADY_INITIALIZED) + { + return TRUE; + } + + if (flags & WINPR_SSL_INIT_ENABLE_LOCKING) + { + if (!_winpr_openssl_initialize_locking(FALSE)) + { + return FALSE; + } + } + + /* SSL_load_error_strings() is void */ + SSL_load_error_strings(); + + /* SSL_library_init() always returns "1" */ + SSL_library_init(); + + g_winpr_openssl_initialized_by_winpr = TRUE; + + return TRUE; +} + + +/* exported functions */ + +BOOL winpr_InitializeSSL(DWORD flags) +{ + static INIT_ONCE once = INIT_ONCE_STATIC_INIT; + return InitOnceExecuteOnce(&once, _winpr_openssl_initialize, &flags, NULL); +} + +BOOL winpr_CleanupSSL(DWORD flags) +{ + if (flags & WINPR_SSL_CLEANUP_GLOBAL) + { + if (!g_winpr_openssl_initialized_by_winpr) + { + fprintf(stderr, "%s: warning: ssl was not initialized by winpr\n", __FUNCTION__); + return FALSE; + } + g_winpr_openssl_initialized_by_winpr = FALSE; + _winpr_openssl_cleanup_locking(); + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings(); + EVP_cleanup(); + flags |= WINPR_SSL_CLEANUP_THREAD; + } + + if (flags & WINPR_SSL_CLEANUP_THREAD) + { +#if (OPENSSL_VERSION_NUMBER < 0x10000000L) + ERR_remove_state(0); +#else + ERR_remove_thread_state(NULL); +#endif + } + + return TRUE; +} From e303c3bd4c8f0553b7b51ec0a85885d9d563a60f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 28 Jul 2014 16:47:42 -0400 Subject: [PATCH 24/35] channels: cleanup RDP8 virtual channels --- channels/disp/client/disp_main.c | 53 ++++++++++--------- channels/disp/client/disp_main.h | 2 +- channels/echo/client/echo_main.c | 78 +++++++++------------------- channels/rdpgfx/client/rdpgfx_main.c | 9 ++-- libfreerdp/core/info.c | 3 ++ libfreerdp/core/info.h | 1 + 6 files changed, 60 insertions(+), 86 deletions(-) diff --git a/channels/disp/client/disp_main.c b/channels/disp/client/disp_main.c index e8827366b..3682449fe 100644 --- a/channels/disp/client/disp_main.c +++ b/channels/disp/client/disp_main.c @@ -66,8 +66,8 @@ struct _DISP_PLUGIN DISP_LISTENER_CALLBACK* listener_callback; UINT32 MaxNumMonitors; - UINT32 MaxMonitorWidth; - UINT32 MaxMonitorHeight; + UINT32 MaxMonitorAreaFactorA; + UINT32 MaxMonitorAreaFactorB; }; typedef struct _DISP_PLUGIN DISP_PLUGIN; @@ -110,15 +110,9 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback if (Monitors[index].Width < 200) Monitors[index].Width = 200; - if (Monitors[index].Width > disp->MaxMonitorWidth) - Monitors[index].Width = disp->MaxMonitorWidth; - if (Monitors[index].Height < 200) Monitors[index].Height = 200; - if (Monitors[index].Height > disp->MaxMonitorHeight) - Monitors[index].Height = disp->MaxMonitorHeight; - Stream_Write_UINT32(s, Monitors[index].Flags); /* Flags (4 bytes) */ Stream_Write_UINT32(s, Monitors[index].Left); /* Left (4 bytes) */ Stream_Write_UINT32(s, Monitors[index].Top); /* Top (4 bytes) */ @@ -127,6 +121,8 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback Stream_Write_UINT32(s, Monitors[index].PhysicalWidth); /* PhysicalWidth (4 bytes) */ Stream_Write_UINT32(s, Monitors[index].PhysicalHeight); /* PhysicalHeight (4 bytes) */ Stream_Write_UINT32(s, Monitors[index].Orientation); /* Orientation (4 bytes) */ + Stream_Write_UINT32(s, Monitors[index].DesktopScaleFactor); /* DesktopScaleFactor (4 bytes) */ + Stream_Write_UINT32(s, Monitors[index].DeviceScaleFactor); /* DeviceScaleFactor (4 bytes) */ #if 0 fprintf(stderr, "\t: Flags: 0x%04X\n", Monitors[index].Flags); @@ -138,9 +134,6 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback fprintf(stderr, "\t: PhysicalHeight: %d\n", Monitors[index].PhysicalHeight); fprintf(stderr, "\t: Orientation: %d\n", Monitors[index].Orientation); #endif - - Stream_Write_UINT32(s, Monitors[index].DesktopScaleFactor); /* DesktopScaleFactor (4 bytes) */ - Stream_Write_UINT32(s, Monitors[index].DeviceScaleFactor); /* DeviceScaleFactor (4 bytes) */ } Stream_SealLength(s); @@ -158,12 +151,15 @@ int disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* disp = (DISP_PLUGIN*) callback->plugin; - Stream_Read_UINT32(s, disp->MaxNumMonitors); /* MaxNumMonitors (4 bytes) */ - Stream_Read_UINT32(s, disp->MaxMonitorWidth); /* MaxMonitorWidth (4 bytes) */ - Stream_Read_UINT32(s, disp->MaxMonitorHeight); /* MaxMonitorHeight (4 bytes) */ + if (Stream_GetRemainingLength(s) < 12) + return -1; - //fprintf(stderr, "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorWidth: %d MaxMonitorHeight: %d\n", - // disp->MaxNumMonitors, disp->MaxMonitorWidth, disp->MaxMonitorHeight); + Stream_Read_UINT32(s, disp->MaxNumMonitors); /* MaxNumMonitors (4 bytes) */ + Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorA); /* MaxMonitorAreaFactorA (4 bytes) */ + Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorB); /* MaxMonitorAreaFactorB (4 bytes) */ + + //fprintf(stderr, "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorAreaFactorA: %d MaxMonitorAreaFactorB: %d\n", + // disp->MaxNumMonitors, disp->MaxMonitorAreaFactorA, disp->MaxMonitorAreaFactorB); return 0; } @@ -173,6 +169,9 @@ int disp_recv_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s) UINT32 type; UINT32 length; + if (Stream_GetRemainingLength(s) < 8) + return -1; + Stream_Read_UINT32(s, type); /* Type (4 bytes) */ Stream_Read_UINT32(s, length); /* Length (4 bytes) */ @@ -220,8 +219,10 @@ static int disp_on_new_channel_connection(IWTSListenerCallback* pListenerCallbac DISP_CHANNEL_CALLBACK* callback; DISP_LISTENER_CALLBACK* listener_callback = (DISP_LISTENER_CALLBACK*) pListenerCallback; - callback = (DISP_CHANNEL_CALLBACK*) malloc(sizeof(DISP_CHANNEL_CALLBACK)); - ZeroMemory(callback, sizeof(DISP_CHANNEL_CALLBACK)); + callback = (DISP_CHANNEL_CALLBACK*) calloc(1, sizeof(DISP_CHANNEL_CALLBACK)); + + if (!callback) + return -1; callback->iface.OnDataReceived = disp_on_data_received; callback->iface.OnClose = disp_on_close; @@ -240,8 +241,10 @@ static int disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager int status; DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin; - disp->listener_callback = (DISP_LISTENER_CALLBACK*) malloc(sizeof(DISP_LISTENER_CALLBACK)); - ZeroMemory(disp->listener_callback, sizeof(DISP_LISTENER_CALLBACK)); + disp->listener_callback = (DISP_LISTENER_CALLBACK*) calloc(1, sizeof(DISP_LISTENER_CALLBACK)); + + if (!disp->listener_callback) + return -1; disp->listener_callback->iface.OnNewChannelConnection = disp_on_new_channel_connection; disp->listener_callback->plugin = pPlugin; @@ -281,11 +284,7 @@ int disp_send_monitor_layout(DispClientContext* context, UINT32 NumMonitors, DIS return 1; } -#ifdef STATIC_CHANNELS -#define DVCPluginEntry disp_DVCPluginEntry -#endif - -int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) +int disp_DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) { int error = 0; DISP_PLUGIN* disp; @@ -317,8 +316,8 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) disp->iface.pInterface = (void*) context; disp->MaxNumMonitors = 16; - disp->MaxMonitorWidth = 8192; - disp->MaxMonitorHeight = 8192; + disp->MaxMonitorAreaFactorA = 8192; + disp->MaxMonitorAreaFactorB = 8192; error = pEntryPoints->RegisterPlugin(pEntryPoints, "disp", (IWTSPlugin*) disp); } diff --git a/channels/disp/client/disp_main.h b/channels/disp/client/disp_main.h index 1851618a0..2cb9156f8 100644 --- a/channels/disp/client/disp_main.h +++ b/channels/disp/client/disp_main.h @@ -31,8 +31,8 @@ #include +#define DISPLAY_CONTROL_PDU_TYPE_CAPS 0x00000005 #define DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002 -#define DISPLAY_CONTROL_PDU_TYPE_CAPS 0x00000003 #endif /* FREERDP_CHANNEL_DISP_CLIENT_MAIN_H */ diff --git a/channels/echo/client/echo_main.c b/channels/echo/client/echo_main.c index ef381e21a..f5633dd41 100644 --- a/channels/echo/client/echo_main.c +++ b/channels/echo/client/echo_main.c @@ -26,12 +26,11 @@ #include #include +#include #include #include -#include - #include "echo_main.h" typedef struct _ECHO_LISTENER_CALLBACK ECHO_LISTENER_CALLBACK; @@ -63,47 +62,21 @@ struct _ECHO_PLUGIN static int echo_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream *data) { - int error; + int status; ECHO_CHANNEL_CALLBACK* callback = (ECHO_CHANNEL_CALLBACK*) pChannelCallback; - BYTE *pBuffer = Stream_Pointer(data); - UINT32 cbSize = Stream_GetRemainingLength(data); - -#ifdef WITH_DEBUG_DVC - int i = 0; - char* debug_buffer; - char* p; - - if (cbSize > 0) - { - debug_buffer = (char*) malloc(3 * cbSize); - ZeroMemory(debug_buffer, 3 * cbSize); - - p = debug_buffer; - - for (i = 0; i < (int) (cbSize - 1); i++) - { - sprintf(p, "%02x ", pBuffer[i]); - p += 3; - } - sprintf(p, "%02x", pBuffer[i]); - - DEBUG_DVC("ECHO %d: %s", cbSize, debug_buffer); - free(debug_buffer); - } -#endif + BYTE* pBuffer = Stream_Pointer(data); + UINT32 cbSize = Stream_GetRemainingLength(data); /* echo back what we have received. ECHO does not have any message IDs. */ - error = callback->channel->Write(callback->channel, cbSize, pBuffer, NULL); + status = callback->channel->Write(callback->channel, cbSize, pBuffer, NULL); - return error; + return status; } static int echo_on_close(IWTSVirtualChannelCallback* pChannelCallback) { ECHO_CHANNEL_CALLBACK* callback = (ECHO_CHANNEL_CALLBACK*) pChannelCallback; - DEBUG_DVC(""); - free(callback); return 0; @@ -116,10 +89,10 @@ static int echo_on_new_channel_connection(IWTSListenerCallback* pListenerCallbac ECHO_CHANNEL_CALLBACK* callback; ECHO_LISTENER_CALLBACK* listener_callback = (ECHO_LISTENER_CALLBACK*) pListenerCallback; - DEBUG_DVC(""); + callback = (ECHO_CHANNEL_CALLBACK*) calloc(1, sizeof(ECHO_CHANNEL_CALLBACK)); - callback = (ECHO_CHANNEL_CALLBACK*) malloc(sizeof(ECHO_CHANNEL_CALLBACK)); - ZeroMemory(callback, sizeof(ECHO_CHANNEL_CALLBACK)); + if (!callback) + return -1; callback->iface.OnDataReceived = echo_on_data_received; callback->iface.OnClose = echo_on_close; @@ -136,10 +109,10 @@ static int echo_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager { ECHO_PLUGIN* echo = (ECHO_PLUGIN*) pPlugin; - DEBUG_DVC(""); + echo->listener_callback = (ECHO_LISTENER_CALLBACK*) calloc(1, sizeof(ECHO_LISTENER_CALLBACK)); - echo->listener_callback = (ECHO_LISTENER_CALLBACK*) malloc(sizeof(ECHO_LISTENER_CALLBACK)); - ZeroMemory(echo->listener_callback, sizeof(ECHO_LISTENER_CALLBACK)); + if (!echo->listener_callback) + return -1; echo->listener_callback->iface.OnNewChannelConnection = echo_on_new_channel_connection; echo->listener_callback->plugin = pPlugin; @@ -153,36 +126,35 @@ static int echo_plugin_terminated(IWTSPlugin* pPlugin) { ECHO_PLUGIN* echo = (ECHO_PLUGIN*) pPlugin; - DEBUG_DVC(""); - - free(echo); + if (echo) + { + free(echo); + } return 0; } -#ifdef STATIC_CHANNELS -#define DVCPluginEntry echo_DVCPluginEntry -#endif - -int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) +int echo_DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) { - int error = 0; + int status = 0; ECHO_PLUGIN* echo; echo = (ECHO_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "echo"); - if (echo == NULL) + if (!echo) { - echo = (ECHO_PLUGIN*) malloc(sizeof(ECHO_PLUGIN)); - ZeroMemory(echo, sizeof(ECHO_PLUGIN)); + echo = (ECHO_PLUGIN*) calloc(1, sizeof(ECHO_PLUGIN)); + + if (!echo) + return -1; echo->iface.Initialize = echo_plugin_initialize; echo->iface.Connected = NULL; echo->iface.Disconnected = NULL; echo->iface.Terminated = echo_plugin_terminated; - error = pEntryPoints->RegisterPlugin(pEntryPoints, "echo", (IWTSPlugin*) echo); + status = pEntryPoints->RegisterPlugin(pEntryPoints, "echo", (IWTSPlugin*) echo); } - return error; + return status; } diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index f50010f93..e214f2145 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -1033,11 +1033,7 @@ void* rdpgfx_get_cache_slot_data(RdpgfxClientContext* context, UINT16 cacheSlot) return pData; } -#ifdef STATIC_CHANNELS -#define DVCPluginEntry rdpgfx_DVCPluginEntry -#endif - -int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) +int rdpgfx_DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) { int status = 0; RDPGFX_PLUGIN* gfx; @@ -1095,6 +1091,9 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) gfx->zgfx = zgfx_context_new(FALSE); + if (!gfx->zgfx) + return -1; + status = pEntryPoints->RegisterPlugin(pEntryPoints, "rdpgfx", (IWTSPlugin*) gfx); } diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index f68dff17b..c5bc9173e 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -431,6 +431,9 @@ void rdp_write_info_packet(wStream* s, rdpSettings* settings) if (settings->RemoteConsoleAudio) flags |= INFO_REMOTECONSOLEAUDIO; + if (settings->HiDefRemoteApp) + flags |= INFO_HIDEF_RAIL_SUPPORTED; + if (settings->CompressionEnabled) { flags |= INFO_COMPRESSION; diff --git a/libfreerdp/core/info.h b/libfreerdp/core/info.h index 3d2758a29..0e98dde3c 100644 --- a/libfreerdp/core/info.h +++ b/libfreerdp/core/info.h @@ -49,6 +49,7 @@ #define INFO_USING_SAVED_CREDS 0x00100000 #define INFO_AUDIOCAPTURE 0x00200000 #define INFO_VIDEO_DISABLE 0x00400000 +#define INFO_HIDEF_RAIL_SUPPORTED 0x02000000 /* Logon Information Types */ #define INFO_TYPE_LOGON 0x00000000 From 8321d7ffadd23e0eaf469f4f593b3bd938fbd01d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 28 Jul 2014 17:22:02 -0400 Subject: [PATCH 25/35] libfreerdp-codec: fix OpenH264 usage thanks to @erbth's hack --- libfreerdp/codec/h264.c | 14 ++++++++++++-- winpr/libwinpr/wtsapi/wtsapi.c | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index c407b6238..c0672df68 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -167,7 +167,7 @@ static void h264_dump_h264_data(BYTE* data, int size) fclose(fp); } -static void h264_dump_yuv_data(BYTE* yuv[], int width, int height, int stride[]) +void h264_dump_yuv_data(BYTE* yuv[], int width, int height, int stride[]) { FILE* fp; BYTE* srcp; @@ -326,7 +326,7 @@ BYTE* h264_strip_nal_unit_au_delimiter(BYTE* pSrcData, UINT32* pSrcSize) #ifdef WITH_OPENH264 -static BOOL g_openh264_trace_enabled = TRUE; +static BOOL g_openh264_trace_enabled = FALSE; static void openh264_trace_callback(H264_CONTEXT* h264, int level, const char* message) { @@ -361,6 +361,16 @@ static int openh264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSiz pYUVData, &sBufferInfo); + /** + * Calling DecodeFrame2 twice apparently works around Openh264 issue #1136: + * https://github.com/cisco/openh264/issues/1136 + * + * This is a hack, but it works and it is only necessary for the first frame. + */ + + if (sBufferInfo.iBufferStatus != 1) + state = (*h264->pDecoder)->DecodeFrame2(h264->pDecoder, NULL, 0, pYUVData, &sBufferInfo); + pSystemBuffer = &sBufferInfo.UsrData.sSystemBuffer; #if 1 diff --git a/winpr/libwinpr/wtsapi/wtsapi.c b/winpr/libwinpr/wtsapi/wtsapi.c index 4fdb1f75b..144927cde 100644 --- a/winpr/libwinpr/wtsapi/wtsapi.c +++ b/winpr/libwinpr/wtsapi/wtsapi.c @@ -126,6 +126,7 @@ int WtsApi32_InitializeWtsApi(void) if (!g_WtsApi32Module) return -1; +#ifdef _WIN32 WTSAPI32_LOAD_PROC(StopRemoteControlSession, WTS_STOP_REMOTE_CONTROL_SESSION_FN); WTSAPI32_LOAD_PROC(StartRemoteControlSessionW, WTS_START_REMOTE_CONTROL_SESSION_FN_W); WTSAPI32_LOAD_PROC(StartRemoteControlSessionA, WTS_START_REMOTE_CONTROL_SESSION_FN_A); @@ -189,6 +190,7 @@ int WtsApi32_InitializeWtsApi(void) WTSAPI32_LOAD_PROC(IsChildSessionsEnabled, WTS_IS_CHILD_SESSIONS_ENABLED_FN); WTSAPI32_LOAD_PROC(GetChildSessionId, WTS_GET_CHILD_SESSION_ID_FN); WTSAPI32_LOAD_PROC(GetActiveConsoleSessionId, WTS_GET_ACTIVE_CONSOLE_SESSION_ID_FN); +#endif g_WtsApi = &WtsApi32_WtsApiFunctionTable; From 0c408c213c557859d5903ce95ff209632a703a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 28 Jul 2014 17:42:23 -0400 Subject: [PATCH 26/35] libfreerdp-codec: stub progressive codec decompressor --- include/freerdp/codec/progressive.h | 53 +++++++++++++++ libfreerdp/codec/CMakeLists.txt | 1 + libfreerdp/codec/progressive.c | 68 +++++++++++++++++++ libfreerdp/codec/test/CMakeLists.txt | 1 + .../codec/test/TestFreeRDPCodecProgressive.c | 10 +++ 5 files changed, 133 insertions(+) create mode 100644 include/freerdp/codec/progressive.h create mode 100644 libfreerdp/codec/progressive.c create mode 100644 libfreerdp/codec/test/TestFreeRDPCodecProgressive.c diff --git a/include/freerdp/codec/progressive.h b/include/freerdp/codec/progressive.h new file mode 100644 index 000000000..016bc7412 --- /dev/null +++ b/include/freerdp/codec/progressive.h @@ -0,0 +1,53 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Progressive Codec Bitmap Compression + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CODEC_PROGRESSIVE_H +#define FREERDP_CODEC_PROGRESSIVE_H + +#include +#include + +#include + +struct _PROGRESSIVE_CONTEXT +{ + BOOL Compressor; +}; +typedef struct _PROGRESSIVE_CONTEXT PROGRESSIVE_CONTEXT; + +#ifdef __cplusplus +extern "C" { +#endif + +FREERDP_API int progressive_compress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize); + +FREERDP_API int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize, + BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight); + +FREERDP_API void progressive_context_reset(PROGRESSIVE_CONTEXT* progressive); + +FREERDP_API PROGRESSIVE_CONTEXT* progressive_context_new(BOOL Compressor); +FREERDP_API void progressive_context_free(PROGRESSIVE_CONTEXT* progressive); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_CODEC_PROGRESSIVE_H */ + diff --git a/libfreerdp/codec/CMakeLists.txt b/libfreerdp/codec/CMakeLists.txt index 5fd04894f..a99b2f21e 100644 --- a/libfreerdp/codec/CMakeLists.txt +++ b/libfreerdp/codec/CMakeLists.txt @@ -24,6 +24,7 @@ set(${MODULE_PREFIX}_SRCS audio.c planar.c planar.h + progressive.c bitmap_decode.c bitmap_encode.c rfx_bitstream.h diff --git a/libfreerdp/codec/progressive.c b/libfreerdp/codec/progressive.c new file mode 100644 index 000000000..4b798065c --- /dev/null +++ b/libfreerdp/codec/progressive.c @@ -0,0 +1,68 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Progressive Codec Bitmap Compression + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include + +int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize, + BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight) +{ + return 1; +} + +int progressive_compress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize) +{ + return 1; +} + +void progressive_context_reset(PROGRESSIVE_CONTEXT* progressive) +{ + +} + +PROGRESSIVE_CONTEXT* progressive_context_new(BOOL Compressor) +{ + PROGRESSIVE_CONTEXT* progressive; + + progressive = (PROGRESSIVE_CONTEXT*) calloc(1, sizeof(PROGRESSIVE_CONTEXT)); + + if (progressive) + { + progressive->Compressor = Compressor; + } + + return progressive; +} + +void progressive_context_free(PROGRESSIVE_CONTEXT* progressive) +{ + if (!progressive) + return; + + free(progressive); +} + diff --git a/libfreerdp/codec/test/CMakeLists.txt b/libfreerdp/codec/test/CMakeLists.txt index ba158560c..6ce9c65c2 100644 --- a/libfreerdp/codec/test/CMakeLists.txt +++ b/libfreerdp/codec/test/CMakeLists.txt @@ -12,6 +12,7 @@ set(${MODULE_PREFIX}_TESTS TestFreeRDPCodecZGfx.c TestFreeRDPCodecPlanar.c TestFreeRDPCodecClear.c + TestFreeRDPCodecProgressive.c TestFreeRDPCodecRemoteFX.c) create_test_sourcelist(${MODULE_PREFIX}_SRCS diff --git a/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c b/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c new file mode 100644 index 000000000..320329300 --- /dev/null +++ b/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c @@ -0,0 +1,10 @@ +#include +#include + +#include + +int TestFreeRDPCodecProgressive(int argc, char* argv[]) +{ + return 0; +} + From b8415af0d8eaf323be49e698a088c320ed47920d Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 23 Jul 2014 17:26:49 +0200 Subject: [PATCH 27/35] Fix compiler warnings. This commit is based on pull request #1493 --- libfreerdp/common/settings.c | 271 ------------------ winpr/libwinpr/crt/string.c | 2 +- winpr/libwinpr/interlocked/interlocked.c | 2 +- winpr/libwinpr/synch/critical.c | 4 +- winpr/libwinpr/sysinfo/sysinfo.c | 1 - winpr/libwinpr/utils/collections/BufferPool.c | 4 +- winpr/libwinpr/utils/sam.c | 6 +- winpr/libwinpr/utils/trio/triodef.h | 6 +- 8 files changed, 12 insertions(+), 284 deletions(-) diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 776a55757..05f672da5 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -657,507 +657,380 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id) { case FreeRDP_ServerMode: return settings->ServerMode; - break; case FreeRDP_NetworkAutoDetect: return settings->NetworkAutoDetect; - break; case FreeRDP_SupportAsymetricKeys: return settings->SupportAsymetricKeys; - break; case FreeRDP_SupportErrorInfoPdu: return settings->SupportErrorInfoPdu; - break; case FreeRDP_SupportStatusInfoPdu: return settings->SupportStatusInfoPdu; - break; case FreeRDP_SupportMonitorLayoutPdu: return settings->SupportMonitorLayoutPdu; - break; case FreeRDP_SupportGraphicsPipeline: return settings->SupportGraphicsPipeline; - break; case FreeRDP_SupportDynamicTimeZone: return settings->SupportDynamicTimeZone; - break; case FreeRDP_DisableEncryption: return settings->DisableEncryption; - break; case FreeRDP_ConsoleSession: return settings->ConsoleSession; - break; case FreeRDP_SpanMonitors: return settings->SpanMonitors; - break; case FreeRDP_UseMultimon: return settings->UseMultimon; - break; case FreeRDP_ForceMultimon: return settings->ForceMultimon; - break; case FreeRDP_AutoLogonEnabled: return settings->AutoLogonEnabled; - break; case FreeRDP_CompressionEnabled: return settings->CompressionEnabled; - break; case FreeRDP_DisableCtrlAltDel: return settings->DisableCtrlAltDel; - break; case FreeRDP_EnableWindowsKey: return settings->EnableWindowsKey; - break; case FreeRDP_MaximizeShell: return settings->MaximizeShell; - break; case FreeRDP_LogonNotify: return settings->LogonNotify; - break; case FreeRDP_LogonErrors: return settings->LogonErrors; - break; case FreeRDP_MouseAttached: return settings->MouseAttached; - break; case FreeRDP_MouseHasWheel: return settings->MouseHasWheel; - break; case FreeRDP_RemoteConsoleAudio: return settings->RemoteConsoleAudio; - break; case FreeRDP_AudioPlayback: return settings->AudioPlayback; - break; case FreeRDP_AudioCapture: return settings->AudioCapture; - break; case FreeRDP_VideoDisable: return settings->VideoDisable; - break; case FreeRDP_PasswordIsSmartcardPin: return settings->PasswordIsSmartcardPin; - break; case FreeRDP_UsingSavedCredentials: return settings->UsingSavedCredentials; - break; case FreeRDP_ForceEncryptedCsPdu: return settings->ForceEncryptedCsPdu; - break; case FreeRDP_HiDefRemoteApp: return settings->HiDefRemoteApp; - break; case FreeRDP_IPv6Enabled: return settings->IPv6Enabled; - break; case FreeRDP_AutoReconnectionEnabled: return settings->AutoReconnectionEnabled; - break; case FreeRDP_DynamicDaylightTimeDisabled: return settings->DynamicDaylightTimeDisabled; - break; case FreeRDP_AllowFontSmoothing: return settings->AllowFontSmoothing; - break; case FreeRDP_DisableWallpaper: return settings->DisableWallpaper; - break; case FreeRDP_DisableFullWindowDrag: return settings->DisableFullWindowDrag; - break; case FreeRDP_DisableMenuAnims: return settings->DisableMenuAnims; - break; case FreeRDP_DisableThemes: return settings->DisableThemes; - break; case FreeRDP_DisableCursorShadow: return settings->DisableCursorShadow; - break; case FreeRDP_DisableCursorBlinking: return settings->DisableCursorBlinking; - break; case FreeRDP_AllowDesktopComposition: return settings->AllowDesktopComposition; - break; case FreeRDP_RemoteAssistanceMode: return settings->RemoteAssistanceMode; - break; case FreeRDP_TlsSecurity: return settings->TlsSecurity; - break; case FreeRDP_NlaSecurity: return settings->NlaSecurity; - break; case FreeRDP_RdpSecurity: return settings->RdpSecurity; - break; case FreeRDP_ExtSecurity: return settings->ExtSecurity; - break; case FreeRDP_Authentication: return settings->Authentication; - break; case FreeRDP_NegotiateSecurityLayer: return settings->NegotiateSecurityLayer; - break; case FreeRDP_RestrictedAdminModeRequired: return settings->RestrictedAdminModeRequired; - break; case FreeRDP_DisableCredentialsDelegation: return settings->DisableCredentialsDelegation; - break; case FreeRDP_AuthenticationLevel: return settings->AuthenticationLevel; - break; case FreeRDP_MstscCookieMode: return settings->MstscCookieMode; - break; case FreeRDP_SendPreconnectionPdu: return settings->SendPreconnectionPdu; - break; case FreeRDP_IgnoreCertificate: return settings->IgnoreCertificate; - break; case FreeRDP_ExternalCertificateManagement: return settings->ExternalCertificateManagement; - break; case FreeRDP_Workarea: return settings->Workarea; - break; case FreeRDP_Fullscreen: return settings->Fullscreen; - break; case FreeRDP_GrabKeyboard: return settings->GrabKeyboard; - break; case FreeRDP_Decorations: return settings->Decorations; - break; case FreeRDP_SmartSizing: return settings->SmartSizing; - break; case FreeRDP_MouseMotion: return settings->MouseMotion; - break; case FreeRDP_AsyncInput: return settings->AsyncInput; - break; case FreeRDP_AsyncUpdate: return settings->AsyncUpdate; - break; case FreeRDP_AsyncChannels: return settings->AsyncChannels; - break; case FreeRDP_AsyncTransport: return settings->AsyncTransport; - break; case FreeRDP_ToggleFullscreen: return settings->ToggleFullscreen; - break; case FreeRDP_SoftwareGdi: return settings->SoftwareGdi; - break; case FreeRDP_LocalConnection: return settings->LocalConnection; - break; case FreeRDP_AuthenticationOnly: return settings->AuthenticationOnly; - break; case FreeRDP_CredentialsFromStdin: return settings->CredentialsFromStdin; - break; case FreeRDP_DumpRemoteFx: return settings->DumpRemoteFx; - break; case FreeRDP_PlayRemoteFx: return settings->PlayRemoteFx; - break; case FreeRDP_GatewayUseSameCredentials: return settings->GatewayUseSameCredentials; - break; case FreeRDP_GatewayEnabled: return settings->GatewayEnabled; - break; case FreeRDP_GatewayBypassLocal: return settings->GatewayBypassLocal; - break; case FreeRDP_RemoteApplicationMode: return settings->RemoteApplicationMode; - break; case FreeRDP_DisableRemoteAppCapsCheck: return settings->DisableRemoteAppCapsCheck; - break; case FreeRDP_RemoteAppLanguageBarSupported: return settings->RemoteAppLanguageBarSupported; - break; case FreeRDP_RefreshRect: return settings->RefreshRect; - break; case FreeRDP_SuppressOutput: return settings->SuppressOutput; - break; case FreeRDP_FastPathOutput: return settings->FastPathOutput; - break; case FreeRDP_SaltedChecksum: return settings->SaltedChecksum; - break; case FreeRDP_LongCredentialsSupported: return settings->LongCredentialsSupported; - break; case FreeRDP_NoBitmapCompressionHeader: return settings->NoBitmapCompressionHeader; - break; case FreeRDP_BitmapCompressionDisabled: return settings->BitmapCompressionDisabled; - break; case FreeRDP_DesktopResize: return settings->DesktopResize; - break; case FreeRDP_DrawAllowDynamicColorFidelity: return settings->DrawAllowDynamicColorFidelity; - break; case FreeRDP_DrawAllowColorSubsampling: return settings->DrawAllowColorSubsampling; - break; case FreeRDP_DrawAllowSkipAlpha: return settings->DrawAllowSkipAlpha; - break; case FreeRDP_BitmapCacheV3Enabled: return settings->BitmapCacheV3Enabled; - break; case FreeRDP_AltSecFrameMarkerSupport: return settings->AltSecFrameMarkerSupport; - break; case FreeRDP_BitmapCacheEnabled: return settings->BitmapCacheEnabled; - break; case FreeRDP_AllowCacheWaitingList: return settings->AllowCacheWaitingList; - break; case FreeRDP_BitmapCachePersistEnabled: return settings->BitmapCachePersistEnabled; - break; case FreeRDP_ColorPointerFlag: return settings->ColorPointerFlag; - break; case FreeRDP_UnicodeInput: return settings->UnicodeInput; - break; case FreeRDP_FastPathInput: return settings->FastPathInput; - break; case FreeRDP_MultiTouchInput: return settings->MultiTouchInput; - break; case FreeRDP_MultiTouchGestures: return settings->MultiTouchGestures; - break; case FreeRDP_SoundBeepsEnabled: return settings->SoundBeepsEnabled; - break; case FreeRDP_SurfaceCommandsEnabled: return settings->SurfaceCommandsEnabled; - break; case FreeRDP_FrameMarkerCommandEnabled: return settings->FrameMarkerCommandEnabled; - break; case FreeRDP_RemoteFxOnly: return settings->RemoteFxOnly; - break; case FreeRDP_RemoteFxCodec: return settings->RemoteFxCodec; - break; case FreeRDP_RemoteFxImageCodec: return settings->RemoteFxImageCodec; - break; case FreeRDP_NSCodec: return settings->NSCodec; - break; case FreeRDP_FrameAcknowledge: return settings->FrameAcknowledge; - break; case FreeRDP_JpegCodec: return settings->JpegCodec; - break; case FreeRDP_GfxThinClient: return settings->GfxThinClient; - break; case FreeRDP_GfxSmallCache: return settings->GfxSmallCache; - break; case FreeRDP_GfxProgressive: return settings->GfxProgressive; - break; case FreeRDP_GfxProgressiveV2: return settings->GfxProgressiveV2; - break; case FreeRDP_GfxH264: return settings->GfxH264; - break; case FreeRDP_DrawNineGridEnabled: return settings->DrawNineGridEnabled; - break; case FreeRDP_DrawGdiPlusEnabled: return settings->DrawGdiPlusEnabled; - break; case FreeRDP_DrawGdiPlusCacheEnabled: return settings->DrawGdiPlusCacheEnabled; - break; case FreeRDP_DeviceRedirection: return settings->DeviceRedirection; - break; case FreeRDP_RedirectDrives: return settings->RedirectDrives; - break; case FreeRDP_RedirectHomeDrive: return settings->RedirectHomeDrive; - break; case FreeRDP_RedirectSmartCards: return settings->RedirectSmartCards; - break; case FreeRDP_RedirectPrinters: return settings->RedirectPrinters; - break; case FreeRDP_RedirectSerialPorts: return settings->RedirectSerialPorts; - break; case FreeRDP_RedirectParallelPorts: return settings->RedirectParallelPorts; - break; case FreeRDP_RedirectClipboard: return settings->RedirectClipboard; - break; default: fprintf(stderr, "freerdp_get_param_bool: unknown id: %d\n", id); return -1; - break; } - - return -1; } int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) @@ -1663,7 +1536,6 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) default: fprintf(stderr, "freerdp_set_param_bool: unknown id %d (param = %d)\n", id, param); return -1; - break; } /* Mark field as modified */ @@ -1678,19 +1550,14 @@ int freerdp_get_param_int(rdpSettings* settings, int id) { case FreeRDP_XPan: return settings->XPan; - break; case FreeRDP_YPan: return settings->YPan; - break; default: fprintf(stderr, "freerdp_get_param_int: unknown id: %d\n", id); return 0; - break; } - - return 0; } int freerdp_set_param_int(rdpSettings* settings, int id, int param) @@ -1708,7 +1575,6 @@ int freerdp_set_param_int(rdpSettings* settings, int id, int param) default: fprintf(stderr, "freerdp_set_param_int: unknown id %d (param = %d)\n", id, param); return -1; - break; } settings->SettingsModified[id] = 1; @@ -1722,307 +1588,230 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id) { case FreeRDP_ShareId: return settings->ShareId; - break; case FreeRDP_PduSource: return settings->PduSource; - break; case FreeRDP_ServerPort: return settings->ServerPort; - break; case FreeRDP_RdpVersion: return settings->RdpVersion; - break; case FreeRDP_DesktopWidth: return settings->DesktopWidth; - break; case FreeRDP_DesktopHeight: return settings->DesktopHeight; - break; case FreeRDP_ColorDepth: return settings->ColorDepth; - break; case FreeRDP_ConnectionType: return settings->ConnectionType; - break; case FreeRDP_ClientBuild: return settings->ClientBuild; - break; case FreeRDP_EarlyCapabilityFlags: return settings->EarlyCapabilityFlags; - break; case FreeRDP_EncryptionMethods: return settings->EncryptionMethods; - break; case FreeRDP_ExtEncryptionMethods: return settings->ExtEncryptionMethods; - break; case FreeRDP_EncryptionLevel: return settings->EncryptionLevel; - break; case FreeRDP_ChannelCount: return settings->ChannelCount; - break; case FreeRDP_ChannelDefArraySize: return settings->ChannelDefArraySize; - break; case FreeRDP_ClusterInfoFlags: return settings->ClusterInfoFlags; - break; case FreeRDP_RedirectedSessionId: return settings->RedirectedSessionId; - break; case FreeRDP_MonitorDefArraySize: return settings->MonitorDefArraySize; - break; case FreeRDP_DesktopPosX: return settings->DesktopPosX; - break; case FreeRDP_DesktopPosY: return settings->DesktopPosY; - break; case FreeRDP_MultitransportFlags: return settings->MultitransportFlags; - break; case FreeRDP_CompressionLevel: return settings->CompressionLevel; - break; case FreeRDP_AutoReconnectMaxRetries: return settings->AutoReconnectMaxRetries; - break; case FreeRDP_PerformanceFlags: return settings->PerformanceFlags; - break; case FreeRDP_RequestedProtocols: return settings->RequestedProtocols; - break; case FreeRDP_SelectedProtocol: return settings->SelectedProtocol; - break; case FreeRDP_NegotiationFlags: return settings->NegotiationFlags; - break; case FreeRDP_CookieMaxLength: return settings->CookieMaxLength; - break; case FreeRDP_PreconnectionId: return settings->PreconnectionId; - break; case FreeRDP_RedirectionFlags: return settings->RedirectionFlags; - break; case FreeRDP_LoadBalanceInfoLength: return settings->LoadBalanceInfoLength; - break; case FreeRDP_RedirectionPasswordLength: return settings->RedirectionPasswordLength; - break; case FreeRDP_RedirectionTsvUrlLength: return settings->RedirectionTsvUrlLength; - break; case FreeRDP_TargetNetAddressCount: return settings->TargetNetAddressCount; - break; case FreeRDP_PercentScreen: return settings->PercentScreen; - break; case FreeRDP_GatewayUsageMethod: return settings->GatewayUsageMethod; - break; case FreeRDP_GatewayPort: return settings->GatewayPort; - break; case FreeRDP_GatewayCredentialsSource: return settings->GatewayCredentialsSource; - break; case FreeRDP_RemoteAppNumIconCaches: return settings->RemoteAppNumIconCaches; - break; case FreeRDP_RemoteAppNumIconCacheEntries: return settings->RemoteAppNumIconCacheEntries; - break; case FreeRDP_ReceivedCapabilitiesSize: return settings->ReceivedCapabilitiesSize; - break; case FreeRDP_OsMajorType: return settings->OsMajorType; - break; case FreeRDP_OsMinorType: return settings->OsMinorType; - break; case FreeRDP_BitmapCacheVersion: return settings->BitmapCacheVersion; - break; case FreeRDP_BitmapCacheV2NumCells: return settings->BitmapCacheV2NumCells; - break; case FreeRDP_PointerCacheSize: return settings->PointerCacheSize; - break; case FreeRDP_KeyboardLayout: return settings->KeyboardLayout; - break; case FreeRDP_KeyboardType: return settings->KeyboardType; - break; case FreeRDP_KeyboardSubType: return settings->KeyboardSubType; - break; case FreeRDP_KeyboardFunctionKey: return settings->KeyboardFunctionKey; - break; case FreeRDP_BrushSupportLevel: return settings->BrushSupportLevel; - break; case FreeRDP_GlyphSupportLevel: return settings->GlyphSupportLevel; - break; case FreeRDP_OffscreenSupportLevel: return settings->OffscreenSupportLevel; - break; case FreeRDP_OffscreenCacheSize: return settings->OffscreenCacheSize; - break; case FreeRDP_OffscreenCacheEntries: return settings->OffscreenCacheEntries; - break; case FreeRDP_VirtualChannelCompressionFlags: return settings->VirtualChannelCompressionFlags; - break; case FreeRDP_VirtualChannelChunkSize: return settings->VirtualChannelChunkSize; - break; case FreeRDP_MultifragMaxRequestSize: return settings->MultifragMaxRequestSize; - break; case FreeRDP_LargePointerFlag: return settings->LargePointerFlag; - break; case FreeRDP_CompDeskSupportLevel: return settings->CompDeskSupportLevel; - break; case FreeRDP_RemoteFxCodecId: return settings->RemoteFxCodecId; - break; case FreeRDP_RemoteFxCodecMode: return settings->RemoteFxCodecMode; - break; case FreeRDP_NSCodecId: return settings->NSCodecId; - break; case FreeRDP_JpegCodecId: return settings->JpegCodecId; - break; case FreeRDP_JpegQuality: return settings->JpegQuality; - break; case FreeRDP_BitmapCacheV3CodecId: return settings->BitmapCacheV3CodecId; - break; case FreeRDP_DrawNineGridCacheSize: return settings->DrawNineGridCacheSize; - break; case FreeRDP_DrawNineGridCacheEntries: return settings->DrawNineGridCacheEntries; - break; case FreeRDP_DeviceCount: return settings->DeviceCount; - break; case FreeRDP_DeviceArraySize: return settings->DeviceArraySize; - break; case FreeRDP_StaticChannelCount: return settings->StaticChannelCount; - break; case FreeRDP_StaticChannelArraySize: return settings->StaticChannelArraySize; - break; case FreeRDP_DynamicChannelCount: return settings->DynamicChannelCount; - break; case FreeRDP_DynamicChannelArraySize: return settings->DynamicChannelArraySize; - break; default: fprintf(stderr, "freerdp_get_param_uint32: unknown id: %d\n", id); return 0; - break; } - - return 0; } int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param) @@ -2328,7 +2117,6 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param) default: fprintf(stderr, "freerdp_set_param_uint32: unknown id %d (param = %u)\n", id, param); return -1; - break; } /* Mark field as modified */ @@ -2343,15 +2131,11 @@ UINT64 freerdp_get_param_uint64(rdpSettings* settings, int id) { case FreeRDP_ParentWindowId: return settings->ParentWindowId; - break; default: fprintf(stderr, "freerdp_get_param_uint64: unknown id: %d\n", id); return -1; - break; } - - return 0; } int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param) @@ -2365,7 +2149,6 @@ int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param) default: fprintf(stderr, "freerdp_set_param_uint64: unknown id %d (param = %u)\n", id, (UINT32) param); return -1; - break; } /* Mark field as modified */ @@ -2380,191 +2163,143 @@ char* freerdp_get_param_string(rdpSettings* settings, int id) { case FreeRDP_ServerHostname: return settings->ServerHostname; - break; case FreeRDP_Username: return settings->Username; - break; case FreeRDP_Password: return settings->Password; - break; case FreeRDP_Domain: return settings->Domain; - break; case FreeRDP_PasswordHash: return settings->PasswordHash; - break; case FreeRDP_ClientHostname: return settings->ClientHostname; - break; case FreeRDP_ClientProductId: return settings->ClientProductId; - break; case FreeRDP_AlternateShell: return settings->AlternateShell; - break; case FreeRDP_ShellWorkingDirectory: return settings->ShellWorkingDirectory; - break; case FreeRDP_ClientAddress: return settings->ClientAddress; - break; case FreeRDP_ClientDir: return settings->ClientDir; - break; case FreeRDP_DynamicDSTTimeZoneKeyName: return settings->DynamicDSTTimeZoneKeyName; - break; case FreeRDP_RemoteAssistanceSessionId: return settings->RemoteAssistanceSessionId; - break; case FreeRDP_RemoteAssistancePassStub: return settings->RemoteAssistancePassStub; - break; case FreeRDP_RemoteAssistancePassword: return settings->RemoteAssistancePassword; - break; case FreeRDP_RemoteAssistanceRCTicket: return settings->RemoteAssistanceRCTicket; - break; case FreeRDP_AuthenticationServiceClass: return settings->AuthenticationServiceClass; - break; case FreeRDP_PreconnectionBlob: return settings->PreconnectionBlob; - break; case FreeRDP_KerberosKdc: return settings->KerberosKdc; - break; case FreeRDP_KerberosRealm: return settings->KerberosRealm; - break; case FreeRDP_CertificateName: return settings->CertificateName; - break; case FreeRDP_CertificateFile: return settings->CertificateFile; - break; case FreeRDP_PrivateKeyFile: return settings->PrivateKeyFile; - break; case FreeRDP_RdpKeyFile: return settings->RdpKeyFile; - break; case FreeRDP_WindowTitle: return settings->WindowTitle; - break; case FreeRDP_ComputerName: return settings->ComputerName; - break; case FreeRDP_ConnectionFile: return settings->ConnectionFile; - break; case FreeRDP_AssistanceFile: return settings->AssistanceFile; - break; case FreeRDP_HomePath: return settings->HomePath; - break; case FreeRDP_ConfigPath: return settings->ConfigPath; - break; case FreeRDP_CurrentPath: return settings->CurrentPath; - break; case FreeRDP_DumpRemoteFxFile: return settings->DumpRemoteFxFile; - break; case FreeRDP_PlayRemoteFxFile: return settings->PlayRemoteFxFile; - break; case FreeRDP_GatewayHostname: return settings->GatewayHostname; - break; case FreeRDP_GatewayUsername: return settings->GatewayUsername; - break; case FreeRDP_GatewayPassword: return settings->GatewayPassword; - break; case FreeRDP_GatewayDomain: return settings->GatewayDomain; - break; case FreeRDP_RemoteApplicationName: return settings->RemoteApplicationName; - break; case FreeRDP_RemoteApplicationIcon: return settings->RemoteApplicationIcon; - break; case FreeRDP_RemoteApplicationProgram: return settings->RemoteApplicationProgram; - break; case FreeRDP_RemoteApplicationFile: return settings->RemoteApplicationFile; - break; case FreeRDP_RemoteApplicationGuid: return settings->RemoteApplicationGuid; - break; case FreeRDP_RemoteApplicationCmdLine: return settings->RemoteApplicationCmdLine; - break; case FreeRDP_ImeFileName: return settings->ImeFileName; - break; case FreeRDP_DrivesToRedirect: return settings->DrivesToRedirect; - break; default: fprintf(stderr, "freerdp_get_param_string: unknown id: %d\n", id); return NULL; - break; } - - return NULL; } int freerdp_set_param_string(rdpSettings* settings, int id, const char* param) @@ -2799,7 +2534,6 @@ int freerdp_set_param_string(rdpSettings* settings, int id, const char* param) default: fprintf(stderr, "freerdp_set_param_string: unknown id %d (param = %s)\n", id, param); return -1; - break; } /* Mark field as modified */ @@ -2814,15 +2548,11 @@ double freerdp_get_param_double(rdpSettings* settings, int id) { case FreeRDP_ScalingFactor: return settings->ScalingFactor; - break; default: fprintf(stderr, "freerdp_get_param_double: unknown id: %d\n", id); return 0; - break; } - - return 0; } int freerdp_set_param_double(rdpSettings* settings, int id, double param) @@ -2835,7 +2565,6 @@ int freerdp_set_param_double(rdpSettings* settings, int id, double param) default: return -1; - break; } /* Mark field as modified */ diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c index 0ecdc6a42..37bd6ebec 100644 --- a/winpr/libwinpr/crt/string.c +++ b/winpr/libwinpr/crt/string.c @@ -54,7 +54,7 @@ WCHAR* _wcsdup(const WCHAR* strSource) if (strSource == NULL) return NULL; -#if sun +#if defined(sun) && sun strDestination = wsdup(strSource); #elif defined(__APPLE__) && defined(__MACH__) || defined(ANDROID) strDestination = malloc(wcslen((wchar_t*)strSource)); diff --git a/winpr/libwinpr/interlocked/interlocked.c b/winpr/libwinpr/interlocked/interlocked.c index 0b8c0d45a..6490bb6f1 100644 --- a/winpr/libwinpr/interlocked/interlocked.c +++ b/winpr/libwinpr/interlocked/interlocked.c @@ -282,7 +282,7 @@ LONGLONG InterlockedCompareExchange64(LONGLONG volatile *Destination, LONGLONG E return previousValue; } -#elif ANDROID || (defined(__GNUC__) && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)) +#elif (defined(ANDROID) && ANDROID) || (defined(__GNUC__) && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)) #include diff --git a/winpr/libwinpr/synch/critical.c b/winpr/libwinpr/synch/critical.c index f67c373a3..0ea0def34 100644 --- a/winpr/libwinpr/synch/critical.c +++ b/winpr/libwinpr/synch/critical.c @@ -101,7 +101,7 @@ DWORD SetCriticalSectionSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dw #endif } -VOID _WaitForCriticalSection(LPCRITICAL_SECTION lpCriticalSection) +static VOID _WaitForCriticalSection(LPCRITICAL_SECTION lpCriticalSection) { #if defined(__APPLE__) semaphore_wait(*((winpr_sem_t*) lpCriticalSection->LockSemaphore)); @@ -110,7 +110,7 @@ VOID _WaitForCriticalSection(LPCRITICAL_SECTION lpCriticalSection) #endif } -VOID _UnWaitCriticalSection(LPCRITICAL_SECTION lpCriticalSection) +static VOID _UnWaitCriticalSection(LPCRITICAL_SECTION lpCriticalSection) { #if defined __APPLE__ semaphore_signal(*((winpr_sem_t*) lpCriticalSection->LockSemaphore)); diff --git a/winpr/libwinpr/sysinfo/sysinfo.c b/winpr/libwinpr/sysinfo/sysinfo.c index 572916ca3..fcef5b4cb 100644 --- a/winpr/libwinpr/sysinfo/sysinfo.c +++ b/winpr/libwinpr/sysinfo/sysinfo.c @@ -222,7 +222,6 @@ BOOL GetComputerNameExA(COMPUTER_NAME_FORMAT NameType, LPSTR lpBuffer, LPDWORD l default: return FALSE; - break; } return TRUE; diff --git a/winpr/libwinpr/utils/collections/BufferPool.c b/winpr/libwinpr/utils/collections/BufferPool.c index 3a0fda5b4..2b05263c6 100644 --- a/winpr/libwinpr/utils/collections/BufferPool.c +++ b/winpr/libwinpr/utils/collections/BufferPool.c @@ -34,7 +34,7 @@ * Methods */ -BOOL BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count) +static BOOL BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count) { if (count > 0) { @@ -61,7 +61,7 @@ BOOL BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count) return TRUE; } -BOOL BufferPool_ShiftUsed(wBufferPool* pool, int index, int count) +static BOOL BufferPool_ShiftUsed(wBufferPool* pool, int index, int count) { if (count > 0) { diff --git a/winpr/libwinpr/utils/sam.c b/winpr/libwinpr/utils/sam.c index 8c3b91764..cf28fa243 100644 --- a/winpr/libwinpr/utils/sam.c +++ b/winpr/libwinpr/utils/sam.c @@ -68,7 +68,7 @@ WINPR_SAM* SamOpen(BOOL read_only) return sam; } -BOOL SamLookupStart(WINPR_SAM* sam) +static BOOL SamLookupStart(WINPR_SAM* sam) { size_t read_size; long int file_size; @@ -105,7 +105,7 @@ BOOL SamLookupStart(WINPR_SAM* sam) return TRUE; } -void SamLookupFinish(WINPR_SAM* sam) +static void SamLookupFinish(WINPR_SAM* sam) { free(sam->buffer); @@ -113,7 +113,7 @@ void SamLookupFinish(WINPR_SAM* sam) sam->line = NULL; } -void HexStrToBin(char* str, BYTE* bin, int length) +static void HexStrToBin(char* str, BYTE* bin, int length) { int i; diff --git a/winpr/libwinpr/utils/trio/triodef.h b/winpr/libwinpr/utils/trio/triodef.h index 11c14b9c4..ce2667b0a 100644 --- a/winpr/libwinpr/utils/trio/triodef.h +++ b/winpr/libwinpr/utils/trio/triodef.h @@ -168,9 +168,9 @@ #if defined(__cplusplus) # define PREDEF_STANDARD_CXX -#endif -#if __cplusplus - 0 >= 199711L -# define PREDEF_STANDARD_CXX89 +# if __cplusplus - 0 >= 199711L +# define PREDEF_STANDARD_CXX89 +# endif #endif #if defined(TRIO_PLATFORM_UNIX) From 8c318da7b1932dc3069c85b247388caee667c51c Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 23 Jul 2014 19:08:06 +0200 Subject: [PATCH 28/35] fix compiler warnings --- channels/echo/server/echo_main.c | 3 ++- libfreerdp/codec/h264.c | 4 +++- libfreerdp/core/tcp.c | 2 +- libfreerdp/utils/test/TestRingBuffer.c | 8 ++++---- winpr/libwinpr/comm/test/TestCommConfig.c | 2 +- winpr/libwinpr/crt/alignment.c | 1 - 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/channels/echo/server/echo_main.c b/channels/echo/server/echo_main.c index 37d42cb61..979294d28 100644 --- a/channels/echo/server/echo_main.c +++ b/channels/echo/server/echo_main.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -166,7 +167,7 @@ static void* echo_server_thread_func(void* arg) break; } - IFCALL(echo->context.Response, &echo->context, (PCHAR) Stream_Buffer(s), BytesReturned); + IFCALL(echo->context.Response, &echo->context, (BYTE *) Stream_Buffer(s), BytesReturned); } Stream_Free(s, TRUE); diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index f690b3f23..2546d9289 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -31,6 +31,7 @@ #define USE_GRAY_SCALE 0 #define USE_UPCONVERT 0 +#ifdef WITH_OPENH264 static BYTE clip(int x) { if (x < 0) return 0; @@ -100,6 +101,7 @@ static UINT32 YUV_to_RGB(BYTE Y, BYTE U, BYTE V) return RGB32(R, G, B); } +#endif //WITH_OPENH264 #if USE_UPCONVERT static BYTE* convert_420_to_444(BYTE* chroma420, int chroma420Width, int chroma420Height, int chroma420Stride) @@ -335,8 +337,8 @@ H264_CONTEXT* h264_context_new(BOOL Compressor) return h264; -EXCEPTION: #ifdef WITH_OPENH264 +EXCEPTION: if (h264->pDecoder) { WelsDestroyDecoder(h264->pDecoder); diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index 21a875150..4ed62e1ba 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -562,7 +562,7 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout) } } - BIO_set_close(tcp->socketBio, BIO_NOCLOSE); + (void)BIO_set_close(tcp->socketBio, BIO_NOCLOSE); BIO_free(tcp->socketBio); tcp->socketBio = BIO_new(BIO_s_simple_socket()); diff --git a/libfreerdp/utils/test/TestRingBuffer.c b/libfreerdp/utils/test/TestRingBuffer.c index 1f4e3f504..dd128f44e 100644 --- a/libfreerdp/utils/test/TestRingBuffer.c +++ b/libfreerdp/utils/test/TestRingBuffer.c @@ -111,7 +111,7 @@ int TestRingBuffer(int argc, char* argv[]) if (ringbuffer_used(&ringBuffer) != 15) { - fprintf(stderr, "invalid used size got %d when i would expect 15\n", ringbuffer_used(&ringBuffer)); + fprintf(stderr, "invalid used size got %ld when i would expect 15\n", ringbuffer_used(&ringBuffer)); return -1; } @@ -134,7 +134,7 @@ int TestRingBuffer(int argc, char* argv[]) if (ringbuffer_used(&ringBuffer) != 5) { - fprintf(stderr, "invalid used size after read got %d when i would expect 5\n", ringbuffer_used(&ringBuffer)); + fprintf(stderr, "invalid used size after read got %ld when i would expect 5\n", ringbuffer_used(&ringBuffer)); return -1; } @@ -189,7 +189,7 @@ int TestRingBuffer(int argc, char* argv[]) if (ringbuffer_capacity(&ringBuffer) != 10) { - fprintf(stderr, "not the expected capacity, have %d and expects 10\n", ringbuffer_capacity(&ringBuffer)); + fprintf(stderr, "not the expected capacity, have %ld and expects 10\n", ringbuffer_capacity(&ringBuffer)); return -1; } fprintf(stderr, "ok\n"); @@ -213,7 +213,7 @@ int TestRingBuffer(int argc, char* argv[]) fprintf(stderr, "%d: specific overlaps test...", ++testNo); if (!test_overlaps()) { - fprintf(stderr, "ko\n", i); + fprintf(stderr, "ko\n"); return -1; } fprintf(stderr, "ok\n"); diff --git a/winpr/libwinpr/comm/test/TestCommConfig.c b/winpr/libwinpr/comm/test/TestCommConfig.c index 093c44e24..b60abd885 100644 --- a/winpr/libwinpr/comm/test/TestCommConfig.c +++ b/winpr/libwinpr/comm/test/TestCommConfig.c @@ -100,7 +100,7 @@ int TestCommConfig(int argc, char* argv[]) ZeroMemory(&commProp, sizeof(COMMPROP)); if (!GetCommProperties(hComm, &commProp)) { - fprintf(stderr, "GetCommProperties failure: GetLastError(): 0x0.8x\n", GetLastError()); + fprintf(stderr, "GetCommProperties failure: GetLastError(): 0x%0.8x\n", GetLastError()); return EXIT_FAILURE; } diff --git a/winpr/libwinpr/crt/alignment.c b/winpr/libwinpr/crt/alignment.c index 47bb88e89..a4b870f94 100644 --- a/winpr/libwinpr/crt/alignment.c +++ b/winpr/libwinpr/crt/alignment.c @@ -139,7 +139,6 @@ void* _aligned_offset_realloc(void* memblock, size_t size, size_t alignment, siz void* _aligned_offset_recalloc(void* memblock, size_t num, size_t size, size_t alignment, size_t offset) { - size_t copySize; void* newMemblock; WINPR_ALIGNED_MEM* pMem; WINPR_ALIGNED_MEM* pNewMem; From 352dbd52e2d34ddae4052254189e76f022846a38 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 23 Jul 2014 19:08:30 +0200 Subject: [PATCH 29/35] winpr/comm: don't build on apple Since code is only defined on linux building comm causes /usr/bin/ranlib to warn about empty objects and the test doesn't build at all on apple. --- winpr/libwinpr/comm/CMakeLists.txt | 32 ++++++++++++++++-------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/winpr/libwinpr/comm/CMakeLists.txt b/winpr/libwinpr/comm/CMakeLists.txt index 58ff2fe1d..0fe9f566f 100644 --- a/winpr/libwinpr/comm/CMakeLists.txt +++ b/winpr/libwinpr/comm/CMakeLists.txt @@ -18,21 +18,23 @@ set(MODULE_NAME "winpr-comm") set(MODULE_PREFIX "WINPR_COMM") -set(${MODULE_PREFIX}_SRCS - comm.c - comm.h - comm_io.c - comm_ioctl.c - comm_ioctl.h - comm_serial_sys.c - comm_serial_sys.h - comm_sercx_sys.c - comm_sercx_sys.h - comm_sercx2_sys.c - comm_sercx2_sys.h) +if(UNIX AND NOT WIN32 AND NOT APPLE) + set(${MODULE_PREFIX}_SRCS + comm.c + comm.h + comm_io.c + comm_ioctl.c + comm_ioctl.h + comm_serial_sys.c + comm_serial_sys.h + comm_sercx_sys.c + comm_sercx_sys.h + comm_sercx2_sys.c + comm_sercx2_sys.h) -winpr_module_add(${${MODULE_PREFIX}_SRCS}) + winpr_module_add(${${MODULE_PREFIX}_SRCS}) -if(BUILD_TESTING AND UNIX AND NOT WIN32) - add_subdirectory(test) + if(BUILD_TESTING) + add_subdirectory(test) + endif() endif() From a9eed46e38940ede5ad17b6e832557e60f6c6af2 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 23 Jul 2014 20:22:30 +0200 Subject: [PATCH 30/35] Fix warnings found in Xcode --- channels/cliprdr/client/cliprdr_main.c | 2 ++ libfreerdp/core/nego.c | 2 ++ winpr/libwinpr/synch/timer.c | 8 ++++++-- winpr/libwinpr/utils/trio/trio.c | 4 ++-- winpr/libwinpr/utils/trio/trionan.c | 3 ++- winpr/libwinpr/utils/trio/triostr.c | 3 ++- 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index 7a7907021..7eeaad6a9 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -36,6 +36,7 @@ #include "cliprdr_main.h" #include "cliprdr_format.h" +#ifdef WITH_DEBUG_CLIPRDR static const char* const CB_MSG_TYPE_STRINGS[] = { "", @@ -51,6 +52,7 @@ static const char* const CB_MSG_TYPE_STRINGS[] = "CB_LOCK_CLIPDATA" "CB_UNLOCK_CLIPDATA" }; +#endif CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr) { diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index 09d63065a..c10cd274f 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -32,6 +32,7 @@ #include "transport.h" +#ifdef WITH_DEBUG_NEGO static const char* const NEGO_STATE_STRINGS[] = { "NEGO_STATE_INITIAL", @@ -55,6 +56,7 @@ static const char PROTOCOL_SECURITY_STRINGS[9][4] = "UNK", "EXT" }; +#endif // WITH_DEBUG_NEGO BOOL nego_security_connect(rdpNego* nego); diff --git a/winpr/libwinpr/synch/timer.c b/winpr/libwinpr/synch/timer.c index 0f0c41572..f19f1366e 100644 --- a/winpr/libwinpr/synch/timer.c +++ b/winpr/libwinpr/synch/timer.c @@ -190,10 +190,14 @@ BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPerio { ULONG Type; PVOID Object; - int status = 0; WINPR_TIMER* timer; - LONGLONG seconds = 0; +#ifdef WITH_POSIX_TIMER + LONGLONG seconds = 0; LONGLONG nanoseconds = 0; +#ifdef HAVE_TIMERFD_H + int status = 0; +#endif // HAVE_TIMERFD_H +#endif // WITH_POSIX_TIMER if (!winpr_Handle_GetInfo(hTimer, &Type, &Object)) return FALSE; diff --git a/winpr/libwinpr/utils/trio/trio.c b/winpr/libwinpr/utils/trio/trio.c index 08b02240a..19cfdadd0 100644 --- a/winpr/libwinpr/utils/trio/trio.c +++ b/winpr/libwinpr/utils/trio/trio.c @@ -901,8 +901,8 @@ typedef struct _trio_userdef_t { * Internal Variables * *************************************************************************/ - -static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.131 2010/09/12 11:08:08 breese Exp $"; +/* Unused but kept for reference */ +/* static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.131 2010/09/12 11:08:08 breese Exp $"; */ #if TRIO_FEATURE_FLOAT /* diff --git a/winpr/libwinpr/utils/trio/trionan.c b/winpr/libwinpr/utils/trio/trionan.c index 301632257..d58246881 100644 --- a/winpr/libwinpr/utils/trio/trionan.c +++ b/winpr/libwinpr/utils/trio/trionan.c @@ -227,7 +227,8 @@ */ #if !defined(TRIO_EMBED_NAN) -static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $"; +/* Unused but kept for reference */ +/* static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $"; */ #endif #if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE) \ diff --git a/winpr/libwinpr/utils/trio/triostr.c b/winpr/libwinpr/utils/trio/triostr.c index c471b4a1d..4425bcd21 100644 --- a/winpr/libwinpr/utils/trio/triostr.c +++ b/winpr/libwinpr/utils/trio/triostr.c @@ -160,7 +160,8 @@ struct _trio_string_t */ #if !defined(TRIO_EMBED_STRING) -static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $"; +/* Unused but kept for reference */ +/* static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $"; */ #endif /************************************************************************* From a124f6a7c6aea9186fe36b3e7e9803ee5a811336 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 23 Jul 2014 23:53:43 +0200 Subject: [PATCH 31/35] fix comment style // to /* */ --- libfreerdp/codec/h264.c | 2 +- libfreerdp/core/nego.c | 2 +- winpr/libwinpr/synch/timer.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index 2546d9289..3ec637ebe 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -101,7 +101,7 @@ static UINT32 YUV_to_RGB(BYTE Y, BYTE U, BYTE V) return RGB32(R, G, B); } -#endif //WITH_OPENH264 +#endif /* WITH_OPENH264 */ #if USE_UPCONVERT static BYTE* convert_420_to_444(BYTE* chroma420, int chroma420Width, int chroma420Height, int chroma420Stride) diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index c10cd274f..8d385bf6d 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -56,7 +56,7 @@ static const char PROTOCOL_SECURITY_STRINGS[9][4] = "UNK", "EXT" }; -#endif // WITH_DEBUG_NEGO +#endif /* WITH_DEBUG_NEGO */ BOOL nego_security_connect(rdpNego* nego); diff --git a/winpr/libwinpr/synch/timer.c b/winpr/libwinpr/synch/timer.c index f19f1366e..3b715a74a 100644 --- a/winpr/libwinpr/synch/timer.c +++ b/winpr/libwinpr/synch/timer.c @@ -196,8 +196,8 @@ BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPerio LONGLONG nanoseconds = 0; #ifdef HAVE_TIMERFD_H int status = 0; -#endif // HAVE_TIMERFD_H -#endif // WITH_POSIX_TIMER +#endif /* HAVE_TIMERFD_H */ +#endif /* WITH_POSIX_TIMER */ if (!winpr_Handle_GetInfo(hTimer, &Type, &Object)) return FALSE; From a3de93d867db3695dc196e86a73779eecc884851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 28 Jul 2014 23:41:16 -0400 Subject: [PATCH 32/35] libfreerdp-codec: start parsing progressive codec --- client/X11/xf_gfx.c | 20 +++ client/X11/xfreerdp.h | 2 + include/freerdp/codec/progressive.h | 127 +++++++++++++++++++ libfreerdp/codec/progressive.c | 181 ++++++++++++++++++++++++++++ 4 files changed, 330 insertions(+) diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index bf04042f6..b99fd5e37 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -67,6 +67,14 @@ int xf_ResetGraphics(RdpgfxClientContext* context, RDPGFX_RESET_GRAPHICS_PDU* re xfc->h264 = h264_context_new(FALSE); + if (xfc->progressive) + { + progressive_context_free(xfc->progressive); + xfc->progressive = NULL; + } + + xfc->progressive = progressive_context_new(TRUE); + region16_init(&(xfc->invalidRegion)); xfc->graphicsReset = TRUE; @@ -470,6 +478,7 @@ int xf_SurfaceCommand_Alpha(xfContext* xfc, RdpgfxClientContext* context, RDPGFX int xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status = 0; + BYTE* DstData = NULL; xfGfxSurface* surface; RECTANGLE_16 invalidRect; @@ -478,6 +487,17 @@ int xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, if (!surface) return -1; + DstData = surface->data; + + status = progressive_decompress(xfc->progressive, cmd->data, cmd->length, &DstData, + PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height); + + if (status < 0) + { + printf("progressive_decompress failure: %d\n", status); + return -1; + } + printf("xf_SurfaceCommand_Progressive: status: %d\n", status); /* fill with blue for now to distinguish from the rest */ diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index d0a8e3cfb..6a4718d35 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -35,6 +35,7 @@ typedef struct xf_context xfContext; #include #include #include +#include #include struct xf_WorkArea @@ -155,6 +156,7 @@ struct xf_context NSC_CONTEXT* nsc; CLEAR_CONTEXT* clear; H264_CONTEXT* h264; + PROGRESSIVE_CONTEXT* progressive; void* xv_context; void* clipboard_context; diff --git a/include/freerdp/codec/progressive.h b/include/freerdp/codec/progressive.h index 016bc7412..be063aadd 100644 --- a/include/freerdp/codec/progressive.h +++ b/include/freerdp/codec/progressive.h @@ -23,8 +23,135 @@ #include #include +#include #include +#define PROGRESSIVE_WBT_SYNC 0xCCC0 +#define PROGRESSIVE_WBT_FRAME_BEGIN 0xCCC1 +#define PROGRESSIVE_WBT_FRAME_END 0xCCC2 +#define PROGRESSIVE_WBT_CONTEXT 0xCCC3 +#define PROGRESSIVE_WBT_REGION 0xCCC4 +#define PROGRESSIVE_WBT_TILE_SIMPLE 0xCCC5 +#define PROGRESSIVE_WBT_TILE_PROGRESSIVE_FIRST 0xCCC6 +#define PROGRESSIVE_WBT_TILE_PROGRESSIVE_UPGRADE 0xCCC7 + +struct _PROGRESSIVE_SYNC +{ + UINT16 blockType; + UINT32 blockLen; + + UINT32 magic; + UINT16 version; +}; +typedef struct _PROGRESSIVE_SYNC PROGRESSIVE_SYNC; + +struct _PROGRESSIVE_REGION +{ + UINT16 blockType; + UINT32 blockLen; + + BYTE tileSize; + UINT16 numRects; + BYTE numQuant; + BYTE numProgQuant; + BYTE flags; + UINT16 numTiles; + UINT32 tileDataSize; + RFX_RECT* rects; + UINT32* quantVals; + UINT32* quantProgVals; +}; +typedef struct _PROGRESSIVE_REGION PROGRESSIVE_REGION; + +struct _PROGRESSIVE_FRAME_BEGIN +{ + UINT16 blockType; + UINT32 blockLen; + + UINT32 frameIndex; + UINT16 regionCount; + PROGRESSIVE_REGION* regions; +}; +typedef struct _PROGRESSIVE_FRAME_BEGIN PROGRESSIVE_FRAME_BEGIN; + +struct _PROGRESSIVE_FRAME_END +{ + UINT16 blockType; + UINT32 blockLen; +}; +typedef struct _PROGRESSIVE_FRAME_END PROGRESSIVE_FRAME_END; + +struct _PROGRESSIVE_TILE_SIMPLE +{ + UINT16 blockType; + UINT32 blockLen; + + BYTE quantIdxY; + BYTE quantIdxCb; + BYTE quantIdxCr; + UINT16 xIdx; + UINT16 yIdx; + BYTE flags; + UINT16 yLen; + UINT16 cbLen; + UINT16 crLen; + UINT16 tailLen; + BYTE* yData; + BYTE* cbData; + BYTE* crData; + BYTE* tailData; +}; +typedef struct _PROGRESSIVE_TILE_SIMPLE PROGRESSIVE_TILE_SIMPLE; + +struct _PROGRESSIVE_TILE_FIRST +{ + UINT16 blockType; + UINT32 blockLen; + + BYTE quantIdxY; + BYTE quantIdxCb; + BYTE quantIdxCr; + UINT16 xIdx; + UINT16 yIdx; + BYTE flags; + BYTE quality; + UINT16 yLen; + UINT16 cbLen; + UINT16 crLen; + UINT16 tailLen; + BYTE* yData; + BYTE* cbData; + BYTE* crData; + BYTE* tailData; +}; +typedef struct _PROGRESSIVE_TILE_FIRST PROGRESSIVE_TILE_FIRST; + +struct _PROGRESSIVE_TILE_UPGRADE +{ + UINT16 blockType; + UINT32 blockLen; + + BYTE quantIdxY; + BYTE quantIdxCb; + BYTE quantIdxCr; + UINT16 xIdx; + UINT16 yIdx; + BYTE quality; + UINT16 ySrlLen; + UINT16 yRawLen; + UINT16 cbSrlLen; + UINT16 cbRawLen; + UINT16 crSrlLen; + UINT16 crRawLen; + BYTE* ySrlData; + BYTE* yRawData; + BYTE* cbSrlData; + BYTE* cbRawData; + BYTE* crSrlData; + BYTE* crRawData; +}; +typedef struct _PROGRESSIVE_TILE_UPGRADE PROGRESSIVE_TILE_UPGRADE; + struct _PROGRESSIVE_CONTEXT { BOOL Compressor; diff --git a/libfreerdp/codec/progressive.c b/libfreerdp/codec/progressive.c index 4b798065c..2dfee8460 100644 --- a/libfreerdp/codec/progressive.c +++ b/libfreerdp/codec/progressive.c @@ -31,6 +31,187 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight) { + BYTE* block; + UINT32 boffset; + UINT32 ctxId; + UINT32 flags; + UINT32 tileSize; + UINT32 magic; + UINT32 version; + UINT16 blockType; + UINT32 blockLen; + UINT32 offset = 0; + UINT32 frameIndex; + UINT32 regionCount; + PROGRESSIVE_REGION region; + PROGRESSIVE_TILE_SIMPLE simple; + PROGRESSIVE_TILE_FIRST first; + PROGRESSIVE_TILE_UPGRADE upgrade; + + printf("ProgressiveDecompress\n"); + + while ((SrcSize - offset) > 6) + { + boffset = 0; + block = &pSrcData[offset]; + + blockType = *((UINT16*) &block[boffset]); /* blockType (2 bytes) */ + blockLen = *((UINT32*) &block[boffset + 2]); /* blockLen (4 bytes) */ + boffset += 6; + + switch (blockType) + { + case PROGRESSIVE_WBT_SYNC: + + if (blockLen != 12) + return -1; + + magic = (UINT32) *((UINT32*) &block[boffset]); /* magic (4 bytes) */ + version = (UINT32) *((UINT16*) &block[boffset + 4]); /* version (2 bytes) */ + boffset += 6; + + break; + + case PROGRESSIVE_WBT_FRAME_BEGIN: + + frameIndex = (UINT32) *((UINT32*) &block[boffset]); /* frameIndex (4 bytes) */ + regionCount = (UINT32) *((UINT16*) &block[boffset + 4]); /* regionCount (2 bytes) */ + boffset += 6; + + break; + + case PROGRESSIVE_WBT_FRAME_END: + + if (blockLen != 6) + return -1; + + break; + + case PROGRESSIVE_WBT_CONTEXT: + + if (blockLen != 10) + return -1; + + ctxId = (UINT32) block[boffset]; /* ctxId (1 byte) */ + tileSize = (UINT32) *((UINT16*) &block[boffset + 1]); /* tileSize (2 bytes) */ + flags = (UINT32) block[boffset + 3]; /* flags (1 byte) */ + boffset += 4; + + if (tileSize != 64) + return -1; + + break; + + case PROGRESSIVE_WBT_REGION: + + region.tileSize = block[boffset]; /* tileSize (1 byte) */ + region.numRects = *((UINT16*) &block[boffset + 1]); /* numRects (2 bytes) */ + region.numQuant = block[boffset + 3]; /* numQuant (1 byte) */ + region.numProgQuant = block[boffset + 4]; /* numProgQuant (1 byte) */ + region.flags = block[boffset + 5]; /* flags (1 byte) */ + region.numTiles = *((UINT16*) &block[boffset + 6]); /* numTiles (2 bytes) */ + region.tileDataSize = *((UINT32*) &block[boffset + 8]); /* tileDataSize (4 bytes) */ + boffset += 12; + + break; + + case PROGRESSIVE_WBT_TILE_SIMPLE: + + simple.quantIdxY = block[boffset]; /* quantIdxY (1 byte) */ + simple.quantIdxCb = block[boffset + 1]; /* quantIdxCb (1 byte) */ + simple.quantIdxCr = block[boffset + 2]; /* quantIdxCr (1 byte) */ + simple.xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */ + simple.yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */ + simple.flags = block[boffset + 7]; /* flags (1 byte) */ + simple.yLen = *((UINT16*) &block[boffset + 8]); /* yLen (2 bytes) */ + simple.cbLen = *((UINT16*) &block[boffset + 10]); /* cbLen (2 bytes) */ + simple.crLen = *((UINT16*) &block[boffset + 12]); /* crLen (2 bytes) */ + simple.tailLen = *((UINT16*) &block[boffset + 14]); /* tailLen (2 bytes) */ + boffset += 16; + + simple.yData = &block[boffset]; + boffset += simple.yLen; + + simple.cbData = &block[boffset]; + boffset += simple.cbLen; + + simple.crData = &block[boffset]; + boffset += simple.crLen; + + simple.tailData = &block[boffset]; + boffset += simple.tailLen; + + break; + + case PROGRESSIVE_WBT_TILE_PROGRESSIVE_FIRST: + + first.quantIdxY = block[boffset]; /* quantIdxY (1 byte) */ + first.quantIdxCb = block[boffset + 1]; /* quantIdxCb (1 byte) */ + first.quantIdxCr = block[boffset + 2]; /* quantIdxCr (1 byte) */ + first.xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */ + first.yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */ + first.flags = block[boffset + 7]; /* flags (1 byte) */ + first.quality = block[boffset + 8]; /* quality (1 byte) */ + first.yLen = *((UINT16*) &block[boffset + 9]); /* yLen (2 bytes) */ + first.cbLen = *((UINT16*) &block[boffset + 11]); /* cbLen (2 bytes) */ + first.crLen = *((UINT16*) &block[boffset + 13]); /* crLen (2 bytes) */ + first.tailLen = *((UINT16*) &block[boffset + 15]); /* tailLen (2 bytes) */ + boffset += 17; + + first.yData = &block[boffset]; + boffset += first.yLen; + + first.cbData = &block[boffset]; + boffset += first.cbLen; + + first.crData = &block[boffset]; + boffset += first.crLen; + + first.tailData = &block[boffset]; + boffset += first.tailLen; + + break; + + case PROGRESSIVE_WBT_TILE_PROGRESSIVE_UPGRADE: + + upgrade.quantIdxY = block[boffset]; /* quantIdxY (1 byte) */ + upgrade.quantIdxCb = block[boffset + 1]; /* quantIdxCb (1 byte) */ + upgrade.quantIdxCr = block[boffset + 2]; /* quantIdxCr (1 byte) */ + upgrade.xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */ + upgrade.yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */ + upgrade.quality = block[boffset + 7]; /* quality (1 byte) */ + upgrade.ySrlLen = *((UINT16*) &block[boffset + 8]); /* ySrlLen (2 bytes) */ + upgrade.yRawLen = *((UINT16*) &block[boffset + 10]); /* yRawLen (2 bytes) */ + upgrade.cbSrlLen = *((UINT16*) &block[boffset + 12]); /* cbSrlLen (2 bytes) */ + upgrade.cbRawLen = *((UINT16*) &block[boffset + 14]); /* cbRawLen (2 bytes) */ + upgrade.crSrlLen = *((UINT16*) &block[boffset + 16]); /* crSrlLen (2 bytes) */ + upgrade.crRawLen = *((UINT16*) &block[boffset + 18]); /* crRawLen (2 bytes) */ + boffset += 18; + + upgrade.ySrlData = &block[boffset]; + boffset += upgrade.ySrlLen; + + upgrade.yRawData = &block[boffset]; + boffset += upgrade.yRawLen; + + upgrade.cbSrlData = &block[boffset]; + boffset += upgrade.cbSrlLen; + + upgrade.cbRawData = &block[boffset]; + boffset += upgrade.cbRawLen; + + upgrade.crSrlData = &block[boffset]; + boffset += upgrade.crSrlLen; + + upgrade.crRawData = &block[boffset]; + boffset += upgrade.crRawLen; + + break; + } + + offset += blockLen; + } + return 1; } From c060fb07a2dd1927277eb0645434e00ca9689dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 29 Jul 2014 13:41:21 -0400 Subject: [PATCH 33/35] libfreerdp-codec: fix build on Windows --- libfreerdp/codec/h264.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index c0672df68..c2fbedf10 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -160,7 +160,7 @@ static void h264_dump_h264_data(BYTE* data, int size) FILE* fp; char buf[4096]; - snprintf(buf, sizeof(buf), "/tmp/wlog/bs_%d.h264", g_H264FrameId); + sprintf_s(buf, sizeof(buf), "/tmp/wlog/bs_%d.h264", g_H264FrameId); fp = fopen(buf, "wb"); fwrite(data, 1, size, fp); fflush(fp); @@ -174,10 +174,10 @@ void h264_dump_yuv_data(BYTE* yuv[], int width, int height, int stride[]) char buf[4096]; int j; - snprintf(buf, sizeof(buf), "/tmp/wlog/H264_%d.ppm", g_H264FrameId); + sprintf_s(buf, sizeof(buf), "/tmp/wlog/H264_%d.ppm", g_H264FrameId); fp = fopen(buf, "wb"); fwrite("P5\n", 1, 3, fp); - snprintf(buf, sizeof(buf), "%d %d\n", width, height); + sprintf_s(buf, sizeof(buf), "%d %d\n", width, height); fwrite(buf, 1, strlen(buf), fp); fwrite("255\n", 1, 4, fp); From b05c43c6020f3237d943df0a5584da19fb767c4e Mon Sep 17 00:00:00 2001 From: Robert Lockwood Date: Tue, 29 Jul 2014 23:30:47 +0100 Subject: [PATCH 34/35] rdpsnd->Initialize requires two arguments Fixes rdpsnd->Initialize() to have two arguments. Fixes compilation on XCode 5. To be tested. --- server/Mac/mf_rdpsnd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/Mac/mf_rdpsnd.c b/server/Mac/mf_rdpsnd.c index 3333795af..e99d3eb38 100644 --- a/server/Mac/mf_rdpsnd.c +++ b/server/Mac/mf_rdpsnd.c @@ -161,7 +161,7 @@ BOOL mf_peer_rdpsnd_init(mfPeerContext* context) context->rdpsnd->Activated = mf_peer_rdpsnd_activated; - context->rdpsnd->Initialize(context->rdpsnd); + context->rdpsnd->Initialize(context->rdpsnd, TRUE); return TRUE; } From 9bde12f26a218cb18398da2b33ff6563d0465183 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Thu, 31 Jul 2014 11:22:46 +0200 Subject: [PATCH 35/35] winpr/utils/ssl: fix comp warning and wrong param --- winpr/libwinpr/utils/ssl.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/winpr/libwinpr/utils/ssl.c b/winpr/libwinpr/utils/ssl.c index 2a0463977..add22b12b 100644 --- a/winpr/libwinpr/utils/ssl.c +++ b/winpr/libwinpr/utils/ssl.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,7 @@ struct CRYPTO_dynlock_value #if (OPENSSL_VERSION_NUMBER < 0x10000000L) -static unsigned long _winpr_openssl_id() +static unsigned long _winpr_openssl_id(void) { return (unsigned long)GetCurrentThreadId(); } @@ -84,7 +85,7 @@ static void _winpr_openssl_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock, free(dynlock); } -static BOOL _winpr_openssl_initialize_locking() +static BOOL _winpr_openssl_initialize_locking(void) { int i, count; @@ -159,7 +160,7 @@ static BOOL _winpr_openssl_initialize_locking() return TRUE; } -static BOOL _winpr_openssl_cleanup_locking() +static BOOL _winpr_openssl_cleanup_locking(void) { /* undo our static locking modifications */ @@ -219,7 +220,7 @@ static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVO if (flags & WINPR_SSL_INIT_ENABLE_LOCKING) { - if (!_winpr_openssl_initialize_locking(FALSE)) + if (!_winpr_openssl_initialize_locking()) { return FALSE; }