diff options
author | Tomasz Moń <desowin@gmail.com> | 2019-04-27 08:39:12 +0200 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2019-04-29 20:24:05 +0000 |
commit | ca553bcb2a78ab65476bf4f2b2a35e7578064de0 (patch) | |
tree | ce6ce08649aad87b4316a1ec4f771b80447daadc /caputils | |
parent | 7a6b6631c853412f5405fe6ca571790e23a4025c (diff) |
caputils: Convert error string to UTF-8 on Windows
The libpcap library on Windows can fill error buffer with localized
message obtained from system. The localized message is encoded in active
code page and can contain non-ASCII characters.
Bug: 15715
Change-Id: I7451c6831ae83503ddeb5314e172c76f3dab500e
Reviewed-on: https://code.wireshark.org/review/32993
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'caputils')
-rw-r--r-- | caputils/capture-wpcap.c | 114 |
1 files changed, 95 insertions, 19 deletions
diff --git a/caputils/capture-wpcap.c b/caputils/capture-wpcap.c index 7c8971e77d..f60517f410 100644 --- a/caputils/capture-wpcap.c +++ b/caputils/capture-wpcap.c @@ -246,6 +246,47 @@ load_wpcap(void) } static char * +local_code_page_str_to_utf8(char *str) +{ + ULONG utf16_len; + wchar_t *utf16_str; + char *utf8_str; + + if (str == NULL) { + return NULL; + } + + utf16_len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + utf16_str = g_malloc_n(utf16_len, sizeof(wchar_t)); + MultiByteToWideChar(CP_ACP, 0, str, -1, utf16_str, utf16_len); + + utf8_str = g_utf16_to_utf8(utf16_str, -1, NULL, NULL, NULL); + + g_free(utf16_str); + return utf8_str; +} + +static void +prepare_errbuf(char *errbuf) +{ + g_assert(errbuf); + errbuf[0] = '\0'; +} + +static void +convert_errbuf_to_utf8(char *errbuf) +{ + gchar *utf8_err; + if (errbuf[0] == '\0') { + return; + } + errbuf[PCAP_ERRBUF_SIZE - 1] = '\0'; + utf8_err = local_code_page_str_to_utf8(errbuf); + g_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s", utf8_err); + g_free(utf8_err); +} + +static char * cant_load_winpcap_err(const char *app_name) { return g_strdup_printf( @@ -262,12 +303,16 @@ cant_load_winpcap_err(const char *app_name) } char* -pcap_lookupdev (char *a) +pcap_lookupdev (char *errbuf) { + char *ret; if (!has_wpcap) { return NULL; } - return p_pcap_lookupdev(a); + ret = p_pcap_lookupdev(errbuf); + if (ret == NULL) + convert_errbuf_to_utf8(errbuf); + return ret; } void @@ -324,8 +369,11 @@ pcap_setfilter(pcap_t *a, struct bpf_program *b) char* pcap_geterr(pcap_t *a) { + char *errbuf; g_assert(has_wpcap); - return p_pcap_geterr(a); + errbuf = p_pcap_geterr(a); + convert_errbuf_to_utf8(errbuf); + return errbuf; } int @@ -345,22 +393,30 @@ pcap_compile_nopcap(int a, int b, struct bpf_program *c, const char *d, int e, } int -pcap_lookupnet(const char *a, bpf_u_int32 *b, bpf_u_int32 *c, char *d) +pcap_lookupnet(const char *a, bpf_u_int32 *b, bpf_u_int32 *c, char *errbuf) { + int ret; g_assert(has_wpcap); - return p_pcap_lookupnet(a, b, c, d); + ret = p_pcap_lookupnet(a, b, c, errbuf); + if (ret == -1) + convert_errbuf_to_utf8(errbuf); + return ret; } pcap_t* -pcap_open_live(const char *a, int b, int c, int d, char *e) +pcap_open_live(const char *a, int b, int c, int d, char *errbuf) { + pcap_t *p; if (!has_wpcap) { - g_snprintf(e, PCAP_ERRBUF_SIZE, + g_snprintf(errbuf, PCAP_ERRBUF_SIZE, "unable to load WinPcap (wpcap.dll); can't open %s to capture", a); return NULL; } - return p_pcap_open_live(a, b, c, d, e); + prepare_errbuf(errbuf); + p = p_pcap_open_live(a, b, c, d, errbuf); + convert_errbuf_to_utf8(errbuf); + return p; } #ifdef HAVE_PCAP_OPEN_DEAD @@ -387,30 +443,42 @@ bpf_image(const struct bpf_insn *a, int b) #ifdef HAVE_PCAP_REMOTE pcap_t* -pcap_open(const char *a, int b, int c, int d, struct pcap_rmtauth *e, char *f) +pcap_open(const char *a, int b, int c, int d, struct pcap_rmtauth *e, char *errbuf) { + pcap_t *ret; if (!has_wpcap) { - g_snprintf(f, PCAP_ERRBUF_SIZE, + g_snprintf(errbuf, PCAP_ERRBUF_SIZE, "unable to load WinPcap (wpcap.dll); can't open %s to capture", a); return NULL; } - return p_pcap_open(a, b, c, d, e, f); + prepare_errbuf(errbuf); + ret = p_pcap_open(a, b, c, d, e, errbuf); + convert_errbuf_to_utf8(errbuf); + return ret; } int -pcap_findalldevs_ex(char *a, struct pcap_rmtauth *b, pcap_if_t **c, char *d) +pcap_findalldevs_ex(char *a, struct pcap_rmtauth *b, pcap_if_t **c, char *errbuf) { + int ret; g_assert(has_wpcap); - return p_pcap_findalldevs_ex(a, b, c, d); + ret = p_pcap_findalldevs_ex(a, b, c, errbuf); + if (ret == -1) + convert_errbuf_to_utf8(errbuf); + return ret; } int pcap_createsrcstr(char *a, int b, const char *c, const char *d, const char *e, - char *f) + char *errbuf) { + int ret; g_assert(has_wpcap); - return p_pcap_createsrcstr(a, b, c, d, e, f); + ret = p_pcap_createsrcstr(a, b, c, d, e, errbuf); + if (ret == -1) + convert_errbuf_to_utf8(errbuf); + return ret; } #endif @@ -444,10 +512,14 @@ pcap_freecode(struct bpf_program *a) #ifdef HAVE_PCAP_FINDALLDEVS int -pcap_findalldevs(pcap_if_t **a, char *b) +pcap_findalldevs(pcap_if_t **a, char *errbuf) { + int ret; g_assert(has_wpcap && p_pcap_findalldevs != NULL); - return p_pcap_findalldevs(a, b); + ret = p_pcap_findalldevs(a, errbuf); + if (ret == -1) + convert_errbuf_to_utf8(errbuf); + return ret; } void @@ -460,10 +532,14 @@ pcap_freealldevs(pcap_if_t *a) #ifdef HAVE_PCAP_CREATE pcap_t * -pcap_create(const char *a, char *b) +pcap_create(const char *a, char *errbuf) { + pcap_t *p; g_assert(has_wpcap && p_pcap_create != NULL); - return p_pcap_create(a, b); + p = p_pcap_create(a, errbuf); + if (p == NULL) + convert_errbuf_to_utf8(errbuf); + return p; } int |