/[rdesktop]/jpeg/rdesktop/trunk/rdp.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /jpeg/rdesktop/trunk/rdp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

sourceforge.net/trunk/rdesktop/rdp.c revision 711 by jsorg71, Tue Jun 15 22:45:12 2004 UTC jpeg/rdesktop/trunk/rdp.c revision 1508 by dpavlin, Mon Jul 20 16:47:49 2009 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP layer     Protocol services - RDP layer
4     Copyright (C) Matthew Chapman 1999-2002     Copyright (C) Matthew Chapman 1999-2008
5    
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 19  Line 19 
19  */  */
20    
21  #include <time.h>  #include <time.h>
22    #ifndef _WIN32
23    #include <errno.h>
24    #include <unistd.h>
25    #endif
26  #include "rdesktop.h"  #include "rdesktop.h"
27    
28    #ifdef HAVE_ICONV
29    #ifdef HAVE_ICONV_H
30    #include <iconv.h>
31    #endif
32    
33    #ifndef ICONV_CONST
34    #define ICONV_CONST ""
35    #endif
36    #endif
37    
38    #include <jpeglib.h>
39    /* DJ globals begin */
40    extern unsigned long long g_time_last_write;
41    extern unsigned long long g_time_last_change;
42    extern uint32 g_pixels_changed;
43    extern uint8 * g_bitmap_data;
44    extern uint8 * g_bitmap_data_last_write;
45    /* DJ globals end */
46    /* DJ tuning knobs begin */
47    const uint32 PIXELS_CHANGED_THRESHOLD = 8192;   /* this many pixel changes */
48    const uint32 PIXELS_STABILIZE_DELAY = 100000;   /* no change for .1 sec */
49    const uint32 PIXELS_RESET_INTERVAL = 10000000;  /* within 10 second interval */
50    const uint32 MINIMUM_WRITE_INTERVAL = 1000000;  /* and 1 sec from last write */
51    /* DJ tuning knobs end */
52    
53  extern uint16 g_mcs_userid;  extern uint16 g_mcs_userid;
54  extern char g_username[16];  extern char *g_username;
55  extern BOOL g_bitmap_compression;  extern char g_codepage[16];
56  extern BOOL g_orders;  extern RD_BOOL g_bitmap_compression;
57  extern BOOL g_encryption;  extern RD_BOOL g_orders;
58  extern BOOL g_desktop_save;  extern RD_BOOL g_encryption;
59  extern BOOL g_use_rdp5;  extern RD_BOOL g_desktop_save;
60    extern RD_BOOL g_polygon_ellipse_orders;
61    extern RD_BOOL g_use_rdp5;
62  extern uint16 g_server_rdp_version;  extern uint16 g_server_rdp_version;
63  extern uint32 g_rdp5_performanceflags;  extern uint32 g_rdp5_performanceflags;
64  extern int g_server_bpp;  extern int g_server_depth;
65  extern int g_width;  extern int g_width;
66  extern int g_height;  extern int g_height;
67  extern BOOL g_bitmap_cache;  extern RD_BOOL g_bitmap_cache;
68    extern RD_BOOL g_bitmap_cache_persist_enable;
69    extern RD_BOOL g_numlock_sync;
70    
71  uint8 *g_next_packet;  uint8 *g_next_packet;
72  uint32 g_rdp_shareid;  uint32 g_rdp_shareid;
73    
74  extern RDPCOMP g_mppc_dict;  extern RDPCOMP g_mppc_dict;
75    
76    /* Session Directory support */
77    extern RD_BOOL g_redirect;
78    extern char g_redirect_server[64];
79    extern char g_redirect_domain[16];
80    extern char g_redirect_password[64];
81    extern char *g_redirect_username;
82    extern char g_redirect_cookie[128];
83    extern uint32 g_redirect_flags;
84    /* END Session Directory support */
85    
86  #if WITH_DEBUG  #if WITH_DEBUG
87  static uint32 g_packetno;  static uint32 g_packetno;
88  #endif  #endif
89    
90    #ifdef HAVE_ICONV
91    static RD_BOOL g_iconv_works = True;
92    #endif
93    
94    unsigned long long
95    tod(void)
96    {
97            struct timeval tim;
98            unsigned long long ret;
99            gettimeofday(&tim, NULL);
100            ret=tim.tv_sec;
101            ret*=1000000;
102            ret+=tim.tv_usec;
103            return ret;
104    }
105    
106  /* Receive an RDP packet */  /* Receive an RDP packet */
107  static STREAM  static STREAM
108  rdp_recv(uint8 * type)  rdp_recv(uint8 * type)
109  {  {
110          static STREAM rdp_s;          static STREAM rdp_s;
111          uint16 length, pdu_type;          uint16 length, pdu_type;
112            uint8 rdpver;
113            unsigned long long current_time;
114    
115          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL))
116          {          {
117                  rdp_s = sec_recv();                  rdp_s = sec_recv(&rdpver);
118                    current_time = tod();
119    
120                    if (g_pixels_changed >= PIXELS_CHANGED_THRESHOLD)
121                    {
122                            if ((current_time - g_time_last_change) < PIXELS_STABILIZE_DELAY)
123                            {
124                                    printf("%llu still unstable\n", current_time);
125                            }
126                            else if ((current_time - g_time_last_write) < MINIMUM_WRITE_INTERVAL)
127                            {
128                                    printf("%llu too close to last write\n", current_time);
129                            }
130                            else
131                                    write_file();
132                    }
133                    else if ((current_time - g_time_last_write) > PIXELS_RESET_INTERVAL && g_bitmap_data)
134                    {
135                            memcpy(g_bitmap_data_last_write, g_bitmap_data, g_width * g_height * 3);
136                            printf("reset at g_pixels_changed=%d\n",g_pixels_changed);
137                            g_pixels_changed=0;
138                            g_time_last_write = current_time;
139                    }
140    
141                  if (rdp_s == NULL)                  if (rdp_s == NULL)
142                          return NULL;                          return NULL;
143                    if (rdpver == 0xff)
144                    {
145                            g_next_packet = rdp_s->end;
146                            *type = 0;
147                            return rdp_s;
148                    }
149                    else if (rdpver != 3)
150                    {
151                            /* rdp5_process should move g_next_packet ok */
152                            rdp5_process(rdp_s);
153                            *type = 0;
154                            return rdp_s;
155                    }
156    
157                  g_next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
158          }          }
# Line 125  rdp_send_data(STREAM s, uint8 data_pdu_t Line 222  rdp_send_data(STREAM s, uint8 data_pdu_t
222  void  void
223  rdp_out_unistr(STREAM s, char *string, int len)  rdp_out_unistr(STREAM s, char *string, int len)
224  {  {
225          int i = 0, j = 0;  #ifdef HAVE_ICONV
226            size_t ibl = strlen(string), obl = len + 2;
227            static iconv_t iconv_h = (iconv_t) - 1;
228            char *pin = string, *pout = (char *) s->p;
229    
230          len += 2;          memset(pout, 0, len + 4);
231    
232          while (i < len)          if (g_iconv_works)
233          {          {
234                  s->p[i++] = string[j++];                  if (iconv_h == (iconv_t) - 1)
235                  s->p[i++] = 0;                  {
236                            size_t i = 1, o = 4;
237                            if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
238                            {
239                                    warning("rdp_out_unistr: iconv_open[%s -> %s] fail %p\n",
240                                            g_codepage, WINDOWS_CODEPAGE, iconv_h);
241    
242                                    g_iconv_works = False;
243                                    rdp_out_unistr(s, string, len);
244                                    return;
245                            }
246                            if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) ==
247                                (size_t) - 1)
248                            {
249                                    iconv_close(iconv_h);
250                                    iconv_h = (iconv_t) - 1;
251                                    warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
252    
253                                    g_iconv_works = False;
254                                    rdp_out_unistr(s, string, len);
255                                    return;
256                            }
257                            pin = string;
258                            pout = (char *) s->p;
259                    }
260    
261                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
262                    {
263                            iconv_close(iconv_h);
264                            iconv_h = (iconv_t) - 1;
265                            warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
266    
267                            g_iconv_works = False;
268                            rdp_out_unistr(s, string, len);
269                            return;
270                    }
271    
272                    s->p += len + 2;
273    
274          }          }
275            else
276    #endif
277            {
278                    int i = 0, j = 0;
279    
280                    len += 2;
281    
282          s->p += len;                  while (i < len)
283                    {
284                            s->p[i++] = string[j++];
285                            s->p[i++] = 0;
286                    }
287    
288                    s->p += len;
289            }
290  }  }
291    
292  /* Input a string in Unicode  /* Input a string in Unicode
# Line 143  rdp_out_unistr(STREAM s, char *string, i Line 294  rdp_out_unistr(STREAM s, char *string, i
294   * Returns str_len of string   * Returns str_len of string
295   */   */
296  int  int
297  rdp_in_unistr(STREAM s, char *string, int uni_len)  rdp_in_unistr(STREAM s, char *string, int str_size, int in_len)
298  {  {
299          int i = 0;  #ifdef HAVE_ICONV
300            size_t ibl = in_len, obl = str_size - 1;
301            char *pin = (char *) s->p, *pout = string;
302            static iconv_t iconv_h = (iconv_t) - 1;
303    
304          while (i < uni_len / 2)          if (g_iconv_works)
305          {          {
306                  in_uint8a(s, &string[i++], 1);                  if (iconv_h == (iconv_t) - 1)
307                  in_uint8s(s, 1);                  {
308                            if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
309                            {
310                                    warning("rdp_in_unistr: iconv_open[%s -> %s] fail %p\n",
311                                            WINDOWS_CODEPAGE, g_codepage, iconv_h);
312    
313                                    g_iconv_works = False;
314                                    return rdp_in_unistr(s, string, str_size, in_len);
315                            }
316                    }
317    
318                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
319                    {
320                            if (errno == E2BIG)
321                            {
322                                    warning("server sent an unexpectedly long string, truncating\n");
323                            }
324                            else
325                            {
326                                    iconv_close(iconv_h);
327                                    iconv_h = (iconv_t) - 1;
328                                    warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
329    
330                                    g_iconv_works = False;
331                                    return rdp_in_unistr(s, string, str_size, in_len);
332                            }
333                    }
334    
335                    /* we must update the location of the current STREAM for future reads of s->p */
336                    s->p += in_len;
337    
338                    *pout = 0;
339                    return pout - string;
340          }          }
341            else
342    #endif
343            {
344                    int i = 0;
345                    int len = in_len / 2;
346                    int rem = 0;
347    
348                    if (len > str_size - 1)
349                    {
350                            warning("server sent an unexpectedly long string, truncating\n");
351                            len = str_size - 1;
352                            rem = in_len - 2 * len;
353                    }
354    
355                    while (i < len)
356                    {
357                            in_uint8a(s, &string[i++], 1);
358                            in_uint8s(s, 1);
359                    }
360    
361          return i - 1;                  in_uint8s(s, rem);
362                    string[len] = 0;
363                    return len;
364            }
365  }  }
366    
367    
# Line 176  rdp_send_logon_info(uint32 flags, char * Line 384  rdp_send_logon_info(uint32 flags, char *
384          time_t t = time(NULL);          time_t t = time(NULL);
385          time_t tzone;          time_t tzone;
386    
 #if 0  
         /* enable rdp compression */  
         /* some problems still exist with rdp5 */  
         flags |= RDP_COMPRESSION;  
 #endif  
   
