diff --git a/reactos/drivers/network/tcpip/include/transmit.h b/reactos/drivers/network/tcpip/include/transmit.h index cef0b998742..2466f861aea 100644 --- a/reactos/drivers/network/tcpip/include/transmit.h +++ b/reactos/drivers/network/tcpip/include/transmit.h @@ -25,8 +25,8 @@ typedef struct IPFRAGMENT_CONTEXT { UINT BytesLeft; /* Number of bytes left to send */ UINT PathMTU; /* Path Maximum Transmission Unit */ PNEIGHBOR_CACHE_ENTRY NCE; /* Pointer to NCE to use */ - PIP_TRANSMIT_COMPLETE Complete; /* Completion Routine */ - PVOID Context; /* Completion Context */ + KEVENT Event; /* Signalled when the transmission is complete */ + NDIS_STATUS Status; /* Status of the transmission */ } IPFRAGMENT_CONTEXT, *PIPFRAGMENT_CONTEXT; diff --git a/reactos/lib/drivers/ip/network/transmit.c b/reactos/lib/drivers/ip/network/transmit.c index b97318223f2..076e5376e87 100644 --- a/reactos/lib/drivers/ip/network/transmit.c +++ b/reactos/lib/drivers/ip/network/transmit.c @@ -28,30 +28,14 @@ VOID IPSendComplete */ { PIPFRAGMENT_CONTEXT IFC = (PIPFRAGMENT_CONTEXT)Context; - NTSTATUS Status; TI_DbgPrint (MAX_TRACE, ("Called. Context (0x%X) NdisPacket (0x%X) NdisStatus (0x%X)\n", Context, NdisPacket, NdisStatus)); - - if (NT_SUCCESS(NdisStatus) && PrepareNextFragment(IFC)) { - /* A fragment was prepared for transmission, so send it */ - Status = IPSendFragment(IFC->NdisPacket, IFC->NCE, IFC); - if (!NT_SUCCESS(Status)) - { - FreeNdisPacket(IFC->NdisPacket); - IFC->Complete(IFC->Context, IFC->Datagram, Status); - ExFreePoolWithTag(IFC, IFC_TAG); - } - } else { - TI_DbgPrint(MAX_TRACE, ("Calling completion handler.\n")); - - /* There are no more fragments to transmit, so call completion handler */ - FreeNdisPacket(IFC->NdisPacket); - IFC->Complete(IFC->Context, IFC->Datagram, NdisStatus); - ExFreePoolWithTag(IFC, IFC_TAG); - } + + IFC->Status = NdisStatus; + KeSetEvent(&IFC->Event, 0, FALSE); } NTSTATUS IPSendFragment( @@ -202,8 +186,7 @@ NTSTATUS SendFragments( IFC->Position = 0; IFC->BytesLeft = IPPacket->TotalSize - IPPacket->HeaderSize; IFC->Data = (PVOID)((ULONG_PTR)IFC->Header + IPPacket->HeaderSize); - IFC->Complete = Complete; - IFC->Context = Context; + KeInitializeEvent(&IFC->Event, NotificationEvent, FALSE); TI_DbgPrint(MID_TRACE,("Copying header from %x to %x (%d)\n", IPPacket->Header, IFC->Header, @@ -211,20 +194,28 @@ NTSTATUS SendFragments( RtlCopyMemory( IFC->Header, IPPacket->Header, IPPacket->HeaderSize ); - /* Prepare next fragment for transmission and send it */ - - if (!PrepareNextFragment(IFC)) { - FreeNdisPacket(IFC->NdisPacket); - ExFreePoolWithTag(IFC, IFC_TAG); - return NDIS_STATUS_FAILURE; - } - - if (!NT_SUCCESS((NdisStatus = IPSendFragment(IFC->NdisPacket, NCE, IFC)))) + while (PrepareNextFragment(IFC)) { - FreeNdisPacket(IFC->NdisPacket); - ExFreePoolWithTag(IFC, IFC_TAG); + NdisStatus = IPSendFragment(IFC->NdisPacket, NCE, IFC); + if (NT_SUCCESS(NdisStatus)) + { + KeWaitForSingleObject(&IFC->Event, + Executive, + KernelMode, + FALSE, + NULL); + NdisStatus = IFC->Status; + } + + if (!NT_SUCCESS(NdisStatus)) + break; } + FreeNdisPacket(IFC->NdisPacket); + ExFreePoolWithTag(IFC, IFC_TAG); + + Complete(Context, IPPacket->NdisPacket, NdisStatus); + return NdisStatus; }