aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Knall <rknall@gmail.com>2016-06-28 21:34:46 +0200
committerRoland Knall <rknall@gmail.com>2016-07-05 11:54:43 +0000
commitf2786bc8ff5ea25fd1c36d3ebf83a29277ee662b (patch)
tree0e0f3c89505d3257ab5510c55eff956543814e40
parentfdd87a1e41db7039b0af5bb15f40b83db1ca3a96 (diff)
extcap: Remove g_spawn_helper support
Move g_spawn to separate file and implement functions to use Windows based method of spawning, instead of the glib based version Change-Id: Ibae03d834ec86531eba37dc8768fbf17ddadf57f Reviewed-on: https://code.wireshark.org/review/16049 Petri-Dish: Roland Knall <rknall@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Graham Bloice <graham.bloice@trihedral.com> Reviewed-by: Roland Knall <rknall@gmail.com>
-rw-r--r--CMakeLists.txt1
-rw-r--r--Makefile.am6
-rw-r--r--capture_opts.c3
-rw-r--r--capture_opts.h1
-rw-r--r--extcap.c189
-rw-r--r--extcap_spawn.c368
-rw-r--r--extcap_spawn.h67
-rw-r--r--packaging/nsis/CMakeLists.txt2
-rw-r--r--packaging/wix/CMakeLists.txt8
-rw-r--r--tools/Get-HardenFlags.ps14
10 files changed, 503 insertions, 146 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c79ee445fa..9bfaf68943 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1280,6 +1280,7 @@ if(ENABLE_EXTCAP)
${SHARK_COMMON_SRC}
extcap.c
extcap_parser.c
+ extcap_spawn.c
)
endif()
diff --git a/Makefile.am b/Makefile.am
index a4458e0a6d..a6149110c1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -383,11 +383,13 @@ GENERATED_FILES = $(GENERATED_C_FILES) $(GENERATED_HEADER_FILES)
EXTCAP_COMMON_SRC = \
extcap.c \
- extcap_parser.c
+ extcap_parser.c \
+ extcap_spawn.c
EXTCAP_COMMON_INCLUDES = \
extcap.h \
- extcap_parser.h
+ extcap_parser.h \
+ extcap_spawn.h
# sources common for wireshark, tshark, and rawshark
SHARK_COMMON_SRC = \
diff --git a/capture_opts.c b/capture_opts.c
index f383c82a94..2eb5b630d1 100644
--- a/capture_opts.c
+++ b/capture_opts.c
@@ -685,6 +685,7 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str
interface_opts.extcap_fifo = g_strdup(capture_opts->default_options.extcap_fifo);
interface_opts.extcap_args = NULL;
interface_opts.extcap_pid = INVALID_EXTCAP_PID;
+ interface_opts.extcap_userdata = NULL;
#endif
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
interface_opts.buffer_size = capture_opts->default_options.buffer_size;
@@ -1111,6 +1112,7 @@ capture_opts_del_iface(capture_options *capture_opts, guint if_index)
g_hash_table_unref(interface_opts.extcap_args);
if (interface_opts.extcap_pid != INVALID_EXTCAP_PID)
g_spawn_close_pid(interface_opts.extcap_pid);
+ g_free(interface_opts.extcap_userdata);
#endif
#ifdef HAVE_PCAP_REMOTE
if (interface_opts.src_type == CAPTURE_IFREMOTE) {
@@ -1160,6 +1162,7 @@ collect_ifaces(capture_options *capture_opts)
interface_opts.extcap_pid = INVALID_EXTCAP_PID;
if (interface_opts.extcap_args)
g_hash_table_ref(interface_opts.extcap_args);
+ interface_opts.extcap_userdata = NULL;
#endif
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
interface_opts.buffer_size = device.buffer;
diff --git a/capture_opts.h b/capture_opts.h
index 4a8bddb1e6..4fc4d67fd1 100644
--- a/capture_opts.h
+++ b/capture_opts.h
@@ -233,6 +233,7 @@ typedef struct interface_options_tag {
gchar *extcap_fifo;
GHashTable *extcap_args;
GPid extcap_pid; /* pid of running process or INVALID_EXTCAP_PID */
+ gpointer extcap_userdata;
guint extcap_child_watch;
#endif
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
diff --git a/extcap.c b/extcap.c
index 29f931ac12..cff843487c 100644
--- a/extcap.c
+++ b/extcap.c
@@ -51,6 +51,7 @@
#include "extcap.h"
#include "extcap_parser.h"
+#include "extcap_spawn.h"
#ifdef _WIN32
static HANDLE pipe_h = NULL;
@@ -153,67 +154,28 @@ static void extcap_foreach(gint argc, gchar **args, extcap_cb_t cb,
GDir *dir;
const gchar *file;
gboolean keep_going;
- gint i;
- gchar **argv;
-#ifdef _WIN32
- gchar **dll_search_envp;
- gchar *progfile_dir;
-#endif
keep_going = TRUE;
- argv = (gchar **) g_malloc0(sizeof(gchar *) * (argc + 2));
-
-#ifdef _WIN32
- /*
- * Make sure executables can find dependent DLLs and that they're *our*
- * DLLs: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586.aspx
- * Alternatively we could create a simple wrapper exe similar to Create
- * Hidden Process (http://www.commandline.co.uk/chp/).
- */
- dll_search_envp = g_get_environ();
- progfile_dir = g_strdup_printf("%s;%s", get_progfile_dir(), g_environ_getenv(dll_search_envp, "Path"));
- dll_search_envp = g_environ_setenv(dll_search_envp, "Path", progfile_dir, TRUE);
- g_free(progfile_dir);
-#endif
-
if ((dir = g_dir_open(dirname, 0, NULL)) != NULL) {
GString *extcap_path = NULL;
extcap_path = g_string_new("");
while (keep_going && (file = g_dir_read_name(dir)) != NULL ) {
gchar *command_output = NULL;
- gboolean status = FALSE;
- gint exit_status = 0;
- gchar **envp = NULL;
/* full path to extcap binary */
#ifdef _WIN32
g_string_printf(extcap_path, "%s\\%s", dirname, file);
- envp = dll_search_envp;
#else
g_string_printf(extcap_path, "%s/%s", dirname, file);
#endif
if ( extcap_if_exists(ifname) && !extcap_if_exists_for_extcap(ifname, extcap_path->str ) )
continue;
-#ifdef _WIN32
- argv[0] = g_strescape(extcap_path->str, NULL);
-#else
- argv[0] = g_strdup(extcap_path->str);
-#endif
- for (i = 0; i < argc; ++i)
- argv[i+1] = args[i];
- argv[argc+1] = NULL;
-
- status = g_spawn_sync(dirname, argv, envp,
- (GSpawnFlags) 0, NULL, NULL,
- &command_output, NULL, &exit_status, NULL);
-
- if (status && exit_status == 0)
+ if ( extcap_spawn_sync ( (gchar *) dirname, extcap_path->str, argc, args, &command_output ) )
keep_going = cb(extcap_path->str, ifname, command_output, cb_data, err_str);
- g_free(argv[0]);
g_free(command_output);
}
@@ -221,10 +183,6 @@ static void extcap_foreach(gint argc, gchar **args, extcap_cb_t cb,
g_string_free(extcap_path, TRUE);
}
-#ifdef _WIN32
- g_strfreev(dll_search_envp);
-#endif
- g_free(argv);
}
static gboolean dlt_cb(const gchar *extcap _U_, const gchar *ifname _U_, gchar *output, void *data,
@@ -644,7 +602,7 @@ void extcap_cleanup(capture_options * capture_opts) {
/* skip native interfaces */
if (interface_opts.if_type != IF_EXTCAP)
- continue;
+ continue;
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
"Extcap [%s] - Cleaning up fifo: %s; PID: %d", interface_opts.name,
@@ -730,34 +688,20 @@ static void extcap_child_watch_cb(GPid pid, gint status _U_, gpointer user_data)
}
}
-/* call mkfifo for each extcap,
- * returns FALSE if there's an error creating a FIFO */
-gboolean
-extcap_init_interfaces(capture_options *capture_opts)
+static
+GPtrArray * extcap_prepare_arguments(interface_options interface_opts)
{
- guint i;
- interface_options interface_opts;
-
- for (i = 0; i < capture_opts->ifaces->len; i++)
- {
- GPtrArray *args = NULL;
- GPid pid = INVALID_EXTCAP_PID;
- gchar **tmp;
- int tmp_i;
-
- interface_opts = g_array_index(capture_opts->ifaces, interface_options, i);
-
- /* skip native interfaces */
- if (interface_opts.if_type != IF_EXTCAP )
- continue;
+ GPtrArray *result = NULL;
+#if ARG_DEBUG
+ gchar **tmp;
+ int tmp_i;
+#endif
- /* create pipe for fifo */
- if ( ! extcap_create_pipe ( &interface_opts.extcap_fifo ) )
- return FALSE;
+ if (interface_opts.if_type == IF_EXTCAP )
+ {
+ result = g_ptr_array_new();
- /* Create extcap call */
- args = g_ptr_array_new();
-#define add_arg(X) g_ptr_array_add(args, g_strdup(X))
+#define add_arg(X) g_ptr_array_add(result, g_strdup(X))
add_arg(interface_opts.extcap);
add_arg(EXTCAP_ARGUMENT_RUN_CAPTURE);
@@ -824,26 +768,62 @@ extcap_init_interfaces(capture_options *capture_opts)
}
else
{
- g_hash_table_foreach_remove(interface_opts.extcap_args, extcap_add_arg_and_remove_cb, args);
+ g_hash_table_foreach_remove(interface_opts.extcap_args, extcap_add_arg_and_remove_cb, result);
}
add_arg(NULL);
#undef add_arg
+#if ARG_DEBUG
/* Dump commandline parameters sent to extcap. */
- for (tmp = (gchar **)args->pdata, tmp_i = 0; *tmp && **tmp; ++tmp_i, ++tmp)
+ for (tmp = (gchar **)result->pdata, tmp_i = 0; *tmp && **tmp; ++tmp_i, ++tmp)
{
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", tmp_i, *tmp);
}
+#endif
+
+ }
- /* Wireshark for windows crashes here sometimes *
- * Access violation reading location 0x... */
- g_spawn_async(NULL, (gchar **)args->pdata, NULL,
- (GSpawnFlags) G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL,
- &pid,NULL);
+ return result;
+}
+
+/* call mkfifo for each extcap,
+ * returns FALSE if there's an error creating a FIFO */
+gboolean
+extcap_init_interfaces(capture_options *capture_opts)
+{
+ guint i;
+ interface_options interface_opts;
+
+ for (i = 0; i < capture_opts->ifaces->len; i++)
+ {
+ GPtrArray *args = NULL;
+ GPid pid = INVALID_EXTCAP_PID;
+
+ interface_opts = g_array_index(capture_opts->ifaces, interface_options, i);
+
+ /* skip native interfaces */
+ if (interface_opts.if_type != IF_EXTCAP )
+ continue;
+
+ /* create pipe for fifo */
+ if ( ! extcap_create_pipe ( &interface_opts.extcap_fifo ) )
+ return FALSE;
+
+ /* Create extcap call */
+ args = extcap_prepare_arguments(interface_opts);
+
+ interface_opts.extcap_userdata = NULL;
+
+ pid = extcap_spawn_async(&interface_opts, args );
g_ptr_array_foreach(args, (GFunc)g_free, NULL);
g_ptr_array_free(args, TRUE);
+
+ if ( pid == INVALID_EXTCAP_PID )
+ continue;
+
interface_opts.extcap_pid = pid;
+
interface_opts.extcap_child_watch =
g_child_watch_add(pid, extcap_child_watch_cb, (gpointer)capture_opts);
capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, i);
@@ -861,60 +841,7 @@ extcap_init_interfaces(capture_options *capture_opts)
*/
if (pid != INVALID_EXTCAP_PID)
{
- DWORD dw;
- HANDLE handles[2];
- OVERLAPPED ov;
- ov.Pointer = 0;
- ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-
- ConnectNamedPipe(pipe_h, &ov);
- handles[0] = ov.hEvent;
- handles[1] = pid;
-
- if (GetLastError() == ERROR_PIPE_CONNECTED)
- {
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap connected to pipe");
- }
- else
- {
- dw = WaitForMultipleObjects(2, handles, FALSE, 30000);
- if (dw == WAIT_OBJECT_0)
- {
- /* ConnectNamedPipe finished. */
- DWORD code;
-
- code = GetLastError();
- if (code == ERROR_IO_PENDING)
- {
- DWORD dummy;
- if (!GetOverlappedResult(ov.hEvent, &ov, &dummy, TRUE))
- {
- code = GetLastError();
- }
- else
- {
- code = ERROR_SUCCESS;
- }
- }
-
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "ConnectNamedPipe code: %d", code);
- }
- else if (dw == (WAIT_OBJECT_0 + 1))
- {
- /* extcap process terminated. */
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap terminated without connecting to pipe!");
- }
- else if (dw == WAIT_TIMEOUT)
- {
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap didn't connect to pipe within 30 seconds!");
- }
- else
- {
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "WaitForMultipleObjects returned 0x%08X. Error %d", dw, GetLastError());
- }
- }
-
- CloseHandle(ov.hEvent);
+ extcap_wait_for_pipe(pipe_h, pid);
}
#endif
}
diff --git a/extcap_spawn.c b/extcap_spawn.c
new file mode 100644
index 0000000000..555958c687
--- /dev/null
+++ b/extcap_spawn.c
@@ -0,0 +1,368 @@
+/* extcap_spawn.c
+ *
+ * Routines to spawn extcap external capture programs
+ * Copyright 2016, Roland Knall <rknall@gmail.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <glib.h>
+#include <string.h>
+
+#include <wsutil/file_util.h>
+#include <wsutil/filesystem.h>
+#ifdef _WIN32
+#include <wsutil/win32-utils.h>
+#endif
+
+#include <log.h>
+
+#include "extcap.h"
+#include "extcap_spawn.h"
+
+#ifdef _WIN32
+
+void win32_readfrompipe(HANDLE read_pipe, gint32 max_buffer, gchar * buffer)
+{
+ gboolean bSuccess = FALSE;
+ gint32 bytes_written = 0;
+ gint32 max_bytes = 0;
+
+ DWORD dwRead;
+ DWORD bytes_avail = 0;
+
+ for (;;)
+ {
+ if (!PeekNamedPipe(read_pipe, NULL, 0, NULL, &bytes_avail, NULL)) break;
+ if (bytes_avail <= 0) break;
+
+ max_bytes = max_buffer - bytes_written - 1;
+
+ bSuccess = ReadFile(read_pipe, &buffer[bytes_written], max_bytes, &dwRead, NULL);
+ if (!bSuccess || dwRead == 0) break;
+
+ bytes_written += dwRead;
+ if ((bytes_written + 1) >= max_buffer) break;
+ }
+
+ buffer[bytes_written] = '\0';
+}
+#endif
+
+gboolean extcap_spawn_sync ( gchar * dirname, gchar * command, gint argc, gchar ** args, gchar ** command_output )
+{
+ gboolean status = FALSE;
+ gboolean result = FALSE;
+ gchar ** argv = NULL;
+ gint cnt = 0;
+ gchar * local_output = NULL;
+#ifdef _WIN32
+
+#define BUFFER_SIZE 4096
+ gchar buffer[BUFFER_SIZE];
+
+ GString *winargs = g_string_sized_new(200);
+ gchar *quoted_arg;
+ gunichar2 *wcommandline;
+
+ STARTUPINFO info;
+ PROCESS_INFORMATION processInfo;
+
+ SECURITY_ATTRIBUTES sa;
+ HANDLE child_stdout_rd = NULL;
+ HANDLE child_stdout_wr = NULL;
+ HANDLE child_stderr_rd = NULL;
+ HANDLE child_stderr_wr = NULL;
+
+ const gchar * oldpath = g_getenv("PATH");
+ gchar * newpath = NULL;
+#else
+ gint exit_status = 0;
+#endif
+
+ argv = (gchar **) g_malloc0(sizeof(gchar *) * (argc + 2));
+
+#ifdef _WIN32
+ newpath = g_strdup_printf("%s;%s", g_strescape(get_progfile_dir(), NULL), oldpath);
+ g_setenv("PATH", newpath, TRUE);
+
+ argv[0] = g_strescape(command, NULL);
+#else
+ argv[0] = g_strdup(command);
+#endif
+
+ for ( cnt = 0; cnt < argc; cnt++ )
+ argv[cnt+1] = args[cnt];
+ argv[argc+1] = NULL;
+
+#ifdef _WIN32
+
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = TRUE;
+ sa.lpSecurityDescriptor = NULL;
+
+ if (!CreatePipe(&child_stdout_rd, &child_stdout_wr, &sa, 0))
+ {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not create stdout handle");
+ return FALSE;
+ }
+
+ if (!CreatePipe(&child_stderr_rd, &child_stderr_wr, &sa, 0))
+ {
+ CloseHandle(child_stdout_rd);
+ CloseHandle(child_stdout_wr);
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not create stderr handle");
+ return FALSE;
+ }
+
+ /* convert args array into a single string */
+ /* XXX - could change sync_pipe_add_arg() instead */
+ /* there is a drawback here: the length is internally limited to 1024 bytes */
+ for (cnt = 0; argv[cnt] != 0; cnt++) {
+ if (cnt != 0) g_string_append_c(winargs, ' '); /* don't prepend a space before the path!!! */
+ quoted_arg = protect_arg(argv[cnt]);
+ g_string_append(winargs, quoted_arg);
+ g_free(quoted_arg);
+ }
+
+ wcommandline = g_utf8_to_utf16(winargs->str, (glong)winargs->len, NULL, NULL, NULL);
+
+ memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
+ memset(&info, 0, sizeof(STARTUPINFO));
+
+ info.cb = sizeof(STARTUPINFO);
+ info.hStdError = child_stderr_wr;
+ info.hStdOutput = child_stdout_wr;
+ info.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ info.wShowWindow = SW_HIDE;
+
+ if (CreateProcess(NULL, wcommandline, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &info, &processInfo))
+ {
+ WaitForSingleObject(processInfo.hProcess, INFINITE);
+ win32_readfrompipe(child_stdout_rd, BUFFER_SIZE, buffer);
+ local_output = g_strdup_printf("%s", buffer);
+
+ CloseHandle(child_stdout_rd);
+ CloseHandle(child_stdout_wr);
+ CloseHandle(child_stderr_rd);
+ CloseHandle(child_stderr_wr);
+
+ CloseHandle(processInfo.hProcess);
+ CloseHandle(processInfo.hThread);
+ status = TRUE;
+ }
+ else
+ status = FALSE;
+
+ g_setenv("PATH", oldpath, TRUE);
+#else
+
+ status = g_spawn_sync(dirname, argv, NULL,
+ (GSpawnFlags) 0, NULL, NULL, &local_output, NULL, &exit_status, NULL);
+
+ if (status && exit_status != 0)
+ status = FALSE;
+#endif
+
+ if (status)
+ {
+ if ( command_output != NULL && local_output != NULL )
+ *command_output = g_strdup(local_output);
+
+ result = TRUE;
+ }
+
+ g_free(local_output);
+ g_free(argv);
+
+ return result;
+}
+
+GPid extcap_spawn_async(interface_options * interface, GPtrArray * args)
+{
+ GPid pid = INVALID_EXTCAP_PID;
+
+#ifdef _WIN32
+ gint cnt = 0;
+ gchar ** tmp = NULL;
+
+ GString *winargs = g_string_sized_new(200);
+ gchar *quoted_arg;
+ gunichar2 *wcommandline;
+
+ STARTUPINFO info;
+ PROCESS_INFORMATION processInfo;
+
+ SECURITY_ATTRIBUTES sa;
+ HANDLE child_stdout_rd = NULL;
+ HANDLE child_stdout_wr = NULL;
+ HANDLE child_stderr_rd = NULL;
+ HANDLE child_stderr_wr = NULL;
+
+ const gchar * oldpath = g_getenv("PATH");
+ gchar * newpath = NULL;
+
+#endif
+
+ extcap_userdata * userdata = NULL;
+ userdata = (extcap_userdata *) g_malloc0(sizeof(extcap_userdata));
+
+#ifdef _WIN32
+ newpath = g_strdup_printf("%s;%s", g_strescape(get_progfile_dir(), NULL), oldpath);
+ g_setenv("PATH", newpath, TRUE);
+
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = TRUE;
+ sa.lpSecurityDescriptor = NULL;
+
+ if (!CreatePipe(&child_stdout_rd, &child_stdout_wr, &sa, 0))
+ {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not create stdout handle");
+ return FALSE;
+ }
+
+ if (!CreatePipe(&child_stderr_rd, &child_stderr_wr, &sa, 0))
+ {
+ CloseHandle(child_stdout_rd);
+ CloseHandle(child_stdout_wr);
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not create stderr handle");
+ return FALSE;
+ }
+
+ /* convert args array into a single string */
+ /* XXX - could change sync_pipe_add_arg() instead */
+ /* there is a drawback here: the length is internally limited to 1024 bytes */
+ for (tmp = (gchar **)args->pdata, cnt = 0; *tmp && **tmp; ++cnt, ++tmp) {
+ if (cnt != 0) g_string_append_c(winargs, ' '); /* don't prepend a space before the path!!! */
+ quoted_arg = protect_arg(*tmp);
+ g_string_append(winargs, quoted_arg);
+ g_free(quoted_arg);
+ }
+
+ wcommandline = g_utf8_to_utf16(winargs->str, (glong)winargs->len, NULL, NULL, NULL);
+
+ memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
+ memset(&info, 0, sizeof(STARTUPINFO));
+
+ info.cb = sizeof(STARTUPINFO);
+ info.hStdError = child_stderr_wr;
+ info.hStdOutput = child_stdout_wr;
+ info.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ info.wShowWindow = SW_HIDE;
+
+ if (CreateProcess(NULL, wcommandline, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &info, &processInfo))
+ {
+ userdata->extcap_stderr_rd = _open_osfhandle((intptr_t)(child_stderr_rd), _O_BINARY);
+ userdata->extcap_stdout_rd = _open_osfhandle((intptr_t)(child_stdout_rd), _O_BINARY);
+ userdata->threadId = processInfo.hThread;
+ pid = processInfo.hProcess;
+ }
+
+ g_setenv("PATH", oldpath, TRUE);
+#else
+ g_spawn_async(NULL, (gchar **)args->pdata, NULL, (GSpawnFlags) G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL,
+ &pid, NULL);
+#endif
+
+ userdata->pid = pid;
+ interface->extcap_userdata = userdata;
+
+ return pid;
+}
+
+#ifdef _WIN32
+gboolean
+extcap_wait_for_pipe(HANDLE pipe_h, HANDLE pid)
+{
+ DWORD dw;
+ HANDLE handles[2];
+ OVERLAPPED ov;
+ ov.Pointer = 0;
+ gboolean success = FALSE;
+ ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ ConnectNamedPipe(pipe_h, &ov);
+ handles[0] = ov.hEvent;
+ handles[1] = pid;
+
+ if (GetLastError() == ERROR_PIPE_CONNECTED)
+ {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap connected to pipe");
+ }
+ else
+ {
+ dw = WaitForMultipleObjects(2, handles, FALSE, 30000);
+ if (dw == WAIT_OBJECT_0)
+ {
+ /* ConnectNamedPipe finished. */
+ DWORD code;
+
+ code = GetLastError();
+ if (code == ERROR_IO_PENDING)
+ {
+ DWORD dummy;
+ if (!GetOverlappedResult(ov.hEvent, &ov, &dummy, TRUE))
+ {
+ code = GetLastError();
+ }
+ else
+ {
+ code = ERROR_SUCCESS;
+ success = TRUE;
+ }
+ }
+
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "ConnectNamedPipe code: %d", code);
+ }
+ else if (dw == (WAIT_OBJECT_0 + 1))
+ {
+ /* extcap process terminated. */
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap terminated without connecting to pipe!");
+ }
+ else if (dw == WAIT_TIMEOUT)
+ {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap didn't connect to pipe within 30 seconds!");
+ }
+ else
+ {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "WaitForMultipleObjects returned 0x%08X. Error %d", dw, GetLastError());
+ }
+ }
+
+ CloseHandle(ov.hEvent);
+
+ return success;
+}
+#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/extcap_spawn.h b/extcap_spawn.h
new file mode 100644
index 0000000000..b9b2ef491e
--- /dev/null
+++ b/extcap_spawn.h
@@ -0,0 +1,67 @@
+/* extcap_spawn.h
+ * Helper routines for executing extcap utilities
+ *
+ * Copyright 2016, Roland Knall <rknall@gmail.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EXTCAP_SPAWN_H__
+#define __EXTCAP_SPAWN_H__
+
+#include <config.h>
+
+#include <glib.h>
+
+#include <extcap.h>
+
+typedef struct _extcap_userdata {
+ GPid pid;
+ gchar * extcap_stderr;
+ gint exitcode;
+ gint extcap_stderr_rd;
+ gint extcap_stdout_rd;
+#ifdef _WIN32
+ HANDLE threadId;
+#endif
+} extcap_userdata;
+
+gboolean extcap_spawn_sync ( gchar * dirname, gchar * command, gint argc, gchar ** argv, gchar ** command_output );
+
+GPid extcap_spawn_async ( interface_options * interface, GPtrArray * args );
+
+#ifdef _WIN32
+gboolean extcap_wait_for_pipe(HANDLE pipe_h, HANDLE pid);
+void win32_readfrompipe(HANDLE read_pipe, gint32 max_buffer, gchar * buffer);
+#endif
+
+#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/packaging/nsis/CMakeLists.txt b/packaging/nsis/CMakeLists.txt
index 7ecb927dd8..3452568999 100644
--- a/packaging/nsis/CMakeLists.txt
+++ b/packaging/nsis/CMakeLists.txt
@@ -125,8 +125,6 @@ foreach(_dll ${GLIB2_DLLS} ${CARES_DLL} ${GCRYPT_DLLS} ${GEOIP_DLL}
)
set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
endforeach()
-set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\gspawn-${WIRESHARK_TARGET_PLATFORM}-helper.exe\"\n")
-set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\gspawn-${WIRESHARK_TARGET_PLATFORM}-helper-console.exe\"\n")
foreach(_script "init.lua" "console.lua" "dtd_gen.lua")
set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_script}\"\n")
endforeach()
diff --git a/packaging/wix/CMakeLists.txt b/packaging/wix/CMakeLists.txt
index ed9f035a9c..065e279aa6 100644
--- a/packaging/wix/CMakeLists.txt
+++ b/packaging/wix/CMakeLists.txt
@@ -134,12 +134,6 @@ foreach(_dll ${GLIB2_DLLS} ${CARES_DLL} ${GCRYPT_DLLS} ${GEOIP_DLL}
SET(unique_component ${unique_component} ${_dll})
ENDIF(NOT "${unique_component}" MATCHES "(^|;)${_dll}(;|$)")
endforeach()
-file(APPEND "${_all_manifest_wix}" " <Component Id=\"cmpGSpawn_${WIRESHARK_TARGET_PLATFORM}_helper_exe\" Guid=\"*\">\n")
-file(APPEND "${_all_manifest_wix}" " <File Id=\"filSpawn_${WIRESHARK_TARGET_PLATFORM}_helper_exe\" KeyPath=\"yes\" Source=\"$(var.Staging.Dir)\\gspawn-${WIRESHARK_TARGET_PLATFORM}-helper.exe\"/>\n")
-file(APPEND "${_all_manifest_wix}" " </Component>\n")
-file(APPEND "${_all_manifest_wix}" " <Component Id=\"cmpGSpawn_${WIRESHARK_TARGET_PLATFORM}_helper_console_exe\" Guid=\"*\">\n")
-file(APPEND "${_all_manifest_wix}" " <File Id=\"filSpawn_${WIRESHARK_TARGET_PLATFORM}_helper_console_exe\" KeyPath=\"yes\" Source=\"$(var.Staging.Dir)\\gspawn-${WIRESHARK_TARGET_PLATFORM}-helper-console.exe\"/>\n")
-file(APPEND "${_all_manifest_wix}" " </Component>\n")
foreach(_script "init.lua" "console.lua" "dtd_gen.lua")
STRING(REGEX REPLACE "[-|\\.]" "_" _wix_name ${_script})
file(APPEND "${_all_manifest_wix}" " <Component Id=\"cmp${_wix_name}\" Guid=\"*\">\n")
@@ -162,8 +156,6 @@ foreach(_dll ${GLIB2_DLLS} ${CARES_DLL} ${GCRYPT_DLLS} ${GEOIP_DLL}
SET(unique_file ${unique_file} ${_dll})
ENDIF(NOT "${unique_file}" MATCHES "(^|;)${_dll}(;|$)")
endforeach()
-file(APPEND "${_all_manifest_wix}" " <ComponentRef Id=\"cmpGSpawn_${WIRESHARK_TARGET_PLATFORM}_helper_exe\" />\n")
-file(APPEND "${_all_manifest_wix}" " <ComponentRef Id=\"cmpGSpawn_${WIRESHARK_TARGET_PLATFORM}_helper_console_exe\" />\n")
foreach(_script "init.lua" "console.lua" "dtd_gen.lua")
STRING(REGEX REPLACE "[-|\\.]" "_" _wix_name ${_script})
file(APPEND "${_all_manifest_wix}" " <ComponentRef Id=\"cmp${_wix_name}\" />\n")
diff --git a/tools/Get-HardenFlags.ps1 b/tools/Get-HardenFlags.ps1
index 83c36e509a..665d1eb9a9 100644
--- a/tools/Get-HardenFlags.ps1
+++ b/tools/Get-HardenFlags.ps1
@@ -77,8 +77,6 @@ $SoftBins = (
"libgail.dll",
"airpcap.dll",
"comerr32.dll",
- "gspawn-win32-helper-console.exe",
- "gspawn-win32-helper.exe",
"k5sprt32.dll",
"krb5_32.dll",
"libatk-1.0-0.dll",
@@ -159,4 +157,4 @@ $Binaries | ForEach-Object {
}
}
-exit $Count \ No newline at end of file
+exit $Count