mirror of
https://github.com/reactos/reactos.git
synced 2025-07-30 05:02:38 +00:00
[0.4.14][KERNEL32][TCPIP] A big squashed fix for CORE-16757 CORE-17596 CORE-17647 CORE-6473 (#3170)
The interesting kernel32 part is a port of 0.4.15-dev-2069-gfd8080b094
CORE-16757 'Task Manager failed to show process's priority' which I actually wanted to improve for 0.4.14. But if we took that on its own, then it would unhide CORE-17596 'Google Earth 7.1.8 regressed AGAIN by the same work' That's why we take with us: 0.4.15-dev-2766-g27fcfe66a2
(is also part of CORE-6473, I left the 2nd commit out that added an assert in NTOSKRNL) Small hack: this backport required me to define _Unreferenced_parameter_ myself in tcp.c stolen from newer sdk/include/psdk/specstrings.h. I didn't want to port back that entire file as well. In combination those two fixes allow both 'Google Earth and to change process priority' to be fixed within the same build. But I felt a bit more safe then by taking 0.4.15-dev-2793-g979b7d4d8e
with me as well, because I was too afraid, that I might otherwise introduce CORE-17647 'BSOD 0xc2 BAD_POOL_CALLER induced by networking, triggered by using KeePass 2.23' although I could not trigger that in practice when leaving that third commit out as an experiment. And since it was a safe no-brainer-fix, I couldn't resist to also pick 0.4.15-dev-764-g4aeb45ce0c
(#3170)
This commit is contained in:
parent
5917fa575b
commit
e7cfa907e9
16 changed files with 470 additions and 483 deletions
|
@ -215,7 +215,7 @@ ReassembleDatagram(
|
|||
RtlCopyMemory(&IPPacket->DstAddr, &IPDR->DstAddr, sizeof(IP_ADDRESS));
|
||||
|
||||
/* Allocate space for full IP datagram */
|
||||
IPPacket->Header = ExAllocatePoolWithTag(PagedPool, IPPacket->TotalSize, PACKET_BUFFER_TAG);
|
||||
IPPacket->Header = ExAllocatePoolWithTag(NonPagedPool, IPPacket->TotalSize, PACKET_BUFFER_TAG);
|
||||
if (!IPPacket->Header) {
|
||||
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
|
||||
(*IPPacket->Free)(IPPacket);
|
||||
|
@ -303,7 +303,7 @@ VOID ProcessFragment(
|
|||
TI_DbgPrint(DEBUG_IP, ("Continueing assembly.\n"));
|
||||
/* We have a reassembly structure */
|
||||
TcpipAcquireSpinLock(&IPDR->Lock, &OldIrql);
|
||||
|
||||
|
||||
/* Reset the timeout since we received a fragment */
|
||||
IPDR->TimeoutCount = 0;
|
||||
} else {
|
||||
|
@ -454,7 +454,7 @@ VOID ProcessFragment(
|
|||
Assemble the datagram and pass it to an upper layer protocol */
|
||||
|
||||
TI_DbgPrint(DEBUG_IP, ("Complete datagram received.\n"));
|
||||
|
||||
|
||||
RemoveIPDR(IPDR);
|
||||
TcpipReleaseSpinLock(&IPDR->Lock, OldIrql);
|
||||
|
||||
|
@ -539,7 +539,7 @@ VOID IPDatagramReassemblyTimeout(
|
|||
TcpipReleaseSpinLockFromDpcLevel(&CurrentIPDR->Lock);
|
||||
RemoveEntryList(CurrentEntry);
|
||||
FreeIPDR(CurrentIPDR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(CurrentIPDR->TimeoutCount < MAX_TIMEOUT_COUNT);
|
||||
|
@ -562,9 +562,9 @@ VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
|
|||
{
|
||||
UCHAR FirstByte;
|
||||
ULONG BytesCopied;
|
||||
|
||||
|
||||
TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n"));
|
||||
|
||||
|
||||
/* Read in the first IP header byte for size information */
|
||||
BytesCopied = CopyPacketToBuffer((PCHAR)&FirstByte,
|
||||
IPPacket->NdisPacket,
|
||||
|
@ -623,7 +623,7 @@ VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
|
|||
|
||||
AddrInitIPv4(&IPPacket->SrcAddr, ((PIPv4_HEADER)IPPacket->Header)->SrcAddr);
|
||||
AddrInitIPv4(&IPPacket->DstAddr, ((PIPv4_HEADER)IPPacket->Header)->DstAddr);
|
||||
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("IPPacket->Position = %d\n",
|
||||
IPPacket->Position));
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
DereferenceObject(Connection);
|
||||
ASSERT_TCPIP_OBJECT_LOCKED(Connection);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
ASSERT_TCPIP_OBJECT_LOCKED(Connection);
|
||||
|
||||
DereferenceObject(Connection);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
ASSERT_TCPIP_OBJECT_LOCKED(Connection);
|
||||
|
||||
DereferenceObject(Connection);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest, &Connection->Lock)))
|
||||
ReferenceObject(Connection);
|
||||
LockObject(Connection);
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -25,48 +25,70 @@ PORT_SET TCPPorts;
|
|||
|
||||
NPAGED_LOOKASIDE_LIST TdiBucketLookasideList;
|
||||
|
||||
VOID NTAPI
|
||||
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)Context;
|
||||
PLIST_ENTRY Entry;
|
||||
PTDI_BUCKET Bucket;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
UnlockObject(Connection);
|
||||
|
||||
DereferenceObject(Connection);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DisconnectTimeoutDpc(PKDPC Dpc,
|
||||
PVOID DeferredContext,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
{
|
||||
PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)DeferredContext;
|
||||
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));
|
||||
|
||||
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);
|
||||
|
||||
DereferenceObject(Connection);
|
||||
IoQueueWorkItem(Connection->DisconnectWorkItem, DisconnectWorker, DelayedWorkQueue, Connection);
|
||||
}
|
||||
|
||||
VOID ConnectionFree(PVOID 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))
|
||||
{
|
||||
/* 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))
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
connaddr.addr = RemoteAddress.Address.IPv4Address;
|
||||
|
||||
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));
|
||||
}
|
||||
UnlockObject(Connection);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UnlockObject(Connection, OldIrql);
|
||||
/* 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))
|
||||
{
|
||||
UnlockObject(Connection);
|
||||
return 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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue