Author: zhu
Date: Fri Jul  8 17:52:42 2016
New Revision: 71865

URL: http://svn.reactos.org/svn/reactos?rev=71865&view=rev
Log:
Structural, style, correctness fixes. 

Modified:
    branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c
    branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h
    branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c

Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c?rev=71865&r1=71864&r2=71865&view=diff
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c       
[iso-8859-1] (original)
+++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c       
[iso-8859-1] Fri Jul  8 17:52:42 2016
@@ -14,12 +14,12 @@
 
 typedef struct
 {
-    LIST_ENTRY ListEntry;
-    TDI_ADDRESS_IP RemoteAddress;
-    PIRP Irp;
-    PVOID Buffer;
-    ULONG BufferLength;
-    PTDI_CONNECTION_INFORMATION ReturnInfo;
+       LIST_ENTRY ListEntry;
+       TDI_ADDRESS_IP RemoteAddress;
+       PIRP Irp;
+       PVOID Buffer;
+       ULONG BufferLength;
+       PTDI_CONNECTION_INFORMATION ReturnInfo;
 } RECEIVE_DATAGRAM_REQUEST;
 
 /* The pool tags we will use for all of our allocation */
@@ -33,6 +33,8 @@
 static LIST_ENTRY AddressListHead;
 
 /* implementation in testing */
+/* Must already hold the Context->RequestListLock */
+/* Context should be in ->FileObject->FsContext */
 NTSTATUS
 PrepareIrpForCancel(
        PIRP Irp,
@@ -44,7 +46,6 @@
        PIO_STACK_LOCATION IrpSp;
        PTCP_CONTEXT Context;
        PTCP_REQUEST Request;
-       KIRQL OldIrql;
        NTSTATUS Status;
        
        DPRINT1("Prepare for cancel\n");
@@ -67,10 +68,8 @@
                Request->CancelMode = CancelMode;
                Request->PendingMode = PendingMode;
                
-               KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
                IoSetCancelRoutine(Irp, CancelRoutine);
                InsertTailList(&Context->RequestListHead, &Request->ListEntry);
-               KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
                
                Status = STATUS_SUCCESS;
                DPRINT1("Prepared for cancel\n");
@@ -143,6 +142,7 @@
                                        {
                                                AddressFile->lwip_tcp_pcb = 
NULL;
                                        }
+                                       tcp_arg(Context->lwip_tcp_pcb, NULL);
                                        tcp_abort(Context->lwip_tcp_pcb);
                                        InterlockedDecrement(&PcbCount);
                                        DPRINT1("\n    PCB Count: %d\n", 
PcbCount);
@@ -207,8 +207,8 @@
 void
 TcpIpInitializeAddresses(void)
 {
-    KeInitializeSpinLock(&AddressListLock);
-    InitializeListHead(&AddressListHead);
+       KeInitializeSpinLock(&AddressListLock);
+       InitializeListHead(&AddressListHead);
        
        PcbCount = 0;
 }
@@ -216,9 +216,9 @@
 static
 BOOLEAN
 AddrIsUnspecified(
-    _In_ PTDI_ADDRESS_IP Address)
-{
-    return ((Address->in_addr == 0) || (Address->in_addr == 0xFFFFFFFF));
+       _In_ PTDI_ADDRESS_IP Address)
+{
+       return ((Address->in_addr == 0) || (Address->in_addr == 0xFFFFFFFF));
 }
 
 /* Implementation in testing */
@@ -231,8 +231,8 @@
        PTCP_CONTEXT Context;
        PTCP_REQUEST Request;
        PLIST_ENTRY Head;
-       PLIST_ENTRY HeadNest;
-       PLIST_ENTRY EntryNest;
+       PLIST_ENTRY RequestHead;
+       PLIST_ENTRY RequestEntry;
        PLIST_ENTRY Entry;
        PLIST_ENTRY Temp;
        PIRP Irp;
@@ -267,11 +267,23 @@
        
        Status = STATUS_ADDRESS_CLOSED;
        
+       if (!arg)
+       {
+               DPRINT1("We did the cancelling ourselves, no need to worry 
about deallocations\n");
+               return;
+       }
+       
+       /* This switch relies on UCHAR Type being the first member in
+                       _ADDRESS_FILE
+                       _TCP_CONTEXT
+               This works assuming the compiler never adds padding before the 
first struct member
+               */
+       DPRINT1("Type: %08x\n", *((UCHAR*)arg));
        switch (*((UCHAR*)arg))
        {
                case TDI_TRANSPORT_ADDRESS_FILE :
                        AddressFile = (PADDRESS_FILE)arg;
-                       DPRINT1("AddressFile at %08x\n", AddressFile);
+                       DPRINT1("AddressFile at %p\n", AddressFile);
                        KeAcquireSpinLock(&AddressFile->ContextListLock, 
&OldIrql);
                        
                        Head = &AddressFile->ContextListHead;
@@ -281,11 +293,11 @@
                                Context = CONTAINING_RECORD(Entry, TCP_CONTEXT, 
ListEntry);
                                
KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock);
                                
-                               HeadNest = &Context->RequestListHead;
-                               EntryNest = HeadNest->Flink;
-                               while (EntryNest != HeadNest)
+                               RequestHead = &Context->RequestListHead;
+                               RequestEntry = RequestHead->Flink;
+                               while (RequestEntry != RequestHead)
                                {
-                                       Request = CONTAINING_RECORD(EntryNest, 
TCP_REQUEST, ListEntry);
+                                       Request = 
CONTAINING_RECORD(RequestEntry, TCP_REQUEST, ListEntry);
                                        Irp = Request->PendingIrp;
                                        if (Irp)
                                        {
@@ -298,16 +310,17 @@
                                                Irp->IoStatus.Information = 0;
                                                IoCompleteRequest(Irp, 
IO_NETWORK_INCREMENT);
                                        }
-                                       Temp = EntryNest->Flink;
-                                       RemoveEntryList(EntryNest);
+                                       Temp = RequestEntry->Flink;
+                                       RemoveEntryList(RequestEntry);
                                        ExFreePoolWithTag(Request, 
TAG_TCP_REQUEST);
-                                       EntryNest = Temp;
+                                       RequestEntry = Temp;
                                }
                                
                                
KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
                                
                                if (Context->lwip_tcp_pcb != 
AddressFile->lwip_tcp_pcb)
                                {
+                                       tcp_arg(Context->lwip_tcp_pcb, NULL);
                                        tcp_abort(Context->lwip_tcp_pcb);
                                        InterlockedDecrement(&PcbCount);
                                        DPRINT1("\n    PCB Count\n", PcbCount);
@@ -324,14 +337,14 @@
                        return;
                case TDI_CONNECTION_FILE :
                        Context = (PTCP_CONTEXT)arg;
-                       DPRINT1("AddressFile at %08x\n", Context->AddressFile);
+                       DPRINT1("AddressFile at %p\n", Context->AddressFile);
                        KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
                                
-                       HeadNest = &Context->RequestListHead;
-                       EntryNest = HeadNest->Flink;
-                       while (EntryNest != HeadNest)
+                       RequestHead = &Context->RequestListHead;
+                       RequestEntry = RequestHead->Flink;
+                       while (RequestEntry != RequestHead)
                        {
-                               Request = CONTAINING_RECORD(EntryNest, 
TCP_REQUEST, ListEntry);
+                               Request = CONTAINING_RECORD(RequestEntry, 
TCP_REQUEST, ListEntry);
                                Irp = Request->PendingIrp;
                                if (Irp)
                                {
@@ -344,10 +357,10 @@
                                        Irp->IoStatus.Information = 0;
                                        IoCompleteRequest(Irp, 
IO_NETWORK_INCREMENT);
                                }
-                               Temp = EntryNest->Flink;
-                               RemoveEntryList(EntryNest);
+                               Temp = RequestEntry->Flink;
+                               RemoveEntryList(RequestEntry);
                                ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
-                               EntryNest = Temp;
+                               RequestEntry = Temp;
                        }
                        
                        KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
@@ -361,7 +374,7 @@
                        
                        return;
                default :
-                       DPRINT1("Invalid argument: %08x\n", arg);
+                       DPRINT1("Invalid argument: %p\n", arg);
                        return;
        }
 }
@@ -369,96 +382,96 @@
 static
 BOOLEAN
 ReceiveDatagram(
-    ADDRESS_FILE* AddressFile,
-    struct pbuf *p,
-    ip_addr_t *addr,
-    u16_t port)
-{
-    KIRQL OldIrql;
-    LIST_ENTRY* ListEntry;
-    RECEIVE_DATAGRAM_REQUEST* Request;
-    ip_addr_t RequestAddr;
-    BOOLEAN Result = FALSE;
-
-    NT_ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
-
-    DPRINT1("Receiving datagram for addr 0x%08x on port %u.\n", 
ip4_addr_get_u32(addr), port);
-
-    /* Block any cancellation that could occur */
-    KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql);
-
-    ListEntry = AddressFile->RequestListHead.Flink;
-    while (ListEntry != &AddressFile->RequestListHead)
-    {
-        Request = CONTAINING_RECORD(ListEntry, RECEIVE_DATAGRAM_REQUEST, 
ListEntry);
-        ListEntry = ListEntry->Flink;
-
-        ip4_addr_set_u32(&RequestAddr, Request->RemoteAddress.in_addr);
-
-        if ((RequestAddr.addr == IPADDR_ANY) ||
-                (ip_addr_cmp(&RequestAddr, addr) &&
-                        ((Request->RemoteAddress.sin_port == lwip_htons(port)) 
|| !port)))
-        {
-            PTA_IP_ADDRESS ReturnAddress;
-            PIRP Irp;
-
-            DPRINT1("Found a corresponding IRP.\n");
-
-            Irp = Request->Irp;
-
-            /* We found a request for this one */
-            IoSetCancelRoutine(Irp, NULL);
-            RemoveEntryList(&Request->ListEntry);
-            Result = TRUE;
-
-            KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
-
-            /* In case of UDP, lwip provides a pbuf directly pointing to the 
data.
-             * In other case, we must skip the IP header */
-            Irp->IoStatus.Information = pbuf_copy_partial(
-                p,
-                Request->Buffer,
-                Request->BufferLength,
-                0);
-            ReturnAddress = Request->ReturnInfo->RemoteAddress;
-            ReturnAddress->Address->AddressLength = TDI_ADDRESS_LENGTH_IP;
-            ReturnAddress->Address->AddressType = TDI_ADDRESS_TYPE_IP;
-            ReturnAddress->Address->Address->sin_port = lwip_htons(port);
-            ReturnAddress->Address->Address->in_addr = ip4_addr_get_u32(addr);
-            RtlZeroMemory(ReturnAddress->Address->Address->sin_zero,
-                sizeof(ReturnAddress->Address->Address->sin_zero));
-
-            if (Request->BufferLength < p->tot_len)
-                Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
-            else
-                Irp->IoStatus.Status = STATUS_SUCCESS;
-            IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
-
-            ExFreePoolWithTag(Request, TAG_DGRAM_REQST);
-
-            /* Start again from the beginning */
-            KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql);
-        }
-    }
-
-    KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
-
-    return Result;
+       ADDRESS_FILE* AddressFile,
+       struct pbuf *p,
+       ip_addr_t *addr,
+       u16_t port)
+{
+       KIRQL OldIrql;
+       LIST_ENTRY* ListEntry;
+       RECEIVE_DATAGRAM_REQUEST* Request;
+       ip_addr_t RequestAddr;
+       BOOLEAN Result = FALSE;
+
+       NT_ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
+
+       DPRINT1("Receiving datagram for addr 0x%08x on port %u.\n", 
ip4_addr_get_u32(addr), port);
+
+       /* Block any cancellation that could occur */
+       KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql);
+
+       ListEntry = AddressFile->RequestListHead.Flink;
+       while (ListEntry != &AddressFile->RequestListHead)
+       {
+               Request = CONTAINING_RECORD(ListEntry, 
RECEIVE_DATAGRAM_REQUEST, ListEntry);
+               ListEntry = ListEntry->Flink;
+
+               ip4_addr_set_u32(&RequestAddr, Request->RemoteAddress.in_addr);
+
+               if ((RequestAddr.addr == IPADDR_ANY) ||
+                               (ip_addr_cmp(&RequestAddr, addr) &&
+                                               
((Request->RemoteAddress.sin_port == lwip_htons(port)) || !port)))
+               {
+                       PTA_IP_ADDRESS ReturnAddress;
+                       PIRP Irp;
+
+                       DPRINT1("Found a corresponding IRP.\n");
+
+                       Irp = Request->Irp;
+
+                       /* We found a request for this one */
+                       IoSetCancelRoutine(Irp, NULL);
+                       RemoveEntryList(&Request->ListEntry);
+                       Result = TRUE;
+
+                       KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
+
+                       /* In case of UDP, lwip provides a pbuf directly 
pointing to the data.
+                        * In other case, we must skip the IP header */
+                       Irp->IoStatus.Information = pbuf_copy_partial(
+                               p,
+                               Request->Buffer,
+                               Request->BufferLength,
+                               0);
+                       ReturnAddress = Request->ReturnInfo->RemoteAddress;
+                       ReturnAddress->Address->AddressLength = 
TDI_ADDRESS_LENGTH_IP;
+                       ReturnAddress->Address->AddressType = 
TDI_ADDRESS_TYPE_IP;
+                       ReturnAddress->Address->Address->sin_port = 
lwip_htons(port);
+                       ReturnAddress->Address->Address->in_addr = 
ip4_addr_get_u32(addr);
+                       RtlZeroMemory(ReturnAddress->Address->Address->sin_zero,
+                               
sizeof(ReturnAddress->Address->Address->sin_zero));
+
+                       if (Request->BufferLength < p->tot_len)
+                               Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
+                       else
+                               Irp->IoStatus.Status = STATUS_SUCCESS;
+                       IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+
+                       ExFreePoolWithTag(Request, TAG_DGRAM_REQST);
+
+                       /* Start again from the beginning */
+                       KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql);
+               }
+       }
+
+       KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
+
+       return Result;
 }
 
 static
 void
 lwip_udp_ReceiveDatagram_callback(
-    void *arg,
-    struct udp_pcb *pcb,
-    struct pbuf *p,
-    ip_addr_t *addr,
-    u16_t port)
-{
-    UNREFERENCED_PARAMETER(pcb);
-
-    ReceiveDatagram(arg, p, addr, port);
-    pbuf_free(p);
+       void *arg,
+       struct udp_pcb *pcb,
+       struct pbuf *p,
+       ip_addr_t *addr,
+       u16_t port)
+{
+       UNREFERENCED_PARAMETER(pcb);
+
+       ReceiveDatagram(arg, p, addr, port);
+       pbuf_free(p);
 }
 
 /* implementation in testing */
