Merge trunk r45185
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Thu, 21 Jan 2010 18:34:48 +0000 (18:34 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Thu, 21 Jan 2010 18:34:48 +0000 (18:34 +0000)
svn path=/branches/ros-amd64-bringup/; revision=45186

31 files changed:
1  2 
reactos/dll/win32/iphlpapi/iphlpapi_private.h
reactos/dll/win32/user32/include/user32p.h
reactos/dll/win32/user32/misc/misc.c
reactos/drivers/network/afd/afd/lock.c
reactos/drivers/network/afd/afd/main.c
reactos/drivers/network/dd/pcnet/pcnet.c
reactos/drivers/network/tcpip/datalink/lan.c
reactos/drivers/network/tcpip/tcpip.rbuild
reactos/drivers/network/tcpip/tcpip/dispatch.c
reactos/hal/halx86/hal_generic.rbuild
reactos/hal/halx86/hal_generic_up.rbuild
reactos/hal/halx86/include/halp.h
reactos/hal/halx86/mp/apic.c
reactos/hal/halx86/mp/i386/mps.S
reactos/hal/halx86/mp/i386/mpsboot.asm
reactos/hal/halx86/mp/mpsirql.c
reactos/hal/halx86/up/irq.S
reactos/include/psdk/winuser.h
reactos/include/reactos/win32k/ntuser.h
reactos/lib/drivers/ip/transport/tcp/tcp.c
reactos/lib/tdilib/tdilib.rbuild
reactos/ntoskrnl/include/internal/ke.h
reactos/ntoskrnl/include/internal/ke_x.h
reactos/ntoskrnl/ke/freeldr.c
reactos/ntoskrnl/ke/i386/cpu.c
reactos/ntoskrnl/ke/i386/ctxswitch.S
reactos/ntoskrnl/mm/ARM3/contmem.c
reactos/ntoskrnl/ntoskrnl-generic.rbuild
reactos/subsystems/win32/win32k/ntuser/message.c
reactos/subsystems/win32/win32k/objects/gdiobj.c
reactos/tools/rbuild/module.cpp

Simple merge
@@@ -203,8 -178,8 +178,8 @@@ VOID NTAPI DispCancelRequest
          break;
      }
  
-     IoReleaseCancelSpinLock(Irp->CancelIrql);
+     if (DequeuedIrp)
 -       IRPFinish(Irp, STATUS_CANCELLED);
 +    IRPFinish(Irp, STATUS_CANCELLED);
  
      TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
  }
@@@ -243,16 -219,12 +219,12 @@@ VOID NTAPI DispCancelListenRequest
      /* Try canceling the request */
      Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
  
-     TCPRemoveIRP(Connection, Irp);
-     TCPAbortListenForSocket(
-           Connection->AddressFile->Listener,
-           Connection );
-     IoReleaseCancelSpinLock(Irp->CancelIrql);
+     if (TCPAbortListenForSocket(Connection->AddressFile->Listener,
+                                 Connection))
+     {
 -        Irp->IoStatus.Information = 0;
 -        IRPFinish(Irp, STATUS_CANCELLED);
 +    Irp->IoStatus.Information = 0;
 +    IRPFinish(Irp, STATUS_CANCELLED);
+     }
  
      TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
  }
@@@ -765,15 -753,19 +753,19 @@@ NTSTATUS DispTdiQueryInformation
            return STATUS_INVALID_PARAMETER;
          }
  
-         Status = TCPGetSockAddress( Endpoint, AddressInfo->RemoteAddress, TRUE );
+         return TCPGetSockAddress( Endpoint, AddressInfo->RemoteAddress, TRUE );
+       }
+       case TDI_QUERY_MAX_DATAGRAM_INFO:
+       {
+          PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo = MmGetSystemAddressForMdl(Irp->MdlAddress);
+          MaxDatagramInfo->MaxDatagramSize = 0xFFFF;
  
-         TcpipRecursiveMutexLeave(&TCPLock);
-         return Status;
+          return STATUS_SUCCESS;
 -     }
 +      }
    }
  
-   TcpipRecursiveMutexLeave(&TCPLock);
    return STATUS_NOT_IMPLEMENTED;
  }
  
@@@ -1068,11 -1044,11 +1046,13 @@@ NTSTATUS DispTdiSendDatagram
                  DgramInfo->SendDatagramInformation,
                  DataBuffer,
                  BufferSize,
 -                &Irp->IoStatus.Information);
 +                &DataUsed);
 +            Irp->IoStatus.Information = DataUsed;
 +        }
