mirror of
https://github.com/reactos/reactos.git
synced 2024-05-16 02:01:59 +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
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)); \
|
||||
}
|
||||
#define LockObject(Object) do \
|
||||
{ \
|
||||
ReferenceObject(Object); \
|
||||
KeEnterCriticalRegion(); \
|
||||
ExAcquireResourceExclusiveLite(&(Object)->Resource, TRUE); \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* VOID LockObjectAtDpcLevel(PVOID Object)
|
||||
* VOID UnlockObject(PVOID Object)
|
||||
*/
|
||||
#define LockObjectAtDpcLevel(Object) \
|
||||
{ \
|
||||
ReferenceObject(Object); \
|
||||
KeAcquireSpinLockAtDpcLevel(&((Object)->Lock)); \
|
||||
(Object)->OldIrql = DISPATCH_LEVEL; \
|
||||
}
|
||||
|
||||
/*
|
||||
* VOID UnlockObject(PVOID Object, KIRQL OldIrql)
|
||||
*/
|
||||
#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 <ip.h>
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -25,12 +25,15 @@ 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;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -364,6 +361,33 @@ LibTCPSocket(void *arg)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue