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

@@@ -19,6 -19,8 +19,6 @@@
  # include <resolv.h>
  #endif
  
 -#undef _WIN32_WINNT
 -#define _WIN32_WINNT 0x500
  #define WIN32_NO_STATUS
  #include <winsock2.h>
  #include <ws2tcpip.h>
@@@ -35,6 -37,8 +35,8 @@@
  #include "ddk/tdiinfo.h"
  #include "tcpioctl.h"
  
+ #include "tdilib.h"
  #ifndef ETH_ALEN
  #define ETH_ALEN 6
  #endif
@@@ -118,20 -122,9 +120,9 @@@ typedef enum _IPHLPAddrType 
  } IPHLPAddrType;
  
  /** Prototypes **/
- NTSTATUS openTcpFile(PHANDLE tcpFile);
- VOID closeTcpFile(HANDLE tcpFile);
- NTSTATUS tdiGetEntityIDSet( HANDLE tcpFile, TDIEntityID **entitySet,
-                           PDWORD numEntities );
- NTSTATUS tdiGetSetOfThings( HANDLE tcpFile, DWORD toiClass, DWORD toiType,
-                           DWORD toiId, DWORD teiEntity, DWORD teiInstance,
-                           DWORD fixedPart,
-                           DWORD entrySize, PVOID *tdiEntitySet,
-                           PDWORD numEntries );
- VOID tdiFreeThingSet( PVOID things );
  NTSTATUS getNthIpEntity( HANDLE tcpFile, DWORD index, TDIEntityID *ent );
  NTSTATUS tdiGetIpAddrsForIpEntity( HANDLE tcpFile, TDIEntityID *ent,
                                   IPAddrEntry **addrs, PDWORD numAddrs );
  int GetLongestChildKeyName( HANDLE RegHandle );
  LONG OpenChildKeyRead( HANDLE RegHandle,
                       PWCHAR ChildKeyName,
@@@ -97,7 -97,7 +97,7 @@@
    NtUserCallOneParam((DWORD_PTR)bShow, ONEPARAM_ROUTINE_SHOWCURSOR)
  
  #define NtUserGetDesktopMapping(Ptr) \
 -  (PVOID)NtUserCallOneParam((DWORD)Ptr, ONEPARAM_ROUTINE_GETDESKTOPMAPPING)
 +  (PVOID)NtUserCallOneParam((DWORD_PTR)Ptr, ONEPARAM_ROUTINE_GETDESKTOPMAPPING)
  
  #define NtUserSetCursorPos(x, y) \
    (BOOL)NtUserCallTwoParam((DWORD)x, (DWORD)y, TWOPARAM_ROUTINE_SETCURSORPOS)
@@@ -180,6 -180,8 +180,8 @@@ extern int SPY_Init(void)
  #define USER_BODY_TO_HEADER(ObjectBody) \
    ((PUSER_OBJECT_HEADER)(((PUSER_OBJECT_HEADER)ObjectBody) - 1))
  
+ #define HANDLEENTRY_INDESTROY 1
  typedef struct _USER_HANDLE_ENTRY
  {
      void          *ptr;          /* pointer to object */
          PTHREADINFO pti;          // pointer to Win32ThreadInfo
          PPROCESSINFO ppi;         // pointer to W32ProcessInfo
      };
-     unsigned short type;         /* object type (0 if free) */
+     unsigned char  type;         /* object type (0 if free) */
+     unsigned char  flags;
      unsigned short generation;   /* generation counter */
  } USER_HANDLE_ENTRY, * PUSER_HANDLE_ENTRY;
  
@@@ -274,7 -274,7 +274,7 @@@ TestWindowProcess(PWND Wnd
        return TRUE;
     else
        return (NtUserQueryWindow(Wnd->head.h, QUERY_WINDOW_UNIQUE_PROCESS_ID) ==
 -              (DWORD)NtCurrentTeb()->ClientId.UniqueProcess );
 +              (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess );
  }
  
  BOOL