-         else
+         else {
              Status = STATUS_UNSUCCESSFUL;
 -        }
+             ASSERT(FALSE);
++    }
      }
  
  done:
                        <file>profil.c</file>
                        <file>reboot.c</file>
                        <file>sysinfo.c</file>
 -                      <file>systimer.S</file>
                        <file>timer.c</file>
 -                      <file>usage.c</file>
 -                      <file>v86.s</file>
 +                      <if property="ARCH" value="i386">
 +                              <file>bios.c</file>
 +                              <file>halinit.c</file>
 +                              <file>misc.c</file>
 +                              <file>usage.c</file>
 +                              <directory name="i386">
 +                                      <file>portio.c</file>
 +                                      <file>systimer.S</file>
 +                                      <file>v86.s</file>
 +                              </directory>
 +                      </if>
 +                      <if property="ARCH" value="amd64">
 +                              <directory name="amd64">
 +                                      <file>halinit.c</file>
 +                                      <file>irq.S</file>
 +                                      <file>misc.c</file>
-                                       <file>pic.c</file>
 +                                      <file>systimer.S</file>
 +                                      <file>usage.c</file>
 +                                      <file>x86bios.c</file>
 +                              </directory>
 +                      </if>
                </directory>
 +              <if property="ARCH" value="amd64">
 +                      <directory name="mp">
 +                              <file>apic.c</file>
 +                      </directory>
 +              </if>
                <directory name="include">
                        <pch>hal.h</pch>
                </directory>
@@@ -6,13 -6,10 +6,14 @@@
                <include base="ntoskrnl">include</include>
                <define name="_NTHAL_" />
                <directory name="generic">
 -                      <file>irq.S</file>
 -                      <file>processor.c</file>
+                       <file>pic.c</file>
                        <file>spinlock.c</file>
                </directory>
 +              <directory name="up">
 +                      <file>processor.c</file>
 +                      <if property="ARCH" value="i386">
 +                              <file>irq.S</file>
 +                      </if>
 +              </directory>
        </module>
  </group>
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
  LONG TCP_IPIdentification = 0;
  static BOOLEAN TCPInitialized = FALSE;
  static NPAGED_LOOKASIDE_LIST TCPSegmentList;
- LIST_ENTRY SignalledConnectionsList;
- KSPIN_LOCK SignalledConnectionsLock;
- LIST_ENTRY SleepingThreadsList;
- FAST_MUTEX SleepingThreadsLock;
- RECURSIVE_MUTEX TCPLock;
  PORT_SET TCPPorts;
+ CLIENT_DATA ClientInfo;
  
- static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
-     NTSTATUS Status = STATUS_SUCCESS;
-     PTCP_COMPLETION_ROUTINE Complete;
+ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
+ {
 -        PTDI_BUCKET Bucket;
 -        PLIST_ENTRY Entry;
 +    PTDI_BUCKET Bucket;
 +    PLIST_ENTRY Entry;
+         NTSTATUS Status;
 -        PIRP Irp;
 -        PMDL Mdl;
 +    PIRP Irp;
 +    PMDL Mdl;
+         ULONG SocketError = 0;
+         KIRQL OldIrql;
+         PTCP_COMPLETION_ROUTINE Complete;
  
-     ASSERT_LOCKED(&TCPLock);
+         if (ClientInfo.Unlocked)
+             LockObjectAtDpcLevel(Connection);
  
 -        TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
 -                               Connection, Connection->SocketContext));
 +    TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
 +                           Connection, Connection->SocketContext));
  
 -        if( Connection->SignalState & SEL_FIN ) {
 -            TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
 +    if( Connection->SignalState & SEL_FIN ) {
 +        TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
  
-         while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
-                                                      &Connection->Lock )) != NULL)
+             /* If OskitTCP initiated the disconnect, try to read the socket error that occurred */
+             if (Connection->SocketContext)
+                 SocketError = TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
+             /* Default to STATUS_CANCELLED if we initiated the disconnect or no socket error was reported */
+             if (!Connection->SocketContext || !SocketError)
+                 SocketError = STATUS_CANCELLED;
+             while (!IsListEmpty(&Connection->ReceiveRequest))
 -            {
 +        {
-            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-            Complete = Bucket->Request.RequestNotifyObject;
+                Entry = RemoveHeadList( &Connection->ReceiveRequest );
  
-            /* We have to notify oskittcp of the abortion */
-            TCPDisconnect
-            ( Connection,
-              TDI_DISCONNECT_RELEASE | TDI_DISCONNECT_ABORT,
-              NULL,
-              NULL,
-              Bucket->Request.RequestNotifyObject,
-              (PIRP)Bucket->Request.RequestContext );
 -               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
++           Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
  
-            Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+                Bucket->Status = SocketError;
+                Bucket->Information = 0;
  
-            exFreePool(Bucket);
+                InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
 -            }
 +        }
  