@@ -491,8 +504,7 @@
                Context = CONTAINING_RECORD(Entry, TCP_CONTEXT, ListEntry);
                if (Context->TcpState == TCP_STATE_LISTENING)
                {
-                       KeReleaseSpinLock(&AddressFile->ContextListLock, 
OldIrql);
-                       KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
+                       KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock);
                        
                        Context->lwip_tcp_pcb = newpcb;
                        InterlockedIncrement(&PcbCount);
@@ -504,14 +516,34 @@
                
                        Request = CONTAINING_RECORD(Entry, TCP_REQUEST, 
ListEntry);
                        Irp = Request->PendingIrp;
-                       IrpSp = IoGetCurrentIrpStackLocation(Irp);
-                       if (!Irp || IrpSp->MinorFunction != TDI_LISTEN)
+                       if (!Irp)
                        {
                                DPRINT1("Received accept callback for cancelled 
TDI_LISTEN\n");
                                RemoveEntryList(Entry);
-                               Entry = Entry->Flink;
                                ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
-                               KeReleaseSpinLock(&Context->RequestListLock, 
OldIrql);
+                               
KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
+                               
KeReleaseSpinLock(&AddressFile->ContextListLock, OldIrql);
+                               return ERR_ABRT;
+                       }
+                       IrpSp = IoGetCurrentIrpStackLocation(Irp);
+                       if (IrpSp->MinorFunction != TDI_LISTEN)
+                       {
+                               DPRINT1("The IRP is not a listening request, 
something is seriously wrong\n");
+                               /* this should maybe clean out the entire 
context, 
+                                       since this should never happen */
+                               RemoveEntryList(Entry);
+                               
+                               
KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
+                               
KeReleaseSpinLock(&AddressFile->ContextListLock, OldIrql);
+                               
+                               ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
+                               
+                               Irp->IoStatus.Status = STATUS_CANCELLED;
+                               Irp->IoStatus.Information = 0;
+                               IoSetCancelRoutine(Irp, NULL);
+                               
+                               IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+                               
                                return ERR_ABRT;
                        }
                        
@@ -520,7 +552,8 @@
                        IoSetCancelRoutine(Irp, NULL);
                        Irp->Cancel = FALSE;
                        
-                       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
+                       
KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
+                       KeReleaseSpinLock(&AddressFile->ContextListLock, 
OldIrql);
                        
                        Irp->IoStatus.Status = STATUS_SUCCESS;
                        IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
@@ -622,11 +655,6 @@
                        IrpSp = IoGetCurrentIrpStackLocation(Irp);
                        RequestInfo = 
(PTDI_REQUEST_KERNEL_SEND)&IrpSp->Parameters;
                        lwip_err = tcp_write(Context->lwip_tcp_pcb, Buffer, 
RequestInfo->SendLength, 0);
-                       PrepareIrpForCancel(
-                               Irp,
-                               CancelRequestRoutine,
-                               TCP_REQUEST_CANCEL_MODE_PRESERVE,
-                               TCP_REQUEST_PENDING_SEND);
                        break;
                }
                Entry = Entry->Flink;
@@ -662,6 +690,7 @@
        UCHAR *CurrentSrceLocation;
        PLIST_ENTRY Head;
        PLIST_ENTRY Entry;
+       PLIST_ENTRY NextEntry;
        NTSTATUS Status;
        err_t lwip_err;
        
@@ -692,9 +721,10 @@
                DPRINT1("Request Fetched. Points to %08x\n", Request);
                if (!Request->PendingIrp) {
                        DPRINT1("IRP pointer dereferenced\n");
+                       NextEntry = Entry->Flink;
                        RemoveEntryList(Entry);
                        DPRINT1("Entry removed\n");
-                       Entry = Entry->Flink;
+                       Entry = NextEntry;
                        ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
                        continue;
                }
@@ -718,6 +748,7 @@
        
        if (Context->lwip_tcp_pcb != tpcb) {
                DPRINT1("Receive tcp_pcb mismatch\n");
+               tcp_arg(tpcb, NULL);
                tcp_abort(tpcb);
                InterlockedDecrement(&PcbCount);
                DPRINT1("\n    PCB Count\n", PcbCount);
@@ -795,14 +826,16 @@
                        tcp_recv(tpcb, lwip_tcp_receive_callback);
                        break;
                }
+               Entry = Entry->Flink;
        }
        lwip_err = ERR_OK;
        
 BAD:
        RemoveEntryList(&Request->ListEntry);
+       
+       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
+       
        ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
-       
-       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
        
        Irp->IoStatus.Status = Status;
        Irp->IoStatus.Information = CopiedLength;
@@ -814,46 +847,46 @@
 static
 u8_t
 lwip_raw_ReceiveDatagram_callback(
-    void *arg,
-    struct raw_pcb *pcb,
-    struct pbuf *p,
-    ip_addr_t *addr)
-{
-    BOOLEAN Result;
-    ADDRESS_FILE* AddressFile = arg;
-
-    UNREFERENCED_PARAMETER(pcb);
-
-    /* If this is for ICMP, only process the "echo received" packets.
-     * The rest is processed by lwip. */
-    if (AddressFile->Protocol == IPPROTO_ICMP)
-    {
-        /* See icmp_input */
-        s16_t hlen;
-        struct ip_hdr *iphdr;
-
-        iphdr = (struct ip_hdr *)p->payload;
-        hlen = IPH_HL(iphdr) * 4;
-
-        /* Adjust the pbuf to skip the IP header */
-        if (pbuf_header(p, -hlen))
-            return FALSE;
-
-        if (*((u8_t*)p->payload) != ICMP_ER)
-        {
-            pbuf_header(p, hlen);
-            return FALSE;
-        }
-
-        pbuf_header(p, hlen);
-    }
-
-    Result = ReceiveDatagram(arg, p, addr, 0);
-
-    if (Result)
-        pbuf_free(p);
-
-    return Result;
+       void *arg,
+       struct raw_pcb *pcb,
+       struct pbuf *p,
+       ip_addr_t *addr)
+{
+       BOOLEAN Result;
+       ADDRESS_FILE* AddressFile = arg;
+
+       UNREFERENCED_PARAMETER(pcb);
+
+       /* If this is for ICMP, only process the "echo received" packets.
+        * The rest is processed by lwip. */
+       if (AddressFile->Protocol == IPPROTO_ICMP)
+       {
+               /* See icmp_input */
+               s16_t hlen;
+               struct ip_hdr *iphdr;
+
+               iphdr = (struct ip_hdr *)p->payload;
+               hlen = IPH_HL(iphdr) * 4;
+
+               /* Adjust the pbuf to skip the IP header */
+               if (pbuf_header(p, -hlen))
+                       return FALSE;
+
+               if (*((u8_t*)p->payload) != ICMP_ER)
+               {
+                       pbuf_header(p, hlen);
+                       return FALSE;
+               }
+
+               pbuf_header(p, hlen);
+       }
+
+       Result = ReceiveDatagram(arg, p, addr, 0);
+
+       if (Result)
+               pbuf_free(p);
+
+       return Result;
 }
 
 /* implementation in testing */
@@ -877,24 +910,20 @@
        Context = (PTCP_CONTEXT)arg;
        KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
        Head = &Context->RequestListHead;
-       Entry = Head->Flink;
-       if (Head == Entry)
+       if (IsListEmpty(Head))
        {
                DPRINT1("Request list is empty\n");
                KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
                return ERR_ARG;
        }
+       Entry = RemoveHeadList(Head);
+       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
        Request = CONTAINING_RECORD(Entry, TCP_REQUEST, ListEntry);
        Irp = Request->PendingIrp;
        if (!Irp)
        {
                DPRINT1("Callback on cancelled IRP\n");
-               
-               RemoveEntryList(&Request->ListEntry);
                ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
-               
-               KeReleaseSpinLock(&Request->Context->RequestListLock, OldIrql);
-               
                return ERR_ABRT;
        }
        IoSetCancelRoutine(Irp, NULL);
@@ -910,11 +939,7 @@
        lwip_err = ERR_OK;
        
 FINISH:
-       
-       RemoveEntryList(&Request->ListEntry);
        ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
-       
-       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
        
        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
@@ -925,176 +950,178 @@
 /* implementation in testing */
 NTSTATUS
 TcpIpCreateAddress(
-    _Inout_ PIRP Irp,
-    _In_ PTDI_ADDRESS_IP Address,
-    _In_ IPPROTO Protocol
+       _Inout_ PIRP Irp,
+       _In_ PTDI_ADDRESS_IP Address,
+       _In_ IPPROTO Protocol
 )
 {
-    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
-    PADDRESS_FILE AddressFile;
-    LIST_ENTRY* ListEntry;
-    KIRQL OldIrql;
-       
-    USHORT Port = 1;
-
-    /* See if this port is already taken, and find a free one if needed. */
-    KeAcquireSpinLock(&AddressListLock, &OldIrql);
+       PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+       PADDRESS_FILE AddressFile;
+       LIST_ENTRY* ListEntry;
+       KIRQL OldIrql;
+       
+       USHORT Port = 1;
+
+       /* See if this port is already taken, and find a free one if needed. */
+       KeAcquireSpinLock(&AddressListLock, &OldIrql);
 
        DPRINT1("Search through used ports\n");
        
-    ListEntry = AddressListHead.Flink;
-    while (ListEntry != &AddressListHead)
-    {
-        AddressFile = CONTAINING_RECORD(ListEntry, ADDRESS_FILE, ListEntry);
-
-        if (Address->sin_port)
-        {
-            if ((AddressFile->Protocol == Protocol) &&
-                    (AddressFile->Address.sin_port == Address->sin_port))
-            {
-                if (IrpSp->Parameters.Create.ShareAccess)
-                {
-                    /* Good, we found the shared address we were looking for */
-                    InterlockedIncrement(&AddressFile->RefCount);
-                    KeReleaseSpinLock(&AddressListLock, OldIrql);
-                    goto Success;
-                }
-
-                KeReleaseSpinLock(&AddressListLock, OldIrql);
-                return STATUS_ADDRESS_ALREADY_EXISTS;
-            }
-        }
-        else if ((AddressFile->Address.sin_port == lwip_htons(Port))
-                && AddressFile->Protocol == Protocol)
-        {
-            Port++;
-            if (Port == 0)
-            {
-                /* Oh no. Already 65535 ports occupied! */
-                DPRINT1("No more free ports for protocol %d!\n", Protocol);
-                KeReleaseSpinLock(&AddressListLock, OldIrql);
-                return STATUS_TOO_MANY_ADDRESSES;
-            }
-
-            /* We must start anew to check again the previous entries in the 
list */
-            ListEntry = &AddressListHead;
-        }
-        ListEntry = ListEntry->Flink;
-    }
+       ListEntry = AddressListHead.Flink;
+       while (ListEntry != &AddressListHead)
+       {
+               AddressFile = CONTAINING_RECORD(ListEntry, ADDRESS_FILE, 
ListEntry);
+
+               if (Address->sin_port)
+               {
+                       if ((AddressFile->Protocol == Protocol) &&
+                                       (AddressFile->Address.sin_port == 
Address->sin_port))
+                       {
+                               if (IrpSp->Parameters.Create.ShareAccess)
+                               {
+                                       /* Good, we found the shared address we 
were looking for */
+                                       
InterlockedIncrement(&AddressFile->RefCount);
+                                       DPRINT1("RefCount increment to %d\n", 
AddressFile->RefCount);
+                                       KeReleaseSpinLock(&AddressListLock, 
OldIrql);
+                                       goto Success;
+                               }
+
+                               KeReleaseSpinLock(&AddressListLock, OldIrql);
+                               DPRINT1("Address taken\n");
+                               return STATUS_ADDRESS_ALREADY_EXISTS;
+                       }
+               }
+               else if ((AddressFile->Address.sin_port == lwip_htons(Port))
+                               && AddressFile->Protocol == Protocol)
+               {
+                       Port++;
+                       if (Port == 0)
+                       {
+                               /* Oh no. Already 65535 ports occupied! */
+                               DPRINT1("No more free ports for protocol 
%d!\n", Protocol);
+                               KeReleaseSpinLock(&AddressListLock, OldIrql);
+                               return STATUS_TOO_MANY_ADDRESSES;
+                       }
+
+                       /* We must start anew to check again the previous 
entries in the list */
+                       ListEntry = &AddressListHead;
+               }
+               ListEntry = ListEntry->Flink;
+       }
 
        DPRINT1("Find local interface for address\n");
        
-    if (!AddrIsUnspecified(Address))
-    {
-        /* Find the local interface for this address */
-        struct netif* lwip_netif = netif_list;
-        ip_addr_t IpAddr;
-
-        ip4_addr_set_u32(&IpAddr, Address->in_addr);
-        while (lwip_netif)
-        {
+       if (!AddrIsUnspecified(Address))
+       {
+               /* Find the local interface for this address */
+               struct netif* lwip_netif = netif_list;
+               ip_addr_t IpAddr;
+
+               ip4_addr_set_u32(&IpAddr, Address->in_addr);
+               while (lwip_netif)
+               {
 //                     DPRINT1("Comparing against address %lx\n", 
lwip_netif->ip_addr.addr);
-            if (ip_addr_cmp(&IpAddr, &lwip_netif->ip_addr))
-            {
-                break;
-            }
-            lwip_netif = lwip_netif->next;
-        }
-
-        if (!lwip_netif)
-        {
-            DPRINT1("Cound not find an interface for address 0x%08x\n", 
AddressFile->Address.in_addr);
-            KeReleaseSpinLock(&AddressListLock, OldIrql);
-            return STATUS_INVALID_ADDRESS;
-        }
-    }
+                       if (ip_addr_cmp(&IpAddr, &lwip_netif->ip_addr))
+                       {
+                               break;
+                       }
+                       lwip_netif = lwip_netif->next;
+               }
+
+               if (!lwip_netif)
+               {
+                       DPRINT1("Cound not find an interface for address 
0x%08x\n", AddressFile->Address.in_addr);
+                       KeReleaseSpinLock(&AddressListLock, OldIrql);
+                       return STATUS_INVALID_ADDRESS;
+               }
+       }
 
        DPRINT1("Allocate address file\n");
        
-    /* Allocate our new address file */
-    AddressFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(*AddressFile), 
TAG_ADDRESS_FILE);
-    if (!AddressFile)
-    {
+       /* Allocate our new address file */
+       AddressFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(*AddressFile), 
TAG_ADDRESS_FILE);
+       if (!AddressFile)
+       {
                KeReleaseSpinLock(&AddressListLock, OldIrql);
-        return STATUS_NO_MEMORY;
-    }
-
-    RtlZeroMemory(AddressFile, sizeof(*AddressFile));
+               return STATUS_NO_MEMORY;
+       }
+
+       RtlZeroMemory(AddressFile, sizeof(*AddressFile));
        AddressFile->Type = TDI_TRANSPORT_ADDRESS_FILE;
