/* Process an update PDU */ static void process_update_pdu(STREAM s) { uint16 update_type, count; in_uint16_le(s, update_type); ui_begin_update(); switch (update_type) { case RDP_UPDATE_ORDERS: in_uint8s(s, 2); /* pad */ in_uint16_le(s, count); in_uint8s(s, 2); /* pad */ process_orders(s, count); break; case RDP_UPDATE_BITMAP: process_bitmap_updates(s); break; case RDP_UPDATE_PALETTE: process_palette(s); break; case RDP_UPDATE_SYNCHRONIZE: break; default: unimpl("update %d\n", update_type); } ui_end_update(); }
static int xrdp_caps_process_glyphcache(struct xrdp_rdp *self, struct stream *s, int len) { int glyph_support_level; if (len < 40 + 4 + 2 + 2) /* MS-RDPBCGR 2.2.7.1.8 */ { g_writeln("xrdp_caps_process_glyphcache: error"); return 1; } in_uint8s(s, 40); /* glyph cache */ in_uint8s(s, 4); /* frag cache */ in_uint16_le(s, glyph_support_level); in_uint8s(s, 2); /* pad */ if (glyph_support_level == GLYPH_SUPPORT_ENCODE) { self->client_info.use_cache_glyph_v2 = 1; } g_writeln("xrdp_caps_process_glyphcache: support level %d ", glyph_support_level); return 0; }
bool APP_CC xrdp_emt_process(struct xrdp_rdp* self, struct stream* s) { int sequenceNumber; int requestType; unsigned int current_time = g_time3(); struct xrdp_emt* emt = self->sec_layer->chan_layer->emt_channel; in_uint8s(s, 1); // headerLength in_uint8s(s, 1); // headerTypeId in_uint16_le(s, sequenceNumber); // sequenceNumber in_uint16_le(s, requestType); // requestType switch (requestType) { case RDP_RTT_RESPONSE_TYPE: emt->state = ready; break; case RDP_BW_RESULTS: xrdp_emt_process_results(self, emt, s); break; default: printf("Unknow request type: 0x%x", requestType); return false; } return true; }
/* Process a palette update */ void process_palette(STREAM s) { COLOURENTRY *entry; COLOURMAP map; RD_HCOLOURMAP hmap; int i; in_uint8s(s, 2); /* pad */ in_uint16_le(s, map.ncolours); in_uint8s(s, 2); /* pad */ map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours); DEBUG(("PALETTE(c=%d)\n", map.ncolours)); for (i = 0; i < map.ncolours; i++) { entry = &map.colours[i]; in_uint8(s, entry->red); in_uint8(s, entry->green); in_uint8(s, entry->blue); } hmap = ui_create_colourmap(&map); ui_set_colourmap(hmap); xfree(map.colours); }
/* read in CLIPRDR_FILEDESCRIPTOR */ static int clipboard_c2s_in_file_info(struct stream *s, struct clip_file_desc *cfd) { int num_chars; int ex_bytes; in_uint32_le(s, cfd->flags); in_uint8s(s, 32); /* reserved1 */ in_uint32_le(s, cfd->fileAttributes); in_uint8s(s, 16); /* reserved2 */ in_uint32_le(s, cfd->lastWriteTimeLow); in_uint32_le(s, cfd->lastWriteTimeHigh); in_uint32_le(s, cfd->fileSizeHigh); in_uint32_le(s, cfd->fileSizeLow); num_chars = 256; clipboard_in_unicode(s, cfd->cFileName, &num_chars); ex_bytes = 512 - num_chars * 2; ex_bytes -= 2; in_uint8s(s, ex_bytes); in_uint8s(s, 8); /* pad */ log_debug("clipboard_c2s_in_file_info:"); log_debug(" flags 0x%8.8x", cfd->flags); log_debug(" fileAttributes 0x%8.8x", cfd->fileAttributes); log_debug(" lastWriteTime 0x%8.8x%8.8x", cfd->lastWriteTimeHigh, cfd->lastWriteTimeLow); log_debug(" fileSize 0x%8.8x%8.8x", cfd->fileSizeHigh, cfd->fileSizeLow); log_debug(" num_chars %d cFileName [%s]", num_chars, cfd->cFileName); return 0; }
/* Process a bitmap cache order */ static void process_bmpcache(STREAM s) { HBITMAP bitmap; uint16 cache_idx, size; uint8 cache_id, width, height, bpp; uint8 *data, *bmpdata; in_uint8(s, cache_id); in_uint8s(s, 1); /* pad */ in_uint8(s, width); in_uint8(s, height); in_uint8(s, bpp); in_uint8s(s, 2); /* bufsize */ in_uint16_le(s, cache_idx); in_uint8s(s, 2); /* pad */ in_uint16_le(s, size); in_uint8s(s, 4); /* row_size, final_size */ in_uint8p(s, data, size); DEBUG(("BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx)); bmpdata = xmalloc(width * height); if (bitmap_decompress(bmpdata, width, height, data, size)) { bitmap = ui_create_bitmap(width, height, bmpdata); cache_put_bitmap(cache_id, cache_idx, bitmap); } xfree(bmpdata); }
/* Process bitmap updates */ void process_bitmap_updates(STREAM s) { uint16 num_updates; uint16 left, top, right, bottom, width, height; uint16 cx, cy, bpp, Bpp, compress, bufsize, size; uint8 *data, *bmpdata; int i; in_uint16_le(s, num_updates); for (i = 0; i < num_updates; i++) { in_uint16_le(s, left); in_uint16_le(s, top); in_uint16_le(s, right); in_uint16_le(s, bottom); in_uint16_le(s, width); in_uint16_le(s, height); in_uint16_le(s, bpp); Bpp = (bpp + 7) / 8; //Bpp = 4; in_uint16_le(s, compress); in_uint16_le(s, bufsize); cx = right - left + 1; cy = bottom - top + 1; //DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n", // left, top, right, bottom, width, height, Bpp, compress)); __android_log_print(ANDROID_LOG_INFO,"JNIMsg","BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)",left, top, right, bottom, width, height, Bpp, compress); if (!compress) { int y; bmpdata = (uint8 *) xmalloc(width * height * Bpp); for (y = 0; y < height; y++) { in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)], width * Bpp); } __android_log_print(ANDROID_LOG_INFO,"JNIMsg","in if do ui_paint_bitmap"); ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata); xfree(bmpdata); continue; } if (compress & 0x400) { size = bufsize; } else { in_uint8s(s, 2); /* pad */ in_uint16_le(s, size); in_uint8s(s, 4); /* line_size, final_size */ }in_uint8p(s, data, size); bmpdata = (uint8 *) xmalloc(width * height * Bpp); if (bitmap_decompress(bmpdata, width, height, data, size, Bpp)) { ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata); } else { DEBUG_RDP5(("Failed to decompress data\n")); } xfree(bmpdata); } }
/* Process an update PDU */ static void process_update_pdu(STREAM s) { uint16 update_type, count; in_uint16_le(s, update_type); // TODO ui_begin_update(); __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "process_update_pdu STREAM:%p", s); switch (update_type) { case RDP_UPDATE_ORDERS: in_uint8s(s, 2); /* pad */ in_uint16_le(s, count); in_uint8s(s, 2); /* pad */ process_orders(s, count); break; case RDP_UPDATE_BITMAP: process_bitmap_updates(s); break; case RDP_UPDATE_PALETTE: process_palette(s); break; case RDP_UPDATE_SYNCHRONIZE: break; default: unimpl("update %d\n", update_type); } // TODO ui_end_update(); }
/* Process a new licence packet */ static void licence_process_new_license(STREAM s) { RDSSL_RC4 crypt_key; uint32 length; int i; in_uint8s(s, 2); // Skip license binary blob type in_uint16_le(s, length); if (!s_check_rem(s, length)) return; rdssl_rc4_set_key(&crypt_key, g_licence_key, 16); rdssl_rc4_crypt(&crypt_key, s->p, s->p, length); /* Parse NEW_LICENSE_INFO block */ in_uint8s(s, 4); // skip dwVersion /* Skip strings, Scope, CompanyName and ProductId to get to the LicenseInfo which we store in license blob. */ length = 0; for (i = 0; i < 4; i++) { in_uint8s(s, length); in_uint32_le(s, length); if (!s_check_rem(s, length)) return; } g_licence_issued = True; save_licence(s->p, length); }
/* Process a palette update */ void process_palette(RDPCLIENT * This, STREAM s) { COLOURENTRY *entry; COLOURMAP map; HCOLOURMAP hmap; int i; in_uint8s(s, 2); /* pad */ in_uint16_le(s, map.ncolours); in_uint8s(s, 2); /* pad */ map.colours = (COLOURENTRY *) malloc(sizeof(COLOURENTRY) * map.ncolours); if(map.colours == NULL) { in_uint8s(s, sizeof(*entry) * map.ncolours); return; } DEBUG(("PALETTE(c=%d)\n", map.ncolours)); for (i = 0; i < map.ncolours; i++) { entry = &map.colours[i]; in_uint8(s, entry->red); in_uint8(s, entry->green); in_uint8(s, entry->blue); } hmap = ui_create_colourmap(This, &map); ui_set_colourmap(This, hmap); free(map.colours); }
/* returns error */ static int APP_CC xrdp_iso_recv_msg(struct xrdp_iso* self, struct stream* s, int* code) { int ver; int len; *code = 0; if (xrdp_tcp_recv(self->tcp_layer, s, 4) != 0) { return 1; } in_uint8(s, ver); if (ver != 3) { return 1; } in_uint8s(s, 1); in_uint16_be(s, len); if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) { return 1; } in_uint8s(s, 1); in_uint8(s, *code); if (*code == ISO_PDU_DT) { in_uint8s(s, 1); } else { in_uint8s(s, 5); } return 0; }
static void rdpsnd_process(STREAM s) { uint16 len; while (!s_check_end(s)) { /* New packet */ if (packet.size == 0) { if ((s->end - s->p) < 4) { logger(Sound, Error, "rdpsnd_process(), split at packet header, things will go south from here..."); return; } in_uint8(s, packet_opcode); in_uint8s(s, 1); /* Padding */ in_uint16_le(s, len); logger(Sound, Debug, "rdpsnd_process(), Opcode = 0x%x Length= %d", (int) packet_opcode, (int) len); packet.p = packet.data; packet.end = packet.data + len; packet.size = len; } else { len = MIN(s->end - s->p, packet.end - packet.p); /* Microsoft's server is so broken it's not even funny... */ if (packet_opcode == SNDC_WAVE) { if ((packet.p - packet.data) < 12) len = MIN(len, 12 - (packet.p - packet.data)); else if ((packet.p - packet.data) == 12) { logger(Sound, Debug, "rdpsnd_process(), eating 4 bytes of %d bytes...", len); in_uint8s(s, 4); len -= 4; } } in_uint8a(s, packet.p, len); packet.p += len; } /* Packet fully assembled */ if (packet.p == packet.end) { packet.p = packet.data; rdpsnd_process_packet(packet_opcode, &packet); packet.size = 0; } } }
static void rdpsnd_process(STREAM s) { uint16 len; while (!s_check_end(s)) { /* New packet */ if (packet.size == 0) { if ((s->end - s->p) < 4) { error("RDPSND: Split at packet header. Things will go south from here...\n"); return; } in_uint8(s, packet_opcode); in_uint8s(s, 1); /* Padding */ in_uint16_le(s, len); DEBUG_SOUND(("RDPSND: == Opcode %x Length: %d ==\n", (int) packet_opcode, (int) len)); packet.p = packet.data; packet.end = packet.data + len; packet.size = len; } else { len = MIN(s->end - s->p, packet.end - packet.p); /* Microsoft's server is so broken it's not even funny... */ if (packet_opcode == RDPSND_WRITE) { if ((packet.p - packet.data) < 12) len = MIN(len, 12 - (packet.p - packet.data)); else if ((packet.p - packet.data) == 12) { DEBUG_SOUND(("RDPSND: Eating 4 bytes of %d bytes...\n", len)); in_uint8s(s, 4); len -= 4; } } in_uint8a(s, packet.p, len); packet.p += len; } /* Packet fully assembled */ if (packet.p == packet.end) { packet.p = packet.data; rdpsnd_process_packet(packet_opcode, &packet); packet.size = 0; } } }
/* software decode */ int surface_cmd(rdpRdp * rdp, STREAM s) { int cmdType; int frameAction; int frameId; int destLeft; int destTop; int destRight; int destBottom; int bpp; int codecID; int width; int height; int bitmapDataLength; //printf("surface_cmd: size %d\n", s->end - s->p); //hexdump(s->p, 1024); frameId = 0; while (s->p < s->end) { in_uint16_le(s, cmdType); //printf(" surface_cmd: %d\n", cmdType); switch (cmdType) { case 4: /* CMDTYPE_FRAME_MARKER */ in_uint16_le(s, frameAction); in_uint32_le(s, frameId); //printf(" surface_cmd: CMDTYPE_FRAME_MARKER %d %d\n", frameAction, frameId); if (frameAction == 1) { rdp_send_frame_ack(rdp, frameId); } break; case 6: /* CMDTYPE_STREAM_SURFACE_BITS */ in_uint16_le(s, destLeft); in_uint16_le(s, destTop); in_uint16_le(s, destRight); in_uint16_le(s, destBottom); in_uint8(s, bpp); in_uint8s(s, 2); in_uint8(s, codecID); in_uint16_le(s, width); in_uint16_le(s, height); in_uint32_le(s, bitmapDataLength); in_uint8s(s, bitmapDataLength); //printf(" surface_cmd: CMDTYPE_STREAM_SURFACE_BITS " // "id %d width %d height %d bpp %d size %d\n", // codecID, width, height, bpp, bitmapDataLength); break; } } return 0; }
/* client is asking from info about a file */ int clipboard_process_file_request(struct stream *s, int clip_msg_status, int clip_msg_len) { int streamId; int lindex; int dwFlags; int nPositionLow; int cbRequested; //int clipDataId; log_debug("clipboard_process_file_request:"); //g_hexdump(s->p, clip_msg_len); in_uint32_le(s, streamId); in_uint32_le(s, lindex); in_uint32_le(s, dwFlags); in_uint32_le(s, nPositionLow); in_uint8s(s, 4); /* nPositionHigh */ in_uint32_le(s, cbRequested); //in_uint32_le(s, clipDataId); /* options, used when locking */ if (dwFlags & CB_FILECONTENTS_SIZE) { clipboard_send_file_size(streamId, lindex); } if (dwFlags & CB_FILECONTENTS_RANGE) { clipboard_send_file_data(streamId, lindex, nPositionLow, cbRequested); } return 0; }
/* Process a pointer PDU */ static void process_pointer_pdu(STREAM s) { uint16 message_type; uint16 x, y; in_uint16_le(s, message_type); in_uint8s(s, 2); /* pad */ switch (message_type) { case RDP_POINTER_MOVE: in_uint16_le(s, x); in_uint16_le(s, y); if (s_check(s)) ui_move_pointer(x, y); break; case RDP_POINTER_COLOR: process_colour_pointer_pdu(s); break; case RDP_POINTER_CACHED: process_cached_pointer_pdu(s); break; case RDP_POINTER_SYSTEM: process_system_pointer_pdu(s); break; default: unimpl("Pointer message 0x%x\n", message_type); } }
/* Process a licence packet */ void licence_process(STREAM s) { uint16 tag; in_uint16_le(s, tag); in_uint8s(s, 2); /* length */ switch (tag) { case LICENCE_TAG_DEMAND: licence_process_demand(s); break; case LICENCE_TAG_AUTHREQ: licence_process_authreq(s); break; case LICENCE_TAG_ISSUE: licence_process_issue(s); break; case LICENCE_TAG_REISSUE: break; case LICENCE_TAG_RESULT: break; default: unimpl("licence tag 0x%x\n", tag); } }
static int APP_CC xrdp_caps_process_general(struct xrdp_rdp *self, struct stream *s, int len) { int extraFlags; int client_does_fastpath_output; if (len < 10 + 2) { g_writeln("xrdp_caps_process_general: error"); return 1; } in_uint16_le(s, self->client_info.client_os_major); /* osMajorType (2 bytes) */ in_uint16_le(s, self->client_info.client_os_minor); /* osMinorType (2 bytes) */ in_uint8s(s, 6); in_uint16_le(s, extraFlags); /* extraFlags (2 bytes) */ self->client_info.op1 = extraFlags & NO_BITMAP_COMPRESSION_HDR; /* use_compact_packets is pretty much 'use rdp5' */ self->client_info.use_compact_packets = (extraFlags != 0); /* op2 is a boolean to use compact bitmap headers in bitmap cache */ /* set it to same as 'use rdp5' boolean */ self->client_info.op2 = self->client_info.use_compact_packets; /* FASTPATH_OUTPUT_SUPPORTED 0x0001 */ client_does_fastpath_output = extraFlags & FASTPATH_OUTPUT_SUPPORTED; if ((self->client_info.use_fast_path & 1) && !client_does_fastpath_output) { /* server supports fast path output and client does not, turn it off */ self->client_info.use_fast_path &= ~1; } return 0; }
/* Respond to a demand active PDU */ static void process_demand_active(STREAM s) { uint8 type; uint16 len_src_descriptor, len_combined_caps; in_uint32_le(s, g_rdp_shareid); in_uint16_le(s, len_src_descriptor); in_uint16_le(s, len_combined_caps); in_uint8s(s, len_src_descriptor); DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid)); rdp_process_server_caps(s, len_combined_caps); rdp_send_confirm_active(); rdp_send_synchronise(); rdp_send_control(RDP_CTL_COOPERATE); rdp_send_control(RDP_CTL_REQUEST_CONTROL); rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */ rdp_recv(&type); /* RDP_CTL_COOPERATE */ rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */ rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, g_numlock_sync ? ui_get_numlock_state(read_keyboard_state()) : 0, 0); if (g_use_rdp5) { rdp_enum_bmpcache2(); rdp_send_fonts(3); } else { rdp_send_fonts(1); rdp_send_fonts(2); } rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */ reset_order_state(); }
/* Process a licence packet */ void licence_process(RDPCLIENT * This, STREAM s) { uint8 tag; in_uint8(s, tag); in_uint8s(s, 3); /* version, length */ switch (tag) { case LICENCE_TAG_DEMAND: licence_process_demand(This, s); break; case LICENCE_TAG_AUTHREQ: licence_process_authreq(This, s); break; case LICENCE_TAG_ISSUE: licence_process_issue(This, s); break; case LICENCE_TAG_REISSUE: case LICENCE_TAG_RESULT: break; default: unimpl("licence tag 0x%x\n", tag); } }
/* Process a bitmap capability set */ static void rdp_process_bitmap_caps(STREAM s) { uint16 width, height, depth; in_uint16_le(s, depth); in_uint8s(s, 6); in_uint16_le(s, width); in_uint16_le(s, height); __android_log_print(ANDROID_LOG_INFO,"JNIMsg","setting desktop size and depth to: %dx%dx%d", width, height, depth); /* * The server may limit depth and change the size of the desktop (for * example when shadowing another session). */ if (g_server_depth != depth) { __android_log_print(ANDROID_LOG_WARN,"JNIMsg","Remote desktop does not support colour depth %d; falling back to %d",g_server_depth, depth); g_server_depth = depth; } if (g_width != width || g_height != height) { __android_log_print(ANDROID_LOG_WARN,"JNIMsg","Remote desktop changed from %dx%d to %dx%d.", g_width,g_height, width, height); g_width = width; g_height = height; ui_resize_window(); } }
/* Process a licence packet */ void licence_process(RDConnectionRef conn, RDStreamRef s) { uint8 tag; in_uint8(s, tag); in_uint8s(s, 3); /* version, length */ switch (tag) { case LICENCE_TAG_DEMAND: licence_process_demand(conn, s); break; case LICENCE_TAG_AUTHREQ: licence_process_authreq(conn, s); break; case LICENCE_TAG_ISSUE: licence_process_issue(conn, s); break; case LICENCE_TAG_REISSUE: case LICENCE_TAG_RESULT: break; default: unimpl("licence tag 0x%x\n", tag); } }
/* Process server capabilities */ static void rdp_process_server_caps(STREAM s, uint16 length) { int n; uint8 *next, *start; uint16 ncapsets, capset_type, capset_length; start = s->p; in_uint16_le(s, ncapsets); in_uint8s(s, 2); /* pad */ for (n = 0; n < ncapsets; n++) { if (s->p > start + length) return; in_uint16_le(s, capset_type); in_uint16_le(s, capset_length); next = s->p + capset_length - 4; switch (capset_type) { case RDP_CAPSET_GENERAL: rdp_process_general_caps(s); break; case RDP_CAPSET_BITMAP: rdp_process_bitmap_caps(s); break; } s->p = next; } }
/* Process a raw bitmap cache order */ static void process_raw_bmpcache(STREAM s) { HBITMAP bitmap; uint16 cache_idx, bufsize; uint8 cache_id, width, height, bpp; uint8 *data, *inverted; int y; in_uint8(s, cache_id); in_uint8s(s, 1); /* pad */ in_uint8(s, width); in_uint8(s, height); in_uint8(s, bpp); in_uint16_le(s, bufsize); in_uint16_le(s, cache_idx); in_uint8p(s, data, bufsize); DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx)); inverted = xmalloc(width * height); for (y = 0; y < height; y++) { memcpy(&inverted[(height - y - 1) * width], &data[y * width], width); } bitmap = ui_create_bitmap(width, height, inverted); xfree(inverted); cache_put_bitmap(cache_id, cache_idx, bitmap); }
/* data in from client ( clinet -> xrdp -> chansrv ) */ int APP_CC sound_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { int code; int size; print_got_here(); in_uint8(s, code); in_uint8s(s, 1); in_uint16_le(s, size); switch (code) { case SNDC_WAVECONFIRM: sound_process_wave_confirm(s, size); break; case SNDC_TRAINING: sound_process_training(s, size); break; case SNDC_FORMATS: sound_process_formats(s, size); break; default: LOG(0, ("sound_data_in: unknown code %d size %d", code, size)); break; } return 0; }
/* Process a colourmap cache order */ static void process_colcache(STREAM s) { COLOURENTRY *entry; COLOURMAP map; HCOLOURMAP hmap; uint8 cache_id; int i; in_uint8(s, cache_id); in_uint16_le(s, map.ncolours); map.colours = xmalloc(3 * map.ncolours); for (i = 0; i < map.ncolours; i++) { entry = &map.colours[i]; in_uint8(s, entry->blue); in_uint8(s, entry->green); in_uint8(s, entry->red); in_uint8s(s, 1); /* pad */ } DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours)); hmap = ui_create_colourmap(&map); ui_set_colourmap(hmap); xfree(map.colours); }
/* Process a bitmap capability set */ static void rdp_process_bitmap_caps(STREAM s) { uint16 width, height, depth; in_uint16_le(s, depth); in_uint8s(s, 6); in_uint16_le(s, width); in_uint16_le(s, height); DEBUG(("setting desktop size and depth to: %dx%dx%d\n", width, height, depth)); /* * The server may limit depth and change the size of the desktop (for * example when shadowing another session). */ if (g_server_depth != depth) { warning("Remote desktop does not support colour depth %d; falling back to %d\n", g_server_depth, depth); g_server_depth = depth; } if (g_width != width || g_height != height) { warning("Remote desktop changed from %dx%d to %dx%d.\n", g_width, g_height, width, height); g_width = width; g_height = height; ui_resize_window(); } }
/* Receive a message on the ISO layer, return code */ static STREAM iso_recv_msg(uint8 * code, uint8 * rdpver) { STREAM s; uint16 length; uint8 version; s = tcp_recv(NULL, 4); if (s == NULL) return NULL; in_uint8(s, version); if (rdpver != NULL) *rdpver = version; if (version == 3) { in_uint8s(s, 1); /* pad */ in_uint16_be(s, length); } else { in_uint8(s, length); if (length & 0x80) { length &= ~0x80; next_be(s, length); } } if (length < 4) { error("Bad packet header\n"); return NULL; } s = tcp_recv(s, length - 4); if (s == NULL) return NULL; if (version != 3) return s; in_uint8s(s, 1); /* hdrlen */ in_uint8(s, *code); if (*code == ISO_PDU_DT) { in_uint8s(s, 1); /* eot */ return s; } in_uint8s(s, 5); /* dst_ref, src_ref, class */ return s; }
/* returns error */ static int APP_CC rdp_iso_recv_msg(struct rdp_iso *self, struct stream *s, int *code) { int ver; int len; *code = 0; if (rdp_tcp_recv(self->tcp_layer, s, 4) != 0) { DEBUG((" out rdp_iso_recv_msg error rdp_tcp_recv 1 failed")); return 1; } in_uint8(s, ver); if (ver != 3) { DEBUG((" out rdp_iso_recv_msg error ver != 3")); return 1; } in_uint8s(s, 1); in_uint16_be(s, len); if (rdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) { DEBUG((" out rdp_iso_recv_msg error rdp_tcp_recv 2 failed")); return 1; } in_uint8s(s, 1); in_uint8(s, *code); if (*code == ISO_PDU_DT) { in_uint8s(s, 1); } else { in_uint8s(s, 5); } return 0; }
void rdp_process_bitmap_capset(rdpRdp * rdp, STREAM s) { uint16 preferredBitsPerPixel; uint16 desktopWidth; uint16 desktopHeight; uint16 desktopResizeFlag; uint16 bitmapCompressionFlag; uint8 drawingFlags; /* * preferredBitsPerPixel (2 bytes): * A 16-bit, unsigned integer. Color depth of the remote session. In RDP 4.0 and 5.0, * this field MUST be set to 8 (even for a 16-color session) */ in_uint16_le(s, preferredBitsPerPixel); /* preferredBitsPerPixel */ in_uint8s(s, 6); /* Ignore receive1BitPerPixel, receive4BitPerPixel, receive8BitPerPixel */ in_uint16_le(s, desktopWidth); /* desktopWidth */ in_uint16_le(s, desktopHeight); /* desktopHeight */ in_uint8s(s, 2); /* pad */ in_uint16_le(s, desktopResizeFlag); /* desktopResizeFlag */ in_uint16_le(s, bitmapCompressionFlag); /* bitmapCompressionFlag */ in_uint8s(s, 1); /* Ignore highColorFlags */ in_uint8(s, drawingFlags); /* drawingFlags */ /* * The server may limit depth and change the size of the desktop (for * example when shadowing another session). */ if (rdp->settings->server_depth != preferredBitsPerPixel) { ui_warning(rdp->inst, "Remote desktop does not support color depth %d; falling back to %d\n", rdp->settings->server_depth, preferredBitsPerPixel); rdp->settings->server_depth = preferredBitsPerPixel; ui_resize_window(rdp->inst); } if (rdp->settings->width != desktopWidth || rdp->settings->height != desktopHeight) { ui_warning(rdp->inst, "Remote desktop changed from %dx%d to %dx%d.\n", rdp->settings->width, rdp->settings->height, desktopWidth, desktopHeight); rdp->settings->width = desktopWidth; rdp->settings->height = desktopHeight; ui_resize_window(rdp->inst); } }