Milestone 5: deliver embedded RDP sessions and lifecycle hardening

This commit is contained in:
Keith Smith
2026-03-03 18:59:26 -07:00
parent 230a401386
commit 36006bd4aa
2941 changed files with 724359 additions and 77 deletions

View File

@@ -0,0 +1,26 @@
# FreeRDP: A Remote Desktop Protocol Implementation
# FreeRDP cmake build script
#
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
#
# 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.
define_channel("rdpgfx")
if(WITH_CLIENT_CHANNELS)
add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME})
endif()
if(WITH_SERVER_CHANNELS)
add_channel_server(${MODULE_PREFIX} ${CHANNEL_NAME})
endif()

View File

@@ -0,0 +1,20 @@
set(OPTION_DEFAULT ON)
set(OPTION_CLIENT_DEFAULT ON)
set(OPTION_SERVER_DEFAULT ON)
define_channel_options(
NAME
"rdpgfx"
TYPE
"dynamic"
DESCRIPTION
"Graphics Pipeline Extension"
SPECIFICATIONS
"[MS-RDPEGFX]"
DEFAULT
${OPTION_DEFAULT}
CLIENT_DEFAULT
${OPTION_CLIENT_DEFAULT}
SERVER_DEFAULT
${OPTION_SERVER_DEFAULT}
)

View File

@@ -0,0 +1,27 @@
# FreeRDP: A Remote Desktop Protocol Implementation
# FreeRDP cmake build script
#
# Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
#
# 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.
define_channel_client("rdpgfx")
set(${MODULE_PREFIX}_SRCS rdpgfx_main.c rdpgfx_main.h rdpgfx_codec.c rdpgfx_codec.h ../rdpgfx_common.c
../rdpgfx_common.h
)
set(${MODULE_PREFIX}_LIBS winpr freerdp)
include_directories(..)
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "DVCPluginEntry")

View File