-    AddressFile->RefCount = 1;
-    RtlCopyMemory(&AddressFile->Address, Address, sizeof(*Address));
-    AddressFile->Protocol = Protocol;
-    if (!Address->sin_port)
-        AddressFile->Address.sin_port = lwip_htons(Port);
-
-    /* Initialize the datagram request stuff */
-    KeInitializeSpinLock(&AddressFile->RequestLock);
-    InitializeListHead(&AddressFile->RequestListHead);
+       AddressFile->RefCount = 1;
+       RtlCopyMemory(&AddressFile->Address, Address, sizeof(*Address));
+       AddressFile->Protocol = Protocol;
+       if (!Address->sin_port)
+               AddressFile->Address.sin_port = lwip_htons(Port);
+
+       /* Initialize the datagram request stuff */
+       KeInitializeSpinLock(&AddressFile->RequestLock);
+       InitializeListHead(&AddressFile->RequestListHead);
 
        DPRINT1("Protocol-dependent operations\n");
        
-    /* Give it an entity ID and open a PCB if needed. */
-    switch (Protocol)
-    {
-        case IPPROTO_TCP:
+       /* Give it an entity ID and open a PCB if needed. */
+       switch (Protocol)
+       {
+               case IPPROTO_TCP:
                {
                        ip_addr_t IpAddr;
-            ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr);
-            InsertEntityInstance(CO_TL_ENTITY, &AddressFile->Instance);
+                       ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr);
+                       InsertEntityInstance(CO_TL_ENTITY, 
&AddressFile->Instance);
                        AddressFile->ContextCount = 0;
                        AddressFile->lwip_tcp_pcb = tcp_new();
                        InterlockedIncrement(&PcbCount);
                        DPRINT1("\n    PCB Count: %d\n", PcbCount);
                        tcp_arg(AddressFile->lwip_tcp_pcb, AddressFile);
                        tcp_err(AddressFile->lwip_tcp_pcb, 
lwip_tcp_err_callback);
-            break;
-               }
-        case IPPROTO_UDP:
-        {
-            ip_addr_t IpAddr;
-            ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr);
-            InsertEntityInstance(CL_TL_ENTITY, &AddressFile->Instance);
-            AddressFile->lwip_udp_pcb = udp_new();
-            udp_bind(AddressFile->lwip_udp_pcb, &IpAddr, 
lwip_ntohs(AddressFile->Address.sin_port));
-            ip_set_option(AddressFile->lwip_udp_pcb, SOF_BROADCAST);
-            /* Register our recv handler to lwip */
-            udp_recv(
-                AddressFile->lwip_udp_pcb,
-                lwip_udp_ReceiveDatagram_callback,
-                AddressFile);
-            break;
-        }
-        default:
-        {
-            ip_addr_t IpAddr;
-            ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr);
-            if (Protocol == IPPROTO_ICMP)
-                InsertEntityInstance(ER_ENTITY, &AddressFile->Instance);
-            else
-                InsertEntityInstance(CL_TL_ENTITY, &AddressFile->Instance);
-            AddressFile->lwip_raw_pcb = raw_new(Protocol);
-            raw_bind(AddressFile->lwip_raw_pcb, &IpAddr);
-            ip_set_option(AddressFile->lwip_raw_pcb, SOF_BROADCAST);
-            /* Register our recv handler for lwip */
-            raw_recv(
-                AddressFile->lwip_raw_pcb,
-                lwip_raw_ReceiveDatagram_callback,
-                AddressFile);
-            break;
-        }
-    }
+                       break;
+               }
+               case IPPROTO_UDP:
+               {
+                       ip_addr_t IpAddr;
+                       ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr);
+                       InsertEntityInstance(CL_TL_ENTITY, 
&AddressFile->Instance);
+                       AddressFile->lwip_udp_pcb = udp_new();
+                       udp_bind(AddressFile->lwip_udp_pcb, &IpAddr, 
lwip_ntohs(AddressFile->Address.sin_port));
+                       ip_set_option(AddressFile->lwip_udp_pcb, SOF_BROADCAST);
+                       /* Register our recv handler to lwip */
+                       udp_recv(
+                               AddressFile->lwip_udp_pcb,
+                               lwip_udp_ReceiveDatagram_callback,
+                               AddressFile);
+                       break;
+               }
+               default:
+               {
+                       ip_addr_t IpAddr;
+                       ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr);
+                       if (Protocol == IPPROTO_ICMP)
+                               InsertEntityInstance(ER_ENTITY, 
&AddressFile->Instance);
+                       else
+                               InsertEntityInstance(CL_TL_ENTITY, 
&AddressFile->Instance);
+                       AddressFile->lwip_raw_pcb = raw_new(Protocol);
+                       raw_bind(AddressFile->lwip_raw_pcb, &IpAddr);
+                       ip_set_option(AddressFile->lwip_raw_pcb, SOF_BROADCAST);
+                       /* Register our recv handler for lwip */
+                       raw_recv(
+                               AddressFile->lwip_raw_pcb,
+                               lwip_raw_ReceiveDatagram_callback,
+                               AddressFile);
+                       break;
+               }
+       }
 
        DPRINT1("Insert into address list\n");
        
-    /* Insert it into the list. */
-    InsertTailList(&AddressListHead, &AddressFile->ListEntry);
-    KeReleaseSpinLock(&AddressListLock, OldIrql);
+       /* Insert it into the list. */
+       InsertTailList(&AddressListHead, &AddressFile->ListEntry);
+       KeReleaseSpinLock(&AddressListLock, OldIrql);
 
 Success:
-    IrpSp->FileObject->FsContext = AddressFile;
-    IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE;
-       
-    return STATUS_SUCCESS;
+       IrpSp->FileObject->FsContext = AddressFile;
+       IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE;
+       
+       return STATUS_SUCCESS;
 }
 
 /* implementation in testing */
