implemented sweeping of handle tables
[reactos.git] / reactos / ntoskrnl / ex / handle.c
index 1c0d9d3..71ec925 100644 (file)
@@ -1,17 +1,16 @@
 /* $Id$
- * 
+ *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/handle.c
  * PURPOSE:         Generic Executive Handle Tables
- * 
+ *
  * PROGRAMMERS:     Thomas Weidenmueller <w3seek@reactos.com>
  *
  *  TODO:
  *
  *  - the last entry of a subhandle list should be reserved for auditing
  *
- *  ExSweepHandleTable (???)
  *  ExReferenceHandleDebugInfo
  *  ExSnapShotHandleTables
  *  ExpMoveFreeHandles (???)
@@ -77,6 +76,11 @@ static LARGE_INTEGER ExpHandleShortWait;
 #define IS_VALID_EX_HANDLE(index)                                              \
   (((index) & ~VALID_HANDLE_MASK) == 0)
 
+#define HANDLE_TO_EX_HANDLE(handle)                                            \
+  (LONG)(((LONG)(handle) >> 2) - 1)
+#define EX_HANDLE_TO_HANDLE(exhandle)                                          \
+  (HANDLE)(((exhandle) + 1) << 2)
+
 static BOOLEAN ExpInitialized = FALSE;
 
 /******************************************************************************/