@@@ -300,7 -300,7 +300,7 @@@ GetUser32Handle(HANDLE handle
      INT Index;
      USHORT generation;
  
 -    Index = (((UINT)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
 +    Index = (((UINT_PTR)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
  
      if (Index < 0 || Index >= gHandleTable->nb_handles)
          return NULL;
      if (!gHandleEntries[Index].type || !gHandleEntries[Index].ptr)
          return NULL;
  
 -    generation = (UINT)handle >> 16;
 +    generation = (UINT_PTR)handle >> 16;
  
      if (generation == gHandleEntries[Index].generation || !generation || generation == 0xffff)
          return &gHandleEntries[Index];
  static const BOOL g_ObjectHeapTypeShared[VALIDATE_TYPE_EVENT + 1] =
  {
      FALSE, /* VALIDATE_TYPE_FREE (not used) */
-     TRUE, /* VALIDATE_TYPE_WIN */ /* FIXME: FALSE once WINDOW_OBJECT is deleted! */
-     TRUE, /* VALIDATE_TYPE_MENU */
+     TRUE, /* VALIDATE_TYPE_WIN  FALSE */
+     TRUE, /* VALIDATE_TYPE_MENU  FALSE */
      TRUE, /* VALIDATE_TYPE_CURSOR */
      TRUE, /* VALIDATE_TYPE_MWPOS */
-     TRUE, /* VALIDATE_TYPE_HOOK */
+     TRUE, /* VALIDATE_TYPE_HOOK  FALSE */
      FALSE, /* (not used) */
-     TRUE, /* VALIDATE_TYPE_CALLPROC */
+     TRUE, /* VALIDATE_TYPE_CALLPROC  FALSE */
      TRUE, /* VALIDATE_TYPE_ACCEL */
      FALSE, /* (not used) */
      FALSE, /* (not used) */
@@@ -357,7 -357,10 +357,10 @@@ ValidateHandle(HANDLE handle, UINT uTyp
        uType = pEntry->type;
  
  // Must have an entry and must be the same type!
-   if ( (!pEntry) || (pEntry->type != uType) || !pEntry->ptr )
+   if ( (!pEntry) ||
+         (pEntry->type != uType) ||
+         !pEntry->ptr ||
+         (pEntry->flags & HANDLEENTRY_INDESTROY) )
    {
       switch ( uType )
       {  // Test (with wine too) confirms these results!
@@@ -442,6 -445,13 +445,13 @@@ ValidateCallProc(HANDLE hCallProc
    return NULL;
  }
  
+ // HACK HACK HACK!
+ typedef struct _WNDX
+ {
+     THRDESKHEAD head;
+     PWND pWnd;
+ } WNDX, *PWNDX;
  //
  // Validate a window handle and return the pointer to the object.
  //
@@@ -460,9 -470,6 +470,6 @@@ ValidateHwnd(HWND hwnd
      Wnd = ValidateHandle((HANDLE)hwnd, VALIDATE_TYPE_WIN);
      if (Wnd != NULL)
      {
-         /* FIXME: Check if handle table entry is marked as deleting and
-                   return NULL in this case! */
  #if 0
          return Wnd;
  #else
             !!! REMOVE AS SOON AS WINDOW_OBJECT NO LONGER EXISTS !!!
           */
  
-         if (*((PVOID*)Wnd) != NULL)
-             return DesktopPtrToUser(*((PVOID*)Wnd));
+         if ( ((PWNDX)Wnd)->pWnd != NULL)
+             return DesktopPtrToUser( ((PWNDX)Wnd)->pWnd );
  #endif
      }
  
@@@ -499,9 -506,6 +506,6 @@@ ValidateHwndNoErr(HWND hwnd
      Wnd = ValidateHandleNoErr((HANDLE)hwnd, VALIDATE_TYPE_WIN);
      if (Wnd != NULL)
      {
-         /* FIXME: Check if handle table entry is marked as deleting and
-                   return NULL in this case! */
  #if 0
          return Wnd;
  #else
             !!! REMOVE AS SOON AS WINDOW_OBJECT NO LONGER EXISTS !!!
           */
  
-         if (*((PVOID*)Wnd) != NULL)
-             return DesktopPtrToUser(*((PVOID*)Wnd));
+         if ( ((PWNDX)Wnd)->pWnd != NULL)
+             return DesktopPtrToUser( ((PWNDX)Wnd)->pWnd );
  #endif
      }
  
@@@ -40,6 -40,7 +40,7 @@@ PVOID LockRequest( PIRP Irp, PIO_STACK_
            MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
  
        if( !IrpSp->Parameters.DeviceIoControl.Type3InputBuffer ) {
+             MmUnlockPages( Irp->MdlAddress );
            IoFreeMdl( Irp->MdlAddress );
            Irp->MdlAddress = NULL;
            return NULL;
      } else return NULL;
  }
  
- VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
-     PVOID Buffer = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
-     if( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer == Buffer || Buffer == NULL ) {
-       MmUnmapLockedPages( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer, Irp->MdlAddress );
-         MmUnlockPages( Irp->MdlAddress );
-         IoFreeMdl( Irp->MdlAddress );
-     }
+ VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp )
+ {
+     MmUnlockPages( Irp->MdlAddress );
+     IoFreeMdl( Irp->MdlAddress );
      Irp->MdlAddress = NULL;
  }
  
@@@ -181,7 -178,7 +178,7 @@@ PAFD_HANDLE LockHandles( PAFD_HANDLE Ha
        if( !HandleArray[i].Handle ) continue;
        if( NT_SUCCESS(Status) ) {
                Status = ObReferenceObjectByHandle
 -              ( (PVOID)HandleArray[i].Handle,
 +              ( (PVOID)(ULONG_PTR)HandleArray[i].Handle,
                 FILE_ALL_ACCESS,
                 NULL,
                 KernelMode,
@@@ -206,85 -203,25 +203,25 @@@ VOID UnlockHandles( PAFD_HANDLE HandleA
  
      for( i = 0; i < HandleCount; i++ ) {
        if( HandleArray[i].Handle )
 -          ObDereferenceObject( (PVOID)HandleArray[i].Handle );
 +          ObDereferenceObject( (PVOID)(ULONG_PTR)HandleArray[i].Handle );
      }
  
      ExFreePool( HandleArray );
      HandleArray = NULL;
  }
  
- /* Returns transitioned state or SOCKET_STATE_INVALID_TRANSITION */
- UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
-     NTSTATUS Status = STATUS_SUCCESS;
-     PVOID CurrentThread = KeGetCurrentThread();
-     ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
-     AFD_DbgPrint(MAX_TRACE,("Called on %x, attempting to lock\n", FCB));
-     /* Wait for the previous user to unlock the FCB state.  There might be
-      * multiple waiters waiting to change the state.  We need to check each
-      * time we get the event whether somebody still has the state locked */
+ BOOLEAN SocketAcquireStateLock( PAFD_FCB FCB ) {
      if( !FCB ) return FALSE;
  
-     if( CurrentThread == FCB->CurrentThread ) {
-       FCB->LockCount++;
-       AFD_DbgPrint(MID_TRACE,
-                    ("Same thread, lock count %d\n", FCB->LockCount));
-       return TRUE;
-     } else {
-       AFD_DbgPrint(MID_TRACE,
-                    ("Thread %x opposes lock thread %x\n",
-                     CurrentThread, FCB->CurrentThread));
-     }
-     ExAcquireFastMutex( &FCB->Mutex );
-     while( FCB->Locked ) {
-       AFD_DbgPrint
-           (MID_TRACE,("FCB %x is locked, waiting for notification\n",
-                       FCB));
-       ExReleaseFastMutex( &FCB->Mutex );
-       Status = KeWaitForSingleObject( &FCB->StateLockedEvent,
-                                       UserRequest,
-                                       KernelMode,
-                                       FALSE,
-                                       NULL );
-       ExAcquireFastMutex( &FCB->Mutex );
-     }
-     FCB->Locked = TRUE;
-     FCB->CurrentThread = CurrentThread;
-     FCB->LockCount++;
-     ExReleaseFastMutex( &FCB->Mutex );
-     AFD_DbgPrint(MAX_TRACE,("Got lock (%d).\n", FCB->LockCount));
-     return TRUE;
+     return !KeWaitForMutexObject(&FCB->Mutex,
+                                  Executive,
+                                  KernelMode,
+                                  FALSE,
+                                  NULL);
  }
  
  VOID SocketStateUnlock( PAFD_FCB FCB ) {
- #if DBG
-     PVOID CurrentThread = KeGetCurrentThread();
- #endif
-     ASSERT(FCB->LockCount > 0);
-     ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
-     ExAcquireFastMutex( &FCB->Mutex );
-     FCB->LockCount--;
-     if( !FCB->LockCount ) {
-       FCB->CurrentThread = NULL;
-       FCB->Locked = FALSE;
-       AFD_DbgPrint(MAX_TRACE,("Unlocked.\n"));
-       KePulseEvent( &FCB->StateLockedEvent, IO_NETWORK_INCREMENT, FALSE );
-     } else {
-       AFD_DbgPrint(MAX_TRACE,("New lock count: %d (Thr: %x)\n",
-                               FCB->LockCount, CurrentThread));
-     }
-     ExReleaseFastMutex( &FCB->Mutex );
+     KeReleaseMutex(&FCB->Mutex, FALSE);
  }
  
  NTSTATUS NTAPI UnlockAndMaybeComplete
@@@ -30,7 -30,7 +30,7 @@@ void OskitDumpBuffer( PCHAR Data, UINT 
  
      for( i = 0; i < Len; i++ ) {
        if( i && !(i & 0xf) ) DbgPrint( "\n" );
 -      if( !(i & 0xf) ) DbgPrint( "%08x: ", (UINT)(Data + i) );
 +      if( !(i & 0xf) ) DbgPrint( "%08x: ", (UINT_PTR)(Data + i) );
        DbgPrint( " %02x", Data[i] & 0xff );
      }
      DbgPrint("\n");
  NTSTATUS NTAPI
  DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
  
+ NTSTATUS NTAPI
+ AfdGetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                 PIO_STACK_LOCATION IrpSp)
+ {
+     PFILE_OBJECT FileObject = IrpSp->FileObject;
+     PAFD_FCB FCB = FileObject->FsContext;
+     UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+     if (FCB->DisconnectOptionsSize == 0)
+         return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
+     ASSERT(FCB->DisconnectOptions);
+     if (FCB->FilledDisconnectOptions < BufferSize) BufferSize = FCB->FilledDisconnectOptions;
+     RtlCopyMemory(Irp->UserBuffer,
+                   FCB->DisconnectOptions,
+                   BufferSize);
+     return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, BufferSize);
+ }
+ NTSTATUS
+ NTAPI
+ AfdSetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                   PIO_STACK_LOCATION IrpSp)
+ {
+     PFILE_OBJECT FileObject = IrpSp->FileObject;
+     PAFD_FCB FCB = FileObject->FsContext;
+     PVOID DisconnectOptions = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+     UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+     if (FCB->DisconnectOptions)
+     {
+         ExFreePool(FCB->DisconnectOptions);
+         FCB->DisconnectOptions = NULL;
+         FCB->DisconnectOptionsSize = 0;
+         FCB->FilledDisconnectOptions = 0;
+     }
+     FCB->DisconnectOptions = ExAllocatePool(PagedPool, DisconnectOptionsSize);
+     if (!FCB->DisconnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+     RtlCopyMemory(FCB->DisconnectOptions,
+                   DisconnectOptions,
+                   DisconnectOptionsSize);
+     FCB->DisconnectOptionsSize = DisconnectOptionsSize;
+     return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+ }
+ NTSTATUS
+ NTAPI
+ AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                       PIO_STACK_LOCATION IrpSp)
+ {
+     PFILE_OBJECT FileObject = IrpSp->FileObject;
+     PAFD_FCB FCB = FileObject->FsContext;
+     PUINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+     UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+     if (BufferSize < sizeof(UINT))
+         return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
+     if (FCB->DisconnectOptions)
+     {
+         ExFreePool(FCB->DisconnectOptions);
+         FCB->DisconnectOptionsSize = 0;
+         FCB->FilledDisconnectOptions = 0;
+     }
+     FCB->DisconnectOptions = ExAllocatePool(PagedPool, *DisconnectOptionsSize);
+     if (!FCB->DisconnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+     FCB->DisconnectOptionsSize = *DisconnectOptionsSize;
+     return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+ }
+ NTSTATUS NTAPI
+ AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                 PIO_STACK_LOCATION IrpSp)
+ {
+     PFILE_OBJECT FileObject = IrpSp->FileObject;
+     PAFD_FCB FCB = FileObject->FsContext;
+     UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+     if (FCB->DisconnectDataSize == 0)
+         return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
+     ASSERT(FCB->DisconnectData);
+     if (FCB->FilledDisconnectData < BufferSize) BufferSize = FCB->FilledDisconnectData;
+     RtlCopyMemory(Irp->UserBuffer,
+                   FCB->DisconnectData,
+                   BufferSize);
+     return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, BufferSize);
+ }
+ NTSTATUS
+ NTAPI
+ AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                   PIO_STACK_LOCATION IrpSp)
+ {
+     PFILE_OBJECT FileObject = IrpSp->FileObject;
+     PAFD_FCB FCB = FileObject->FsContext;
+     PVOID DisconnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+     UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+     if (FCB->DisconnectData)
+     {
+         ExFreePool(FCB->DisconnectData);
+         FCB->DisconnectData = NULL;
+         FCB->DisconnectDataSize = 0;
+         FCB->FilledDisconnectData = 0;
+     }
+     FCB->DisconnectData = ExAllocatePool(PagedPool, DisconnectDataSize);
+     if (!FCB->DisconnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+     RtlCopyMemory(FCB->DisconnectData,
+                   DisconnectData,
+                   DisconnectDataSize);
+     FCB->DisconnectDataSize = DisconnectDataSize;
+     return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+ }
+ NTSTATUS
+ NTAPI
+ AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+                       PIO_STACK_LOCATION IrpSp)
+ {
+     PFILE_OBJECT FileObject = IrpSp->FileObject;
+     PAFD_FCB FCB = FileObject->FsContext;
+     PUINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+     UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+     if (BufferSize < sizeof(UINT))
+         return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
+     if (FCB->DisconnectData)
+     {
+         ExFreePool(FCB->DisconnectData);
+         FCB->DisconnectDataSize = 0;
+         FCB->FilledDisconnectData = 0;
+     }
+     FCB->DisconnectData = ExAllocatePool(PagedPool, *DisconnectDataSize);
+     if (!FCB->DisconnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+     FCB->DisconnectDataSize = *DisconnectDataSize;
+     return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+ }
  static NTSTATUS NTAPI
  AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                PIO_STACK_LOCATION IrpSp) {
      FCB->State = SOCKET_STATE_CREATED;
      FCB->FileObject = FileObject;
      FCB->DeviceExt = DeviceExt;
-     FCB->Recv.Size = DEFAULT_RECEIVE_WINDOW_SIZE;
-     FCB->Send.Size = DEFAULT_SEND_WINDOW_SIZE;
      FCB->AddressFile.Handle = INVALID_HANDLE_VALUE;
      FCB->Connection.Handle = INVALID_HANDLE_VALUE;
  
-     KeInitializeSpinLock( &FCB->SpinLock );
-     ExInitializeFastMutex( &FCB->Mutex );
-     KeInitializeEvent( &FCB->StateLockedEvent, NotificationEvent, FALSE );
+     KeInitializeMutex( &FCB->Mutex, 0 );
  
      for( i = 0; i < MAX_FUNCTIONS; i++ ) {
        InitializeListHead( &FCB->PendingIrpList[i] );
      FileObject->FsContext = FCB;
  
      /* It seems that UDP sockets are writable from inception */
-     if( FCB->Flags & SGID_CONNECTIONLESS ) {
+     if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) {
          AFD_DbgPrint(MID_TRACE,("Packet oriented socket\n"));
-       /* Allocate our backup buffer */
-       FCB->Recv.Window = ExAllocatePool( NonPagedPool, FCB->Recv.Size );
-       if( !FCB->Recv.Window ) Status = STATUS_NO_MEMORY;
-         if( NT_SUCCESS(Status) )
-         {
-             FCB->Send.Window = ExAllocatePool( NonPagedPool, FCB->Send.Size );
-           if( !FCB->Send.Window ) {
-                if( FCB->Recv.Window ) ExFreePool( FCB->Recv.Window );
-                Status = STATUS_NO_MEMORY;
-             }
-            }
+         
        /* A datagram socket is always sendable */
        FCB->PollState |= AFD_EVENT_SEND;
          PollReeval( FCB->DeviceExt, FCB->FileObject );
@@@ -254,6 -412,21 +412,21 @@@ AfdCloseSocket(PDEVICE_OBJECT DeviceObj
      if( FCB->AddressFrom )
        ExFreePool( FCB->AddressFrom );
  
+     if( FCB->ConnectInfo )
+         ExFreePool( FCB->ConnectInfo );
+     if( FCB->ConnectData )
+         ExFreePool( FCB->ConnectData );
+     if( FCB->DisconnectData )
+         ExFreePool( FCB->DisconnectData );
+     if( FCB->ConnectOptions )
+         ExFreePool( FCB->ConnectOptions );
+     if( FCB->DisconnectOptions )
+         ExFreePool( FCB->DisconnectOptions );
      if( FCB->LocalAddress )
        ExFreePool( FCB->LocalAddress );
  
@@@ -303,8 -476,8 +476,8 @@@ AfdDisconnect(PDEVICE_OBJECT DeviceObje
      PAFD_FCB FCB = FileObject->FsContext;
      PAFD_DISCONNECT_INFO DisReq;
      IO_STATUS_BLOCK Iosb;
-     PTDI_CONNECTION_INFORMATION ConnInfo;
-     NTSTATUS Status;
+     PTDI_CONNECTION_INFORMATION ConnectionReturnInfo;
+     NTSTATUS Status = STATUS_SUCCESS;
      USHORT Flags = 0;
  
      if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
        return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
                                       Irp, 0 );
  
-     if (NULL == FCB->RemoteAddress)
-       {
-         ConnInfo = NULL;
-       }
-     else
-       {
-       Status = TdiBuildNullConnectionInfo
-           ( &ConnInfo, FCB->RemoteAddress->Address[0].AddressType );
+     if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
+     {
+         if( !FCB->ConnectInfo )
+             return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER,
+                                            Irp, 0 );
+         ASSERT(FCB->RemoteAddress);
  
-       if( !NT_SUCCESS(Status) || !ConnInfo )
+         Status = TdiBuildNullConnectionInfo
+              ( &ConnectionReturnInfo, FCB->RemoteAddress->Address[0].AddressType );
+         if( !NT_SUCCESS(Status) )
            return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
-                                          Irp, 0 );
-       }
-     if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
-       Flags |= TDI_DISCONNECT_RELEASE;
-     if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
-       DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
-       Flags |= TDI_DISCONNECT_ABORT;
-     Status = TdiDisconnect( FCB->Connection.Object,
-                           &DisReq->Timeout,
-                           Flags,
-                           &Iosb,
-                           NULL,
-                           NULL,
-                           FCB->AddressFrom,
-                           ConnInfo);
-     if (ConnInfo) ExFreePool( ConnInfo );
-     FCB->PollState |= AFD_EVENT_DISCONNECT;
-     PollReeval( FCB->DeviceExt, FCB->FileObject );
+                                          Irp, 0 );
+         if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
+           Flags |= TDI_DISCONNECT_RELEASE;
+         if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
+           DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
+           Flags |= TDI_DISCONNECT_ABORT;
+         FCB->ConnectInfo->UserData = FCB->DisconnectData;
+         FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize;
+         FCB->ConnectInfo->Options = FCB->DisconnectOptions;
+         FCB->ConnectInfo->OptionsLength = FCB->DisconnectOptionsSize;
+         Status = TdiDisconnect( FCB->Connection.Object,
+                               &DisReq->Timeout,
+                               Flags,
+                               &Iosb,
+                               NULL,
+                               NULL,
+                               FCB->ConnectInfo,
+                               ConnectionReturnInfo);
+         if (NT_SUCCESS(Status)) {
+             FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize, ConnectionReturnInfo->UserDataLength);
+             if (FCB->FilledDisconnectData)
+             {
+                 RtlCopyMemory(FCB->DisconnectData,
+                               ConnectionReturnInfo->UserData,
+                               FCB->FilledDisconnectData);
+             }
+             FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize, ConnectionReturnInfo->OptionsLength);
+             if (FCB->FilledDisconnectOptions)
+             {
+                 RtlCopyMemory(FCB->DisconnectOptions,
+                               ConnectionReturnInfo->Options,
+                               FCB->FilledDisconnectOptions);
+             }
+         }
+         ExFreePool( ConnectionReturnInfo );
+         FCB->PollState |= AFD_EVENT_DISCONNECT;
+         PollReeval( FCB->DeviceExt, FCB->FileObject );
+     } else
+         Status = STATUS_INVALID_PARAMETER;
  
      return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
  }
@@@ -455,56 -654,44 +654,44 @@@ AfdDispatch(PDEVICE_OBJECT DeviceObject
          case IOCTL_AFD_GET_PEER_NAME:
              return AfdGetPeerName( DeviceObject, Irp, IrpSp );
  
-       case IOCTL_AFD_GET_TDI_HANDLES:
-           DbgPrint("IOCTL_AFD_GET_TDI_HANDLES is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_GET_CONNECT_DATA:
+           return AfdGetConnectData(DeviceObject, Irp, IrpSp);
  
        case IOCTL_AFD_SET_CONNECT_DATA:
-           DbgPrint("IOCTL_AFD_SET_CONNECT_DATA is UNIMPLEMENTED!\n");
-           break;
-       case IOCTL_AFD_SET_CONNECT_OPTIONS:
-           DbgPrint("IOCTL_AFD_SET_CONNECT_OPTIONS is UNIMPLEMENTED!\n");
-           break;
+           return AfdSetConnectData(DeviceObject, Irp, IrpSp);
  
        case IOCTL_AFD_SET_DISCONNECT_DATA:
-           DbgPrint("IOCTL_AFD_SET_DISCONNECT_DATA is UNIMPLEMENTED!\n");
-           break;
+           return AfdSetDisconnectData(DeviceObject, Irp, IrpSp);
  
-       case IOCTL_AFD_SET_DISCONNECT_OPTIONS:
-           DbgPrint("IOCTL_AFD_SET_DISCONNECT_OPTIONS is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_GET_DISCONNECT_DATA:
+           return AfdGetDisconnectData(DeviceObject, Irp, IrpSp);
  
-       case IOCTL_AFD_GET_CONNECT_DATA:
-           DbgPrint("IOCTL_AFD_GET_CONNECT_DATA is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_SET_CONNECT_DATA_SIZE:
+           return AfdSetConnectDataSize(DeviceObject, Irp, IrpSp);
  
-       case IOCTL_AFD_GET_CONNECT_OPTIONS:
-           DbgPrint("IOCTL_AFD_GET_CONNECT_OPTIONS is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE:
+           return AfdSetDisconnectDataSize(DeviceObject, Irp, IrpSp);
  
-       case IOCTL_AFD_GET_DISCONNECT_DATA:
-           DbgPrint("IOCTL_AFD_GET_DISCONNECT_DATA is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_SET_CONNECT_OPTIONS:
+           return AfdSetConnectOptions(DeviceObject, Irp, IrpSp);
  
-       case IOCTL_AFD_GET_DISCONNECT_OPTIONS:
-           DbgPrint("IOCTL_AFD_GET_DISCONNECT_OPTIONS is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_SET_DISCONNECT_OPTIONS:
+           return AfdSetDisconnectOptions(DeviceObject, Irp, IrpSp);
  
-       case IOCTL_AFD_SET_CONNECT_DATA_SIZE:
-           DbgPrint("IOCTL_AFD_SET_CONNECT_DATA_SIZE is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_GET_CONNECT_OPTIONS:
+           return AfdGetConnectOptions(DeviceObject, Irp, IrpSp);
  
-       case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE:
-           DbgPrint("IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_GET_DISCONNECT_OPTIONS:
+           return AfdGetDisconnectOptions(DeviceObject, Irp, IrpSp);
  
-       case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE:
-           DbgPrint("IOCTL_AFD_SET_DISCONNECT_DATA_SIZE is UNIMPLEMENTED!\n");
-           break;
+       case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE:
+           return AfdSetConnectOptionsSize(DeviceObject, Irp, IrpSp);
  
        case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE:
-           DbgPrint("IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE is UNIMPLEMENTED!\n");
+           return AfdSetDisconnectOptionsSize(DeviceObject, Irp, IrpSp);
+       case IOCTL_AFD_GET_TDI_HANDLES:
+           DbgPrint("IOCTL_AFD_GET_TDI_HANDLES is UNIMPLEMENTED!\n");
            break;
  
        case IOCTL_AFD_DEFER_ACCEPT:
@@@ -143,7 -143,7 +143,7 @@@ MiniportHandleInterrupt
  
                RtlZeroMemory(Descriptor, sizeof(RECEIVE_DESCRIPTOR));
                Descriptor->RBADR =
 -                  (ULONG)(Adapter->ReceiveBufferPtrPhys + Adapter->CurrentReceiveDescriptorIndex * BUFFER_SIZE);
 +                  (ULONG_PTR)(Adapter->ReceiveBufferPtrPhys + Adapter->CurrentReceiveDescriptorIndex * BUFFER_SIZE);
                Descriptor->BCNT = (-BUFFER_SIZE) | 0xf000;
                Descriptor->FLAGS |= RD_OWN;
  
@@@ -332,14 -332,14 +332,14 @@@ MiAllocateSharedMemory
        return NDIS_STATUS_RESOURCES;
      }
  
 -  if(((ULONG)Adapter->InitializationBlockVirt & 0x00000003) != 0)
 +  if(((ULONG_PTR)Adapter->InitializationBlockVirt & 0x00000003) != 0)
      {
        DPRINT("address 0x%x not dword-aligned\n", Adapter->InitializationBlockVirt);
        BREAKPOINT;
        return NDIS_STATUS_RESOURCES;
      }
  
 -  Adapter->InitializationBlockPhys = (PINITIALIZATION_BLOCK)NdisGetPhysicalAddressLow(PhysicalAddress);
 +  Adapter->InitializationBlockPhys = (PINITIALIZATION_BLOCK)(ptrdiff_t)NdisGetPhysicalAddressLow(PhysicalAddress);
  
    /* allocate the transport descriptor ring */
    Adapter->TransmitDescriptorRingLength = sizeof(TRANSMIT_DESCRIPTOR) * NUMBER_OF_BUFFERS;
        return NDIS_STATUS_RESOURCES;
      }
  
 -  if(((ULONG)Adapter->TransmitDescriptorRingVirt & 0x00000003) != 0)
 +  if(((ULONG_PTR)Adapter->TransmitDescriptorRingVirt & 0x00000003) != 0)
      {
        DPRINT("address 0x%x not dword-aligned\n", Adapter->TransmitDescriptorRingVirt);
        BREAKPOINT;
        return NDIS_STATUS_RESOURCES;
      }
  
 -  Adapter->TransmitDescriptorRingPhys = (PTRANSMIT_DESCRIPTOR)NdisGetPhysicalAddressLow(PhysicalAddress);
 +  Adapter->TransmitDescriptorRingPhys = (PTRANSMIT_DESCRIPTOR)(ptrdiff_t)NdisGetPhysicalAddressLow(PhysicalAddress);
    RtlZeroMemory(Adapter->TransmitDescriptorRingVirt, sizeof(TRANSMIT_DESCRIPTOR) * NUMBER_OF_BUFFERS);
  
    /* allocate the receive descriptor ring */
        return NDIS_STATUS_RESOURCES;
      }
  
 -  if(((ULONG)Adapter->ReceiveDescriptorRingVirt & 0x00000003) != 0)
 +  if(((ULONG_PTR)Adapter->ReceiveDescriptorRingVirt & 0x00000003) != 0)
      {
        DPRINT("address 0x%x not dword-aligned\n", Adapter->ReceiveDescriptorRingVirt);
        BREAKPOINT;
        return NDIS_STATUS_RESOURCES;
      }
  
 -  Adapter->ReceiveDescriptorRingPhys = (PRECEIVE_DESCRIPTOR)NdisGetPhysicalAddressLow(PhysicalAddress);
 +  Adapter->ReceiveDescriptorRingPhys = (PRECEIVE_DESCRIPTOR)(ptrdiff_t)NdisGetPhysicalAddressLow(PhysicalAddress);
    RtlZeroMemory(Adapter->ReceiveDescriptorRingVirt, sizeof(RECEIVE_DESCRIPTOR) * NUMBER_OF_BUFFERS);
  
    /* allocate transmit buffers */
        return NDIS_STATUS_RESOURCES;
      }
  
 -  if(((ULONG)Adapter->TransmitBufferPtrVirt & 0x00000003) != 0)
 +  if(((ULONG_PTR)Adapter->TransmitBufferPtrVirt & 0x00000003) != 0)
      {
        DPRINT("address 0x%x not dword-aligned\n", Adapter->TransmitBufferPtrVirt);
        BREAKPOINT;
        return NDIS_STATUS_RESOURCES;
      }
  
 -  Adapter->TransmitBufferPtrPhys = (PCHAR)NdisGetPhysicalAddressLow(PhysicalAddress);
 +  Adapter->TransmitBufferPtrPhys = (PCHAR)(ULONG_PTR)NdisGetPhysicalAddressLow(PhysicalAddress);
    RtlZeroMemory(Adapter->TransmitBufferPtrVirt, BUFFER_SIZE * NUMBER_OF_BUFFERS);
  
    /* allocate receive buffers */
        return NDIS_STATUS_RESOURCES;
      }
  
 -  if(((ULONG)Adapter->ReceiveBufferPtrVirt & 0x00000003) != 0)
 +  if(((ULONG_PTR)Adapter->ReceiveBufferPtrVirt & 0x00000003) != 0)
      {
        DPRINT("address 0x%x not dword-aligned\n", Adapter->ReceiveBufferPtrVirt);
        BREAKPOINT;
        return NDIS_STATUS_RESOURCES;
      }
  
 -  Adapter->ReceiveBufferPtrPhys = (PCHAR)NdisGetPhysicalAddressLow(PhysicalAddress);
 +  Adapter->ReceiveBufferPtrPhys = (PCHAR)(ULONG_PTR)NdisGetPhysicalAddressLow(PhysicalAddress);
    RtlZeroMemory(Adapter->ReceiveBufferPtrVirt, BUFFER_SIZE * NUMBER_OF_BUFFERS);
  
    /* initialize tx descriptors */
    TransmitDescriptor = Adapter->TransmitDescriptorRingVirt;
    for(i = 0; i < NUMBER_OF_BUFFERS; i++)
      {
 -      (TransmitDescriptor+i)->TBADR = (ULONG)Adapter->TransmitBufferPtrPhys + i * BUFFER_SIZE;
 +      (TransmitDescriptor+i)->TBADR = (ULONG_PTR)Adapter->TransmitBufferPtrPhys + i * BUFFER_SIZE;
        (TransmitDescriptor+i)->BCNT = 0xf000 | -BUFFER_SIZE; /* 2's compliment  + set top 4 bits */
        (TransmitDescriptor+i)->FLAGS = TD1_STP | TD1_ENP;
      }
    ReceiveDescriptor = Adapter->ReceiveDescriptorRingVirt;
    for(i = 0; i < NUMBER_OF_BUFFERS; i++)
      {
 -      (ReceiveDescriptor+i)->RBADR = (ULONG)Adapter->ReceiveBufferPtrPhys + i * BUFFER_SIZE;
 +      (ReceiveDescriptor+i)->RBADR = (ULONG_PTR)Adapter->ReceiveBufferPtrPhys + i * BUFFER_SIZE;
        (ReceiveDescriptor+i)->BCNT = 0xf000 | -BUFFER_SIZE; /* 2's compliment  + set top 4 bits */
        (ReceiveDescriptor+i)->FLAGS = RD_OWN;
      }
@@@ -476,12 -476,12 +476,12 @@@ MiPrepareInitializationBlock
  
    /* set up receive ring */
    DPRINT("Receive ring physical address: 0x%x\n", Adapter->ReceiveDescriptorRingPhys);
 -  Adapter->InitializationBlockVirt->RDRA = (ULONG)Adapter->ReceiveDescriptorRingPhys;
 +  Adapter->InitializationBlockVirt->RDRA = (ULONG_PTR)Adapter->ReceiveDescriptorRingPhys;
    Adapter->InitializationBlockVirt->RLEN = (LOG_NUMBER_OF_BUFFERS << 4) & 0xf0;
  
    /* set up transmit ring */
    DPRINT("Transmit ring physical address: 0x%x\n", Adapter->TransmitDescriptorRingPhys);
 -  Adapter->InitializationBlockVirt->TDRA = (ULONG)Adapter->TransmitDescriptorRingPhys;
 +  Adapter->InitializationBlockVirt->TDRA = (ULONG_PTR)Adapter->TransmitDescriptorRingPhys;
    Adapter->InitializationBlockVirt->TLEN = (LOG_NUMBER_OF_BUFFERS << 4) & 0xf0;
  }
  
@@@ -500,35 -500,35 +500,35 @@@ MiFreeSharedMemory
  
    if(Adapter->InitializationBlockVirt)
      {
 -      PhysicalAddress.u.LowPart = (ULONG)Adapter->InitializationBlockPhys;
 +      PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->InitializationBlockPhys;
        NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->InitializationBlockLength,
            FALSE, Adapter->InitializationBlockVirt, PhysicalAddress);
      }
  
    if(Adapter->TransmitDescriptorRingVirt)
      {
 -      PhysicalAddress.u.LowPart = (ULONG)Adapter->TransmitDescriptorRingPhys;
 +      PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->TransmitDescriptorRingPhys;
        NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitDescriptorRingLength,
          FALSE, Adapter->TransmitDescriptorRingVirt, PhysicalAddress);
      }
  
    if(Adapter->ReceiveDescriptorRingVirt)
      {
 -      PhysicalAddress.u.LowPart = (ULONG)Adapter->ReceiveDescriptorRingPhys;
 +      PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->ReceiveDescriptorRingPhys;
        NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveDescriptorRingLength,
            FALSE, Adapter->ReceiveDescriptorRingVirt, PhysicalAddress);
      }
  
    if(Adapter->TransmitBufferPtrVirt)
      {
 -      PhysicalAddress.u.LowPart = (ULONG)Adapter->TransmitBufferPtrPhys;
 +      PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->TransmitBufferPtrPhys;
        NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitBufferLength,
            FALSE, Adapter->TransmitBufferPtrVirt, PhysicalAddress);
      }
  
    if(Adapter->ReceiveBufferPtrVirt)
      {
 -      PhysicalAddress.u.LowPart = (ULONG)Adapter->ReceiveBufferPtrPhys;
 +      PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->ReceiveBufferPtrPhys;
        NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveBufferLength,
            FALSE, Adapter->ReceiveBufferPtrVirt, PhysicalAddress);
      }
@@@ -713,9 -713,9 +713,9 @@@ MiInitChip
  
    /* set up csr1 and csr2 with init block */
    NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR1);
 -  NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG)Adapter->InitializationBlockPhys & 0xffff));
 +  NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG_PTR)Adapter->InitializationBlockPhys & 0xffff));
    NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR2);
 -  NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG)Adapter->InitializationBlockPhys >> 16) & 0xffff);
 +  NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG_PTR)Adapter->InitializationBlockPhys >> 16) & 0xffff);
  
    DPRINT("programmed with init block\n");
  