-         while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
-                                                      &Connection->Lock )) != NULL)
+             while (!IsListEmpty(&Connection->SendRequest))
 -            {
 +        {
-            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-            Complete = Bucket->Request.RequestNotifyObject;
+                Entry = RemoveHeadList( &Connection->SendRequest );
  
-            /* We have to notify oskittcp of the abortion */
-            TCPDisconnect
-            ( Connection,
-              TDI_DISCONNECT_RELEASE,
-              NULL,
-              NULL,
-              Bucket->Request.RequestNotifyObject,
-              (PIRP)Bucket->Request.RequestContext );
 -               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
++           Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
  
-            Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+                Bucket->Status = SocketError;
+                Bucket->Information = 0;
  
-            exFreePool(Bucket);
+                InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
 -            }
 +        }
  
-         while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
-                                                      &Connection->Lock )) != NULL)
+             while (!IsListEmpty(&Connection->ListenRequest))
 -            {
 +        {
+                Entry = RemoveHeadList( &Connection->ListenRequest );
 -               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
 +           Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-            Complete = Bucket->Request.RequestNotifyObject;
  
-            /* We have to notify oskittcp of the abortion */
-            TCPAbortListenForSocket(Connection->AddressFile->Listener,
-                                Connection);
+                Bucket->Status = SocketError;
+                Bucket->Information = 0;
+                DereferenceObject(Bucket->AssociatedEndpoint);
  
-            Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+                InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
 -            }
 +        }
  
-         while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
-                                                      &Connection->Lock )) != NULL)
+             while (!IsListEmpty(&Connection->ConnectRequest))
 -            {
 +        {
+                Entry = RemoveHeadList( &Connection->ConnectRequest );
 -               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
 +           Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-            Complete = Bucket->Request.RequestNotifyObject;
  
-            Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+                Bucket->Status = SocketError;
+                Bucket->Information = 0;
+                InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
 -            }
 +        }
  
-         Connection->SignalState = 0;
+             Connection->SignalState = SEL_FIN;
          }
  
 -        /* Things that can happen when we try the initial connection */
 -        if( Connection->SignalState & SEL_CONNECT ) {
 +    /* Things that can happen when we try the initial connection */
 +    if( Connection->SignalState & SEL_CONNECT ) {
-         while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
-                                                      &Connection->Lock )) != NULL ) {
+             while (!IsListEmpty(&Connection->ConnectRequest)) {
+                Entry = RemoveHeadList( &Connection->ConnectRequest );
 -
 -               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
 +            
-             TI_DbgPrint(DEBUG_TCP, ("Connect Event\n"));
 +            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-             Complete = Bucket->Request.RequestNotifyObject;
-             TI_DbgPrint(DEBUG_TCP,
-                         ("Completing Request %x\n", Bucket->Request.RequestContext));
  
-             Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
+                Bucket->Status = STATUS_SUCCESS;
+                Bucket->Information = 0;
  
-             /* Frees the bucket allocated in TCPConnect */
-             exFreePool( Bucket );
+                InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
 -           }
 -       }
 +        }
 +    }
  
 -       if( Connection->SignalState & SEL_ACCEPT ) {
 -           /* Handle readable on a listening socket --
 -            * TODO: Implement filtering
 -            */
 -           TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n",
 -                                  Connection,
 -                                  IsListEmpty(&Connection->ListenRequest) ?
 -                                  "empty" : "nonempty"));
 +    if( Connection->SignalState & SEL_ACCEPT ) {
 +        /* Handle readable on a listening socket --
 +         * TODO: Implement filtering
 +         */
 +        TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n",
 +                               Connection,
 +                               IsListEmpty(&Connection->ListenRequest) ?
 +                               "empty" : "nonempty"));
  
