diff --git a/channels/rdpgfx/server/rdpgfx_main.c b/channels/rdpgfx/server/rdpgfx_main.c index 547b41758..fbcf56b12 100644 --- a/channels/rdpgfx/server/rdpgfx_main.c +++ b/channels/rdpgfx/server/rdpgfx_main.c @@ -54,15 +54,14 @@ static INLINE UINT32 rdpgfx_pdu_length(UINT32 dataLen) return RDPGFX_HEADER_SIZE + dataLen; } -static INLINE UINT rdpgfx_server_packet_init_header(wStream* s, UINT16 cmdId, UINT32 pduLength) +static INLINE UINT rdpgfx_server_packet_init_header(wStream* s, + UINT16 cmdId, UINT32 pduLength) { RDPGFX_HEADER header; - header.flags = 0; header.cmdId = cmdId; header.pduLength = pduLength; - - /* Write header. Note that actual length might be changed + /* Write header. Note that actual length might be changed * after the entire packet has been constructed. */ return rdpgfx_write_header(s, &header); } @@ -77,7 +76,6 @@ static INLINE UINT rdpgfx_server_packet_init_header(wStream* s, UINT16 cmdId, UI static INLINE void rdpgfx_server_packet_complete_header(wStream* s, size_t start) { size_t current = Stream_GetPosition(s); - /* Fill actual length */ Stream_SetPosition(s, start + RDPGFX_HEADER_SIZE - sizeof(UINT32)); Stream_Write_UINT32(s, current - start); /* pduLength (4 bytes) */ @@ -86,7 +84,7 @@ static INLINE void rdpgfx_server_packet_complete_header(wStream* s, size_t start /** * Function description - * Send the stream for rdpgfx server packet. + * Send the stream for rdpgfx server packet. * The packet would be compressed according to [MS-RDPEGFX]. * * @return 0 on success, otherwise a Win32 error code @@ -99,30 +97,30 @@ static UINT rdpgfx_server_packet_send(RdpgfxServerContext* context, wStream* s) BYTE* pSrcData = Stream_Buffer(s); UINT32 SrcSize = Stream_GetPosition(s); wStream* fs; - /* Allocate new stream with enough capacity. Additional overhead is * descriptor (1 bytes) + segmentCount (2 bytes) + uncompressedSize (4 bytes) * + segmentCount * size (4 bytes) */ - fs = Stream_New(NULL, SrcSize + 7 - + (SrcSize/ZGFX_SEGMENTED_MAXSIZE + 1) * 4); + fs = Stream_New(NULL, SrcSize + 7 + + (SrcSize/ZGFX_SEGMENTED_MAXSIZE + 1) * 4); - if(!fs) + if (!fs) { - WLog_ERR(TAG, "Stream_New failed!"); + WLog_ERR(TAG, "Stream_New failed!"); error = CHANNEL_RC_NO_MEMORY; - goto out; + goto out; } - if (zgfx_compress_to_stream(context->priv->zgfx, fs, pSrcData, SrcSize, &flags) < 0) + if (zgfx_compress_to_stream(context->priv->zgfx, fs, pSrcData, + SrcSize, &flags) < 0) { WLog_ERR(TAG, "zgfx_compress_to_stream failed!"); error = ERROR_INTERNAL_ERROR; goto out; } - if (!WTSVirtualChannelWrite(context->priv->rdpgfx_channel, - (PCHAR) Stream_Buffer(fs), - Stream_GetPosition(fs), &written)) + if (!WTSVirtualChannelWrite(context->priv->rdpgfx_channel, + (PCHAR) Stream_Buffer(fs), + Stream_GetPosition(fs), &written)) { WLog_ERR(TAG, "WTSVirtualChannelWrite failed!"); error = ERROR_INTERNAL_ERROR; @@ -131,16 +129,14 @@ static UINT rdpgfx_server_packet_send(RdpgfxServerContext* context, wStream* s) if (written < Stream_GetPosition(fs)) { - WLog_WARN(TAG, "Unexpected bytes written: %lu/%lu", - written, Stream_GetPosition(fs)); + WLog_WARN(TAG, "Unexpected bytes written: %lu/%lu", + written, Stream_GetPosition(fs)); } error = CHANNEL_RC_OK; - out: Stream_Free(fs, TRUE); Stream_Free(s, TRUE); - return error; } @@ -148,10 +144,10 @@ out: * Function description * Create new stream for single rdpgfx packet. The new stream length * would be required data length + header. The header will be written - * to the stream before return, but the pduLength field might be + * to the stream before return, but the pduLength field might be * changed in rdpgfx_server_single_packet_send. * - * @param cmdId + * @param cmdId * @param dataLen estimated data length without header * * @return new stream @@ -160,43 +156,40 @@ static wStream* rdpgfx_server_single_packet_new(UINT16 cmdId, UINT32 dataLen) { UINT error; wStream* s; - UINT32 pduLength = rdpgfx_pdu_length(dataLen); - + UINT32 pduLength = rdpgfx_pdu_length(dataLen); s = Stream_New(NULL, pduLength); - if(!s) + if (!s) { - WLog_ERR(TAG, "Stream_New failed!"); - goto error; + WLog_ERR(TAG, "Stream_New failed!"); + goto error; } if ((error = rdpgfx_server_packet_init_header(s, cmdId, pduLength))) { WLog_ERR(TAG, "Failed to init header with error %lu!", error); - goto error; + goto error; } return s; - error: Stream_Free(s, TRUE); - return NULL; } /** * Function description - * Send the stream for single rdpgfx packet. + * Send the stream for single rdpgfx packet. * The header will be filled with actual length. * The packet would be compressed according to [MS-RDPEGFX]. * * @return 0 on success, otherwise a Win32 error code */ -static INLINE UINT rdpgfx_server_single_packet_send(RdpgfxServerContext* context, wStream* s) +static INLINE UINT rdpgfx_server_single_packet_send( + RdpgfxServerContext* context, wStream* s) { /* Fill actual length */ rdpgfx_server_packet_complete_header(s, 0); - return rdpgfx_server_packet_send(context, s); } @@ -205,12 +198,13 @@ static INLINE UINT rdpgfx_server_single_packet_send(RdpgfxServerContext* context * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_caps_confirm_pdu(RdpgfxServerContext* context, RDPGFX_CAPS_CONFIRM_PDU* capsConfirm) +static UINT rdpgfx_send_caps_confirm_pdu(RdpgfxServerContext* context, + RDPGFX_CAPS_CONFIRM_PDU* capsConfirm) { RDPGFX_CAPSET* capsSet = capsConfirm->capsSet; wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_CAPSCONFIRM, - sizeof(RDPGFX_CAPSET) + sizeof(capsSet->flags)); + RDPGFX_CMDID_CAPSCONFIRM, + sizeof(RDPGFX_CAPSET) + sizeof(capsSet->flags)); if (!s) { @@ -221,7 +215,6 @@ static UINT rdpgfx_send_caps_confirm_pdu(RdpgfxServerContext* context, RDPGFX_CA Stream_Write_UINT32(s, capsSet->version); /* version (4 bytes) */ Stream_Write_UINT32(s, sizeof(capsSet->flags)); /* capsDataLength (4 bytes) */ Stream_Write_UINT32(s, capsSet->flags); /* capsData (4 bytes) */ - return rdpgfx_server_single_packet_send(context, s); } @@ -230,23 +223,24 @@ static UINT rdpgfx_send_caps_confirm_pdu(RdpgfxServerContext* context, RDPGFX_CA * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_reset_graphics_pdu(RdpgfxServerContext* context, RDPGFX_RESET_GRAPHICS_PDU* pdu) +static UINT rdpgfx_send_reset_graphics_pdu(RdpgfxServerContext* context, + RDPGFX_RESET_GRAPHICS_PDU* pdu) { UINT32 index; MONITOR_DEF* monitor; wStream* s; - + /* Check monitorCount. This ensures total size within 340 bytes) */ if (pdu->monitorCount >= 16) { WLog_ERR(TAG, "Monitor count MUST be less than or equal to 16: %lu", - pdu->monitorCount); + pdu->monitorCount); return ERROR_INVALID_DATA; } s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_RESETGRAPHICS, - RDPGFX_RESET_GRAPHICS_PDU_SIZE - RDPGFX_HEADER_SIZE); + RDPGFX_CMDID_RESETGRAPHICS, + RDPGFX_RESET_GRAPHICS_PDU_SIZE - RDPGFX_HEADER_SIZE); if (!s) { @@ -270,7 +264,6 @@ static UINT rdpgfx_send_reset_graphics_pdu(RdpgfxServerContext* context, RDPGFX_ /* pad (total size must be 340 bytes) */ Stream_SetPosition(s, RDPGFX_RESET_GRAPHICS_PDU_SIZE); - return rdpgfx_server_single_packet_send(context, s); } @@ -279,11 +272,12 @@ static UINT rdpgfx_send_reset_graphics_pdu(RdpgfxServerContext* context, RDPGFX_ * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_evict_cache_entry_pdu(RdpgfxServerContext* context, RDPGFX_EVICT_CACHE_ENTRY_PDU* pdu) +static UINT rdpgfx_send_evict_cache_entry_pdu(RdpgfxServerContext* context, + RDPGFX_EVICT_CACHE_ENTRY_PDU* pdu) { wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_EVICTCACHEENTRY, - sizeof(RDPGFX_EVICT_CACHE_ENTRY_PDU)); + RDPGFX_CMDID_EVICTCACHEENTRY, + sizeof(RDPGFX_EVICT_CACHE_ENTRY_PDU)); if (!s) { @@ -292,7 +286,6 @@ static UINT rdpgfx_send_evict_cache_entry_pdu(RdpgfxServerContext* context, RDPG } Stream_Write_UINT16(s, pdu->cacheSlot); /* cacheSlot (2 bytes) */ - return rdpgfx_server_single_packet_send(context, s); } @@ -301,12 +294,14 @@ static UINT rdpgfx_send_evict_cache_entry_pdu(RdpgfxServerContext* context, RDPG * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_cache_import_reply_pdu(RdpgfxServerContext* context, RDPGFX_CACHE_IMPORT_REPLY_PDU* pdu) +static UINT rdpgfx_send_cache_import_reply_pdu(RdpgfxServerContext* context, + RDPGFX_CACHE_IMPORT_REPLY_PDU* pdu) { UINT16 index; wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_CACHEIMPORTREPLY, - sizeof(RDPGFX_CACHE_IMPORT_REPLY_PDU) + sizeof(UINT16) * pdu->importedEntriesCount); + RDPGFX_CMDID_CACHEIMPORTREPLY, + sizeof(RDPGFX_CACHE_IMPORT_REPLY_PDU) + + sizeof(UINT16) * pdu->importedEntriesCount); if (!s) { @@ -314,7 +309,9 @@ static UINT rdpgfx_send_cache_import_reply_pdu(RdpgfxServerContext* context, RDP return CHANNEL_RC_NO_MEMORY; } - Stream_Write_UINT16(s, pdu->importedEntriesCount); /* importedEntriesCount (2 bytes) */ + /* importedEntriesCount (2 bytes) */ + Stream_Write_UINT16(s, pdu->importedEntriesCount); + for (index = 0; index < pdu->importedEntriesCount; index++) { Stream_Write_UINT16(s, pdu->cacheSlots[index]); /* cacheSlot (2 bytes) */ @@ -328,11 +325,12 @@ static UINT rdpgfx_send_cache_import_reply_pdu(RdpgfxServerContext* context, RDP * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_create_surface_pdu(RdpgfxServerContext* context, RDPGFX_CREATE_SURFACE_PDU* pdu) +static UINT rdpgfx_send_create_surface_pdu(RdpgfxServerContext* context, + RDPGFX_CREATE_SURFACE_PDU* pdu) { wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_CREATESURFACE, - sizeof(RDPGFX_CREATE_SURFACE_PDU)); + RDPGFX_CMDID_CREATESURFACE, + sizeof(RDPGFX_CREATE_SURFACE_PDU)); if (!s) { @@ -344,7 +342,6 @@ static UINT rdpgfx_send_create_surface_pdu(RdpgfxServerContext* context, RDPGFX_ Stream_Write_UINT16(s, pdu->width); /* width (2 bytes) */ Stream_Write_UINT16(s, pdu->height); /* height (2 bytes) */ Stream_Write_UINT8(s, pdu->pixelFormat); /* RDPGFX_PIXELFORMAT (1 byte) */ - return rdpgfx_server_single_packet_send(context, s); } @@ -353,11 +350,12 @@ static UINT rdpgfx_send_create_surface_pdu(RdpgfxServerContext* context, RDPGFX_ * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpgfx_send_delete_surface_pdu(RdpgfxServerContext* context, RDPGFX_DELETE_SURFACE_PDU* pdu) +UINT rdpgfx_send_delete_surface_pdu(RdpgfxServerContext* context, + RDPGFX_DELETE_SURFACE_PDU* pdu) { wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_DELETESURFACE, - sizeof(RDPGFX_DELETE_SURFACE_PDU)); + RDPGFX_CMDID_DELETESURFACE, + sizeof(RDPGFX_DELETE_SURFACE_PDU)); if (!s) { @@ -366,17 +364,18 @@ UINT rdpgfx_send_delete_surface_pdu(RdpgfxServerContext* context, RDPGFX_DELETE_ } Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */ - return rdpgfx_server_single_packet_send(context, s); } -static INLINE void rdpgfx_write_start_frame_pdu(wStream* s, RDPGFX_START_FRAME_PDU* pdu) +static INLINE void rdpgfx_write_start_frame_pdu(wStream* s, + RDPGFX_START_FRAME_PDU* pdu) { Stream_Write_UINT32(s, pdu->timestamp); /* timestamp (4 bytes) */ Stream_Write_UINT32(s, pdu->frameId); /* frameId (4 bytes) */ } -static INLINE void rdpgfx_write_end_frame_pdu(wStream* s, RDPGFX_END_FRAME_PDU* pdu) +static INLINE void rdpgfx_write_end_frame_pdu(wStream* s, + RDPGFX_END_FRAME_PDU* pdu) { Stream_Write_UINT32(s, pdu->frameId); /* frameId (4 bytes) */ } @@ -386,11 +385,12 @@ static INLINE void rdpgfx_write_end_frame_pdu(wStream* s, RDPGFX_END_FRAME_PDU* * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_start_frame_pdu(RdpgfxServerContext* context, RDPGFX_START_FRAME_PDU* pdu) +static UINT rdpgfx_send_start_frame_pdu(RdpgfxServerContext* context, + RDPGFX_START_FRAME_PDU* pdu) { wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_STARTFRAME, - sizeof(RDPGFX_START_FRAME_PDU)); + RDPGFX_CMDID_STARTFRAME, + sizeof(RDPGFX_START_FRAME_PDU)); if (!s) { @@ -399,7 +399,6 @@ static UINT rdpgfx_send_start_frame_pdu(RdpgfxServerContext* context, RDPGFX_STA } rdpgfx_write_start_frame_pdu(s, pdu); - return rdpgfx_server_single_packet_send(context, s); } @@ -408,11 +407,12 @@ static UINT rdpgfx_send_start_frame_pdu(RdpgfxServerContext* context, RDPGFX_STA * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_end_frame_pdu(RdpgfxServerContext* context, RDPGFX_END_FRAME_PDU* pdu) +static UINT rdpgfx_send_end_frame_pdu(RdpgfxServerContext* context, + RDPGFX_END_FRAME_PDU* pdu) { wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_ENDFRAME, - sizeof(RDPGFX_END_FRAME_PDU)); + RDPGFX_CMDID_ENDFRAME, + sizeof(RDPGFX_END_FRAME_PDU)); if (!s) { @@ -421,22 +421,22 @@ static UINT rdpgfx_send_end_frame_pdu(RdpgfxServerContext* context, RDPGFX_END_F } rdpgfx_write_end_frame_pdu(s, pdu); - return rdpgfx_server_single_packet_send(context, s); } /** * Function description - * Estimate RFX_AVC420_BITMAP_STREAM structure size in stream + * Estimate RFX_AVC420_BITMAP_STREAM structure size in stream * * @return estimated size */ -static INLINE UINT32 rdpgfx_estimate_h264_avc420(RDPGFX_AVC420_BITMAP_STREAM *havc420) +static INLINE UINT32 rdpgfx_estimate_h264_avc420( + RDPGFX_AVC420_BITMAP_STREAM* havc420) { return sizeof(UINT32) /* numRegionRects */ - + (sizeof(RECTANGLE_16) + 2) /* regionRects + quantQualityVals */ - * havc420->meta.numRegionRects - + havc420->length; + + (sizeof(RECTANGLE_16) + 2) /* regionRects + quantQualityVals */ + * havc420->meta.numRegionRects + + havc420->length; } /** @@ -447,28 +447,26 @@ static INLINE UINT32 rdpgfx_estimate_h264_avc420(RDPGFX_AVC420_BITMAP_STREAM *ha */ static INLINE UINT32 rdpgfx_estimate_surface_command(RDPGFX_SURFACE_COMMAND* cmd) { - RDPGFX_AVC420_BITMAP_STREAM *havc420 = NULL; - RDPGFX_AVC444_BITMAP_STREAM *havc444 = NULL; + RDPGFX_AVC420_BITMAP_STREAM* havc420 = NULL; + RDPGFX_AVC444_BITMAP_STREAM* havc444 = NULL; UINT32 h264Size = 0; /* Create new stream according to codec. */ if (cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE || - cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2) + cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2) { return sizeof(RDPGFX_WIRE_TO_SURFACE_PDU_2) + cmd->length; } else if (cmd->codecId == RDPGFX_CODECID_AVC420) { - havc420 = (RDPGFX_AVC420_BITMAP_STREAM *)cmd->extra; + havc420 = (RDPGFX_AVC420_BITMAP_STREAM*)cmd->extra; h264Size = rdpgfx_estimate_h264_avc420(havc420); - return sizeof(RDPGFX_WIRE_TO_SURFACE_PDU_1) + h264Size; } else if (cmd->codecId == RDPGFX_CODECID_AVC444) { - havc444 = (RDPGFX_AVC444_BITMAP_STREAM *)cmd->extra; + havc444 = (RDPGFX_AVC444_BITMAP_STREAM*)cmd->extra; h264Size = sizeof(UINT32); /* cbAvc420EncodedBitstream1 */ - /* avc420EncodedBitstream1 */ havc420 = &(havc444->bitstream[0]); h264Size += rdpgfx_estimate_h264_avc420(havc420); @@ -490,7 +488,7 @@ static INLINE UINT32 rdpgfx_estimate_surface_command(RDPGFX_SURFACE_COMMAND* cmd /** * Function description - * Resolve RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 + * Resolve RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 * according to codecId * * @return 0 on success, otherwise a Win32 error code @@ -498,7 +496,7 @@ static INLINE UINT32 rdpgfx_estimate_surface_command(RDPGFX_SURFACE_COMMAND* cmd static INLINE UINT16 rdpgfx_surface_command_cmdid(RDPGFX_SURFACE_COMMAND* cmd) { if (cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE || - cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2) + cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2) { return RDPGFX_CMDID_WIRETOSURFACE_2; } @@ -517,12 +515,12 @@ static UINT rdpgfx_write_h264_metablock(wStream* s, RDPGFX_H264_METABLOCK* meta) RECTANGLE_16* regionRect; RDPGFX_H264_QUANT_QUALITY* quantQualityVal; UINT error = CHANNEL_RC_OK; - Stream_Write_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */ for (index = 0; index < meta->numRegionRects; index++) { regionRect = &(meta->regionRects[index]); + if ((error = rdpgfx_write_rect16(s, regionRect))) { WLog_ERR(TAG, "rdpgfx_write_rect16 failed with error %lu!", error); @@ -533,11 +531,11 @@ static UINT rdpgfx_write_h264_metablock(wStream* s, RDPGFX_H264_METABLOCK* meta) for (index = 0; index < meta->numRegionRects; index++) { quantQualityVal = &(meta->quantQualityVals[index]); - Stream_Write_UINT8(s, quantQualityVal->qp - | (quantQualityVal->r << 6) - | (quantQualityVal->p << 7)); /* qpVal (1 byte) */ - Stream_Write_UINT8(s, quantQualityVal->qualityVal); /* qualityVal (1 byte) */ + | (quantQualityVal->r << 6) + | (quantQualityVal->p << 7)); /* qpVal (1 byte) */ + /* qualityVal (1 byte) */ + Stream_Write_UINT8(s, quantQualityVal->qualityVal); } return error; @@ -549,12 +547,15 @@ static UINT rdpgfx_write_h264_metablock(wStream* s, RDPGFX_H264_METABLOCK* meta) * * @return 0 on success, otherwise a Win32 error code */ -static INLINE UINT rdpgfx_write_h264_avc420(wStream* s, RDPGFX_AVC420_BITMAP_STREAM* havc420) +static INLINE UINT rdpgfx_write_h264_avc420(wStream* s, + RDPGFX_AVC420_BITMAP_STREAM* havc420) { UINT error = CHANNEL_RC_OK; + if ((error = rdpgfx_write_h264_metablock(s, &(havc420->meta)))) { - WLog_ERR(TAG, "rdpgfx_write_h264_metablock failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_write_h264_metablock failed with error %lu!", + error); return error; } @@ -572,44 +573,40 @@ static INLINE UINT rdpgfx_write_h264_avc420(wStream* s, RDPGFX_AVC420_BITMAP_STR static UINT rdpgfx_write_surface_command(wStream* s, RDPGFX_SURFACE_COMMAND* cmd) { UINT error = CHANNEL_RC_OK; - RDPGFX_AVC420_BITMAP_STREAM *havc420 = NULL; - RDPGFX_AVC444_BITMAP_STREAM *havc444 = NULL; + RDPGFX_AVC420_BITMAP_STREAM* havc420 = NULL; + RDPGFX_AVC444_BITMAP_STREAM* havc444 = NULL; UINT32 bitmapDataStart = 0; UINT32 bitmapDataLength = 0; if (cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE || - cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2) + cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2) { /* Write RDPGFX_CMDID_WIRETOSURFACE_2 format for CAPROGRESSIVE */ - Stream_Write_UINT16(s, cmd->surfaceId); /* surfaceId (2 bytes) */ Stream_Write_UINT16(s, cmd->codecId); /* codecId (2 bytes) */ Stream_Write_UINT32(s, cmd->contextId); /* codecContextId (4 bytes) */ Stream_Write_UINT8(s, cmd->format); /* pixelFormat (1 byte) */ - Stream_Write_UINT32(s, cmd->length); /* bitmapDataLength (4 bytes) */ Stream_Write(s, cmd->data, cmd->length); } else { /* Write RDPGFX_CMDID_WIRETOSURFACE_1 format for others */ - Stream_Write_UINT16(s, cmd->surfaceId); /* surfaceId (2 bytes) */ Stream_Write_UINT16(s, cmd->codecId); /* codecId (2 bytes) */ Stream_Write_UINT8(s, cmd->format); /* pixelFormat (1 byte) */ - Stream_Write_UINT16(s, cmd->left); /* left (2 bytes) */ Stream_Write_UINT16(s, cmd->top); /* top (2 bytes) */ Stream_Write_UINT16(s, cmd->right); /* right (2 bytes) */ Stream_Write_UINT16(s, cmd->bottom); /* bottom (2 bytes) */ - Stream_Write_UINT32(s, cmd->length); /* bitmapDataLength (4 bytes) */ bitmapDataStart = Stream_GetPosition(s); if (cmd->codecId == RDPGFX_CODECID_AVC420) { - havc420 = (RDPGFX_AVC420_BITMAP_STREAM *)cmd->extra; + havc420 = (RDPGFX_AVC420_BITMAP_STREAM*)cmd->extra; error = rdpgfx_write_h264_avc420(s, havc420); + if (error != CHANNEL_RC_OK) { WLog_ERR(TAG, "rdpgfx_write_h264_avc420 failed!"); @@ -618,14 +615,13 @@ static UINT rdpgfx_write_surface_command(wStream* s, RDPGFX_SURFACE_COMMAND* cmd } else if (cmd->codecId == RDPGFX_CODECID_AVC444) { - havc444 = (RDPGFX_AVC444_BITMAP_STREAM *)cmd->extra; + havc444 = (RDPGFX_AVC444_BITMAP_STREAM*)cmd->extra; havc420 = &(havc444->bitstream[0]); - /* avc420EncodedBitstreamInfo (4 bytes) */ Stream_Write_UINT32(s, havc420->length | (havc444->LC << 30UL)); - /* avc420EncodedBitstream1 */ error = rdpgfx_write_h264_avc420(s, havc420); + if (error != CHANNEL_RC_OK) { WLog_ERR(TAG, "rdpgfx_write_h264_avc420 failed!"); @@ -637,6 +633,7 @@ static UINT rdpgfx_write_surface_command(wStream* s, RDPGFX_SURFACE_COMMAND* cmd { havc420 = &(havc444->bitstream[0]); error = rdpgfx_write_h264_avc420(s, havc420); + if (error != CHANNEL_RC_OK) { WLog_ERR(TAG, "rdpgfx_write_h264_avc420 failed!"); @@ -650,7 +647,6 @@ static UINT rdpgfx_write_surface_command(wStream* s, RDPGFX_SURFACE_COMMAND* cmd } assert(Stream_GetPosition(s) <= Stream_Capacity(s)); - /* Fill actual bitmap data length */ bitmapDataLength = Stream_GetPosition(s) - bitmapDataStart; Stream_SetPosition(s, bitmapDataStart - sizeof(UINT32)); @@ -663,19 +659,19 @@ static UINT rdpgfx_write_surface_command(wStream* s, RDPGFX_SURFACE_COMMAND* cmd /** * Function description - * Send RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 + * Send RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 * message according to codecId * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_surface_command(RdpgfxServerContext* context, RDPGFX_SURFACE_COMMAND* cmd) +static UINT rdpgfx_send_surface_command(RdpgfxServerContext* context, + RDPGFX_SURFACE_COMMAND* cmd) { UINT error = CHANNEL_RC_OK; wStream* s; - s = rdpgfx_server_single_packet_new( - rdpgfx_surface_command_cmdid(cmd), - rdpgfx_estimate_surface_command(cmd)); + rdpgfx_surface_command_cmdid(cmd), + rdpgfx_estimate_surface_command(cmd)); if (!s) { @@ -684,6 +680,7 @@ static UINT rdpgfx_send_surface_command(RdpgfxServerContext* context, RDPGFX_SUR } error = rdpgfx_write_surface_command(s, cmd); + if (error != CHANNEL_RC_OK) { WLog_ERR(TAG, "rdpgfx_write_surface_command failed!"); @@ -691,24 +688,22 @@ static UINT rdpgfx_send_surface_command(RdpgfxServerContext* context, RDPGFX_SUR } return rdpgfx_server_single_packet_send(context, s); - error: Stream_Free(s, TRUE); - return error; } /** * Function description - * Send RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 + * Send RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 * message according to codecId. * Prepend/append start/end frame message in same packet if exists. * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context, - RDPGFX_SURFACE_COMMAND* cmd, RDPGFX_START_FRAME_PDU* startFrame, - RDPGFX_END_FRAME_PDU* endFrame) + RDPGFX_SURFACE_COMMAND* cmd, RDPGFX_START_FRAME_PDU* startFrame, + RDPGFX_END_FRAME_PDU* endFrame) { UINT error = CHANNEL_RC_OK; @@ -728,9 +723,9 @@ static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context, s = Stream_New(NULL, size); - if(!s) + if (!s) { - WLog_ERR(TAG, "Stream_New failed!"); + WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } @@ -738,8 +733,9 @@ static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context, if (startFrame) { position = Stream_GetPosition(s); - error = rdpgfx_server_packet_init_header(s, - RDPGFX_CMDID_STARTFRAME, 0); + error = rdpgfx_server_packet_init_header(s, + RDPGFX_CMDID_STARTFRAME, 0); + if (error != CHANNEL_RC_OK) { WLog_ERR(TAG, "Failed to init header with error %lu!", error); @@ -752,9 +748,10 @@ static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context, /* Write RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 */ position = Stream_GetPosition(s); - error = rdpgfx_server_packet_init_header(s, - rdpgfx_surface_command_cmdid(cmd), - 0); // Actual length will be filled later + error = rdpgfx_server_packet_init_header(s, + rdpgfx_surface_command_cmdid(cmd), + 0); // Actual length will be filled later + if (error != CHANNEL_RC_OK) { WLog_ERR(TAG, "Failed to init header with error %lu!", error); @@ -762,19 +759,22 @@ static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context, } error = rdpgfx_write_surface_command(s, cmd); + if (error != CHANNEL_RC_OK) { WLog_ERR(TAG, "rdpgfx_write_surface_command failed!"); goto error; } + rdpgfx_server_packet_complete_header(s, position); /* Write end frame if exists */ if (endFrame) { position = Stream_GetPosition(s); - error = rdpgfx_server_packet_init_header(s, - RDPGFX_CMDID_ENDFRAME, 0); + error = rdpgfx_server_packet_init_header(s, + RDPGFX_CMDID_ENDFRAME, 0); + if (error != CHANNEL_RC_OK) { WLog_ERR(TAG, "Failed to init header with error %lu!", error); @@ -786,10 +786,8 @@ static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context, } return rdpgfx_server_packet_send(context, s); - error: Stream_Free(s, TRUE); - return error; } @@ -798,11 +796,12 @@ error: * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_delete_encoding_context_pdu(RdpgfxServerContext* context, RDPGFX_DELETE_ENCODING_CONTEXT_PDU* pdu) +static UINT rdpgfx_send_delete_encoding_context_pdu(RdpgfxServerContext* context, + RDPGFX_DELETE_ENCODING_CONTEXT_PDU* pdu) { wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_DELETEENCODINGCONTEXT, - sizeof(RDPGFX_DELETE_ENCODING_CONTEXT_PDU)); + RDPGFX_CMDID_DELETEENCODINGCONTEXT, + sizeof(RDPGFX_DELETE_ENCODING_CONTEXT_PDU)); if (!s) { @@ -812,7 +811,6 @@ static UINT rdpgfx_send_delete_encoding_context_pdu(RdpgfxServerContext* context Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */ Stream_Write_UINT32(s, pdu->codecContextId); /* codecContextId (4 bytes) */ - return rdpgfx_server_single_packet_send(context, s); } @@ -821,14 +819,16 @@ static UINT rdpgfx_send_delete_encoding_context_pdu(RdpgfxServerContext* context * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpgfx_send_solid_fill_pdu(RdpgfxServerContext* context, RDPGFX_SOLID_FILL_PDU* pdu) +UINT rdpgfx_send_solid_fill_pdu(RdpgfxServerContext* context, + RDPGFX_SOLID_FILL_PDU* pdu) { UINT error = CHANNEL_RC_OK; UINT16 index; RECTANGLE_16* fillRect; wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_SOLIDFILL, - sizeof(RDPGFX_SOLID_FILL_PDU) + sizeof(RECTANGLE_16) * pdu->fillRectCount); + RDPGFX_CMDID_SOLIDFILL, + sizeof(RDPGFX_SOLID_FILL_PDU) + + sizeof(RECTANGLE_16) * pdu->fillRectCount); if (!s) { @@ -837,16 +837,20 @@ UINT rdpgfx_send_solid_fill_pdu(RdpgfxServerContext* context, RDPGFX_SOLID_FILL_ } Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */ - if ((error = rdpgfx_write_color32(s, &(pdu->fillPixel)))) /* fillPixel (4 bytes) */ + + /* fillPixel (4 bytes) */ + if ((error = rdpgfx_write_color32(s, &(pdu->fillPixel)))) { WLog_ERR(TAG, "rdpgfx_write_color32 failed with error %lu!", error); goto error; } Stream_Write_UINT16(s, pdu->fillRectCount); /* fillRectCount (2 bytes) */ + for (index = 0; index < pdu->fillRectCount; index++) { fillRect = &(pdu->fillRects[index]); + if ((error = rdpgfx_write_rect16(s, fillRect))) { WLog_ERR(TAG, "rdpgfx_write_rect16 failed with error %lu!", error); @@ -855,10 +859,8 @@ UINT rdpgfx_send_solid_fill_pdu(RdpgfxServerContext* context, RDPGFX_SOLID_FILL_ } return rdpgfx_server_single_packet_send(context, s); - error: Stream_Free(s, TRUE); - return error; } @@ -867,14 +869,16 @@ error: * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_surface_to_surface_pdu(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* pdu) +static UINT rdpgfx_send_surface_to_surface_pdu(RdpgfxServerContext* context, + RDPGFX_SURFACE_TO_SURFACE_PDU* pdu) { UINT error = CHANNEL_RC_OK; UINT16 index; RDPGFX_POINT16* destPt; wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_SURFACETOSURFACE, - sizeof(RDPGFX_SURFACE_TO_SURFACE_PDU) + sizeof(RDPGFX_POINT16) * pdu->destPtsCount); + RDPGFX_CMDID_SURFACETOSURFACE, + sizeof(RDPGFX_SURFACE_TO_SURFACE_PDU) + + sizeof(RDPGFX_POINT16) * pdu->destPtsCount); if (!s) { @@ -885,16 +889,19 @@ static UINT rdpgfx_send_surface_to_surface_pdu(RdpgfxServerContext* context, RDP Stream_Write_UINT16(s, pdu->surfaceIdSrc); /* surfaceIdSrc (2 bytes) */ Stream_Write_UINT16(s, pdu->surfaceIdDest); /* surfaceIdDest (2 bytes) */ - if ((error = rdpgfx_write_rect16(s, &(pdu->rectSrc)))) /* rectSrc (8 bytes ) */ + /* rectSrc (8 bytes ) */ + if ((error = rdpgfx_write_rect16(s, &(pdu->rectSrc)))) { WLog_ERR(TAG, "rdpgfx_write_rect16 failed with error %lu!", error); goto error; } Stream_Write_UINT16(s, pdu->destPtsCount); /* destPtsCount (2 bytes) */ + for (index = 0; index < pdu->destPtsCount; index++) { destPt = &(pdu->destPts[index]); + if ((error = rdpgfx_write_point16(s, destPt))) { WLog_ERR(TAG, "rdpgfx_write_point16 failed with error %lu!", error); @@ -903,10 +910,8 @@ static UINT rdpgfx_send_surface_to_surface_pdu(RdpgfxServerContext* context, RDP } return rdpgfx_server_single_packet_send(context, s); - error: Stream_Free(s, TRUE); - return error; } @@ -915,12 +920,13 @@ error: * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_surface_to_cache_pdu(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_CACHE_PDU* pdu) +static UINT rdpgfx_send_surface_to_cache_pdu(RdpgfxServerContext* context, + RDPGFX_SURFACE_TO_CACHE_PDU* pdu) { UINT error = CHANNEL_RC_OK; wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_SURFACETOCACHE, - sizeof(RDPGFX_SURFACE_TO_CACHE_PDU)); + RDPGFX_CMDID_SURFACETOCACHE, + sizeof(RDPGFX_SURFACE_TO_CACHE_PDU)); if (!s) { @@ -931,17 +937,17 @@ static UINT rdpgfx_send_surface_to_cache_pdu(RdpgfxServerContext* context, RDPGF Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */ Stream_Write_UINT64(s, pdu->cacheKey); /* cacheKey (8 bytes) */ Stream_Write_UINT16(s, pdu->cacheSlot); /* cacheSlot (2 bytes) */ - if ((error = rdpgfx_write_rect16(s, &(pdu->rectSrc)))) /* rectSrc (8 bytes ) */ + + /* rectSrc (8 bytes ) */ + if ((error = rdpgfx_write_rect16(s, &(pdu->rectSrc)))) { WLog_ERR(TAG, "rdpgfx_write_rect16 failed with error %lu!", error); goto error; } return rdpgfx_server_single_packet_send(context, s); - error: Stream_Free(s, TRUE); - return error; } @@ -950,14 +956,16 @@ error: * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_cache_to_surface_pdu(RdpgfxServerContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* pdu) +static UINT rdpgfx_send_cache_to_surface_pdu(RdpgfxServerContext* context, + RDPGFX_CACHE_TO_SURFACE_PDU* pdu) { UINT error = CHANNEL_RC_OK; UINT16 index; RDPGFX_POINT16* destPt; wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_CACHETOSURFACE, - sizeof(RDPGFX_CACHE_TO_SURFACE_PDU) + sizeof(RDPGFX_POINT16) * pdu->destPtsCount); + RDPGFX_CMDID_CACHETOSURFACE, + sizeof(RDPGFX_CACHE_TO_SURFACE_PDU) + + sizeof(RDPGFX_POINT16) * pdu->destPtsCount); if (!s) { @@ -972,6 +980,7 @@ static UINT rdpgfx_send_cache_to_surface_pdu(RdpgfxServerContext* context, RDPGF for (index = 0; index < pdu->destPtsCount; index++) { destPt = &(pdu->destPts[index]); + if ((error = rdpgfx_write_point16(s, destPt))) { WLog_ERR(TAG, "rdpgfx_write_point16 failed with error %lu", error); @@ -980,10 +989,8 @@ static UINT rdpgfx_send_cache_to_surface_pdu(RdpgfxServerContext* context, RDPGF } return rdpgfx_server_single_packet_send(context, s); - error: Stream_Free(s, TRUE); - return error; } @@ -992,11 +999,12 @@ error: * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_map_surface_to_output_pdu(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* pdu) +static UINT rdpgfx_send_map_surface_to_output_pdu(RdpgfxServerContext* context, + RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* pdu) { wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_MAPSURFACETOOUTPUT, - sizeof(RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU)); + RDPGFX_CMDID_MAPSURFACETOOUTPUT, + sizeof(RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU)); if (!s) { @@ -1008,7 +1016,6 @@ static UINT rdpgfx_send_map_surface_to_output_pdu(RdpgfxServerContext* context, Stream_Write_UINT16(s, 0); /* reserved (2 bytes). Must be 0 */ Stream_Write_UINT32(s, pdu->outputOriginX); /* outputOriginX (4 bytes) */ Stream_Write_UINT32(s, pdu->outputOriginY); /* outputOriginY (4 bytes) */ - return rdpgfx_server_single_packet_send(context, s); } @@ -1017,11 +1024,12 @@ static UINT rdpgfx_send_map_surface_to_output_pdu(RdpgfxServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_map_surface_to_window_pdu(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* pdu) +static UINT rdpgfx_send_map_surface_to_window_pdu(RdpgfxServerContext* context, + RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* pdu) { wStream* s = rdpgfx_server_single_packet_new( - RDPGFX_CMDID_MAPSURFACETOWINDOW, - sizeof(RDPGFX_MAP_SURFACE_TO_WINDOW_PDU)); + RDPGFX_CMDID_MAPSURFACETOWINDOW, + sizeof(RDPGFX_MAP_SURFACE_TO_WINDOW_PDU)); if (!s) { @@ -1033,7 +1041,6 @@ static UINT rdpgfx_send_map_surface_to_window_pdu(RdpgfxServerContext* context, Stream_Write_UINT64(s, pdu->windowId); /* windowId (8 bytes) */ Stream_Write_UINT32(s, pdu->mappedWidth); /* mappedWidth (4 bytes) */ Stream_Write_UINT32(s, pdu->mappedHeight); /* mappedHeight (4 bytes) */ - return rdpgfx_server_single_packet_send(context, s); } @@ -1042,26 +1049,30 @@ static UINT rdpgfx_send_map_surface_to_window_pdu(RdpgfxServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_frame_acknowledge_pdu(RdpgfxServerContext* context, wStream* s) +static UINT rdpgfx_recv_frame_acknowledge_pdu(RdpgfxServerContext* context, + wStream* s) { RDPGFX_FRAME_ACKNOWLEDGE_PDU pdu; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < sizeof(RDPGFX_FRAME_ACKNOWLEDGE_PDU)) - { - WLog_ERR(TAG, "not enough data!"); - return ERROR_INVALID_DATA; - } + if (Stream_GetRemainingLength(s) < sizeof(RDPGFX_FRAME_ACKNOWLEDGE_PDU)) + { + WLog_ERR(TAG, "not enough data!"); + return ERROR_INVALID_DATA; + } Stream_Read_UINT32(s, pdu.queueDepth); /* queueDepth (4 bytes) */ Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ - Stream_Read_UINT32(s, pdu.totalFramesDecoded); /* totalFramesDecoded (4 bytes) */ + /* totalFramesDecoded (4 bytes) */ + Stream_Read_UINT32(s, pdu.totalFramesDecoded); if (context) { IFCALLRET(context->FrameAcknowledge, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->FrameAcknowledge failed with error %lu", error); + WLog_ERR(TAG, "context->FrameAcknowledge failed with error %lu", + error); } return error; @@ -1072,20 +1083,23 @@ static UINT rdpgfx_recv_frame_acknowledge_pdu(RdpgfxServerContext* context, wStr * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context, wStream* s) +static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context, + wStream* s) { UINT16 index; RDPGFX_CACHE_IMPORT_OFFER_PDU pdu; RDPGFX_CACHE_ENTRY_METADATA* cacheEntries; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < sizeof(UINT16)) - { - WLog_ERR(TAG, "not enough data!"); - return ERROR_INVALID_DATA; - } + if (Stream_GetRemainingLength(s) < sizeof(UINT16)) + { + WLog_ERR(TAG, "not enough data!"); + return ERROR_INVALID_DATA; + } + + /* cacheEntriesCount (2 bytes) */ + Stream_Read_UINT16(s, pdu.cacheEntriesCount); - Stream_Read_UINT16(s, pdu.cacheEntriesCount); /* cacheEntriesCount (2 bytes) */ if (pdu.cacheEntriesCount <= 0) { /* According to the latest spec, capsSetCount <= 3 */ @@ -1093,16 +1107,16 @@ static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context, wSt return ERROR_INVALID_DATA; } - if (Stream_GetRemainingLength(s) < - (pdu.cacheEntriesCount * sizeof(RDPGFX_CACHE_ENTRY_METADATA))) - { - WLog_ERR(TAG, "not enough data!"); - return ERROR_INVALID_DATA; - } + if (Stream_GetRemainingLength(s) < + (pdu.cacheEntriesCount * sizeof(RDPGFX_CACHE_ENTRY_METADATA))) + { + WLog_ERR(TAG, "not enough data!"); + return ERROR_INVALID_DATA; + } - pdu.cacheEntries = (RDPGFX_CACHE_ENTRY_METADATA*) - calloc(pdu.cacheEntriesCount, - sizeof(RDPGFX_CACHE_ENTRY_METADATA)); + pdu.cacheEntries = (RDPGFX_CACHE_ENTRY_METADATA*) + calloc(pdu.cacheEntriesCount, + sizeof(RDPGFX_CACHE_ENTRY_METADATA)); if (!pdu.cacheEntries) { @@ -1114,18 +1128,20 @@ static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context, wSt { cacheEntries = &(pdu.cacheEntries[index]); Stream_Read_UINT64(s, cacheEntries->cacheKey); /* cacheKey (8 bytes) */ - Stream_Read_UINT32(s, cacheEntries->bitmapLength); /* bitmapLength (4 bytes) */ + /* bitmapLength (4 bytes) */ + Stream_Read_UINT32(s, cacheEntries->bitmapLength); } if (context) { IFCALLRET(context->CacheImportOffer, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->CacheImportOffer failed with error %lu", error); + WLog_ERR(TAG, "context->CacheImportOffer failed with error %lu", + error); } free(pdu.cacheEntries); - return error; } @@ -1134,7 +1150,8 @@ static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context, wSt * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream* s) +static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, + wStream* s) { UINT16 index; RDPGFX_CAPSET* capsSet; @@ -1143,13 +1160,14 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream UINT error = CHANNEL_RC_OK; UINT32 capsDataLength; - if (Stream_GetRemainingLength(s) < sizeof(UINT16)) - { - WLog_ERR(TAG, "not enough data!"); - return ERROR_INVALID_DATA; - } + if (Stream_GetRemainingLength(s) < sizeof(UINT16)) + { + WLog_ERR(TAG, "not enough data!"); + return ERROR_INVALID_DATA; + } Stream_Read_UINT16(s, pdu.capsSetCount); /* capsSetCount (2 bytes) */ + if (pdu.capsSetCount > 3) { /* According to the latest spec, capsSetCount <= 3 */ @@ -1157,12 +1175,12 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream return ERROR_INVALID_DATA; } - if (Stream_GetRemainingLength(s) < - (pdu.capsSetCount * (sizeof(RDPGFX_CAPSET) + sizeof(UINT32)))) - { - WLog_ERR(TAG, "not enough data!"); - return ERROR_INVALID_DATA; - } + if (Stream_GetRemainingLength(s) < + (pdu.capsSetCount * (sizeof(RDPGFX_CAPSET) + sizeof(UINT32)))) + { + WLog_ERR(TAG, "not enough data!"); + return ERROR_INVALID_DATA; + } pdu.capsSets = (RDPGFX_CAPSET*) capsSets; @@ -1171,17 +1189,21 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream capsSet = &(pdu.capsSets[index]); Stream_Read_UINT32(s, capsSet->version); /* version (4 bytes) */ Stream_Read_UINT32(s, capsDataLength); /* capsDataLength (4 bytes) */ + if (capsDataLength != 4) { - WLog_ERR(TAG, "capsDataLength does not equal to 4: %lu", capsDataLength); + WLog_ERR(TAG, "capsDataLength does not equal to 4: %lu", + capsDataLength); return ERROR_INVALID_DATA; } + Stream_Read_UINT32(s, capsSet->flags); /* capsData (4 bytes) */ } if (context) { IFCALLRET(context->CapsAdvertise, error, context, &pdu); + if (error) WLog_ERR(TAG, "context->CapsAdvertise failed with error %lu", error); } @@ -1194,16 +1216,17 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_qoe_frame_acknowledge_pdu(RdpgfxServerContext* context, wStream* s) +static UINT rdpgfx_recv_qoe_frame_acknowledge_pdu(RdpgfxServerContext* context, + wStream* s) { RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU pdu; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < sizeof(RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU)) - { - WLog_ERR(TAG, "not enough data!"); - return ERROR_INVALID_DATA; - } + if (Stream_GetRemainingLength(s) < sizeof(RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU)) + { + WLog_ERR(TAG, "not enough data!"); + return ERROR_INVALID_DATA; + } Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ Stream_Read_UINT32(s, pdu.timestamp); /* timestamp (4 bytes) */ @@ -1213,8 +1236,10 @@ static UINT rdpgfx_recv_qoe_frame_acknowledge_pdu(RdpgfxServerContext* context, if (context) { IFCALLRET(context->QoeFrameAcknowledge, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->QoeFrameAcknowledge failed with error %lu", error); + WLog_ERR(TAG, "context->QoeFrameAcknowledge failed with error %lu", + error); } return error; @@ -1230,7 +1255,6 @@ static UINT rdpgfx_server_receive_pdu(RdpgfxServerContext* context, wStream* s) int beg, end; RDPGFX_HEADER header; UINT error = CHANNEL_RC_OK; - beg = Stream_GetPosition(s); if ((error = rdpgfx_read_header(s, &header))) @@ -1240,30 +1264,39 @@ static UINT rdpgfx_server_receive_pdu(RdpgfxServerContext* context, wStream* s) } WLog_DBG(TAG, "cmdId: %s (0x%04X) flags: 0x%04X pduLength: %d", - rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, header.flags, header.pduLength); + rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, + header.flags, header.pduLength); switch (header.cmdId) { case RDPGFX_CMDID_FRAMEACKNOWLEDGE: + if ((error = rdpgfx_recv_frame_acknowledge_pdu(context, s))) - WLog_ERR(TAG, "rdpgfx_recv_frame_acknowledge_pdu failed with error %lu!", error); - break; + WLog_ERR(TAG, "rdpgfx_recv_frame_acknowledge_pdu " + "failed with error %lu!", error); + break; case RDPGFX_CMDID_CACHEIMPORTOFFER: + if ((error = rdpgfx_recv_cache_import_offer_pdu(context, s))) - WLog_ERR(TAG, "rdpgfx_recv_cache_import_offer_pdu failed with error %lu!", error); - break; + WLog_ERR(TAG, "rdpgfx_recv_cache_import_offer_pdu " + "failed with error %lu!", error); + break; case RDPGFX_CMDID_CAPSADVERTISE: + if ((error = rdpgfx_recv_caps_advertise_pdu(context, s))) - WLog_ERR(TAG, "rdpgfx_recv_caps_advertise_pdu failed with error %lu!", error); - break; + WLog_ERR(TAG, "rdpgfx_recv_caps_advertise_pdu " + "failed with error %lu!", error); + break; case RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE: - if ((error = rdpgfx_recv_qoe_frame_acknowledge_pdu(context, s))) - WLog_ERR(TAG, "rdpgfx_recv_qoe_frame_acknowledge_pdu failed with error %lu!", error); - break; + if ((error = rdpgfx_recv_qoe_frame_acknowledge_pdu(context, s))) + WLog_ERR(TAG, "rdpgfx_recv_qoe_frame_acknowledge_pdu " + "failed with error %lu!", error); + + break; default: error = CHANNEL_RC_BAD_PROC; break; @@ -1281,90 +1314,31 @@ static UINT rdpgfx_server_receive_pdu(RdpgfxServerContext* context, wStream* s) if (end != (beg + header.pduLength)) { WLog_ERR(TAG, "Unexpected gfx pdu end: Actual: %d, Expected: %d", - end, (beg + header.pduLength)); + end, (beg + header.pduLength)); Stream_SetPosition(s, (beg + header.pduLength)); } return error; - } static void* rdpgfx_server_thread_func(void* arg) { RdpgfxServerContext* context = (RdpgfxServerContext*) arg; RdpgfxServerPrivate* priv = context->priv; - wStream* s; DWORD status; DWORD nCount; void* buffer; HANDLE events[8]; - HANDLE ChannelEvent; DWORD BytesReturned = 0; UINT error = CHANNEL_RC_OK; - BOOL ready = FALSE; - buffer = NULL; BytesReturned = 0; - ChannelEvent = NULL; - - /* Query for channel event handle */ - if (WTSVirtualChannelQuery(priv->rdpgfx_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) - { - if (BytesReturned == sizeof(HANDLE)) - CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); - - WTSFreeMemory(buffer); - } - else - { - WLog_ERR(TAG, "WTSVirtualChannelQuery failed"); - error = ERROR_INTERNAL_ERROR; - goto out; - } - nCount = 0; events[nCount++] = priv->stopEvent; - events[nCount++] = ChannelEvent; - - /* Wait for the client to confirm that the dynamic channel is ready */ - while (1) - { - if ((status = WaitForMultipleObjects(nCount, events, FALSE, 100)) == WAIT_OBJECT_0) - goto out; - - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); - goto out; - } - - if (WTSVirtualChannelQuery(priv->rdpgfx_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE) - { - WLog_ERR(TAG, "WTSVirtualChannelQuery failed"); - error = ERROR_INTERNAL_ERROR; - goto out; - } - - ready = *((BOOL*) buffer); - - WTSFreeMemory(buffer); - - if (ready) - break; - } - - /* Create shared stream */ - s = Stream_New(NULL, 4096); - if (!s) - { - WLog_ERR(TAG, "Stream_New failed!"); - error = CHANNEL_RC_NO_MEMORY; - goto out; - } + events[nCount++] = priv->channelEvent; /* Main virtual channel loop. RDPGFX do not need version negotiation */ - while (ready) + while (TRUE) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); @@ -1372,65 +1346,24 @@ static void* rdpgfx_server_thread_func(void* arg) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); - goto out; + break; } - /* Stop Event */ + /* Stop Event */ if (status == WAIT_OBJECT_0) break; - /* Channel Event */ - Stream_SetPosition(s, 0); - - if (!WTSVirtualChannelRead(priv->rdpgfx_channel, 0, NULL, 0, &BytesReturned)) - { - WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); - error = ERROR_INTERNAL_ERROR; - break; - } - - if (BytesReturned < 1) - continue; - - if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) - { - WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); - error = CHANNEL_RC_NO_MEMORY; - break; - } - - if (WTSVirtualChannelRead(priv->rdpgfx_channel, 0, (PCHAR) Stream_Buffer(s), - Stream_Capacity(s), &BytesReturned) == FALSE) - { - WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); - error = ERROR_INTERNAL_ERROR; - break; - } - - Stream_SetLength(s, BytesReturned); - Stream_SetPosition(s, 0); - - while (((size_t) Stream_GetPosition(s)) < Stream_Length(s)) - { - if ((error = rdpgfx_server_receive_pdu(context, s))) - { - WLog_ERR(TAG, "rdpgfx_server_receive_pdu failed with error %lu!", error); - break; - } - } - - if (error != CHANNEL_RC_OK) + if ((error = rdpgfx_server_handle_messages(context))) { + WLog_ERR(TAG, "rdpgfx_server_handle_messages failed with error %lu", + error); break; } } - Stream_Free(s, TRUE); -out: - WTSVirtualChannelClose(priv->rdpgfx_channel); - priv->rdpgfx_channel = NULL; if (error && context->rdpcontext) - setChannelError(context->rdpcontext, error, "rdpgfx_server_thread_func reported an error"); + setChannelError(context->rdpcontext, error, + "rdpgfx_server_thread_func reported an error"); ExitThread((DWORD)error); return NULL; @@ -1438,24 +1371,28 @@ out: static BOOL rdpgfx_server_open(RdpgfxServerContext* context) { - RdpgfxServerPrivate* priv = (RdpgfxServerPrivate *) context->priv; + RdpgfxServerPrivate* priv = (RdpgfxServerPrivate*) context->priv; + void* buffer = NULL; - if (!priv->thread) + if (!priv->isOpened) { PULONG pSessionId = NULL; DWORD BytesReturned = 0; - priv->SessionId = WTS_CURRENT_SESSION; if (WTSQuerySessionInformationA(context->vcm, WTS_CURRENT_SESSION, - WTSSessionId, (LPSTR*) &pSessionId, &BytesReturned)) + WTSSessionId, (LPSTR*) &pSessionId, + &BytesReturned) == FALSE) { - priv->SessionId = (DWORD) *pSessionId; - WTSFreeMemory(pSessionId); + WLog_ERR(TAG, "WTSQuerySessionInformationA failed!"); + return FALSE; } + priv->SessionId = (DWORD) *pSessionId; + WTSFreeMemory(pSessionId); priv->rdpgfx_channel = WTSVirtualChannelOpenEx(priv->SessionId, - RDPGFX_DVC_CHANNEL_NAME, WTS_CHANNEL_OPTION_DYNAMIC); + RDPGFX_DVC_CHANNEL_NAME, + WTS_CHANNEL_OPTION_DYNAMIC); if (!priv->rdpgfx_channel) { @@ -1463,56 +1400,80 @@ static BOOL rdpgfx_server_open(RdpgfxServerContext* context) return FALSE; } + /* Query for channel event handle */ + if (!WTSVirtualChannelQuery(priv->rdpgfx_channel, WTSVirtualEventHandle, + &buffer, &BytesReturned) + || (BytesReturned != sizeof(HANDLE))) + { + WLog_ERR(TAG, "WTSVirtualChannelQuery failed " + "or invalid returned size(%d)", + BytesReturned); + + if (buffer) + WTSFreeMemory(buffer); + + goto out_close; + } + + CopyMemory(&priv->channelEvent, buffer, sizeof(HANDLE)); + WTSFreeMemory(buffer); + if (!(priv->zgfx = zgfx_context_new(TRUE))) { WLog_ERR(TAG, "Create zgfx context failed!"); goto out_close; } - if (!(priv->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + if (priv->ownThread) { - WLog_ERR(TAG, "CreateEvent failed!"); - goto out_zgfx; - } - - if (!(priv->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) rdpgfx_server_thread_func, (void*) context, 0, NULL))) - { - WLog_ERR(TAG, "CreateThread failed!"); - goto out_stopEvent; + if (!(priv->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + WLog_ERR(TAG, "CreateEvent failed!"); + goto out_zgfx; + } + + if (!(priv->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) + rdpgfx_server_thread_func, + (void*) context, 0, NULL))) + { + WLog_ERR(TAG, "CreateThread failed!"); + goto out_stopEvent; + } } + priv->isOpened = TRUE; + priv->isReady = FALSE; return TRUE; } - WLog_ERR(TAG, "thread already running!"); + WLog_ERR(TAG, "RDPGFX channel is already opened!"); return FALSE; - out_stopEvent: CloseHandle(priv->stopEvent); priv->stopEvent = NULL; - out_zgfx: zgfx_context_free(priv->zgfx); priv->zgfx = NULL; - out_close: WTSVirtualChannelClose(priv->rdpgfx_channel); priv->rdpgfx_channel = NULL; - + priv->channelEvent = NULL; return FALSE; } static BOOL rdpgfx_server_close(RdpgfxServerContext* context) { - RdpgfxServerPrivate* priv = (RdpgfxServerPrivate *) context->priv; + RdpgfxServerPrivate* priv = (RdpgfxServerPrivate*) context->priv; - if (priv->thread) + if (priv->ownThread && priv->thread) { SetEvent(priv->stopEvent); + if (WaitForSingleObject(priv->thread, INFINITE) == WAIT_FAILED) { - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", GetLastError()); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", + GetLastError()); return FALSE; } @@ -1531,15 +1492,18 @@ static BOOL rdpgfx_server_close(RdpgfxServerContext* context) priv->rdpgfx_channel = NULL; } + priv->channelEvent = NULL; + priv->isOpened = FALSE; + priv->isReady = FALSE; return TRUE; } RdpgfxServerContext* rdpgfx_server_context_new(HANDLE vcm) { RdpgfxServerContext* context; - RdpgfxServerPrivate *priv; + RdpgfxServerPrivate* priv; + context = (RdpgfxServerContext*)calloc(1, sizeof(RdpgfxServerContext)); - context = (RdpgfxServerContext *)calloc(1, sizeof(RdpgfxServerContext)); if (!context) { WLog_ERR(TAG, "calloc failed!"); @@ -1549,7 +1513,6 @@ RdpgfxServerContext* rdpgfx_server_context_new(HANDLE vcm) context->vcm = vcm; context->Open = rdpgfx_server_open; context->Close = rdpgfx_server_close; - context->ResetGraphics = rdpgfx_send_reset_graphics_pdu; context->StartFrame = rdpgfx_send_start_frame_pdu; context->EndFrame = rdpgfx_send_end_frame_pdu; @@ -1571,16 +1534,30 @@ RdpgfxServerContext* rdpgfx_server_context_new(HANDLE vcm) context->CapsConfirm = rdpgfx_send_caps_confirm_pdu; context->FrameAcknowledge = NULL; context->QoeFrameAcknowledge = NULL; + context->priv = priv = (RdpgfxServerPrivate*) + calloc(1, sizeof(RdpgfxServerPrivate)); - context->priv = priv = (RdpgfxServerPrivate *)calloc(1, sizeof(RdpgfxServerPrivate)); if (!priv) { WLog_ERR(TAG, "calloc failed!"); goto out_free; } - return (RdpgfxServerContext*) context; + /* Create shared input stream */ + priv->input_stream = Stream_New(NULL, 4); + if (!priv->input_stream) + { + WLog_ERR(TAG, "Stream_New failed!"); + goto out_free_priv; + } + + priv->isOpened = FALSE; + priv->isReady = FALSE; + priv->ownThread = TRUE; + return (RdpgfxServerContext*) context; +out_free_priv: + free(context->priv); out_free: free(context); return NULL; @@ -1590,7 +1567,98 @@ void rdpgfx_server_context_free(RdpgfxServerContext* context) { rdpgfx_server_close(context); - free(context->priv); + if (context->priv) + Stream_Free(context->priv->input_stream, TRUE); + free(context->priv); free(context); } + +FREERDP_API HANDLE rdpgfx_server_get_event_handle(RdpgfxServerContext* context) +{ + return context->priv->channelEvent; +} + +/* + * Handle rpdgfx messages - server side + * + * @param Server side context + * + * @return 0 on success + * ERROR_NO_DATA if no data could be read this time + * otherwise a Win32 error code + */ +UINT rdpgfx_server_handle_messages(RdpgfxServerContext* context) +{ + DWORD BytesReturned; + void* buffer; + UINT ret = CHANNEL_RC_OK; + RdpgfxServerPrivate* priv = context->priv; + wStream* s = priv->input_stream; + + /* Check whether the dynamic channel is ready */ + if (!priv->isReady) + { + if (WTSVirtualChannelQuery(priv->rdpgfx_channel, + WTSVirtualChannelReady, + &buffer, &BytesReturned) == FALSE) + { + if (GetLastError() == ERROR_NO_DATA) + return ERROR_NO_DATA; + + WLog_ERR(TAG, "WTSVirtualChannelQuery failed"); + return ERROR_INTERNAL_ERROR; + } + + priv->isReady = *((BOOL*) buffer); + WTSFreeMemory(buffer); + } + + /* Consume channel event only after the gfx dynamic channel is ready */ + if (priv->isReady) + { + Stream_SetPosition(s, 0); + + if (!WTSVirtualChannelRead(priv->rdpgfx_channel, + 0, NULL, 0, &BytesReturned)) + { + if (GetLastError() == ERROR_NO_DATA) + return ERROR_NO_DATA; + + WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); + return ERROR_INTERNAL_ERROR; + } + + if (BytesReturned < 1) + return CHANNEL_RC_OK; + + if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) + { + WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + if (WTSVirtualChannelRead(priv->rdpgfx_channel, 0, + (PCHAR) Stream_Buffer(s), + Stream_Capacity(s), &BytesReturned) == FALSE) + { + WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); + return ERROR_INTERNAL_ERROR; + } + + Stream_SetLength(s, BytesReturned); + Stream_SetPosition(s, 0); + + while (((size_t) Stream_GetPosition(s)) < Stream_Length(s)) + { + if ((ret = rdpgfx_server_receive_pdu(context, s))) + { + WLog_ERR(TAG, "rdpgfx_server_receive_pdu " + "failed with error %lu!", ret); + return ret; + } + } + } + + return ret; +} diff --git a/channels/rdpgfx/server/rdpgfx_main.h b/channels/rdpgfx/server/rdpgfx_main.h index caad8ccf1..be29b7638 100644 --- a/channels/rdpgfx/server/rdpgfx_main.h +++ b/channels/rdpgfx/server/rdpgfx_main.h @@ -26,11 +26,15 @@ struct _rdpgfx_server_private { ZGFX_CONTEXT* zgfx; + BOOL ownThread; HANDLE thread; HANDLE stopEvent; + HANDLE channelEvent; void* rdpgfx_channel; DWORD SessionId; - BOOL opened; + wStream* input_stream; + BOOL isOpened; + BOOL isReady; }; #endif /* FREERDP_CHANNEL_RDPGFX_SERVER_MAIN_H */ diff --git a/include/freerdp/server/rdpgfx.h b/include/freerdp/server/rdpgfx.h index 983779e11..fad778935 100644 --- a/include/freerdp/server/rdpgfx.h +++ b/include/freerdp/server/rdpgfx.h @@ -28,27 +28,27 @@ typedef struct _rdpgfx_server_private RdpgfxServerPrivate; typedef BOOL (*psRdpgfxServerOpen)(RdpgfxServerContext* context); typedef BOOL (*psRdpgfxServerClose)(RdpgfxServerContext* context); -typedef UINT (*psRdpgfxResetGraphics)(RdpgfxServerContext* context, RDPGFX_RESET_GRAPHICS_PDU* resetGraphics); -typedef UINT (*psRdpgfxStartFrame)(RdpgfxServerContext* context, RDPGFX_START_FRAME_PDU* startFrame); -typedef UINT (*psRdpgfxEndFrame)(RdpgfxServerContext* context, RDPGFX_END_FRAME_PDU* endFrame); -typedef UINT (*psRdpgfxSurfaceCommand)(RdpgfxServerContext* context, RDPGFX_SURFACE_COMMAND* cmd); -typedef UINT (*psRdpgfxSurfaceFrameCommand)(RdpgfxServerContext* context, RDPGFX_SURFACE_COMMAND* cmd, RDPGFX_START_FRAME_PDU* startFrame, RDPGFX_END_FRAME_PDU* endFrame); -typedef UINT (*psRdpgfxDeleteEncodingContext)(RdpgfxServerContext* context, RDPGFX_DELETE_ENCODING_CONTEXT_PDU* deleteEncodingContext); -typedef UINT (*psRdpgfxCreateSurface)(RdpgfxServerContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface); -typedef UINT (*psRdpgfxDeleteSurface)(RdpgfxServerContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface); -typedef UINT (*psRdpgfxSolidFill)(RdpgfxServerContext* context, RDPGFX_SOLID_FILL_PDU* solidFill); -typedef UINT (*psRdpgfxSurfaceToSurface)(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface); -typedef UINT (*psRdpgfxSurfaceToCache)(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_CACHE_PDU* surfaceToCache); -typedef UINT (*psRdpgfxCacheToSurface)(RdpgfxServerContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface); -typedef UINT (*psRdpgfxCacheImportOffer)(RdpgfxServerContext* context, RDPGFX_CACHE_IMPORT_OFFER_PDU* cacheImportOffer); -typedef UINT (*psRdpgfxCacheImportReply)(RdpgfxServerContext* context, RDPGFX_CACHE_IMPORT_REPLY_PDU* cacheImportReply); -typedef UINT (*psRdpgfxEvictCacheEntry)(RdpgfxServerContext* context, RDPGFX_EVICT_CACHE_ENTRY_PDU* evictCacheEntry); -typedef UINT (*psRdpgfxMapSurfaceToOutput)(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput); -typedef UINT (*psRdpgfxMapSurfaceToWindow)(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow); -typedef UINT (*psRdpgfxCapsAdvertise)(RdpgfxServerContext* context, RDPGFX_CAPS_ADVERTISE_PDU* capsAdvertise); -typedef UINT (*psRdpgfxCapsConfirm)(RdpgfxServerContext* context, RDPGFX_CAPS_CONFIRM_PDU* capsConfirm); -typedef UINT (*psRdpgfxFrameAcknowledge)(RdpgfxServerContext* context, RDPGFX_FRAME_ACKNOWLEDGE_PDU* frameAcknowledge); -typedef UINT (*psRdpgfxQoeFrameAcknowledge)(RdpgfxServerContext* context, RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* qoeFrameAcknowledge); +typedef UINT(*psRdpgfxResetGraphics)(RdpgfxServerContext* context, RDPGFX_RESET_GRAPHICS_PDU* resetGraphics); +typedef UINT(*psRdpgfxStartFrame)(RdpgfxServerContext* context, RDPGFX_START_FRAME_PDU* startFrame); +typedef UINT(*psRdpgfxEndFrame)(RdpgfxServerContext* context, RDPGFX_END_FRAME_PDU* endFrame); +typedef UINT(*psRdpgfxSurfaceCommand)(RdpgfxServerContext* context, RDPGFX_SURFACE_COMMAND* cmd); +typedef UINT(*psRdpgfxSurfaceFrameCommand)(RdpgfxServerContext* context, RDPGFX_SURFACE_COMMAND* cmd, RDPGFX_START_FRAME_PDU* startFrame, RDPGFX_END_FRAME_PDU* endFrame); +typedef UINT(*psRdpgfxDeleteEncodingContext)(RdpgfxServerContext* context, RDPGFX_DELETE_ENCODING_CONTEXT_PDU* deleteEncodingContext); +typedef UINT(*psRdpgfxCreateSurface)(RdpgfxServerContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface); +typedef UINT(*psRdpgfxDeleteSurface)(RdpgfxServerContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface); +typedef UINT(*psRdpgfxSolidFill)(RdpgfxServerContext* context, RDPGFX_SOLID_FILL_PDU* solidFill); +typedef UINT(*psRdpgfxSurfaceToSurface)(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface); +typedef UINT(*psRdpgfxSurfaceToCache)(RdpgfxServerContext* context, RDPGFX_SURFACE_TO_CACHE_PDU* surfaceToCache); +typedef UINT(*psRdpgfxCacheToSurface)(RdpgfxServerContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface); +typedef UINT(*psRdpgfxCacheImportOffer)(RdpgfxServerContext* context, RDPGFX_CACHE_IMPORT_OFFER_PDU* cacheImportOffer); +typedef UINT(*psRdpgfxCacheImportReply)(RdpgfxServerContext* context, RDPGFX_CACHE_IMPORT_REPLY_PDU* cacheImportReply); +typedef UINT(*psRdpgfxEvictCacheEntry)(RdpgfxServerContext* context, RDPGFX_EVICT_CACHE_ENTRY_PDU* evictCacheEntry); +typedef UINT(*psRdpgfxMapSurfaceToOutput)(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput); +typedef UINT(*psRdpgfxMapSurfaceToWindow)(RdpgfxServerContext* context, RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow); +typedef UINT(*psRdpgfxCapsAdvertise)(RdpgfxServerContext* context, RDPGFX_CAPS_ADVERTISE_PDU* capsAdvertise); +typedef UINT(*psRdpgfxCapsConfirm)(RdpgfxServerContext* context, RDPGFX_CAPS_CONFIRM_PDU* capsConfirm); +typedef UINT(*psRdpgfxFrameAcknowledge)(RdpgfxServerContext* context, RDPGFX_FRAME_ACKNOWLEDGE_PDU* frameAcknowledge); +typedef UINT(*psRdpgfxQoeFrameAcknowledge)(RdpgfxServerContext* context, RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* qoeFrameAcknowledge); struct _rdpgfx_server_context { @@ -90,6 +90,8 @@ extern "C" { FREERDP_API RdpgfxServerContext* rdpgfx_server_context_new(HANDLE vcm); FREERDP_API void rdpgfx_server_context_free(RdpgfxServerContext* context); +FREERDP_API HANDLE rdpgfx_server_get_event_handle(RdpgfxServerContext* context); +FREERDP_API UINT rdpgfx_server_handle_messages(RdpgfxServerContext* context); #ifdef __cplusplus }