@@@ -1101,8 -1101,6 +1101,6 @@@ MiniportReset
  {
    DPRINT("Called\n");
  
-   ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
    /* MiniportReset doesn't do anything at the moment... perhaps this should be fixed. */
  
    *AddressingReset = FALSE;
@@@ -108,7 -108,7 +108,7 @@@ VOID FreeAdapter
   *     Adapter = Pointer to LAN_ADAPTER structure to free
   */
  {
-     exFreePool(Adapter);
+     ExFreePoolWithTag(Adapter, LAN_ADAPTER_TAG);
  }
  
  
@@@ -249,7 -249,7 +249,7 @@@ VOID LanReceiveWorker( PVOID Context ) 
      Adapter = WorkItem->Adapter;
      BytesTransferred = WorkItem->BytesTransferred;
  
-     exFreePool(WorkItem);
+     ExFreePoolWithTag(WorkItem, WQ_CONTEXT_TAG);
  
      IPInitializePacket(&IPPacket, 0);
  
@@@ -300,7 -300,8 +300,8 @@@ VOID LanSubmitReceiveWork
      PNDIS_PACKET Packet,
      NDIS_STATUS Status,
      UINT BytesTransferred) {
-     PLAN_WQ_ITEM WQItem = exAllocatePool(NonPagedPool, sizeof(LAN_WQ_ITEM));
+     PLAN_WQ_ITEM WQItem = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_WQ_ITEM),
+                                                 WQ_CONTEXT_TAG);
      PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
  
      TI_DbgPrint(DEBUG_DATALINK,("called\n"));
      WQItem->BytesTransferred = BytesTransferred;
  
      if (!ChewCreate( LanReceiveWorker, WQItem ))
-         exFreePool(WQItem);
+         ExFreePoolWithTag(WQItem, WQ_CONTEXT_TAG);
  }
  
  VOID NTAPI ProtocolTransferDataComplete(
@@@ -683,7 -684,7 +684,7 @@@ VOID LANTransmit
          if (Adapter->MTU < Size) {
              /* This is NOT a pointer. MSDN explicitly says so. */
              NDIS_PER_PACKET_INFO_FROM_PACKET(NdisPacket,
 -                                             TcpLargeSendPacketInfo) = (PVOID)((ULONG)Adapter->MTU);
 +                                             TcpLargeSendPacketInfo) = (PVOID)((ULONG_PTR)Adapter->MTU);
          }
  
        TcpipAcquireSpinLock( &Adapter->Lock, &OldIrql );
@@@ -768,9 -769,9 +769,9 @@@ NTSTATUS NTAPI AppendUnicodeString(PUNI
                                   BOOLEAN Deallocate) {
      NTSTATUS Status;
      UNICODE_STRING Ustr = *ResultFirst;
-     PWSTR new_string = ExAllocatePoolWithTag
+     PWSTR new_string = ExAllocatePool
          (PagedPool,
-          (ResultFirst->Length + Second->Length + sizeof(WCHAR)), TAG_STRING);
+          (ResultFirst->Length + Second->Length + sizeof(WCHAR)));
      if( !new_string ) {
        return STATUS_NO_MEMORY;
      }
@@@ -991,6 -992,11 +992,11 @@@ BOOLEAN BindAdapter
      GetName( RegistryPath, &IF->Name );
  
      Status = FindDeviceDescForAdapter( &IF->Name, &IF->Description );
+     if (!NT_SUCCESS(Status)) {
+         TI_DbgPrint(MIN_TRACE, ("Failed to get device description.\n"));
+         IPDestroyInterface(IF);
+         return FALSE;
+     }
  
      TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n",
                  &IF->Description));
@@@ -1082,7 -1088,7 +1088,7 @@@ NDIS_STATUS LANRegisterAdapter
  
      TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
  
-     IF = exAllocatePool(NonPagedPool, sizeof(LAN_ADAPTER));
+     IF = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_ADAPTER), LAN_ADAPTER_TAG);
      if (!IF) {
          TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
          return NDIS_STATUS_RESOURCES;
          KeWaitForSingleObject(&IF->Event, UserRequest, KernelMode, FALSE, NULL);
      else if (NdisStatus != NDIS_STATUS_SUCCESS) {
        TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ\n", AdapterName));
-       exFreePool(IF);
+       ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
          return NdisStatus;
      }
  
      default:
          /* Unsupported media */
          TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n"));
-         exFreePool(IF);
+         ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
          return NDIS_STATUS_NOT_SUPPORTED;
      }
  
                            sizeof(UINT));
      if (NdisStatus != NDIS_STATUS_SUCCESS) {
        TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (NDISCall)\n", AdapterName));
-         exFreePool(IF);
+         ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
          return NdisStatus;
      }
  
                            sizeof(UINT));
      if (NdisStatus != NDIS_STATUS_SUCCESS) {
          TI_DbgPrint(MIN_TRACE, ("Query for maximum packet size failed.\n"));
-         exFreePool(IF);
+         ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
          return NdisStatus;
      }
  
                            IF->HWAddressLength);
      if (NdisStatus != NDIS_STATUS_SUCCESS) {
          TI_DbgPrint(MIN_TRACE, ("Query for current hardware address failed.\n"));
-         exFreePool(IF);
+         ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
          return NdisStatus;
      }
  
                            sizeof(UINT));
      if (NdisStatus != NDIS_STATUS_SUCCESS) {
          TI_DbgPrint(MIN_TRACE, ("Query for maximum link speed failed.\n"));
-         exFreePool(IF);
+         ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
          return NdisStatus;
      }
  
      /* Bind adapter to IP layer */
      if( !BindAdapter(IF, RegistryPath) ) {
        TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (BindAdapter)\n", AdapterName));
-       exFreePool(IF);
+       ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
        return NDIS_STATUS_NOT_ACCEPTED;
      }
  
        <library>chew</library>
        <library>ntoskrnl</library>
        <library>hal</library>
 -      <!-- See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38269
        <directory name="include">
                <pch>precomp.h</pch>
        </directory>
 -      -->
        <directory name="datalink">
                <file>lan.c</file>
        </directory>
-       <directory name="recmutex">
-               <file>recmutex.c</file>
-       </directory>
        <directory name="tcpip">
                <file>ainfo.c</file>
                <file>buffer.c</file>
@@@ -29,7 -28,6 +26,6 @@@
                <file>fileobjs.c</file>
                <file>iinfo.c</file>
                <file>info.c</file>
-               <file>irp.c</file>
                <file>lock.c</file>
                <file>main.c</file>
                <file>ninfo.c</file>
@@@ -38,4 -36,6 +34,4 @@@
                <file>wait.c</file>
        </directory>
        <file>tcpip.rc</file>
 -      <!-- See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 -->
 -      <compilerflag compilerset="gcc">-fno-unit-at-a-time</compilerflag>
  </module>
  #include "precomp.h"
  #include <pseh/pseh2.h>
  
+ NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) {
+     KIRQL OldIrql;
+     Irp->IoStatus.Status = Status;
+     if( Status == STATUS_PENDING )
+       IoMarkIrpPending( Irp );
+     else {
+         IoAcquireCancelSpinLock(&OldIrql);
+       (void)IoSetCancelRoutine( Irp, NULL );
+         IoReleaseCancelSpinLock(OldIrql);
+       IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+     }
+     return Status;
+ }
  NTSTATUS DispPrepareIrpForCancel(
      PTRANSPORT_CONTEXT Context,
      PIRP Irp,
@@@ -70,23 -89,10 +89,10 @@@ VOID DispDataRequestComplete
   *     Count   = Number of bytes sent or received
   */
  {
-     PIRP Irp;
-     PIO_STACK_LOCATION IrpSp;
-     PTRANSPORT_CONTEXT TranContext;
-     KIRQL OldIrql;
+     PIRP Irp = Context;
  
      TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n",
-                           Context, Status, Count));
-     Irp         = Context;
-     IrpSp       = IoGetCurrentIrpStackLocation(Irp);
-     TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
-     IoAcquireCancelSpinLock(&OldIrql);
-     (void)IoSetCancelRoutine(Irp, NULL);
-     IoReleaseCancelSpinLock(OldIrql);
+                           Irp, Status, Count));
  
      Irp->IoStatus.Status      = Status;
      Irp->IoStatus.Information = Count;
      TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n"));
  }
  
- VOID DispDoDisconnect( PVOID Data ) {
-     PDISCONNECT_TYPE DisType = (PDISCONNECT_TYPE)Data;
-     TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect\n"));
-     TcpipRecursiveMutexEnter(&TCPLock, TRUE);
-     TCPDisconnect
-       ( DisType->Context,
-         DisType->Type,
-         NULL,
-         NULL,
-         DispDataRequestComplete,
-         DisType->Irp );
-     TcpipRecursiveMutexLeave(&TCPLock);
-     TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n"));
-     DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0);
-     exFreePool(DisType);
- }
  VOID NTAPI DispCancelRequest(
      PDEVICE_OBJECT Device,
      PIRP Irp)
      PTRANSPORT_CONTEXT TranContext;
      PFILE_OBJECT FileObject;
      UCHAR MinorFunction;
-     PDISCONNECT_TYPE DisType;
+     BOOLEAN DequeuedIrp = TRUE;
+     IoReleaseCancelSpinLock(Irp->CancelIrql);
  
      TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
  
      switch(MinorFunction) {
      case TDI_SEND:
      case TDI_RECEIVE:
-         DisType = exAllocatePool(NonPagedPool, sizeof(DISCONNECT_TYPE));
-         if (DisType)
-         {
-           DisType->Type = TDI_DISCONNECT_RELEASE |
-              ((MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0);
-           DisType->Context = TranContext->Handle.ConnectionContext;
-           DisType->Irp = Irp;
-       TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
-             if (!ChewCreate(DispDoDisconnect, DisType))
-                 exFreePool(DisType);
-         }
-       IoReleaseCancelSpinLock(Irp->CancelIrql);
-         return;
+       DequeuedIrp = TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
+         break;
  
      case TDI_SEND_DATAGRAM:
          if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
              break;
          }
  
-         DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
+         DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
          break;
  
      case TDI_RECEIVE_DATAGRAM:
              break;
          }
  
-         DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
+         DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
          break;
  
      case TDI_CONNECT:
-         TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp);
+         DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp);
          break;
  
      default:
          TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction));
+         ASSERT(FALSE);
          break;
      }
  
-     IoReleaseCancelSpinLock(Irp->CancelIrql);
+     if (DequeuedIrp)
 -       IRPFinish(Irp, STATUS_CANCELLED);
 +    IRPFinish(Irp, STATUS_CANCELLED);
  
      TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
  }
@@@ -224,7 -199,8 +199,8 @@@ VOID NTAPI DispCancelListenRequest
      PTRANSPORT_CONTEXT TranContext;
      PFILE_OBJECT FileObject;
      PCONNECTION_ENDPOINT Connection;
-     /*NTSTATUS Status = STATUS_SUCCESS;*/
+     IoReleaseCancelSpinLock(Irp->CancelIrql);
  
      TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
  
      /* 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"));
  }
@@@ -291,6 -263,7 +263,7 @@@ NTSTATUS DispTdiAssociateAddress
    PFILE_OBJECT FileObject;
    PADDRESS_FILE AddrFile = NULL;
    NTSTATUS Status;
+   KIRQL OldIrql;
  
    TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
  
      return STATUS_INVALID_PARAMETER;
    }
  
-   if (Connection->AddressFile) {
-     TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n"));
-     return STATUS_INVALID_PARAMETER;
-   }
    Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters;
  
    Status = ObReferenceObjectByHandle(
      return STATUS_INVALID_PARAMETER;
    }
  
+   LockObject(Connection, &OldIrql);
+   if (Connection->AddressFile) {
+     ObDereferenceObject(FileObject);
+     UnlockObject(Connection, OldIrql);
+     TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n"));
+     return STATUS_INVALID_PARAMETER;
+   }
    if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
      ObDereferenceObject(FileObject);
+     UnlockObject(Connection, OldIrql);
      TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n",
        FileObject->FsContext2));
      return STATUS_INVALID_PARAMETER;
    TranContext = FileObject->FsContext;
    if (!TranContext) {
      ObDereferenceObject(FileObject);
+     UnlockObject(Connection, OldIrql);
      TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
      return STATUS_INVALID_PARAMETER;
    }
  
    AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
    if (!AddrFile) {
+       UnlockObject(Connection, OldIrql);
        ObDereferenceObject(FileObject);
        TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
        return STATUS_INVALID_PARAMETER;
    }
  
+   LockObjectAtDpcLevel(AddrFile);
+   ReferenceObject(AddrFile);
    Connection->AddressFile = AddrFile;
  
    /* Add connection endpoint to the address file */