@@ -1138,25 +1165,27 @@
 /* implementation in testing */
 NTSTATUS
 TcpIpCloseAddress(
-    _Inout_ ADDRESS_FILE* AddressFile
+       _Inout_ ADDRESS_FILE* AddressFile
 )
 {
-    KIRQL OldIrql;
+       KIRQL OldIrql;
+       NTSTATUS Status;
        
        err_t lwip_err;
 
-    /* Lock the global address list */
-    KeAcquireSpinLock(&AddressListLock, &OldIrql);
-
-    if (InterlockedDecrement(&AddressFile->RefCount) != 0)
-    {
-        /* There are still some open handles for this address */
-               DPRINT1("TcpIpCloseAddress on address with open handles\n");
-        KeReleaseSpinLock(&AddressListLock, OldIrql);
-        return STATUS_SUCCESS;
-    }
-
-    /* remove the lwip pcb */
+       /* Lock the global address list */
+       KeAcquireSpinLock(&AddressListLock, &OldIrql);
+
+       InterlockedDecrement(&AddressFile->RefCount);
+       if (AddressFile->RefCount != 0)
+       {
+               /* There are still some open handles for this address */
+               DPRINT1("TcpIpCloseAddress on address with %d open handles\n", 
AddressFile->RefCount);
+               KeReleaseSpinLock(&AddressListLock, OldIrql);
+               return STATUS_SUCCESS;
+       }
+
+       /* remove the lwip pcb */
        switch (AddressFile->Protocol)
        {
                case IPPROTO_UDP :
@@ -1166,6 +1195,7 @@
                        if (AddressFile->ContextCount != 0)
                        {
                                DPRINT1("Calling close on TCP address with open 
contexts\n");
+                               // Should never happen due to how callers are 
written. 
                                KeReleaseSpinLock(&AddressListLock, OldIrql);
                                return STATUS_INVALID_PARAMETER;
                        }
@@ -1177,6 +1207,7 @@
                                }
                                else
                                {
+                                       tcp_arg(AddressFile->lwip_tcp_pcb, 
NULL);
                                        tcp_abort(AddressFile->lwip_tcp_pcb);
                                        lwip_err = ERR_OK;
                                }
@@ -1185,29 +1216,35 @@
                                if (lwip_err != ERR_OK)
                                {
                                        DPRINT1("lwIP tcp_close error: %d", 
lwip_err);
-                                       KeReleaseSpinLock(&AddressListLock, 
OldIrql);
-                                       return STATUS_UNSUCCESSFUL;
+                                       // TODO: better return code
+                                       Status = STATUS_UNSUCCESSFUL;
                                }
+                               Status = STATUS_SUCCESS;
+                               break;
                        }
                        break;
                case IPPROTO_RAW :
                        raw_remove(AddressFile->lwip_raw_pcb);
+                       Status = STATUS_SUCCESS;
                        break;
                default :
                        DPRINT1("Unknown protocol\n");
-                       KeReleaseSpinLock(&AddressListLock, OldIrql);
-                       return STATUS_INVALID_ADDRESS;
-       }
-
-    /* Remove from the list and free the structure */
-    RemoveEntryList(&AddressFile->ListEntry);
-    KeReleaseSpinLock(&AddressListLock, OldIrql);
-
-    RemoveEntityInstance(&AddressFile->Instance);
-
-    ExFreePoolWithTag(AddressFile, TAG_ADDRESS_FILE);
-
-    return STATUS_SUCCESS;
+                       // Should never happen due to how callers are written. 
+                       // This case is particularly bad since we don't know 
what needs
+                       // to be deallocated at all. 
+                       Status = STATUS_INVALID_ADDRESS;
+                       break;
+       }
+
+       /* Remove from the list and free the structure */
+       RemoveEntryList(&AddressFile->ListEntry);
+       KeReleaseSpinLock(&AddressListLock, OldIrql);
+
+       RemoveEntityInstance(&AddressFile->Instance);
+
+       ExFreePoolWithTag(AddressFile, TAG_ADDRESS_FILE);
+
+       return Status;
 }
 
 /* implementation in testing */
@@ -1218,6 +1255,7 @@
        err_t lwip_err;
        PLIST_ENTRY Head;
        PLIST_ENTRY Entry;
+       PADDRESS_FILE AddressFile;
        PTCP_REQUEST Request;
        PIRP Irp;
        PIO_STACK_LOCATION IrpSp;
@@ -1229,7 +1267,7 @@
                DPRINT1("Invalid protocol\n");
                return STATUS_INVALID_PARAMETER;
        }
-       if (Context->AddressFile)
+       if (!(Context->TcpState & TCP_STATE_DISASSOCIATED))
        {
                DPRINT1("Context retains association\n");
                return STATUS_UNSUCCESSFUL;
@@ -1245,6 +1283,7 @@
                }
                else
                {
+                       tcp_arg(Context->lwip_tcp_pcb, NULL);
                        tcp_abort(Context->lwip_tcp_pcb);
                        lwip_err = ERR_OK;
                }
@@ -1284,7 +1323,16 @@
        
        KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
        
+       AddressFile = Context->AddressFile;
+       
        ExFreePoolWithTag(Context, TAG_TCP_CONTEXT);
+       
+       if (AddressFile->ContextCount == 0)
+       {
+               DPRINT1("Closing Address File at %p from TcpIpCloseContext on 
Context at %p\n",
+                       AddressFile, Context);
+               return TcpIpCloseAddress(AddressFile);
+       }
        
        return STATUS_SUCCESS;
 }
@@ -1292,73 +1340,73 @@
 static
 NTSTATUS
 ExtractAddressFromList(
-    _In_ PTRANSPORT_ADDRESS AddressList,
-    _Out_ PTDI_ADDRESS_IP Address)
-{
-    PTA_ADDRESS CurrentAddress;
-    INT i;
-
-    CurrentAddress = &AddressList->Address[0];
-
-    /* We can only use IP addresses. Search the list until we find one */
-    for (i = 0; i < AddressList->TAAddressCount; i++)
-    {
-        if (CurrentAddress->AddressType == TDI_ADDRESS_TYPE_IP)
-        {
-            if (CurrentAddress->AddressLength == TDI_ADDRESS_LENGTH_IP)
-            {
-                /* This is an IPv4 address */
-                RtlCopyMemory(Address, &CurrentAddress->Address[0], 
CurrentAddress->AddressLength);
-                return STATUS_SUCCESS;
-            }
-        }
-        CurrentAddress = 
(PTA_ADDRESS)&CurrentAddress->Address[CurrentAddress->AddressLength];
-    }
-    return STATUS_INVALID_ADDRESS;
+       _In_ PTRANSPORT_ADDRESS AddressList,
+       _Out_ PTDI_ADDRESS_IP Address)
+{
+       PTA_ADDRESS CurrentAddress;
+       INT i;
+
+       CurrentAddress = &AddressList->Address[0];
+
+       /* We can only use IP addresses. Search the list until we find one */
+       for (i = 0; i < AddressList->TAAddressCount; i++)
+       {
+               if (CurrentAddress->AddressType == TDI_ADDRESS_TYPE_IP)
+               {
+                       if (CurrentAddress->AddressLength == 
TDI_ADDRESS_LENGTH_IP)
+                       {
+                               /* This is an IPv4 address */
+                               RtlCopyMemory(Address, 
&CurrentAddress->Address[0], CurrentAddress->AddressLength);
+                               return STATUS_SUCCESS;
+                       }
+               }
+               CurrentAddress = 
(PTA_ADDRESS)&CurrentAddress->Address[CurrentAddress->AddressLength];
+       }
+       return STATUS_INVALID_ADDRESS;
 }
 
 static
 VOID
 NTAPI
 CancelReceiveDatagram(
-    _Inout_ struct _DEVICE_OBJECT* DeviceObject,
-    _Inout_ _IRQL_uses_cancel_ struct _IRP *Irp)
-{
-    PIO_STACK_LOCATION IrpSp;
-    ADDRESS_FILE* AddressFile;
-    RECEIVE_DATAGRAM_REQUEST* Request;
-    LIST_ENTRY* ListEntry;
-    KIRQL OldIrql;
-
-    IoReleaseCancelSpinLock(Irp->CancelIrql);
-
-    IrpSp = IoGetCurrentIrpStackLocation(Irp);
-    AddressFile = IrpSp->FileObject->FsContext;
-
-    /* Find this IRP in the list of requests */
-    KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql);
-    ListEntry = AddressFile->RequestListHead.Flink;
-    while (ListEntry != &AddressFile->RequestListHead)
-    {
-        Request = CONTAINING_RECORD(ListEntry, RECEIVE_DATAGRAM_REQUEST, 
ListEntry);
-        if (Request->Irp == Irp)
-            break;
-        ListEntry = ListEntry->Flink;
-    }
-
-    /* We must have found it */
-    NT_ASSERT(ListEntry != &AddressFile->RequestListHead);
-
-    RemoveEntryList(&Request->ListEntry);
-
-    Irp->IoStatus.Status = STATUS_CANCELLED;
-    Irp->IoStatus.Information = 0;
-       
-    KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
-
-    IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
-
-    ExFreePoolWithTag(Request, TAG_DGRAM_REQST);
+       _Inout_ struct _DEVICE_OBJECT* DeviceObject,
+       _Inout_ _IRQL_uses_cancel_ struct _IRP *Irp)
+{
+       PIO_STACK_LOCATION IrpSp;
+       ADDRESS_FILE* AddressFile;
+       RECEIVE_DATAGRAM_REQUEST* Request;
+       LIST_ENTRY* ListEntry;
+       KIRQL OldIrql;
+
+       IoReleaseCancelSpinLock(Irp->CancelIrql);
+
+       IrpSp = IoGetCurrentIrpStackLocation(Irp);
+       AddressFile = IrpSp->FileObject->FsContext;
+
+       /* Find this IRP in the list of requests */
+       KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql);
+       ListEntry = AddressFile->RequestListHead.Flink;
+       while (ListEntry != &AddressFile->RequestListHead)
+       {
+               Request = CONTAINING_RECORD(ListEntry, 
RECEIVE_DATAGRAM_REQUEST, ListEntry);
+               if (Request->Irp == Irp)
+                       break;
+               ListEntry = ListEntry->Flink;
+       }
+
+       /* We must have found it */
+       NT_ASSERT(ListEntry != &AddressFile->RequestListHead);
+
+       RemoveEntryList(&Request->ListEntry);
+       
+       KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
+
+       Irp->IoStatus.Status = STATUS_CANCELLED;
+       Irp->IoStatus.Information = 0;
+
+       IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+
+       ExFreePoolWithTag(Request, TAG_DGRAM_REQST);
 }
 
 /* implementation in testing */
