From 56dc61cc068f2e2998cb815603ee508c1779b803 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 19 Mar 2015 11:05:16 +0100 Subject: [PATCH] Added error name and string functions. Added new functions allowing to get a string representation of an error code and a description of the error for connect and base error classes. --- include/freerdp/error.h | 81 +++++++++++++++---- include/freerdp/freerdp.h | 2 + libfreerdp/core/CMakeLists.txt | 2 + libfreerdp/core/errbase.c | 88 +++++++++++++++++++++ libfreerdp/core/errconnect.c | 138 +++++++++++++++++++++++++++++++++ libfreerdp/core/errinfo.c | 2 + libfreerdp/core/errinfo.h | 2 - libfreerdp/core/freerdp.c | 53 ++++++++++++- 8 files changed, 352 insertions(+), 16 deletions(-) create mode 100644 libfreerdp/core/errbase.c create mode 100644 libfreerdp/core/errconnect.c diff --git a/include/freerdp/error.h b/include/freerdp/error.h index 248b38e19..765b7a57e 100644 --- a/include/freerdp/error.h +++ b/include/freerdp/error.h @@ -194,6 +194,17 @@ FREERDP_API extern int connectErrorCode; #define FREERDP_ERROR_BASE 0 +/** + * Error Base Codes + */ +#define FREERDP_ERROR_ERRBASE_CLASS (FREERDP_ERROR_BASE + 0) + +#define ERRBASE_SUCCESS ERRINFO_SUCCESS +#define ERRBASE_NONE ERRINFO_NONE + +FREERDP_API const char* freerdp_get_error_base_string(UINT32 code); +FREERDP_API const char* freerdp_get_error_base_name(UINT32 code); + #define FREERDP_ERROR_SUCCESS ERRINFO_SUCCESS #define FREERDP_ERROR_NONE ERRINFO_NONE @@ -214,22 +225,66 @@ FREERDP_API extern int connectErrorCode; #define FREERDP_ERROR_LOGOFF_BY_USER MAKE_FREERDP_ERROR(ERRINFO, ERRINFO_LOGOFF_BY_USER) /* Connection Error Codes */ +#define ERRCONNECT_PRE_CONNECT_FAILED 0x00000001 +#define ERRCONNECT_CONNECT_UNDEFINED 0x00000002 +#define ERRCONNECT_POST_CONNECT_FAILED 0x00000003 +#define ERRCONNECT_DNS_ERROR 0x00000004 +#define ERRCONNECT_DNS_NAME_NOT_FOUND 0x00000005 +#define ERRCONNECT_CONNECT_FAILED 0x00000006 +#define ERRCONNECT_MCS_CONNECT_INITIAL_ERROR 0x00000007 +#define ERRCONNECT_TLS_CONNECT_FAILED 0x00000008 +#define ERRCONNECT_AUTHENTICATION_FAILED 0x00000009 +#define ERRCONNECT_INSUFFICIENT_PRIVILEGES 0x0000000A +#define ERRCONNECT_CONNECT_CANCELLED 0x0000000B +#define ERRCONNECT_SECURITY_NEGO_CONNECT_FAILED 0x0000000C +#define ERRCONNECT_CONNECT_TRANSPORT_FAILED 0x0000000D + +#define ERRCONNECT_SUCCESS ERRINFO_SUCCESS +#define ERRCONNECT_NONE ERRINFO_NONE + +FREERDP_API const char* freerdp_get_error_connect_string(UINT32 code); +FREERDP_API const char* freerdp_get_error_connect_name(UINT32 code); #define FREERDP_ERROR_CONNECT_CLASS (FREERDP_ERROR_BASE + 2) -#define FREERDP_ERROR_PRE_CONNECT_FAILED MAKE_FREERDP_ERROR(CONNECT, 1) -#define FREERDP_ERROR_CONNECT_UNDEFINED MAKE_FREERDP_ERROR(CONNECT, 2) -#define FREERDP_ERROR_POST_CONNECT_FAILED MAKE_FREERDP_ERROR(CONNECT, 3) -#define FREERDP_ERROR_DNS_ERROR MAKE_FREERDP_ERROR(CONNECT, 4) -#define FREERDP_ERROR_DNS_NAME_NOT_FOUND MAKE_FREERDP_ERROR(CONNECT, 5) -#define FREERDP_ERROR_CONNECT_FAILED MAKE_FREERDP_ERROR(CONNECT, 6) -#define FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR MAKE_FREERDP_ERROR(CONNECT, 7) -#define FREERDP_ERROR_TLS_CONNECT_FAILED MAKE_FREERDP_ERROR(CONNECT, 8) -#define FREERDP_ERROR_AUTHENTICATION_FAILED MAKE_FREERDP_ERROR(CONNECT, 9) -#define FREERDP_ERROR_INSUFFICIENT_PRIVILEGES MAKE_FREERDP_ERROR(CONNECT, 10) -#define FREERDP_ERROR_CONNECT_CANCELLED MAKE_FREERDP_ERROR(CONNECT, 11) -#define FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED MAKE_FREERDP_ERROR(CONNECT, 12) -#define FREERDP_ERROR_CONNECT_TRANSPORT_FAILED MAKE_FREERDP_ERROR(CONNECT, 13) +#define FREERDP_ERROR_PRE_CONNECT_FAILED \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_PRE_CONNECT_FAILED) + +#define FREERDP_ERROR_CONNECT_UNDEFINED \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CONNECT_UNDEFINED) + +#define FREERDP_ERROR_POST_CONNECT_FAILED \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_POST_CONNECT_FAILED) + +#define FREERDP_ERROR_DNS_ERROR \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_DNS_ERROR) + +#define FREERDP_ERROR_DNS_NAME_NOT_FOUND \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_DNS_NAME_NOT_FOUND) + +#define FREERDP_ERROR_CONNECT_FAILED \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CONNECT_FAILED) + +#define FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_MCS_CONNECT_INITIAL_ERROR) + +#define FREERDP_ERROR_TLS_CONNECT_FAILED \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_TLS_CONNECT_FAILED) + +#define FREERDP_ERROR_AUTHENTICATION_FAILED \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_AUTHENTICATION_FAILED) + +#define FREERDP_ERROR_INSUFFICIENT_PRIVILEGES \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_INSUFFICIENT_PRIVILEGES) + +#define FREERDP_ERROR_CONNECT_CANCELLED \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CONNECT_CANCELLED) + +#define FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_SECURITY_NEGO_CONNECT_FAILED) + +#define FREERDP_ERROR_CONNECT_TRANSPORT_FAILED \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CONNECT_TRANSPORT_FAILED) #ifdef __cplusplus } diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index 180009220..3f9359fc1 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -268,6 +268,8 @@ FREERDP_API BOOL freerdp_focus_required(freerdp* instance); FREERDP_API void freerdp_set_focus(freerdp* instance); FREERDP_API UINT32 freerdp_get_last_error(rdpContext* context); +FREERDP_API const char* freerdp_get_last_error_name(UINT32 error); +FREERDP_API const char* freerdp_get_last_error_string(UINT32 error); FREERDP_API void freerdp_set_last_error(rdpContext* context, UINT32 lastError); #ifdef __cplusplus diff --git a/libfreerdp/core/CMakeLists.txt b/libfreerdp/core/CMakeLists.txt index 0f020304a..1a559d7de 100644 --- a/libfreerdp/core/CMakeLists.txt +++ b/libfreerdp/core/CMakeLists.txt @@ -67,6 +67,8 @@ set(${MODULE_PREFIX}_SRCS license.c license.h errinfo.c + errbase.c + errconnect.c errinfo.h security.c security.h diff --git a/libfreerdp/core/errbase.c b/libfreerdp/core/errbase.c new file mode 100644 index 000000000..d47d49968 --- /dev/null +++ b/libfreerdp/core/errbase.c @@ -0,0 +1,88 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Error Base + * + * Copyright 2015 Armin Novak + * Copyright 2015 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "errinfo.h" + +#define TAG FREERDP_TAG("core") + +#define ERRBASE_DEFINE(_code) { ERRBASE_##_code , "ERRBASE_" #_code , ERRBASE_##_code##_STRING } + +/* Protocol-independent codes */ + +#define ERRBASE_POSTCONNECTERROR_STRING \ + + +/* Special codes */ +#define ERRBASE_SUCCESS_STRING "Success." +#define ERRBASE_NONE_STRING "" + +static const ERRINFO ERRBASE_CODES[] = +{ + ERRBASE_DEFINE(SUCCESS), + + ERRBASE_DEFINE(NONE) +}; + +const char* freerdp_get_error_base_string(UINT32 code) +{ + const ERRINFO* errInfo; + + errInfo = &ERRBASE_CODES[0]; + + while (errInfo->code != ERRBASE_NONE) + { + if (code == errInfo->code) + { + return errInfo->info; + } + + errInfo++; + } + + return "ERRBASE_UNKNOWN"; +} + +const char* freerdp_get_error_base_name(UINT32 code) +{ + const ERRINFO* errInfo; + + errInfo = &ERRBASE_CODES[0]; + + while (errInfo->code != ERRBASE_NONE) + { + if (code == errInfo->code) + { + return errInfo->name; + } + + errInfo++; + } + + return "ERRBASE_UNKNOWN"; +} + diff --git a/libfreerdp/core/errconnect.c b/libfreerdp/core/errconnect.c new file mode 100644 index 000000000..a52912b08 --- /dev/null +++ b/libfreerdp/core/errconnect.c @@ -0,0 +1,138 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Error Connect + * + * Copyright 2015 Armin Novak + * Copyright 2015 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "errinfo.h" + +#define TAG FREERDP_TAG("core") + +#define ERRCONNECT_DEFINE(_code) { ERRCONNECT_##_code , "ERRCONNECT_" #_code , ERRCONNECT_##_code##_STRING } + +/* Protocol-independent codes */ + +#define ERRCONNECT_PRE_CONNECT_FAILED_STRING \ + "A configuration error prevented a connection to be established." + +#define ERRCONNECT_CONNECT_UNDEFINED_STRING \ + "A undefined connection error occured." + +#define ERRCONNECT_POST_CONNECT_FAILED_STRING \ + "The connection attempt was aborted due to post connect configuration errors." + +#define ERRCONNECT_DNS_ERROR_STRING \ + "The DNS entry could not be resolved." + +#define ERRCONNECT_DNS_NAME_NOT_FOUND_STRING \ + "The DNS host name was not found." + +#define ERRCONNECT_CONNECT_FAILED_STRING \ + "The connection failed." + +#define ERRCONNECT_MCS_CONNECT_INITIAL_ERROR_STRING \ + "The connection failed at initial MCS connect" + +#define ERRCONNECT_TLS_CONNECT_FAILED_STRING \ + "The connection failed at TLS connect." + +#define ERRCONNECT_AUTHENTICATION_FAILED_STRING \ + "An authentication failure aborted the connection." + +#define ERRCONNECT_INSUFFICIENT_PRIVILEGES_STRING \ + "Insufficient privileges to establish a connection." + +#define ERRCONNECT_CONNECT_CANCELLED_STRING \ + "The connection was cancelled." + +#define ERRCONNECT_SECURITY_NEGO_CONNECT_FAILED_STRING \ + "The connection failed at negociating security settings." + +#define ERRCONNECT_CONNECT_TRANSPORT_FAILED_STRING \ + "The connection transport layer failed." + +/* Special codes */ +#define ERRCONNECT_SUCCESS_STRING "Success." +#define ERRCONNECT_NONE_STRING "" + +static const ERRINFO ERRCONNECT_CODES[] = +{ + ERRCONNECT_DEFINE(SUCCESS), + + ERRCONNECT_DEFINE(PRE_CONNECT_FAILED), + ERRCONNECT_DEFINE(CONNECT_UNDEFINED), + ERRCONNECT_DEFINE(POST_CONNECT_FAILED), + ERRCONNECT_DEFINE(DNS_ERROR), + ERRCONNECT_DEFINE(DNS_NAME_NOT_FOUND), + ERRCONNECT_DEFINE(CONNECT_FAILED), + ERRCONNECT_DEFINE(MCS_CONNECT_INITIAL_ERROR), + ERRCONNECT_DEFINE(TLS_CONNECT_FAILED), + ERRCONNECT_DEFINE(AUTHENTICATION_FAILED), + ERRCONNECT_DEFINE(INSUFFICIENT_PRIVILEGES), + ERRCONNECT_DEFINE(CONNECT_CANCELLED), + ERRCONNECT_DEFINE(SECURITY_NEGO_CONNECT_FAILED), + ERRCONNECT_DEFINE(CONNECT_TRANSPORT_FAILED), + + ERRCONNECT_DEFINE(NONE) +}; + +const char* freerdp_get_error_connect_string(UINT32 code) +{ + const ERRINFO* errInfo; + + errInfo = &ERRCONNECT_CODES[0]; + + while (errInfo->code != ERRCONNECT_NONE) + { + if (code == errInfo->code) + { + return errInfo->info; + } + + errInfo++; + } + + return "ERRCONNECT_UNKNOWN"; +} + +const char* freerdp_get_error_connect_name(UINT32 code) +{ + const ERRINFO* errInfo; + + errInfo = &ERRCONNECT_CODES[0]; + + while (errInfo->code != ERRCONNECT_NONE) + { + if (code == errInfo->code) + { + return errInfo->name; + } + + errInfo++; + } + + return "ERRCONNECT_UNKNOWN"; +} + diff --git a/libfreerdp/core/errinfo.c b/libfreerdp/core/errinfo.c index 0411ed067..5820163e3 100644 --- a/libfreerdp/core/errinfo.c +++ b/libfreerdp/core/errinfo.c @@ -29,6 +29,8 @@ #define TAG FREERDP_TAG("core") +#define ERRINFO_DEFINE(_code) { ERRINFO_##_code , "ERRINFO_" #_code , ERRINFO_##_code##_STRING } + int connectErrorCode; /* Protocol-independent codes */ diff --git a/libfreerdp/core/errinfo.h b/libfreerdp/core/errinfo.h index 54c1ee7d6..14d8c3f27 100644 --- a/libfreerdp/core/errinfo.h +++ b/libfreerdp/core/errinfo.h @@ -30,8 +30,6 @@ struct _ERRINFO }; typedef struct _ERRINFO ERRINFO; -#define ERRINFO_DEFINE(_code) { ERRINFO_##_code , "ERRINFO_" #_code , ERRINFO_##_code##_STRING } - void rdp_print_errinfo(UINT32 code); #endif diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index fc955efc8..ac06c70a8 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -511,10 +511,61 @@ UINT32 freerdp_get_last_error(rdpContext* context) return context->LastError; } +const char* freerdp_get_last_error_name(UINT32 code) +{ + const char *name = NULL; + const UINT32 cls = GET_FREERDP_ERROR_CLASS(code); + const UINT32 type = GET_FREERDP_ERROR_TYPE(code); + + switch(cls) + { + case FREERDP_ERROR_ERRBASE_CLASS: + name = freerdp_get_error_base_name(type); + break; + case FREERDP_ERROR_ERRINFO_CLASS: + name = freerdp_get_error_info_name(type); + break; + case FREERDP_ERROR_CONNECT_CLASS: + name = freerdp_get_error_connect_name(type); + break; + default: + name = "Unknown error class"; + break; + } + + return name; +} + +const char* freerdp_get_last_error_string(UINT32 code) +{ + const char* string = NULL; + const UINT32 cls = GET_FREERDP_ERROR_CLASS(code); + const UINT32 type = GET_FREERDP_ERROR_TYPE(code); + + switch(cls) + { + case FREERDP_ERROR_ERRBASE_CLASS: + string = freerdp_get_error_base_string(type); + break; + case FREERDP_ERROR_ERRINFO_CLASS: + string = freerdp_get_error_info_string(type); + break; + case FREERDP_ERROR_CONNECT_CLASS: + string = freerdp_get_error_connect_string(type); + break; + default: + string = "Unknown error class"; + break; + } + + return string; +} + void freerdp_set_last_error(rdpContext* context, UINT32 lastError) { if (lastError) - WLog_ERR(TAG, "freerdp_set_last_error 0x%04X", lastError); + WLog_ERR(TAG, "freerdp_set_last_error %s [0x%04X]", lastError, + freerdp_get_last_error_name(lastError)); context->LastError = lastError;