-         while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
-                                                      &Connection->Lock )) != NULL ) {
+            while (!IsListEmpty(&Connection->ListenRequest)) {
 -               PIO_STACK_LOCATION IrpSp;
 +            PIO_STACK_LOCATION IrpSp;
  
 -               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+                Entry = RemoveHeadList( &Connection->ListenRequest );
-             Complete = Bucket->Request.RequestNotifyObject;
 +            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
  
 -               Irp = Bucket->Request.RequestContext;
 -               IrpSp = IoGetCurrentIrpStackLocation( Irp );
 +            Irp = Bucket->Request.RequestContext;
 +            IrpSp = IoGetCurrentIrpStackLocation( Irp );
  
 -               TI_DbgPrint(DEBUG_TCP,("Getting the socket\n"));
 +            TI_DbgPrint(DEBUG_TCP,("Getting the socket\n"));
 -               Status = TCPServiceListeningSocket
 -                   ( Connection->AddressFile->Listener,
 -                     Bucket->AssociatedEndpoint,
 -                     (PTDI_REQUEST_KERNEL)&IrpSp->Parameters );
 +            Status = TCPServiceListeningSocket
 +                ( Connection->AddressFile->Listener,
 +                  Bucket->AssociatedEndpoint,
 +                  (PTDI_REQUEST_KERNEL)&IrpSp->Parameters );
  
 -               TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
 +            TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
  
 -               if( Status == STATUS_PENDING ) {
 +            if( Status == STATUS_PENDING ) {
-                 ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, &Connection->Lock );
+                    InsertHeadList( &Connection->ListenRequest, &Bucket->Entry );
 -                   break;
 -               } else {
 +                break;
 +            } else {
-                 Complete( Bucket->Request.RequestContext, Status, 0 );
-                 exFreePool( Bucket );
+                    Bucket->Status = Status;
+                    Bucket->Information = 0;
+                    DereferenceObject(Bucket->AssociatedEndpoint);
+                    InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
 -               }
 -          }
 -      }
 +            }
 +        }
 +    }
  
 -      /* Things that happen after we're connected */
 -      if( Connection->SignalState & SEL_READ ) {
 -          TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
 -                                 IsListEmpty(&Connection->ReceiveRequest) ?
 -                                 "empty" : "nonempty"));
 +    /* Things that happen after we're connected */
 +    if( Connection->SignalState & SEL_READ ) {
 +        TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
 +                               IsListEmpty(&Connection->ReceiveRequest) ?
 +                               "empty" : "nonempty"));
  
-         while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
-                                                      &Connection->Lock )) != NULL ) {
+            while (!IsListEmpty(&Connection->ReceiveRequest)) {
 -               OSK_UINT RecvLen = 0, Received = 0;
 -               PVOID RecvBuffer = 0;
 +            OSK_UINT RecvLen = 0, Received = 0;
 +            PVOID RecvBuffer = 0;
  
 -               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+                Entry = RemoveHeadList( &Connection->ReceiveRequest );
-             Complete = Bucket->Request.RequestNotifyObject;
 +            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
  
 -               Irp = Bucket->Request.RequestContext;
 -               Mdl = Irp->MdlAddress;
 +            Irp = Bucket->Request.RequestContext;
 +            Mdl = Irp->MdlAddress;
  
 -               TI_DbgPrint(DEBUG_TCP,
 -                           ("Getting the user buffer from %x\n", Mdl));
 +            TI_DbgPrint(DEBUG_TCP,
 +                        ("Getting the user buffer from %x\n", Mdl));
  
 -               NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
 +            NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
  
 -               TI_DbgPrint(DEBUG_TCP,
 -                           ("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
 +            TI_DbgPrint(DEBUG_TCP,
 +                        ("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
  
 -               TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
 -               TI_DbgPrint
 -                   (DEBUG_TCP,
 -                    ("Connection->SocketContext: %x\n",
 -                     Connection->SocketContext));
 -               TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
 +            TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
 +            TI_DbgPrint
 +                (DEBUG_TCP,
 +                 ("Connection->SocketContext: %x\n",
 +                  Connection->SocketContext));
 +            TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
  
 -               Status = TCPTranslateError
 -                    ( OskitTCPRecv( Connection->SocketContext,
 -                                    RecvBuffer,
 -                                    RecvLen,
 -                                    &Received,
 -                                    0 ) );
 +            Status = TCPTranslateError
 +                ( OskitTCPRecv( Connection->SocketContext,
 +                                RecvBuffer,
 +                                RecvLen,
 +                                &Received,
 +                                0 ) );
  
 -               TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
 +            TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
  
-             if( Status == STATUS_SUCCESS ) {
-                 TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n",
-                                        Received, Status));
-                 Complete( Bucket->Request.RequestContext,
-                           STATUS_SUCCESS, Received );
-                 exFreePool( Bucket );
-             } else if( Status == STATUS_PENDING ) {
-                 ExInterlockedInsertHeadList
-                     ( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock );
+                if( Status == STATUS_PENDING ) {
+                    InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry );
 -                   break;
 -               } else {
 -                   TI_DbgPrint(DEBUG_TCP,
 -                               ("Completing Receive request: %x %x\n",
 -                                Bucket->Request, Status));
 +                break;
 +            } else {
 +                TI_DbgPrint(DEBUG_TCP,
 +                            ("Completing Receive request: %x %x\n",
 +                             Bucket->Request, Status));
-                 Complete( Bucket->Request.RequestContext, Status, 0 );
-                 exFreePool( Bucket );
+                    Bucket->Status = Status;
+                    Bucket->Information = (Status == STATUS_SUCCESS) ? Received : 0;
+                    InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
 -               }
 -           }
 -       }
 -       if( Connection->SignalState & SEL_WRITE ) {
 -           TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
 -                                  IsListEmpty(&Connection->SendRequest) ?
 -                                  "empty" : "nonempty"));
 +            }
 +        }
 +    }
 +    if( Connection->SignalState & SEL_WRITE ) {
 +        TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
 +                               IsListEmpty(&Connection->SendRequest) ?
 +                               "empty" : "nonempty"));
  