+   ReferenceObject(Connection);
    AddrFile->Connection = Connection;
  
    /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
    ObDereferenceObject(FileObject);
  
+   UnlockObjectFromDpcLevel(AddrFile);
+   UnlockObject(Connection, OldIrql);
    return Status;
  }
  
@@@ -387,8 -374,6 +374,6 @@@ NTSTATUS DispTdiConnect
  
    /* Get associated connection endpoint file object. Quit if none exists */
  
-   TcpipRecursiveMutexEnter( &TCPLock, TRUE );
    TranContext = IrpSp->FileObject->FsContext;
    if (!TranContext) {
      TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
    }
  
  done:
-   TcpipRecursiveMutexLeave( &TCPLock );
    if (Status != STATUS_PENDING) {
        DispDataRequestComplete(Irp, Status, 0);
    } else
@@@ -445,6 -428,7 +428,7 @@@ NTSTATUS DispTdiDisassociateAddress
    PCONNECTION_ENDPOINT Connection;
    PTRANSPORT_CONTEXT TranContext;
    PIO_STACK_LOCATION IrpSp;
+   KIRQL OldIrql;
  
    TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
  
      return STATUS_INVALID_PARAMETER;
    }
  
+   LockObject(Connection, &OldIrql);
    if (!Connection->AddressFile) {
+     UnlockObject(Connection, OldIrql);
      TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n"));
      return STATUS_INVALID_PARAMETER;
    }
  
+   LockObjectAtDpcLevel(Connection->AddressFile);
    /* Remove this connection from the address file */
+   DereferenceObject(Connection->AddressFile->Connection);
    Connection->AddressFile->Connection = NULL;
  
+   UnlockObjectFromDpcLevel(Connection->AddressFile);
    /* Remove the address file from this connection */
+   DereferenceObject(Connection->AddressFile);
    Connection->AddressFile = NULL;
  
+   UnlockObject(Connection, OldIrql);
    return STATUS_SUCCESS;
  }
  
@@@ -500,8 -495,6 +495,6 @@@ NTSTATUS DispTdiDisconnect
    IrpSp = IoGetCurrentIrpStackLocation(Irp);
    DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters;
  
-   TcpipRecursiveMutexEnter( &TCPLock, TRUE );
    /* Get associated connection endpoint file object. Quit if none exists */
  
    TranContext = IrpSp->FileObject->FsContext;
        Irp );
  
  done:
-    TcpipRecursiveMutexLeave( &TCPLock );
     if (Status != STATUS_PENDING) {
         DispDataRequestComplete(Irp, Status, 0);
     } else
@@@ -555,6 -546,7 +546,7 @@@ NTSTATUS DispTdiListen
    PTRANSPORT_CONTEXT TranContext;
    PIO_STACK_LOCATION IrpSp;
    NTSTATUS Status = STATUS_SUCCESS;
+   KIRQL OldIrql;
  
    TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
  
  
    /* Get associated connection endpoint file object. Quit if none exists */
  
-   TcpipRecursiveMutexEnter( &TCPLock, TRUE );
    TranContext = IrpSp->FileObject->FsContext;
    if (TranContext == NULL)
      {
  
    Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
  
-   TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n",
-                         Connection->AddressFile ));
-   ASSERT(Connection->AddressFile);
    Status = DispPrepareIrpForCancel
        (TranContext->Handle.ConnectionContext,
         Irp,
         (PDRIVER_CANCEL)DispCancelListenRequest);
  
+   LockObject(Connection, &OldIrql);
+   if (Connection->AddressFile == NULL)
+   {
+      TI_DbgPrint(MID_TRACE, ("No associated address file\n"));
+      UnlockObject(Connection, OldIrql);
+      Status = STATUS_INVALID_PARAMETER;
+      goto done;
+   }
+   LockObjectAtDpcLevel(Connection->AddressFile);
    /* Listening will require us to create a listening socket and store it in
     * the address file.  It will be signalled, and attempt to complete an irp
     * when a new connection arrives. */
          Status = STATUS_NO_MEMORY;
  
        if( NT_SUCCESS(Status) ) {
+           ReferenceObject(Connection->AddressFile);
          Connection->AddressFile->Listener->AddressFile =
              Connection->AddressFile;
  
            Irp );
    }
  
- done:
-   TcpipRecursiveMutexLeave( &TCPLock );
+   UnlockObjectFromDpcLevel(Connection->AddressFile);
+   UnlockObject(Connection, OldIrql);
  
+ done:
    if (Status != STATUS_PENDING) {
        DispDataRequestComplete(Irp, Status, 0);
    } else
@@@ -656,19 -656,15 +656,15 @@@ NTSTATUS DispTdiQueryInformation
    PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters;
    PTRANSPORT_CONTEXT TranContext;
    PIO_STACK_LOCATION IrpSp;
-   NTSTATUS Status;
  
    TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
  
    IrpSp = IoGetCurrentIrpStackLocation(Irp);
    Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;
  
-   TcpipRecursiveMutexEnter( &TCPLock, TRUE );
    TranContext = IrpSp->FileObject->FsContext;
    if (!TranContext) {
      TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
-     TcpipRecursiveMutexLeave(&TCPLock);
      return STATUS_INVALID_PARAMETER;
    }
  
              (FIELD_OFFSET(TDI_ADDRESS_INFO, Address.Address[0].Address) +
               sizeof(TDI_ADDRESS_IP))) {
            TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n"));
-           TcpipRecursiveMutexLeave(&TCPLock);
            return STATUS_BUFFER_TOO_SMALL;
          }
  
          AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress);
                Address = (PTA_IP_ADDRESS)&AddressInfo->Address;
  
 -        switch ((ULONG)IrpSp->FileObject->FsContext2) {
 +        switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
            case TDI_TRANSPORT_ADDRESS_FILE:
              AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
  
                        RtlZeroMemory(
                                &Address->Address[0].Address[0].sin_zero,
                                sizeof(Address->Address[0].Address[0].sin_zero));
-                       TcpipRecursiveMutexLeave(&TCPLock);
                        return STATUS_SUCCESS;
  
            case TDI_CONNECTION_FILE:
              Endpoint =
                                (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
-                       TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE );
-                       DbgPrint("Returning socket address %x\n", Address->Address[0].Address[0].in_addr);
                        RtlZeroMemory(
                                &Address->Address[0].Address[0].sin_zero,
                                sizeof(Address->Address[0].Address[0].sin_zero));
-                       TcpipRecursiveMutexLeave(&TCPLock);
-                       return STATUS_SUCCESS;
+                       return TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE );
  
            default:
              TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
-             TcpipRecursiveMutexLeave(&TCPLock);
              return STATUS_INVALID_PARAMETER;
          }
        }
              (FIELD_OFFSET(TDI_CONNECTION_INFORMATION, RemoteAddress) +
               sizeof(PVOID))) {
            TI_DbgPrint(MID_TRACE, ("MDL buffer too small (ptr).\n"));
-           TcpipRecursiveMutexLeave(&TCPLock);
            return STATUS_BUFFER_TOO_SMALL;
          }
  
          AddressInfo = (PTDI_CONNECTION_INFORMATION)
            MmGetSystemAddressForMdl(Irp->MdlAddress);
  
 -        switch ((ULONG)IrpSp->FileObject->FsContext2) {
 +        switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
            case TDI_TRANSPORT_ADDRESS_FILE:
              AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
              Endpoint = AddrFile ? AddrFile->Connection : NULL;
  
            default:
              TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
-             TcpipRecursiveMutexLeave(&TCPLock);
              return STATUS_INVALID_PARAMETER;
          }
  
          if (!Endpoint) {
            TI_DbgPrint(MID_TRACE, ("No connection object.\n"));
-           TcpipRecursiveMutexLeave(&TCPLock);
            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;
  }
  
@@@ -799,8 -791,6 +791,6 @@@ NTSTATUS DispTdiReceive
    IrpSp = IoGetCurrentIrpStackLocation(Irp);
    ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
  
-   TcpipRecursiveMutexEnter( &TCPLock, TRUE );
    TranContext = IrpSp->FileObject->FsContext;
    if (TranContext == NULL)
      {
      }
  
  done:
-   TcpipRecursiveMutexLeave( &TCPLock );
    if (Status != STATUS_PENDING) {
        DispDataRequestComplete(Irp, Status, BytesReceived);
    } else
@@@ -871,8 -859,6 +859,6 @@@ NTSTATUS DispTdiReceiveDatagram
    IrpSp     = IoGetCurrentIrpStackLocation(Irp);
    DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters);
  
-   TcpipRecursiveMutexEnter( &TCPLock, TRUE );
    TranContext = IrpSp->FileObject->FsContext;
    if (TranContext == NULL)
      {
      }
  
  done:
-    TcpipRecursiveMutexLeave( &TCPLock );
     if (Status != STATUS_PENDING) {
         DispDataRequestComplete(Irp, Status, BytesReceived);
     } else
@@@ -948,8 -932,6 +932,6 @@@ NTSTATUS DispTdiSend
    IrpSp = IoGetCurrentIrpStackLocation(Irp);
    SendInfo = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters);
  
-   TcpipRecursiveMutexEnter( &TCPLock, TRUE );
    TranContext = IrpSp->FileObject->FsContext;
    if (TranContext == NULL)
      {
      }
  
  done:
-    TcpipRecursiveMutexLeave( &TCPLock );
     if (Status != STATUS_PENDING) {
         DispDataRequestComplete(Irp, Status, BytesSent);
     } else
@@@ -1024,8 -1004,6 +1004,6 @@@ NTSTATUS DispTdiSendDatagram
      IrpSp       = IoGetCurrentIrpStackLocation(Irp);
      DgramInfo   = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters);
  
-     TcpipRecursiveMutexEnter( &TCPLock, TRUE );
      TranContext = IrpSp->FileObject->FsContext;
      if (TranContext == NULL)
      {
                     (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)));
  
          if( (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send != NULL) )
 +        {
 +              ULONG DataUsed = 0;
              Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
                  Request.Handle.AddressHandle,
                  DgramInfo->SendDatagramInformation,
                  DataBuffer,
                  BufferSize,
 -                &Irp->IoStatus.Information);
 +                &DataUsed);
 +            Irp->IoStatus.Information = DataUsed;
 +        }
-         else
+         else {
              Status = STATUS_UNSUCCESSFUL;
 -        }
+             ASSERT(FALSE);
++    }
      }
  
  done:
-     TcpipRecursiveMutexLeave( &TCPLock );
      if (Status != STATUS_PENDING) {
          DispDataRequestComplete(Irp, Status, Irp->IoStatus.Information);
      } else