@@ -0,0 +1,305 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Graphics Pipeline Extension
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
*
* 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 <freerdp/config.h>
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <freerdp/log.h>
#include <freerdp/utils/profiler.h>
#include "rdpgfx_common.h"
#include "rdpgfx_codec.h"
#define TAG CHANNELS_TAG("rdpgfx.client")
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpgfx_read_h264_metablock(WINPR_ATTR_UNUSED RDPGFX_PLUGIN* gfx, wStream* s,
RDPGFX_H264_METABLOCK* meta)
{
RECTANGLE_16* regionRect = nullptr;
RDPGFX_H264_QUANT_QUALITY* quantQualityVal = nullptr;
UINT error = ERROR_INVALID_DATA;
meta->regionRects = nullptr;
meta->quantQualityVals = nullptr;
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
goto error_out;
Stream_Read_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */
if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, meta->numRegionRects, 8ull))
goto error_out;
meta->regionRects = (RECTANGLE_16*)calloc(meta->numRegionRects, sizeof(RECTANGLE_16));
if (!meta->regionRects)
{
WLog_ERR(TAG, "malloc failed!");
error = CHANNEL_RC_NO_MEMORY;
goto error_out;
}
meta->quantQualityVals =
(RDPGFX_H264_QUANT_QUALITY*)calloc(meta->numRegionRects, sizeof(RDPGFX_H264_QUANT_QUALITY));
if (!meta->quantQualityVals)
{
WLog_ERR(TAG, "malloc failed!");
error = CHANNEL_RC_NO_MEMORY;
goto error_out;
}
WLog_DBG(TAG, "H264_METABLOCK: numRegionRects: %" PRIu32 "", meta->numRegionRects);
for (UINT32 index = 0; index < meta->numRegionRects; index++)
{
regionRect = &(meta->regionRects[index]);
if ((error = rdpgfx_read_rect16(s, regionRect)))
{
WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %" PRIu32 "!", error);
goto error_out;
}
WLog_DBG(TAG,
"regionRects[%" PRIu32 "]: left: %" PRIu16 " top: %" PRIu16 " right: %" PRIu16
" bottom: %" PRIu16 "",
index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom);
}
if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, meta->numRegionRects, 2ull))
{
error = ERROR_INVALID_DATA;
goto error_out;
}
for (UINT32 index = 0; index < meta->numRegionRects; index++)
{
quantQualityVal = &(meta->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;
WLog_DBG(TAG,
"quantQualityVals[%" PRIu32 "]: qp: %" PRIu8 " r: %" PRIu8 " p: %" PRIu8
" qualityVal: %" PRIu8 "",
index, quantQualityVal->qp, quantQualityVal->r, quantQualityVal->p,
quantQualityVal->qualityVal);
}
return CHANNEL_RC_OK;
error_out:
free_h264_metablock(meta);
return error;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpgfx_decode_AVC420(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd)
{
UINT error = 0;
RDPGFX_AVC420_BITMAP_STREAM h264 = WINPR_C_ARRAY_INIT;
RdpgfxClientContext* context = gfx->context;
wStream* s = Stream_New(cmd->data, cmd->length);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
return CHANNEL_RC_NO_MEMORY;
}
if ((error = rdpgfx_read_h264_metablock(gfx, s, &(h264.meta))))
{
Stream_Free(s, FALSE);
WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %" PRIu32 "!", error);
return error;
}
h264.data = Stream_Pointer(s);
h264.length = (UINT32)Stream_GetRemainingLength(s);
Stream_Free(s, FALSE);
cmd->extra = (void*)&h264;
if (context)
{
IFCALLRET(context->SurfaceCommand, error, context, cmd);
if (error)
WLog_ERR(TAG, "context->SurfaceCommand failed with error %" PRIu32 "", error);
}
free_h264_metablock(&h264.meta);
cmd->extra = nullptr;
return error;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpgfx_decode_AVC444(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd)
{
UINT error = 0;
UINT32 tmp = 0;
size_t pos1 = 0;
size_t pos2 = 0;
RDPGFX_AVC444_BITMAP_STREAM h264 = WINPR_C_ARRAY_INIT;
RdpgfxClientContext* context = gfx->context;
wStream* s = Stream_New(cmd->data, cmd->length);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
return CHANNEL_RC_NO_MEMORY;
}
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
{
error = ERROR_INVALID_DATA;
goto fail;
}
Stream_Read_UINT32(s, tmp);
h264.cbAvc420EncodedBitstream1 = tmp & 0x3FFFFFFFUL;
h264.LC = (tmp >> 30UL) & 0x03UL;
if (h264.LC == 0x03)
{
error = ERROR_INVALID_DATA;
goto fail;
}
pos1 = Stream_GetPosition(s);
if ((error = rdpgfx_read_h264_metablock(gfx, s, &(h264.bitstream[0].meta))))
{
WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %" PRIu32 "!", error);
goto fail;
}
pos2 = Stream_GetPosition(s);
h264.bitstream[0].data = Stream_Pointer(s);
if (h264.LC == 0)
{
const size_t bitstreamLen = 1ULL * h264.cbAvc420EncodedBitstream1 - pos2 + pos1;
if ((bitstreamLen > UINT32_MAX) || !Stream_CheckAndLogRequiredLength(TAG, s, bitstreamLen))
{
error = ERROR_INVALID_DATA;
goto fail;
}
h264.bitstream[0].length = (UINT32)bitstreamLen;
Stream_Seek(s, bitstreamLen);
if ((error = rdpgfx_read_h264_metablock(gfx, s, &(h264.bitstream[1].meta))))
{
WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %" PRIu32 "!", error);
goto fail;
}
h264.bitstream[1].data = Stream_Pointer(s);
const size_t len = Stream_GetRemainingLength(s);
if (len > UINT32_MAX)
goto fail;
h264.bitstream[1].length = (UINT32)len;
}
else
{
const size_t len = Stream_GetRemainingLength(s);
if (len > UINT32_MAX)
goto fail;
h264.bitstream[0].length = (UINT32)len;
}
cmd->extra = (void*)&h264;
if (context)
{
IFCALLRET(context->SurfaceCommand, error, context, cmd);
if (error)
WLog_ERR(TAG, "context->SurfaceCommand failed with error %" PRIu32 "", error);
}
fail:
Stream_Free(s, FALSE);
free_h264_metablock(&h264.bitstream[0].meta);
free_h264_metablock(&h264.bitstream[1].meta);
cmd->extra = nullptr;
return error;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd)
{
UINT error = CHANNEL_RC_OK;
RdpgfxClientContext* context = gfx->context;
PROFILER_ENTER(context->SurfaceProfiler)
switch (cmd->codecId)
{
case RDPGFX_CODECID_AVC420:
if ((error = rdpgfx_decode_AVC420(gfx, cmd)))
WLog_ERR(TAG, "rdpgfx_decode_AVC420 failed with error %" PRIu32 "", error);
break;
case RDPGFX_CODECID_AVC444:
case RDPGFX_CODECID_AVC444v2:
if ((error = rdpgfx_decode_AVC444(gfx, cmd)))
WLog_ERR(TAG, "rdpgfx_decode_AVC444 failed with error %" PRIu32 "", error);
break;
default:
if (context)
{
IFCALLRET(context->SurfaceCommand, error, context, cmd);
if (error)
WLog_ERR(TAG, "context->SurfaceCommand failed with error %" PRIu32 "", error);
}
break;
}
PROFILER_EXIT(context->SurfaceProfiler)
return error;
}

View File