-         while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
-                                                      &Connection->Lock )) != NULL ) {
+            while (!IsListEmpty(&Connection->SendRequest)) {
 -               OSK_UINT SendLen = 0, Sent = 0;
 -               PVOID SendBuffer = 0;
 +            OSK_UINT SendLen = 0, Sent = 0;
 +            PVOID SendBuffer = 0;
  
 -               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+                Entry = RemoveHeadList( &Connection->SendRequest );
-             Complete = Bucket->Request.RequestNotifyObject;
 +            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
  
 -               Irp = Bucket->Request.RequestContext;
 -               Mdl = Irp->MdlAddress;
 +            Irp = Bucket->Request.RequestContext;
 +            Mdl = Irp->MdlAddress;
  
 -               TI_DbgPrint(DEBUG_TCP,
 -                           ("Getting the user buffer from %x\n", Mdl));
 +            TI_DbgPrint(DEBUG_TCP,
 +                        ("Getting the user buffer from %x\n", Mdl));
  
 -               NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
 +            NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
  
 -               TI_DbgPrint(DEBUG_TCP,
 -                           ("Writing %d bytes to %x\n", SendLen, SendBuffer));
 +            TI_DbgPrint(DEBUG_TCP,
 +                        ("Writing %d bytes to %x\n", SendLen, SendBuffer));
  
 -               TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
 -               TI_DbgPrint
 +            TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
 +            TI_DbgPrint
                  (DEBUG_TCP,
                   ("Connection->SocketContext: %x\n",
                    Connection->SocketContext));
  
 -               Status = TCPTranslateError
 -                   ( OskitTCPSend( Connection->SocketContext,
 -                                   SendBuffer,
 -                                   SendLen,
 -                                   &Sent,
 -                                   0 ) );
 +            Status = TCPTranslateError
 +                ( OskitTCPSend( Connection->SocketContext,
 +                                SendBuffer,
 +                                SendLen,
 +                                &Sent,
 +                                0 ) );
  
 -               TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
 +            TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
  
-             if( Status == STATUS_SUCCESS ) {
-                 TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n",
-                                        Sent, Status));
-                 Complete( Bucket->Request.RequestContext,
-                           STATUS_SUCCESS, Sent );
-                 exFreePool( Bucket );
-             } else if( Status == STATUS_PENDING ) {
-                 ExInterlockedInsertHeadList
-                     ( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock );
+                if( Status == STATUS_PENDING ) {
+                    InsertHeadList( &Connection->SendRequest, &Bucket->Entry );
 -                   break;
 -               } else {
 -                   TI_DbgPrint(DEBUG_TCP,
 -                               ("Completing Send request: %x %x\n",
 -                               Bucket->Request, Status));
 +                break;
 +            } else {
 +                TI_DbgPrint(DEBUG_TCP,
 +                            ("Completing Send request: %x %x\n",
 +                             Bucket->Request, Status));
-                 Complete( Bucket->Request.RequestContext, Status, 0 );
-                 exFreePool( Bucket );
+                    Bucket->Status = Status;
+                    Bucket->Information = (Status == STATUS_SUCCESS) ? Sent : 0;
+                    InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
 -               }
 -           }
 -       }
 +            }
 +        }
 +    }
  
