Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion scapy/automaton.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,13 @@ def select_objects(inputs, remain):
False,
remainms
)
if res != 0xFFFFFFFF and res != 0x00000102: # Failed or Timeout
# ctypes' default signed c_int restype returns WAIT_FAILED as -1.
if res == -1 or res == 0xFFFFFFFF:
error = ctypes.WinError()
for evt in created:
ctypes.windll.ws2_32.WSACloseEvent(evt)
raise error
if res != 0x00000102: # Timeout
results.add(inputs[res])
if len(events) > 1:
# Now poll the others, if any
Expand All @@ -148,6 +154,11 @@ def select_objects(inputs, remain):
ctypes.c_void_p(evt),
0 # poll: don't wait
)
if res == -1 or res == 0xFFFFFFFF:
error = ctypes.WinError()
for created_evt in created:
ctypes.windll.ws2_32.WSACloseEvent(created_evt)
raise error
if res == 0:
results.add(inputs[i])
# Cleanup created events, if any
Expand Down
46 changes: 46 additions & 0 deletions test/windows.uts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
+ Configuration

= Imports
~ automaton

from unittest import mock

Expand All @@ -21,6 +22,51 @@ a = ObjectPipe()
a.send("test")
assert select_objects([a], 0) == [a]

= Automaton - WaitFor* errors are raised
~ automaton

import ctypes as _ctypes
import scapy.automaton as _automaton

for failure, input_count, use_native_socket in [
(-1, 1, True),
(0xFFFFFFFF, 2, False),
(0, 2, True)]:
inputs = [mock.Mock() for _ in range(input_count)]
for index, obj in enumerate(inputs):
obj.fileno.return_value = index + 10
obj.__selectable_force_select__ = False
if use_native_socket:
inputs[0].__selectable_force_select__ = True
kernel32 = mock.Mock()
if input_count == 1:
kernel32.WaitForSingleObject.return_value = failure
elif use_native_socket:
kernel32.WaitForMultipleObjects.return_value = 0
kernel32.WaitForSingleObject.return_value = -1
else:
kernel32.WaitForMultipleObjects.return_value = failure
ws2_32 = mock.Mock()
ws2_32.WSACreateEvent.return_value = 100
ws2_32.WSAEventSelect.return_value = 0
windll = mock.Mock(kernel32=kernel32, ws2_32=ws2_32)
with mock.patch.object(_automaton, "WINDOWS", True):
with mock.patch.object(_automaton, "ctypes", _ctypes, create=True):
with mock.patch.object(
_ctypes, "windll", windll, create=True):
with mock.patch.object(
_ctypes, "WinError",
return_value=OSError("wait failed"), create=True
) as win_error:
try:
select_objects(inputs, 0)
except OSError:
pass
else:
assert False, "WAIT_FAILED must raise an OSError"
win_error.assert_called_once_with()
if use_native_socket:
assert ws2_32.WSACloseEvent.call_count == 1
############
############
+ Windows arch unit tests
Expand Down
Loading