aboutsummaryrefslogtreecommitdiffstats
path: root/extcap_spawn.c
diff options
context:
space:
mode:
authorHåkon Øye Amundsen <haakon.amundsen@nordicsemi.no>2017-08-25 11:28:34 +0200
committerAnders Broman <a.broman58@gmail.com>2017-08-28 05:48:01 +0000
commit018f6bff18785a1c3971a1ccfe3b1b5243d4d154 (patch)
treeaa4d61e478e39f628000dd6cf7bbbccc2e745a7d /extcap_spawn.c
parent7aeff4fb904e67ce8f81053f595b8a8b0340cb52 (diff)
extcap: Interface Toolbar support on Windows
Add support for extcap control pipes on Windows. Improved read loop in InterfaceToolbarReader. Delay opening control pipes until extcap has opened the fifo pipe. Make extcap_example.py work on Windows. Bug: 13833 Change-Id: I4b47d25452637759b8a3be53be48eee5365bc0e4 Reviewed-on: https://code.wireshark.org/review/23211 Petri-Dish: Stig Bjørlykke <stig@bjorlykke.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'extcap_spawn.c')
-rw-r--r--extcap_spawn.c132
1 files changed, 91 insertions, 41 deletions
diff --git a/extcap_spawn.c b/extcap_spawn.c
index 8b9b5988bf..d88c3945d0 100644
--- a/extcap_spawn.c
+++ b/extcap_spawn.c
@@ -287,67 +287,117 @@ GPid extcap_spawn_async(extcap_userdata *userdata, GPtrArray *args)
}
#ifdef _WIN32
+
+typedef struct
+{
+ HANDLE pipeHandle;
+ OVERLAPPED ol;
+ BOOL pendingIO;
+} PIPEINTS;
+
gboolean
-extcap_wait_for_pipe(HANDLE pipe_h, HANDLE pid)
+extcap_wait_for_pipe(HANDLE * pipe_handles, int num_pipe_handles, HANDLE pid)
{
- DWORD dw;
- HANDLE handles[2];
- OVERLAPPED ov;
- gboolean success = FALSE;
- 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)
+ PIPEINTS pipeinsts[3];
+ DWORD dw, cbRet;
+ HANDLE handles[4];
+ int error_code;
+ int num_waiting_to_connect = 0;
+ int num_handles = num_pipe_handles + 1; // PID handle is also added to list of handles.
+
+ if (num_pipe_handles == 0 || num_pipe_handles > 3)
{
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap connected to pipe");
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Invalid number of pipes given as argument.");
+ return FALSE;
}
- else
+
+ for (int i = 0; i < num_pipe_handles; ++i)
{
- dw = WaitForMultipleObjects(2, handles, FALSE, 30000);
- if (dw == WAIT_OBJECT_0)
+ pipeinsts[i].pipeHandle = pipe_handles[i];
+ pipeinsts[i].ol.Pointer = 0;
+ pipeinsts[i].ol.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ pipeinsts[i].pendingIO = FALSE;
+ handles[i] = pipeinsts[i].ol.hEvent;
+ BOOL connected = ConnectNamedPipe(pipeinsts[i].pipeHandle, &pipeinsts[i].ol);
+ if (connected)
+ {
+ error_code = GetLastError();
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "ConnectNamedPipe failed with %d \n.", error_code);
+ return FALSE;
+ }
+
+ switch (GetLastError())
{
- /* ConnectNamedPipe finished. */
- DWORD code;
+ case ERROR_IO_PENDING:
+ num_waiting_to_connect++;
+ pipeinsts[i].pendingIO = TRUE;
+ break;
- code = GetLastError();
- if (code == ERROR_IO_PENDING)
+ case ERROR_PIPE_CONNECTED:
+ if (SetEvent(pipeinsts[i].ol.hEvent))
{
- DWORD dummy;
- if (!GetOverlappedResult(ov.hEvent, &ov, &dummy, TRUE))
- {
- code = GetLastError();
- }
- else
- {
- code = ERROR_SUCCESS;
- success = TRUE;
- }
- }
+ break;
+ } // Fallthrough if this fails.
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "ConnectNamedPipe code: %d", code);
+ default:
+ error_code = GetLastError();
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "ConnectNamedPipe failed with %d \n.", error_code);
+ return FALSE;
}
- else if (dw == (WAIT_OBJECT_0 + 1))
+ }
+
+ // Store pid of extcap process so it can be monitored in case it fails before the pipes has connceted.
+ handles[num_pipe_handles] = pid;
+
+ while(num_waiting_to_connect > 0)
+ {
+ dw = WaitForMultipleObjects(num_handles, handles, FALSE, 30000);
+ int idx = dw - WAIT_OBJECT_0;
+ if (dw == WAIT_TIMEOUT)
{
- /* extcap process terminated. */
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap terminated without connecting to pipe.");
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap didn't connect to pipe within 30 seconds.");
+ return FALSE;
}
- else if (dw == WAIT_TIMEOUT)
+ // If index points to our handles array
+ else if (idx >= 0 && idx < num_handles)
{
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap didn't connect to pipe within 30 seconds.");
+ if (idx < num_pipe_handles) // Index of pipe handle
+ {
+ if (pipeinsts[idx].pendingIO)
+ {
+ BOOL success = GetOverlappedResult(
+ pipeinsts[idx].pipeHandle, // handle to pipe
+ &pipeinsts[idx].ol, // OVERLAPPED structure
+ &cbRet, // bytes transferred
+ FALSE); // do not wait
+
+ if (!success)
+ {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Error %d \n.", GetLastError());
+ return FALSE;
+ }
+ else
+ {
+ pipeinsts[idx].pendingIO = FALSE;
+ num_waiting_to_connect--;
+ }
+ }
+ }
+ else // Index of PID
+ {
+ // Fail since index of 'pid' indicates that the pid of the extcap process has terminated.
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap terminated without connecting to pipe.");
+ return FALSE;
+ }
}
else
{
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "WaitForMultipleObjects returned 0x%08X. Error %d", dw, GetLastError());
+ return FALSE;
}
}
- CloseHandle(ov.hEvent);
-
- return success;
+ return TRUE;
}
#endif