aboutsummaryrefslogtreecommitdiffstats
path: root/wsutil/win32-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'wsutil/win32-utils.c')
-rw-r--r--wsutil/win32-utils.c75
1 files changed, 72 insertions, 3 deletions
diff --git a/wsutil/win32-utils.c b/wsutil/win32-utils.c
index 9de0723652..b0541a2021 100644
--- a/wsutil/win32-utils.c
+++ b/wsutil/win32-utils.c
@@ -8,8 +8,14 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
+#include <config.h>
+
#include "win32-utils.h"
+#include <log.h>
+
+#include <tchar.h>
+
/* Quote the argument element if necessary, so that it will get
* reconstructed correctly in the C runtime startup code. Note that
* the unquoting algorithm in the C runtime is really weird, and
@@ -149,15 +155,78 @@ win32strexception(DWORD exception)
return errbuf;
}
+// This appears to be the closest equivalent to SIGPIPE on Windows.
+// https://blogs.msdn.microsoft.com/oldnewthing/20131209-00/?p=2433
+// https://stackoverflow.com/a/53214/82195
+
+static void win32_kill_child_on_exit(HANDLE child_handle) {
+ static HANDLE cjo_handle = NULL;
+ if (!cjo_handle) {
+ cjo_handle = CreateJobObject(NULL, _T("Local\\Wireshark child process cleanup"));
+
+ if (!cjo_handle) {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not create child cleanup job object: %s",
+ win32strerror(GetLastError()));
+ return;
+ }
+
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION cjo_jel_info = { 0 };
+ cjo_jel_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
+ BOOL sijo_ret = SetInformationJobObject(cjo_handle, JobObjectExtendedLimitInformation,
+ &cjo_jel_info, sizeof(cjo_jel_info));
+ if (!sijo_ret) {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not set child cleanup limits: %s",
+ win32strerror(GetLastError()));
+ }
+ }
+
+ BOOL aptjo_ret = AssignProcessToJobObject(cjo_handle, child_handle);
+ if (!aptjo_ret) {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not assign child cleanup process: %s",
+ win32strerror(GetLastError()));
+ }
+}
+
+BOOL win32_create_process(const char *application_name, const char *command_line, LPSECURITY_ATTRIBUTES process_attributes, LPSECURITY_ATTRIBUTES thread_attributes, BOOL inherit_handles, DWORD creation_flags, LPVOID environment, const char *current_directory, LPSTARTUPINFO startup_info, LPPROCESS_INFORMATION process_information)
+{
+ gunichar2 *wappname = NULL, *wcurrentdirectory = NULL;
+ gunichar2 *wcommandline = g_utf8_to_utf16(command_line, -1, NULL, NULL, NULL);
+ // CREATE_SUSPENDED: Suspend the child so that we can cleanly call
+ // AssignProcessToJobObject.
+ // CREATE_BREAKAWAY_FROM_JOB: The main application might be associated with
+ // a job, e.g. if we're running from ConEmu or Visual Studio. Break away
+ // from it so that we can cleanly call AssignProcessToJobObject on *our* job.
+ DWORD wcreationflags = creation_flags|CREATE_SUSPENDED|CREATE_BREAKAWAY_FROM_JOB;
+
+ if (application_name) {
+ wappname = g_utf8_to_utf16(application_name, -1, NULL, NULL, NULL);
+ }
+ if (current_directory) {
+ wcurrentdirectory = g_utf8_to_utf16(current_directory, -1, NULL, NULL, NULL);
+ }
+ BOOL cp_res = CreateProcess(wappname, wcommandline, process_attributes, thread_attributes,
+ inherit_handles, wcreationflags, environment, wcurrentdirectory, startup_info,
+ process_information);
+ if (cp_res) {
+ win32_kill_child_on_exit(process_information->hProcess);
+ ResumeThread(process_information->hThread);
+ }
+
+ g_free(wappname);
+ g_free(wcommandline);
+ g_free(wcurrentdirectory);
+ return cp_res;
+}
+
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local Variables:
- * c-basic-offset: 2
+ * c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
- * ex: set shiftwidth=2 tabstop=8 expandtab:
- * :indentSize=2:tabSize=8:noTabs=true:
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
*/