@@@ -1126,7 -1100,7 +1104,7 @@@ NTSTATUS DispTdiSetEventHandler(PIRP Ir
    Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
    Status     = STATUS_SUCCESS;
  
-   TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+   LockObject(AddrFile, &OldIrql);
  
    /* Set the event handler. if an event handler is associated with
       a specific event, it's flag (RegisteredXxxHandler) is TRUE.
      Status = STATUS_INVALID_PARAMETER;
    }
  
-   TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+   UnlockObject(AddrFile, OldIrql);
  
    return Status;
  }
@@@ -1282,11 -1256,10 +1260,10 @@@ VOID DispTdiQueryInformationExComplete
   */
  {
      PTI_QUERY_CONTEXT QueryContext;
-     UINT Count = 0;
  
      QueryContext = (PTI_QUERY_CONTEXT)Context;
      if (NT_SUCCESS(Status)) {
-         Count = CopyBufferToBufferChain(
+         CopyBufferToBufferChain(
              QueryContext->InputMdl,
              FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context),
              (PCHAR)&QueryContext->QueryInfo.Context,
      QueryContext->Irp->IoStatus.Information = ByteCount;
      QueryContext->Irp->IoStatus.Status      = Status;
  
-     exFreePool(QueryContext);
+     ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
  }
  
  
@@@ -1337,7 -1310,7 +1314,7 @@@ NTSTATUS DispTdiQueryInformationEx
  
      TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
  
 -    switch ((ULONG)IrpSp->FileObject->FsContext2) {
 +    switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
      case TDI_TRANSPORT_ADDRESS_FILE:
          Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
          break;
              IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
          OutputBuffer = Irp->UserBuffer;
  
-         QueryContext = exAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
+         QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG);
          if (QueryContext) {
            _SEH2_TRY {
                  InputMdl = IoAllocateMdl(InputBuffer,
                  IoFreeMdl(OutputMdl);
              }
  
-             exFreePool(QueryContext);
+             ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
          } else
              Status = STATUS_INSUFFICIENT_RESOURCES;
      } else if( InputBufferLength ==
  
        Size = 0;
  
-         QueryContext = exAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
+         QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG);
          if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES;
  
        _SEH2_TRY {
  
        if( !NT_SUCCESS(Status) || !InputMdl ) {
            if( InputMdl ) IoFreeMdl( InputMdl );
-           exFreePool(QueryContext);
+           ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
            return Status;
        }
  
@@@ -1512,7 -1485,7 +1489,7 @@@ NTSTATUS DispTdiSetInformationEx
      TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
      Info        = (PTCP_REQUEST_SET_INFORMATION_EX)Irp->AssociatedIrp.SystemBuffer;
  
 -    switch ((ULONG)IrpSp->FileObject->FsContext2) {
 +    switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
      case TDI_TRANSPORT_ADDRESS_FILE:
          Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
          break;
@@@ -5,53 -5,31 +5,52 @@@
                <include>include</include>
                <include base="ntoskrnl">include</include>
                <define name="_NTHAL_" />
 +              <define name="_X86BIOS_" />
                <directory name="generic">
                        <directory name="bus">
                                <file>bushndlr.c</file>
                                <file>isabus.c</file>
                                <file>halbus.c</file>
 +                              <file>pcibus.c</file>
                                <file>pcidata.c</file>
                                <file>sysbus.c</file>
                        </directory>
                        <file>beep.c</file>
 -                      <file>bios.c</file>
                        <file>cmos.c</file>
                        <file>dma.c</file>
                        <file>drive.c</file>
                        <file>display.c</file>
 -                      <file>halinit.c</file>
 -                      <file>misc.c</file>
 -                      <file>portio.c</file>
                        <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>
@@@ -127,6 -127,161 +127,161 @@@ typedef union _SYSTEM_CONTROL_PORT_B_RE
      UCHAR Bits;
  } SYSTEM_CONTROL_PORT_B_REGISTER, *PSYSTEM_CONTROL_PORT_B_REGISTER;
  
+ //
+ // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
+ // P. 396, 397
+ //
+ // These ports are controlled by the i8259 Programmable Interrupt Controller (PIC)
+ //
+ #define PIC1_CONTROL_PORT      0x20
+ #define PIC1_DATA_PORT         0x21
+ #define PIC2_CONTROL_PORT      0xA0
+ #define PIC2_DATA_PORT         0xA1
+ //
+ // Definitions for ICW/OCW Bits
+ //
+ typedef enum _I8259_ICW1_OPERATING_MODE
+ {
+     Cascade,
+     Single
+ } I8259_ICW1_OPERATING_MODE;
+ typedef enum _I8259_ICW1_INTERRUPT_MODE
+ {
+     EdgeTriggered,
+     LevelTriggered
+ } I8259_ICW1_INTERRUPT_MODE;
+ typedef enum _I8259_ICW1_INTERVAL
+ {
+     Interval8,
+     Interval4
+ } I8259_ICW1_INTERVAL;
+ typedef enum _I8259_ICW4_SYSTEM_MODE
+ {
+     Mcs8085Mode,
+     New8086Mode
+ } I8259_ICW4_SYSTEM_MODE;
+ typedef enum _I8259_ICW4_EOI_MODE
+ {
+     NormalEoi,
+     AutomaticEoi
+ } I8259_ICW4_EOI_MODE;
+ typedef enum _I8259_ICW4_BUFFERED_MODE
+ {
+     NonBuffered,
+     NonBuffered2,
+     BufferedSlave,
+     BufferedMaster
+ } I8259_ICW4_BUFFERED_MODE;
+ //
+ // Definitions for ICW Registers
+ //
+ typedef union _I8259_ICW1
+ {
+     struct 
+     {
+         UCHAR NeedIcw4:1;
+         I8259_ICW1_OPERATING_MODE OperatingMode:1;
+         I8259_ICW1_INTERVAL Interval:1;
+         I8259_ICW1_INTERRUPT_MODE InterruptMode:1;
+         UCHAR Init:1;
+         UCHAR InterruptVectorAddress:3;
+     };
+     UCHAR Bits;
+ } I8259_ICW1, *PI8259_ICW1;
+ typedef union _I8259_ICW2
+ {
+     struct 
+     {
+         UCHAR Sbz:3;
+         UCHAR InterruptVector:5;
+     };
+     UCHAR Bits;
+ } I8259_ICW2, *PI8259_ICW2;
+ typedef union _I8259_ICW3
+ {
+     union
+     {
+         struct 
+         {
+             UCHAR SlaveIrq0:1;
+             UCHAR SlaveIrq1:1;
+             UCHAR SlaveIrq2:1;
+             UCHAR SlaveIrq3:1;
+             UCHAR SlaveIrq4:1;
+             UCHAR SlaveIrq5:1;
+             UCHAR SlaveIrq6:1;
+             UCHAR SlaveIrq7:1;
+         };
+         struct 
+         {
+             UCHAR SlaveId:3;
+             UCHAR Reserved:5;
+         };
+     };
+     UCHAR Bits;
+ } I8259_ICW3, *PI8259_ICW3;
+ typedef union _I8259_ICW4
+ {
+     struct 
+     {
+         I8259_ICW4_SYSTEM_MODE SystemMode:1;
+         I8259_ICW4_EOI_MODE EoiMode:1;
+         I8259_ICW4_BUFFERED_MODE BufferedMode:2;
+         UCHAR SpecialFullyNestedMode:1;
+         UCHAR Reserved:3;
+     };
+     UCHAR Bits;
+ } I8259_ICW4, *PI8259_ICW4;
+ //
+ // See EISA System Architecture 2nd Edition (Tom Shanley, Don Anderson, John Swindle)
+ // P. 34, 35
+ //
+ // These ports are controlled by the i8259A Programmable Interrupt Controller (PIC)
+ //
+ #define EISA_ELCR_MASTER       0x4D0
+ #define EISA_ELCR_SLAVE        0x4D1
+ typedef union _EISA_ELCR
+ {
+     struct
+     {
+         struct
+         {
+             UCHAR Irq0Level:1;
+             UCHAR Irq1Level:1;
+             UCHAR Irq2Level:1;
+             UCHAR Irq3Level:1;
+             UCHAR Irq4Level:1;
+             UCHAR Irq5Level:1;
+             UCHAR Irq6Level:1;
+             UCHAR Irq7Level:1;
+         } Master;
+         struct
+         {
+             UCHAR Irq8Level:1;
+             UCHAR Irq9Level:1;
+             UCHAR Irq10Level:1;
+             UCHAR Irq11Level:1;
+             UCHAR Irq12Level:1;
+             UCHAR Irq13Level:1;
+             UCHAR Irq14Level:1;
+             UCHAR Irq15Level:1;
+         } Slave;
+     };
+     USHORT Bits;
+ } EISA_ELCR, *PEISA_ELCR;
  //
  // Mm PTE/PDE to Hal PTE/PDE
  //
@@@ -176,8 -331,8 +331,8 @@@ HalpEnableInterruptHandler(IN UCHAR Fla
                             IN PVOID Handler,
                             IN KINTERRUPT_MODE Mode);
  
- /* irql.c */
- VOID NTAPI HalpInitPICs(VOID);
+ /* pic.c */
+ VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
  
  /* udelay.c */
  VOID NTAPI HalpInitializeClock(VOID);
@@@ -325,10 -480,6 +480,10 @@@ HalpReleaseCmosSpinLock
      VOID
  );
  
 +VOID
 +NTAPI
 +HalpSetInterruptGate(ULONG Index, PVOID Address);
 +
  #ifdef _M_AMD64
  #define KfLowerIrql KeLowerIrql
  #ifndef CONFIG_SMP
@@@ -20,7 -20,7 +20,7 @@@
   *
   * COPYRIGHT:   See COPYING in the top level directory
   * PROJECT:     ReactOS kernel
-  * FILE:        hal/halx86/apic.c
+  * FILE:        hal/halx86/mp/apic.c
   * PURPOSE:     
   * PROGRAMMER:  
   */
@@@ -798,8 -798,6 +798,8 @@@ APICCalibrateTimer(ULONG CPU
     LONG tt1, tt2;
     BOOLEAN TSCPresent;
  
 +   t1.QuadPart = 0;
 +
     DPRINT("Calibrating APIC timer for CPU %d\n", CPU);
  
     APICSetupLVTT(1000000000);
          CPUMap[CPU].BusSpeed%1000000);
  }
  
 -VOID 
 -SetInterruptGate(ULONG index, ULONG_PTR address)
 -{
 -#ifdef _M_AMD64
 -  KIDTENTRY64 *idt;
 -
 -  idt = &KeGetPcr()->IdtBase[index];
 -
 -  idt->OffsetLow = address & 0xffff;
 -  idt->Selector = KGDT_64_R0_CODE;
 -  idt->IstIndex = 0;
 -  idt->Reserved0 = 0;
 -  idt->Type = 0x0e;
 -  idt->Dpl = 0;
 -  idt->Present = 1;
 -  idt->OffsetMiddle = (address >> 16) & 0xffff;
 -  idt->OffsetHigh = address >> 32;
 -  idt->Reserved1 = 0;
 -  idt->Alignment = 0;
 -#else
 -  KIDTENTRY *idt;
 -  KIDT_ACCESS Access;
 -
 -  /* Set the IDT Access Bits */
 -  Access.Reserved = 0;
 -  Access.Present = 1;
 -  Access.Dpl = 0; /* Kernel-Mode */
 -  Access.SystemSegmentFlag = 0;
 -  Access.SegmentType = I386_INTERRUPT_GATE;
 -  
 -  idt = (KIDTENTRY*)((ULONG)KeGetPcr()->IDT + index * sizeof(KIDTENTRY));
 -  idt->Offset = (USHORT)(address & 0xffff);
 -  idt->Selector = KGDT_R0_CODE;
 -  idt->Access = Access.Value;
 -  idt->ExtendedOffset = (USHORT)(address >> 16);
 -#endif
 -}
 -
  VOID HaliInitBSP(VOID)
  {
  #ifdef CONFIG_SMP
     BSPInitialized = TRUE;
  
     /* Setup interrupt handlers */
 -   SetInterruptGate(LOCAL_TIMER_VECTOR, (ULONG_PTR)MpsTimerInterrupt);
 -   SetInterruptGate(ERROR_VECTOR, (ULONG_PTR)MpsErrorInterrupt);
 -   SetInterruptGate(SPURIOUS_VECTOR, (ULONG_PTR)MpsSpuriousInterrupt);
 +   HalpSetInterruptGate(LOCAL_TIMER_VECTOR, MpsTimerInterrupt);
 +   HalpSetInterruptGate(ERROR_VECTOR, MpsErrorInterrupt);
 +   HalpSetInterruptGate(SPURIOUS_VECTOR, MpsSpuriousInterrupt);
  #ifdef CONFIG_SMP
 -   SetInterruptGate(IPI_VECTOR, (ULONG_PTR)MpsIpiInterrupt);
 +   HalpSetInterruptGate(IPI_VECTOR, MpsIpiInterrupt);
  #endif
 -   DPRINT("APIC is mapped at 0x%X\n", APICBase);
 +   DPRINT1("APIC is mapped at 0x%p\n", (PVOID)APICBase);
  
     if (VerifyLocalAPIC()) 
     {
     } 
     else 
     {
 -      DPRINT("No APIC found\n");
 +      DPRINT1("No APIC found\n");
        ASSERT(FALSE);
     }
  
@@@ -2,7 -2,7 +2,7 @@@
   *
   * COPYRIGHT:       See COPYING in the top level directory
   * PROJECT:         ReactOS kernel
-  * FILE:            ntoskrnl/hal/x86/mps.S
+  * FILE:            hal/halx86/mp/mps.S
   * PURPOSE:         Intel MultiProcessor specification support
   * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
   * UPDATE HISTORY:
@@@ -1,7 -1,7 +1,7 @@@
  ;
  ; COPYRIGHT:       See COPYING in the top level directory
  ; PROJECT:         ReactOS kernel
- ; FILE:            ntoskrnl/hal/x86/mpsboot.c
+ ; FILE:            hal/halx86/mp/mpsboot.c
  ; PURPOSE:         Bootstrap code for application processors
  ; PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
  ; UPDATE HISTORY:
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * COPYRIGHT:       See COPYING in the top level directory
   * PROJECT:         ReactOS kernel
-  * FILE:            ntoskrnl/hal/x86/mpsirql.c
+  * FILE:            hal/halx86/mp/mpsirql.c
   * PURPOSE:         Implements IRQLs for multiprocessor systems
   * PROGRAMMERS:     David Welch (welch@cwcom.net)
   *                  Casper S. Hornstrup (chorns@users.sourceforge.net)
@@@ -143,6 -143,30 +143,6 @@@ KfLowerIrql (KIRQL        NewIrql
    HalpLowerIrql (NewIrql, FALSE);
  }
  
 -
 -/**********************************************************************
 - * NAME                                                       EXPORTED
 - *    KeLowerIrql
 - *
 - * DESCRIPTION
 - *    Restores the irq level on the current processor
 - *
 - * ARGUMENTS
 - *    NewIrql = Irql to lower to
 - *
 - * RETURN VALUE
 - *    None
 - *
 - * NOTES
 - */
 -#undef KeLowerIrql
 -VOID NTAPI
 -KeLowerIrql (KIRQL NewIrql)
 -{
 -  KfLowerIrql (NewIrql);
 -}
 -
 -
  /**********************************************************************
   * NAME                                                       EXPORTED
   *    KfRaiseIrql
@@@ -192,6 -216,32 +192,6 @@@ KfRaiseIrql (KIRQL        NewIrql
  }
  
  
 -/**********************************************************************
 - * NAME                                                       EXPORTED
 - *    KeRaiseIrql
 - *
 - * DESCRIPTION
 - *    Raises the hardware priority (irql)
 - *
 - * ARGUMENTS
 - *    NewIrql = Irql to raise to
 - *    OldIrql (OUT) = Caller supplied storage for the previous irql
 - *
 - * RETURN VALUE
 - *    None
 - *
 - * NOTES
 - *    Calls KfRaiseIrql
 - */
 -#undef KeRaiseIrql
 -VOID NTAPI
 -KeRaiseIrql (KIRQL    NewIrql,
 -      PKIRQL  OldIrql)
 -{
 -  *OldIrql = KfRaiseIrql (NewIrql);
 -}
 -
 -
  /**********************************************************************
   * NAME                                                       EXPORTED
   *    KeRaiseIrqlToDpcLevel
@@@ -288,8 -338,8 +288,8 @@@ HalEndSystemInterrupt (KIRQL Irql
    
  VOID
  NTAPI
 -HalDisableSystemInterrupt(ULONG Vector,
 -                                    KIRQL Irql)
 +HalDisableSystemInterrupt (ULONG Vector,
 +                         KIRQL Irql)
  {
    ULONG irq;
  
  
  /* GLOBALS *******************************************************************/
  
- PICInitTable:
-     /* Master PIC */
-     .short 0x20                         /* Port */
-     .byte 0x11                          /* Edge, cascade, CAI 8, ICW4 */
-     .byte PRIMARY_VECTOR_BASE           /* Base */
-     .byte 4                             /* IRQ 4 connected to slave */
-     .byte 1                             /* Non buffered, not nested, 8086 */
-     /* Slave PIC */
-     .short 0xA0                         /* Port */
-     .byte 0x11                          /* Edge, cascade, CAI 8, ICW4 */
-     .byte PRIMARY_VECTOR_BASE + 8       /* Base */
-     .byte 2                             /* Slave ID: Slave 2 */
-     .byte 1                             /* Non buffered, not nested, 8086 */
-     /* End of initialization table */
-     .short 0
  KiI8259MaskTable:
      .long 0                             /* IRQL 0 */
      .long 0                             /* IRQL 1 */
@@@ -104,19 -85,19 +85,19 @@@ FindHigherIrqlMask
      .long 0                             /* IRQL 31 */
  
  HalpSpecialDismissTable:
- .rept 7
    .rept 7
      .long GenericIRQ                    /* IRQ 0-7 */
- .endr
    .endr
      .long IRQ7                          /* IRQ 7 */
      .rept 5
      .long GenericIRQ                    /* IRQ 8-12 */
- .endr
    .endr
      .long IRQ13                         /* IRQ 13 */
      .long GenericIRQ                    /* IRQ 14 */
      .long IRQ15                         /* IRQ 15 */
- .rept 20
    .rept 20
      .long GenericIRQ                    /* IRQ 16-35 */
- .endr
    .endr
  #if DBG
  .rept 172
      .long InvalidIRQ                    /* IRQ 36-207 */
@@@ -193,66 -174,6 +174,6 @@@ NothingHardware
      ret
  .endfunc
  
- .globl _HalpInitPICs@0
- .func HalpInitPICs@0
- _HalpInitPICs@0:
-     /* Save ESI and disable interrupts */
-     push esi
-     pushf
-     cli
-     /* Read the init table */
-     lea esi, PICInitTable
-     lodsw
- InitLoop:
-     /* Put the port in EDX */
-     movzx edx, ax
-     /* Initialize the PIC, using a delay for each command */
-     outsb
-     jmp $+2
-     inc edx
-     outsb
-     jmp $+2
-     outsb
-     jmp $+2
-     outsb
-     jmp $+2
-     /* Mask all interrupts */
-     mov al, 0xFF
-     out dx, al
-     /* Check if we're done, otherwise initialize next PIC */
-     lodsw
-     cmp ax, 0
-     jnz InitLoop
-     /* Read EISA Edge/Level Register */
-     mov edx, 0x4D1
-     in al, dx
-     mov ah, al
-     dec edx
-     in al, dx
-     /* Clear reserved bits and see if there's anything there */
-     and eax, 0xDEF8
-     cmp eax, 0xDEF8
-     jz NoEisa
-     /* FIXME */
-     //UNHANDLED_PATH
-     /* Restore interrupts and return */
- NoEisa:
-     popf
-     pop esi
-     ret
- .endfunc
  .globl @HalClearSoftwareInterrupt@4
  .func @HalClearSoftwareInterrupt@4, @HalClearSoftwareInterrupt@4
  @HalClearSoftwareInterrupt@4:
@@@ -660,10 -581,10 +581,10 @@@ _@KfLowerIrql@4
      and ecx, 0xFF
  
      /* Validate IRQL */
- #if DBG
    #if DBG
      cmp cl, PCR[KPCR_IRQL]
      ja InvalidIrql
- #endif
    #endif
  
      /* Save flags since we'll disable interrupts */
      pushf
@@@ -722,7 -643,7 +643,7 @@@ DoCall3
  _@KfRaiseIrql@4:
  @KfRaiseIrql@4:
  
-     /* Get the IRQL  */
+     /* Get the IRQL */
      movzx ecx, cl
      mov eax, PCR[KPCR_IRQL]
  
@@@ -1803,6 -1803,12 +1803,12 @@@ extern "C" 
  #define WM_HOTKEY 786
  #define WM_PRINT 791
  #define WM_PRINTCLIENT 792
+ #define WM_DWMCOMPOSITIONCHANGED 0x031E
+ #define WM_DWMNCRENDERINGCHANGED 0x031F
+ #define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320
+ #define WM_DWMWINDOWMAXIMIZEDCHANGE 0x0321
  #define WM_HANDHELDFIRST 856
  #define WM_HANDHELDLAST 863
  #define WM_AFXFIRST 864
@@@ -3195,7 -3201,7 +3201,7 @@@ typedef struct tagICONMETRICSA 
        int iVertSpacing;
        int iTitleWrap;
        LOGFONTA lfFont;
 -} ICONMETRICSA,*LPICONMETRICSA;
 +} ICONMETRICSA, *PICONMETRICSA, *LPICONMETRICSA;
  
  typedef struct tagICONMETRICSW {
        UINT cbSize;
        int iVertSpacing;
        int iTitleWrap;
        LOGFONTW lfFont;
 -} ICONMETRICSW,*LPICONMETRICSW;
 +} ICONMETRICSW, *PICONMETRICSW, *LPICONMETRICSW;
  
  #ifdef UNICODE
  typedef ICONMETRICSW ICONMETRICS,*LPICONMETRICS;
@@@ -4660,14 -4666,14 +4666,14 @@@ typedef MONITORINFOEXW MONITORINFOEX, *
  #define wsprintf wsprintfW
  #define wvsprintf wvsprintfW
  
 -#ifndef NOGDI
 +#if defined(_WINGDI_) && !defined(NOGDI)
  #define ChangeDisplaySettings ChangeDisplaySettingsW
  #define ChangeDisplaySettingsEx ChangeDisplaySettingsExW
  #define CreateDesktop CreateDesktopW
  #define EnumDisplaySettings EnumDisplaySettingsW
  #define EnumDisplaySettingsEx EnumDisplaySettingsExW
  #define EnumDisplayDevices EnumDisplayDevicesW
 -#endif /* NOGDI */
 +#endif /* _WINGDI_ && !NOGDI */
  #else /* UNICODE */
  #define EDITWORDBREAKPROC EDITWORDBREAKPROCA
  #define PROPENUMPROC PROPENUMPROCA
@@@ -94,13 -94,19 +94,19 @@@ typedef struct _THRDESKHEA
  
  typedef struct _PROCDESKHEAD
  {
-   HANDLE h;
-   DWORD  cLockObj;  
+   HEAD;
    DWORD hTaskWow;
    struct _DESKTOP *rpdesk;
    PVOID       pSelf;
  } PROCDESKHEAD, *PPROCDESKHEAD;
  
+ typedef struct _PROCMARKHEAD
+ {
+   HEAD;
+   ULONG hTaskWow;
+   PPROCESSINFO ppi;
+ } PROCMARKHEAD, *PPROCMARKHEAD;
  #define UserHMGetHandle(obj) ((obj)->head.h)
  
  /* Window Client Information structure */