@@ -1370,6 +1418,7 @@
        PTCP_CONTEXT Context;
        PTDI_REQUEST_KERNEL_CONNECT Parameters;
        PTRANSPORT_ADDRESS RemoteTransportAddress;
+       KIRQL OldIrql;
        
        struct sockaddr *SocketAddressRemote;
        struct sockaddr_in *SocketAddressInRemote;
@@ -1412,10 +1461,13 @@
                Context->lwip_tcp_pcb->local_ip,
                Context->lwip_tcp_pcb->local_port);
        
+       DPRINT1("Call into lwIP tcp_connect(). Context at %p, pcb at %p\n",
+               Context, Context->lwip_tcp_pcb);
        lwip_err = tcp_connect(Context->lwip_tcp_pcb,
                (ip_addr_t *)&SocketAddressInRemote->sin_addr.s_addr,
                SocketAddressInRemote->sin_port,
                lwip_tcp_connected_callback);
+       DPRINT1("Return from lwIP tcp_connect()\n");
        switch (lwip_err)
        {
                case (ERR_VAL) :
@@ -1454,6 +1506,7 @@
                }
                case (ERR_OK) :
                {
+                       KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
                        PrepareIrpForCancel(
                                Irp,
                                CancelRequestRoutine,
@@ -1461,6 +1514,7 @@
                                TCP_REQUEST_PENDING_GENERAL);
                        tcp_arg(Context->lwip_tcp_pcb, Context);
                        Context->TcpState = TCP_STATE_CONNECTING;
+                       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
                        return STATUS_PENDING;
                }
                default :
@@ -1662,12 +1716,13 @@
                        if (Request->PendingIrp)
                        {
                                IrpSp = 
IoGetCurrentIrpStackLocation(Request->PendingIrp);
-                               DPRINT1("Pending IRP Control Code: %08x\n", 
IrpSp->MinorFunction);
+                               DPRINT1("Pending IRP MonorFunction: %08x\n", 
IrpSp->MinorFunction);
                        }
                        else
                        {
                                DPRINT1("IRP is NULL\n");
                        }
+                       Entry = Entry->Flink;
                }
        }
        KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
@@ -1675,13 +1730,8 @@
        KeAcquireSpinLock(&AddressFile->ContextListLock, &OldIrql);
        RemoveEntryList(&Context->ListEntry);
        AddressFile->ContextCount--;
-       Context->AddressFile = NULL;
+       Context->TcpState |= TCP_STATE_DISASSOCIATED;
        KeReleaseSpinLock(&AddressFile->ContextListLock, OldIrql);
-       
-       if (AddressFile->ContextCount == 0)
-       {
-               return TcpIpCloseAddress(AddressFile);
-       }
        
        return STATUS_SUCCESS;
 }
@@ -1738,12 +1788,14 @@
        }
        KeReleaseSpinLock(&AddressFile->ContextListLock, OldIrql);
        
+       KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
        PrepareIrpForCancel(
                Irp,
                CancelRequestRoutine,
                TCP_REQUEST_CANCEL_MODE_CLOSE,
                TCP_REQUEST_PENDING_GENERAL);
        Context->TcpState = TCP_STATE_LISTENING;
+       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
        return STATUS_PENDING;
 }
 
@@ -1861,10 +1913,11 @@
 {
        PIO_STACK_LOCATION IrpSp;
        PTCP_CONTEXT Context;
+       KIRQL OldIrql;
        
        PTDI_REQUEST_KERNEL_RECEIVE RequestInfo;
        
-       DPRINT1("Receive IRP Address: %08x\n", Irp);
+       DPRINT1("Receive IRP Address: %p\n", Irp);
        
        IrpSp = IoGetCurrentIrpStackLocation(Irp);
        
@@ -1880,6 +1933,8 @@
        {
                RequestInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&IrpSp->Parameters;
                DPRINT1("\n  Request Length = %d\n", 
RequestInfo->ReceiveLength);
+               
+               KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
                
                PrepareIrpForCancel(
                        Irp,
@@ -1894,6 +1949,7 @@
                        Context->TcpState |= TCP_STATE_RECEIVING;
                }
                
+               KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
                return STATUS_PENDING;
        }
        DPRINT1("Invalid TCP state: %d\n", Context->TcpState);
@@ -1903,275 +1959,275 @@
 
 NTSTATUS
 TcpIpReceiveDatagram(
-    _Inout_ PIRP Irp)
-{
-    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
-    ADDRESS_FILE *AddressFile;
-    RECEIVE_DATAGRAM_REQUEST* Request = NULL;
-    PTDI_REQUEST_KERNEL_RECEIVEDG RequestInfo;
-    NTSTATUS Status;
-
-    /* Check this is really an address file */
-    if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE)
-    {
-        Status = STATUS_FILE_INVALID;
-        goto Failure;
-    }
-
-    /* Get the address file */
-    AddressFile = IrpSp->FileObject->FsContext;
-
-    if (AddressFile->Protocol == IPPROTO_TCP)
-    {
-        /* TCP has no such thing as datagrams */
-        DPRINT1("Received TDI_RECEIVE_DATAGRAM for a TCP adress file.\n");
-        Status = STATUS_INVALID_ADDRESS;
-        goto Failure;
-    }
-
-    /* Queue the request */
-    Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), 
TAG_DGRAM_REQST);
-    if (!Request)
-    {
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto Failure;
-    }
-    RtlZeroMemory(Request, sizeof(*Request));
-    Request->Irp = Irp;
-
-    /* Get details about what we should be receiving */
-    RequestInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&IrpSp->Parameters;
-
-    /* Get the address */
-    if (RequestInfo->ReceiveDatagramInformation->RemoteAddressLength != 0)
-    {
-        Status = ExtractAddressFromList(
-            RequestInfo->ReceiveDatagramInformation->RemoteAddress,
-            &Request->RemoteAddress);
-        if (!NT_SUCCESS(Status))
-            goto Failure;
-    }
-
-    DPRINT1("Queuing datagram receive on address 0x%08x, port %u.\n",
-        Request->RemoteAddress.in_addr, Request->RemoteAddress.sin_port);
-
-    /* Get the buffer */
-    Request->Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
-    Request->BufferLength = MmGetMdlByteCount(Irp->MdlAddress);
-
-    Request->ReturnInfo = RequestInfo->ReturnDatagramInformation;
-
-    /* Mark pending */
-    Irp->IoStatus.Status = STATUS_PENDING;
-    IoMarkIrpPending(Irp);
-    IoSetCancelRoutine(Irp, CancelReceiveDatagram);
-
-    /* We're ready to go */
-    ExInterlockedInsertTailList(
-        &AddressFile->RequestListHead,
-        &Request->ListEntry,
-        &AddressFile->RequestLock);
-
-    return STATUS_PENDING;
+       _Inout_ PIRP Irp)
+{
+       PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+       ADDRESS_FILE *AddressFile;
+       RECEIVE_DATAGRAM_REQUEST* Request = NULL;
+       PTDI_REQUEST_KERNEL_RECEIVEDG RequestInfo;
+       NTSTATUS Status;
+
+       /* Check this is really an address file */
+       if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != 
TDI_TRANSPORT_ADDRESS_FILE)
+       {
+               Status = STATUS_FILE_INVALID;
+               goto Failure;
+       }
+
+       /* Get the address file */
+       AddressFile = IrpSp->FileObject->FsContext;
+
+       if (AddressFile->Protocol == IPPROTO_TCP)
+       {
+               /* TCP has no such thing as datagrams */
+               DPRINT1("Received TDI_RECEIVE_DATAGRAM for a TCP adress 
file.\n");
+               Status = STATUS_INVALID_ADDRESS;
+               goto Failure;
+       }
+
+       /* Queue the request */
+       Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), 
TAG_DGRAM_REQST);
+       if (!Request)
+       {
+               Status = STATUS_INSUFFICIENT_RESOURCES;
+               goto Failure;
+       }
+       RtlZeroMemory(Request, sizeof(*Request));
+       Request->Irp = Irp;
+
+       /* Get details about what we should be receiving */
+       RequestInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&IrpSp->Parameters;
+
+       /* Get the address */
+       if (RequestInfo->ReceiveDatagramInformation->RemoteAddressLength != 0)
+       {
+               Status = ExtractAddressFromList(
+                       RequestInfo->ReceiveDatagramInformation->RemoteAddress,
+                       &Request->RemoteAddress);
+               if (!NT_SUCCESS(Status))
+                       goto Failure;
+       }
+
+       DPRINT1("Queuing datagram receive on address 0x%08x, port %u.\n",
+               Request->RemoteAddress.in_addr, 
Request->RemoteAddress.sin_port);
+
+       /* Get the buffer */
+       Request->Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
+       Request->BufferLength = MmGetMdlByteCount(Irp->MdlAddress);
+
+       Request->ReturnInfo = RequestInfo->ReturnDatagramInformation;
+
+       /* Mark pending */
+       Irp->IoStatus.Status = STATUS_PENDING;
+       IoMarkIrpPending(Irp);
+       IoSetCancelRoutine(Irp, CancelReceiveDatagram);
+
+       /* We're ready to go */
+       ExInterlockedInsertTailList(
+               &AddressFile->RequestListHead,
+               &Request->ListEntry,
+               &AddressFile->RequestLock);
+
+       return STATUS_PENDING;
 
 Failure:
