diff --git a/dll/win32/kernel32/client/proc.c b/dll/win32/kernel32/client/proc.c index b44624c..802bf34 100644 --- a/dll/win32/kernel32/client/proc.c +++ b/dll/win32/kernel32/client/proc.c @@ -1657,7 +1657,7 @@ WINAPI GetPriorityClass(IN HANDLE hProcess) { NTSTATUS Status; - PROCESS_PRIORITY_CLASS PriorityClass; + PROCESS_PRIORITY_CLASS DECLSPEC_ALIGN(4) PriorityClass; /* Query the kernel */ Status = NtQueryInformationProcess(hProcess, @@ -1681,7 +1681,7 @@ GetPriorityClass(IN HANDLE hProcess) /* Failure path */ BaseSetLastNTError(Status); - return FALSE; + return 0; } /* diff --git a/drivers/network/tcpip/include/tcp.h b/drivers/network/tcpip/include/tcp.h index 6bb8280..65a5d11 100644 --- a/drivers/network/tcpip/include/tcp.h +++ b/drivers/network/tcpip/include/tcp.h @@ -201,13 +201,13 @@ VOID FlushConnectQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status); VOID -FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked); +FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status); VOID -FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked); +FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status); VOID -FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked); +FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status); VOID FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status); diff --git a/drivers/network/tcpip/include/titypes.h b/drivers/network/tcpip/include/titypes.h index 3f75976..0290c2d 100644 --- a/drivers/network/tcpip/include/titypes.h +++ b/drivers/network/tcpip/include/titypes.h @@ -29,44 +29,26 @@ } /* - * VOID LockObject(PVOID Object, PKIRQL OldIrql) + * VOID LockObject(PVOID Object) */ -#define LockObject(Object, Irql) \ -{ \ - ReferenceObject(Object); \ - KeAcquireSpinLock(&((Object)->Lock), Irql); \ - memcpy(&(Object)->OldIrql, Irql, sizeof(KIRQL)); \ -} - -/* - * VOID LockObjectAtDpcLevel(PVOID Object) - */ -#define LockObjectAtDpcLevel(Object) \ -{ \ - ReferenceObject(Object); \ - KeAcquireSpinLockAtDpcLevel(&((Object)->Lock)); \ - (Object)->OldIrql = DISPATCH_LEVEL; \ -} +#define LockObject(Object) do \ +{ \ + ReferenceObject(Object); \ + KeEnterCriticalRegion(); \ + ExAcquireResourceExclusiveLite(&(Object)->Resource, TRUE); \ +} while(0) /* - * VOID UnlockObject(PVOID Object, KIRQL OldIrql) + * VOID UnlockObject(PVOID Object) */ -#define UnlockObject(Object, OldIrql) \ +#define UnlockObject(Object) do \ { \ - KeReleaseSpinLock(&((Object)->Lock), OldIrql); \ + ExReleaseResourceLite(&(Object)->Resource); \ + KeLeaveCriticalRegion(); \ DereferenceObject(Object); \ -} - -/* - * VOID UnlockObjectFromDpcLevel(PVOID Object) - */ -#define UnlockObjectFromDpcLevel(Object) \ -{ \ - KeReleaseSpinLockFromDpcLevel(&((Object)->Lock)); \ - DereferenceObject(Object); \ -} - +} while(0) +#define ASSERT_TCPIP_OBJECT_LOCKED(Object) ASSERT(ExIsResourceAcquiredExclusiveLite(&(Object)->Resource)) #include @@ -131,8 +113,7 @@ typedef struct _ADDRESS_FILE { LIST_ENTRY ListEntry; /* Entry on list */ LONG RefCount; /* Reference count */ OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */ - KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */ - KIRQL OldIrql; /* Currently not used */ + ERESOURCE Resource; /* Resource to manipulate this structure */ IP_ADDRESS Address; /* Address of this address file */ USHORT Family; /* Address family */ USHORT Protocol; /* Protocol number */ @@ -142,7 +123,6 @@ typedef struct _ADDRESS_FILE { UINT DF; /* Don't fragment */ UINT BCast; /* Receive broadcast packets */ UINT HeaderIncl; /* Include header in RawIP packets */ - WORK_QUEUE_ITEM WorkItem; /* Work queue item handle */ DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine for delete request */ PVOID Context; /* Delete request context */ DATAGRAM_SEND_ROUTINE Send; /* Routine to send a datagram */ @@ -262,8 +242,7 @@ typedef struct _CONNECTION_ENDPOINT { LIST_ENTRY ListEntry; /* Entry on list */ LONG RefCount; /* Reference count */ OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */ - KSPIN_LOCK Lock; /* Spin lock to protect this structure */ - KIRQL OldIrql; /* The old irql is stored here for use in HandleSignalledConnection */ + ERESOURCE Resource; /* The lock protecting this structure */ PVOID ClientContext; /* Pointer to client context information */ PADDRESS_FILE AddressFile; /* Associated address file object (NULL if none) */ @@ -275,10 +254,11 @@ typedef struct _CONNECTION_ENDPOINT { LIST_ENTRY ShutdownRequest;/* Queued shutdown requests */ LIST_ENTRY PacketQueue; /* Queued received packets waiting to be processed */ - + /* Disconnect Timer */ KTIMER DisconnectTimer; KDPC DisconnectDpc; + PIO_WORKITEM DisconnectWorkItem; /* Socket state */ BOOLEAN SendShutdown; diff --git a/drivers/network/tcpip/tcpip/ainfo.c b/drivers/network/tcpip/tcpip/ainfo.c index bba0aff..1553149 100644 --- a/drivers/network/tcpip/tcpip/ainfo.c +++ b/drivers/network/tcpip/tcpip/ainfo.c @@ -13,17 +13,15 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID, PVOID Buffer, UINT BufferSize) { - KIRQL OldIrql; - switch (ID->toi_id) { case AO_OPTION_TTL: if (BufferSize < sizeof(UINT)) return TDI_INVALID_PARAMETER; - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); AddrFile->TTL = *((PUCHAR)Buffer); - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return TDI_SUCCESS; @@ -31,9 +29,9 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID, if (BufferSize < sizeof(UINT)) return TDI_INVALID_PARAMETER; - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); AddrFile->DF = *((PUINT)Buffer); - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return TDI_SUCCESS; @@ -41,9 +39,9 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID, if (BufferSize < sizeof(UINT)) return TDI_INVALID_PARAMETER; - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); AddrFile->BCast = *((PUINT)Buffer); - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return TDI_SUCCESS; @@ -51,9 +49,9 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID, if (BufferSize < sizeof(UINT)) return TDI_INVALID_PARAMETER; - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); AddrFile->HeaderIncl = *((PUINT)Buffer); - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return TDI_SUCCESS; diff --git a/drivers/network/tcpip/tcpip/dispatch.c b/drivers/network/tcpip/tcpip/dispatch.c index bb3625c..97e8681 100644 --- a/drivers/network/tcpip/tcpip/dispatch.c +++ b/drivers/network/tcpip/tcpip/dispatch.c @@ -284,7 +284,6 @@ NTSTATUS DispTdiAssociateAddress( PFILE_OBJECT FileObject; PADDRESS_FILE AddrFile = NULL; NTSTATUS Status; - KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -319,18 +318,18 @@ NTSTATUS DispTdiAssociateAddress( return STATUS_INVALID_PARAMETER; } - LockObject(Connection, &OldIrql); + LockObject(Connection); if (Connection->AddressFile) { ObDereferenceObject(FileObject); - UnlockObject(Connection, OldIrql); + UnlockObject(Connection); TI_DbgPrint(MID_TRACE, ("An address file is already associated.\n")); return STATUS_INVALID_PARAMETER; } if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { ObDereferenceObject(FileObject); - UnlockObject(Connection, OldIrql); + UnlockObject(Connection); TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n", FileObject->FsContext2)); return STATUS_INVALID_PARAMETER; @@ -341,20 +340,20 @@ NTSTATUS DispTdiAssociateAddress( TranContext = FileObject->FsContext; if (!TranContext) { ObDereferenceObject(FileObject); - UnlockObject(Connection, OldIrql); + UnlockObject(Connection); TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); return STATUS_INVALID_PARAMETER; } AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; if (!AddrFile) { - UnlockObject(Connection, OldIrql); + UnlockObject(Connection); ObDereferenceObject(FileObject); TI_DbgPrint(MID_TRACE, ("No address file object.\n")); return STATUS_INVALID_PARAMETER; } - LockObjectAtDpcLevel(AddrFile); + LockObject(AddrFile); ReferenceObject(AddrFile); Connection->AddressFile = AddrFile; @@ -373,8 +372,8 @@ NTSTATUS DispTdiAssociateAddress( ObDereferenceObject(FileObject); - UnlockObjectFromDpcLevel(AddrFile); - UnlockObject(Connection, OldIrql); + UnlockObject(AddrFile); + UnlockObject(Connection); return STATUS_SUCCESS; } @@ -563,7 +562,6 @@ NTSTATUS DispTdiListen( PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; NTSTATUS Status = STATUS_SUCCESS; - KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -596,17 +594,17 @@ NTSTATUS DispTdiListen( Irp, (PDRIVER_CANCEL)DispCancelListenRequest); - LockObject(Connection, &OldIrql); + LockObject(Connection); if (Connection->AddressFile == NULL) { TI_DbgPrint(MID_TRACE, ("No associated address file\n")); - UnlockObject(Connection, OldIrql); + UnlockObject(Connection); Status = STATUS_INVALID_PARAMETER; goto done; } - LockObjectAtDpcLevel(Connection->AddressFile); + LockObject(Connection->AddressFile); /* Listening will require us to create a listening socket and store it in * the address file. It will be signalled, and attempt to complete an irp @@ -647,8 +645,8 @@ NTSTATUS DispTdiListen( Irp ); } - UnlockObjectFromDpcLevel(Connection->AddressFile); - UnlockObject(Connection, OldIrql); + UnlockObject(Connection->AddressFile); + UnlockObject(Connection); done: if (Status != STATUS_PENDING) { @@ -1104,7 +1102,6 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp) PIO_STACK_LOCATION IrpSp; PADDRESS_FILE AddrFile; NTSTATUS Status; - KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -1127,7 +1124,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp) Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters; Status = STATUS_SUCCESS; - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); /* Set the event handler. if an event handler is associated with a specific event, it's flag (RegisteredXxxHandler) is TRUE. @@ -1248,7 +1245,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp) Status = STATUS_INVALID_PARAMETER; } - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return Status; } diff --git a/drivers/network/tcpip/tcpip/fileobjs.c b/drivers/network/tcpip/tcpip/fileobjs.c index 614f1e1..d926abe 100644 --- a/drivers/network/tcpip/tcpip/fileobjs.c +++ b/drivers/network/tcpip/tcpip/fileobjs.c @@ -42,7 +42,7 @@ PADDRESS_FILE AddrSearchFirst( PAF_SEARCH SearchContext) { KIRQL OldIrql; - + SearchContext->Address = Address; SearchContext->Port = Port; SearchContext->Protocol = Protocol; @@ -115,7 +115,7 @@ LogActiveObjects(VOID) PCONNECTION_ENDPOINT Conn; DbgPrint("----------- TCP/IP Active Object Dump -------------\n"); - + TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql); CurrentEntry = AddressFileListHead.Flink; @@ -144,19 +144,19 @@ LogActiveObjects(VOID) } DbgPrint("\n"); } - + CurrentEntry = CurrentEntry->Flink; } - + TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); - + TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); - + CurrentEntry = ConnectionEndpointListHead.Flink; while (CurrentEntry != &ConnectionEndpointListHead) { Conn = CONTAINING_RECORD(CurrentEntry, CONNECTION_ENDPOINT, ListEntry); - + DbgPrint("Connection @ 0x%p | Ref count: %d\n", Conn, Conn->RefCount); DbgPrint("\tPCB: "); if (Conn->SocketContext == NULL) @@ -177,10 +177,10 @@ LogActiveObjects(VOID) DbgPrint("\tReceive shutdown: %s\n", Conn->ReceiveShutdown ? "Yes" : "No"); if (Conn->ReceiveShutdown) DbgPrint("\tReceive shutdown status: 0x%x\n", Conn->ReceiveShutdownStatus); DbgPrint("\tClosing: %s\n", Conn->Closing ? "Yes" : "No"); - + CurrentEntry = CurrentEntry->Flink; } - + TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); DbgPrint("---------------------------------------------------\n"); @@ -237,7 +237,7 @@ PADDRESS_FILE AddrSearchNext( PADDRESS_FILE Current = NULL; BOOLEAN Found = FALSE; PADDRESS_FILE StartingAddrFile; - + TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql); if (SearchContext->Next == &AddressFileListHead) @@ -310,7 +310,7 @@ VOID AddrFileFree( PADDRESS_FILE AddrFile = Object; KIRQL OldIrql; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; - PDATAGRAM_SEND_REQUEST SendRequest; + // PDATAGRAM_SEND_REQUEST SendRequest; See WTF below PLIST_ENTRY CurrentEntry; TI_DbgPrint(MID_TRACE, ("Called.\n")); @@ -330,20 +330,26 @@ VOID AddrFileFree( TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile)); /* Go through pending receive request list and cancel them all */ - while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { + while (!IsListEmpty(&AddrFile->ReceiveQueue)) + { + CurrentEntry = RemoveHeadList(&AddrFile->ReceiveQueue); ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry); (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0); - /* ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); FIXME: WTF? */ + ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); } TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile)); +#if 0 /* Biggest WTF. All of this was taken care of above as DATAGRAM_RECEIVE_REQUEST. */ /* Go through pending send request list and cancel them all */ - while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { + while (!IsListEmpty(&AddrFile->ReceiveQueue)) + { + CurrentEntry = RemoveHeadList(&AddrFile->ReceiveQueue); SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry); (*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0); ExFreePoolWithTag(SendRequest, DATAGRAM_SEND_TAG); } +#endif /* Protocol specific handling */ switch (AddrFile->Protocol) { @@ -361,6 +367,8 @@ VOID AddrFileFree( RemoveEntityByContext(AddrFile); + ExDeleteResourceLite(&AddrFile->Resource); + ExFreePoolWithTag(Object, ADDR_FILE_TAG); } @@ -465,14 +473,14 @@ NTSTATUS FileOpenAddress( { /* The client specified an explicit port so we force a bind to this */ AddrFile->Port = TCPAllocatePort(Address->Address[0].Address[0].sin_port); - + /* Check for bind success */ if (AddrFile->Port == 0xffff) { ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); return STATUS_ADDRESS_ALREADY_EXISTS; } - + /* Sanity check */ ASSERT(Address->Address[0].Address[0].sin_port == AddrFile->Port); } @@ -480,7 +488,7 @@ NTSTATUS FileOpenAddress( { /* The client is trying to bind to a local address so allocate a port now too */ AddrFile->Port = TCPAllocatePort(0); - + /* Check for bind success */ if (AddrFile->Port == 0xffff) { @@ -553,7 +561,7 @@ NTSTATUS FileOpenAddress( InitializeListHead(&AddrFile->TransmitQueue); /* Initialize spin lock that protects the address file object */ - KeInitializeSpinLock(&AddrFile->Lock); + ExInitializeResourceLite(&AddrFile->Resource); /* Return address file object */ Request->Handle.AddressHandle = AddrFile; @@ -581,27 +589,27 @@ NTSTATUS FileCloseAddress( PTDI_REQUEST Request) { PADDRESS_FILE AddrFile = Request->Handle.AddressHandle; - KIRQL OldIrql; + PCONNECTION_ENDPOINT Listener; if (!Request->Handle.AddressHandle) return STATUS_INVALID_PARAMETER; - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); if (InterlockedDecrement(&AddrFile->Sharers) != 0) { /* Still other guys have open handles to this, so keep it around */ - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return STATUS_SUCCESS; } /* We have to close this listener because we started it */ - if( AddrFile->Listener ) + Listener = AddrFile->Listener; + UnlockObject(AddrFile); + if( Listener ) { - TCPClose( AddrFile->Listener ); + TCPClose( Listener ); } - UnlockObject(AddrFile, OldIrql); - DereferenceObject(AddrFile); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); diff --git a/drivers/network/tcpip/tcpip/icmp.c b/drivers/network/tcpip/tcpip/icmp.c index 7603e25..67d77c1 100644 --- a/drivers/network/tcpip/tcpip/icmp.c +++ b/drivers/network/tcpip/tcpip/icmp.c @@ -74,11 +74,9 @@ VOID ClearReceiveHandler( _In_ PADDRESS_FILE AddrFile) { - KIRQL OldIrql; - - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); AddrFile->RegisteredReceiveDatagramHandler = FALSE; - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); } IO_WORKITEM_ROUTINE EndRequestHandler; @@ -95,6 +93,8 @@ EndRequestHandler( UINT32 nReplies; KIRQL OldIrql; + ClearReceiveHandler((PADDRESS_FILE)Context->TdiRequest.Handle.AddressHandle); + KeWaitForSingleObject(&Context->DatagramProcessedEvent, Executive, KernelMode, FALSE, NULL); TI_DbgPrint(DEBUG_ICMP, ("Finishing request Context: %p\n", Context)); @@ -267,8 +267,6 @@ TimeoutHandler( _In_opt_ PVOID SystemArgument2) { PICMP_PACKET_CONTEXT Context = (PICMP_PACKET_CONTEXT)_Context; - PADDRESS_FILE AddrFile = (PADDRESS_FILE)Context->TdiRequest.Handle.AddressHandle; - ClearReceiveHandler(AddrFile); IoQueueWorkItem(Context->FinishWorker, &EndRequestHandler, DelayedWorkQueue, _Context); } @@ -290,7 +288,6 @@ DispEchoRequest( PUCHAR Buffer; UINT16 RequestSize; PICMP_PACKET_CONTEXT SendContext; - KIRQL OldIrql; LARGE_INTEGER RequestTimeout; UINT8 SavedTtl; @@ -390,14 +387,14 @@ DispEchoRequest( RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, OutputBufferLength); - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); AddrFile->TTL = SavedTtl; AddrFile->ReceiveDatagramHandlerContext = SendContext; AddrFile->ReceiveDatagramHandler = ReceiveDatagram; AddrFile->RegisteredReceiveDatagramHandler = TRUE; - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); Status = AddrFile->Send(AddrFile, &ConnectionInfo, (PCHAR)Buffer, RequestSize, &DataUsed); diff --git a/sdk/lib/drivers/ip/transport/datagram/datagram.c b/sdk/lib/drivers/ip/transport/datagram/datagram.c index 13acca1..2840dc9 100644 --- a/sdk/lib/drivers/ip/transport/datagram/datagram.c +++ b/sdk/lib/drivers/ip/transport/datagram/datagram.c @@ -16,15 +16,14 @@ BOOLEAN DGRemoveIRP( { PLIST_ENTRY ListEntry; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; - KIRQL OldIrql; BOOLEAN Found = FALSE; TI_DbgPrint(MAX_TRACE, ("Called (Cancel IRP %08x for file %08x).\n", Irp, AddrFile)); - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); - for( ListEntry = AddrFile->ReceiveQueue.Flink; + for( ListEntry = AddrFile->ReceiveQueue.Flink; ListEntry != &AddrFile->ReceiveQueue; ListEntry = ListEntry->Flink ) { @@ -42,7 +41,7 @@ BOOLEAN DGRemoveIRP( } } - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); TI_DbgPrint(MAX_TRACE, ("Done.\n")); @@ -73,7 +72,6 @@ DGDeliverData( * handler if it exists, otherwise we drop the packet. */ { - KIRQL OldIrql; LONG AddressLength; PVOID SourceAddress; ULONG BytesTaken; @@ -82,13 +80,13 @@ DGDeliverData( TI_DbgPrint(MIN_TRACE, ("Called.\n")); - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); if (AddrFile->Protocol == IPPROTO_UDP) { DataBuffer = IPPacket->Data; } - else if (AddrFile->HeaderIncl) + else if (AddrFile->HeaderIncl) { DataBuffer = IPPacket->Header; } @@ -145,7 +143,7 @@ DGDeliverData( SrcAddress->Address.IPv4Address, SrcPort)); ReferenceObject(AddrFile); - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); /* Complete the receive request */ if (Current->BufferSize < DataSize) @@ -153,12 +151,12 @@ DGDeliverData( else Current->Complete(Current->Context, STATUS_SUCCESS, DataSize); - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); DereferenceObject(AddrFile); } } - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); } else if (AddrFile->RegisteredReceiveDatagramHandler) { @@ -186,7 +184,7 @@ DGDeliverData( } ReferenceObject(AddrFile); - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); TI_DbgPrint(MIN_TRACE, ("OptionsSize %d DataSize: %u\n", OptionsSize, DataSize)); @@ -209,7 +207,7 @@ DGDeliverData( } else { - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n")); } @@ -254,11 +252,10 @@ NTSTATUS DGReceiveDatagram( { NTSTATUS Status; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; - KIRQL OldIrql; TI_DbgPrint(MAX_TRACE, ("Called.\n")); - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); ReceiveRequest = ExAllocatePoolWithTag(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST), DATAGRAM_RECV_TAG); @@ -276,7 +273,7 @@ NTSTATUS DGReceiveDatagram( if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return Status; } } @@ -304,13 +301,13 @@ NTSTATUS DGReceiveDatagram( TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest)); - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return STATUS_PENDING; } else { - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); Status = STATUS_INSUFFICIENT_RESOURCES; } diff --git a/sdk/lib/drivers/ip/transport/rawip/rawip.c b/sdk/lib/drivers/ip/transport/rawip/rawip.c index 7e7fb22..cb32d4b 100644 --- a/sdk/lib/drivers/ip/transport/rawip/rawip.c +++ b/sdk/lib/drivers/ip/transport/rawip/rawip.c @@ -191,9 +191,8 @@ NTSTATUS RawIPSendDatagram( USHORT RemotePort; NTSTATUS Status; PNEIGHBOR_CACHE_ENTRY NCE; - KIRQL OldIrql; - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -208,7 +207,7 @@ NTSTATUS RawIPSendDatagram( break; default: - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return STATUS_UNSUCCESSFUL; } @@ -222,7 +221,7 @@ NTSTATUS RawIPSendDatagram( * interface we're sending over */ if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return STATUS_NETWORK_UNREACHABLE; } @@ -231,7 +230,7 @@ NTSTATUS RawIPSendDatagram( else { if(!(NCE = NBLocateNeighbor( &LocalAddress, NULL ))) { - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return STATUS_INVALID_PARAMETER; } } @@ -245,7 +244,7 @@ NTSTATUS RawIPSendDatagram( BufferData, DataSize ); - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); if( !NT_SUCCESS(Status) ) return Status; diff --git a/sdk/lib/drivers/ip/transport/tcp/accept.c b/sdk/lib/drivers/ip/transport/tcp/accept.c index ab47b9d..19b6d46 100644 --- a/sdk/lib/drivers/ip/transport/tcp/accept.c +++ b/sdk/lib/drivers/ip/transport/tcp/accept.c @@ -22,23 +22,23 @@ NTSTATUS TCPCheckPeerForAccept(PVOID Context, PTDI_CONNECTION_INFORMATION WhoIsConnecting; PTA_IP_ADDRESS RemoteAddress; struct ip_addr ipaddr; - + if (Request->RequestFlags & TDI_QUERY_ACCEPT) DbgPrint("TDI_QUERY_ACCEPT NOT SUPPORTED!!!\n"); WhoIsConnecting = (PTDI_CONNECTION_INFORMATION)Request->ReturnConnectionInformation; RemoteAddress = (PTA_IP_ADDRESS)WhoIsConnecting->RemoteAddress; - + RemoteAddress->TAAddressCount = 1; RemoteAddress->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; RemoteAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; - + Status = TCPTranslateError(LibTCPGetPeerName(newpcb, &ipaddr, &RemoteAddress->Address[0].Address[0].sin_port)); - + RemoteAddress->Address[0].Address[0].in_addr = ipaddr.addr; - + return Status; } @@ -48,12 +48,11 @@ NTSTATUS TCPListen(PCONNECTION_ENDPOINT Connection, UINT Backlog) { NTSTATUS Status = STATUS_SUCCESS; struct ip_addr AddressToBind; - KIRQL OldIrql; TA_IP_ADDRESS LocalAddress; ASSERT(Connection); - LockObject(Connection, &OldIrql); + LockObject(Connection); ASSERT_KM_POINTER(Connection->AddressFile); @@ -61,7 +60,7 @@ NTSTATUS TCPListen(PCONNECTION_ENDPOINT Connection, UINT Backlog) TI_DbgPrint(DEBUG_TCP, ("Connection->SocketContext %x\n", Connection->SocketContext)); - + AddressToBind.addr = Connection->AddressFile->Address.Address.IPv4Address; Status = TCPTranslateError(LibTCPBind(Connection, @@ -79,7 +78,7 @@ NTSTATUS TCPListen(PCONNECTION_ENDPOINT Connection, UINT Backlog) { /* Allocate the port in the port bitmap */ Connection->AddressFile->Port = TCPAllocatePort(LocalAddress.Address[0].Address[0].sin_port); - + /* This should never fail */ ASSERT(Connection->AddressFile->Port != 0xFFFF); } @@ -93,7 +92,7 @@ NTSTATUS TCPListen(PCONNECTION_ENDPOINT Connection, UINT Backlog) Status = STATUS_UNSUCCESSFUL; } - UnlockObject(Connection, OldIrql); + UnlockObject(Connection); TI_DbgPrint(DEBUG_TCP,("[IP, TCPListen] Leaving. Status = %x\n", Status)); @@ -106,10 +105,9 @@ BOOLEAN TCPAbortListenForSocket { PLIST_ENTRY ListEntry; PTDI_BUCKET Bucket; - KIRQL OldIrql; BOOLEAN Found = FALSE; - LockObject(Listener, &OldIrql); + LockObject(Listener); ListEntry = Listener->ListenRequest.Flink; while (ListEntry != &Listener->ListenRequest) @@ -128,7 +126,7 @@ BOOLEAN TCPAbortListenForSocket ListEntry = ListEntry->Flink; } - UnlockObject(Listener, OldIrql); + UnlockObject(Listener); return Found; } @@ -141,12 +139,11 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request, { NTSTATUS Status; PTDI_BUCKET Bucket; - KIRQL OldIrql; - LockObject(Listener, &OldIrql); + LockObject(Listener); Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList); - + if (Bucket) { Bucket->AssociatedEndpoint = Connection; @@ -160,7 +157,7 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request, else Status = STATUS_NO_MEMORY; - UnlockObject(Listener, OldIrql); + UnlockObject(Listener); return Status; } diff --git a/sdk/lib/drivers/ip/transport/tcp/event.c b/sdk/lib/drivers/ip/transport/tcp/event.c index 1d9918c..9294815 100644 --- a/sdk/lib/drivers/ip/transport/tcp/event.c +++ b/sdk/lib/drivers/ip/transport/tcp/event.c @@ -24,11 +24,11 @@ BucketCompletionWorker(PVOID Context) { PTDI_BUCKET Bucket = (PTDI_BUCKET)Context; PTCP_COMPLETION_ROUTINE Complete; - + Complete = (PTCP_COMPLETION_ROUTINE)Bucket->Request.RequestNotifyObject; - + Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information); - + DereferenceObject(Bucket->AssociatedEndpoint); ExFreeToNPagedLookasideList(&TdiBucketLookasideList, Bucket); @@ -50,125 +50,66 @@ CompleteBucket(PCONNECTION_ENDPOINT Connection, PTDI_BUCKET Bucket, const BOOLEA } VOID -FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked) +FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status) { PTDI_BUCKET Bucket; PLIST_ENTRY Entry; - - ReferenceObject(Connection); - - if (interlocked) - { - while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock))) - { - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - - TI_DbgPrint(DEBUG_TCP, - ("Completing Receive request: %x %x\n", - Bucket->Request, Status)); - - Bucket->Status = Status; - Bucket->Information = 0; - - CompleteBucket(Connection, Bucket, FALSE); - } - } - else + + ASSERT_TCPIP_OBJECT_LOCKED(Connection); + + while (!IsListEmpty(&Connection->ReceiveRequest)) { - while (!IsListEmpty(&Connection->ReceiveRequest)) - { - Entry = RemoveHeadList(&Connection->ReceiveRequest); - - Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry); - - Bucket->Information = 0; - Bucket->Status = Status; - - CompleteBucket(Connection, Bucket, FALSE); - } - } + Entry = RemoveHeadList(&Connection->ReceiveRequest); - DereferenceObject(Connection); + Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry); + + Bucket->Information = 0; + Bucket->Status = Status; + + CompleteBucket(Connection, Bucket, FALSE); + } } VOID -FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked) +FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status) { PTDI_BUCKET Bucket; PLIST_ENTRY Entry; - - ReferenceObject(Connection); - if (interlocked) - { - while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest, &Connection->Lock))) - { - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - - TI_DbgPrint(DEBUG_TCP, - ("Completing Send request: %x %x\n", - Bucket->Request, Status)); - - Bucket->Status = Status; - Bucket->Information = 0; - - CompleteBucket(Connection, Bucket, FALSE); - } - } - else + ASSERT_TCPIP_OBJECT_LOCKED(Connection); + + while (!IsListEmpty(&Connection->SendRequest)) { - while (!IsListEmpty(&Connection->SendRequest)) - { - Entry = RemoveHeadList(&Connection->SendRequest); - - Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry); - - Bucket->Information = 0; - Bucket->Status = Status; - - CompleteBucket(Connection, Bucket, FALSE); - } - } + Entry = RemoveHeadList(&Connection->SendRequest); - DereferenceObject(Connection); + Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry); + + Bucket->Information = 0; + Bucket->Status = Status; + + CompleteBucket(Connection, Bucket, FALSE); + } } VOID -FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked) +FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status) { PTDI_BUCKET Bucket; PLIST_ENTRY Entry; - - ReferenceObject(Connection); - if (interlocked) - { - while ((Entry = ExInterlockedRemoveHeadList(&Connection->ShutdownRequest, &Connection->Lock))) - { - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - - Bucket->Status = Status; - Bucket->Information = 0; - - CompleteBucket(Connection, Bucket, FALSE); - } - } - else + ASSERT_TCPIP_OBJECT_LOCKED(Connection); + + while (!IsListEmpty(&Connection->ShutdownRequest)) { - while (!IsListEmpty(&Connection->ShutdownRequest)) - { - Entry = RemoveHeadList(&Connection->ShutdownRequest); - - Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry); - - Bucket->Information = 0; - Bucket->Status = Status; - - CompleteBucket(Connection, Bucket, FALSE); - } - } + Entry = RemoveHeadList(&Connection->ShutdownRequest); - DereferenceObject(Connection); + Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry); + + Bucket->Information = 0; + Bucket->Status = Status; + + CompleteBucket(Connection, Bucket, FALSE); + } } VOID @@ -176,20 +117,19 @@ FlushConnectQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status) { PTDI_BUCKET Bucket; PLIST_ENTRY Entry; - - ReferenceObject(Connection); - while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest, &Connection->Lock))) + ASSERT_TCPIP_OBJECT_LOCKED(Connection); + + while (!IsListEmpty(&Connection->ConnectRequest)) { + Entry = RemoveHeadList(&Connection->ConnectRequest); Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - + Bucket->Status = Status; Bucket->Information = 0; - + CompleteBucket(Connection, Bucket, FALSE); } - - DereferenceObject(Connection); } VOID @@ -197,50 +137,45 @@ FlushListenQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status) { PTDI_BUCKET Bucket; PLIST_ENTRY Entry; - - ReferenceObject(Connection); - while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest, &Connection->Lock))) + ASSERT_TCPIP_OBJECT_LOCKED(Connection); + + while (!IsListEmpty(&Connection->ListenRequest)) { + Entry = RemoveHeadList(&Connection->ListenRequest); Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - + Bucket->Status = Status; Bucket->Information = 0; - + DereferenceObject(Bucket->AssociatedEndpoint); CompleteBucket(Connection, Bucket, FALSE); } - - DereferenceObject(Connection); } VOID FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status) -{ - ReferenceObject(Connection); - +{ // flush receive queue - FlushReceiveQueue(Connection, Status, TRUE); + FlushReceiveQueue(Connection, Status); /* We completed the reads successfully but we need to return failure now */ if (Status == STATUS_SUCCESS) { Status = STATUS_FILE_CLOSED; } - + // flush listen queue FlushListenQueue(Connection, Status); - + // flush send queue - FlushSendQueue(Connection, Status, TRUE); - + FlushSendQueue(Connection, Status); + // flush connect queue FlushConnectQueue(Connection, Status); // flush shutdown queue - FlushShutdownQueue(Connection, Status, TRUE); - - DereferenceObject(Connection); + FlushShutdownQueue(Connection, Status); } VOID @@ -248,18 +183,17 @@ TCPFinEventHandler(void *arg, const err_t err) { PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)arg, LastConnection; const NTSTATUS Status = TCPTranslateError(err); - KIRQL OldIrql; ASSERT(Connection->SocketContext == NULL); ASSERT(Connection->AddressFile); ASSERT(err != ERR_OK); + LockObject(Connection); + /* Complete all outstanding requests now */ FlushAllQueues(Connection, Status); - LockObject(Connection, &OldIrql); - - LockObjectAtDpcLevel(Connection->AddressFile); + LockObject(Connection->AddressFile); /* Unlink this connection from the address file */ if (Connection->AddressFile->Connection == Connection) @@ -284,15 +218,15 @@ TCPFinEventHandler(void *arg, const err_t err) } } - UnlockObjectFromDpcLevel(Connection->AddressFile); + UnlockObject(Connection->AddressFile); /* Remove the address file from this connection */ DereferenceObject(Connection->AddressFile); Connection->AddressFile = NULL; - UnlockObject(Connection, OldIrql); + UnlockObject(Connection); } - + VOID TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb) { @@ -301,49 +235,50 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb) PLIST_ENTRY Entry; PIRP Irp; NTSTATUS Status; - KIRQL OldIrql; - - ReferenceObject(Connection); - - while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest, &Connection->Lock))) + + LockObject(Connection); + + while (!IsListEmpty(&Connection->ListenRequest)) { PIO_STACK_LOCATION IrpSp; - + + Entry = RemoveHeadList(&Connection->ListenRequest); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - + Irp = Bucket->Request.RequestContext; IrpSp = IoGetCurrentIrpStackLocation( Irp ); - + TI_DbgPrint(DEBUG_TCP,("[IP, TCPAcceptEventHandler] Getting the socket\n")); - + Status = TCPCheckPeerForAccept(newpcb, (PTDI_REQUEST_KERNEL)&IrpSp->Parameters); - + TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n", Status)); - + Bucket->Status = Status; Bucket->Information = 0; - + if (Status == STATUS_SUCCESS) { - LockObject(Bucket->AssociatedEndpoint, &OldIrql); + LockObject(Bucket->AssociatedEndpoint); /* sanity assert...this should never be in anything else but a CLOSED state */ ASSERT( ((PTCP_PCB)Bucket->AssociatedEndpoint->SocketContext)->state == CLOSED ); - + /* free socket context created in FileOpenConnection, as we're using a new one */ LibTCPClose(Bucket->AssociatedEndpoint, TRUE, FALSE); /* free previously created socket context (we don't use it, we use newpcb) */ Bucket->AssociatedEndpoint->SocketContext = newpcb; - - LibTCPAccept(newpcb, (PTCP_PCB)Connection->SocketContext, Bucket->AssociatedEndpoint); - UnlockObject(Bucket->AssociatedEndpoint, OldIrql); + UnlockObject(Bucket->AssociatedEndpoint); + + LibTCPAccept(newpcb, (PTCP_PCB)Connection->SocketContext, Bucket->AssociatedEndpoint); } - + DereferenceObject(Bucket->AssociatedEndpoint); - + CompleteBucket(Connection, Bucket, FALSE); if (Status == STATUS_SUCCESS) @@ -351,8 +286,8 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb) break; } } - - DereferenceObject(Connection); + + UnlockObject(Connection); } VOID @@ -365,44 +300,48 @@ TCPSendEventHandler(void *arg, const u16_t space) NTSTATUS Status; PMDL Mdl; ULONG BytesSent; - + ReferenceObject(Connection); + LockObject(Connection); - while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest, &Connection->Lock))) + while (!IsListEmpty(&Connection->SendRequest)) { UINT SendLen = 0; PVOID SendBuffer = 0; - + + Entry = RemoveHeadList(&Connection->SendRequest); + + UnlockObject(Connection); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - + Irp = Bucket->Request.RequestContext; Mdl = Irp->MdlAddress; - + TI_DbgPrint(DEBUG_TCP, ("Getting the user buffer from %x\n", Mdl)); - + NdisQueryBuffer( Mdl, &SendBuffer, &SendLen ); - + TI_DbgPrint(DEBUG_TCP, ("Writing %d bytes to %x\n", SendLen, SendBuffer)); - + TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); TI_DbgPrint (DEBUG_TCP, ("Connection->SocketContext: %x\n", Connection->SocketContext)); - + Status = TCPTranslateError(LibTCPSend(Connection, SendBuffer, SendLen, &BytesSent, TRUE)); - + TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", BytesSent)); - + if( Status == STATUS_PENDING ) { - ExInterlockedInsertHeadList(&Connection->SendRequest, - &Bucket->Entry, - &Connection->Lock); + LockObject(Connection); + InsertHeadList(&Connection->SendRequest, &Bucket->Entry); break; } else @@ -410,26 +349,30 @@ TCPSendEventHandler(void *arg, const u16_t space) TI_DbgPrint(DEBUG_TCP, ("Completing Send request: %x %x\n", Bucket->Request, Status)); - + Bucket->Status = Status; Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ? BytesSent : 0; - + CompleteBucket(Connection, Bucket, FALSE); } + + LockObject(Connection); } // If we completed all outstanding send requests then finish all pending shutdown requests, // cancel the timer and dereference the connection if (IsListEmpty(&Connection->SendRequest)) { - FlushShutdownQueue(Connection, STATUS_SUCCESS, FALSE); + FlushShutdownQueue(Connection, STATUS_SUCCESS); if (KeCancelTimer(&Connection->DisconnectTimer)) { DereferenceObject(Connection); } } - + + UnlockObject(Connection); + DereferenceObject(Connection); } @@ -446,12 +389,13 @@ TCPRecvEventHandler(void *arg) PUCHAR RecvBuffer; NTSTATUS Status; - ReferenceObject(Connection); + LockObject(Connection); - while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock))) + while(!IsListEmpty(&Connection->ReceiveRequest)) { + Entry = RemoveHeadList(&Connection->ReceiveRequest); Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - + Irp = Bucket->Request.RequestContext; Mdl = Irp->MdlAddress; @@ -460,9 +404,7 @@ TCPRecvEventHandler(void *arg) Status = LibTCPGetDataFromConnectionQueue(Connection, RecvBuffer, RecvLen, &Received); if (Status == STATUS_PENDING) { - ExInterlockedInsertHeadList(&Connection->ReceiveRequest, - &Bucket->Entry, - &Connection->Lock); + InsertHeadList(&Connection->ReceiveRequest, &Bucket->Entry); break; } @@ -471,8 +413,7 @@ TCPRecvEventHandler(void *arg) CompleteBucket(Connection, Bucket, FALSE); } - - DereferenceObject(Connection); + UnlockObject(Connection); } VOID @@ -481,19 +422,20 @@ TCPConnectEventHandler(void *arg, const err_t err) PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)arg; PTDI_BUCKET Bucket; PLIST_ENTRY Entry; - - ReferenceObject(Connection); - - while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest, &Connection->Lock))) + + LockObject(Connection); + + while (!IsListEmpty(&Connection->ConnectRequest)) { - + Entry = RemoveHeadList(&Connection->ConnectRequest); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - + Bucket->Status = TCPTranslateError(err); Bucket->Information = 0; - + CompleteBucket(Connection, Bucket, FALSE); } - - DereferenceObject(Connection); + + UnlockObject(Connection); } diff --git a/sdk/lib/drivers/ip/transport/tcp/tcp.c b/sdk/lib/drivers/ip/transport/tcp/tcp.c index 675971b..f5304dd 100644 --- a/sdk/lib/drivers/ip/transport/tcp/tcp.c +++ b/sdk/lib/drivers/ip/transport/tcp/tcp.c @@ -25,50 +25,72 @@ PORT_SET TCPPorts; NPAGED_LOOKASIDE_LIST TdiBucketLookasideList; -VOID NTAPI -DisconnectTimeoutDpc(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) +static +IO_WORKITEM_ROUTINE +DisconnectWorker; + +#ifndef _Unreferenced_parameter_ /* stolen from newer sdk/include/psdk/specstrings.h */ +#define _Unreferenced_parameter_ _Const_ +#endif + +_Use_decl_annotations_ +VOID +NTAPI +DisconnectWorker( + _Unreferenced_parameter_ PDEVICE_OBJECT DeviceObject, + _In_ PVOID Context +) { - PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)DeferredContext; + PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)Context; PLIST_ENTRY Entry; PTDI_BUCKET Bucket; - LockObjectAtDpcLevel(Connection); - /* We timed out waiting for pending sends so force it to shutdown */ TCPTranslateError(LibTCPShutdown(Connection, 0, 1)); + LockObject(Connection); + while (!IsListEmpty(&Connection->SendRequest)) { Entry = RemoveHeadList(&Connection->SendRequest); - + Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry); - + Bucket->Information = 0; Bucket->Status = STATUS_FILE_CLOSED; - + CompleteBucket(Connection, Bucket, FALSE); } - + while (!IsListEmpty(&Connection->ShutdownRequest)) { Entry = RemoveHeadList( &Connection->ShutdownRequest ); - + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - + Bucket->Status = STATUS_TIMEOUT; Bucket->Information = 0; - + CompleteBucket(Connection, Bucket, FALSE); } - - UnlockObjectFromDpcLevel(Connection); - + + UnlockObject(Connection); + DereferenceObject(Connection); } +VOID +NTAPI +DisconnectTimeoutDpc(PKDPC Dpc, + PVOID DeferredContext, + PVOID SystemArgument1, + PVOID SystemArgument2) +{ + PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)DeferredContext; + + IoQueueWorkItem(Connection->DisconnectWorkItem, DisconnectWorker, DelayedWorkQueue, Connection); +} + VOID ConnectionFree(PVOID Object) { PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)Object; @@ -80,6 +102,9 @@ VOID ConnectionFree(PVOID Object) RemoveEntryList(&Connection->ListEntry); TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); + ExDeleteResourceLite(&Connection->Resource); + IoFreeWorkItem(Connection->DisconnectWorkItem); + ExFreePoolWithTag( Connection, CONN_ENDPT_TAG ); } @@ -96,7 +121,7 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT)); /* Initialize spin lock that protects the connection endpoint file object */ - KeInitializeSpinLock(&Connection->Lock); + ExInitializeResourceLite(&Connection->Resource); InitializeListHead(&Connection->ConnectRequest); InitializeListHead(&Connection->ListenRequest); InitializeListHead(&Connection->ReceiveRequest); @@ -107,6 +132,13 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) /* Initialize disconnect timer */ KeInitializeTimer(&Connection->DisconnectTimer); KeInitializeDpc(&Connection->DisconnectDpc, DisconnectTimeoutDpc, Connection); + Connection->DisconnectWorkItem = IoAllocateWorkItem(TCPDeviceObject); + if (!Connection->DisconnectWorkItem) + { + ExDeleteResourceLite(&Connection->Resource); + ExFreePoolWithTag( Connection, CONN_ENDPT_TAG ); + return NULL; + } /* Save client context pointer */ Connection->ClientContext = ClientContext; @@ -126,9 +158,8 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, UINT Family, UINT Type, UINT Proto ) { NTSTATUS Status; - KIRQL OldIrql; - LockObject(Connection, &OldIrql); + LockObject(Connection); TI_DbgPrint(DEBUG_TCP,("[IP, TCPSocket] Called: Connection %x, Family %d, Type %d, " "Proto %d, sizeof(CONNECTION_ENDPOINT) = %d\n", @@ -140,7 +171,7 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, else Status = STATUS_INSUFFICIENT_RESOURCES; - UnlockObject(Connection, OldIrql); + UnlockObject(Connection); TI_DbgPrint(DEBUG_TCP,("[IP, TCPSocket] Leaving. Status = 0x%x\n", Status)); @@ -149,15 +180,13 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, NTSTATUS TCPClose( PCONNECTION_ENDPOINT Connection ) { - KIRQL OldIrql; - - LockObject(Connection, &OldIrql); + LockObject(Connection); FlushAllQueues(Connection, STATUS_CANCELLED); - LibTCPClose(Connection, FALSE, TRUE); + UnlockObject(Connection); - UnlockObject(Connection, OldIrql); + LibTCPClose(Connection, FALSE, TRUE); DereferenceObject(Connection); @@ -176,7 +205,7 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket) TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to lwIP\n", IPPacket->TotalSize, IPPacket->HeaderSize)); - + LibIPInsertPacket(Interface->TCPContext, IPPacket->Header, IPPacket->TotalSize); } @@ -202,13 +231,13 @@ NTSTATUS TCPStartup(VOID) sizeof(TDI_BUCKET), TDI_BUCKET_TAG, 0); - + /* Initialize our IP library */ LibIPInitialize(); - + /* Register this protocol with IP layer */ IPRegisterProtocol(IPPROTO_TCP, TCPReceive); - + TCPInitialized = TRUE; return STATUS_SUCCESS; @@ -226,7 +255,7 @@ NTSTATUS TCPShutdown(VOID) return STATUS_SUCCESS; ExDeleteNPagedLookasideList(&TdiBucketLookasideList); - + LibIPShutdown(); /* Deregister this protocol with IP layer */ @@ -287,7 +316,6 @@ NTSTATUS TCPConnect TA_IP_ADDRESS LocalAddress; PTDI_BUCKET Bucket; PNEIGHBOR_CACHE_ENTRY NCE; - KIRQL OldIrql; TI_DbgPrint(DEBUG_TCP,("[IP, TCPConnect] Called\n")); @@ -308,11 +336,11 @@ NTSTATUS TCPConnect RemoteAddress.Address.IPv4Address, RemotePort)); - LockObject(Connection, &OldIrql); + LockObject(Connection); if (!Connection->AddressFile) { - UnlockObject(Connection, OldIrql); + UnlockObject(Connection); return STATUS_INVALID_PARAMETER; } @@ -320,7 +348,7 @@ NTSTATUS TCPConnect { if (!(NCE = RouteGetRouteToDestination(&RemoteAddress))) { - UnlockObject(Connection, OldIrql); + UnlockObject(Connection); return STATUS_NETWORK_UNREACHABLE; } @@ -334,49 +362,52 @@ NTSTATUS TCPConnect Status = TCPTranslateError(LibTCPBind(Connection, &bindaddr, Connection->AddressFile->Port)); - - if (NT_SUCCESS(Status)) + + if (!NT_SUCCESS(Status)) + { + UnlockObject(Connection); + return Status; + } + + /* Copy bind address into connection */ + Connection->AddressFile->Address.Address.IPv4Address = bindaddr.addr; + /* Check if we had an unspecified port */ + if (!Connection->AddressFile->Port) { - /* Copy bind address into connection */ - Connection->AddressFile->Address.Address.IPv4Address = bindaddr.addr; - /* Check if we had an unspecified port */ - if (!Connection->AddressFile->Port) + /* We did, so we need to copy back the port */ + Status = TCPGetSockAddress(Connection, (PTRANSPORT_ADDRESS)&LocalAddress, FALSE); + if (!NT_SUCCESS(Status)) { - /* We did, so we need to copy back the port */ - Status = TCPGetSockAddress(Connection, (PTRANSPORT_ADDRESS)&LocalAddress, FALSE); - if (NT_SUCCESS(Status)) - { - /* Allocate the port in the port bitmap */ - Connection->AddressFile->Port = TCPAllocatePort(LocalAddress.Address[0].Address[0].sin_port); - - /* This should never fail */ - ASSERT(Connection->AddressFile->Port != 0xFFFF); - } + UnlockObject(Connection); + return Status; } - if (NT_SUCCESS(Status)) - { - connaddr.addr = RemoteAddress.Address.IPv4Address; + /* Allocate the port in the port bitmap */ + Connection->AddressFile->Port = TCPAllocatePort(LocalAddress.Address[0].Address[0].sin_port); - Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList); - if (!Bucket) - { - UnlockObject(Connection, OldIrql); - return STATUS_NO_MEMORY; - } - - Bucket->Request.RequestNotifyObject = (PVOID)Complete; - Bucket->Request.RequestContext = Context; - - InsertTailList( &Connection->ConnectRequest, &Bucket->Entry ); - - Status = TCPTranslateError(LibTCPConnect(Connection, - &connaddr, - RemotePort)); - } + /* This should never fail */ + ASSERT(Connection->AddressFile->Port != 0xFFFF); } - UnlockObject(Connection, OldIrql); + connaddr.addr = RemoteAddress.Address.IPv4Address; + + Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList); + if (!Bucket) + { + UnlockObject(Connection); + return STATUS_NO_MEMORY; + } + + Bucket->Request.RequestNotifyObject = (PVOID)Complete; + Bucket->Request.RequestContext = Context; + + InsertTailList( &Connection->ConnectRequest, &Bucket->Entry ); + + UnlockObject(Connection); + + Status = TCPTranslateError(LibTCPConnect(Connection, + &connaddr, + RemotePort)); TI_DbgPrint(DEBUG_TCP,("[IP, TCPConnect] Leaving. Status = 0x%x\n", Status)); @@ -394,12 +425,11 @@ NTSTATUS TCPDisconnect { NTSTATUS Status = STATUS_INVALID_PARAMETER; PTDI_BUCKET Bucket; - KIRQL OldIrql; LARGE_INTEGER ActualTimeout; TI_DbgPrint(DEBUG_TCP,("[IP, TCPDisconnect] Called\n")); - LockObject(Connection, &OldIrql); + LockObject(Connection); if (Connection->SocketContext) { @@ -407,15 +437,23 @@ NTSTATUS TCPDisconnect { if (IsListEmpty(&Connection->SendRequest)) { + ReferenceObject(Connection); + UnlockObject(Connection); Status = TCPTranslateError(LibTCPShutdown(Connection, 0, 1)); + LockObject(Connection); + DereferenceObject(Connection); } else if (Timeout && Timeout->QuadPart == 0) { - FlushSendQueue(Connection, STATUS_FILE_CLOSED, FALSE); - TCPTranslateError(LibTCPShutdown(Connection, 0, 1)); + FlushSendQueue(Connection, STATUS_FILE_CLOSED); + ReferenceObject(Connection); + UnlockObject(Connection); + LibTCPShutdown(Connection, 0, 1); + LockObject(Connection); + DereferenceObject(Connection); Status = STATUS_TIMEOUT; } - else + else { /* Use the timeout specified or 1 second if none was specified */ if (Timeout) @@ -431,7 +469,7 @@ NTSTATUS TCPDisconnect Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList); if (!Bucket) { - UnlockObject(Connection, OldIrql); + UnlockObject(Connection); return STATUS_NO_MEMORY; } @@ -441,11 +479,11 @@ NTSTATUS TCPDisconnect InsertTailList(&Connection->ShutdownRequest, &Bucket->Entry); ReferenceObject(Connection); - if (KeCancelTimer(&Connection->DisconnectTimer)) + if (KeSetTimer(&Connection->DisconnectTimer, ActualTimeout, &Connection->DisconnectDpc)) { + /* Timer was already in the queue. */ DereferenceObject(Connection); } - KeSetTimer(&Connection->DisconnectTimer, ActualTimeout, &Connection->DisconnectDpc); Status = STATUS_PENDING; } @@ -453,20 +491,26 @@ NTSTATUS TCPDisconnect if ((Flags & TDI_DISCONNECT_ABORT) || !Flags) { - FlushReceiveQueue(Connection, STATUS_FILE_CLOSED, FALSE); - FlushSendQueue(Connection, STATUS_FILE_CLOSED, FALSE); - FlushShutdownQueue(Connection, STATUS_FILE_CLOSED, FALSE); + FlushReceiveQueue(Connection, STATUS_FILE_CLOSED); + FlushSendQueue(Connection, STATUS_FILE_CLOSED); + FlushShutdownQueue(Connection, STATUS_FILE_CLOSED); + ReferenceObject(Connection); + UnlockObject(Connection); Status = TCPTranslateError(LibTCPShutdown(Connection, 1, 1)); + DereferenceObject(Connection); + } + else + { + UnlockObject(Connection); } } else { + UnlockObject(Connection); /* We already got closed by the other side so just return success */ Status = STATUS_SUCCESS; } - UnlockObject(Connection, OldIrql); - TI_DbgPrint(DEBUG_TCP,("[IP, TCPDisconnect] Leaving. Status = 0x%x\n", Status)); return Status; @@ -502,11 +546,13 @@ NTSTATUS TCPReceiveData return STATUS_NO_MEMORY; } - + Bucket->Request.RequestNotifyObject = Complete; Bucket->Request.RequestContext = Context; - ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock ); + LockObject(Connection); + InsertTailList( &Connection->ReceiveRequest, &Bucket->Entry ); + UnlockObject(Connection); TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Queued read irp\n")); TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Leaving. Status = STATUS_PENDING\n")); @@ -532,9 +578,8 @@ NTSTATUS TCPSendData { NTSTATUS Status; PTDI_BUCKET Bucket; - KIRQL OldIrql; - LockObject(Connection, &OldIrql); + ReferenceObject(Connection); TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Called for %d bytes (on socket %x)\n", SendLength, Connection->SocketContext)); @@ -548,7 +593,7 @@ NTSTATUS TCPSendData SendLength, BytesSent, FALSE)); - + TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Send: %x, %d\n", Status, SendLength)); /* Keep this request around ... there was no data yet */ @@ -558,21 +603,23 @@ NTSTATUS TCPSendData Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList); if (!Bucket) { - UnlockObject(Connection, OldIrql); + DereferenceObject(Connection); TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Failed to allocate bucket\n")); return STATUS_NO_MEMORY; } - + Bucket->Request.RequestNotifyObject = Complete; Bucket->Request.RequestContext = Context; - + + LockObject(Connection); InsertTailList( &Connection->SendRequest, &Bucket->Entry ); TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Queued write irp\n")); + UnlockObject(Connection); } - UnlockObject(Connection, OldIrql); TI_DbgPrint(DEBUG_TCP, ("[IP, TCPSendData] Leaving. Status = %x\n", Status)); + DereferenceObject(Connection); return Status; } @@ -606,13 +653,12 @@ NTSTATUS TCPGetSockAddress PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address; struct ip_addr ipaddr; NTSTATUS Status; - KIRQL OldIrql; - + AddressIP->TAAddressCount = 1; AddressIP->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; AddressIP->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; - LockObject(Connection, &OldIrql); + LockObject(Connection); if (GetRemote) { @@ -627,10 +673,10 @@ NTSTATUS TCPGetSockAddress &AddressIP->Address[0].Address[0].sin_port)); } - UnlockObject(Connection, OldIrql); - + UnlockObject(Connection); + AddressIP->Address[0].Address[0].in_addr = ipaddr.addr; - + RtlZeroMemory(&AddressIP->Address[0].Address[0].sin_zero, sizeof(AddressIP->Address[0].Address[0].sin_zero)); @@ -641,7 +687,6 @@ BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { PLIST_ENTRY Entry; PLIST_ENTRY ListHead[5]; - KIRQL OldIrql; PTDI_BUCKET Bucket; UINT i = 0; BOOLEAN Found = FALSE; @@ -652,7 +697,7 @@ BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) ListHead[3] = &Endpoint->ListenRequest; ListHead[4] = &Endpoint->ShutdownRequest; - LockObject(Endpoint, &OldIrql); + LockObject(Endpoint); for( i = 0; i < 5; i++ ) { @@ -671,7 +716,7 @@ BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) } } - UnlockObject(Endpoint, OldIrql); + UnlockObject(Endpoint); return Found; } diff --git a/sdk/lib/drivers/ip/transport/udp/udp.c b/sdk/lib/drivers/ip/transport/udp/udp.c index 2f7dae9..0ad09fa 100644 --- a/sdk/lib/drivers/ip/transport/udp/udp.c +++ b/sdk/lib/drivers/ip/transport/udp/udp.c @@ -171,9 +171,8 @@ NTSTATUS UDPSendDatagram( USHORT RemotePort; NTSTATUS Status; PNEIGHBOR_CACHE_ENTRY NCE; - KIRQL OldIrql; - LockObject(AddrFile, &OldIrql); + LockObject(AddrFile); TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -188,7 +187,7 @@ NTSTATUS UDPSendDatagram( break; default: - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return STATUS_UNSUCCESSFUL; } @@ -200,7 +199,7 @@ NTSTATUS UDPSendDatagram( * interface we're sending over */ if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return STATUS_NETWORK_UNREACHABLE; } @@ -209,7 +208,7 @@ NTSTATUS UDPSendDatagram( else { if(!(NCE = NBLocateNeighbor( &LocalAddress, NULL ))) { - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); return STATUS_INVALID_PARAMETER; } } @@ -223,7 +222,7 @@ NTSTATUS UDPSendDatagram( BufferData, DataSize ); - UnlockObject(AddrFile, OldIrql); + UnlockObject(AddrFile); if( !NT_SUCCESS(Status) ) return Status; @@ -347,7 +346,7 @@ NTSTATUS UDPStartup( #ifdef __NTDRIVER__ RtlZeroMemory(&UDPStats, sizeof(UDP_STATISTICS)); #endif - + Status = PortsStartup( &UDPPorts, 1, UDP_STARTING_PORT + UDP_DYNAMIC_PORTS ); if( !NT_SUCCESS(Status) ) return Status; diff --git a/sdk/lib/drivers/lwip/src/include/rosip.h b/sdk/lib/drivers/lwip/src/include/rosip.h index 03aaf0c..701a656 100644 --- a/sdk/lib/drivers/lwip/src/include/rosip.h +++ b/sdk/lib/drivers/lwip/src/include/rosip.h @@ -25,13 +25,16 @@ struct lwip_callback_msg { /* Synchronization */ KEVENT Event; - + /* Input */ union { struct { PVOID Arg; } Socket; struct { + struct tcp_pcb* pcb; + } FreeSocket; + struct { PCONNECTION_ENDPOINT Connection; struct ip_addr *IpAddress; u16_t Port; @@ -60,7 +63,7 @@ struct lwip_callback_msg int Callback; } Close; } Input; - + /* Output */ union { struct { @@ -99,6 +102,7 @@ extern void TCPRecvEventHandler(void *arg); /* TCP functions */ PTCP_PCB LibTCPSocket(void *arg); +VOID LibTCPFreeSocket(PTCP_PCB pcb); err_t LibTCPBind(PCONNECTION_ENDPOINT Connection, struct ip_addr *const ipaddr, const u16_t port); PTCP_PCB LibTCPListen(PCONNECTION_ENDPOINT Connection, const u8_t backlog); err_t LibTCPSend(PCONNECTION_ENDPOINT Connection, void *const dataptr, const u16_t len, u32_t *sent, const int safe); diff --git a/sdk/lib/drivers/lwip/src/rostcp.c b/sdk/lib/drivers/lwip/src/rostcp.c index 8e22ccd..577a408 100644 --- a/sdk/lib/drivers/lwip/src/rostcp.c +++ b/sdk/lib/drivers/lwip/src/rostcp.c @@ -81,7 +81,9 @@ void LibTCPEnqueuePacket(PCONNECTION_ENDPOINT Connection, struct pbuf *p) qp->p = p; qp->Offset = 0; - ExInterlockedInsertTailList(&Connection->PacketQueue, &qp->ListEntry, &Connection->Lock); + LockObject(Connection); + InsertTailList(&Connection->PacketQueue, &qp->ListEntry); + UnlockObject(Connection); } PQUEUE_ENTRY LibTCPDequeuePacket(PCONNECTION_ENDPOINT Connection) @@ -104,11 +106,10 @@ NTSTATUS LibTCPGetDataFromConnectionQueue(PCONNECTION_ENDPOINT Connection, PUCHA struct pbuf* p; NTSTATUS Status; UINT ReadLength, PayloadLength, Offset, Copied; - KIRQL OldIrql; (*Received) = 0; - LockObject(Connection, &OldIrql); + LockObject(Connection); if (!IsListEmpty(&Connection->PacketQueue)) { @@ -132,13 +133,9 @@ NTSTATUS LibTCPGetDataFromConnectionQueue(PCONNECTION_ENDPOINT Connection, PUCHA qp = NULL; } - UnlockObject(Connection, OldIrql); - Copied = pbuf_copy_partial(p, RecvBuffer, ReadLength, Offset); ASSERT(Copied == ReadLength); - LockObject(Connection, &OldIrql); - /* Update trackers */ RecvLen -= ReadLength; RecvBuffer += ReadLength; @@ -172,7 +169,7 @@ NTSTATUS LibTCPGetDataFromConnectionQueue(PCONNECTION_ENDPOINT Connection, PUCHA Status = STATUS_PENDING; } - UnlockObject(Connection, OldIrql); + UnlockObject(Connection); return Status; } @@ -366,6 +363,33 @@ LibTCPSocket(void *arg) static void +LibTCPFreeSocketCallback(void *arg) +{ + struct lwip_callback_msg *msg = arg; + + ASSERT(msg); + + /* Calling tcp_close will free it */ + tcp_close(msg->Input.FreeSocket.pcb); + + KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE); +} + +void LibTCPFreeSocket(PTCP_PCB pcb) +{ + struct lwip_callback_msg msg; + + KeInitializeEvent(&msg.Event, NotificationEvent, FALSE); + msg.Input.FreeSocket.pcb = pcb; + + tcpip_callback_with_block(LibTCPFreeSocketCallback, &msg, 1); + + WaitForEventSafely(&msg.Event); +} + + +static +void LibTCPBindCallback(void *arg) { struct lwip_callback_msg *msg = arg;