@@@ -195,8 -201,8 +201,8 @@@ typedef struct _CLIENTINF
      PPROCESSINFO ppi;
  } CLIENTINFO, *PCLIENTINFO;
  
 -/* Make sure it fits exactly into the TEB */
 -C_ASSERT(sizeof(CLIENTINFO) == FIELD_OFFSET(TEB, glDispatchTable) - FIELD_OFFSET(TEB, Win32ClientInfo));
 +/* Make sure it fits into the TEB */
 +C_ASSERT(sizeof(CLIENTINFO) <= sizeof(((PTEB)0)->Win32ClientInfo));
  
  #define GetWin32ClientInfo() ((PCLIENTINFO)(NtCurrentTeb()->Win32ClientInfo))
  
@@@ -2881,7 -2887,7 +2887,7 @@@ BOO
  NTAPI
  NtUserTranslateMessage(
    LPMSG lpMsg,
 -  HKL dwhkl );
 +  UINT flags );
  
  BOOL
  NTAPI
  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 =
-         exAllocatePool(NonPagedPool, sizeof(CONNECTION_ENDPOINT));
+         ExAllocatePoolWithTag(NonPagedPool, sizeof(CONNECTION_ENDPOINT),
+                               CONN_ENDPT_TAG);
      if (!Connection)
          return Connection;
  
      RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT));
  
      /* Initialize spin lock that protects the connection endpoint file object */
-     TcpipInitializeSpinLock(&Connection->Lock);
+     KeInitializeSpinLock(&Connection->Lock);
      InitializeListHead(&Connection->ConnectRequest);
      InitializeListHead(&Connection->ListenRequest);
      InitializeListHead(&Connection->ReceiveRequest);
      InitializeListHead(&Connection->SendRequest);
+     InitializeListHead(&Connection->CompletionQueue);
  
      /* Save client context pointer */
      Connection->ClientContext = ClientContext;
  
-     return Connection;
- }
+     /* Add an extra reference for oskit */
+     Connection->RefCount = 2;
+     Connection->Free = ConnectionFree;
  
- VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ) {
-     TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
-     exFreePool( Connection );
+     /* Add connection endpoint to global list */
+     ExInterlockedInsertTailList(&ConnectionEndpointListHead,
+                                 &Connection->ListEntry,
+                                 &ConnectionEndpointListLock);
+     return Connection;
  }
  
  NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
                      UINT Family, UINT Type, UINT Proto ) {
      NTSTATUS Status;
+     KIRQL OldIrql;
  
-     ASSERT_LOCKED(&TCPLock);
+     LockObject(Connection, &OldIrql);
  
      TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, "
                             "Proto %d\n",
      TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
                             Connection->SocketContext));
  
+     UnlockObject(Connection, OldIrql);
      return Status;
  }
  
@@@ -358,19 -384,22 +384,22 @@@ VOID TCPReceive(PIP_INTERFACE Interface
   *     This is the low level interface for receiving TCP data
   */
  {
+     KIRQL OldIrql;
      TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to oskit\n",
                             IPPacket->TotalSize,
                             IPPacket->HeaderSize));
  
-     TcpipRecursiveMutexEnter( &TCPLock, TRUE );
+     KeAcquireSpinLock(&ClientInfo.Lock, &OldIrql);
+     ClientInfo.Unlocked = TRUE;
+     ClientInfo.OldIrql = OldIrql;
  
      OskitTCPReceiveDatagram( IPPacket->Header,
                               IPPacket->TotalSize,
                               IPPacket->HeaderSize );
  
-     DrainSignals();
-     TcpipRecursiveMutexLeave( &TCPLock );
+     ClientInfo.Unlocked = FALSE;
+     KeReleaseSpinLock(&ClientInfo.Lock, OldIrql);
  }
  
  /* event.c */
@@@ -395,11 -424,6 +424,6 @@@ void TCPFree( void *ClientData
                void *data, OSK_PCHAR file, OSK_UINT line );
  void TCPMemShutdown( void );
  
- int TCPSleep( void *ClientData, void *token, int priority, char *msg,
-               int tmio );
- void TCPWakeup( void *ClientData, void *token );
  OSKITTCP_EVENT_HANDLERS EventHandlers = {
      NULL,             /* Client Data */
      TCPSocketState,   /* SocketState */
      TCPFindInterface, /* FindInterface */
      TCPMalloc,        /* Malloc */
      TCPFree,          /* Free */
-     TCPSleep,         /* Sleep */
-     TCPWakeup         /* Wakeup */
+     NULL,             /* Sleep */
+     NULL,             /* Wakeup */
  };
  
  static KEVENT TimerLoopEvent;
@@@ -434,7 -458,7 +458,7 @@@ TimerThread(PVOID Context
      while ( 1 ) {
          if (Next == NextFast) {
              NextFast += 2;
 -       }
 +        }
          if (Next == NextSlow) {
              NextSlow += 5;
          }
              PsTerminateSystemThread(Status);
          }
  
-         TcpipRecursiveMutexEnter( &TCPLock, TRUE );
          TimerOskitTCP( Next == NextFast, Next == NextSlow );
-         if (Next == NextSlow) {
-             DrainSignals();
-         }
-         TcpipRecursiveMutexLeave( &TCPLock );
  
          Current = Next;
          if (10 <= Current) {
@@@ -471,7 -490,6 +490,6 @@@ StartTimer(VOID
                           TimerThread, NULL);
  }
  
  NTSTATUS TCPStartup(VOID)
  /*
   * FUNCTION: Initializes the TCP subsystem
  {
      NTSTATUS Status;
  
-     TcpipRecursiveMutexInit( &TCPLock );
-     ExInitializeFastMutex( &SleepingThreadsLock );
-     KeInitializeSpinLock( &SignalledConnectionsLock );
-     InitializeListHead( &SleepingThreadsList );
-     InitializeListHead( &SignalledConnectionsList );
      Status = TCPMemStartup();
      if ( ! NT_SUCCESS(Status) ) {
          return Status;
          return Status;
      }
  
-     TcpipRecursiveMutexEnter(&TCPLock, TRUE);
+     KeInitializeSpinLock(&ClientInfo.Lock);
+     ClientInfo.Unlocked = FALSE;
      RegisterOskitTCPEventHandlers( &EventHandlers );
      InitOskitTCP();
-     TcpipRecursiveMutexLeave(&TCPLock);
  
      /* Register this protocol with IP layer */
      IPRegisterProtocol(IPPROTO_TCP, TCPReceive);
@@@ -561,8 -575,9 +575,9 @@@ NTSTATUS TCPTranslateError( int OskitEr
      case 0: Status = STATUS_SUCCESS; break;
      case OSK_EADDRNOTAVAIL: Status = STATUS_INVALID_ADDRESS; break;
      case OSK_EAFNOSUPPORT: Status = STATUS_INVALID_CONNECTION; break;
-     case OSK_ECONNREFUSED:
-     case OSK_ECONNRESET: Status = STATUS_REMOTE_NOT_LISTENING; break;
+     case OSK_ECONNREFUSED: Status = STATUS_REMOTE_NOT_LISTENING; break;
+     case OSK_ECONNRESET:
+     case OSK_ECONNABORTED: Status = STATUS_REMOTE_DISCONNECT; break;
      case OSK_EWOULDBLOCK:
      case OSK_EINPROGRESS: Status = STATUS_PENDING; break;
      case OSK_EINVAL: Status = STATUS_INVALID_PARAMETER; break;
@@@ -595,11 -610,10 +610,10 @@@ NTSTATUS TCPConnec
      USHORT RemotePort;
      PTDI_BUCKET Bucket;
      PNEIGHBOR_CACHE_ENTRY NCE;
+     KIRQL OldIrql;
  
      TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n"));
  
-     ASSERT_LOCKED(&TCPLock);
      Status = AddrBuildAddress
          ((PTRANSPORT_ADDRESS)ConnInfo->RemoteAddress,
           &RemoteAddress,
          return Status;
      }
  
-     if (!(NCE = RouteGetRouteToDestination(&RemoteAddress)))
-     {
-         return STATUS_NETWORK_UNREACHABLE;
-     }
-     if (Connection->State & SEL_FIN)
-     {
-         return STATUS_REMOTE_DISCONNECT;
-     }
      /* Freed in TCPSocketState */
      TI_DbgPrint(DEBUG_TCP,
                  ("Connecting to address %x:%x\n",
  
      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,
  
          Status = TCPTranslateError
              ( OskitTCPConnect( Connection->SocketContext,
-                                Connection,
                                 &AddressToConnect,
                                 sizeof(AddressToConnect) ) );
  
          if (Status == STATUS_PENDING)
          {
-             Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
-             if( !Bucket ) return STATUS_NO_MEMORY;
+             Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG );
+             if( !Bucket )
+             {
+                UnlockObject(Connection, OldIrql);
+                return STATUS_NO_MEMORY;
+             }
              
              Bucket->Request.RequestNotifyObject = (PVOID)Complete;
              Bucket->Request.RequestContext = Context;
 -                      
 +            
-             IoMarkIrpPending((PIRP)Context);
-                       
-             ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, &Connection->Lock );
+             InsertTailList( &Connection->ConnectRequest, &Bucket->Entry );
          }
      }
  
+     UnlockObject(Connection, OldIrql);
      return Status;
  }
  
@@@ -671,29 -700,20 +700,20 @@@ NTSTATUS TCPDisconnec
    PTDI_CONNECTION_INFORMATION ReturnInfo,
    PTCP_COMPLETION_ROUTINE Complete,
    PVOID Context ) {
-     NTSTATUS Status;
-     ASSERT_LOCKED(&TCPLock);
+     NTSTATUS Status = STATUS_INVALID_PARAMETER;
+     KIRQL OldIrql;
  
      TI_DbgPrint(DEBUG_TCP,("started\n"));
  
-     switch( Flags & (TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE) ) {
-     case 0:
-     case TDI_DISCONNECT_ABORT:
-         Flags = 0;
-         break;
+     LockObject(Connection, &OldIrql);
  
-     case TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE:
-         Flags = 2;
-         break;
+     if (Flags & TDI_DISCONNECT_RELEASE)
+         Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext));
  
-     case TDI_DISCONNECT_RELEASE:
-         Flags = 1;
-         break;
-     }
+     if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
+         Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD));
  
-     Status = TCPTranslateError
-         ( OskitTCPShutdown( Connection->SocketContext, Flags ) );
+     UnlockObject(Connection, OldIrql);
  
      TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status));
  
  }
  
  NTSTATUS TCPClose
- ( PCONNECTION_ENDPOINT Connection ) {
+ ( PCONNECTION_ENDPOINT Connection )
+ {
+     KIRQL OldIrql;
      NTSTATUS Status;
+     PVOID Socket;
  
-     TI_DbgPrint(DEBUG_TCP,("TCPClose started\n"));
+     /* We don't rely on SocketContext == NULL for socket
+      * closure anymore but we still need it to determine
+      * if we caused the closure
+      */
+     LockObject(Connection, &OldIrql);
+     Socket = Connection->SocketContext;
+     Connection->SocketContext = NULL;
  
-     ASSERT_LOCKED(&TCPLock);
+     /* We need to close here otherwise oskit will never indicate
+      * SEL_FIN and we will never fully close the connection
+      */
+     Status = TCPTranslateError( OskitTCPClose( Socket ) );
  
-     /* Make our code remove all pending IRPs */
-     Connection->State |= SEL_FIN;
-     DrainSignals();
+     if (!NT_SUCCESS(Status))
+     {
+         Connection->SocketContext = Socket;
+         UnlockObject(Connection, OldIrql);
+         return Status;
+     }
  
-     Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) );
-     if (Status == STATUS_SUCCESS)
-         Connection->SocketContext = NULL;
+     if (Connection->AddressFile)
+         DereferenceObject(Connection->AddressFile);
  
-     TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status));
+     UnlockObject(Connection, OldIrql);
+     DereferenceObject(Connection);
  
      return Status;
  }
@@@ -733,25 -769,17 +769,17 @@@ NTSTATUS TCPReceiveDat
      UINT DataLen, Received = 0;
      NTSTATUS Status;
      PTDI_BUCKET Bucket;
+     KIRQL OldIrql;
  
      TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
                             ReceiveLength, Connection->SocketContext));
  
-     ASSERT_LOCKED(&TCPLock);
-     ASSERT_KM_POINTER(Connection->SocketContext);
-     /* Closing */
-     if (Connection->State & SEL_FIN)
-     {
-         *BytesReceived = 0;
-         return STATUS_REMOTE_DISCONNECT;
-     }
      NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
  
      TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen));
  
+     LockObject(Connection, &OldIrql);
      Status = TCPTranslateError
          ( OskitTCPRecv
            ( Connection->SocketContext,
      /* Keep this request around ... there was no data yet */
      if( Status == STATUS_PENDING ) {
          /* Freed in TCPSocketState */
-         Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
+         Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG );
          if( !Bucket ) {
              TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n"));
+             UnlockObject(Connection, OldIrql);
              return STATUS_NO_MEMORY;
          }
  
          Bucket->Request.RequestContext = Context;
          *BytesReceived = 0;
  
-         IoMarkIrpPending((PIRP)Context);
-         ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock );
+         InsertTailList( &Connection->ReceiveRequest, &Bucket->Entry );
          TI_DbgPrint(DEBUG_TCP,("Queued read irp\n"));
      } else {
          TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received));
          *BytesReceived = Received;
      }
  
+     UnlockObject(Connection, OldIrql);
      TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
  
      return Status;
@@@ -800,25 -829,17 +829,17 @@@ NTSTATUS TCPSendDat
      UINT Sent = 0;
      NTSTATUS Status;
      PTDI_BUCKET Bucket;
+     KIRQL OldIrql;
  
-     ASSERT_LOCKED(&TCPLock);
+     LockObject(Connection, &OldIrql);
  
      TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
                             SendLength, Connection->SocketContext));
  
-     ASSERT_KM_POINTER(Connection->SocketContext);
      TI_DbgPrint(DEBUG_TCP,("Connection = %x\n", Connection));
      TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n",
                             Connection->SocketContext));
  
-     /* Closing */
-     if (Connection->State & SEL_FIN)
-     {
-         *BytesSent = 0;
-         return STATUS_REMOTE_DISCONNECT;
-     }
      Status = TCPTranslateError
          ( OskitTCPSend( Connection->SocketContext,
                          (OSK_PCHAR)BufferData, SendLength,
      /* Keep this request around ... there was no data yet */
      if( Status == STATUS_PENDING ) {
          /* Freed in TCPSocketState */
-         Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
+         Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG );
          if( !Bucket ) {
+             UnlockObject(Connection, OldIrql);
              TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n"));
              return STATUS_NO_MEMORY;
          }
          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;
  }
  
- VOID TCPTimeout(VOID) {
-     /* Now handled by TimerThread */
- }
  UINT TCPAllocatePort( UINT HintPort ) {
      if( HintPort ) {
          if( AllocatePort( &TCPPorts, HintPort ) ) return HintPort;
@@@ -880,12 -898,16 +898,16 @@@ NTSTATUS TCPGetSockAddres
      OSK_UI16 LocalPort, RemotePort;
      PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address;
      NTSTATUS Status;
+     KIRQL OldIrql;
  
-     ASSERT_LOCKED(&TCPLock);
+     LockObject(Connection, &OldIrql);
  
      Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext,
                                                    &LocalAddress, &LocalPort,
                                                    &RemoteAddress, &RemotePort));
+     UnlockObject(Connection, OldIrql);
      if (!NT_SUCCESS(Status))
          return Status;
  
      return Status;
  }
  
VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) {
BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) {
      PLIST_ENTRY Entry;
      PLIST_ENTRY ListHead[4];
      KIRQL OldIrql;
      PTDI_BUCKET Bucket;
      UINT i = 0;
+     BOOLEAN Found = FALSE;
  
      ListHead[0] = &Endpoint->SendRequest;
      ListHead[1] = &Endpoint->ReceiveRequest;
      ListHead[2] = &Endpoint->ConnectRequest;
      ListHead[3] = &Endpoint->ListenRequest;
  
-     TcpipAcquireSpinLock( &Endpoint->Lock, &OldIrql );
+     LockObject(Endpoint, &OldIrql);
  
      for( i = 0; i < 4; i++ )
      {
              if( Bucket->Request.RequestContext == Irp )
              {
                  RemoveEntryList( &Bucket->Entry );
-                 exFreePool( Bucket );
+                 ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG );
+                 Found = TRUE;
                  break;
              }
          }
      }
  
-     TcpipReleaseSpinLock( &Endpoint->Lock, OldIrql );
+     UnlockObject(Endpoint, OldIrql);
+     return Found;
  }
  
  /* EOF */
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 -->
@@@ -103,8 -103,7 +103,7 @@@ extern PULONG KiInterruptTemplateObject
  extern PULONG KiInterruptTemplateDispatch;
  extern PULONG KiInterruptTemplate2ndDispatch;
  extern ULONG KiUnexpectedEntrySize;
- extern UCHAR P0BootStack[];
- extern UCHAR KiDoubleFaultStack[];
+ extern ULONG_PTR KiDoubleFaultStack;
  extern EX_PUSH_LOCK KernelAddressSpaceLock;
  extern ULONG KiMaximumDpcQueueDepth;
  extern ULONG KiMinimumDpcRate;
@@@ -138,6 -137,7 +137,7 @@@ extern ULONG KeTimeAdjustment
  extern ULONG_PTR KiBugCheckData[5];
  extern ULONG KiFreezeFlag;
  extern ULONG KiDPCTimeout;
+ extern PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch;
  
  /* MACROS *************************************************************************/
  