@@ -95,14 +99,14 @@ PHANDLE_TABLE
 ExCreateHandleTable(IN PEPROCESS QuotaProcess  OPTIONAL)
 {
   PHANDLE_TABLE HandleTable;
-  
+
   PAGED_CODE();
-  
+
   if(!ExpInitialized)
   {
     KEBUGCHECK(0);
   }
-  
+
   if(QuotaProcess != NULL)
   {
     /* FIXME - Charge process quota before allocating the handle table! */
@@ -154,126 +158,95 @@ ExCreateHandleTable(IN PEPROCESS QuotaProcess  OPTIONAL)
   {
     /* FIXME - return the quota to the process */
   }
-  
+
   return HandleTable;
 }
 
-static BOOLEAN
-ExLockHandleTableEntryNoDestructionCheck(IN PHANDLE_TABLE HandleTable,
-                                         IN PHANDLE_TABLE_ENTRY Entry)
+VOID
+ExSweepHandleTable(IN PHANDLE_TABLE HandleTable,
+                   IN PEX_SWEEP_HANDLE_CALLBACK SweepHandleCallback  OPTIONAL,
+                   IN PVOID Context  OPTIONAL)
 {
-  ULONG_PTR Current, New;
+  PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp;
 
   PAGED_CODE();
 
-  DPRINT("Entering handle table entry 0x%x lock...\n", Entry);
-
   ASSERT(HandleTable);
-  ASSERT(Entry);
 
-  for(;;)
-  {
-    Current = (volatile ULONG_PTR)Entry->u1.Object;
-
-    if(!Current)
-    {
-      DPRINT("Attempted to lock empty handle table entry 0x%x or handle table shut down\n", Entry);
-      break;
-    }
-
-    if(!(Current & EX_HANDLE_ENTRY_LOCKED))
-    {
-      New = Current | EX_HANDLE_ENTRY_LOCKED;
-      if(InterlockedCompareExchangePointer(&Entry->u1.Object,
-                                           (PVOID)New,
-                                           (PVOID)Current) == (PVOID)Current)
-      {
-        DPRINT("SUCCESS handle table 0x%x entry 0x%x lock\n", HandleTable, Entry);
-        /* we acquired the lock */
-        return TRUE;
-      }
-    }
-
-    /* wait about 5ms at maximum so we don't wait forever in unfortunate
-       co-incidences where releasing the lock in another thread happens right
-       before we're waiting on the contention event to get pulsed, which might
-       never happen again... */
-    KeWaitForSingleObject(&HandleTable->HandleContentionEvent,
-                          Executive,
-                          KernelMode,
-                          FALSE,
-                          &ExpHandleShortWait);
-  }
-
-  return FALSE;
-}
-
-VOID
-ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
-                     IN PEX_DESTROY_HANDLE_CALLBACK DestroyHandleCallback  OPTIONAL,
-                     IN PVOID Context  OPTIONAL)
-{
-  PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp;
-  PEPROCESS QuotaProcess;
-  
-  PAGED_CODE();
-  
-  ASSERT(HandleTable);
-  
   KeEnterCriticalRegion();
-  
+
   /* ensure there's no other operations going by acquiring an exclusive lock */
   ExAcquireHandleTableLockExclusive(HandleTable);
-  
+
   ASSERT(!(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING));
-  
+
   HandleTable->Flags |= EX_HANDLE_TABLE_CLOSING;
-  
+
   KePulseEvent(&HandleTable->HandleContentionEvent,
                EVENT_INCREMENT,
                FALSE);
-  
-  /* remove the handle table from the global handle table list */
-  ExAcquireHandleTableListLock();
-  RemoveEntryList(&HandleTable->HandleTableList);
-  ExReleaseHandleTableListLock();
-  
+
   /* call the callback function to cleanup the objects associated with the
      handle table */
-  if(DestroyHandleCallback != NULL)
+  for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS;
+      tlp != lasttlp;
+      tlp++)
   {
-    for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS;
-        tlp != lasttlp;
-        tlp++)
+    if((*tlp) != NULL)
     {
-      if((*tlp) != NULL)
+      for(mlp = *tlp, lastmlp = (*tlp) + N_MIDDLELEVEL_POINTERS;
+          mlp != lastmlp;
+          mlp++)
       {
-        for(mlp = *tlp, lastmlp = (*tlp) + N_MIDDLELEVEL_POINTERS;
-            mlp != lastmlp;
-            mlp++)
+        if((*mlp) != NULL)
         {
-          if((*mlp) != NULL)
+          PHANDLE_TABLE_ENTRY curee, laste;
+
+          for(curee = *mlp, laste = *mlp + N_SUBHANDLE_ENTRIES;
+              curee != laste;
+              curee++)
           {
-            PHANDLE_TABLE_ENTRY curee, laste;
-            
-            for(curee = *mlp, laste = *mlp + N_SUBHANDLE_ENTRIES;
-                curee != laste;
-                curee++)
+            if(curee->u1.Object != NULL && SweepHandleCallback != NULL)
             {
-              if(curee->u1.Object != NULL && ExLockHandleTableEntryNoDestructionCheck(HandleTable, curee))
-              {
-                DestroyHandleCallback(HandleTable, curee->u1.Object, curee->u2.GrantedAccess, Context);
-                ExUnlockHandleTableEntry(HandleTable, curee);
-              }
+              curee->u1.ObAttributes |= EX_HANDLE_ENTRY_LOCKED;
+              SweepHandleCallback(HandleTable, curee->u1.Object, curee->u2.GrantedAccess, Context);
             }
           }
         }
       }
     }
   }
-  
+
+  ExReleaseHandleTableLock(HandleTable);
+
+  KeLeaveCriticalRegion();
+}
+
+VOID
+ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable)
+{
+  PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp;
+  PEPROCESS QuotaProcess;
+
+  PAGED_CODE();
+
+  ASSERT(HandleTable);
+  ASSERT(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING);
+
+  KeEnterCriticalRegion();
+
+  /* at this point the table should not be queried or altered anymore,
+     no locks should be necessary */
+
+  ASSERT(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING);
+
+  /* remove the handle table from the global handle table list */
+  ExAcquireHandleTableListLock();
+  RemoveEntryList(&HandleTable->HandleTableList);
+  ExReleaseHandleTableListLock();
+
   QuotaProcess = HandleTable->QuotaProcess;
-  
+
   /* free the tables */
   for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS;
       tlp != lasttlp;
@@ -288,7 +261,7 @@ ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
         if((*mlp) != NULL)
         {
           ExFreePool(*mlp);
-          
+
           if(QuotaProcess != NULL)
           {
             /* FIXME - return the quota to the process */
@@ -297,22 +270,20 @@ ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
       }
 
       ExFreePool(*tlp);
-      
+
       if(QuotaProcess != NULL)
       {
         /* FIXME - return the quota to the process */
       }
     }
   }