-     Connection->SignalState = 0;
-     Connection->Signalled = FALSE;
+        ReferenceObject(Connection);
+        if (ClientInfo.Unlocked)
+        {
+            UnlockObjectFromDpcLevel(Connection);
+            KeReleaseSpinLock(&ClientInfo.Lock, ClientInfo.OldIrql);
 -       }
 +}
+        else
+        {
+            UnlockObject(Connection, Connection->OldIrql);
+        }
+        while ((Entry = ExInterlockedRemoveHeadList(&Connection->CompletionQueue,
+                                                    &Connection->Lock)))
+        {
+            Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+            Complete = Bucket->Request.RequestNotifyObject;
  
- VOID DrainSignals() {
-     PCONNECTION_ENDPOINT Connection;
-     PLIST_ENTRY ListEntry;
+            Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
  
-     while( (ListEntry = ExInterlockedRemoveHeadList(&SignalledConnectionsList,
-                                                     &SignalledConnectionsLock)) != NULL) {
-         Connection = CONTAINING_RECORD( ListEntry, CONNECTION_ENDPOINT,
-                                         SignalList );
-         HandleSignalledConnection( Connection );
-         }
-     }
+            ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+        }
+        if (!ClientInfo.Unlocked)
+        {
+            LockObject(Connection, &OldIrql);
+        }
+        else
+        {
+            KeAcquireSpinLock(&ClientInfo.Lock, &ClientInfo.OldIrql);
+        }
+        DereferenceObject(Connection);
+        /* If the socket is dead, remove the reference we added for oskit */
+        if (Connection->SignalState & SEL_FIN)
+            DereferenceObject(Connection);
+ }
+ VOID ConnectionFree(PVOID Object) {
+     PCONNECTION_ENDPOINT Connection = Object;
+     KIRQL OldIrql;
+     TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
+     TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
+     RemoveEntryList(&Connection->ListEntry);
+     TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
+     ExFreePoolWithTag( Connection, CONN_ENDPT_TAG );
+ }
  
  PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
      PCONNECTION_ENDPOINT Connection =
@@@ -628,7 -632,29 +632,29 @@@ NTSTATUS TCPConnec
  
      AddressToConnect.sin_family = AF_INET;
      AddressToBind = AddressToConnect;
 -        AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address;
+     LockObject(Connection, &OldIrql);
+     if (!Connection->AddressFile)
+     {
+         UnlockObject(Connection, OldIrql);
+         return STATUS_INVALID_PARAMETER;
+     }
+     if (AddrIsUnspecified(&Connection->AddressFile->Address))
+     {
+         if (!(NCE = RouteGetRouteToDestination(&RemoteAddress)))
+         {
+             UnlockObject(Connection, OldIrql);
+             return STATUS_NETWORK_UNREACHABLE;
+         }
 +    AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address;
+     }
+     else
+     {
+         AddressToBind.sin_addr.s_addr = Connection->AddressFile->Address.Address.IPv4Address;
+     }
  
      Status = TCPTranslateError
          ( OskitTCPBind( Connection->SocketContext,
              
              Bucket->Request.RequestNotifyObject = (PVOID)Complete;
              Bucket->Request.RequestContext = Context;
 -                      
 +            
-             IoMarkIrpPending((PIRP)Context);
-                       
-             ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, &Connection->Lock );
+             InsertTailList( &Connection->ConnectRequest, &Bucket->Entry );
          }
      }
  
@@@ -838,16 -860,16 +860,16 @@@ NTSTATUS TCPSendDat
          Bucket->Request.RequestNotifyObject = Complete;
          Bucket->Request.RequestContext = Context;
          *BytesSent = 0;
 -        
 +
-         IoMarkIrpPending((PIRP)Context);
-         
-         ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock );
+         InsertTailList( &Connection->SendRequest, &Bucket->Entry );
          TI_DbgPrint(DEBUG_TCP,("Queued write irp\n"));
      } else {
          TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent));
          *BytesSent = Sent;
      }
 -
 +    
+     UnlockObject(Connection, OldIrql);
      TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
  
      return Status;
index 0000000,6c8cc60..ae4f39d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,9 +1,9 @@@
 -<module name="tdilib" type="staticlibrary">
+ <?xml version="1.0"?>
+ <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 -</module>
++<!-- module name="tdilib" type="staticlibrary">
+       <include base="iphlpapi">.</include>
+       <include base="tdilib">.</include>
+       <library>ntdll</library>
+       <file>enum.c</file>
+       <file>handle.c</file>
++</module -->
Simple merge
Simple merge
  #define Running 2
  #define WrDispatchInt 0x1F
  
