Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenrdp.c
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 8 -*- 00002 rdesktop: A Remote Desktop Protocol client. 00003 Protocol services - RDP layer 00004 Copyright (C) Matthew Chapman 1999-2005 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License along 00017 with this program; if not, write to the Free Software Foundation, Inc., 00018 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 #include <precomp.h> 00022 00023 00024 extern uint16 g_mcs_userid; 00025 extern char g_username[]; 00026 extern char g_codepage[]; 00027 extern BOOL g_bitmap_compression; 00028 extern BOOL g_orders; 00029 extern BOOL g_encryption; 00030 extern BOOL g_desktop_save; 00031 extern BOOL g_polygon_ellipse_orders; 00032 extern BOOL g_use_rdp5; 00033 extern uint16 g_server_rdp_version; 00034 extern uint32 g_rdp5_performanceflags; 00035 extern int g_server_depth; 00036 extern int g_width; 00037 extern int g_height; 00038 extern BOOL g_bitmap_cache; 00039 extern BOOL g_bitmap_cache_persist_enable; 00040 00041 uint8 *g_next_packet; 00042 uint32 g_rdp_shareid; 00043 00044 extern RDPCOMP g_mppc_dict; 00045 00046 /* Session Directory support */ 00047 extern BOOL g_redirect; 00048 extern char g_redirect_server[64]; 00049 extern char g_redirect_domain[16]; 00050 extern char g_redirect_password[64]; 00051 extern char g_redirect_username[64]; 00052 extern char g_redirect_cookie[128]; 00053 extern uint32 g_redirect_flags; 00054 /* END Session Directory support */ 00055 00056 #ifdef WITH_DEBUG 00057 static uint32 g_packetno; 00058 #endif 00059 00060 #ifdef HAVE_ICONV 00061 static BOOL g_iconv_works = True; 00062 #endif 00063 00064 /* Receive an RDP packet */ 00065 static STREAM 00066 rdp_recv(uint8 * type) 00067 { 00068 static STREAM rdp_s; 00069 uint16 length, pdu_type; 00070 uint8 rdpver; 00071 00072 if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL)) 00073 { 00074 rdp_s = sec_recv(&rdpver); 00075 if (rdp_s == NULL) 00076 return NULL; 00077 if (rdpver == 0xff) 00078 { 00079 g_next_packet = rdp_s->end; 00080 *type = 0; 00081 return rdp_s; 00082 } 00083 else if (rdpver != 3) 00084 { 00085 /* rdp5_process should move g_next_packet ok */ 00086 rdp5_process(rdp_s); 00087 *type = 0; 00088 return rdp_s; 00089 } 00090 00091 g_next_packet = rdp_s->p; 00092 } 00093 else 00094 { 00095 rdp_s->p = g_next_packet; 00096 } 00097 00098 in_uint16_le(rdp_s, length); 00099 /* 32k packets are really 8, keepalive fix */ 00100 if (length == 0x8000) 00101 { 00102 g_next_packet += 8; 00103 *type = 0; 00104 return rdp_s; 00105 } 00106 in_uint16_le(rdp_s, pdu_type); 00107 in_uint8s(rdp_s, 2); /* userid */ 00108 *type = pdu_type & 0xf; 00109 00110 #ifdef WITH_DEBUG 00111 DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type)); 00112 hexdump(g_next_packet, length); 00113 #endif /* */ 00114 00115 g_next_packet += length; 00116 return rdp_s; 00117 } 00118 00119 /* Initialise an RDP data packet */ 00120 static STREAM 00121 rdp_init_data(int maxlen) 00122 { 00123 STREAM s = NULL; 00124 00125 s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18); 00126 s_push_layer(s, rdp_hdr, 18); 00127 00128 return s; 00129 } 00130 00131 /* Send an RDP data packet */ 00132 static void 00133 rdp_send_data(STREAM s, uint8 data_pdu_type) 00134 { 00135 uint16 length; 00136 00137 s_pop_layer(s, rdp_hdr); 00138 length = s->end - s->p; 00139 00140 out_uint16_le(s, length); 00141 out_uint16_le(s, (RDP_PDU_DATA | 0x10)); 00142 out_uint16_le(s, (g_mcs_userid + 1001)); 00143 00144 out_uint32_le(s, g_rdp_shareid); 00145 out_uint8(s, 0); /* pad */ 00146 out_uint8(s, 1); /* streamid */ 00147 out_uint16_le(s, (length - 14)); 00148 out_uint8(s, data_pdu_type); 00149 out_uint8(s, 0); /* compress_type */ 00150 out_uint16(s, 0); /* compress_len */ 00151 00152 sec_send(s, g_encryption ? SEC_ENCRYPT : 0); 00153 } 00154 00155 /* Output a string in Unicode */ 00156 void 00157 rdp_out_unistr(STREAM s, char *string, int len) 00158 { 00159 #ifdef HAVE_ICONV 00160 size_t ibl = strlen(string), obl = len + 2; 00161 static iconv_t iconv_h = (iconv_t) - 1; 00162 char *pin = string, *pout = (char *) s->p; 00163 00164 memset(pout, 0, len + 4); 00165 00166 if (g_iconv_works) 00167 { 00168 if (iconv_h == (iconv_t) - 1) 00169 { 00170 size_t i = 1, o = 4; 00171 if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1) 00172 { 00173 warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n", 00174 g_codepage, WINDOWS_CODEPAGE, (int) iconv_h); 00175 00176 g_iconv_works = False; 00177 rdp_out_unistr(s, string, len); 00178 return; 00179 } 00180 if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) == 00181 (size_t) - 1) 00182 { 00183 iconv_close(iconv_h); 00184 iconv_h = (iconv_t) - 1; 00185 warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno); 00186 00187 g_iconv_works = False; 00188 rdp_out_unistr(s, string, len); 00189 return; 00190 } 00191 pin = string; 00192 pout = (char *) s->p; 00193 } 00194 00195 if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) 00196 { 00197 iconv_close(iconv_h); 00198 iconv_h = (iconv_t) - 1; 00199 warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno); 00200 00201 g_iconv_works = False; 00202 rdp_out_unistr(s, string, len); 00203 return; 00204 } 00205 00206 s->p += len + 2; 00207 00208 } 00209 else 00210 #endif 00211 { 00212 int i = 0, j = 0; 00213 00214 len += 2; 00215 00216 while (i < len) 00217 { 00218 s->p[i++] = string[j++]; 00219 s->p[i++] = 0; 00220 } 00221 00222 s->p += len; 00223 } 00224 } 00225 00226 /* Input a string in Unicode 00227 * 00228 * Returns str_len of string 00229 */ 00230 int 00231 rdp_in_unistr(STREAM s, char *string, int uni_len) 00232 { 00233 #ifdef HAVE_ICONV 00234 size_t ibl = uni_len, obl = uni_len; 00235 char *pin = (char *) s->p, *pout = string; 00236 static iconv_t iconv_h = (iconv_t) - 1; 00237 00238 if (g_iconv_works) 00239 { 00240 if (iconv_h == (iconv_t) - 1) 00241 { 00242 if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1) 00243 { 00244 warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n", 00245 WINDOWS_CODEPAGE, g_codepage, (int) iconv_h); 00246 00247 g_iconv_works = False; 00248 return rdp_in_unistr(s, string, uni_len); 00249 } 00250 } 00251 00252 if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) 00253 { 00254 iconv_close(iconv_h); 00255 iconv_h = (iconv_t) - 1; 00256 warning("rdp_in_unistr: iconv fail, errno %d\n", errno); 00257 00258 g_iconv_works = False; 00259 return rdp_in_unistr(s, string, uni_len); 00260 } 00261 00262 /* we must update the location of the current STREAM for future reads of s->p */ 00263 s->p += uni_len; 00264 00265 return pout - string; 00266 } 00267 else 00268 #endif 00269 { 00270 int i = 0; 00271 00272 while (i < uni_len / 2) 00273 { 00274 in_uint8a(s, &string[i++], 1); 00275 in_uint8s(s, 1); 00276 } 00277 00278 return i - 1; 00279 } 00280 } 00281 00282 00283 /* Parse a logon info packet */ 00284 static void 00285 rdp_send_logon_info(uint32 flags, char *domain, char *user, 00286 char *password, char *program, char *directory) 00287 { 00288 //char *ipaddr = tcp_get_address(); 00289 int len_domain = 2 * strlen(domain); 00290 int len_user = 2 * strlen(user); 00291 int len_password = 2 * strlen(password); 00292 int len_program = 2 * strlen(program); 00293 int len_directory = 2 * strlen(directory); 00294 //int len_ip = 2 * strlen(ipaddr); 00295 //int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll"); 00296 //int packetlen = 0; 00297 uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO; 00298 STREAM s = NULL; 00299 //time_t t = time(NULL); 00300 //time_t tzone; 00301 00302 if (!g_use_rdp5 || 1 == g_server_rdp_version) 00303 { 00304 DEBUG_RDP5(("Sending RDP4-style Logon packet\n")); 00305 00306 s = sec_init(sec_flags, 18 + len_domain + len_user + len_password 00307 + len_program + len_directory + 10); 00308 00309 out_uint32(s, 0); 00310 out_uint32_le(s, flags); 00311 out_uint16_le(s, len_domain); 00312 out_uint16_le(s, len_user); 00313 out_uint16_le(s, len_password); 00314 out_uint16_le(s, len_program); 00315 out_uint16_le(s, len_directory); 00316 rdp_out_unistr(s, domain, len_domain); 00317 rdp_out_unistr(s, user, len_user); 00318 rdp_out_unistr(s, password, len_password); 00319 rdp_out_unistr(s, program, len_program); 00320 rdp_out_unistr(s, directory, len_directory); 00321 } 00322 else 00323 { 00324 #if 0 00325 flags |= RDP_LOGON_BLOB; 00326 DEBUG_RDP5(("Sending RDP5-style Logon packet\n")); 00327 packetlen = 4 + /* Unknown uint32 */ 00328 4 + /* flags */ 00329 2 + /* len_domain */ 00330 2 + /* len_user */ 00331 (flags & RDP_LOGON_AUTO ? 2 : 0) + /* len_password */ 00332 (flags & RDP_LOGON_BLOB ? 2 : 0) + /* Length of BLOB */ 00333 2 + /* len_program */ 00334 2 + /* len_directory */ 00335 (0 < len_domain ? len_domain : 2) + /* domain */ 00336 len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 + /* We have no 512 byte BLOB. Perhaps we must? */ 00337 (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */ 00338 (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 + /* Unknown (2) */ 00339 2 + /* Client ip length */ 00340 len_ip + /* Client ip */ 00341 2 + /* DLL string length */ 00342 len_dll + /* DLL string */ 00343 2 + /* Unknown */ 00344 2 + /* Unknown */ 00345 64 + /* Time zone #0 */ 00346 2 + /* Unknown */ 00347 64 + /* Time zone #1 */ 00348 32; /* Unknown */ 00349 00350 s = sec_init(sec_flags, packetlen); 00351 DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen)); 00352 00353 out_uint32(s, 0); /* Unknown */ 00354 out_uint32_le(s, flags); 00355 out_uint16_le(s, len_domain); 00356 out_uint16_le(s, len_user); 00357 if (flags & RDP_LOGON_AUTO) 00358 { 00359 out_uint16_le(s, len_password); 00360 00361 } 00362 if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO)) 00363 { 00364 out_uint16_le(s, 0); 00365 } 00366 out_uint16_le(s, len_program); 00367 out_uint16_le(s, len_directory); 00368 if (0 < len_domain) 00369 rdp_out_unistr(s, domain, len_domain); 00370 else 00371 out_uint16_le(s, 0); 00372 rdp_out_unistr(s, user, len_user); 00373 if (flags & RDP_LOGON_AUTO) 00374 { 00375 rdp_out_unistr(s, password, len_password); 00376 } 00377 if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO)) 00378 { 00379 out_uint16_le(s, 0); 00380 } 00381 if (0 < len_program) 00382 { 00383 rdp_out_unistr(s, program, len_program); 00384 00385 } 00386 else 00387 { 00388 out_uint16_le(s, 0); 00389 } 00390 if (0 < len_directory) 00391 { 00392 rdp_out_unistr(s, directory, len_directory); 00393 } 00394 else 00395 { 00396 out_uint16_le(s, 0); 00397 } 00398 out_uint16_le(s, 2); 00399 out_uint16_le(s, len_ip + 2); /* Length of client ip */ 00400 rdp_out_unistr(s, ipaddr, len_ip); 00401 out_uint16_le(s, len_dll + 2); 00402 rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll); 00403 00404 tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60; 00405 out_uint32_le(s, tzone); 00406 00407 rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid")); 00408 out_uint8s(s, 62 - 2 * strlen("GTB, normaltid")); 00409 00410 out_uint32_le(s, 0x0a0000); 00411 out_uint32_le(s, 0x050000); 00412 out_uint32_le(s, 3); 00413 out_uint32_le(s, 0); 00414 out_uint32_le(s, 0); 00415 00416 rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid")); 00417 out_uint8s(s, 62 - 2 * strlen("GTB, sommartid")); 00418 00419 out_uint32_le(s, 0x30000); 00420 out_uint32_le(s, 0x050000); 00421 out_uint32_le(s, 2); 00422 out_uint32(s, 0); 00423 out_uint32_le(s, 0xffffffc4); 00424 out_uint32_le(s, 0xfffffffe); 00425 out_uint32_le(s, g_rdp5_performanceflags); 00426 out_uint32(s, 0); 00427 00428 #endif 00429 } 00430 s_mark_end(s); 00431 sec_send(s, sec_flags); 00432 } 00433 00434 /* Send a control PDU */ 00435 static void 00436 rdp_send_control(uint16 action) 00437 { 00438 STREAM s; 00439 00440 s = rdp_init_data(8); 00441 00442 out_uint16_le(s, action); 00443 out_uint16(s, 0); /* userid */ 00444 out_uint32(s, 0); /* control id */ 00445 00446 s_mark_end(s); 00447 rdp_send_data(s, RDP_DATA_PDU_CONTROL); 00448 } 00449 00450 /* Send a synchronisation PDU */ 00451 static void 00452 rdp_send_synchronise(void) 00453 { 00454 STREAM s; 00455 00456 s = rdp_init_data(4); 00457 00458 out_uint16_le(s, 1); /* type */ 00459 out_uint16_le(s, 1002); 00460 00461 s_mark_end(s); 00462 rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE); 00463 } 00464 00465 /* Send a single input event */ 00466 void 00467 rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2) 00468 { 00469 STREAM s; 00470 00471 s = rdp_init_data(16); 00472 00473 out_uint16_le(s, 1); /* number of events */ 00474 out_uint16(s, 0); /* pad */ 00475 00476 out_uint32_le(s, time); 00477 out_uint16_le(s, message_type); 00478 out_uint16_le(s, device_flags); 00479 out_uint16_le(s, param1); 00480 out_uint16_le(s, param2); 00481 00482 s_mark_end(s); 00483 rdp_send_data(s, RDP_DATA_PDU_INPUT); 00484 } 00485 00486 /* Send a client window information PDU */ 00487 void 00488 rdp_send_client_window_status(int status) 00489 { 00490 STREAM s; 00491 static int current_status = 1; 00492 00493 if (current_status == status) 00494 return; 00495 00496 s = rdp_init_data(12); 00497 00498 out_uint32_le(s, status); 00499 00500 switch (status) 00501 { 00502 case 0: /* shut the server up */ 00503 break; 00504 00505 case 1: /* receive data again */ 00506 out_uint32_le(s, 0); /* unknown */ 00507 out_uint16_le(s, g_width); 00508 out_uint16_le(s, g_height); 00509 break; 00510 } 00511 00512 s_mark_end(s); 00513 rdp_send_data(s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS); 00514 current_status = status; 00515 } 00516 00517 /* Send persistent bitmap cache enumeration PDU's */ 00518 static void 00519 rdp_enum_bmpcache2(void) 00520 { 00521 STREAM s; 00522 HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS]; 00523 uint32 num_keys, offset, count, flags; 00524 00525 offset = 0; 00526 num_keys = pstcache_enumerate(2, keylist); 00527 00528 while (offset < num_keys) 00529 { 00530 count = MIN(num_keys - offset, 169); 00531 00532 s = rdp_init_data(24 + count * sizeof(HASH_KEY)); 00533 00534 flags = 0; 00535 if (offset == 0) 00536 flags |= PDU_FLAG_FIRST; 00537 if (num_keys - offset <= 169) 00538 flags |= PDU_FLAG_LAST; 00539 00540 /* header */ 00541 out_uint32_le(s, 0); 00542 out_uint16_le(s, count); 00543 out_uint16_le(s, 0); 00544 out_uint16_le(s, 0); 00545 out_uint16_le(s, 0); 00546 out_uint16_le(s, 0); 00547 out_uint16_le(s, num_keys); 00548 out_uint32_le(s, 0); 00549 out_uint32_le(s, flags); 00550 00551 /* list */ 00552 out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY)); 00553 00554 s_mark_end(s); 00555 rdp_send_data(s, 0x2b); 00556 00557 offset += 169; 00558 } 00559 } 00560 00561 /* Send an (empty) font information PDU */ 00562 static void 00563 rdp_send_fonts(uint16 seq) 00564 { 00565 STREAM s; 00566 00567 s = rdp_init_data(8); 00568 00569 out_uint16(s, 0); /* number of fonts */ 00570 out_uint16_le(s, 0); /* pad? */ 00571 out_uint16_le(s, seq); /* unknown */ 00572 out_uint16_le(s, 0x32); /* entry size */ 00573 00574 s_mark_end(s); 00575 rdp_send_data(s, RDP_DATA_PDU_FONT2); 00576 } 00577 00578 /* Output general capability set */ 00579 static void 00580 rdp_out_general_caps(STREAM s) 00581 { 00582 out_uint16_le(s, RDP_CAPSET_GENERAL); 00583 out_uint16_le(s, RDP_CAPLEN_GENERAL); 00584 00585 out_uint16_le(s, 1); /* OS major type */ 00586 out_uint16_le(s, 3); /* OS minor type */ 00587 out_uint16_le(s, 0x200); /* Protocol version */ 00588 out_uint16(s, 0); /* Pad */ 00589 out_uint16(s, 0); /* Compression types */ 00590 out_uint16_le(s, g_use_rdp5 ? 0x40d : 0); 00591 /* Pad, according to T.128. 0x40d seems to 00592 trigger 00593 the server to start sending RDP5 packets. 00594 However, the value is 0x1d04 with W2KTSK and 00595 NT4MS. Hmm.. Anyway, thankyou, Microsoft, 00596 for sending such information in a padding 00597 field.. */ 00598 out_uint16(s, 0); /* Update capability */ 00599 out_uint16(s, 0); /* Remote unshare capability */ 00600 out_uint16(s, 0); /* Compression level */ 00601 out_uint16(s, 0); /* Pad */ 00602 } 00603 00604 /* Output bitmap capability set */ 00605 static void 00606 rdp_out_bitmap_caps(STREAM s) 00607 { 00608 out_uint16_le(s, RDP_CAPSET_BITMAP); 00609 out_uint16_le(s, RDP_CAPLEN_BITMAP); 00610 00611 out_uint16_le(s, g_server_depth); /* Preferred colour depth */ 00612 out_uint16_le(s, 1); /* Receive 1 BPP */ 00613 out_uint16_le(s, 1); /* Receive 4 BPP */ 00614 out_uint16_le(s, 1); /* Receive 8 BPP */ 00615 out_uint16_le(s, 800); /* Desktop width */ 00616 out_uint16_le(s, 600); /* Desktop height */ 00617 out_uint16(s, 0); /* Pad */ 00618 out_uint16(s, 1); /* Allow resize */ 00619 out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */ 00620 out_uint16(s, 0); /* Unknown */ 00621 out_uint16_le(s, 1); /* Unknown */ 00622 out_uint16(s, 0); /* Pad */ 00623 } 00624 00625 /* Output order capability set */ 00626 static void 00627 rdp_out_order_caps(STREAM s) 00628 { 00629 uint8 order_caps[32]; 00630 00631 memset(order_caps, 0, 32); 00632 order_caps[0] = 1; /* dest blt */ 00633 order_caps[1] = 1; /* pat blt */ 00634 order_caps[2] = 1; /* screen blt */ 00635 order_caps[3] = (g_bitmap_cache ? 1 : 0); /* memblt */ 00636 order_caps[4] = 0; /* triblt */ 00637 order_caps[8] = 1; /* line */ 00638 order_caps[9] = 1; /* line */ 00639 order_caps[10] = 1; /* rect */ 00640 order_caps[11] = (g_desktop_save ? 1 : 0); /* desksave */ 00641 order_caps[13] = 1; /* memblt */ 00642 order_caps[14] = 1; /* triblt */ 00643 order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon */ 00644 order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon2 */ 00645 order_caps[22] = 1; /* polyline */ 00646 order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse */ 00647 order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse2 */ 00648 order_caps[27] = 1; /* text2 */ 00649 out_uint16_le(s, RDP_CAPSET_ORDER); 00650 out_uint16_le(s, RDP_CAPLEN_ORDER); 00651 00652 out_uint8s(s, 20); /* Terminal desc, pad */ 00653 out_uint16_le(s, 1); /* Cache X granularity */ 00654 out_uint16_le(s, 20); /* Cache Y granularity */ 00655 out_uint16(s, 0); /* Pad */ 00656 out_uint16_le(s, 1); /* Max order level */ 00657 out_uint16_le(s, 0x147); /* Number of fonts */ 00658 out_uint16_le(s, 0x2a); /* Capability flags */ 00659 out_uint8p(s, order_caps, 32); /* Orders supported */ 00660 out_uint16_le(s, 0x6a1); /* Text capability flags */ 00661 out_uint8s(s, 6); /* Pad */ 00662 out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400); /* Desktop cache size */ 00663 out_uint32(s, 0); /* Unknown */ 00664 out_uint32_le(s, 0x4e4); /* Unknown */ 00665 } 00666 00667 /* Output bitmap cache capability set */ 00668 static void 00669 rdp_out_bmpcache_caps(STREAM s) 00670 { 00671 int Bpp; 00672 out_uint16_le(s, RDP_CAPSET_BMPCACHE); 00673 out_uint16_le(s, RDP_CAPLEN_BMPCACHE); 00674 00675 Bpp = (g_server_depth + 7) / 8; /* bytes per pixel */ 00676 out_uint8s(s, 24); /* unused */ 00677 out_uint16_le(s, 0x258); /* entries */ 00678 out_uint16_le(s, 0x100 * Bpp); /* max cell size */ 00679 out_uint16_le(s, 0x12c); /* entries */ 00680 out_uint16_le(s, 0x400 * Bpp); /* max cell size */ 00681 out_uint16_le(s, 0x106); /* entries */ 00682 out_uint16_le(s, 0x1000 * Bpp); /* max cell size */ 00683 } 00684 00685 /* Output bitmap cache v2 capability set */ 00686 static void 00687 rdp_out_bmpcache2_caps(STREAM s) 00688 { 00689 out_uint16_le(s, RDP_CAPSET_BMPCACHE2); 00690 out_uint16_le(s, RDP_CAPLEN_BMPCACHE2); 00691 00692 out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0); /* version */ 00693 00694 out_uint16_be(s, 3); /* number of caches in this set */ 00695 00696 /* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */ 00697 out_uint32_le(s, BMPCACHE2_C0_CELLS); 00698 out_uint32_le(s, BMPCACHE2_C1_CELLS); 00699 if (pstcache_init(2)) 00700 { 00701 out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST); 00702 } 00703 else 00704 { 00705 out_uint32_le(s, BMPCACHE2_C2_CELLS); 00706 } 00707 out_uint8s(s, 20); /* other bitmap caches not used */ 00708 } 00709 00710 /* Output control capability set */ 00711 static void 00712 rdp_out_control_caps(STREAM s) 00713 { 00714 out_uint16_le(s, RDP_CAPSET_CONTROL); 00715 out_uint16_le(s, RDP_CAPLEN_CONTROL); 00716 00717 out_uint16(s, 0); /* Control capabilities */ 00718 out_uint16(s, 0); /* Remote detach */ 00719 out_uint16_le(s, 2); /* Control interest */ 00720 out_uint16_le(s, 2); /* Detach interest */ 00721 } 00722 00723 /* Output activation capability set */ 00724 static void 00725 rdp_out_activate_caps(STREAM s) 00726 { 00727 out_uint16_le(s, RDP_CAPSET_ACTIVATE); 00728 out_uint16_le(s, RDP_CAPLEN_ACTIVATE); 00729 00730 out_uint16(s, 0); /* Help key */ 00731 out_uint16(s, 0); /* Help index key */ 00732 out_uint16(s, 0); /* Extended help key */ 00733 out_uint16(s, 0); /* Window activate */ 00734 } 00735 00736 /* Output pointer capability set */ 00737 static void 00738 rdp_out_pointer_caps(STREAM s) 00739 { 00740 out_uint16_le(s, RDP_CAPSET_POINTER); 00741 out_uint16_le(s, RDP_CAPLEN_POINTER); 00742 00743 out_uint16(s, 0); /* Colour pointer */ 00744 out_uint16_le(s, 20); /* Cache size */ 00745 } 00746 00747 /* Output share capability set */ 00748 static void 00749 rdp_out_share_caps(STREAM s) 00750 { 00751 out_uint16_le(s, RDP_CAPSET_SHARE); 00752 out_uint16_le(s, RDP_CAPLEN_SHARE); 00753 00754 out_uint16(s, 0); /* userid */ 00755 out_uint16(s, 0); /* pad */ 00756 } 00757 00758 /* Output colour cache capability set */ 00759 static void 00760 rdp_out_colcache_caps(STREAM s) 00761 { 00762 out_uint16_le(s, RDP_CAPSET_COLCACHE); 00763 out_uint16_le(s, RDP_CAPLEN_COLCACHE); 00764 00765 out_uint16_le(s, 6); /* cache size */ 00766 out_uint16(s, 0); /* pad */ 00767 } 00768 00769 static uint8 caps_0x0d[] = { 00770 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 00771 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00772 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00779 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00780 0x00, 0x00, 0x00, 0x00 00781 }; 00782 00783 static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 }; 00784 00785 static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 }; 00786 00787 static uint8 caps_0x10[] = { 00788 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 00789 0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00, 00790 0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 00791 0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00, 00792 0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 00793 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00 00794 }; 00795 00796 /* Output unknown capability sets */ 00797 static void 00798 rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps) 00799 { 00800 out_uint16_le(s, id); 00801 out_uint16_le(s, length); 00802 00803 out_uint8p(s, caps, length - 4); 00804 } 00805 00806 #define RDP5_FLAG 0x0030 00807 /* Send a confirm active PDU */ 00808 static void 00809 rdp_send_confirm_active(void) 00810 { 00811 STREAM s; 00812 uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG; 00813 uint16 caplen = 00814 RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER + 00815 RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE + 00816 RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL + 00817 RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + 00818 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ + 00819 4 /* w2k fix, why? */ ; 00820 00821 s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE)); 00822 00823 out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE)); 00824 out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */ 00825 out_uint16_le(s, (g_mcs_userid + 1001)); 00826 00827 out_uint32_le(s, g_rdp_shareid); 00828 out_uint16_le(s, 0x3ea); /* userid */ 00829 out_uint16_le(s, sizeof(RDP_SOURCE)); 00830 out_uint16_le(s, caplen); 00831 00832 out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE)); 00833 out_uint16_le(s, 0xd); /* num_caps */ 00834 out_uint8s(s, 2); /* pad */ 00835 00836 rdp_out_general_caps(s); 00837 rdp_out_bitmap_caps(s); 00838 rdp_out_order_caps(s); 00839 g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s); 00840 rdp_out_colcache_caps(s); 00841 rdp_out_activate_caps(s); 00842 rdp_out_control_caps(s); 00843 rdp_out_pointer_caps(s); 00844 rdp_out_share_caps(s); 00845 00846 rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */ 00847 rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c); 00848 rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e); 00849 rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */ 00850 00851 s_mark_end(s); 00852 sec_send(s, sec_flags); 00853 } 00854 00855 /* Process a general capability set */ 00856 static void 00857 rdp_process_general_caps(STREAM s) 00858 { 00859 uint16 pad2octetsB; /* rdp5 flags? */ 00860 00861 in_uint8s(s, 10); 00862 in_uint16_le(s, pad2octetsB); 00863 00864 if (!pad2octetsB) 00865 g_use_rdp5 = False; 00866 } 00867 00868 /* Process a bitmap capability set */ 00869 static void 00870 rdp_process_bitmap_caps(STREAM s) 00871 { 00872 uint16 width, height, depth; 00873 00874 in_uint16_le(s, depth); 00875 in_uint8s(s, 6); 00876 00877 in_uint16_le(s, width); 00878 in_uint16_le(s, height); 00879 00880 DEBUG(("setting desktop size and depth to: %dx%dx%d\n", width, height, depth)); 00881 00882 /* 00883 * The server may limit depth and change the size of the desktop (for 00884 * example when shadowing another session). 00885 */ 00886 if (g_server_depth != depth) 00887 { 00888 warning("Remote desktop does not support colour depth %d; falling back to %d\n", 00889 g_server_depth, depth); 00890 g_server_depth = depth; 00891 } 00892 if (g_width != width || g_height != height) 00893 { 00894 warning("Remote desktop changed from %dx%d to %dx%d.\n", g_width, g_height, 00895 width, height); 00896 g_width = width; 00897 g_height = height; 00898 ui_resize_window(); 00899 } 00900 } 00901 00902 /* Process server capabilities */ 00903 static void 00904 rdp_process_server_caps(STREAM s, uint16 length) 00905 { 00906 int n; 00907 uint8 *next, *start; 00908 uint16 ncapsets, capset_type, capset_length; 00909 00910 start = s->p; 00911 00912 in_uint16_le(s, ncapsets); 00913 in_uint8s(s, 2); /* pad */ 00914 00915 for (n = 0; n < ncapsets; n++) 00916 { 00917 if (s->p > start + length) 00918 return; 00919 00920 in_uint16_le(s, capset_type); 00921 in_uint16_le(s, capset_length); 00922 00923 next = s->p + capset_length - 4; 00924 00925 switch (capset_type) 00926 { 00927 case RDP_CAPSET_GENERAL: 00928 rdp_process_general_caps(s); 00929 break; 00930 00931 case RDP_CAPSET_BITMAP: 00932 rdp_process_bitmap_caps(s); 00933 break; 00934 } 00935 00936 s->p = next; 00937 } 00938 } 00939 00940 /* Respond to a demand active PDU */ 00941 static void 00942 process_demand_active(STREAM s) 00943 { 00944 uint8 type; 00945 uint16 len_src_descriptor, len_combined_caps; 00946 00947 in_uint32_le(s, g_rdp_shareid); 00948 in_uint16_le(s, len_src_descriptor); 00949 in_uint16_le(s, len_combined_caps); 00950 in_uint8s(s, len_src_descriptor); 00951 00952 DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid)); 00953 rdp_process_server_caps(s, len_combined_caps); 00954 00955 rdp_send_confirm_active(); 00956 rdp_send_synchronise(); 00957 rdp_send_control(RDP_CTL_COOPERATE); 00958 rdp_send_control(RDP_CTL_REQUEST_CONTROL); 00959 rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */ 00960 rdp_recv(&type); /* RDP_CTL_COOPERATE */ 00961 rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */ 00962 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0); 00963 00964 if (g_use_rdp5) 00965 { 00966 rdp_enum_bmpcache2(); 00967 rdp_send_fonts(3); 00968 } 00969 else 00970 { 00971 rdp_send_fonts(1); 00972 rdp_send_fonts(2); 00973 } 00974 00975 rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */ 00976 reset_order_state(); 00977 } 00978 00979 /* Process a colour pointer PDU */ 00980 void 00981 process_colour_pointer_pdu(STREAM s) 00982 { 00983 uint16 x, y, width, height, cache_idx, masklen, datalen; 00984 uint8 *mask, *data; 00985 HCURSOR cursor; 00986 00987 in_uint16_le(s, cache_idx); 00988 in_uint16_le(s, x); 00989 in_uint16_le(s, y); 00990 in_uint16_le(s, width); 00991 in_uint16_le(s, height); 00992 in_uint16_le(s, masklen); 00993 in_uint16_le(s, datalen); 00994 in_uint8p(s, data, datalen); 00995 in_uint8p(s, mask, masklen); 00996 cursor = ui_create_cursor(x, y, width, height, mask, data); 00997 ui_set_cursor(cursor); 00998 cache_put_cursor(cache_idx, cursor); 00999 } 01000 01001 /* Process a cached pointer PDU */ 01002 void 01003 process_cached_pointer_pdu(STREAM s) 01004 { 01005 uint16 cache_idx; 01006 01007 in_uint16_le(s, cache_idx); 01008 ui_set_cursor(cache_get_cursor(cache_idx)); 01009 } 01010 01011 /* Process a system pointer PDU */ 01012 void 01013 process_system_pointer_pdu(STREAM s) 01014 { 01015 uint16 system_pointer_type; 01016 01017 in_uint16(s, system_pointer_type); 01018 switch (system_pointer_type) 01019 { 01020 case RDP_NULL_POINTER: 01021 ui_set_null_cursor(); 01022 break; 01023 01024 default: 01025 unimpl("System pointer message 0x%x\n", system_pointer_type); 01026 } 01027 } 01028 01029 /* Process a pointer PDU */ 01030 static void 01031 process_pointer_pdu(STREAM s) 01032 { 01033 uint16 message_type; 01034 uint16 x, y; 01035 01036 in_uint16_le(s, message_type); 01037 in_uint8s(s, 2); /* pad */ 01038 01039 switch (message_type) 01040 { 01041 case RDP_POINTER_MOVE: 01042 in_uint16_le(s, x); 01043 in_uint16_le(s, y); 01044 if (s_check(s)) 01045 ui_move_pointer(x, y); 01046 break; 01047 01048 case RDP_POINTER_COLOR: 01049 process_colour_pointer_pdu(s); 01050 break; 01051 01052 case RDP_POINTER_CACHED: 01053 process_cached_pointer_pdu(s); 01054 break; 01055 01056 case RDP_POINTER_SYSTEM: 01057 process_system_pointer_pdu(s); 01058 break; 01059 01060 default: 01061 unimpl("Pointer message 0x%x\n", message_type); 01062 } 01063 } 01064 01065 /* Process bitmap updates */ 01066 void 01067 process_bitmap_updates(STREAM s) 01068 { 01069 uint16 num_updates; 01070 uint16 left, top, right, bottom, width, height; 01071 uint16 cx, cy, bpp, Bpp, compress, bufsize, size; 01072 uint8 *data, *bmpdata; 01073 int i; 01074 01075 in_uint16_le(s, num_updates); 01076 01077 for (i = 0; i < num_updates; i++) 01078 { 01079 in_uint16_le(s, left); 01080 in_uint16_le(s, top); 01081 in_uint16_le(s, right); 01082 in_uint16_le(s, bottom); 01083 in_uint16_le(s, width); 01084 in_uint16_le(s, height); 01085 in_uint16_le(s, bpp); 01086 Bpp = (bpp + 7) / 8; 01087 in_uint16_le(s, compress); 01088 in_uint16_le(s, bufsize); 01089 01090 cx = right - left + 1; 01091 cy = bottom - top + 1; 01092 01093 DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n", 01094 left, top, right, bottom, width, height, Bpp, compress)); 01095 01096 if (!compress) 01097 { 01098 int y; 01099 bmpdata = (uint8 *) xmalloc(width * height * Bpp); 01100 for (y = 0; y < height; y++) 01101 { 01102 in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)], 01103 width * Bpp); 01104 } 01105 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata); 01106 xfree(bmpdata); 01107 continue; 01108 } 01109 01110 01111 if (compress & 0x400) 01112 { 01113 size = bufsize; 01114 } 01115 else 01116 { 01117 in_uint8s(s, 2); /* pad */ 01118 in_uint16_le(s, size); 01119 in_uint8s(s, 4); /* line_size, final_size */ 01120 } 01121 in_uint8p(s, data, size); 01122 bmpdata = (uint8 *) xmalloc(width * height * Bpp); 01123 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp)) 01124 { 01125 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata); 01126 } 01127 else 01128 { 01129 DEBUG_RDP5(("Failed to decompress data\n")); 01130 } 01131 01132 xfree(bmpdata); 01133 } 01134 } 01135 01136 /* Process a palette update */ 01137 void 01138 process_palette(STREAM s) 01139 { 01140 COLOURENTRY *entry; 01141 COLOURMAP map; 01142 RD_HCOLOURMAP hmap; 01143 int i; 01144 01145 in_uint8s(s, 2); /* pad */ 01146 in_uint16_le(s, map.ncolours); 01147 in_uint8s(s, 2); /* pad */ 01148 01149 map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours); 01150 01151 DEBUG(("PALETTE(c=%d)\n", map.ncolours)); 01152 01153 for (i = 0; i < map.ncolours; i++) 01154 { 01155 entry = &map.colours[i]; 01156 in_uint8(s, entry->red); 01157 in_uint8(s, entry->green); 01158 in_uint8(s, entry->blue); 01159 } 01160 01161 hmap = ui_create_colourmap(&map); 01162 ui_set_colourmap(hmap); 01163 01164 xfree(map.colours); 01165 } 01166 01167 /* Process an update PDU */ 01168 static void 01169 process_update_pdu(STREAM s) 01170 { 01171 uint16 update_type, count; 01172 01173 in_uint16_le(s, update_type); 01174 01175 ui_begin_update(); 01176 switch (update_type) 01177 { 01178 case RDP_UPDATE_ORDERS: 01179 in_uint8s(s, 2); /* pad */ 01180 in_uint16_le(s, count); 01181 in_uint8s(s, 2); /* pad */ 01182 process_orders(s, count); 01183 break; 01184 01185 case RDP_UPDATE_BITMAP: 01186 process_bitmap_updates(s); 01187 break; 01188 01189 case RDP_UPDATE_PALETTE: 01190 process_palette(s); 01191 break; 01192 01193 case RDP_UPDATE_SYNCHRONIZE: 01194 break; 01195 01196 default: 01197 unimpl("update %d\n", update_type); 01198 } 01199 ui_end_update(); 01200 } 01201 01202 /* Process a disconnect PDU */ 01203 void 01204 process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason) 01205 { 01206 in_uint32_le(s, *ext_disc_reason); 01207 01208 DEBUG(("Received disconnect PDU\n")); 01209 } 01210 01211 /* Process data PDU */ 01212 static BOOL 01213 process_data_pdu(STREAM s, uint32 * ext_disc_reason) 01214 { 01215 uint8 data_pdu_type; 01216 uint8 ctype; 01217 uint16 clen; 01218 uint32 len; 01219 01220 uint32 roff, rlen; 01221 01222 struct stream *ns = &(g_mppc_dict.ns); 01223 01224 in_uint8s(s, 6); /* shareid, pad, streamid */ 01225 in_uint16(s, len); 01226 in_uint8(s, data_pdu_type); 01227 in_uint8(s, ctype); 01228 in_uint16(s, clen); 01229 clen -= 18; 01230 01231 if (ctype & RDP_MPPC_COMPRESSED) 01232 { 01233 if (len > RDP_MPPC_DICT_SIZE) 01234 error("error decompressed packet size exceeds max\n"); 01235 if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1) 01236 error("error while decompressing packet\n"); 01237 01238 /* len -= 18; */ 01239 01240 /* allocate memory and copy the uncompressed data into the temporary stream */ 01241 ns->data = (uint8 *) xrealloc(ns->data, rlen); 01242 01243 memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen); 01244 01245 ns->size = rlen; 01246 ns->end = (ns->data + ns->size); 01247 ns->p = ns->data; 01248 ns->rdp_hdr = ns->p; 01249 01250 s = ns; 01251 } 01252 01253 switch (data_pdu_type) 01254 { 01255 case RDP_DATA_PDU_UPDATE: 01256 process_update_pdu(s); 01257 break; 01258 01259 case RDP_DATA_PDU_CONTROL: 01260 DEBUG(("Received Control PDU\n")); 01261 break; 01262 01263 case RDP_DATA_PDU_SYNCHRONISE: 01264 DEBUG(("Received Sync PDU\n")); 01265 break; 01266 01267 case RDP_DATA_PDU_POINTER: 01268 process_pointer_pdu(s); 01269 break; 01270 01271 case RDP_DATA_PDU_BELL: 01272 ui_bell(); 01273 break; 01274 01275 case RDP_DATA_PDU_LOGON: 01276 DEBUG(("Received Logon PDU\n")); 01277 /* User logged on */ 01278 break; 01279 01280 case RDP_DATA_PDU_DISCONNECT: 01281 process_disconnect_pdu(s, ext_disc_reason); 01282 return True; 01283 01284 default: 01285 unimpl("data PDU %d\n", data_pdu_type); 01286 } 01287 return False; 01288 } 01289 01290 /* Process redirect PDU from Session Directory */ 01291 static BOOL 01292 process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ ) 01293 { 01294 uint32 len; 01295 01296 /* these 2 bytes are unknown, seem to be zeros */ 01297 in_uint8s(s, 2); 01298 01299 /* read connection flags */ 01300 in_uint32_le(s, g_redirect_flags); 01301 01302 /* read length of ip string */ 01303 in_uint32_le(s, len); 01304 01305 /* read ip string */ 01306 rdp_in_unistr(s, g_redirect_server, len); 01307 01308 /* read length of cookie string */ 01309 in_uint32_le(s, len); 01310 01311 /* read cookie string (plain ASCII) */ 01312 in_uint8a(s, g_redirect_cookie, len); 01313 g_redirect_cookie[len] = 0; 01314 01315 /* read length of username string */ 01316 in_uint32_le(s, len); 01317 01318 /* read username string */ 01319 rdp_in_unistr(s, g_redirect_username, len); 01320 01321 /* read length of domain string */ 01322 in_uint32_le(s, len); 01323 01324 /* read domain string */ 01325 rdp_in_unistr(s, g_redirect_domain, len); 01326 01327 /* read length of password string */ 01328 in_uint32_le(s, len); 01329 01330 /* read password string */ 01331 rdp_in_unistr(s, g_redirect_password, len); 01332 01333 g_redirect = True; 01334 01335 return True; 01336 } 01337 01338 /* Process incoming packets */ 01339 /* nevers gets out of here till app is done */ 01340 void 01341 rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason) 01342 { 01343 while (rdp_loop(deactivated, ext_disc_reason)) 01344 ; 01345 } 01346 01347 /* used in uiports and rdp_main_loop, processes the rdp packets waiting */ 01348 BOOL 01349 rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason) 01350 { 01351 uint8 type; 01352 BOOL disc = False; /* True when a disconnect PDU was received */ 01353 BOOL cont = True; 01354 STREAM s; 01355 01356 while (cont) 01357 { 01358 s = rdp_recv(&type); 01359 if (s == NULL) 01360 return False; 01361 switch (type) 01362 { 01363 case RDP_PDU_DEMAND_ACTIVE: 01364 process_demand_active(s); 01365 *deactivated = False; 01366 break; 01367 case RDP_PDU_DEACTIVATE: 01368 DEBUG(("RDP_PDU_DEACTIVATE\n")); 01369 *deactivated = True; 01370 break; 01371 case RDP_PDU_REDIRECT: 01372 return process_redirect_pdu(s); 01373 break; 01374 case RDP_PDU_DATA: 01375 disc = process_data_pdu(s, ext_disc_reason); 01376 break; 01377 case 0: 01378 break; 01379 default: 01380 unimpl("PDU %d\n", type); 01381 } 01382 if (disc) 01383 return False; 01384 cont = g_next_packet < s->end; 01385 } 01386 return True; 01387 } 01388 01389 /* Establish a connection up to the RDP layer */ 01390 BOOL 01391 rdp_connect(char *server, uint32 flags, char *domain, char *password, 01392 char *command, char *directory) 01393 { 01394 if (!sec_connect(server, g_username)) 01395 return False; 01396 01397 rdp_send_logon_info(flags, domain, g_username, password, command, directory); 01398 return True; 01399 } 01400 01401 /* Establish a reconnection up to the RDP layer */ 01402 BOOL 01403 rdp_reconnect(char *server, uint32 flags, char *domain, char *password, 01404 char *command, char *directory, char *cookie) 01405 { 01406 if (!sec_reconnect(server)) 01407 return False; 01408 01409 rdp_send_logon_info(flags, domain, g_username, password, command, directory); 01410 return True; 01411 } 01412 01413 /* Called during redirection to reset the state to support redirection */ 01414 void 01415 rdp_reset_state(void) 01416 { 01417 g_next_packet = NULL; /* reset the packet information */ 01418 g_rdp_shareid = 0; 01419 sec_reset_state(); 01420 } 01421 01422 /* Disconnect from the RDP layer */ 01423 void 01424 rdp_disconnect(void) 01425 { 01426 sec_disconnect(); 01427 } Generated on Sun May 27 2012 04:17:11 for ReactOS by
1.7.6.1
|