From 374b8aeba0fbd2861233286bed4a6f11bfd5691b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C3=85strand?= Date: Tue, 20 Apr 2004 07:01:21 +0000 Subject: [PATCH] Applied disconnect handling patch from Jeroen Meijer git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@675 423420c4-83ab-492f-b58f-81f9feb106b5 --- constants.h | 22 +++++++++ proto.h | 2 +- rdesktop.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++-- rdp.c | 54 ++++++++++++++-------- 4 files changed, 180 insertions(+), 26 deletions(-) diff --git a/constants.h b/constants.h index e75a052..709fb6d 100644 --- a/constants.h +++ b/constants.h @@ -356,3 +356,25 @@ enum RDP_INPUT_DEVICE #define FILE_DIRECTORY_FILE 0x00000001 #define FILE_NON_DIRECTORY_FILE 0x00000040 #define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 + +/* RDP5 disconnect PDU */ +#define exDiscReasonNoInfo 0x0000 +#define exDiscReasonAPIInitiatedDisconnect 0x0001 +#define exDiscReasonAPIInitiatedLogoff 0x0002 +#define exDiscReasonServerIdleTimeout 0x0003 +#define exDiscReasonServerLogonTimeout 0x0004 +#define exDiscReasonReplacedByOtherConnection 0x0005 +#define exDiscReasonOutOfMemory 0x0006 +#define exDiscReasonServerDeniedConnection 0x0007 +#define exDiscReasonServerDeniedConnectionFips 0x0008 +#define exDiscReasonLicenseInternal 0x0100 +#define exDiscReasonLicenseNoLicenseServer 0x0101 +#define exDiscReasonLicenseNoLicense 0x0102 +#define exDiscReasonLicenseErrClientMsg 0x0103 +#define exDiscReasonLicenseHwidDoesntMatchLicense 0x0104 +#define exDiscReasonLicenseErrClientLicense 0x0105 +#define exDiscReasonLicenseCantFinishProtocol 0x0106 +#define exDiscReasonLicenseClientEndedProtocol 0x0107 +#define exDiscReasonLicenseErrClientEncryption 0x0108 +#define exDiscReasonLicenseCantUpgradeLicense 0x0109 +#define exDiscReasonLicenseNoRemoteConnections 0x010a diff --git a/proto.h b/proto.h index a9735ad..9c0bb61 100644 --- a/proto.h +++ b/proto.h @@ -85,7 +85,7 @@ void process_cached_pointer_pdu(STREAM s); void process_system_pointer_pdu(STREAM s); void process_bitmap_updates(STREAM s); void process_palette(STREAM s); -BOOL rdp_main_loop(void); +void rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason); BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command, char *directory); void rdp_disconnect(void); diff --git a/rdesktop.c b/rdesktop.c index 0f3133b..329837b 100644 --- a/rdesktop.c +++ b/rdesktop.c @@ -148,6 +148,106 @@ usage(char *program) fprintf(stderr, " -5: use RDP version 5 (default)\n"); } +void +print_disconnect_reason(uint16 reason) +{ + char *text; + + switch (reason) + { + case exDiscReasonNoInfo: + text = "No information available"; + break; + + case exDiscReasonAPIInitiatedDisconnect: + text = "Server initiated disconnect"; + break; + + case exDiscReasonAPIInitiatedLogoff: + text = "Server initiated logoff"; + break; + + case exDiscReasonServerIdleTimeout: + text = "Server idle timeout reached"; + break; + + case exDiscReasonServerLogonTimeout: + text = "Server logon timeout reached"; + break; + + case exDiscReasonReplacedByOtherConnection: + text = "The session was replaced"; + break; + + case exDiscReasonOutOfMemory: + text = "The server is out of memory"; + break; + + case exDiscReasonServerDeniedConnection: + text = "The server denied the connection"; + break; + + case exDiscReasonServerDeniedConnectionFips: + text = "The server denied the connection for security reason"; + break; + + case exDiscReasonLicenseInternal: + text = "Internal licensing error"; + break; + + case exDiscReasonLicenseNoLicenseServer: + text = "No license server available"; + break; + + case exDiscReasonLicenseNoLicense: + text = "No valid license available"; + break; + + case exDiscReasonLicenseErrClientMsg: + text = "Invalid licensing message"; + break; + + case exDiscReasonLicenseHwidDoesntMatchLicense: + text = "Hardware id doesn't match software license"; + break; + + case exDiscReasonLicenseErrClientLicense: + text = "Client license error"; + break; + + case exDiscReasonLicenseCantFinishProtocol: + text = "Network error during licensing protocol"; + break; + + case exDiscReasonLicenseClientEndedProtocol: + text = "Licensing protocol was not completed"; + break; + + case exDiscReasonLicenseErrClientEncryption: + text = "Incorrect client license enryption"; + break; + + case exDiscReasonLicenseCantUpgradeLicense: + text = "Can't upgrade license"; + break; + + case exDiscReasonLicenseNoRemoteConnections: + text = "The server is not licensed to accept remote connections"; + break; + + default: + if (reason > 0x1000 && reason < 0x7fff) + { + text = "Internal protocol error"; + } + else + { + text = "Unknown reason"; + } + } + fprintf(stderr, "disconnect: %s.\n", text); +} + static BOOL read_password(char *password, int size) { @@ -242,9 +342,9 @@ main(int argc, char *argv[]) char password[64]; char shell[128]; char directory[32]; - BOOL prompt_password, rdp_retval = False; + BOOL prompt_password, deactivated; struct passwd *pw; - uint32 flags; + uint32 flags, ext_disc_reason = 0; char *p; int c; @@ -604,7 +704,7 @@ main(int argc, char *argv[]) if (ui_create_window()) { - rdp_retval = rdp_main_loop(); + rdp_main_loop(&deactivated, &ext_disc_reason); ui_destroy_window(); } @@ -612,10 +712,28 @@ main(int argc, char *argv[]) rdp_disconnect(); ui_deinit(); - if (True == rdp_retval) + if (ext_disc_reason >= 2) + print_disconnect_reason(ext_disc_reason); + + if (deactivated) + { + /* clean disconnect */ return 0; + } else - return 2; + { + if (ext_disc_reason == exDiscReasonAPIInitiatedDisconnect + || ext_disc_reason == exDiscReasonAPIInitiatedLogoff) + { + /* not so clean disconnect, but nothing to worry about */ + return 0; + } + else + { + /* return error */ + return 2; + } + } #endif diff --git a/rdp.c b/rdp.c index 70e6f04..488de50 100644 --- a/rdp.c +++ b/rdp.c @@ -886,9 +886,18 @@ process_update_pdu(STREAM s) } +/* Process a disconnect PDU */ +void +process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason) +{ + in_uint32_le(s, *ext_disc_reason); + + DEBUG(("Received disconnect PDU\n")); +} + /* Process data PDU */ -static void -process_data_pdu(STREAM s) +static BOOL +process_data_pdu(STREAM s, uint32 * ext_disc_reason) { uint8 data_pdu_type; uint8 ctype; @@ -939,6 +948,14 @@ process_data_pdu(STREAM s) process_update_pdu(s); break; + case RDP_DATA_PDU_CONTROL: + DEBUG(("Received Control PDU\n")); + break; + + case RDP_DATA_PDU_SYNCHRONISE: + DEBUG(("Received Sync PDU\n")); + break; + case RDP_DATA_PDU_POINTER: process_pointer_pdu(s); break; @@ -953,21 +970,21 @@ process_data_pdu(STREAM s) break; case RDP_DATA_PDU_DISCONNECT: - /* Normally received when user logs out or disconnects from a - console session on Windows XP and 2003 Server */ - DEBUG(("Received disconnect PDU\n")); - break; + process_disconnect_pdu(s, ext_disc_reason); + return True; default: unimpl("data PDU %d\n", data_pdu_type); } + return False; } /* Process incoming packets */ -BOOL -rdp_main_loop(void) +void +rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason) { uint8 type; + BOOL disc = False; /* True when a disconnect PDU was received */ STREAM s; while ((s = rdp_recv(&type)) != NULL) @@ -976,20 +993,15 @@ rdp_main_loop(void) { case RDP_PDU_DEMAND_ACTIVE: process_demand_active(s); + *deactivated = False; break; case RDP_PDU_DEACTIVATE: - DEBUG(("RDP_PDU_DEACTIVATE\n")); - /* 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; */ + *deactivated = True; break; case RDP_PDU_DATA: - process_data_pdu(s); + disc = process_data_pdu(s, ext_disc_reason); break; case 0: @@ -998,11 +1010,13 @@ rdp_main_loop(void) default: unimpl("PDU %d\n", type); } + + if (disc) + { + return; + } } - return True; - /* We want to detect if we got a clean shutdown, but we - can't. Se above. - return False; */ + return; } /* Establish a connection up to the RDP layer */