-    if (Request)
-        ExFreePoolWithTag(Request, TAG_DGRAM_REQST);
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
-    return Status;
+       if (Request)
+               ExFreePoolWithTag(Request, TAG_DGRAM_REQST);
+       Irp->IoStatus.Status = Status;
+       IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+       return Status;
 }
 
 
 NTSTATUS
 TcpIpSendDatagram(
-    _Inout_ PIRP Irp)
-{
-    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
-    ADDRESS_FILE *AddressFile;
-    PTDI_REQUEST_KERNEL_SENDDG RequestInfo;
-    NTSTATUS Status;
-    ip_addr_t IpAddr;
-    u16_t Port;
-    PVOID Buffer;
-    ULONG BufferLength;
-    struct pbuf* p = NULL;
-    err_t lwip_error;
-
-    /* Check this is really an address file */
-    if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE)
-    {
-        Status = STATUS_FILE_INVALID;
-        goto Finish;
-    }
-
-    /* Get the address file */
-    AddressFile = IrpSp->FileObject->FsContext;
-
-    if (AddressFile->Protocol == IPPROTO_TCP)
-    {
-        /* TCP has no such thing as datagrams */
-        DPRINT1("Received TDI_SEND_DATAGRAM for a TCP adress file.\n");
-        Status = STATUS_INVALID_ADDRESS;
-        goto Finish;
-    }
-
-    /* Get details about what we should be receiving */
-    RequestInfo = (PTDI_REQUEST_KERNEL_SENDDG)&IrpSp->Parameters;
-
-    /* Get the address */
-    if (RequestInfo->SendDatagramInformation->RemoteAddressLength != 0)
-    {
-        TDI_ADDRESS_IP Address;
-        Status = ExtractAddressFromList(
-            RequestInfo->SendDatagramInformation->RemoteAddress,
-            &Address);
-        if (!NT_SUCCESS(Status))
-            goto Finish;
-        ip4_addr_set_u32(&IpAddr, Address.in_addr);
-        Port = lwip_ntohs(Address.sin_port);
-    }
-    else
-    {
-        ip_addr_set_any(&IpAddr);
-        Port = 0;
-    }
-
-    DPRINT1("Sending datagram to address 0x%08x, port %u\n", 
ip4_addr_get_u32(&IpAddr), lwip_ntohs(Port));
-
-    /* Get the buffer */
-    Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
-    BufferLength = MmGetMdlByteCount(Irp->MdlAddress);
-    p = pbuf_alloc(PBUF_RAW, BufferLength, PBUF_REF);
-    if (!p)
-    {
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto Finish;
-    }
-    p->payload = Buffer;
-
-    /* Send it for real */
-    switch (AddressFile->Protocol)
-    {
-        case IPPROTO_UDP:
-            if (((ip4_addr_get_u32(&IpAddr) == IPADDR_ANY) ||
-                    (ip4_addr_get_u32(&IpAddr) == IPADDR_BROADCAST)) &&
-                    (Port == 67) && (AddressFile->Address.in_addr == 0))
-            {
-                struct netif* lwip_netif = netif_list;
-
-                /*
-                 * This is a DHCP packet for an address file with address 
0.0.0.0.
-                 * Try to find an ethernet interface with no address set,
-                 * and send the packet through it.
-                 */
-                while (lwip_netif != NULL)
-                {
-                    if (ip4_addr_get_u32(&lwip_netif->ip_addr) == 0)
-                        break;
-                    lwip_netif = lwip_netif->next;
-                }
-
-                if (lwip_netif == NULL)
-                {
-                    /* Do a regular send. (This will most likely fail) */
-                    lwip_error = udp_sendto(AddressFile->lwip_udp_pcb, p, 
&IpAddr, Port);
-                }
-                else
-                {
-                    /* We found an interface with address being 0.0.0.0 */
-                    lwip_error = udp_sendto_if(AddressFile->lwip_udp_pcb, p, 
&IpAddr, Port, lwip_netif);
-                }
-            }
-            else
-            {
-                lwip_error = udp_sendto(AddressFile->lwip_udp_pcb, p, &IpAddr, 
Port);
-            }
-            break;
-        default:
-            lwip_error = raw_sendto(AddressFile->lwip_raw_pcb, p, &IpAddr);
-            break;
-    }
-
-    switch (lwip_error)
-    {
-        case ERR_OK:
-            Status = STATUS_SUCCESS;
-            Irp->IoStatus.Information = BufferLength;
-            break;
-        case ERR_MEM:
-        case ERR_BUF:
-            DPRINT1("Received ERR_MEM from lwip.\n");
-            Status = STATUS_INSUFFICIENT_RESOURCES;
-            break;
-        case ERR_RTE:
-            DPRINT1("Received ERR_RTE from lwip.\n");
-            Status = STATUS_INVALID_ADDRESS;
-            break;
-        case ERR_VAL:
-            DPRINT1("Received ERR_VAL from lwip.\n");
-            Status = STATUS_INVALID_PARAMETER;
-            break;
-        default:
-            DPRINT1("Received error %d from lwip.\n", lwip_error);
-            Status = STATUS_UNEXPECTED_NETWORK_ERROR;
-    }
+       _Inout_ PIRP Irp)
+{
+       PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+       ADDRESS_FILE *AddressFile;
+       PTDI_REQUEST_KERNEL_SENDDG RequestInfo;
+       NTSTATUS Status;
+       ip_addr_t IpAddr;
+       u16_t Port;
+       PVOID Buffer;
+       ULONG BufferLength;
+       struct pbuf* p = NULL;
+       err_t lwip_error;
+
+       /* Check this is really an address file */
+       if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != 
TDI_TRANSPORT_ADDRESS_FILE)
+       {
+               Status = STATUS_FILE_INVALID;
+               goto Finish;
+       }
+
+       /* Get the address file */
+       AddressFile = IrpSp->FileObject->FsContext;
+
+       if (AddressFile->Protocol == IPPROTO_TCP)
+       {
+               /* TCP has no such thing as datagrams */
+               DPRINT1("Received TDI_SEND_DATAGRAM for a TCP adress file.\n");
+               Status = STATUS_INVALID_ADDRESS;
+               goto Finish;
+       }
+
+       /* Get details about what we should be receiving */
+       RequestInfo = (PTDI_REQUEST_KERNEL_SENDDG)&IrpSp->Parameters;
+
+       /* Get the address */
+       if (RequestInfo->SendDatagramInformation->RemoteAddressLength != 0)
+       {
+               TDI_ADDRESS_IP Address;
+               Status = ExtractAddressFromList(
+                       RequestInfo->SendDatagramInformation->RemoteAddress,
+                       &Address);
+               if (!NT_SUCCESS(Status))
+                       goto Finish;
+               ip4_addr_set_u32(&IpAddr, Address.in_addr);
+               Port = lwip_ntohs(Address.sin_port);
+       }
+       else
+       {
+               ip_addr_set_any(&IpAddr);
+               Port = 0;
+       }
+
+       DPRINT1("Sending datagram to address 0x%08x, port %u\n", 
ip4_addr_get_u32(&IpAddr), lwip_ntohs(Port));
+
+       /* Get the buffer */
+       Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
+       BufferLength = MmGetMdlByteCount(Irp->MdlAddress);
+       p = pbuf_alloc(PBUF_RAW, BufferLength, PBUF_REF);
+       if (!p)
+       {
+               Status = STATUS_INSUFFICIENT_RESOURCES;
+               goto Finish;
+       }
+       p->payload = Buffer;
+
+       /* Send it for real */
+       switch (AddressFile->Protocol)
+       {
+               case IPPROTO_UDP:
+                       if (((ip4_addr_get_u32(&IpAddr) == IPADDR_ANY) ||
+                                       (ip4_addr_get_u32(&IpAddr) == 
IPADDR_BROADCAST)) &&
+                                       (Port == 67) && 
(AddressFile->Address.in_addr == 0))
+                       {
+                               struct netif* lwip_netif = netif_list;
+
+                               /*
+                                * This is a DHCP packet for an address file 
with address 0.0.0.0.
+                                * Try to find an ethernet interface with no 
address set,
+                                * and send the packet through it.
+                                */
+                               while (lwip_netif != NULL)
+                               {
+                                       if 
(ip4_addr_get_u32(&lwip_netif->ip_addr) == 0)
+                                               break;
+                                       lwip_netif = lwip_netif->next;
+                               }
+
+                               if (lwip_netif == NULL)
+                               {
+                                       /* Do a regular send. (This will most 
likely fail) */
+                                       lwip_error = 
udp_sendto(AddressFile->lwip_udp_pcb, p, &IpAddr, Port);
+                               }
+                               else
+                               {
+                                       /* We found an interface with address 
being 0.0.0.0 */
+                                       lwip_error = 
udp_sendto_if(AddressFile->lwip_udp_pcb, p, &IpAddr, Port, lwip_netif);
+                               }
+                       }
+                       else
+                       {
+                               lwip_error = 
udp_sendto(AddressFile->lwip_udp_pcb, p, &IpAddr, Port);
+                       }
+                       break;
+               default:
+                       lwip_error = raw_sendto(AddressFile->lwip_raw_pcb, p, 
&IpAddr);
+                       break;
+       }
+
+       switch (lwip_error)
+       {
+               case ERR_OK:
+                       Status = STATUS_SUCCESS;
+                       Irp->IoStatus.Information = BufferLength;
+                       break;
+               case ERR_MEM:
+               case ERR_BUF:
+                       DPRINT1("Received ERR_MEM from lwip.\n");
+                       Status = STATUS_INSUFFICIENT_RESOURCES;
+                       break;
+               case ERR_RTE:
+                       DPRINT1("Received ERR_RTE from lwip.\n");
+                       Status = STATUS_INVALID_ADDRESS;
+                       break;
+               case ERR_VAL:
+                       DPRINT1("Received ERR_VAL from lwip.\n");
+                       Status = STATUS_INVALID_PARAMETER;
+                       break;
+               default:
+                       DPRINT1("Received error %d from lwip.\n", lwip_error);
+                       Status = STATUS_UNEXPECTED_NETWORK_ERROR;
+       }
 
 Finish:
