--- sourceforge.net/trunk/rdesktop/rdp.c 2005/03/13 17:40:51 861 +++ sourceforge.net/trunk/rdesktop/rdp.c 2005/04/16 11:42:34 886 @@ -49,6 +49,7 @@ 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; @@ -59,6 +60,10 @@ static uint32 g_packetno; #endif +#ifdef HAVE_ICONV +static BOOL g_iconv_works = True; +#endif + /* Receive an RDP packet */ static STREAM rdp_recv(uint8 * type) @@ -157,64 +162,68 @@ #ifdef HAVE_ICONV size_t ibl = strlen(string), obl = len + 2; static iconv_t iconv_h = (iconv_t) - 1; - char *pin = string, *pout; -#ifdef B_ENDIAN - char ss[4096]; // FIXME: global MAX_BUF_SIZE macro need - - pout = ss; -#else - pout = s->p; -#endif + char *pin = string, *pout = (char *) s->p; memset(pout, 0, len + 4); - if (iconv_h == (iconv_t) - 1) + if (g_iconv_works) { - size_t i = 1, o = 4; - if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1) + if (iconv_h == (iconv_t) - 1) { - printf("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n", - g_codepage, WINDOWS_CODEPAGE, (int) iconv_h); - return; + size_t i = 1, o = 4; + if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1) + { + warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n", + g_codepage, WINDOWS_CODEPAGE, (int) iconv_h); + + g_iconv_works = False; + rdp_out_unistr(s, string, len); + return; + } + if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) == + (size_t) - 1) + { + iconv_close(iconv_h); + iconv_h = (iconv_t) - 1; + warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno); + + g_iconv_works = False; + rdp_out_unistr(s, string, len); + return; + } + pin = string; + pout = (char *) s->p; } - if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) == (size_t) - 1) + + if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) { iconv_close(iconv_h); iconv_h = (iconv_t) - 1; - printf("rdp_out_unistr: iconv(1) fail, errno %d\n", errno); + warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno); + + g_iconv_works = False; + rdp_out_unistr(s, string, len); return; } - pin = string; - pout = (char *) s->p; - } - if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) - { - iconv_close(iconv_h); - iconv_h = (iconv_t) - 1; - printf("rdp_out_unistr: iconv(2) fail, errno %d\n", errno); - return; - } + s->p += len + 2; -#ifdef B_ENDIAN - swab(ss, (char *) s->p, len + 4); + } + else #endif + { + int i = 0, j = 0; - s->p += len + 2; - -#else /*HAVE_ICONV undef */ - int i = 0, j = 0; + len += 2; - len += 2; + while (i < len) + { + s->p[i++] = string[j++]; + s->p[i++] = 0; + } - while (i < len) - { - s->p[i++] = string[j++]; - s->p[i++] = 0; + s->p += len; } - - s->p += len; -#endif } /* Input a string in Unicode @@ -226,46 +235,47 @@ { #ifdef HAVE_ICONV size_t ibl = uni_len, obl = uni_len; - char *pin, *pout = string; + char *pin = (char *) s->p, *pout = string; static iconv_t iconv_h = (iconv_t) - 1; -#ifdef B_ENDIAN - char ss[4096]; // FIXME: global MAX_BUF_SIZE macro need - swab((char *) s->p, ss, uni_len); - pin = ss; -#else - pin = s->p; -#endif - - if (iconv_h == (iconv_t) - 1) + if (g_iconv_works) { - if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1) + if (iconv_h == (iconv_t) - 1) { - printf("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n", - WINDOWS_CODEPAGE, g_codepage, (int) iconv_h); - return 0; + if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1) + { + warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n", + WINDOWS_CODEPAGE, g_codepage, (int) iconv_h); + + g_iconv_works = False; + return rdp_in_unistr(s, string, uni_len); + } } - } - if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) - { - iconv_close(iconv_h); - iconv_h = (iconv_t) - 1; - printf("rdp_in_unistr: iconv fail, errno %d\n", errno); - return 0; - } - return pout - string; -#else /* HAVE_ICONV undef */ - int i = 0; + if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) + { + iconv_close(iconv_h); + iconv_h = (iconv_t) - 1; + warning("rdp_in_unistr: iconv fail, errno %d\n", errno); - while (i < uni_len / 2) - { - in_uint8a(s, &string[i++], 1); - in_uint8s(s, 1); + g_iconv_works = False; + return rdp_in_unistr(s, string, uni_len); + } + return pout - string; } - - return i - 1; + else #endif + { + int i = 0; + + while (i < uni_len / 2) + { + in_uint8a(s, &string[i++], 1); + in_uint8s(s, 1); + } + + return i - 1; + } } @@ -650,12 +660,33 @@ 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 */ - out_uint16_le(s, 0x0300); /* flags? number of caches? */ + /* 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_uint32_le(s, BMPCACHE2_C0_CELLS); out_uint32_le(s, BMPCACHE2_C1_CELLS); @@ -1197,7 +1228,7 @@ if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1) error("error while decompressing packet\n"); - //len -= 18; + /* len -= 18; */ /* allocate memory and copy the uncompressed data into the temporary stream */ ns->data = (uint8 *) xrealloc(ns->data, rlen);