-  
-  ExReleaseHandleTableLock(HandleTable);
-  
+
   KeLeaveCriticalRegion();
-  
+
   /* free the handle table */
   ExDeleteResource(&HandleTable->HandleTableLock);
   ExFreePool(HandleTable);
-  
+
   if(QuotaProcess != NULL)
   {
     /* FIXME - return the quota to the process */
@@ -326,9 +297,9 @@ ExDupHandleTable(IN PEPROCESS QuotaProcess  OPTIONAL,
                  IN PHANDLE_TABLE SourceHandleTable)
 {
   PHANDLE_TABLE HandleTable;
-  
+
   PAGED_CODE();
-  
+
   ASSERT(SourceHandleTable);
 
   HandleTable = ExCreateHandleTable(QuotaProcess);
@@ -336,12 +307,12 @@ ExDupHandleTable(IN PEPROCESS QuotaProcess  OPTIONAL,
   {
     PHANDLE_TABLE_ENTRY **tlp, **srctlp, **etlp, *mlp, *srcmlp, *emlp, stbl, srcstbl, estbl;
     LONG tli, mli, eli;
-    
+
     tli = mli = eli = 0;
-  
+
     /* make sure the other handle table isn't being changed during the duplication */
     ExAcquireHandleTableLockShared(SourceHandleTable);
-    
+
     /* allocate enough tables */
     etlp = SourceHandleTable->Table + N_TOPLEVEL_POINTERS;
     for(srctlp = SourceHandleTable->Table, tlp = HandleTable->Table;
@@ -355,16 +326,16 @@ ExDupHandleTable(IN PEPROCESS QuotaProcess  OPTIONAL,
         {
           /* FIXME - Charge process quota before allocating the handle table! */
         }
-        
+
         *tlp = ExAllocatePoolWithTag(PagedPool,
                                      N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY),
                                      TAG('E', 'x', 'H', 't'));
         if(*tlp != NULL)
         {
           RtlZeroMemory(*tlp, N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY));
-          
+
           KeMemoryBarrier();
-          
+
           emlp = *srctlp + N_MIDDLELEVEL_POINTERS;
           for(srcmlp = *srctlp, mlp = *tlp;
               srcmlp != emlp;
@@ -399,13 +370,11 @@ ExDupHandleTable(IN PEPROCESS QuotaProcess  OPTIONAL,
         else
         {
 freehandletable:
-          DPRINT1("Failed to duplicate handle table 0x%x\n", SourceHandleTable);
+          DPRINT1("Failed to duplicate handle table 0x%p\n", SourceHandleTable);
 
           ExReleaseHandleTableLock(SourceHandleTable);
-          
-          ExDestroyHandleTable(HandleTable,
-                               NULL,
-                               NULL);
+
+          ExDestroyHandleTable(HandleTable);
           /* allocate an empty handle table */
           return ExCreateHandleTable(QuotaProcess);
         }
@@ -481,52 +450,52 @@ freehandletable:
         }
       }
     }
-    
+
     /* release the source handle table */
     ExReleaseHandleTableLock(SourceHandleTable);
   }
-  
+
   return HandleTable;
 }
 
 static PHANDLE_TABLE_ENTRY
 ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable,
-                            OUT PLONG Handle)
+                            OUT PHANDLE Handle)
 {
   PHANDLE_TABLE_ENTRY Entry = NULL;
-  
+
   PAGED_CODE();
-  
+
   ASSERT(HandleTable);
   ASSERT(Handle);
   ASSERT(KeGetCurrentThread() != NULL);
-  
-  DPRINT("HT[0x%x]: HandleCount: %d\n", HandleTable, HandleTable->HandleCount);
-  
+
+  DPRINT("HT[0x%p]: HandleCount: %d\n", HandleTable, HandleTable->HandleCount);
+
   if(HandleTable->HandleCount < EX_MAX_HANDLES)
   {
     ULONG tli, mli, eli;
-    
+
     if(HandleTable->FirstFreeTableEntry != -1)
     {
       /* there's a free handle entry we can just grab and use */
       tli = TLI_FROM_HANDLE(HandleTable->FirstFreeTableEntry);
       mli = MLI_FROM_HANDLE(HandleTable->FirstFreeTableEntry);
       eli = ELI_FROM_HANDLE(HandleTable->FirstFreeTableEntry);
-      
+
       /* the pointer should be valid in any way!!! */
       ASSERT(HandleTable->Table[tli]);
       ASSERT(HandleTable->Table[tli][mli]);
-      
+
       Entry = &HandleTable->Table[tli][mli][eli];
-      
-      *Handle = HandleTable->FirstFreeTableEntry;
-      
+
+      *Handle = EX_HANDLE_TO_HANDLE(HandleTable->FirstFreeTableEntry);
+
       /* save the index to the next free handle (if available) */
       HandleTable->FirstFreeTableEntry = Entry->u2.NextFreeTableEntry;
       Entry->u2.NextFreeTableEntry = 0;
       Entry->u1.Object = NULL;
-      
+
       HandleTable->HandleCount++;
     }
     else
@@ -537,7 +506,7 @@ ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable,
       BOOLEAN AllocatedMtbl;
 
       ASSERT(HandleTable->NextIndexNeedingPool <= N_MAX_HANDLE);
-      
+
       /* the index of the next table to be allocated was saved in
          NextIndexNeedingPool the last time a handle entry was allocated and
          the subhandle entry list was full. the subhandle entry index of
@@ -549,8 +518,8 @@ ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable,
 
       ASSERT(ELI_FROM_HANDLE(HandleTable->NextIndexNeedingPool) == 0);
 
-      DPRINT("HandleTable->Table[%d] == 0x%x\n", tli, HandleTable->Table[tli]);
-      
+      DPRINT("HandleTable->Table[%d] == 0x%p\n", tli, HandleTable->Table[tli]);
+
       /* allocate a middle level entry list if required */
       nmtbl = HandleTable->Table[tli];
       if(nmtbl == NULL)
@@ -559,7 +528,7 @@ ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable,
         {
           /* FIXME - Charge process quota before allocating the handle table! */
         }
-        
+
         nmtbl = ExAllocatePoolWithTag(PagedPool,
                                       N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY),
                                       TAG('E', 'x', 'H', 't'));
@@ -569,16 +538,16 @@ ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable,
           {
             /* FIXME - return the quota to the process */
           }
-          
+
           return NULL;
         }
