void update_recv(rdpUpdate* update, STREAM* s) { uint16 updateType; stream_read_uint16(s, updateType); /* updateType (2 bytes) */ //printf("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]); IFCALL(update->BeginPaint, update); switch (updateType) { case UPDATE_TYPE_ORDERS: update_recv_orders(update, s); break; case UPDATE_TYPE_BITMAP: update_read_bitmap(update, s, &update->bitmap_update); IFCALL(update->Bitmap, update, &update->bitmap_update); break; case UPDATE_TYPE_PALETTE: update_read_palette(update, s, &update->palette_update); IFCALL(update->Palette, update, &update->palette_update); break; case UPDATE_TYPE_SYNCHRONIZE: update_read_synchronize(update, s); IFCALL(update->Synchronize, update); break; } IFCALL(update->EndPaint, update); if (stream_get_left(s) > RDP_SHARE_DATA_HEADER_LENGTH) { uint8 type; uint16 pduType; uint16 length; uint16 source; uint32 shareId; uint8 compressed_type; uint16 compressed_len; rdp_read_share_control_header(s, &length, &pduType, &source); if (pduType != PDU_TYPE_DATA) return; rdp_read_share_data_header(s, &length, &type, &shareId, &compressed_type, &compressed_len); if (type == DATA_PDU_TYPE_UPDATE) update_recv(update, s); } }
void test_update_recv_orders(void) { rdpRdp* rdp; STREAM _s, *s; rdpUpdate* update; s = &_s; rdp = rdp_new(NULL); update = update_new(rdp); update->context = malloc(sizeof(rdpContext)); update->context->rdp = rdp; opaque_rect_count = 0; polyline_count = 0; patblt_count = 0; update->primary->OpaqueRect = test_opaque_rect; update->primary->Polyline = test_polyline; update->primary->PatBlt = test_patblt; s->p = s->data = orders_update_1; s->size = sizeof(orders_update_1); update_recv(update, s); CU_ASSERT(opaque_rect_count == 5); CU_ASSERT(polyline_count == 2); update->primary->order_info.orderType = ORDER_TYPE_PATBLT; s->p = s->data = orders_update_2; s->size = sizeof(orders_update_2); update_recv(update, s); CU_ASSERT(patblt_count == 3); free(update->context); }
void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s) { uint8 type; uint16 length; uint32 share_id; uint8 compressed_type; uint16 compressed_len; rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len); #ifdef WITH_DEBUG_RDP if (type != DATA_PDU_TYPE_UPDATE) printf("recv %s Data PDU (0x%02X), length:%d\n", DATA_PDU_TYPE_STRINGS[type], type, length); #endif switch (type) { case DATA_PDU_TYPE_UPDATE: update_recv(rdp->update, s); break; case DATA_PDU_TYPE_CONTROL: rdp_recv_server_control_pdu(rdp, s); break; case DATA_PDU_TYPE_POINTER: update_recv_pointer(rdp->update, s); break; case DATA_PDU_TYPE_INPUT: break; case DATA_PDU_TYPE_SYNCHRONIZE: rdp_recv_synchronize_pdu(rdp, s); break; case DATA_PDU_TYPE_REFRESH_RECT: break; case DATA_PDU_TYPE_PLAY_SOUND: update_recv_play_sound(rdp->update, s); break; case DATA_PDU_TYPE_SUPPRESS_OUTPUT: break; case DATA_PDU_TYPE_SHUTDOWN_REQUEST: break; case DATA_PDU_TYPE_SHUTDOWN_DENIED: break; case DATA_PDU_TYPE_SAVE_SESSION_INFO: rdp_recv_save_session_info(rdp, s); break; case DATA_PDU_TYPE_FONT_LIST: break; case DATA_PDU_TYPE_FONT_MAP: rdp_recv_font_map_pdu(rdp, s); break; case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS: break; case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST: break; case DATA_PDU_TYPE_BITMAP_CACHE_ERROR: break; case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS: break; case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR: break; case DATA_PDU_TYPE_SET_ERROR_INFO: rdp_recv_set_error_info_data_pdu(rdp, s); break; case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR: break; case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR: break; case DATA_PDU_TYPE_ARC_STATUS: break; case DATA_PDU_TYPE_STATUS_INFO: break; case DATA_PDU_TYPE_MONITOR_LAYOUT: break; default: break; } }
int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) { BYTE type; wStream* cs; UINT16 length; UINT32 shareId; BYTE compressedType; UINT16 compressedLength; if (!rdp_read_share_data_header(s, &length, &type, &shareId, &compressedType, &compressedLength)) return -1; cs = s; if (compressedType & PACKET_COMPRESSED) { UINT32 DstSize = 0; BYTE* pDstData = NULL; UINT32 SrcSize = compressedLength - 18; if (Stream_GetRemainingLength(s) < (size_t) SrcSize) { DEBUG_WARN( "bulk_decompress: not enough bytes for compressedLength %d\n", compressedLength); return -1; } if (bulk_decompress(rdp->bulk, Stream_Pointer(s), SrcSize, &pDstData, &DstSize, compressedType)) { cs = StreamPool_Take(rdp->transport->ReceivePool, DstSize); Stream_SetPosition(cs, 0); Stream_Write(cs, pDstData, DstSize); Stream_SealLength(cs); Stream_SetPosition(cs, 0); } else { DEBUG_WARN( "bulk_decompress() failed\n"); return -1; } Stream_Seek(s, SrcSize); } #ifdef WITH_DEBUG_RDP DEBUG_MSG("recv %s Data PDU (0x%02X), length: %d\n", type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length); #endif switch (type) { case DATA_PDU_TYPE_UPDATE: if (!update_recv(rdp->update, cs)) return -1; break; case DATA_PDU_TYPE_CONTROL: if (!rdp_recv_server_control_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_POINTER: if (!update_recv_pointer(rdp->update, cs)) return -1; break; case DATA_PDU_TYPE_SYNCHRONIZE: if (!rdp_recv_synchronize_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_PLAY_SOUND: if (!update_recv_play_sound(rdp->update, cs)) return -1; break; case DATA_PDU_TYPE_SHUTDOWN_DENIED: if (!rdp_recv_server_shutdown_denied_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_SAVE_SESSION_INFO: if (!rdp_recv_save_session_info(rdp, cs)) return -1; break; case DATA_PDU_TYPE_FONT_MAP: if (!rdp_recv_font_map_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS: if (!rdp_recv_server_set_keyboard_indicators_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS: if (!rdp_recv_server_set_keyboard_ime_status_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_SET_ERROR_INFO: if (!rdp_recv_set_error_info_data_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_ARC_STATUS: if (!rdp_recv_server_auto_reconnect_status_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_STATUS_INFO: if (!rdp_recv_server_status_info_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_MONITOR_LAYOUT: if (!rdp_recv_monitor_layout_pdu(rdp, cs)) return -1; break; default: break; } if (cs != s) Stream_Release(cs); return 0; }
int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) { BYTE type; UINT32 roff; UINT32 rlen; wStream* cs; BYTE* buffer; UINT16 length; UINT32 share_id; BYTE compressed_type; UINT16 compressed_len; if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len)) return -1; cs = s; if (compressed_type & PACKET_COMPRESSED) { if (Stream_GetRemainingLength(s) < compressed_len - 18) { fprintf(stderr, "decompress_rdp: not enough bytes for compressed_len=%d\n", compressed_len); return -1; } if (decompress_rdp(rdp->mppc_dec, Stream_Pointer(s), compressed_len - 18, compressed_type, &roff, &rlen)) { buffer = rdp->mppc_dec->history_buf + roff; cs = StreamPool_Take(rdp->transport->ReceivePool, rlen); Stream_SetPosition(cs, 0); Stream_Write(cs, buffer, rlen); Stream_SealLength(cs); Stream_SetPosition(cs, 0); } else { fprintf(stderr, "decompress_rdp() failed\n"); return -1; } Stream_Seek(s, compressed_len - 18); } #ifdef WITH_DEBUG_RDP /* if (type != DATA_PDU_TYPE_UPDATE) */ DEBUG_RDP("recv %s Data PDU (0x%02X), length:%d", type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length); #endif switch (type) { case DATA_PDU_TYPE_UPDATE: if (!update_recv(rdp->update, cs)) return -1; break; case DATA_PDU_TYPE_CONTROL: if (!rdp_recv_server_control_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_POINTER: if (!update_recv_pointer(rdp->update, cs)) return -1; break; case DATA_PDU_TYPE_INPUT: break; case DATA_PDU_TYPE_SYNCHRONIZE: if (!rdp_recv_synchronize_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_REFRESH_RECT: break; case DATA_PDU_TYPE_PLAY_SOUND: if (!update_recv_play_sound(rdp->update, cs)) return -1; break; case DATA_PDU_TYPE_SUPPRESS_OUTPUT: break; case DATA_PDU_TYPE_SHUTDOWN_REQUEST: break; case DATA_PDU_TYPE_SHUTDOWN_DENIED: break; case DATA_PDU_TYPE_SAVE_SESSION_INFO: if (!rdp_recv_save_session_info(rdp, cs)) return -1; break; case DATA_PDU_TYPE_FONT_LIST: break; case DATA_PDU_TYPE_FONT_MAP: if (!rdp_recv_font_map_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS: break; case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST: break; case DATA_PDU_TYPE_BITMAP_CACHE_ERROR: break; case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS: break; case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR: break; case DATA_PDU_TYPE_SET_ERROR_INFO: if (!rdp_recv_set_error_info_data_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR: break; case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR: break; case DATA_PDU_TYPE_ARC_STATUS: break; case DATA_PDU_TYPE_STATUS_INFO: break; case DATA_PDU_TYPE_MONITOR_LAYOUT: break; default: break; } if (cs != s) Stream_Release(cs); return 0; }
tbool rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s) { uint8 type; uint16 length; uint32 share_id; uint8 compressed_type; uint16 compressed_len; uint32 roff; uint32 rlen; STREAM* comp_stream; rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len); comp_stream = s; if (compressed_type & PACKET_COMPRESSED) { if (decompress_rdp(rdp, s->p, compressed_len - 18, compressed_type, &roff, &rlen)) { comp_stream = stream_new(0); comp_stream->data = rdp->mppc->history_buf + roff; comp_stream->p = comp_stream->data; comp_stream->size = rlen; } else { printf("decompress_rdp() failed\n"); return false; } } #ifdef WITH_DEBUG_RDP if (type != DATA_PDU_TYPE_UPDATE) printf("recv %s Data PDU (0x%02X), length:%d\n", DATA_PDU_TYPE_STRINGS[type], type, length); #endif switch (type) { case DATA_PDU_TYPE_UPDATE: update_recv(rdp->update, comp_stream); break; case DATA_PDU_TYPE_CONTROL: rdp_recv_server_control_pdu(rdp, comp_stream); break; case DATA_PDU_TYPE_POINTER: update_recv_pointer(rdp->update, comp_stream); break; case DATA_PDU_TYPE_INPUT: break; case DATA_PDU_TYPE_SYNCHRONIZE: rdp_recv_synchronize_pdu(rdp, comp_stream); break; case DATA_PDU_TYPE_REFRESH_RECT: break; case DATA_PDU_TYPE_PLAY_SOUND: update_recv_play_sound(rdp->update, comp_stream); break; case DATA_PDU_TYPE_SUPPRESS_OUTPUT: break; case DATA_PDU_TYPE_SHUTDOWN_REQUEST: break; case DATA_PDU_TYPE_SHUTDOWN_DENIED: break; case DATA_PDU_TYPE_SAVE_SESSION_INFO: rdp_recv_save_session_info(rdp, comp_stream); break; case DATA_PDU_TYPE_FONT_LIST: break; case DATA_PDU_TYPE_FONT_MAP: rdp_recv_font_map_pdu(rdp, comp_stream); break; case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS: break; case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST: break; case DATA_PDU_TYPE_BITMAP_CACHE_ERROR: break; case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS: break; case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR: break; case DATA_PDU_TYPE_SET_ERROR_INFO: rdp_recv_set_error_info_data_pdu(rdp, comp_stream); break; case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR: break; case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR: break; case DATA_PDU_TYPE_ARC_STATUS: break; case DATA_PDU_TYPE_STATUS_INFO: break; case DATA_PDU_TYPE_MONITOR_LAYOUT: break; default: break; } if (comp_stream != s) { stream_detach(comp_stream); stream_free(comp_stream); } return true; }
int rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s) { BYTE type; UINT16 length; UINT32 share_id; BYTE compressed_type; UINT16 compressed_len; UINT32 roff; UINT32 rlen; STREAM* comp_stream; if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len)) return -1; comp_stream = s; if (compressed_type & PACKET_COMPRESSED) { if (stream_get_left(s) < compressed_len - 18) { printf("decompress_rdp: not enough bytes for compressed_len=%d\n", compressed_len); return -1; } if (decompress_rdp(rdp->mppc_dec, s->p, compressed_len - 18, compressed_type, &roff, &rlen)) { comp_stream = stream_new(0); comp_stream->data = rdp->mppc_dec->history_buf + roff; comp_stream->p = comp_stream->data; comp_stream->size = rlen; } else { printf("decompress_rdp() failed\n"); return -1; } stream_seek(s, compressed_len - 18); } #ifdef WITH_DEBUG_RDP /* if (type != DATA_PDU_TYPE_UPDATE) */ DEBUG_RDP("recv %s Data PDU (0x%02X), length:%d", type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length); #endif switch (type) { case DATA_PDU_TYPE_UPDATE: if (!update_recv(rdp->update, comp_stream)) return -1; break; case DATA_PDU_TYPE_CONTROL: if (!rdp_recv_server_control_pdu(rdp, comp_stream)) return -1; break; case DATA_PDU_TYPE_POINTER: if (!update_recv_pointer(rdp->update, comp_stream)) return -1; break; case DATA_PDU_TYPE_INPUT: break; case DATA_PDU_TYPE_SYNCHRONIZE: if (!rdp_recv_synchronize_pdu(rdp, comp_stream)) return -1; break; case DATA_PDU_TYPE_REFRESH_RECT: break; case DATA_PDU_TYPE_PLAY_SOUND: if (!update_recv_play_sound(rdp->update, comp_stream)) return -1; break; case DATA_PDU_TYPE_SUPPRESS_OUTPUT: break; case DATA_PDU_TYPE_SHUTDOWN_REQUEST: break; case DATA_PDU_TYPE_SHUTDOWN_DENIED: break; case DATA_PDU_TYPE_SAVE_SESSION_INFO: if(!rdp_recv_save_session_info(rdp, comp_stream)) return -1; break; case DATA_PDU_TYPE_FONT_LIST: break; case DATA_PDU_TYPE_FONT_MAP: if(!rdp_recv_font_map_pdu(rdp, comp_stream)) return -1; break; case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS: break; case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST: break; case DATA_PDU_TYPE_BITMAP_CACHE_ERROR: break; case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS: break; case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR: break; case DATA_PDU_TYPE_SET_ERROR_INFO: if (!rdp_recv_set_error_info_data_pdu(rdp, comp_stream)) return -1; break; case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR: break; case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR: break; case DATA_PDU_TYPE_ARC_STATUS: break; case DATA_PDU_TYPE_STATUS_INFO: break; case DATA_PDU_TYPE_MONITOR_LAYOUT: break; default: break; } if (comp_stream != s) { stream_detach(comp_stream); stream_free(comp_stream); } return 0; }