@@@ -728,12 -728,6 +728,6 @@@ KiTimerExpiration
      IN PVOID SystemArgument2
  );
  
- ULONG
- NTAPI
- KiComputeTimerTableIndex(
-     IN LONGLONG TimeValue
- );
  ULONG
  NTAPI
  KeSetProcess(
@@@ -817,7 -811,7 +811,7 @@@ KiInitializeBugCheck(VOID)
  
  VOID
  NTAPI
- KiSystemStartupReal(
+ KiSystemStartup(
      IN PLOADER_PARAMETER_BLOCK LoaderBlock
  );
  
@@@ -905,7 -899,7 +899,7 @@@ KeInvalidAccessAllowed(IN PVOID TrapInf
  VOID
  NTAPI
  KeRosDumpStackFrames(
 -    PULONG Frame,
 +    PULONG_PTR Frame,
      ULONG FrameCount
  );
  
@@@ -938,6 -932,37 +932,37 @@@ KiEndUnexpectedRange
      VOID
  );
  
+ NTSTATUS
+ NTAPI
+ KiRaiseException(
+     IN PEXCEPTION_RECORD ExceptionRecord,
+     IN PCONTEXT Context,
+     IN PKEXCEPTION_FRAME ExceptionFrame,
+     IN PKTRAP_FRAME TrapFrame,
+     IN BOOLEAN SearchFrames
+ );
+ NTSTATUS
+ NTAPI
+ KiContinue(
+     IN PCONTEXT Context,
+     IN PKEXCEPTION_FRAME ExceptionFrame,
+     IN PKTRAP_FRAME TrapFrame
+ );
+ VOID
+ FASTCALL
+ KiServiceExit(
+     IN PKTRAP_FRAME TrapFrame,
+     IN NTSTATUS Status
+ );
+ VOID
+ FASTCALL
+ KiServiceExit2(
+     IN PKTRAP_FRAME TrapFrame
+ );
  #ifndef HAL_INTERRUPT_SUPPORT_IN_C
  VOID
  NTAPI
@@@ -1093,22 -1118,11 +1118,23 @@@ KiSystemService
  );
  
  VOID
+ FASTCALL
  KiIdleLoop(
      VOID
  );
  
 +PVOID
 +NTAPI
 +KiPcToFileHeader(IN PVOID Eip,
 +                 OUT PLDR_DATA_TABLE_ENTRY *LdrEntry,
 +                 IN BOOLEAN DriversOnly,
 +                 OUT PBOOLEAN InKernel);
 +
 +PVOID
 +NTAPI
 +KiRosPcToUserFileHeader(IN PVOID Eip,
 +                        OUT PLDR_DATA_TABLE_ENTRY *LdrEntry);
 +
  #include "ke_x.h"
  
  #endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */
@@@ -102,6 -102,27 +102,6 @@@ KeGetPreviousMode(VOID
  }
  
  #ifndef CONFIG_SMP
 -//
 -// Spinlock Acquire at IRQL >= DISPATCH_LEVEL
 -//
 -FORCEINLINE
 -VOID
 -KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
 -{
 -    /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
 -    UNREFERENCED_PARAMETER(SpinLock);
 -}
 -
 -//
 -// Spinlock Release at IRQL >= DISPATCH_LEVEL
 -//
 -FORCEINLINE
 -VOID
 -KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
 -{
 -    /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
 -    UNREFERENCED_PARAMETER(SpinLock);
 -}
  
  //
  // This routine protects against multiple CPU acquires, it's meaningless on UP.
@@@ -282,6 -303,72 +282,6 @@@ KiReleaseTimerLock(IN PKSPIN_LOCK_QUEU
  
  #else
  
 -//
 -// Spinlock Acquisition at IRQL >= DISPATCH_LEVEL
 -//
 -FORCEINLINE
 -VOID
 -KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
 -{
 -    /* Make sure that we don't own the lock already */
 -    if (((KSPIN_LOCK)KeGetCurrentThread() | 1) == *SpinLock)
 -    {
 -        /* We do, bugcheck! */
 -        KeBugCheckEx(SPIN_LOCK_ALREADY_OWNED, (ULONG_PTR)SpinLock, 0, 0, 0);
 -    }
 -
 -    /* Start acquire loop */
 -    for (;;)
 -    {
 -        /* Try to acquire it */
 -        if (InterlockedBitTestAndSet((PLONG)SpinLock, 0))
 -        {
 -            /* Value changed... wait until it's unlocked */
 -            while (*(volatile KSPIN_LOCK *)SpinLock == 1)
 -            {
 -#if DBG
 -                /* On debug builds, we use a much slower but useful routine */
 -                //Kii386SpinOnSpinLock(SpinLock, 5);
 -
 -                /* FIXME: Do normal yield for now */
 -                YieldProcessor();
 -#else
 -                /* Otherwise, just yield and keep looping */
 -                YieldProcessor();
 -#endif
 -            }
 -        }
 -        else
 -        {
 -#if DBG
 -            /* On debug builds, we OR in the KTHREAD */
 -            *SpinLock = (KSPIN_LOCK)KeGetCurrentThread() | 1;
 -#endif
 -            /* All is well, break out */
 -            break;
 -        }
 -    }
 -}
 -
 -//
 -// Spinlock Release at IRQL >= DISPATCH_LEVEL
 -//
 -FORCEINLINE
 -VOID
 -KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
 -{
 -#if DBG
 -    /* Make sure that the threads match */
 -    if (((KSPIN_LOCK)KeGetCurrentThread() | 1) != *SpinLock)
 -    {
 -        /* They don't, bugcheck */
 -        KeBugCheckEx(SPIN_LOCK_NOT_OWNED, (ULONG_PTR)SpinLock, 0, 0, 0);
 -    }
 -#endif
 -    /* Clear the lock */
 -    InterlockedAnd((PLONG)SpinLock, 0);
 -}
 -
  FORCEINLINE
  VOID
  KiAcquireDispatcherObject(IN DISPATCHER_HEADER* Object)
@@@ -885,6 -972,13 +885,13 @@@ KiCheckAlertability(IN PKTHREAD Thread
      return STATUS_WAIT_0;
  }
  
+ ULONG
+ FORCEINLINE
+ KiComputeTimerTableIndex(IN ULONGLONG DueTime)
+ {
+     return (DueTime / KeMaximumIncrement) & (TIMER_TABLE_SIZE - 1);
+ }
  //
  // Called from KiCompleteTimer, KiInsertTreeTimer, KeSetSystemTime
  // to remove timer entries
  #if defined(_PPC_)
  #include <ppcmmu/mmu.h>
  #define KERNEL_RVA(x) RVA(x,0x80800000)
 -#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)x + KernelBase) >> PAGE_SHIFT)
 +#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)(x) + KernelBase) >> PAGE_SHIFT)
  #else
  #define KERNEL_RVA(x) RVA(x,KSEG0_BASE)
 -#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)x &~ KSEG0_BASE) >> PAGE_SHIFT)
 +#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)(x) & ~KSEG0_BASE) >> PAGE_SHIFT)
  #endif
  
  typedef struct _BIOS_MEMORY_DESCRIPTOR
@@@ -29,9 -29,6 +29,9 @@@
  
  /* GLOBALS *******************************************************************/
  
 +/* Function pointer for early debug prints */
 +ULONG (*FrLdrDbgPrint)(const char *Format, ...);
 +
  /* FreeLDR Loader Data */
  PROS_LOADER_PARAMETER_BLOCK KeRosLoaderBlock;
  ADDRESS_RANGE KeMemoryMap[64];
@@@ -903,7 -900,7 +903,7 @@@ KiRosBuildArcMemoryList(VOID
  VOID
  NTAPI
  KiRosFixupComponentTree(IN PCONFIGURATION_COMPONENT_DATA p,
 -                        IN ULONG i)
 +                        IN ULONG_PTR i)
  {
      PCONFIGURATION_COMPONENT pp;
  
@@@ -977,7 -974,7 +977,7 @@@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PAR
      /* Build entries for ReactOS memory ranges, which uses ARC Descriptors */
      KiRosBuildOsMemoryMap();
  
 -#if defined(_X86_)
 +#if defined(_X86_) || defined(_M_AMD64)
      /* Build entries for the reserved map, which uses ARC Descriptors */
      KiRosBuildReservedMemoryMap();
  #endif
      /* Now mark the remainder of the FreeLDR 6MB area as "in use" */
      KiRosAllocateNtDescriptor(LoaderMemoryData,
                                KERNEL_DESCRIPTOR_PAGE(RosEntry->ModEnd),
 -                              KERNEL_DESCRIPTOR_PAGE((0x80800000 + 0x600000)) -
 +                              KERNEL_DESCRIPTOR_PAGE((RosLoaderBlock->KernelBase + 0x600000)) -
                                KERNEL_DESCRIPTOR_PAGE(RosEntry->ModEnd),
                                0,
                                &Base);
      LoaderBlock->Extension->MajorVersion = 5;
      LoaderBlock->Extension->MinorVersion = 2;
  
 +
 +// FIXME FIXME FIXME NOW!!!!
 +
      /* FreeLDR hackllocates 1536 static pages for the initial boot images */
      LoaderBlock->Extension->LoaderPagesSpanned = 1536 * PAGE_SIZE;
  
@@@ -1325,9 -1319,8 +1325,8 @@@ NTAP
  KiSetupSyscallHandler();
  
  VOID
- FASTCALL
- KiRosPrepareForSystemStartup(IN ULONG Dummy,
-                              IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
+ NTAPI
+ KiRosPrepareForSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
  {
      PLOADER_PARAMETER_BLOCK NtLoaderBlock;
      ULONG size, i = 0, *ent;
      /* Save pointer to ROS Block */
      KeRosLoaderBlock = LoaderBlock;
  
 +    /* Get debugging function */
 +    FrLdrDbgPrint = LoaderBlock->FrLdrDbgPrint;
 +
      /* Save memory manager data */
      KeMemoryMapRangeCount = 0;
      if (LoaderBlock->Flags & MB_FLAGS_MMAP_INFO)
      {
          /* We have a memory map from the nice BIOS */
 -        ent = ((PULONG)(LoaderBlock->MmapAddr - sizeof(ULONG)));
 +        ent = ((PULONG)(LoaderBlock->MmapAddr - sizeof(ULONG))); // FIXME: this is ugly
          size = *ent;
          i = 0;
  
  
          /* Save data */
          LoaderBlock->MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
 -        LoaderBlock->MmapAddr = (ULONG)KeMemoryMap;
 +        LoaderBlock->MmapAddr = (ULONG_PTR)KeMemoryMap;
      }
      else
      {
          /* Nothing from BIOS */
          LoaderBlock->MmapLength = 0;
 -        LoaderBlock->MmapAddr = (ULONG)KeMemoryMap;
 +        LoaderBlock->MmapAddr = (ULONG_PTR)KeMemoryMap;
      }
  
      /* Convert the loader block */
  #endif
  
      /* Do general System Startup */
-     KiSystemStartupReal(NtLoaderBlock);
+     KiSystemStartup(NtLoaderBlock);
  }
@@@ -191,30 -191,30 +191,30 @@@ KiGetCpuVendor(VOID
      Prcb->VendorString[sizeof(Prcb->VendorString) - sizeof(CHAR)] = ANSI_NULL;
  
      /* Now check the CPU Type */
 -    if (!strcmp(Prcb->VendorString, CmpIntelID))
 +    if (!strcmp((PCHAR)Prcb->VendorString, CmpIntelID))
      {
          return CPU_INTEL;
      }
 -    else if (!strcmp(Prcb->VendorString, CmpAmdID))
 +    else if (!strcmp((PCHAR)Prcb->VendorString, CmpAmdID))
      {
          return CPU_AMD;
      }
 -    else if (!strcmp(Prcb->VendorString, CmpCyrixID))
 +    else if (!strcmp((PCHAR)Prcb->VendorString, CmpCyrixID))
      {
          DPRINT1("Cyrix CPU support not fully tested!\n");
          return CPU_CYRIX;
      }
 -    else if (!strcmp(Prcb->VendorString, CmpTransmetaID))
 +    else if (!strcmp((PCHAR)Prcb->VendorString, CmpTransmetaID))
      {
          DPRINT1("Transmeta CPU support not fully tested!\n");
          return CPU_TRANSMETA;
      }
 -    else if (!strcmp(Prcb->VendorString, CmpCentaurID))
 +    else if (!strcmp((PCHAR)Prcb->VendorString, CmpCentaurID))
      {
          DPRINT1("Centaur CPU support not fully tested!\n");
          return CPU_CENTAUR;
      }
 -    else if (!strcmp(Prcb->VendorString, CmpRiseID))
 +    else if (!strcmp((PCHAR)Prcb->VendorString, CmpRiseID))
      {
          DPRINT1("Rise CPU support not fully tested!\n");
          return CPU_RISE;
@@@ -649,8 -649,8 +649,8 @@@ Ki386InitializeTss(IN PKTSS Tss
      Tss = (PKTSS)KiDoubleFaultTSS;
      KiInitializeTSS(Tss);
      Tss->CR3 = __readcr3();
-     Tss->Esp0 = PtrToUlong(KiDoubleFaultStack);
-     Tss->Esp = PtrToUlong(KiDoubleFaultStack);
+     Tss->Esp0 = KiDoubleFaultStack;
+     Tss->Esp = KiDoubleFaultStack;
      Tss->Eip = PtrToUlong(KiTrap08);
      Tss->Cs = KGDT_R0_CODE;
      Tss->Fs = KGDT_R0_PCR;
      Tss = (PKTSS)KiNMITSS;
      KiInitializeTSS(Tss);
      Tss->CR3 = __readcr3();
-     Tss->Esp0 = PtrToUlong(KiDoubleFaultStack);
-     Tss->Esp = PtrToUlong(KiDoubleFaultStack);
+     Tss->Esp0 = KiDoubleFaultStack;
+     Tss->Esp = KiDoubleFaultStack;
      Tss->Eip = PtrToUlong(KiTrap02);
      Tss->Cs = KGDT_R0_CODE;
      Tss->Fs = KGDT_R0_PCR;
@@@ -944,6 -944,155 +944,155 @@@ KiSaveProcessorState(IN PKTRAP_FRAME Tr
      KiSaveProcessorControlState(&Prcb->ProcessorState);
  }
  
+ BOOLEAN
+ NTAPI
+ KiIsNpxPresent(VOID)
+ {
+     ULONG Cr0;
+     USHORT Magic;
+     
+     /* Set magic */
+     Magic = 0xFFFF;
+     
+     /* Read CR0 and mask out FPU flags */
+     Cr0 = __readcr0() & ~(CR0_MP | CR0_TS | CR0_EM | CR0_ET);
+     
+     /* Store on FPU stack */
+     asm volatile ("fninit;" "fnstsw %0" : "+m"(Magic));
+     
+     /* Magic should now be cleared */
+     if (Magic & 0xFF)
+     {
+         /* You don't have an FPU -- enable emulation for now */
+         __writecr0(Cr0 | CR0_EM | CR0_TS);
+         return FALSE;
+     }
+     
+     /* You have an FPU, enable it */
+     Cr0 |= CR0_ET;
+     
+     /* Enable INT 16 on 486 and higher */
+     if (KeGetCurrentPrcb()->CpuType >= 3) Cr0 |= CR0_NE;
+     
+     /* Set FPU state */
+     __writecr0(Cr0 | CR0_EM | CR0_TS);
+     return TRUE;
+ }
+ BOOLEAN
+ NTAPI
+ KiIsNpxErrataPresent(VOID)
+ {
+     BOOLEAN ErrataPresent;
+     ULONG Cr0;
+     volatile double Value1, Value2;
+     
+     /* Disable interrupts */
+     _disable();
+     
+     /* Read CR0 and remove FPU flags */
+     Cr0 = __readcr0();
+     __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
+     
+     /* Initialize FPU state */
+     asm volatile ("fninit");
+     
+     /* Multiply the magic values and divide, we should get the result back */
+     Value1 = 4195835.0;
+     Value2 = 3145727.0;
+     ErrataPresent = (Value1 * Value2 / 3145727.0) != 4195835.0;
+     
+     /* Restore CR0 */
+     __writecr0(Cr0);
+     
+     /* Enable interrupts */
+     _enable();
+     
+     /* Return if there's an errata */
+     return ErrataPresent;
+ }
+ NTAPI
+ VOID
+ KiFlushNPXState(IN PFLOATING_SAVE_AREA SaveArea)
+ {
+     ULONG EFlags, Cr0;
+     PKTHREAD Thread, NpxThread;
+     PFX_SAVE_AREA FxSaveArea;
+     
+     /* Save volatiles and disable interrupts */
+     EFlags = __readeflags();
+     _disable();
+     
+     /* Save the PCR and get the current thread */
+     Thread = KeGetCurrentThread();
+     
+     /* Check if we're already loaded */
+     if (Thread->NpxState != NPX_STATE_LOADED)
+     {
+         /* If there's nothing to load, quit */
+         if (!SaveArea) return;
+         
+         /* Need FXSR support for this */
+         ASSERT(KeI386FxsrPresent == TRUE);
+         
+         /* Check for sane CR0 */
+         Cr0 = __readcr0();
+         if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
+         {
+             /* Mask out FPU flags */
+             __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
+         }
+         
+         /* Get the NPX thread and check its FPU state */
+         NpxThread = KeGetCurrentPrcb()->NpxThread;
+         if ((NpxThread) && (NpxThread->NpxState == NPX_STATE_LOADED))
+         {
+             /* Get the FX frame and store the state there */
+             FxSaveArea = KiGetThreadNpxArea(NpxThread);
+             Ke386FxSave(FxSaveArea);
+             
+             /* NPX thread has lost its state */
+             NpxThread->NpxState = NPX_STATE_NOT_LOADED;
+         }
+         
+         /* Now load NPX state from the NPX area */
+         FxSaveArea = KiGetThreadNpxArea(Thread);
+         Ke386FxStore(FxSaveArea);    
+     }
+     else
+     {
+         /* Check for sane CR0 */
+         Cr0 = __readcr0();
+         if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
+         {
+             /* Mask out FPU flags */
+             __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
+         }
+         
+         /* Get FX frame */
+         FxSaveArea = KiGetThreadNpxArea(Thread);
+         Thread->NpxState = NPX_STATE_NOT_LOADED;
+         
+         /* Save state if supported by CPU */
+         if (KeI386FxsrPresent) Ke386FxSave(FxSaveArea);
+     }
+     /* Now save the FN state wherever it was requested */
+     if (SaveArea) Ke386FnSave(SaveArea);
+     /* Clear NPX thread */
+     KeGetCurrentPrcb()->NpxThread = NULL;
+     
+     /* Add the CR0 from the NPX frame */
+     Cr0 |= NPX_STATE_NOT_LOADED;
+     Cr0 |= FxSaveArea->Cr0NpxState;
+     __writecr0(Cr0);
+     
+     /* Restore interrupt state */
+     __writeeflags(EFlags);
+ }
  /* PUBLIC FUNCTIONS **********************************************************/
  
  /*
  #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.
   *     EDI - Pointer to the KTHREAD to which the caller wishes to
   *           switch from.
   *
 - * Returns:
 - *     None.
 + * \returns
 + *     APC state.
   *
 - * Remarks:
 + * \remarks
   *     Absolutely all registers except ESP can be trampled here for maximum code flexibility.
   *
   *--*/
@@@ -623,25 -320,19 +323,25 @@@ WrongCpu
  #endif
  .endfunc
  
 -/*++
 - * KiSwapContext 
 +/**
 + * KiSwapContext
   *
 + * \brief
   *     The KiSwapContext routine switches context to another thread.
   *
 - * Params:
 - *     TargetThread - Pointer to the KTHREAD to which the caller wishes to
 - *                    switch to.
 + * BOOLEAN FASTCALL
 + * KiSwapContext(PKTHREAD CurrentThread, PKTHREAD TargetThread);
 + *
 + * \param CurrentThread
 + *     Pointer to the KTHREAD of the current thread.
 + *                    
 + * \param TargetThread
 + *     Pointer to the KTHREAD to which the caller wishes to switch to.
   *
 - * Returns:
 + * \returns
   *     The WaitStatus of the Target Thread.
   *
 - * Remarks:
 + * \remarks
   *     This is a wrapper around KiSwapContextInternal which will save all the
   *     non-volatile registers so that the Internal function can use all of
   *     them. It will also save the old current thread and set the new one.
@@@ -816,64 -507,6 +516,6 @@@ NoNextThread
  #endif
  .endfunc
  
- .globl _KiSwapProcess@8
- .func KiSwapProcess@8
- _KiSwapProcess@8:
-     /* Get process pointers */
-     mov edx, [esp+4]
-     mov eax, [esp+8]
- #ifdef CONFIG_SMP
-     /* Update active processors */
-     mov ecx, fs:[KPCR_SET_MEMBER]
-     lock xor [edx+KPROCESS_ACTIVE_PROCESSORS], ecx
-     lock xor [eax+KPROCESS_ACTIVE_PROCESSORS], ecx
-     /* Sanity check */
- #if DBG
-     test [edx+KPROCESS_ACTIVE_PROCESSORS], ecx
-     jz WrongCpu1
-     test [eax+KPROCESS_ACTIVE_PROCESSORS], ecx
-     jnz WrongCpu2
- #endif
- #endif
-     /* Check if their LDTs changed */
-     mov ecx, [edx+KPROCESS_LDT_DESCRIPTOR0]
-     or ecx, [eax+KPROCESS_LDT_DESCRIPTOR0]
-     jnz NewLdt
-     /* Update CR3 */
-     mov eax, [edx+KPROCESS_DIRECTORY_TABLE_BASE]
-     mov cr3, eax
-     /* Get the KTSS */
-     mov ecx, fs:[KPCR_TSS]
-     /* Clear GS on process swap */
-     xor eax, eax
-     mov gs, ax
-     /* Update IOPM offset */
-     mov ax, [edx+KPROCESS_IOPM_OFFSET]
-     mov [ecx+KTSS_IOMAPBASE], ax
-     /* Return */
-     ret 8
- NewLdt:
-     /* FIXME: TODO */
-     int 3
- #if DBG
- WrongCpu1:
-     int 3
- WrongCpu2:
-     int 3
- #endif
- .endfunc
  .globl _Ki386SetupAndExitToV86Mode@4
  .func Ki386SetupAndExitToV86Mode@4
  _Ki386SetupAndExitToV86Mode@4:
@@@ -246,6 -246,7 +246,6 @@@ VOI
  NTAPI
  MiFreeContiguousMemory(IN PVOID BaseAddress)
  {
 -    KIRQL OldIrql;
      PFN_NUMBER PageFrameIndex, LastPage, PageCount;
      PMMPFN Pfn1, StartPfn;
      PAGED_CODE();
      // Now get the PFN entry for this, and make sure it's the correct one
      //
      Pfn1 = MiGetPfnEntry(PageFrameIndex);        
-     if (Pfn1->u3.e1.StartOfAllocation == 0)
+     if ((!Pfn1) || (Pfn1->u3.e1.StartOfAllocation == 0))
      {
          //
          // This probably means you did a free on an address that was in between
      //
      MmUnmapIoSpace(BaseAddress, PageCount << PAGE_SHIFT);
      
 -    //
 -    // Lock the PFN database
 -    //
 -    OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
 -    
      //
      // Loop all the pages
      //
          //
          MmReleasePageMemoryConsumer(MC_NPPOOL, PageFrameIndex);
      } while (++PageFrameIndex < LastPage);
 -    
 -    //
 -    // Release the PFN lock
 -    //
 -    KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
  }
  
  /* PUBLIC FUNCTIONS ***********************************************************/
@@@ -432,7 -443,7 +432,7 @@@ MmFreeContiguousMemory(IN PVOID BaseAdd
  VOID
  NTAPI
  MmFreeContiguousMemorySpecifyCache(IN PVOID BaseAddress,
 -                                   IN ULONG NumberOfBytes,
 +                                   IN SIZE_T NumberOfBytes,
                                     IN MEMORY_CACHING_TYPE CacheType)
  {
      //
        <library>bootvid</library>
        <library>wdmguid</library>
        <dependency>bugcodes</dependency>
 -      <!-- See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38269
        <directory name="include">
                <pch>precomp.h</pch>
        </directory>
 -      -->
        <directory name="ke">
                <if property="ARCH" value="i386">
                        <directory name="i386">
-                               <file first="true">boot.S</file>
                                <file>abios.c</file>
                                <file>cpu.c</file>
+                               <file>context.c</file>
                                <file>ctxswitch.S</file>
                                <file>exp.c</file>
                                <file>irqobj.c</file>
@@@ -46,7 -48,6 +46,6 @@@
                                <file>ldt.c</file>
                                <file>mtrr.c</file>
                                <file>patpge.c</file>
-                               <file>systimer.S</file>
                                <file>thrdini.c</file>
                                <file>trap.s</file>
                                <file>traphdlr.c</file>
@@@ -64,7 -65,6 +63,6 @@@
                                <file>kiinit.c</file>
                                <file>stubs_asm.s</file>
                                <file>thrdini.c</file>
-                               <file>time.c</file>
                                <file>trap.s</file>
                                <file>trapc.c</file>
                                <file>usercall.c</file>
                                <file>ctxhelp.S</file>
                        </directory>
                </if>
 +              <if property="ARCH" value="amd64">
 +                      <directory name="amd64">
 +                              <file first="true">boot.S</file>
 +                              <file>context.c</file>
 +                              <file>cpu.c</file>
 +                              <file>ctxswitch.S</file>
 +                              <file>except.c</file>
 +                              <file>interrupt.c</file>
 +                              <file>irql.c</file>
 +                              <file>kiinit.c</file>
 +                              <file>spinlock.c</file>
 +                              <file>stubs.c</file>
 +                              <file>thrdini.c</file>
 +                              <file>trap.S</file>
 +                      </directory>
 +              </if>
                <file>apc.c</file>
                <file>balmgr.c</file>
                <file>bug.c</file>
                <file>dpc.c</file>
                <file>eventobj.c</file>
                <file>except.c</file>
 -              <file>freeldr.c</file>
 +              <if property="ARCH" value="i386">
 +                      <file>freeldr.c</file>
 +              </if>
                <file>freeze.c</file>
                <file>gate.c</file>
                <file>gmutex.c</file>
                <file>queue.c</file>
                <file>semphobj.c</file>
                <file>spinlock.c</file>
+               <file>time.c</file>
                <file>thrdschd.c</file>
                <file>thrdobj.c</file>
                <file>timerobj.c</file>
                                <file>cmhardwr.c</file>
                        </directory>
                </if>
 +              <if property="ARCH" value="amd64">
 +                      <directory name="i386">
 +                              <file>cmhardwr.c</file>
 +                      </directory>
 +              </if>
                <if property="ARCH" value="arm">
                        <directory name="arm">
                                <file>cmhardwr.c</file>
                                <file>ioport.S</file>
                        </directory>
                </if>
 +              <if property="ARCH" value="amd64">
 +                      <directory name="amd64">
 +                              <file>fastinterlck.c</file>
 +                      </directory>
 +              </if>
                <file>atom.c</file>
                <file>callback.c</file>
                <file>dbgctrl.c</file>
                                        </if>
                                </directory>
                        </if>
 +                      <if property="ARCH" value="amd64">
 +                              <directory name="amd64">
 +                                      <if property="KDBG" value="1">
 +                                              <group>
 +                                                      <file>i386-dis.c</file>
 +                                                      <file>kdb_help.S</file>
 +                                                      <file>kdb.c</file>
 +                                                      <file>setjmp.S</file>
 +                                              </group>
 +                                      </if>
 +                              </directory>
 +                      </if>
                        <if property="KDBG" value="1">
                                <file>kdb.c</file>
                                <file>kdb_cli.c</file>
                                </if>
                                <file>kdbg.c</file>
                        </directory>
 +                      <if property="ARCH" value="amd64">
 +                              <directory name="amd64">
 +                                      <file>kd.c</file>
 +                                      <file>kdmemsup.c</file>
 +                              </directory>
 +                      </if>
                        <file>kdinit.c</file>
                        <file>kdio.c</file>
                        <file>kdmain.c</file>
                                <file>page.c</file>
                        </directory>
                </if>
 +              <if property="ARCH" value="amd64">
 +                      <directory name="amd64">
 +                              <file>init.c</file>
 +                              <file>page.c</file>
 +                      </directory>
 +              </if>
                <directory name="ARM3">
                        <if property="ARCH" value="i386">
                                <directory name="i386">
                                <file>psctx.c</file>
                        </directory>
                </if>
 +              <if property="ARCH" value="amd64">
 +                      <directory name="amd64">
 +                              <file>psctx.c</file>
 +                      </directory>
 +              </if>
                <file>debug.c</file>
                <file>job.c</file>
                <file>kill.c</file>
        </directory>
        <file>ntoskrnl.rc</file>
        <linkerscript>ntoskrnl_$(ARCH).lnk</linkerscript>
 -
 -      <!-- See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 -->
 -      <compilerflag compilerset="gcc">-fno-unit-at-a-time</compilerflag>
  </group>
@@@ -416,9 -416,9 +416,9 @@@ IntDispatchMessage(PMSG pMsg
    if (pMsg->message == WM_PAINT)
    {
    /* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
-      HRGN hrgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
+      HRGN hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
       co_UserGetUpdateRgn( Window, hrgn, TRUE );
-      GreDeleteObject( hrgn );
+      REGION_FreeRgnByHandle( hrgn );
    }
    return retval;
  }
@@@ -2283,7 -2283,7 +2283,7 @@@ NtUserDispatchMessage(PMSG UnsafeMsgInf
  
  BOOL APIENTRY
  NtUserTranslateMessage(LPMSG lpMsg,
 -                       HKL dwhkl)
 +                       UINT flags)
  {
     NTSTATUS Status;
     MSG SafeMsg;
        RETURN( FALSE);
     }
  
 -   RETURN( IntTranslateKbdMessage(&SafeMsg, dwhkl));
 +   RETURN( IntTranslateKbdMessage(&SafeMsg, flags));
  
  CLEANUP:
     DPRINT("Leave NtUserTranslateMessage: ret=%i\n",_ret_);
@@@ -30,7 -30,7 +30,7 @@@
  
  #include "gdidbg.c"
  
 -/* static */ /* FIXME: -fno-unit-at-a-time breaks this */
 +static
  BOOL INTERNAL_CALL GDI_CleanupDummy(PVOID ObjectBody);
  
  /** GLOBALS *******************************************************************/
@@@ -87,7 -87,7 +87,7 @@@ static LARGE_INTEGER ShortDelay
  /*
   * Dummy GDI Cleanup Callback
   */
 -/* static */ /* FIXME: -fno-unit-at-a-time breaks this */
 +static
  BOOL INTERNAL_CALL
  GDI_CleanupDummy(PVOID ObjectBody)
  {
@@@ -695,7 -695,7 +695,7 @@@ bPEBCacheHandle(HGDIOBJ Handle, int oTy
  
       hPtr = GdiHandleCache->Handle + Offset;
  
-      if ( oType == hctRegionHandle)
+      if ( pAttr && oType == hctRegionHandle)
       {
          if ( Number < CACHE_REGION_ENTRIES )
          {
@@@ -746,14 -746,18 +746,18 @@@ GreDeleteObject(HGDIOBJ hObject
               break;
  
            case GDI_OBJECT_TYPE_REGION:
-              if (bPEBCacheHandle(hObject, hctRegionHandle, pAttr))
+              /* If pAttr NULL, the probability is high for System Region. */
+              if ( pAttr &&
+                   bPEBCacheHandle(hObject, hctRegionHandle, pAttr))
               {
+                 /* User space handle only! */
                  return TRUE;
               }
               if (pAttr)
               {
                  KeEnterCriticalRegion();
                  FreeObjectAttr(pAttr);
+                 Entry->UserData = NULL;
                  KeLeaveCriticalRegion();
               }
               break;
@@@ -1559,6 -1563,36 +1563,36 @@@ GDI_MapHandleTable(PSECTION_OBJECT Sect
  
  /** PUBLIC FUNCTIONS **********************************************************/
  
+ BOOL
+ FASTCALL
+ IntGdiSetRegionOwner(HRGN hRgn, DWORD OwnerMask)
+ {
+   INT Index;
+   PGDI_TABLE_ENTRY Entry;
+ /*
+   System Regions:
+      These regions do not use attribute sections and when allocated, use gdiobj
+      level functions.
+  */
+   // FIXME! HAX!!! Remove this once we get everything right!
+   KeEnterCriticalRegion();
+   Index = GDI_HANDLE_GET_INDEX(hRgn);
+   Entry = &GdiHandleTable->Entries[Index];
+   if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+   Entry->UserData = NULL;
+   KeLeaveCriticalRegion();
+   //
+   if ((OwnerMask == GDI_OBJ_HMGR_PUBLIC) || OwnerMask == GDI_OBJ_HMGR_NONE)
+   {
+      return GDIOBJ_SetOwnership(hRgn, NULL);
+   }
+   if (OwnerMask == GDI_OBJ_HMGR_POWNED)
+   {
+      return GDIOBJ_SetOwnership((HGDIOBJ) hRgn, PsGetCurrentProcess() );
+   }
+   return FALSE;
+ }
  BOOL
  FASTCALL
  IntGdiSetBrushOwner(PBRUSH pbr, DWORD OwnerMask)
    return TRUE;
  }
  
  BOOL
  FASTCALL
  IntGdiSetDCOwnerEx( HDC hDC, DWORD OwnerMask, BOOL NoSetBrush)
@@@ -1672,7 -1705,6 +1705,6 @@@ GreGetObjectOwner(HGDIOBJ Handle, GDIOB
    return Ret;
  }
  
  W32KAPI
  HANDLE
  APIENTRY
@@@ -396,12 -396,6 +396,12 @@@ Module::Module ( const Project& project
        if ( att != NULL )
        {
                const XMLAttribute* installbase = moduleNode.GetAttribute ( "installbase", false );
 +
 +        if(installbase)
 +            this->installbase = installbase->value;
 +        else
 +            this->installbase = "";
 +
                install = new FileLocation ( InstallDirectory,
                                             installbase ? installbase->value : "",
                                             att->value,
@@@ -1119,7 -1113,8 +1119,8 @@@ Module::GetDefaultModuleEntrypoint () c
        switch ( type )
        {
                case Kernel:
-                       return "KiSystemStartup";
+                       if (Environment::GetArch() == "arm") return "KiSystemStartup";
+             return "KiSystemStartup@4";
                case KeyboardLayout:
                case KernelModeDLL:
                case KernelModeDriver: