VOID
TCPFinEventHandler(void *arg, const err_t err)
{
- PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)arg, LastConnection;
- const NTSTATUS Status = TCPTranslateError(err);
- KIRQL OldIrql;
-
- ASSERT(Connection->AddressFile);
-
- /* Check if this was a partial socket closure */
- if (err == ERR_OK && Connection->SocketContext)
- {
- /* Just flush the receive queue and get out of here */
- FlushReceiveQueue(Connection, STATUS_SUCCESS, TRUE);
- }
- else
- {
- /* First off all, remove the PCB pointer */
- Connection->SocketContext = NULL;
-
- /* Complete all outstanding requests now */
- FlushAllQueues(Connection, Status);
-
- LockObject(Connection, &OldIrql);
-
- LockObjectAtDpcLevel(Connection->AddressFile);
-
- /* Unlink this connection from the address file */
- if (Connection->AddressFile->Connection == Connection)
- {
- Connection->AddressFile->Connection = Connection->Next;
- DereferenceObject(Connection);
- }
- else if (Connection->AddressFile->Listener == Connection)
- {
- Connection->AddressFile->Listener = NULL;
- DereferenceObject(Connection);
- }
- else
- {
- LastConnection = Connection->AddressFile->Connection;
- while (LastConnection->Next != Connection && LastConnection->Next != NULL)
- LastConnection = LastConnection->Next;
- if (LastConnection->Next == Connection)
- {
- LastConnection->Next = Connection->Next;
- DereferenceObject(Connection);
- }
- }
-
- UnlockObjectFromDpcLevel(Connection->AddressFile);
-
- /* Remove the address file from this connection */
- DereferenceObject(Connection->AddressFile);
- Connection->AddressFile = NULL;
-
- UnlockObject(Connection, OldIrql);
- }
+ PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)arg, LastConnection;
+ const NTSTATUS Status = TCPTranslateError(err);
+ KIRQL OldIrql;
+
+ ASSERT(Connection->AddressFile);
+ ASSERT(err != ERR_OK);
+
+ /* First off all, remove the PCB pointer */
+ Connection->SocketContext = NULL;
+
+ /* Complete all outstanding requests now */
+ FlushAllQueues(Connection, Status);
+
+ LockObject(Connection, &OldIrql);
+
+ LockObjectAtDpcLevel(Connection->AddressFile);
+
+ /* Unlink this connection from the address file */
+ if (Connection->AddressFile->Connection == Connection)
+ {
+ Connection->AddressFile->Connection = Connection->Next;
+ DereferenceObject(Connection);
+ }
+ else if (Connection->AddressFile->Listener == Connection)
+ {
+ Connection->AddressFile->Listener = NULL;
+ DereferenceObject(Connection);
+ }
+ else
+ {
+ LastConnection = Connection->AddressFile->Connection;
+ while (LastConnection->Next != Connection && LastConnection->Next != NULL)
+ LastConnection = LastConnection->Next;
+ if (LastConnection->Next == Connection)
+ {
+ LastConnection->Next = Connection->Next;
+ DereferenceObject(Connection);
+ }
+ }
+
+ UnlockObjectFromDpcLevel(Connection->AddressFile);
+
+ /* Remove the address file from this connection */
+ DereferenceObject(Connection->AddressFile);
+ Connection->AddressFile = NULL;
+
+ UnlockObject(Connection, OldIrql);
}
VOID