@@ -0,0 +1,36 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Graphics Pipeline Extension
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
*
* 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_CHANNEL_RDPGFX_CLIENT_CODEC_H
#define FREERDP_CHANNEL_RDPGFX_CLIENT_CODEC_H
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <freerdp/channels/rdpgfx.h>
#include <freerdp/api.h>
#include "rdpgfx_main.h"
WINPR_ATTR_NODISCARD
FREERDP_LOCAL UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd);
#endif /* FREERDP_CHANNEL_RDPGFX_CLIENT_CODEC_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,61 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Graphics Pipeline Extension
*
* Copyright 2013-2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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_CHANNEL_RDPGFX_CLIENT_MAIN_H
#define FREERDP_CHANNEL_RDPGFX_CLIENT_MAIN_H
#include <freerdp/dvc.h>
#include <freerdp/types.h>
#include <freerdp/addin.h>
#include <winpr/wlog.h>
#include <winpr/collections.h>
#include <freerdp/client/channels.h>
#include <freerdp/client/rdpgfx.h>
#include <freerdp/channels/log.h>
#include <freerdp/codec/zgfx.h>
#include <freerdp/cache/persistent.h>
#include <freerdp/freerdp.h>
typedef struct
{
GENERIC_DYNVC_PLUGIN base;
ZGFX_CONTEXT* zgfx;
UINT32 UnacknowledgedFrames;
UINT32 TotalDecodedFrames;
UINT64 StartDecodingTime;
BOOL suspendFrameAcks;
BOOL sendFrameAcks;
wHashTable* SurfaceTable;
UINT16 MaxCacheSlots;
void* CacheSlots[25600];
rdpPersistentCache* persistent;
rdpContext* rdpcontext;
wLog* log;
RDPGFX_CAPSET ConnectionCaps;
RdpgfxClientContext* context;
} RDPGFX_PLUGIN;
#endif /* FREERDP_CHANNEL_RDPGFX_CLIENT_MAIN_H */

View File