387          if (!g_use_rdp5 || 1 == g_server_rdp_version)          if (!g_use_rdp5 || 1 == g_server_rdp_version)
388          {          {
389                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
# Line 306  rdp_send_logon_info(uint32 flags, char * Line 508  rdp_send_logon_info(uint32 flags, char *
508                  out_uint32_le(s, 0xffffffc4);                  out_uint32_le(s, 0xffffffc4);
509                  out_uint32_le(s, 0xfffffffe);                  out_uint32_le(s, 0xfffffffe);
510                  out_uint32_le(s, g_rdp5_performanceflags);                  out_uint32_le(s, g_rdp5_performanceflags);
511                  out_uint32(s, 0);                  out_uint16(s, 0);
512    
513    
514          }          }
# Line 366  rdp_send_input(uint32 time, uint16 messa Line 568  rdp_send_input(uint32 time, uint16 messa
568          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
569  }  }
570    
571    /* Send a client window information PDU */
572    void
573    rdp_send_client_window_status(int status)
574    {
575            STREAM s;
576            static int current_status = 1;
577    
578            if (current_status == status)
579                    return;
580    
581            s = rdp_init_data(12);
582    
583            out_uint32_le(s, status);
584    
585            switch (status)
586            {
587                    case 0: /* shut the server up */
588                            break;
589    
590                    case 1: /* receive data again */
591                            out_uint32_le(s, 0);    /* unknown */
592                            out_uint16_le(s, g_width);
593                            out_uint16_le(s, g_height);
594                            break;
595            }
596    
597            s_mark_end(s);
598            rdp_send_data(s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS);
599            current_status = status;
600    }
601    
602    /* Send persistent bitmap cache enumeration PDU's */
603    static void
604    rdp_enum_bmpcache2(void)
605    {
606            STREAM s;
607            HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
608            uint32 num_keys, offset, count, flags;
609    
610            offset = 0;
611            num_keys = pstcache_enumerate(2, keylist);
612    
613            while (offset < num_keys)
614            {
615                    count = MIN(num_keys - offset, 169);
616    
617                    s = rdp_init_data(24 + count * sizeof(HASH_KEY));
618    
619                    flags = 0;
620                    if (offset == 0)
621                            flags |= PDU_FLAG_FIRST;
622                    if (num_keys - offset <= 169)
623                            flags |= PDU_FLAG_LAST;
624    
625                    /* header */
626                    out_uint32_le(s, 0);
627                    out_uint16_le(s, count);
628                    out_uint16_le(s, 0);
629                    out_uint16_le(s, 0);
630                    out_uint16_le(s, 0);
631                    out_uint16_le(s, 0);
632                    out_uint16_le(s, num_keys);
633                    out_uint32_le(s, 0);
634                    out_uint32_le(s, flags);
635    
636                    /* list */
637                    out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
638    
639                    s_mark_end(s);
640                    rdp_send_data(s, 0x2b);
641    
642                    offset += 169;
643            }
644    }
645    
646  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
647  static void  static void
648  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 416  rdp_out_bitmap_caps(STREAM s) Line 693  rdp_out_bitmap_caps(STREAM s)
693          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
694          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
695    
696          out_uint16_le(s, g_server_bpp); /* Preferred BPP */          out_uint16_le(s, g_server_depth);       /* Preferred colour depth */
697          out_uint16_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
698          out_uint16_le(s, 1);    /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
699          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
# Line 436  rdp_out_order_caps(STREAM s) Line 713  rdp_out_order_caps(STREAM s)
713  {  {
714          uint8 order_caps[32];          uint8 order_caps[32];
715    
   
716          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
717          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
718          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
719          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
720          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
721            order_caps[4] = 0;      /* triblt */
722          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
723          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
724          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
725          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */          order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
726          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
727          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
728            order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon */
729            order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon2 */
730          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
731            order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse */
732            order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse2 */
733          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
734          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
735          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 476  rdp_out_bmpcache_caps(STREAM s) Line 757  rdp_out_bmpcache_caps(STREAM s)
757          out_uint16_le(s, RDP_CAPSET_BMPCACHE);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
758          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
759    
760          Bpp = (g_server_bpp + 7) / 8;          Bpp = (g_server_depth + 7) / 8; /* bytes per pixel */
761          out_uint8s(s, 24);      /* unused */          out_uint8s(s, 24);      /* unused */
762          out_uint16_le(s, 0x258);        /* entries */          out_uint16_le(s, 0x258);        /* entries */
763          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
# Line 486  rdp_out_bmpcache_caps(STREAM s) Line 767  rdp_out_bmpcache_caps(STREAM s)
767          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
768  }  }
769    
770    /* Output bitmap cache v2 capability set */
771    static void
772    rdp_out_bmpcache2_caps(STREAM s)
773    {
774            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
775            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
776    
777            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
778    
779            out_uint16_be(s, 3);    /* number of caches in this set */
780    
781            /* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */
782            out_uint32_le(s, BMPCACHE2_C0_CELLS);
783            out_uint32_le(s, BMPCACHE2_C1_CELLS);
784            if (pstcache_init(2))
785            {
786                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
787            }
788            else
789            {
790                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
791            }
792            out_uint8s(s, 20);      /* other bitmap caches not used */
793    }
794    
795  /* Output control capability set */  /* Output control capability set */
796  static void  static void
797  rdp_out_control_caps(STREAM s)  rdp_out_control_caps(STREAM s)
# Line 545  rdp_out_colcache_caps(STREAM s) Line 851  rdp_out_colcache_caps(STREAM s)
851          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
852  }  }
853    
854  static uint8 canned_caps[] = {  /* Output brush cache capability set */
855          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,  static void
856          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,  rdp_out_brushcache_caps(STREAM s)
857          0x00, 0x00, 0x00, 0x00, 0x00,  {
858          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          out_uint16_le(s, RDP_CAPSET_BRUSHCACHE);
859          0x00, 0x00, 0x00, 0x00, 0x00,          out_uint16_le(s, RDP_CAPLEN_BRUSHCACHE);
860          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          out_uint32_le(s, 1);    /* cache type */
861          0x00, 0x00, 0x00, 0x00, 0x00,  }
862          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
863          0x00, 0x00, 0x00, 0x00, 0x00,  static uint8 caps_0x0d[] = {
864          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
865          0x0C, 0x00, 0x08, 0x00, 0x01,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
866          0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
867          0x10, 0x00, 0x34, 0x00, 0xFE,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
868          0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
869          0xFE, 0x00, 0x08, 0x00, 0xFE,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
870          0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
871          0xFE, 0x00, 0x80, 0x00, 0xFE,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
872          0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
873          0x02, 0x00, 0x00, 0x00          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
874            0x00, 0x00, 0x00, 0x00
875  };  };
876    
877  /* Output unknown capability sets (number 13, 12, 14 and 16) */  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
878    
879    static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
880    
881    static uint8 caps_0x10[] = {
882            0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
883            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
884            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
885            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
886            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
887            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
888    };
889    
890    /* Output unknown capability sets */
891  static void  static void
892  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
893  {  {
894          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
895          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
896    
897          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
898  }  }
899    
900  #define RDP5_FLAG 0x0030  #define RDP5_FLAG 0x0030
# Line 588  rdp_send_confirm_active(void) Line 908  rdp_send_confirm_active(void)
908                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
909                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
910                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
911                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
912                    RDP_CAPLEN_BRUSHCACHE + 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
913                    4 /* w2k fix, why? */ ;
914    
915          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
916    
# Line 608  rdp_send_confirm_active(void) Line 930  rdp_send_confirm_active(void)
930          rdp_out_general_caps(s);          rdp_out_general_caps(s);
931          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
932          rdp_out_order_caps(s);          rdp_out_order_caps(s);
933          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
934          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
935          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
936          rdp_out_control_caps(s);          rdp_out_control_caps(s);
937          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
938          rdp_out_share_caps(s);          rdp_out_share_caps(s);
939          rdp_out_unknown_caps(s);          rdp_out_brushcache_caps(s);
940    
941            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
942            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
943            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
944            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
945    
946          s_mark_end(s);          s_mark_end(s);
947          sec_send(s, sec_flags);          sec_send(s, sec_flags);
# Line 633  rdp_process_general_caps(STREAM s) Line 960  rdp_process_general_caps(STREAM s)
960                  g_use_rdp5 = False;                  g_use_rdp5 = False;
961  }  }
962    
963    
964    void
965    write_file(void)
966    {
967            struct tm time_info;
968            time_t time_seconds;
969            char fname[4096];
970            uint32 divisor = 1000000000;
971            char *c = fname + 25;
972    
973            /* as found in libjpeg sample */
974            struct jpeg_compress_struct cinfo;
975            struct jpeg_error_mgr jerr;
976            JSAMPROW row_pointer[1];
977            FILE *outfile;
978    
979            if (!g_pixels_changed)  /* no change, no write */
980                    return;
981    
982            time_seconds = (time_t) (g_time_last_change / 1000000);
983            localtime_r(&time_seconds, &time_info);
984            strftime((char *) fname, 4096, "/tmp/%Y-%m-%d %H:%M:%S ", &time_info);
985    
986            while (!((g_pixels_changed / divisor) % 10) && (divisor/=10) >1 );
987    
988            do
989            {
990                    *c++ = '0' + (char) ((g_pixels_changed / divisor) % 10);
991            }
992                    while ((divisor/=10) >= 1);
993    
994            *c = 0;
995    
996            strncat(fname, ".jpg", 4096);
997    
998            outfile = fopen(fname, "wb");
999            if (!outfile)
1000            {
1001                    error("can\'t open file %s for write\n", fname);
1002                    exit(1);
1003            }
1004            cinfo.err = jpeg_std_error(&jerr);
1005            jpeg_create_compress(&cinfo);
1006            jpeg_stdio_dest(&cinfo, outfile);
1007            cinfo.image_width = g_width;
1008            cinfo.image_height = g_height;
1009            cinfo.input_components = 3;     /* 3 bytes per pixel, R G B */
1010            cinfo.in_color_space = JCS_RGB;
1011            jpeg_set_defaults(&cinfo);
1012            jpeg_start_compress(&cinfo, TRUE);
1013            while (cinfo.next_scanline < cinfo.image_height)
1014            {
1015                    row_pointer[0] = &g_bitmap_data[cinfo.next_scanline * cinfo.image_width * 3];
1016                    jpeg_write_scanlines(&cinfo, row_pointer, 1);
1017            }
1018            jpeg_finish_compress(&cinfo);
1019            jpeg_destroy_compress(&cinfo);
1020            fclose(outfile);
1021    
1022            g_time_last_write = tod();
1023            printf("%llu (%u) write_file %s\n", g_time_last_write, g_pixels_changed, fname);
1024            memcpy(g_bitmap_data_last_write, g_bitmap_data, g_width * g_height * 3);
1025            g_pixels_changed = 0;
1026    }
1027    
1028  /* Process a bitmap capability set */  /* Process a bitmap capability set */
1029  static void  static void
1030  rdp_process_bitmap_caps(STREAM s)  rdp_process_bitmap_caps(STREAM s)
1031  {  {
1032          uint16 width, height, bpp;          uint16 width, height, depth;
1033    
1034          in_uint16_le(s, bpp);          in_uint16_le(s, depth);
1035          in_uint8s(s, 6);          in_uint8s(s, 6);
1036    
1037          in_uint16_le(s, width);          in_uint16_le(s, width);
1038          in_uint16_le(s, height);          in_uint16_le(s, height);
1039    
1040          DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));          DEBUG(("setting desktop size and depth to: %dx%dx%d\n", width, height, depth));
1041    
1042            if (g_bitmap_data)
1043            {
1044                    /* resolution change, force write of old screen
1045                    g_time_last_change = tod();
1046                    write_file();
1047                    */
1048                    xfree(g_bitmap_data);
1049                    xfree(g_bitmap_data_last_write);
1050            }
1051            g_bitmap_data = (uint8 *) xmalloc(width * height * 3);
1052            g_bitmap_data_last_write = (uint8 *) xmalloc(width * height * 3);
1053            bzero(g_bitmap_data, width * height * 3);
1054            bzero(g_bitmap_data_last_write, width * height * 3);
1055            g_pixels_changed = 0;
1056    
1057          /*          /*
1058           * The server may limit bpp and change the size of the desktop (for           * The server may limit depth and change the size of the desktop (for
1059           * example when shadowing another session).           * example when shadowing another session).
1060           */           */
1061          if (g_server_bpp != bpp)          if (g_server_depth != depth)
1062          {          {
1063                  warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);                  warning("Remote desktop does not support colour depth %d; falling back to %d\n",
1064                  g_server_bpp = bpp;                          g_server_depth, depth);
1065                    g_server_depth = depth;
1066          }          }
1067          if (g_width != width || g_height != height)          if (g_width != width || g_height != height)
1068          {          {
1069                  warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,                  warning("Remote desktop changed from %dx%d to %dx%d.\n", g_width, g_height,
1070                                  width, height);                          width, height);
1071                  g_width = width;                  g_width = width;
1072                  g_height = height;                  g_height = height;
1073                  ui_resize_window();                  ui_resize_window();
1074          }          }
1075  }  }
1076    
1077  /* Respond to a demand active PDU */  /* Process server capabilities */
1078  static void  static void
1079  process_demand_active(STREAM s)  rdp_process_server_caps(STREAM s, uint16 length)
1080  {  {
1081          int n;          int n;
1082          uint8 type, *next;          uint8 *next, *start;
1083          uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;          uint16 ncapsets, capset_type, capset_length;
1084    
1085          in_uint32_le(s, g_rdp_shareid);          start = s->p;
         in_uint16_le(s, len_src_descriptor);  
         in_uint16_le(s, len_combined_caps);  
         in_uint8s(s, len_src_descriptor);  
1086    
1087          in_uint16_le(s, num_capsets);          in_uint16_le(s, ncapsets);
1088          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
1089    
1090          DEBUG(("DEMAND_ACTIVE(id=0x%x,num_caps=%d)\n", g_rdp_shareid, num_capsets));          for (n = 0; n < ncapsets; n++)
   
         for (n = 0; n < num_capsets; n++)  
1091          {          {
1092                    if (s->p > start + length)
1093                            return;
1094    
1095                  in_uint16_le(s, capset_type);                  in_uint16_le(s, capset_type);
1096                  in_uint16_le(s, capset_length);                  in_uint16_le(s, capset_length);
1097    
# Line 704  process_demand_active(STREAM s) Line 1110  process_demand_active(STREAM s)
1110    
1111                  s->p = next;                  s->p = next;
1112          }          }
1113    }
1114    
1115    /* Respond to a demand active PDU */
1116    static void
1117    process_demand_active(STREAM s)
1118    {
1119            uint8 type;
1120            uint16 len_src_descriptor, len_combined_caps;
1121    
1122            in_uint32_le(s, g_rdp_shareid);
1123            in_uint16_le(s, len_src_descriptor);
1124            in_uint16_le(s, len_combined_caps);
1125            in_uint8s(s, len_src_descriptor);
1126    
1127            DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
1128            rdp_process_server_caps(s, len_combined_caps);
1129    
1130          rdp_send_confirm_active();          rdp_send_confirm_active();
1131          rdp_send_synchronise();          rdp_send_synchronise();
# Line 712  process_demand_active(STREAM s) Line 1134  process_demand_active(STREAM s)
1134          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
1135          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
1136          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
1137          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0,
1138                           g_numlock_sync ? ui_get_numlock_state(read_keyboard_state()) : 0, 0);
1139    
1140          if (g_use_rdp5)          if (g_use_rdp5)
1141          {          {
1142                    rdp_enum_bmpcache2();
1143                  rdp_send_fonts(3);                  rdp_send_fonts(3);
1144          }          }
1145          else          else
# Line 734  process_colour_pointer_pdu(STREAM s) Line 1158  process_colour_pointer_pdu(STREAM s)
1158  {  {
1159          uint16 x, y, width, height, cache_idx, masklen, datalen;          uint16 x, y, width, height, cache_idx, masklen, datalen;
1160          uint8 *mask, *data;          uint8 *mask, *data;
1161          HCURSOR cursor;          RD_HCURSOR cursor;
1162    
1163          in_uint16_le(s, cache_idx);          in_uint16_le(s, cache_idx);
1164          in_uint16_le(s, x);          in_uint16_le(s, x);
# Line 766  process_system_pointer_pdu(STREAM s) Line 1190  process_system_pointer_pdu(STREAM s)
1190  {  {
1191          uint16 system_pointer_type;          uint16 system_pointer_type;
1192    
1193          in_uint16(s, system_pointer_type);          in_uint16_le(s, system_pointer_type);
1194          switch (system_pointer_type)          switch (system_pointer_type)
1195          {          {
1196                  case RDP_NULL_POINTER:                  case RDP_NULL_POINTER:
# Line 891  process_palette(STREAM s) Line 1315  process_palette(STREAM s)
1315  {  {
1316          COLOURENTRY *entry;          COLOURENTRY *entry;
1317          COLOURMAP map;          COLOURMAP map;
1318          HCOLOURMAP hmap;          RD_HCOLOURMAP hmap;
1319          int i;          int i;
1320    
1321          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
# Line 924  process_update_pdu(STREAM s) Line 1348  process_update_pdu(STREAM s)
1348    
1349          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1350    
1351            ui_begin_update();
1352          switch (update_type)          switch (update_type)
1353          {          {
1354                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
# Line 947  process_update_pdu(STREAM s) Line 1372  process_update_pdu(STREAM s)
1372                  default:                  default:
1373                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1374          }          }
1375            ui_end_update();
1376  }  }
1377    
1378  /* Process a disconnect PDU */  /* Process a disconnect PDU */
# Line 960  process_disconnect_pdu(STREAM s, uint32 Line 1385  process_disconnect_pdu(STREAM s, uint32
1385  }  }
1386    
1387  /* Process data PDU */  /* Process data PDU */
1388  static BOOL  static RD_BOOL
1389  process_data_pdu(STREAM s, uint32 * ext_disc_reason)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1390  {  {
1391          uint8 data_pdu_type;          uint8 data_pdu_type;
# Line 973  process_data_pdu(STREAM s, uint32 * ext_ Line 1398  process_data_pdu(STREAM s, uint32 * ext_
1398          struct stream *ns = &(g_mppc_dict.ns);          struct stream *ns = &(g_mppc_dict.ns);
1399    
1400          in_uint8s(s, 6);        /* shareid, pad, streamid */          in_uint8s(s, 6);        /* shareid, pad, streamid */
1401          in_uint16(s, len);          in_uint16_le(s, len);
1402          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
1403          in_uint8(s, ctype);          in_uint8(s, ctype);
1404          in_uint16(s, clen);          in_uint16_le(s, clen);
1405          clen -= 18;          clen -= 18;
1406    
1407          if (ctype & RDP_MPPC_COMPRESSED)          if (ctype & RDP_MPPC_COMPRESSED)
1408          {          {
1409                    if (len > RDP_MPPC_DICT_SIZE)
1410                            error("error decompressed packet size exceeds max\n");
1411                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1412                          error("error while decompressing packet\n");                          error("error while decompressing packet\n");
1413    
1414                  //len -= 18;                  /* len -= 18; */
1415    
1416                  /* allocate memory and copy the uncompressed data into the temporary stream */                  /* allocate memory and copy the uncompressed data into the temporary stream */
1417                  ns->data = (uint8 *) xrealloc(ns->data, rlen);                  ns->data = (uint8 *) xrealloc(ns->data, rlen);
# Line 1029  process_data_pdu(STREAM s, uint32 * ext_ Line 1455  process_data_pdu(STREAM s, uint32 * ext_
1455    
1456                  case RDP_DATA_PDU_DISCONNECT:                  case RDP_DATA_PDU_DISCONNECT:
1457                          process_disconnect_pdu(s, ext_disc_reason);                          process_disconnect_pdu(s, ext_disc_reason);
1458                          return True;  
1459                            /* We used to return true and disconnect immediately here, but
1460                             * Windows Vista sends a disconnect PDU with reason 0 when
1461                             * reconnecting to a disconnected session, and MSTSC doesn't
1462                             * drop the connection.  I think we should just save the status.
1463                             */
1464                            break;
1465    
1466                  default:                  default:
1467                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
# Line 1037  process_data_pdu(STREAM s, uint32 * ext_ Line 1469  process_data_pdu(STREAM s, uint32 * ext_
1469          return False;          return False;
1470  }  }
1471    
1472    /* Process redirect PDU from Session Directory */
1473    static RD_BOOL
1474    process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
1475    {
1476            uint32 len;
1477    
1478            /* these 2 bytes are unknown, seem to be zeros */
1479            in_uint8s(s, 2);
1480    
1481            /* read connection flags */
1482            in_uint32_le(s, g_redirect_flags);
1483    
1484            /* read length of ip string */
1485            in_uint32_le(s, len);
1486    
1487            /* read ip string */
1488            rdp_in_unistr(s, g_redirect_server, sizeof(g_redirect_server), len);
1489    
1490            /* read length of cookie string */
1491            in_uint32_le(s, len);
1492    
1493            /* read cookie string (plain ASCII) */
1494            if (len > sizeof(g_redirect_cookie) - 1)
1495            {
1496                    uint32 rem = len - (sizeof(g_redirect_cookie) - 1);
1497                    len = sizeof(g_redirect_cookie) - 1;
1498    
1499                    warning("Unexpectedly large redirection cookie\n");
1500                    in_uint8a(s, g_redirect_cookie, len);
1501                    in_uint8s(s, rem);
1502            }
1503            else
1504            {
1505                    in_uint8a(s, g_redirect_cookie, len);
1506            }
1507            g_redirect_cookie[len] = 0;
1508    
1509            /* read length of username string */
1510            in_uint32_le(s, len);
1511    
1512            /* read username string */
1513            g_redirect_username = (char *) xmalloc(len + 1);
1514            rdp_in_unistr(s, g_redirect_username, strlen(g_redirect_username), len);
1515    
1516            /* read length of domain string */
1517            in_uint32_le(s, len);
1518    
1519            /* read domain string */
1520            rdp_in_unistr(s, g_redirect_domain, sizeof(g_redirect_domain), len);
1521    
1522            /* read length of password string */
1523            in_uint32_le(s, len);
1524    
1525            /* read password string */
1526            rdp_in_unistr(s, g_redirect_password, sizeof(g_redirect_password), len);
1527    
1528            g_redirect = True;
1529    
1530            return True;
1531    }
1532    
1533  /* Process incoming packets */  /* Process incoming packets */
1534    /* nevers gets out of here till app is done */
1535  void  void
1536  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_main_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason)
1537    {
1538            while (rdp_loop(deactivated, ext_disc_reason))
1539                    ;
1540    }
1541    
1542    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1543    RD_BOOL
1544    rdp_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason)
1545  {  {
1546          uint8 type;          uint8 type;
1547          BOOL disc = False;      /* True when a disconnect PDU was received */          RD_BOOL disc = False;   /* True when a disconnect PDU was received */
1548            RD_BOOL cont = True;
1549          STREAM s;          STREAM s;
1550    
1551          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1552          {          {
1553                    s = rdp_recv(&type);
1554                    if (s == NULL)
1555                            return False;
1556                  switch (type)                  switch (type)
1557                  {                  {
1558                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1559                                  process_demand_active(s);                                  process_demand_active(s);
1560                                  *deactivated = False;                                  *deactivated = False;
1561                                  break;                                  break;
   
1562                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1563                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1564                                  *deactivated = True;                                  *deactivated = True;
1565                                  break;                                  break;
1566                            case RDP_PDU_REDIRECT:
1567                                    return process_redirect_pdu(s);
1568                                    break;
1569                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1570                                  disc = process_data_pdu(s, ext_disc_reason);                                  disc = process_data_pdu(s, ext_disc_reason);
1571                                  break;                                  break;
   
1572                          case 0:                          case 0:
1573                                  break;                                  break;
   
1574                          default:                          default:
1575                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1576                  }                  }
   
1577                  if (disc)                  if (disc)
1578                  {                          return False;
1579                          return;                  cont = g_next_packet < s->end;
                 }  
1580          }          }
1581          return;          return True;
1582  }  }
1583    
1584  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */
1585  BOOL  RD_BOOL
1586  rdp_connect(char *server, uint32 flags, char *domain, char *password,  rdp_connect(char *server, uint32 flags, char *domain, char *password,
1587              char *command, char *directory)              char *command, char *directory)
1588  {  {
# Line 1090  rdp_connect(char *server, uint32 flags, Line 1593  rdp_connect(char *server, uint32 flags,
1593          return True;          return True;
1594  }  }
1595    
1596    /* Establish a reconnection up to the RDP layer */
1597    RD_BOOL
1598    rdp_reconnect(char *server, uint32 flags, char *domain, char *password,
1599                  char *command, char *directory, char *cookie)
1600    {
1601            if (!sec_reconnect(server))
1602                    return False;
1603    
1604            rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1605            return True;
1606    }
1607    
1608    /* Called during redirection to reset the state to support redirection */
1609    void
1610    rdp_reset_state(void)
1611    {
1612            g_next_packet = NULL;   /* reset the packet information */
1613            g_rdp_shareid = 0;
1614            sec_reset_state();
1615    }
1616    
1617  /* Disconnect from the RDP layer */  /* Disconnect from the RDP layer */
1618  void  void
1619  rdp_disconnect(void)  rdp_disconnect(void)

Legend:
Removed from v.711  
changed lines
  Added in v.1508

  ViewVC Help
Powered by ViewVC 1.1.26