-        
+
         /* clear the middle level entry list */
         RtlZeroMemory(nmtbl, N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY));
-        
+
         /* make sure the table was zeroed before we set one item */
         KeMemoryBarrier();
-        
+
         /* note, don't set the the pointer in the top level list yet because we
            might screw up lookups if allocating a subhandle entry table failed
            and this newly allocated table might get freed again */
@@ -587,12 +556,12 @@ ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable,
       else
       {
         AllocatedMtbl = FALSE;
-        
+
         /* allocate a subhandle entry table in any case! */
         ASSERT(nmtbl[mli] == NULL);
       }
 
-      DPRINT("HandleTable->Table[%d][%d] == 0x%x\n", tli, mli, nmtbl[mli]);
+      DPRINT("HandleTable->Table[%d][%d] == 0x%p\n", tli, mli, nmtbl[mli]);
 
       if(HandleTable->QuotaProcess != NULL)
       {
@@ -608,31 +577,31 @@ ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable,
         {
           /* FIXME - Return process quota charged  */
         }
-        
+
         /* free the middle level entry list, if allocated, because it's empty and
            unused */
         if(AllocatedMtbl)
         {
           ExFreePool(nmtbl);
-          
+
           if(HandleTable->QuotaProcess != NULL)
           {
             /* FIXME - Return process quota charged  */
           }
         }
-        
+
         return NULL;
       }
-      
+
       /* let's just use the very first entry */
       Entry = ntbl;
       Entry->u1.ObAttributes = EX_HANDLE_ENTRY_LOCKED;
       Entry->u2.NextFreeTableEntry = 0;
