--- sourceforge.net/trunk/rdesktop/rdp.c 2005/04/16 11:42:34 886 +++ sourceforge.net/trunk/rdesktop/rdp.c 2005/08/08 19:15:57 977 @@ -49,13 +49,22 @@ extern int g_height; extern BOOL g_bitmap_cache; extern BOOL g_bitmap_cache_persist_enable; -extern BOOL g_rdp_compression; uint8 *g_next_packet; uint32 g_rdp_shareid; extern RDPCOMP g_mppc_dict; +/* Session Directory support */ +extern BOOL g_redirect; +extern char g_redirect_server[64]; +extern char g_redirect_domain[16]; +extern char g_redirect_password[64]; +extern char g_redirect_username[64]; +extern char g_redirect_cookie[128]; +extern uint32 g_redirect_flags; +/* END Session Directory support */ + #if WITH_DEBUG static uint32 g_packetno; #endif @@ -72,7 +81,7 @@ uint16 length, pdu_type; uint8 rdpver; - if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end)) + if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL)) { rdp_s = sec_recv(&rdpver); if (rdp_s == NULL) @@ -261,6 +270,10 @@ g_iconv_works = False; return rdp_in_unistr(s, string, uni_len); } + + /* we must update the location of the current STREAM for future reads of s->p */ + s->p += uni_len; + return pout - string; } else @@ -298,12 +311,6 @@ time_t t = time(NULL); time_t tzone; -#if 0 - /* enable rdp compression */ - /* some problems still exist with rdp5 */ - flags |= RDP_COMPRESSION; -#endif - if (!g_use_rdp5 || 1 == g_server_rdp_version) { DEBUG_RDP5(("Sending RDP4-style Logon packet\n")); @@ -488,7 +495,38 @@ rdp_send_data(s, RDP_DATA_PDU_INPUT); } -/* Inform the server on the contents of the persistent bitmap cache */ +/* Send a client window information PDU */ +void +rdp_send_client_window_status(int status) +{ + STREAM s; + static int current_status = 1; + + if (current_status == status) + return; + + s = rdp_init_data(12); + + out_uint32_le(s, status); + + switch (status) + { + case 0: /* shut the server up */ + break; + + case 1: /* receive data again */ + out_uint32_le(s, 0); /* unknown */ + out_uint16_le(s, g_width); + out_uint16_le(s, g_height); + break; + } + + s_mark_end(s); + rdp_send_data(s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS); + current_status = status; +} + +/* Send persistent bitmap cache enumeration PDU's */ static void rdp_enum_bmpcache2(void) { @@ -660,34 +698,14 @@ static void rdp_out_bmpcache2_caps(STREAM s) { - uint16 cellsize; - out_uint16_le(s, RDP_CAPSET_BMPCACHE2); out_uint16_le(s, RDP_CAPLEN_BMPCACHE2); out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0); /* version */ - /* Cellsize: - 01 = 16x16, 02 = 32x32, 03 = 64x64 - log2(cell size) - 3 - */ - - cellsize = 0x03; - - if (g_rdp_compression) - { - switch (g_server_bpp) - { - case 24: - case 16: - case 15: - cellsize = 0x02; - break; - } - } - - out_uint16_le(s, (0x0000 | (cellsize << 8))); /* flags? number of caches? */ + out_uint16_be(s, 3); /* number of caches in this set */ + /* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */ out_uint32_le(s, BMPCACHE2_C0_CELLS); out_uint32_le(s, BMPCACHE2_C1_CELLS); if (pstcache_init(2)) @@ -893,7 +911,7 @@ } /* Process server capabilities */ -void +static void rdp_process_server_caps(STREAM s, uint16 length) { int n; @@ -1280,6 +1298,54 @@ return False; } +/* Process redirect PDU from Session Directory */ +static BOOL +process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ ) +{ + uint32 len; + + /* these 2 bytes are unknown, seem to be zeros */ + in_uint8s(s, 2); + + /* read connection flags */ + in_uint32_le(s, g_redirect_flags); + + /* read length of ip string */ + in_uint32_le(s, len); + + /* read ip string */ + rdp_in_unistr(s, g_redirect_server, len); + + /* read length of cookie string */ + in_uint32_le(s, len); + + /* read cookie string (plain ASCII) */ + in_uint8a(s, g_redirect_cookie, len); + g_redirect_cookie[len] = 0; + + /* read length of username string */ + in_uint32_le(s, len); + + /* read username string */ + rdp_in_unistr(s, g_redirect_username, len); + + /* read length of domain string */ + in_uint32_le(s, len); + + /* read domain string */ + rdp_in_unistr(s, g_redirect_domain, len); + + /* read length of password string */ + in_uint32_le(s, len); + + /* read password string */ + rdp_in_unistr(s, g_redirect_password, len); + + g_redirect = True; + + return True; +} + /* Process incoming packets */ /* nevers gets out of here till app is done */ void @@ -1313,6 +1379,9 @@ DEBUG(("RDP_PDU_DEACTIVATE\n")); *deactivated = True; break; + case RDP_PDU_REDIRECT: + return process_redirect_pdu(s); + break; case RDP_PDU_DATA: disc = process_data_pdu(s, ext_disc_reason); break; @@ -1340,6 +1409,27 @@ return True; } +/* Establish a reconnection up to the RDP layer */ +BOOL +rdp_reconnect(char *server, uint32 flags, char *domain, char *password, + char *command, char *directory, char *cookie) +{ + if (!sec_reconnect(server)) + return False; + + rdp_send_logon_info(flags, domain, g_username, password, command, directory); + return True; +} + +/* Called during redirection to reset the state to support redirection */ +void +rdp_reset_state(void) +{ + g_next_packet = NULL; /* reset the packet information */ + g_rdp_shareid = 0; + sec_reset_state(); +} + /* Disconnect from the RDP layer */ void rdp_disconnect(void)