- Update to r53061
[reactos.git] / drivers / network / tcpip / tcpip / main.c
index 19c5a67..034b9df 100644 (file)
@@ -24,8 +24,6 @@ UDP_STATISTICS UDPStats;
 /* Network timers */
 KTIMER IPTimer;
 KDPC IPTimeoutDpc;
-KSPIN_LOCK IpWorkLock;
-WORK_QUEUE_ITEM IpWorkItem;
 
 VOID TiWriteErrorLog(
     PDRIVER_OBJECT DriverContext,
@@ -48,7 +46,7 @@ VOID TiWriteErrorLog(
  *     DumpData         = Pointer to dump data for the log entry
  */
 {
-#ifdef _MSC_VER
+#if 0
     PIO_ERROR_LOG_PACKET LogEntry;
     UCHAR EntrySize;
     ULONG StringSize;
@@ -107,179 +105,161 @@ NTSTATUS TiCreateFileObject(
   PDEVICE_OBJECT DeviceObject,
   PIRP Irp)
 {
-  PFILE_FULL_EA_INFORMATION EaInfo;
-  PTRANSPORT_CONTEXT Context;
-  PIO_STACK_LOCATION IrpSp;
-  PTA_IP_ADDRESS Address;
-  TDI_REQUEST Request;
-  PVOID ClientContext;
-  NTSTATUS Status;
-  ULONG Protocol;
-
-  TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp));
-
-  EaInfo = Irp->AssociatedIrp.SystemBuffer;
-CP
-  /* Parameter check */
-  /* No EA information means that we're opening for SET/QUERY_INFORMATION
-   * style calls. */
-#if 0
-  if (!EaInfo) {
-    TI_DbgPrint(MIN_TRACE, ("No EA information in IRP.\n"));
-    return STATUS_INVALID_PARAMETER;
-  }
-#endif
-CP
-  /* Allocate resources here. We release them again if something failed */
-  Context = ExAllocatePool(NonPagedPool, sizeof(TRANSPORT_CONTEXT));
-  if (!Context) {
-    TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
-    return STATUS_INSUFFICIENT_RESOURCES;
-  }
-CP
-  Context->CancelIrps = FALSE;
-  KeInitializeEvent(&Context->CleanupEvent, NotificationEvent, FALSE);
-CP
-  IrpSp = IoGetCurrentIrpStackLocation(Irp);
-  IrpSp->FileObject->FsContext = Context;
-  Request.RequestContext       = Irp;
-CP
-  /* Branch to the right handler */
-  if (EaInfo &&
-      (EaInfo->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH) &&
-      (RtlCompareMemory
-       (&EaInfo->EaName, TdiTransportAddress,
-       TDI_TRANSPORT_ADDRESS_LENGTH) == TDI_TRANSPORT_ADDRESS_LENGTH)) {
-    /* This is a request to open an address */
-CP
-
-       /* XXX This should probably be done in IoCreateFile() */
-    /* Parameter checks */
-
-    Address = (PTA_IP_ADDRESS)(EaInfo->EaName + EaInfo->EaNameLength + 1); //0-term
-
-    if ((EaInfo->EaValueLength < sizeof(TA_IP_ADDRESS)) ||
-      (Address->TAAddressCount != 1) ||
-      (Address->Address[0].AddressLength < TDI_ADDRESS_LENGTH_IP) ||
-      (Address->Address[0].AddressType != TDI_ADDRESS_TYPE_IP)) {
-      TI_DbgPrint(MIN_TRACE, ("Parameters are invalid:\n"));
-      TI_DbgPrint(MIN_TRACE, ("AddressCount: %d\n", Address->TAAddressCount));
-      if( Address->TAAddressCount == 1 ) {
-         TI_DbgPrint(MIN_TRACE, ("AddressLength: %\n",
-                                 Address->Address[0].AddressLength));
-         TI_DbgPrint(MIN_TRACE, ("AddressType: %\n",
-                                 Address->Address[0].AddressType));
-      }
-      PoolFreeBuffer(Context);
-      return STATUS_INVALID_PARAMETER;
-    }
-CP
-    /* Open address file object */
-
-    /* Protocol depends on device object so find the protocol */
-    if (DeviceObject == TCPDeviceObject)
-      Protocol = IPPROTO_TCP;
-    else if (DeviceObject == UDPDeviceObject)
-      Protocol = IPPROTO_UDP;
-    else if (DeviceObject == IPDeviceObject)
-      Protocol = IPPROTO_RAW;
-    else if (DeviceObject == RawIPDeviceObject) {
-      Status = TiGetProtocolNumber(&IrpSp->FileObject->FileName, &Protocol);
-      if (!NT_SUCCESS(Status)) {
-        TI_DbgPrint(MIN_TRACE, ("Raw IP protocol number is invalid.\n"));
-        PoolFreeBuffer(Context);
-        return STATUS_INVALID_PARAMETER;
-      }
-    } else {
-      TI_DbgPrint(MIN_TRACE, ("Invalid device object at (0x%X).\n", DeviceObject));
-      PoolFreeBuffer(Context);
-      return STATUS_INVALID_PARAMETER;
-    }
-CP
-    Status = FileOpenAddress(&Request, Address, Protocol, NULL);
-    if (NT_SUCCESS(Status)) {
-      IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE;
-      Context->Handle.AddressHandle = Request.Handle.AddressHandle;
-    }
-CP
-  } else if (EaInfo &&
-            (EaInfo->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH) &&
-            (RtlCompareMemory
-             (&EaInfo->EaName, TdiConnectionContext,
-              TDI_CONNECTION_CONTEXT_LENGTH) ==
-             TDI_CONNECTION_CONTEXT_LENGTH)) {
-    /* This is a request to open a connection endpoint */
-CP
-    /* Parameter checks */
-
-    if (EaInfo->EaValueLength < sizeof(PVOID)) {
-      TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
-      PoolFreeBuffer(Context);
-      return STATUS_INVALID_PARAMETER;
-    }
-
-    /* Can only do connection oriented communication using TCP */
-
-    if (DeviceObject != TCPDeviceObject) {
-      TI_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
-      PoolFreeBuffer(Context);
-      return STATUS_INVALID_PARAMETER;
+    PFILE_FULL_EA_INFORMATION EaInfo;
+    PTRANSPORT_CONTEXT Context;
+    PIO_STACK_LOCATION IrpSp;
+    PTA_IP_ADDRESS Address;
+    TDI_REQUEST Request;
+    PVOID ClientContext;
+    NTSTATUS Status;
+    ULONG Protocol;
+
+    TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp));
+
+    EaInfo = Irp->AssociatedIrp.SystemBuffer;
+
+    /* Parameter check */
+    /* No EA information means that we're opening for SET/QUERY_INFORMATION
+    * style calls. */
+
+    /* Allocate resources here. We release them again if something failed */
+    Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(TRANSPORT_CONTEXT),
+                                    TRANS_CONTEXT_TAG);
+    if (!Context)
+    {
+        TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+        return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-    ClientContext = *((PVOID*)(EaInfo->EaName + EaInfo->EaNameLength));
+    Context->CancelIrps = FALSE;
 
-    /* Open connection endpoint file object */
+    IrpSp = IoGetCurrentIrpStackLocation(Irp);
+    IrpSp->FileObject->FsContext = Context;
+    Request.RequestContext       = Irp;
+
+    /* Branch to the right handler */
+    if (EaInfo &&
+        (EaInfo->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH) &&
+        (RtlCompareMemory(&EaInfo->EaName, TdiTransportAddress,
+        TDI_TRANSPORT_ADDRESS_LENGTH) == TDI_TRANSPORT_ADDRESS_LENGTH))
+    {
+        /* This is a request to open an address */
+
+
+        /* XXX This should probably be done in IoCreateFile() */
+        /* Parameter checks */
+
+        Address = (PTA_IP_ADDRESS)(EaInfo->EaName + EaInfo->EaNameLength + 1); //0-term
+
+        if ((EaInfo->EaValueLength < sizeof(TA_IP_ADDRESS)) ||
+            (Address->TAAddressCount != 1) ||
+            (Address->Address[0].AddressLength < TDI_ADDRESS_LENGTH_IP) ||
+            (Address->Address[0].AddressType != TDI_ADDRESS_TYPE_IP))
+        {
+            TI_DbgPrint(MIN_TRACE, ("Parameters are invalid:\n"));
+            TI_DbgPrint(MIN_TRACE, ("AddressCount: %d\n", Address->TAAddressCount));
+            if( Address->TAAddressCount == 1 )
+            {
+                   TI_DbgPrint(MIN_TRACE, ("AddressLength: %\n",
+                                           Address->Address[0].AddressLength));
+                   TI_DbgPrint(MIN_TRACE, ("AddressType: %\n",
+                                           Address->Address[0].AddressType));
+            }
+
+            ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
+            return STATUS_INVALID_PARAMETER;
+        }
+
+        /* Open address file object */
+
+        /* Protocol depends on device object so find the protocol */
+        if (DeviceObject == TCPDeviceObject)
+            Protocol = IPPROTO_TCP;
+        else if (DeviceObject == UDPDeviceObject)
+            Protocol = IPPROTO_UDP;
+        else if (DeviceObject == IPDeviceObject)
+            Protocol = IPPROTO_RAW;
+        else if (DeviceObject == RawIPDeviceObject)
+        {
+            Status = TiGetProtocolNumber(&IrpSp->FileObject->FileName, &Protocol);
+            if (!NT_SUCCESS(Status))
+            {
+                TI_DbgPrint(MIN_TRACE, ("Raw IP protocol number is invalid.\n"));
+                ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
+                return STATUS_INVALID_PARAMETER;
+            }
+        }
+        else
+        {
+            TI_DbgPrint(MIN_TRACE, ("Invalid device object at (0x%X).\n", DeviceObject));
+            ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
+            return STATUS_INVALID_PARAMETER;
+        }
+
+        Status = FileOpenAddress(&Request, Address, Protocol, NULL);
+        if (NT_SUCCESS(Status))
+        {
+            IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE;
+            Context->Handle.AddressHandle = Request.Handle.AddressHandle;
+        }
 
-    Status = FileOpenConnection(&Request, ClientContext);
-    if (NT_SUCCESS(Status)) {
-      IrpSp->FileObject->FsContext2 = (PVOID)TDI_CONNECTION_FILE;
-      Context->Handle.ConnectionContext = Request.Handle.ConnectionContext;
     }
-  } else {
-    /* This is a request to open a control connection */
-    Status = FileOpenControlChannel(&Request);
-    if (NT_SUCCESS(Status)) {
-      IrpSp->FileObject->FsContext2 = (PVOID)TDI_CONTROL_CHANNEL_FILE;
-      Context->Handle.ControlChannel = Request.Handle.ControlChannel;
+    else if (EaInfo &&
+               (EaInfo->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH) &&
+               (RtlCompareMemory
+               (&EaInfo->EaName, TdiConnectionContext,
+               TDI_CONNECTION_CONTEXT_LENGTH) ==
+               TDI_CONNECTION_CONTEXT_LENGTH))
+    {
+        /* This is a request to open a connection endpoint */
+
+        /* Parameter checks */
+
+        if (EaInfo->EaValueLength < sizeof(PVOID))
+        {
+            TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
+            ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
+            return STATUS_INVALID_PARAMETER;
+        }
+
+        /* Can only do connection oriented communication using TCP */
+
+        if (DeviceObject != TCPDeviceObject)
+        {
+            TI_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
+            ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
+            return STATUS_INVALID_PARAMETER;
+        }
+
+        ClientContext = *((PVOID*)(EaInfo->EaName + EaInfo->EaNameLength));
+
+        /* Open connection endpoint file object */
+
+        Status = FileOpenConnection(&Request, ClientContext);
+        if (NT_SUCCESS(Status))
+        {
+            IrpSp->FileObject->FsContext2 = (PVOID)TDI_CONNECTION_FILE;
+            Context->Handle.ConnectionContext = Request.Handle.ConnectionContext;
+        }
+    }
+    else
+    {
+        /* This is a request to open a control connection */
+        Status = FileOpenControlChannel(&Request);
+        if (NT_SUCCESS(Status))
+        {
+            IrpSp->FileObject->FsContext2 = (PVOID)TDI_CONTROL_CHANNEL_FILE;
+            Context->Handle.ControlChannel = Request.Handle.ControlChannel;
+        }
     }
-  }
-
-  if (!NT_SUCCESS(Status))
-    PoolFreeBuffer(Context);
-
-  TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
-
-  Irp->IoStatus.Status = Status;
-  return Status;
-}
-
-
-VOID TiCleanupFileObjectComplete(
-  PVOID Context,
-  NTSTATUS Status)
-/*
- * FUNCTION: Completes an object cleanup IRP I/O request
- * ARGUMENTS:
- *     Context = Pointer to the IRP for this request
- *     Status  = Final status of the operation
- */
-{
-  PIRP Irp;
-  PIO_STACK_LOCATION IrpSp;
-  PTRANSPORT_CONTEXT TranContext;
-  KIRQL OldIrql;
-
-  Irp         = (PIRP)Context;
-  IrpSp       = IoGetCurrentIrpStackLocation(Irp);
-  TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
-
-  Irp->IoStatus.Status = Status;
 
-  IoAcquireCancelSpinLock(&OldIrql);
+    if (!NT_SUCCESS(Status))
+        ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
 
-  KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
+    TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
 
-  IoReleaseCancelSpinLock(OldIrql);
+    Irp->IoStatus.Status = Status;
+    return Status;
 }
 
 
@@ -293,80 +273,52 @@ VOID TiCleanupFileObjectComplete(
  * NOTES:
  *     This function does not pend
  */
-NTSTATUS TiCleanupFileObject(
+NTSTATUS TiCloseFileObject(
   PDEVICE_OBJECT DeviceObject,
   PIRP Irp)
 {
-  PIO_STACK_LOCATION IrpSp;
-  PTRANSPORT_CONTEXT Context;
-  TDI_REQUEST Request;
-  NTSTATUS Status;
-  KIRQL OldIrql;
-
-  IrpSp   = IoGetCurrentIrpStackLocation(Irp);
-  Context = IrpSp->FileObject->FsContext;
-  if (!Context) {
-    TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
-    return STATUS_INVALID_PARAMETER;
-  }
-
-  IoAcquireCancelSpinLock(&OldIrql);
-
-  Context->CancelIrps = TRUE;
-  KeResetEvent(&Context->CleanupEvent);
-
-  IoReleaseCancelSpinLock(OldIrql);
-
-  Request.RequestNotifyObject = TiCleanupFileObjectComplete;
-  Request.RequestContext      = Irp;
-
-  switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
-  case TDI_TRANSPORT_ADDRESS_FILE:
-    Request.Handle.AddressHandle = Context->Handle.AddressHandle;
-    Status = FileCloseAddress(&Request);
-    break;
-
-  case TDI_CONNECTION_FILE:
-    Request.Handle.ConnectionContext = Context->Handle.ConnectionContext;
-    Status = FileCloseConnection(&Request);
-    break;
-
-  case TDI_CONTROL_CHANNEL_FILE:
-    Request.Handle.ControlChannel = Context->Handle.ControlChannel;
-    Status = FileCloseControlChannel(&Request);
-    break;
-
-  default:
-    /* This should never happen */
-
-    TI_DbgPrint(MIN_TRACE, ("Unknown transport context.\n"));
+    PIO_STACK_LOCATION IrpSp;
+    PTRANSPORT_CONTEXT Context;
+    TDI_REQUEST Request;
+    NTSTATUS Status;
+
+    IrpSp   = IoGetCurrentIrpStackLocation(Irp);
+    Context = IrpSp->FileObject->FsContext;
+    if (!Context)
+    {
+        TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
+        return STATUS_INVALID_PARAMETER;
+    }
 
-    IoAcquireCancelSpinLock(&OldIrql);
-    Context->CancelIrps = FALSE;
-    IoReleaseCancelSpinLock(OldIrql);
+    switch ((ULONG_PTR)IrpSp->FileObject->FsContext2)
+    {
+        case TDI_TRANSPORT_ADDRESS_FILE:
+            Request.Handle.AddressHandle = Context->Handle.AddressHandle;
+            Status = FileCloseAddress(&Request);
+            break;
+
+        case TDI_CONNECTION_FILE:
+            Request.Handle.ConnectionContext = Context->Handle.ConnectionContext;
+            Status = FileCloseConnection(&Request);
+            break;
+
+        case TDI_CONTROL_CHANNEL_FILE:
+            Request.Handle.ControlChannel = Context->Handle.ControlChannel;
+            Status = FileCloseControlChannel(&Request);
+            break;
+
+        default:
+            Status = STATUS_INVALID_PARAMETER;
+            break;
+    }
 
-    Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+    Irp->IoStatus.Status = Status;
 
     return Irp->IoStatus.Status;
-  }
-
-  if (Status != STATUS_PENDING)
-  {
-     IoAcquireCancelSpinLock(&OldIrql);
-     KeSetEvent(&Context->CleanupEvent, 0, FALSE);
-     IoReleaseCancelSpinLock(OldIrql);
-
-     KeWaitForSingleObject(&Context->CleanupEvent,
-        UserRequest, KernelMode, FALSE, NULL);
-  }
-
-  Irp->IoStatus.Status = Status;
-
-  return Irp->IoStatus.Status;
 }
 
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 TiDispatchOpenClose(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp)
@@ -381,9 +333,6 @@ TiDispatchOpenClose(
 {
   PIO_STACK_LOCATION IrpSp;
   NTSTATUS Status;
-  PTRANSPORT_CONTEXT Context;
-
-  RIRP(Irp);
 
 //  DbgPrint("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp);
 
@@ -397,16 +346,7 @@ TiDispatchOpenClose(
 
   /* Close an address file, connection endpoint, or control connection */
   case IRP_MJ_CLOSE:
-    Context = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
-    if (Context)
-        PoolFreeBuffer(Context);
-    Status = STATUS_SUCCESS;
-    break;
-
-  /* Release resources bound to an address file, connection endpoint,
-     or control connection */
-  case IRP_MJ_CLEANUP:
-    Status = TiCleanupFileObject(DeviceObject, Irp);
+    Status = TiCloseFileObject(DeviceObject, Irp);
     break;
 
   default:
@@ -433,14 +373,12 @@ TiDispatchInternal(
  */
 {
   NTSTATUS Status;
-  BOOL Complete = TRUE;
+  BOOLEAN Complete = TRUE;
   PIO_STACK_LOCATION IrpSp;
 
-  RIRP(Irp);
-
   IrpSp = IoGetCurrentIrpStackLocation(Irp);
 
-  TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatchInternal] Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
     DeviceObject, Irp, IrpSp->MinorFunction));
 
   Irp->IoStatus.Status      = STATUS_SUCCESS;
@@ -483,6 +421,7 @@ TiDispatchInternal(
 
   case TDI_DISCONNECT:
     Status = DispTdiDisconnect(Irp);
+    Complete = FALSE;
     break;
 
   case TDI_ASSOCIATE_ADDRESS:
@@ -514,12 +453,10 @@ TiDispatchInternal(
     Status = STATUS_INVALID_DEVICE_REQUEST;
   }
 
-  TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatchInternal] Leaving. Status = (0x%X).\n", Status));
 
   if( Complete )
       IRPFinish( Irp, Status );
-  else
-      Irp->IoStatus.Status = Status;
 
   return Status;
 }
@@ -541,15 +478,13 @@ TiDispatch(
   NTSTATUS Status;
   PIO_STACK_LOCATION IrpSp;
 
-  RIRP(Irp);
-
   IrpSp  = IoGetCurrentIrpStackLocation(Irp);
 
-  TI_DbgPrint(DEBUG_IRP, ("Called. IRP is at (0x%X).\n", Irp));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Called. IRP is at (0x%X).\n", Irp));
 
   Irp->IoStatus.Information = 0;
 
-#ifdef _MSC_VER
+#if 0
   Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp);
   if (NT_SUCCESS(Status)) {
     TiDispatchInternal(DeviceObject, Irp);
@@ -588,13 +523,13 @@ TiDispatch(
     }
   }
 
-  TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Leaving. Status = (0x%X).\n", Status));
 
   return IRPFinish( Irp, Status );
 }
 
 
-VOID STDCALL TiUnload(
+VOID NTAPI TiUnload(
   PDRIVER_OBJECT DriverObject)
 /*
  * FUNCTION: Unloads the driver
@@ -602,17 +537,15 @@ VOID STDCALL TiUnload(
  *     DriverObject = Pointer to driver object created by the system
  */
 {
-#ifdef DBG
+#if DBG
   KIRQL OldIrql;
 
   TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
   if (!IsListEmpty(&AddressFileListHead)) {
-    TI_DbgPrint(MIN_TRACE, ("Open address file objects exists.\n"));
+    TI_DbgPrint(MIN_TRACE, ("[TCPIP, TiUnload] Called. Open address file objects exists.\n"));
   }
   TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
 #endif
-  ChewShutdown();
-
   /* Cancel timer */
   KeCancelTimer(&IPTimer);
 
@@ -626,13 +559,11 @@ VOID STDCALL TiUnload(
   TCPShutdown();
   UDPShutdown();
   RawIPShutdown();
+  ICMPShutdown();
 
   /* Shutdown network level protocol subsystem */
   IPShutdown();
 
-  /* Shutdown the lan worker */
-  LANShutdown();
-
   /* Free NDIS buffer descriptors */
   if (GlobalBufferPool)
     NdisFreeBufferPool(GlobalBufferPool);
@@ -652,35 +583,15 @@ VOID STDCALL TiUnload(
   if (RawIPDeviceObject)
     IoDeleteDevice(RawIPDeviceObject);
 
-  if (IPDeviceObject)
-    IoDeleteDevice(IPDeviceObject);
+  if (IPDeviceObject) {
+     ChewShutdown();
+     IoDeleteDevice(IPDeviceObject);
+  }
 
   if (EntityList)
-    PoolFreeBuffer(EntityList);
-
-  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
-}
+    ExFreePoolWithTag(EntityList, TDI_ENTITY_TAG);
 
-VOID STDCALL IPTimeoutDpcFn(
-    PKDPC Dpc,
-    PVOID DeferredContext,
-    PVOID SystemArgument1,
-    PVOID SystemArgument2)
-/*
- * FUNCTION: Timeout DPC
- * ARGUMENTS:
- *     Dpc             = Pointer to our DPC object
- *     DeferredContext = Pointer to context information (unused)
- *     SystemArgument1 = Unused
- *     SystemArgument2 = Unused
- * NOTES:
- *     This routine is dispatched once in a while to do maintainance jobs
- */
-{
-    if( !IpWorkItemQueued ) {
-       ExQueueWorkItem( &IpWorkItem, CriticalWorkQueue );
-       IpWorkItemQueued = TRUE;
-    }
+  TI_DbgPrint(MAX_TRACE, ("[TCPIP, TiUnload] Leaving.\n"));
 }
 
 NTSTATUS NTAPI
@@ -705,23 +616,23 @@ DriverEntry(
   NDIS_STATUS NdisStatus;
   LARGE_INTEGER DueTime;
 
-  TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
-  TrackingInit();
-  TrackTag(NDIS_BUFFER_TAG);
-  TrackTag(NDIS_PACKET_TAG);
-  TrackTag(FBSD_MALLOC);
-  TrackTag(EXALLOC_TAG);
+  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Called\n"));
 
   /* TdiInitialize() ? */
 
   /* FIXME: Create symbolic links in Win32 namespace */
 
+  /* Initialize our periodic timer and its associated DPC object. When the
+     timer expires, the IPTimeout deferred procedure call (DPC) is queued */
+  KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
+  KeInitializeTimer(&IPTimer);
+
   /* Create IP device object */
   Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName,
     FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject);
   if (!NT_SUCCESS(Status)) {
     TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status));
+    TiUnload(DriverObject);
     return Status;
   }
 
@@ -756,35 +667,27 @@ DriverEntry(
 
   /* Setup network layer and transport layer entities */
   KeInitializeSpinLock(&EntityListLock);
-  EntityList = ExAllocatePool(NonPagedPool, sizeof(TDIEntityID) * MAX_TDI_ENTITIES );
-  if (!NT_SUCCESS(Status)) {
-         TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+  EntityList = ExAllocatePoolWithTag(NonPagedPool,
+                                     sizeof(TDIEntityID) * MAX_TDI_ENTITIES,
+                                     TDI_ENTITY_TAG );
+  if (!EntityList) {
+    TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
     TiUnload(DriverObject);
     return STATUS_INSUFFICIENT_RESOURCES;
   }
 
-  EntityList[0].tei_entity   = CL_NL_ENTITY;
-  EntityList[0].tei_instance = 0;
-  EntityList[0].context      = 0;
-  EntityList[0].info_req     = InfoNetworkLayerTdiQueryEx;
-  EntityList[0].info_set     = InfoNetworkLayerTdiSetEx;
-  EntityList[1].tei_entity   = CL_TL_ENTITY;
-  EntityList[1].tei_instance = 0;
-  EntityList[1].context      = 0;
-  EntityList[1].info_req     = InfoTransportLayerTdiQueryEx;
-  EntityList[1].info_set     = InfoTransportLayerTdiSetEx;
-  EntityCount = 2;
+  EntityCount = 0;
   EntityMax   = MAX_TDI_ENTITIES;
 
   /* Allocate NDIS packet descriptors */
-  NdisAllocatePacketPool(&NdisStatus, &GlobalPacketPool, 100, sizeof(PACKET_CONTEXT));
+  NdisAllocatePacketPoolEx(&NdisStatus, &GlobalPacketPool, 500, 1500, sizeof(PACKET_CONTEXT));
   if (NdisStatus != NDIS_STATUS_SUCCESS) {
     TiUnload(DriverObject);
     return STATUS_INSUFFICIENT_RESOURCES;
   }
 
   /* Allocate NDIS buffer descriptors */
-  NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 100);
+  NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 2000);
   if (NdisStatus != NDIS_STATUS_SUCCESS) {
     TiUnload(DriverObject);
     return STATUS_INSUFFICIENT_RESOURCES;
@@ -806,35 +709,28 @@ DriverEntry(
   IPStartup(RegistryPath);
 
   /* Initialize transport level protocol subsystems */
-  RawIPStartup();
-  UDPStartup();
-  TCPStartup();
+  Status = RawIPStartup();
+  if( !NT_SUCCESS(Status) ) {
+      TiUnload(DriverObject);
+      return Status;
+  }
 
-  /* Initialize the lan worker */
-  LANStartup();
+  Status = UDPStartup();
+  if( !NT_SUCCESS(Status) ) {
+      TiUnload(DriverObject);
+      return Status;
+  }
 
-  /* Register protocol with NDIS */
-  /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
-  Status = LANRegisterProtocol(&strNdisDeviceName);
-  if (!NT_SUCCESS(Status)) {
-         TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status));
-         TiWriteErrorLog(
-      DriverObject,
-      EVENT_TRANSPORT_REGISTER_FAILED,
-      TI_ERROR_DRIVERENTRY,
-      Status,
-      NULL,
-      0,
-      NULL);
-    TiUnload(DriverObject);
-    return Status;
+  Status = TCPStartup();
+  if( !NT_SUCCESS(Status) ) {
+      TiUnload(DriverObject);
+      return Status;
   }
 
-  /* Open loopback adapter */
-  if (!NT_SUCCESS(LoopRegisterAdapter(NULL, NULL))) {
-    TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
-    TiUnload(DriverObject);
-    return STATUS_INSUFFICIENT_RESOURCES;
+  Status = ICMPStartup();
+  if( !NT_SUCCESS(Status) ) {
+      TiUnload(DriverObject);
+      return Status;
   }
 
   /* Use direct I/O */
@@ -846,34 +742,54 @@ DriverEntry(
   /* Initialize the driver object with this driver's entry points */
   DriverObject->MajorFunction[IRP_MJ_CREATE]  = TiDispatchOpenClose;
   DriverObject->MajorFunction[IRP_MJ_CLOSE]   = TiDispatchOpenClose;
-  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TiDispatchOpenClose;
   DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = TiDispatchInternal;
   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TiDispatch;
 
   DriverObject->DriverUnload = TiUnload;
 
-  /* Initialize our periodic timer and its associated DPC object. When the
-     timer expires, the IPTimeout deferred procedure call (DPC) is queued */
-  ExInitializeWorkItem( &IpWorkItem, IPTimeout, NULL );
-  KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
-  KeInitializeTimer(&IPTimer);
+  /* Open loopback adapter */
+  Status = LoopRegisterAdapter(NULL, NULL);
+  if (!NT_SUCCESS(Status)) {
+    TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
+    TiUnload(DriverObject);
+    return Status;
+  }
+
+  /* Register protocol with NDIS */
+  /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
+  Status = LANRegisterProtocol(&strNdisDeviceName);
+  if (!NT_SUCCESS(Status)) {
+         TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status));
+         TiWriteErrorLog(
+      DriverObject,
+      EVENT_TRANSPORT_REGISTER_FAILED,
+      TI_ERROR_DRIVERENTRY,
+      Status,
+      NULL,
+      0,
+      NULL);
+      TiUnload(DriverObject);
+      return Status;
+  }
 
   /* Start the periodic timer with an initial and periodic
      relative expiration time of IP_TIMEOUT milliseconds */
   DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000;
   KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc);
 
+  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Finished\n"));
+
+
   return STATUS_SUCCESS;
 }
 
-
 VOID NTAPI
 IPAddInterface(
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2,
-       DWORD   Unknown3,
-       DWORD   Unknown4)
+       ULONG   Unknown0,
+       ULONG   Unknown1,
+       ULONG   Unknown2,
+       ULONG   Unknown3,
+       ULONG   Unknown4)
 {
     UNIMPLEMENTED
 }
@@ -881,7 +797,7 @@ IPAddInterface(
 
 VOID NTAPI
 IPDelInterface(
-       DWORD   Unknown0)
+       ULONG   Unknown0)
 {
     UNIMPLEMENTED
 }
@@ -889,8 +805,8 @@ IPDelInterface(
 
 VOID NTAPI
 LookupRoute(
-       DWORD   Unknown0,
-       DWORD   Unknown1)
+       ULONG   Unknown0,
+       ULONG   Unknown1)
 {
     UNIMPLEMENTED
 }