Complete WinDivertSend() IO requests immediately.

Currently, WinDivert waits until injection completes before completing the
corresponding IO request.  However, packet injection may take an arbitrarily
long time, such as waiting for a user-mode application.

The new version completes the IO request immediately, provided the call to the
corresponding WFP packet injection function did not return an error, thus
eliminating the problem.  The disadvantage is that some packet injection
errors may no longer be detected.
This commit is contained in:
basil00
2017-09-23 20:09:04 +08:00
parent c13a27bb4f
commit 200da2fba1
+9 -8
View File
@@ -1534,25 +1534,29 @@ windivert_write_bad_packet:
{
status = FwpsInjectForwardAsync0(handle, (HANDLE)context->priority,
0, (isipv4? AF_INET: AF_INET6), UNSPECIFIED_COMPARTMENT_ID,
addr->IfIdx, buffers, windivert_inject_complete, (HANDLE)request);
addr->IfIdx, buffers, windivert_inject_complete, NULL);
}
else if (addr->Direction == WINDIVERT_DIRECTION_OUTBOUND)
{
status = FwpsInjectNetworkSendAsync0(handle,
(HANDLE)context->priority, 0, UNSPECIFIED_COMPARTMENT_ID, buffers,
windivert_inject_complete, (HANDLE)request);
windivert_inject_complete, NULL);
}
else
{
status = FwpsInjectNetworkReceiveAsync0(handle,
(HANDLE)context->priority, 0, UNSPECIFIED_COMPARTMENT_ID,
addr->IfIdx, addr->SubIfIdx, buffers, windivert_inject_complete,
(HANDLE)request);
NULL);
}
windivert_write_exit:
if (!NT_SUCCESS(status))
if (NT_SUCCESS(status))
{
WdfRequestCompleteWithInformation(request, status, data_len);
}
else
{
DEBUG_ERROR("failed to inject packet", status);
if (buffers != NULL)
@@ -1578,16 +1582,14 @@ windivert_write_exit:
static void NTAPI windivert_inject_complete(VOID *context,
NET_BUFFER_LIST *buffers, BOOLEAN dispatch_level)
{
WDFREQUEST request = (WDFREQUEST)context;
PMDL mdl;
PVOID data;
PNET_BUFFER buffer;
size_t length = 0;
NTSTATUS status;
UNREFERENCED_PARAMETER(context);
UNREFERENCED_PARAMETER(dispatch_level);
DEBUG("COMPLETE: write/inject packet complete (request=%p)", request);
buffer = NET_BUFFER_LIST_FIRST_NB(buffers);
status = NET_BUFFER_LIST_STATUS(buffers);
if (NT_SUCCESS(status))
@@ -1606,7 +1608,6 @@ static void NTAPI windivert_inject_complete(VOID *context,
}
IoFreeMdl(mdl);
FwpsFreeNetBufferList0(buffers);
WdfRequestCompleteWithInformation(request, status, length);
}
/*