From: Guy Harris Date: Wed, 9 Jan 2019 04:40:50 +0000 (-0800) Subject: Put pcap_win32_err_to_str() into fmtutils.c, and use it for all Win32 errors. X-Git-Tag: libpcap-1.10-bp~646 X-Git-Url: https://git.tcpdump.org/libpcap/commitdiff_plain/0dd92d7d9944b158511e27795ff6952c17fd3497 Put pcap_win32_err_to_str() into fmtutils.c, and use it for all Win32 errors. We don't need N different places all doing their own calls to FormatMessage(); centralize it in pcap_win32_err_to_str(), now in fmtutils.c for use in rpcapd as well as libpcap. Merge in some fixes from the code in sock_fmterror(). --- diff --git a/fmtutils.c b/fmtutils.c index f1a89073..0c527453 100644 --- a/fmtutils.c +++ b/fmtutils.c @@ -129,3 +129,59 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum, pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum)); #endif } + +#ifdef _WIN32 +/* + * Generate a string for a Win32-specific error (i.e. an error generated when + * calling a Win32 API). + * For errors occurred during standard C calls, we still use pcap_strerror(). + */ +void +pcap_win32_err_to_str(DWORD error, char *errbuf) +{ + DWORD retval; + size_t errlen; + char *p; + + /* + * XXX - what language ID to use? + * + * For UN*Xes, pcap_strerror() may or may not return localized + * strings. + * + * We currently don't have localized messages for libpcap, but + * we might want to do so. On the other hand, if most of these + * messages are going to be read by libpcap developers and + * perhaps by developers of libpcap-based applications, English + * might be a better choice, so the developer doesn't have to + * get the message translated if it's in a language they don't + * happen to understand. + */ + retval = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_MAX_WIDTH_MASK, + NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + errbuf, PCAP_ERRBUF_SIZE, NULL); + if (retval == 0) { + /* + * Failed. + */ + pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + "Couldn't get error message for error (%lu)", error); + return; + } + + /* + * "FormatMessage()" "helpfully" sticks CR/LF at the end of the + * message. Get rid of it. + * + * XXX - still true with FORMAT_MESSAGE_MAX_WIDTH_MASK? + */ + errlen = strlen(errbuf); + if (errlen >= 2 && + errbuf[errlen - 2] == '\r' && errbuf[errlen - 1] == '\n') { + errbuf[errlen - 2] = '\0'; + errbuf[errlen - 1] = '\0'; + } + p = strchr(errbuf, '\0'); + pcap_snprintf(p, PCAP_ERRBUF_SIZE+1-(p-errbuf), " (%lu)", error); +} +#endif diff --git a/fmtutils.h b/fmtutils.h index 62c78fdb..d4a171d8 100644 --- a/fmtutils.h +++ b/fmtutils.h @@ -43,6 +43,10 @@ extern "C" { void pcap_fmt_errmsg_for_errno(char *, size_t, int, PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5); +#ifdef _WIN32 +void pcap_win32_err_to_str(DWORD, char *); +#endif + #ifdef __cplusplus } #endif diff --git a/pcap-int.h b/pcap-int.h index ec643eba..d18dd192 100644 --- a/pcap-int.h +++ b/pcap-int.h @@ -521,10 +521,6 @@ int pcap_validate_filter(const struct bpf_insn *, int); */ void pcap_oneshot(u_char *, const struct pcap_pkthdr *, const u_char *); -#ifdef _WIN32 -void pcap_win32_err_to_str(DWORD, char *); -#endif - int install_bpf_program(pcap_t *, struct bpf_program *); int pcap_strcasecmp(const char *, const char *); diff --git a/pcap.c b/pcap.c index 6fe8e16a..84dbe9a8 100644 --- a/pcap.c +++ b/pcap.c @@ -3273,35 +3273,6 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock) } #endif -#ifdef _WIN32 -/* - * Generate a string for a Win32-specific error (i.e. an error generated when - * calling a Win32 API). - * For errors occurred during standard C calls, we still use pcap_strerror() - */ -void -pcap_win32_err_to_str(DWORD error, char *errbuf) -{ - size_t errlen; - char *p; - - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, - PCAP_ERRBUF_SIZE, NULL); - - /* - * "FormatMessage()" "helpfully" sticks CR/LF at the end of the - * message. Get rid of it. - */ - errlen = strlen(errbuf); - if (errlen >= 2) { - errbuf[errlen - 1] = '\0'; - errbuf[errlen - 2] = '\0'; - } - p = strchr(errbuf, '\0'); - pcap_snprintf (p, PCAP_ERRBUF_SIZE+1-(p-errbuf), " (%lu)", error); -} -#endif - /* * Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values. */ diff --git a/rpcapd/daemon.c b/rpcapd/daemon.c index 90bc0cc6..7833d11b 100644 --- a/rpcapd/daemon.c +++ b/rpcapd/daemon.c @@ -1228,12 +1228,7 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf) HANDLE Token; if (LogonUser(username, ".", password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token) == 0) { - int error; - - error = GetLastError(); - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, - PCAP_ERRBUF_SIZE, NULL); - + pcap_win32_err_to_str(GetLastError(), errbuf); return -1; } @@ -1241,12 +1236,7 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf) // I didn't test it. if (ImpersonateLoggedOnUser(Token) == 0) { - int error; - - error = GetLastError(); - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, - PCAP_ERRBUF_SIZE, NULL); - + pcap_win32_err_to_str(GetLastError(), errbuf); CloseHandle(Token); return -1; } diff --git a/rpcapd/win32-svc.c b/rpcapd/win32-svc.c index c846b2cb..5d132a06 100644 --- a/rpcapd/win32-svc.c +++ b/rpcapd/win32-svc.c @@ -33,6 +33,7 @@ #include "rpcapd.h" #include // for PCAP_ERRBUF_SIZE +#include "fmtutils.h" #include "portability.h" #include "fileconf.h" #include "log.h" @@ -40,42 +41,29 @@ static SERVICE_STATUS_HANDLE service_status_handle; static SERVICE_STATUS service_status; -void svc_geterr(char *str); static void WINAPI svc_main(DWORD argc, char **argv); static void update_svc_status(DWORD state, DWORD progress_indicator); int svc_start(void) { - int rc; SERVICE_TABLE_ENTRY ste[] = { { PROGRAM_NAME, svc_main }, { NULL, NULL } }; + char string[PCAP_ERRBUF_SIZE]; // This call is blocking. A new thread is created which will launch // the svc_main() function - if ( (rc = StartServiceCtrlDispatcher(ste)) == 0) - svc_geterr("StartServiceCtrlDispatcher()"); + if (StartServiceCtrlDispatcher(ste) == 0) { + pcap_win32_err_to_str(GetLastError(), string); + rpcapd_log(LOGPRIO_ERROR, + "StartServiceCtrlDispatcher() failed: %s", string); + } return rc; // FALSE if this is not started as a service } -void svc_geterr(char *str) -{ - char message[PCAP_ERRBUF_SIZE]; - char string[PCAP_ERRBUF_SIZE]; - int val; - - val = GetLastError(); - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_MAX_WIDTH_MASK, - NULL, val, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR) string, PCAP_ERRBUF_SIZE, NULL); - - rpcapd_log(LOGPRIO_ERROR, "%s failed with error %d: %s", str, val, string); -} - void WINAPI svc_control_handler(DWORD Opcode) { switch(Opcode) diff --git a/sockutils.c b/sockutils.c index 09d1a961..57bcdf66 100644 --- a/sockutils.c +++ b/sockutils.c @@ -133,25 +133,11 @@ void sock_fmterror(const char *caller, int errcode, char *errbuf, int errbuflen) if (errbuf == NULL) return; - retval = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_MAX_WIDTH_MASK, - NULL, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - message, sizeof(message) / sizeof(TCHAR), NULL); - - if (retval == 0) - { - if ((caller) && (*caller)) - pcap_snprintf(errbuf, errbuflen, "%sUnable to get the exact error message", caller); - else - pcap_snprintf(errbuf, errbuflen, "Unable to get the exact error message"); - } + pcap_win32_err_to_str(errcode, message); + if ((caller) && (*caller)) + pcap_snprintf(errbuf, errbuflen, "%s%s", caller, message, errcode); else - { - if ((caller) && (*caller)) - pcap_snprintf(errbuf, errbuflen, "%s%s (code %d)", caller, message, errcode); - else - pcap_snprintf(errbuf, errbuflen, "%s (code %d)", message, errcode); - } + pcap_snprintf(errbuf, errbuflen, "%s", message, errcode); #else char *message; @@ -161,9 +147,9 @@ void sock_fmterror(const char *caller, int errcode, char *errbuf, int errbuflen) message = strerror(errcode); if ((caller) && (*caller)) - pcap_snprintf(errbuf, errbuflen, "%s%s (code %d)", caller, message, errcode); + pcap_snprintf(errbuf, errbuflen, "%s%s (%d)", caller, message, errcode); else - pcap_snprintf(errbuf, errbuflen, "%s (code %d)", message, errcode); + pcap_snprintf(errbuf, errbuflen, "%s (%d)", message, errcode); #endif }