int rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { int status; int beg, end; RDPGFX_HEADER header; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; beg = Stream_GetPosition(s); status = rdpgfx_read_header(s, &header); if (status < 0) return -1; #if 1 WLog_Print(gfx->log, WLOG_DEBUG, "cmdId: %s (0x%04X) flags: 0x%04X pduLength: %d", rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, header.flags, header.pduLength); #endif switch (header.cmdId) { case RDPGFX_CMDID_WIRETOSURFACE_1: status = rdpgfx_recv_wire_to_surface_1_pdu(callback, s); break; case RDPGFX_CMDID_WIRETOSURFACE_2: status = rdpgfx_recv_wire_to_surface_2_pdu(callback, s); break; case RDPGFX_CMDID_DELETEENCODINGCONTEXT: status = rdpgfx_recv_delete_encoding_context_pdu(callback, s); break; case RDPGFX_CMDID_SOLIDFILL: status = rdpgfx_recv_solid_fill_pdu(callback, s); break; case RDPGFX_CMDID_SURFACETOSURFACE: status = rdpgfx_recv_surface_to_surface_pdu(callback, s); break; case RDPGFX_CMDID_SURFACETOCACHE: status = rdpgfx_recv_surface_to_cache_pdu(callback, s); break; case RDPGFX_CMDID_CACHETOSURFACE: status = rdpgfx_recv_cache_to_surface_pdu(callback, s); break; case RDPGFX_CMDID_EVICTCACHEENTRY: status = rdpgfx_recv_evict_cache_entry_pdu(callback, s); break; case RDPGFX_CMDID_CREATESURFACE: status = rdpgfx_recv_create_surface_pdu(callback, s); break; case RDPGFX_CMDID_DELETESURFACE: status = rdpgfx_recv_delete_surface_pdu(callback, s); break; case RDPGFX_CMDID_STARTFRAME: status = rdpgfx_recv_start_frame_pdu(callback, s); break; case RDPGFX_CMDID_ENDFRAME: status = rdpgfx_recv_end_frame_pdu(callback, s); break; case RDPGFX_CMDID_RESETGRAPHICS: status = rdpgfx_recv_reset_graphics_pdu(callback, s); break; case RDPGFX_CMDID_MAPSURFACETOOUTPUT: status = rdpgfx_recv_map_surface_to_output_pdu(callback, s); break; case RDPGFX_CMDID_CACHEIMPORTREPLY: status = rdpgfx_recv_cache_import_reply_pdu(callback, s); break; case RDPGFX_CMDID_CAPSCONFIRM: status = rdpgfx_recv_caps_confirm_pdu(callback, s); break; case RDPGFX_CMDID_MAPSURFACETOWINDOW: status = rdpgfx_recv_map_surface_to_window_pdu(callback, s); break; default: status = -1; break; } if (status < 0) { WLog_ERR(TAG, "Error while parsing GFX cmdId: %s (0x%04X)", rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId); return -1; } end = Stream_GetPosition(s); if (end != (beg + header.pduLength)) { WLog_ERR(TAG, "Unexpected gfx pdu end: Actual: %d, Expected: %d", end, (beg + header.pduLength)); Stream_SetPosition(s, (beg + header.pduLength)); } return status; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { size_t beg, end; RDPGFX_HEADER header; UINT error; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; beg = Stream_GetPosition(s); if ((error = rdpgfx_read_header(s, &header))) { WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_read_header failed with error %"PRIu32"!", error); return error; } WLog_Print(gfx->log, WLOG_DEBUG, "cmdId: %s (0x%04"PRIX16") flags: 0x%04"PRIX16" pduLength: %"PRIu32"", rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, header.flags, header.pduLength); switch (header.cmdId) { case RDPGFX_CMDID_WIRETOSURFACE_1: if ((error = rdpgfx_recv_wire_to_surface_1_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_wire_to_surface_1_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_WIRETOSURFACE_2: if ((error = rdpgfx_recv_wire_to_surface_2_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_wire_to_surface_2_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_DELETEENCODINGCONTEXT: if ((error = rdpgfx_recv_delete_encoding_context_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_delete_encoding_context_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_SOLIDFILL: if ((error = rdpgfx_recv_solid_fill_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_solid_fill_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_SURFACETOSURFACE: if ((error = rdpgfx_recv_surface_to_surface_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_surface_to_surface_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_SURFACETOCACHE: if ((error = rdpgfx_recv_surface_to_cache_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_surface_to_cache_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_CACHETOSURFACE: if ((error = rdpgfx_recv_cache_to_surface_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_cache_to_surface_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_EVICTCACHEENTRY: if ((error = rdpgfx_recv_evict_cache_entry_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_evict_cache_entry_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_CREATESURFACE: if ((error = rdpgfx_recv_create_surface_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_create_surface_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_DELETESURFACE: if ((error = rdpgfx_recv_delete_surface_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_delete_surface_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_STARTFRAME: if ((error = rdpgfx_recv_start_frame_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_start_frame_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_ENDFRAME: if ((error = rdpgfx_recv_end_frame_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_end_frame_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_RESETGRAPHICS: if ((error = rdpgfx_recv_reset_graphics_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_reset_graphics_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_MAPSURFACETOOUTPUT: if ((error = rdpgfx_recv_map_surface_to_output_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_map_surface_to_output_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_CACHEIMPORTREPLY: if ((error = rdpgfx_recv_cache_import_reply_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_cache_import_reply_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_CAPSCONFIRM: if ((error = rdpgfx_recv_caps_confirm_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_caps_confirm_pdu failed with error %"PRIu32"!", error); break; case RDPGFX_CMDID_MAPSURFACETOWINDOW: if ((error = rdpgfx_recv_map_surface_to_window_pdu(callback, s))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_recv_map_surface_to_window_pdu failed with error %"PRIu32"!", error); break; default: error = CHANNEL_RC_BAD_PROC; break; } if (error) { WLog_Print(gfx->log, WLOG_ERROR, "Error while parsing GFX cmdId: %s (0x%04"PRIX16")", rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId); return error; } end = Stream_GetPosition(s); if (end != (beg + header.pduLength)) { WLog_Print(gfx->log, WLOG_ERROR, "Unexpected gfx pdu end: Actual: %d, Expected: %"PRIu32"", end, (beg + header.pduLength)); Stream_SetPosition(s, (beg + header.pduLength)); } return error; }