From 200da2fba11aaff76de262116dcc0616209acba5 Mon Sep 17 00:00:00 2001 From: basil00 Date: Sat, 23 Sep 2017 20:09:04 +0800 Subject: [PATCH] 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. --- sys/windivert.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/sys/windivert.c b/sys/windivert.c index 76013fe..f637b5e 100644 --- a/sys/windivert.c +++ b/sys/windivert.c @@ -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); } /*