-      
-      *Handle = HandleTable->NextIndexNeedingPool;
-      
+
+      *Handle = EX_HANDLE_TO_HANDLE(HandleTable->NextIndexNeedingPool);
+
       HandleTable->HandleCount++;
-      
+
       /* set the FirstFreeTableEntry member to the second entry and chain the
          free entries */
       HandleTable->FirstFreeTableEntry = HandleTable->NextIndexNeedingPool + 1;
@@ -652,7 +621,7 @@ ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable,
       {
         InterlockedExchangePointer(&HandleTable->Table[tli], nmtbl);
       }
-      
+
       /* increment the NextIndexNeedingPool to the next index where we need to
          allocate new memory */
       HandleTable->NextIndexNeedingPool += N_SUBHANDLE_ENTRIES;
@@ -660,9 +629,9 @@ ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable,
   }
   else
   {
-    DPRINT1("Can't allocate any more handles in handle table 0x%x!\n", HandleTable);
+    DPRINT1("Can't allocate any more handles in handle table 0x%p!\n", HandleTable);
   }
-  
+
   return Entry;
 }
 
@@ -672,20 +641,20 @@ ExpFreeHandleTableEntry(IN PHANDLE_TABLE HandleTable,
                         IN LONG Handle)
 {
   PAGED_CODE();
-  
+
   ASSERT(HandleTable);
   ASSERT(Entry);
   ASSERT(IS_VALID_EX_HANDLE(Handle));
-  
-  DPRINT("ExpFreeHandleTableEntry HT:0x%x Entry:0x%x\n", HandleTable, Entry);
-  
+
+  DPRINT("ExpFreeHandleTableEntry HT:0x%p Entry:0x%p\n", HandleTable, Entry);
+
   /* automatically unlock the entry if currently locked. We however don't notify
      anyone who waited on the handle because we're holding an exclusive lock after
      all and these locks will fail then */
   InterlockedExchangePointer(&Entry->u1.Object, NULL);
   Entry->u2.NextFreeTableEntry = HandleTable->FirstFreeTableEntry;
   HandleTable->FirstFreeTableEntry = Handle;
-  
+
   HandleTable->HandleCount--;
 }
 
@@ -694,33 +663,33 @@ ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable,
                           IN LONG Handle)
 {
   PHANDLE_TABLE_ENTRY Entry = NULL;
-  
+
   PAGED_CODE();
-  
+
   ASSERT(HandleTable);
-  
+
   if(IS_VALID_EX_HANDLE(Handle))
   {
     ULONG tli, mli, eli;
     PHANDLE_TABLE_ENTRY *mlp;
-    
+
     tli = TLI_FROM_HANDLE(Handle);
     mli = MLI_FROM_HANDLE(Handle);
     eli = ELI_FROM_HANDLE(Handle);
-    
+
     mlp = HandleTable->Table[tli];
     if(Handle < HandleTable->NextIndexNeedingPool &&
        mlp != NULL && mlp[mli] != NULL && mlp[mli][eli].u1.Object != NULL)
     {
       Entry = &mlp[mli][eli];
-      DPRINT("handle lookup 0x%x -> entry 0x%x [HT:0x%x] ptr: 0x%x\n", Handle, Entry, HandleTable, mlp[mli][eli].u1.Object);
+      DPRINT("handle lookup 0x%x -> entry 0x%p [HT:0x%p] ptr: 0x%p\n", Handle, Entry, HandleTable, mlp[mli][eli].u1.Object);
     }
   }
   else
   {
     DPRINT("Looking up invalid handle 0x%x\n", Handle);
   }
-  
+
   return Entry;
 }
 
