409 |
out_uint16_le(s, RDP_CAPSET_BITMAP); |
out_uint16_le(s, RDP_CAPSET_BITMAP); |
410 |
out_uint16_le(s, RDP_CAPLEN_BITMAP); |
out_uint16_le(s, RDP_CAPLEN_BITMAP); |
411 |
|
|
412 |
out_uint16_le(s, 8); /* Preferred BPP */ |
out_uint16_le(s, g_server_bpp); /* Preferred BPP */ |
413 |
out_uint16_le(s, 1); /* Receive 1 BPP */ |
out_uint16_le(s, 1); /* Receive 1 BPP */ |
414 |
out_uint16_le(s, 1); /* Receive 4 BPP */ |
out_uint16_le(s, 1); /* Receive 4 BPP */ |
415 |
out_uint16_le(s, 1); /* Receive 8 BPP */ |
out_uint16_le(s, 1); /* Receive 8 BPP */ |
618 |
process_demand_active(STREAM s) |
process_demand_active(STREAM s) |
619 |
{ |
{ |
620 |
uint8 type; |
uint8 type; |
621 |
|
uint16 i; |
622 |
|
uint16 p_bpp; |
623 |
|
|
624 |
in_uint32_le(s, g_rdp_shareid); |
in_uint32_le(s, g_rdp_shareid); |
625 |
|
|
626 |
|
/* scan for prefered bpp */ |
627 |
|
while (s_check_rem(s, 6)) |
628 |
|
{ |
629 |
|
in_uint16_le(s, i); |
630 |
|
if (i == RDP_CAPSET_BITMAP) |
631 |
|
{ |
632 |
|
in_uint16_le(s, i); |
633 |
|
if (i == RDP_CAPLEN_BITMAP) |
634 |
|
{ |
635 |
|
in_uint16_le(s, p_bpp); |
636 |
|
if (p_bpp == 8 || p_bpp == 15 || p_bpp == 16 || p_bpp == 24) |
637 |
|
{ |
638 |
|
if (p_bpp < g_server_bpp) |
639 |
|
{ |
640 |
|
warning("Server limited colour depth to %d bits\n", |
641 |
|
p_bpp); |
642 |
|
g_server_bpp = p_bpp; |
643 |
|
} |
644 |
|
break; |
645 |
|
} |
646 |
|
} |
647 |
|
} |
648 |
|
} |
649 |
|
|
650 |
|
|
651 |
DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid)); |
DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid)); |
652 |
|
|
653 |
rdp_send_confirm_active(); |
rdp_send_confirm_active(); |
781 |
DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n", |
DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n", |
782 |
left, top, right, bottom, width, height, Bpp, compress)); |
left, top, right, bottom, width, height, Bpp, compress)); |
783 |
|
|
|
/* Server may limit bpp - this is how we find out */ |
|
|
if (g_server_bpp != bpp) |
|
|
{ |
|
|
warning("Server limited colour depth to %d bits\n", bpp); |
|
|
g_server_bpp = bpp; |
|
|
} |
|
|
|
|
784 |
if (!compress) |
if (!compress) |
785 |
{ |
{ |
786 |
int y; |
int y; |
886 |
|
|
887 |
} |
} |
888 |
|
|
889 |
|
/* Process a disconnect PDU */ |
890 |
|
void |
891 |
|
process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason) |
892 |
|
{ |
893 |
|
in_uint32_le(s, *ext_disc_reason); |
894 |
|
|
895 |
|
DEBUG(("Received disconnect PDU\n")); |
896 |
|
} |
897 |
|
|
898 |
/* Process data PDU */ |
/* Process data PDU */ |
899 |
static void |
static BOOL |
900 |
process_data_pdu(STREAM s) |
process_data_pdu(STREAM s, uint32 * ext_disc_reason) |
901 |
{ |
{ |
902 |
uint8 data_pdu_type; |
uint8 data_pdu_type; |
903 |
uint8 ctype; |
uint8 ctype; |
904 |
uint16 clen; |
uint16 clen; |
905 |
int roff, rlen, len, ret; |
int len; |
906 |
|
#if 0 |
907 |
|
int roff, rlen, ret; |
908 |
static struct stream ns; |
static struct stream ns; |
909 |
static signed char *dict = 0; |
static signed char *dict = 0; |
910 |
|
#endif |
911 |
|
|
912 |
in_uint8s(s, 6); /* shareid, pad, streamid */ |
in_uint8s(s, 6); /* shareid, pad, streamid */ |
913 |
in_uint16(s, len); |
in_uint16(s, len); |
948 |
process_update_pdu(s); |
process_update_pdu(s); |
949 |
break; |
break; |
950 |
|
|
951 |
|
case RDP_DATA_PDU_CONTROL: |
952 |
|
DEBUG(("Received Control PDU\n")); |
953 |
|
break; |
954 |
|
|
955 |
|
case RDP_DATA_PDU_SYNCHRONISE: |
956 |
|
DEBUG(("Received Sync PDU\n")); |
957 |
|
break; |
958 |
|
|
959 |
case RDP_DATA_PDU_POINTER: |
case RDP_DATA_PDU_POINTER: |
960 |
process_pointer_pdu(s); |
process_pointer_pdu(s); |
961 |
break; |
break; |
970 |
break; |
break; |
971 |
|
|
972 |
case RDP_DATA_PDU_DISCONNECT: |
case RDP_DATA_PDU_DISCONNECT: |
973 |
/* Normally received when user logs out or disconnects from a |
process_disconnect_pdu(s, ext_disc_reason); |
974 |
console session on Windows XP and 2003 Server */ |
return True; |
|
DEBUG(("Received disconnect PDU\n")); |
|
|
break; |
|
975 |
|
|
976 |
default: |
default: |
977 |
unimpl("data PDU %d\n", data_pdu_type); |
unimpl("data PDU %d\n", data_pdu_type); |
978 |
} |
} |
979 |
|
return False; |
980 |
} |
} |
981 |
|
|
982 |
/* Process incoming packets */ |
/* Process incoming packets */ |
983 |
BOOL |
void |
984 |
rdp_main_loop(void) |
rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason) |
985 |
{ |
{ |
986 |
uint8 type; |
uint8 type; |
987 |
|
BOOL disc = False; /* True when a disconnect PDU was received */ |
988 |
STREAM s; |
STREAM s; |
989 |
|
|
990 |
while ((s = rdp_recv(&type)) != NULL) |
while ((s = rdp_recv(&type)) != NULL) |
993 |
{ |
{ |
994 |
case RDP_PDU_DEMAND_ACTIVE: |
case RDP_PDU_DEMAND_ACTIVE: |
995 |
process_demand_active(s); |
process_demand_active(s); |
996 |
|
*deactivated = False; |
997 |
break; |
break; |
998 |
|
|
999 |
case RDP_PDU_DEACTIVATE: |
case RDP_PDU_DEACTIVATE: |
1000 |
DEBUG(("RDP_PDU_DEACTIVATE\n")); |
*deactivated = True; |
|
/* We thought we could detect a clean |
|
|
shutdown of the session by this |
|
|
packet, but it seems Windows 2003 |
|
|
is sending us one of these when we |
|
|
reconnect to a disconnected session |
|
|
return True; */ |
|
1001 |
break; |
break; |
1002 |
|
|
1003 |
case RDP_PDU_DATA: |
case RDP_PDU_DATA: |
1004 |
process_data_pdu(s); |
disc = process_data_pdu(s, ext_disc_reason); |
1005 |
break; |
break; |
1006 |
|
|
1007 |
case 0: |
case 0: |
1010 |
default: |
default: |
1011 |
unimpl("PDU %d\n", type); |
unimpl("PDU %d\n", type); |
1012 |
} |
} |
1013 |
|
|
1014 |
|
if (disc) |
1015 |
|
{ |
1016 |
|
return; |
1017 |
|
} |
1018 |
} |
} |
1019 |
return True; |
return; |
|
/* We want to detect if we got a clean shutdown, but we |
|
|
can't. Se above. |
|
|
return False; */ |
|
1020 |
} |
} |
1021 |
|
|
1022 |
/* Establish a connection up to the RDP layer */ |
/* Establish a connection up to the RDP layer */ |