-    if (p)
-        pbuf_free(p);
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
-    return Status;
+       if (p)
+               pbuf_free(p);
+       Irp->IoStatus.Status = Status;
+       IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+       return Status;
 }
 
 NTSTATUS
 AddressSetIpDontFragment(
-    _In_ TDIEntityID ID,
-    _In_ PVOID InBuffer,
-    _In_ ULONG BufferSize)
-{
-    /* Silently ignore.
-     * lwip doesn't have such thing, and already tries to fragment data as 
less as possible */
-    return STATUS_SUCCESS;
+       _In_ TDIEntityID ID,
+       _In_ PVOID InBuffer,
+       _In_ ULONG BufferSize)
+{
+       /* Silently ignore.
+        * lwip doesn't have such thing, and already tries to fragment data as 
less as possible */
+       return STATUS_SUCCESS;
 }
 
 NTSTATUS
 AddressSetTtl(
-    _In_ TDIEntityID ID,
-    _In_ PVOID InBuffer,
-    _In_ ULONG BufferSize)
-{
-    ADDRESS_FILE* AddressFile;
-    TCPIP_INSTANCE* Instance;
-    NTSTATUS Status;
-    ULONG Value;
-
-    if (BufferSize < sizeof(ULONG))
-        return STATUS_BUFFER_TOO_SMALL;
-
-    /* Get the address file */
-    Status = GetInstance(ID, &Instance);
-    if (!NT_SUCCESS(Status))
-        return Status;
-
-    AddressFile = CONTAINING_RECORD(Instance, ADDRESS_FILE, Instance);
-
-    /* Get the value */
-    Value = *((ULONG*)InBuffer);
-
-    switch (AddressFile->Protocol)
-    {
-        case IPPROTO_TCP:
-            DPRINT1("TCP not supported yet.\n");
-            break;
-        case IPPROTO_UDP:
-            AddressFile->lwip_udp_pcb->ttl = Value;
-            break;
-        default:
-            AddressFile->lwip_raw_pcb->ttl = Value;
-            break;
-    }
-
-    return STATUS_SUCCESS;
-}
+       _In_ TDIEntityID ID,
+       _In_ PVOID InBuffer,
+       _In_ ULONG BufferSize)
+{
+       ADDRESS_FILE* AddressFile;
+       TCPIP_INSTANCE* Instance;
+       NTSTATUS Status;
+       ULONG Value;
+
+       if (BufferSize < sizeof(ULONG))
+               return STATUS_BUFFER_TOO_SMALL;
+
+       /* Get the address file */
+       Status = GetInstance(ID, &Instance);
+       if (!NT_SUCCESS(Status))
+               return Status;
+
+       AddressFile = CONTAINING_RECORD(Instance, ADDRESS_FILE, Instance);
+
+       /* Get the value */
+       Value = *((ULONG*)InBuffer);
+
+       switch (AddressFile->Protocol)
+       {
+               case IPPROTO_TCP:
+                       DPRINT1("TCP not supported yet.\n");
+                       break;
+               case IPPROTO_UDP:
+                       AddressFile->lwip_udp_pcb->ttl = Value;
+                       break;
+               default:
+                       AddressFile->lwip_raw_pcb->ttl = Value;
+                       break;
+       }
+
+       return STATUS_SUCCESS;
+}

Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h?rev=71865&r1=71864&r2=71865&view=diff
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h       
[iso-8859-1] (original)
+++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h       
[iso-8859-1] Fri Jul  8 17:52:42 2016
@@ -9,18 +9,19 @@
 #define TCP_REQUEST_PENDING_SEND    1
 #define TCP_REQUEST_PENDING_RECEIVE 2
 
-#define TCP_STATE_CREATED    0x1 << 0
-#define TCP_STATE_BOUND      0x1 << 1
-#define TCP_STATE_LISTENING  0x1 << 2
-#define TCP_STATE_ACCEPTED   0x1 << 3
-#define TCP_STATE_RECEIVING  0x1 << 4
-#define TCP_STATE_ABORTED    0x1 << 5
-#define TCP_STATE_CONNECTING 0x1 << 6
-#define TCP_STATE_CONNECTED  0x1 << 7
-#define TCP_STATE_SENDING    0x1 << 8
+#define TCP_STATE_CREATED       0x1 << 0
+#define TCP_STATE_BOUND         0x1 << 1
+#define TCP_STATE_LISTENING     0x1 << 2
+#define TCP_STATE_ACCEPTED      0x1 << 3
+#define TCP_STATE_RECEIVING     0x1 << 4
+#define TCP_STATE_ABORTED       0x1 << 5
+#define TCP_STATE_CONNECTING    0x1 << 6
+#define TCP_STATE_CONNECTED     0x1 << 7
+#define TCP_STATE_SENDING       0x1 << 8
+#define TCP_STATE_DISASSOCIATED 0x1 << 9
 
 typedef struct _ADDRESS_FILE {
-       UCHAR Type;
+       UCHAR Type; // must be the first member
     LIST_ENTRY ListEntry;
     LONG RefCount;
        LONG ContextCount;
@@ -46,7 +47,7 @@
 } ADDRESS_FILE, *PADDRESS_FILE;
 
 typedef struct _TCP_CONTEXT {
-       UCHAR Type;
+       UCHAR Type; // must be the first member
        LIST_ENTRY ListEntry;
        PADDRESS_FILE AddressFile;
        IPPROTO Protocol;

Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c?rev=71865&r1=71864&r2=71865&view=diff
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c  [iso-8859-1] 
(original)
+++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c  [iso-8859-1] 
Fri Jul  8 17:52:42 2016
@@ -360,7 +360,6 @@
     {
         case TDI_TRANSPORT_ADDRESS_FILE:
                        DPRINT1("TCPIP Close Transport Address\n");
-               
             if (!IrpSp->FileObject->FsContext)
             {
                 DPRINT1("TCPIP: Got a close request without a file to 
close!\n");


Reply via email to