@@ -0,0 +1,197 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Graphics Pipeline Extension
*
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
*
* 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 <freerdp/config.h>
#include <winpr/crt.h>
#include <winpr/assert.h>
#include <winpr/stream.h>
#include <freerdp/channels/log.h>
#define TAG CHANNELS_TAG("rdpgfx.common")
#include "rdpgfx_common.h"
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header)
{
WINPR_ASSERT(s);
WINPR_ASSERT(header);
if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
return CHANNEL_RC_NO_MEMORY;
Stream_Read_UINT16(s, header->cmdId); /* cmdId (2 bytes) */
Stream_Read_UINT16(s, header->flags); /* flags (2 bytes) */
Stream_Read_UINT32(s, header->pduLength); /* pduLength (4 bytes) */
if (header->pduLength < 8)
{
WLog_ERR(TAG, "header->pduLength %u less than 8!", header->pduLength);
return ERROR_INVALID_DATA;
}
if (!Stream_CheckAndLogRequiredLength(TAG, s, (header->pduLength - 8)))
return ERROR_INVALID_DATA;
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpgfx_write_header(wStream* s, const RDPGFX_HEADER* header)
{
WINPR_ASSERT(s);
WINPR_ASSERT(header);
if (!Stream_EnsureRemainingCapacity(s, 8))
return CHANNEL_RC_NO_MEMORY;
Stream_Write_UINT16(s, header->cmdId); /* cmdId (2 bytes) */
Stream_Write_UINT16(s, header->flags); /* flags (2 bytes) */
Stream_Write_UINT32(s, header->pduLength); /* pduLength (4 bytes) */
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* pt16)
{
WINPR_ASSERT(s);
WINPR_ASSERT(pt16);
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, pt16->x); /* x (2 bytes) */
Stream_Read_UINT16(s, pt16->y); /* y (2 bytes) */
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpgfx_write_point16(wStream* s, const RDPGFX_POINT16* point16)
{
WINPR_ASSERT(s);
WINPR_ASSERT(point16);
if (!Stream_EnsureRemainingCapacity(s, 4))
return CHANNEL_RC_NO_MEMORY;
Stream_Write_UINT16(s, point16->x); /* x (2 bytes) */
Stream_Write_UINT16(s, point16->y); /* y (2 bytes) */
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpgfx_read_rect16(wStream* s, RECTANGLE_16* rect16)
{
WINPR_ASSERT(s);
WINPR_ASSERT(rect16);
if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
return ERROR_INVALID_DATA;
Stream_Read_UINT16(s, rect16->left); /* left (2 bytes) */
Stream_Read_UINT16(s, rect16->top); /* top (2 bytes) */
Stream_Read_UINT16(s, rect16->right); /* right (2 bytes) */
Stream_Read_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
if (rect16->left >= rect16->right)
return ERROR_INVALID_DATA;
if (rect16->top >= rect16->bottom)
return ERROR_INVALID_DATA;
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpgfx_write_rect16(wStream* s, const RECTANGLE_16* rect16)
{
WINPR_ASSERT(s);
WINPR_ASSERT(rect16);
if (!Stream_EnsureRemainingCapacity(s, 8))
return CHANNEL_RC_NO_MEMORY;
Stream_Write_UINT16(s, rect16->left); /* left (2 bytes) */
Stream_Write_UINT16(s, rect16->top); /* top (2 bytes) */
Stream_Write_UINT16(s, rect16->right); /* right (2 bytes) */
Stream_Write_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32)
{
WINPR_ASSERT(s);
WINPR_ASSERT(color32);
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
return ERROR_INVALID_DATA;
Stream_Read_UINT8(s, color32->B); /* B (1 byte) */
Stream_Read_UINT8(s, color32->G); /* G (1 byte) */
Stream_Read_UINT8(s, color32->R); /* R (1 byte) */
Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpgfx_write_color32(wStream* s, const RDPGFX_COLOR32* color32)
{
WINPR_ASSERT(s);
WINPR_ASSERT(color32);
if (!Stream_EnsureRemainingCapacity(s, 4))
return CHANNEL_RC_NO_MEMORY;
Stream_Write_UINT8(s, color32->B); /* B (1 byte) */
Stream_Write_UINT8(s, color32->G); /* G (1 byte) */
Stream_Write_UINT8(s, color32->R); /* R (1 byte) */
Stream_Write_UINT8(s, color32->XA); /* XA (1 byte) */
return CHANNEL_RC_OK;
}

View File

@@ -0,0 +1,66 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Graphics Pipeline Extension
*
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
*
* 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_CHANNEL_RDPGFX_COMMON_H
#define FREERDP_CHANNEL_RDPGFX_COMMON_H
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <freerdp/config.h>
#include <freerdp/channels/rdpgfx.h>
#include <freerdp/api.h>
#include <freerdp/utils/gfx.h>
WINPR_ATTR_NODISCARD
FREERDP_LOCAL UINT rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header);
WINPR_ATTR_NODISCARD
FREERDP_LOCAL UINT rdpgfx_write_header(wStream* s, const RDPGFX_HEADER* header);
WINPR_ATTR_NODISCARD
FREERDP_LOCAL UINT rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* pt16);
WINPR_ATTR_NODISCARD
FREERDP_LOCAL UINT rdpgfx_write_point16(wStream* s, const RDPGFX_POINT16* point16);
WINPR_ATTR_NODISCARD
FREERDP_LOCAL UINT rdpgfx_read_rect16(wStream* s, RECTANGLE_16* rect16);
WINPR_ATTR_NODISCARD
FREERDP_LOCAL UINT rdpgfx_write_rect16(wStream* s, const RECTANGLE_16* rect16);
WINPR_ATTR_NODISCARD
FREERDP_LOCAL UINT rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32);
WINPR_ATTR_NODISCARD
FREERDP_LOCAL UINT rdpgfx_write_color32(wStream* s, const RDPGFX_COLOR32* color32);
#ifdef WITH_DEBUG_RDPGFX
#define DEBUG_RDPGFX(_LOGGER, ...) WLog_Print(_LOGGER, WLOG_DEBUG, __VA_ARGS__)
#else
#define DEBUG_RDPGFX(_LOGGER, ...) \
do \
{ \
} while (0)
#endif
#endif /* FREERDP_CHANNEL_RDPGFX_COMMON_H */

View File

@@ -0,0 +1,26 @@
# FreeRDP: A Remote Desktop Protocol Implementation
# FreeRDP cmake build script
#
# Copyright 2016 Jiang Zihao <zihao.jiang@yahoo.com>
#
# 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.
define_channel_server("rdpgfx")
set(${MODULE_PREFIX}_SRCS rdpgfx_main.c rdpgfx_main.h ../rdpgfx_common.c ../rdpgfx_common.h)
set(${MODULE_PREFIX}_LIBS freerdp)
include_directories(..)
add_channel_server_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "DVCPluginEntry")

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Graphics Pipeline Extension
*
* Copyright 2016 Jiang Zihao <zihao.jiang@yahoo.com>
*
* 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_CHANNEL_RDPGFX_SERVER_MAIN_H
#define FREERDP_CHANNEL_RDPGFX_SERVER_MAIN_H
#include <freerdp/server/rdpgfx.h>
#include <freerdp/codec/zgfx.h>
struct s_rdpgfx_server_private
{
ZGFX_CONTEXT* zgfx;
BOOL ownThread;
HANDLE thread;
HANDLE stopEvent;
HANDLE channelEvent;
void* rdpgfx_channel;
DWORD SessionId;
wStream* input_stream;
BOOL isOpened;
BOOL isReady;
wLog* log;
RDPGFX_CAPSET activeCapSet;
};
#endif /* FREERDP_CHANNEL_RDPGFX_SERVER_MAIN_H */