aboutsummaryrefslogtreecommitdiffstats
path: root/caputils
diff options
context:
space:
mode:
authorTomasz Moń <desowin@gmail.com>2019-04-27 08:39:12 +0200
committerGuy Harris <guy@alum.mit.edu>2019-04-29 20:24:05 +0000
commitca553bcb2a78ab65476bf4f2b2a35e7578064de0 (patch)
treece6ce08649aad87b4316a1ec4f771b80447daadc /caputils
parent7a6b6631c853412f5405fe6ca571790e23a4025c (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.c114
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