@@ -731,22 +700,22 @@ ExLockHandleTableEntry(IN PHANDLE_TABLE HandleTable,
   ULONG_PTR Current, New;
 
   PAGED_CODE();
-  
-  DPRINT("Entering handle table entry 0x%x lock...\n", Entry);
-  
+
+  DPRINT("Entering handle table entry 0x%p lock...\n", Entry);
+
   ASSERT(HandleTable);
   ASSERT(Entry);
-  
+
   for(;;)
   {
     Current = (volatile ULONG_PTR)Entry->u1.Object;
-    
+
     if(!Current || (HandleTable->Flags & EX_HANDLE_TABLE_CLOSING))
     {
-      DPRINT("Attempted to lock empty handle table entry 0x%x or handle table shut down\n", Entry);
+      DPRINT("Attempted to lock empty handle table entry 0x%p or handle table shut down\n", Entry);
       break;
     }
-    
+
     if(!(Current & EX_HANDLE_ENTRY_LOCKED))
     {
       New = Current | EX_HANDLE_ENTRY_LOCKED;
@@ -754,7 +723,7 @@ ExLockHandleTableEntry(IN PHANDLE_TABLE HandleTable,
                                            (PVOID)New,
                                            (PVOID)Current) == (PVOID)Current)
       {
-        DPRINT("SUCCESS handle table 0x%x entry 0x%x lock\n", HandleTable, Entry);
+        DPRINT("SUCCESS handle table 0x%p entry 0x%p lock\n", HandleTable, Entry);
         /* we acquired the lock */
         return TRUE;
       }
@@ -779,20 +748,20 @@ ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable,
                          IN PHANDLE_TABLE_ENTRY Entry)
 {
   ULONG_PTR Current, New;
-  
+
   PAGED_CODE();
-  
+
   ASSERT(HandleTable);
   ASSERT(Entry);
-  
-  DPRINT("ExUnlockHandleTableEntry HT:0x%x Entry:0x%x\n", HandleTable, Entry);
-  
+
+  DPRINT("ExUnlockHandleTableEntry HT:0x%p Entry:0x%p\n", HandleTable, Entry);
+
   Current = (volatile ULONG_PTR)Entry->u1.Object;
 
   ASSERT(Current & EX_HANDLE_ENTRY_LOCKED);
-  
+
   New = Current & ~EX_HANDLE_ENTRY_LOCKED;
-  
+
   InterlockedExchangePointer(&Entry->u1.Object,
                              (PVOID)New);
 
@@ -803,32 +772,32 @@ ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable,
                FALSE);
 }
 
-LONG
+HANDLE
 ExCreateHandle(IN PHANDLE_TABLE HandleTable,
                IN PHANDLE_TABLE_ENTRY Entry)
 {
   PHANDLE_TABLE_ENTRY NewHandleTableEntry;
-  LONG Handle = EX_INVALID_HANDLE;
-  
+  HANDLE Handle = NULL;
+
   PAGED_CODE();
-  
+
   ASSERT(HandleTable);
   ASSERT(Entry);
-  
+
   /* The highest bit in Entry->u1.Object has to be 1 so we make sure it's a
      pointer to kmode memory. It will cleared though because it also indicates
      the lock */
   ASSERT((ULONG_PTR)Entry->u1.Object & EX_HANDLE_ENTRY_LOCKED);
-  
+
   KeEnterCriticalRegion();
   ExAcquireHandleTableLockExclusive(HandleTable);
-  
+
   NewHandleTableEntry = ExpAllocateHandleTableEntry(HandleTable,
                                                     &Handle);
   if(NewHandleTableEntry != NULL)
   {
     *NewHandleTableEntry = *Entry;
-    
+
     ExUnlockHandleTableEntry(HandleTable,
                              NewHandleTableEntry);
   }
@@ -841,51 +810,54 @@ ExCreateHandle(IN PHANDLE_TABLE HandleTable,
 
 BOOLEAN
 ExDestroyHandle(IN PHANDLE_TABLE HandleTable,
-                IN LONG Handle)
+                IN HANDLE Handle)
 {
   PHANDLE_TABLE_ENTRY HandleTableEntry;
+  LONG ExHandle;
   BOOLEAN Ret = FALSE;
-  
+
   PAGED_CODE();
-  
+
   ASSERT(HandleTable);
   
+  ExHandle = HANDLE_TO_EX_HANDLE(Handle);
+
   KeEnterCriticalRegion();
   ExAcquireHandleTableLockExclusive(HandleTable);
-  
+
   HandleTableEntry = ExpLookupHandleTableEntry(HandleTable,
-                                               Handle);
-  
+                                               ExHandle);
+
   if(HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry))
   {
     /* free and automatically unlock the handle. However we don't need to pulse
        the contention event since other locks on this entry will fail */
     ExpFreeHandleTableEntry(HandleTable,
                             HandleTableEntry,
-                            Handle);
+                            ExHandle);
     Ret = TRUE;
   }