- Dividend: .float 4195835.0
- Divisor:  .float 3145727.0
- Result1:  .float 0
- Result2:  .float 0
  /* FUNCTIONS ****************************************************************/
  
- .globl _KiIsNpxErrataPresent@0
- .func KiIsNpxErrataPresent@0
- _KiIsNpxErrataPresent@0:
-     /* Disable interrupts */
-     cli
-     /* Get CR0 and mask out FPU flags */
-     mov eax, cr0
-     mov ecx, eax
-     and eax, ~(CR0_MP + CR0_TS + CR0_EM)
-     mov cr0, eax
-     /* Initialize the FPU */
-     fninit
-     /* Do the divison and inverse multiplication */
-     fld qword ptr Dividend
-     fstp qword ptr Result1
-     fld qword ptr Divisor
-     fstp qword ptr Result2
-     fld qword ptr Result1
-     fdiv qword ptr Result2
-     fmul qword ptr Result2
-     /* Do the compare and check flags */
-     fcomp qword ptr Result1
-     fstsw ax
-     sahf
-     /* Restore CR0 and interrupts */
-     mov cr0, ecx
-     sti
-     /* Return errata status */
-     xor eax, eax
-     jz NoErrata
-     inc eax
- NoErrata:
-     ret
- .endfunc
- .globl _KiIsNpxPresent@0
- .func KiIsNpxPresent@0
- _KiIsNpxPresent@0:
-     /* Save stack */
-     push ebp
-     /* Get CR0 and mask out FPU flags */
-     mov eax, cr0
-     and eax, ~(CR0_MP + CR0_TS + CR0_EM + CR0_ET)
-     /* Initialize the FPU and assume FALSE for return */
-     xor edx, edx
-     fninit
-     /* Save magic value on stack */
-     mov ecx, 0x42424242
-     push ecx
-     /* Setup stack for FPU store */
-     mov ebp ,esp
-     fnstsw [ebp]
-     /* Now check if our magic got cleared */
-     cmp byte ptr [ebp], 0
-     jnz NoFpu
-     /* Enable FPU, set return to TRUE */
-     or eax, CR0_ET
-     mov edx, 1
-     /* If this is a 486 or higher, enable INT 16 as well */
-     cmp dword ptr fs:KPCR_PRCB_CPU_TYPE, 3
-     jbe NoFpu
-     or eax, CR0_NE
- NoFpu:
-     /* Set emulation enabled during the first boot phase and set the CR0 */
-     or eax, (CR0_EM + CR0_TS)
-     mov cr0, eax
-     /* Restore stack */
-     pop eax
-     pop ebp
-     /* Return true or false */
-     mov eax, edx
-     ret
- .endfunc
- .globl _KiFlushNPXState@4
- .func KiFlushNPXState@4
- _KiFlushNPXState@4:
-     /* Save volatiles and disable interrupts */
-     push esi
-     push edi
-     push ebx
-     pushfd
-     cli
-     /* Save the PCR and get the current thread */
-     mov edi, fs:[KPCR_SELF]
-     mov esi, [edi+KPCR_CURRENT_THREAD]
-     /* Check if we're already loaded */
-     cmp byte ptr [esi+KTHREAD_NPX_STATE], NPX_STATE_LOADED
-     je IsValid
-     /* Check if we're supposed to get it */
-     cmp dword ptr [esp+20], 0
-     je Return
- #if DBG
-     /* Assert Fxsr support */
-     test byte ptr _KeI386FxsrPresent, 1
-     jnz AssertOk
-     int 3
- AssertOk:
- #endif
-     /* Get CR0 and test if it's valid */
-     mov ebx, cr0
-     test bl, CR0_MP + CR0_TS + CR0_EM
-     jz Cr0OK
-     /* Enable fnsave to work */
-     and ebx, ~(CR0_MP + CR0_TS + CR0_EM)
-     mov cr0, ebx
- Cr0OK:
-     /* Check if we are the NPX Thread */
-     mov eax, [edi+KPCR_NPX_THREAD]
-     or eax, eax
-     jz DontSave
-     /* Check if it's not loaded */
-     cmp byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
-     jnz DontSave
- #if DBG
-     /* We are the NPX Thread with an unloaded NPX State... this isn't normal! */
-     int 3
- #endif
-     /* Save the NPX State */
-     mov ecx, [eax+KTHREAD_INITIAL_STACK]
-     sub ecx, NPX_FRAME_LENGTH
-     fxsave [ecx]
-     mov byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
- DontSave:
-     /* Load the NPX State */
-     mov ecx, [esi+KTHREAD_INITIAL_STACK]
-     sub ecx, NPX_FRAME_LENGTH
-     fxrstor [ecx]
-     /* Get the CR0 state and destination */
-     mov edx, [ecx+FN_CR0_NPX_STATE]
-     mov ecx, [esp+20]
-     jmp DoneLoad
- IsValid:
-     /* We already have a valid state, flush it */
-     mov ebx, cr0
-     test bl, CR0_MP + CR0_TS + CR0_EM
-     jz Cr0OK2
-     /* Enable fnsave to work */
-     and ebx, ~(CR0_MP + CR0_TS + CR0_EM)
-     mov cr0, ebx
- Cr0OK2:
-     /* Get the kernel stack */
-     mov ecx, [esi+KTHREAD_INITIAL_STACK]
-     test byte ptr _KeI386FxsrPresent, 1
-     lea ecx, [ecx-NPX_FRAME_LENGTH]
-     /* Set the NPX State */
-     mov byte ptr [esi+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
-     /* Get Cr0 */
-     mov edx, [ecx+FN_CR0_NPX_STATE]
-     jz DoneLoad
-     /* Save the FX State */
-     fxsave [ecx]
-     /* Check if we also have to save it in the parameter */
-     mov ecx, [esp+20]
-     jecxz NoSave
- DoneLoad:
-     /* Save the Fn state in the parameter we got */
-     fnsave [ecx]
-     fwait
- NoSave:
-     /* Clear eax */
-     xor eax, eax
-     /* Add NPX State */
-     or ebx, NPX_STATE_NOT_LOADED
-     /* Clear the NPX thread */
-     mov [edi+KPCR_NPX_THREAD], eax
-     /* Add saved CR0 into NPX State, and set it */
-     or ebx, edx
-     mov cr0, ebx
-     /* Re-enable interrupts and return */
- Return:
-     popf
-     pop ebx
-     pop edi
-     pop esi
-     ret 4
- .endfunc
- /*++
-  * KiThreadStartup
-  *
-  *     The KiThreadStartup routine is the beginning of any thread.
-  *
-  * Params:
-  *     SystemRoutine - Pointer to the System Startup Routine. Either 
-  *                     PspUserThreadStartup or PspSystemThreadStartup
-  *
-  *     StartRoutine - For Kernel Threads only, specifies the starting execution
-  *                    point of the new thread.
-  *
-  *     StartContext - For Kernel Threads only, specifies a pointer to variable
-  *                    context data to be sent to the StartRoutine above.
-  *
-  *     UserThread - Indicates whether or not this is a user thread. This tells
-  *                  us if the thread has a context or not.
-  *
-  *     TrapFrame - Pointer to the KTHREAD to which the caller wishes to
-  *           switch from.
-  *
-  * Returns:
-  *     Should never return for a system thread. Returns through the System Call
-  *     Exit Dispatcher for a user thread.
-  *
-  * Remarks:
-  *     If a return from a system thread is detected, a bug check will occur.
-  *
-  *--*/
-  .func KiThreadStartup@156
- .globl _KiThreadStartup@156
- _KiThreadStartup@156:
-     /*
-      * Clear all the non-volatile registers, so the thread won't be tempted to
-      * expect any static data (like some badly coded usermode/win9x apps do)
-      */
-     xor ebx, ebx
-     xor esi, esi
-     xor edi, edi
-     xor ebp, ebp
-     /* It's now safe to go to APC */
-     mov ecx, APC_LEVEL
-     call @KfLowerIrql@4
-     /* 
-      * Call the System Routine which is right on our stack now.
-      * After we pop the pointer, the Start Routine/Context will be on the 
-      * stack, as parameters to the System Routine
-      */
-     pop eax
-     call eax
-     /* The thread returned... was it a user-thread? */
-     pop ecx
-     or ecx, ecx
-     jz BadThread
-     /* Yes it was, set our trapframe for the System Call Exit Dispatcher */
-     mov ebp, esp
-     /* Exit back to user-mode */
-     jmp _KiServiceExit2
- BadThread:
-     /* A system thread returned...this is very bad! */
-     int 3
- .endfunc
  /*++
 - * KiSwapContextInternal 
 + * KiSwapContextInternal
   *
 + * \brief
   *     The KiSwapContextInternal routine switches context to another thread.
   *
 + * BOOLEAN USERCALL KiSwapContextInternal();
 + *
   * Params:
   *     ESI - Pointer to the KTHREAD to which the caller wishes to
   *           switch to.
Simple merge
Simple merge