-  
+
   ExReleaseHandleTableLock(HandleTable);
   KeLeaveCriticalRegion();
-  
+
   return Ret;
 }
 
 VOID
 ExDestroyHandleByEntry(IN PHANDLE_TABLE HandleTable,
                        IN PHANDLE_TABLE_ENTRY Entry,
-                       IN LONG Handle)
+                       IN HANDLE Handle)
 {
   PAGED_CODE();
 
   ASSERT(HandleTable);
   ASSERT(Entry);
-  
+
   /* This routine requires the entry to be locked */
   ASSERT((ULONG_PTR)Entry->u1.Object & EX_HANDLE_ENTRY_LOCKED);
-  
-  DPRINT("DestroyHandleByEntry HT:0x%x Entry:0x%x\n", HandleTable, Entry);
+
+  DPRINT("DestroyHandleByEntry HT:0x%p Entry:0x%p\n", HandleTable, Entry);
 
   KeEnterCriticalRegion();
   ExAcquireHandleTableLockExclusive(HandleTable);
@@ -894,7 +866,7 @@ ExDestroyHandleByEntry(IN PHANDLE_TABLE HandleTable,
      the contention event since other locks on this entry will fail */
   ExpFreeHandleTableEntry(HandleTable,
                           Entry,
-                          Handle);
+                          HANDLE_TO_EX_HANDLE(Handle));
 
   ExReleaseHandleTableLock(HandleTable);
   KeLeaveCriticalRegion();
@@ -902,28 +874,28 @@ ExDestroyHandleByEntry(IN PHANDLE_TABLE HandleTable,
 
 PHANDLE_TABLE_ENTRY
 ExMapHandleToPointer(IN PHANDLE_TABLE HandleTable,
-                     IN LONG Handle)
+                     IN HANDLE Handle)
 {
   PHANDLE_TABLE_ENTRY HandleTableEntry;
 
   PAGED_CODE();
 
   ASSERT(HandleTable);
-  
+
   HandleTableEntry = ExpLookupHandleTableEntry(HandleTable,
-                                               Handle);
+                                               HANDLE_TO_EX_HANDLE(Handle));
   if (HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry))
   {
-    DPRINT("ExMapHandleToPointer HT:0x%x Entry:0x%x locked\n", HandleTable, HandleTableEntry);
+    DPRINT("ExMapHandleToPointer HT:0x%p Entry:0x%p locked\n", HandleTable, HandleTableEntry);
     return HandleTableEntry;
   }
-  
+
   return NULL;
 }
 
 BOOLEAN
 ExChangeHandle(IN PHANDLE_TABLE HandleTable,
-               IN LONG Handle,
+               IN HANDLE Handle,
                IN PEX_CHANGE_HANDLE_CALLBACK ChangeHandleCallback,
                IN PVOID Context)
 {
@@ -936,9 +908,9 @@ ExChangeHandle(IN PHANDLE_TABLE HandleTable,
   ASSERT(ChangeHandleCallback);
 
   KeEnterCriticalRegion();
-  
+
   HandleTableEntry = ExpLookupHandleTableEntry(HandleTable,
-                                               Handle);
+                                               HANDLE_TO_EX_HANDLE(Handle));
 
   if(HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry))
   {
@@ -949,7 +921,7 @@ ExChangeHandle(IN PHANDLE_TABLE HandleTable,
     ExUnlockHandleTableEntry(HandleTable,
                              HandleTableEntry);
   }
-  
+
   KeLeaveCriticalRegion();
 
   return Ret;