started moving tags to a private internal header
[reactos.git] / reactos / ntoskrnl / ex / resource.c
index 5af8a6a..d7e0434 100644 (file)
@@ -1,12 +1,11 @@
-/* $Id: resource.c,v 1.15 2000/10/22 16:36:49 ekohl Exp $
+/* $Id$
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/resource.c
  * PURPOSE:         Resource synchronization construct
- * PROGRAMMER:      Unknown 
- * UPDATE HISTORY:
- *                  Created 22/05/98
+ *
+ * PROGRAMMERS:     No programmer listed.
  */
 
 
@@ -38,9 +37,7 @@
 
 /* INCLUDES *****************************************************************/
 
-#include <ddk/ntddk.h>
-#include <internal/ke.h>
-
+#include <ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
 
@@ -63,6 +60,13 @@ ExTryToAcquireResourceExclusiveLite (
   return(ExAcquireResourceExclusiveLite(Resource,FALSE));
 }
 
+#ifdef ExAcquireResourceExclusive
+#undef ExAcquireResourceExclusive
+#endif
+
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 ExAcquireResourceExclusive (
@@ -73,6 +77,10 @@ ExAcquireResourceExclusive (
    return(ExAcquireResourceExclusiveLite(Resource,Wait));
 }
 
+
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 ExAcquireResourceExclusiveLite (
@@ -91,10 +99,21 @@ ExAcquireResourceExclusiveLite (
  */
 {
    KIRQL oldIrql;
-   
+
    DPRINT("ExAcquireResourceExclusiveLite(Resource %x, Wait %d)\n",
          Resource, Wait);
-   
+
+   ASSERT_IRQL_LESS(DISPATCH_LEVEL);
+
+/* undefed for now, since cdfs must be fixed first */
+#if 0
+   /* At least regular kmode APC's must be disabled
+    * Note that this requirement is missing in old DDK's */
+   ASSERT(KeGetCurrentThread() == NULL || /* <-Early in the boot process the current thread is obseved to be NULL */
+          KeGetCurrentThread()->KernelApcDisable ||
+          KeGetCurrentIrql() == APC_LEVEL);
+#endif
+
    KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
 
    /* resource already locked */
@@ -102,7 +121,7 @@ ExAcquireResourceExclusiveLite (
       && Resource->OwnerThreads[0].OwnerThread == ExGetCurrentResourceThread())
      {
        /* it's ok : same lock for same thread */
-       Resource->OwnerThreads[0].a.OwnerCount++;
+    Resource->OwnerThreads[0].OwnerCount++;
        KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
        DPRINT("ExAcquireResourceExclusiveLite() = TRUE\n");
        return(TRUE);
@@ -114,17 +133,17 @@ ExAcquireResourceExclusiveLite (
        DPRINT("ExAcquireResourceExclusiveLite() = FALSE\n");
        return(FALSE);
      }
-   
-   /* 
+
+   /*
     * This is slightly better than it looks because other exclusive
     * threads who are waiting won't be woken up but there is a race
     * with new threads trying to grab the resource so we must have
     * the spinlock, still normally this loop will only be executed
     * once
-    * NOTE: We might want to set a timeout to detect deadlock 
+    * NOTE: We might want to set a timeout to detect deadlock
     * (10 minutes?)
     */
-   while (Resource->ActiveCount) 
+   while (Resource->ActiveCount)
      {
        Resource->NumberOfExclusiveWaiters++;
        KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
@@ -139,7 +158,7 @@ ExAcquireResourceExclusiveLite (
    Resource->Flag |= ResourceOwnedExclusive;
    Resource->ActiveCount = 1;
    Resource->OwnerThreads[0].OwnerThread = ExGetCurrentResourceThread();
-   Resource->OwnerThreads[0].a.OwnerCount = 1;
+   Resource->OwnerThreads[0].OwnerCount = 1;
    KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
    DPRINT("ExAcquireResourceExclusiveLite() = TRUE\n");
    return(TRUE);
@@ -156,36 +175,36 @@ static BOOLEAN EiRemoveSharedOwner(PERESOURCE Resource,
  */
 {
    ULONG i;
-   
+
    if (Resource->OwnerThreads[1].OwnerThread == ResourceThreadId)
      {
-       Resource->OwnerThreads[1].a.OwnerCount--;
-       Resource->ActiveCount--;
-       if (Resource->OwnerThreads[1].a.OwnerCount == 0)
+    Resource->OwnerThreads[1].OwnerCount--;
+    if (Resource->OwnerThreads[1].OwnerCount == 0)
          {
+             Resource->ActiveCount--;
             Resource->OwnerThreads[1].OwnerThread = 0;
          }
        return(TRUE);
      }
-   
-   if (Resource->OwnerThreads[1].OwnerThread) 
+
+   if (Resource->OwnerThreads[1].OwnerThread)
      {
        /* Oh dear, the caller didn't own the resource after all */
-       return(FALSE);;
+       return(FALSE);
      }
-   
-   for (i=0; i<Resource->OwnerThreads[1].a.TableSize; i++)
+
+   for (i=0; i<Resource->OwnerThreads[1].TableSize; i++)
      {
        if (Resource->OwnerTable[i].OwnerThread == ResourceThreadId)
          {
-            Resource->OwnerTable[1].a.OwnerCount--;
-            Resource->ActiveCount--;
-            if (Resource->OwnerTable[1].a.OwnerCount == 0)
+         Resource->OwnerTable[i].OwnerCount--;
+         if (Resource->OwnerTable[i].OwnerCount == 0)
               {
+                 Resource->ActiveCount--;
                  Resource->OwnerTable[i].OwnerThread = 0;
               }
+            return TRUE;
          }
-       return(TRUE);
      }
    return(FALSE);
 }
@@ -202,14 +221,14 @@ static BOOLEAN EiAddSharedOwner(PERESOURCE Resource)
    ERESOURCE_THREAD CurrentThread = ExGetCurrentResourceThread();
    POWNER_ENTRY freeEntry;
    ULONG i = 0;
-   
+
    DPRINT("EiAddSharedOwner(Resource %x)\n", Resource);
-   
-   if (Resource->ActiveCount == 0) 
+
+   if (Resource->ActiveCount == 0)
      {
        /* no owner, it's easy */
        Resource->OwnerThreads[1].OwnerThread = ExGetCurrentResourceThread();
-       Resource->OwnerThreads[1].a.OwnerCount = 1;
+    Resource->OwnerThreads[1].OwnerCount = 1;
        if (Resource->OwnerTable != NULL)
          {
             ExFreePool(Resource->OwnerTable);
@@ -219,86 +238,94 @@ static BOOLEAN EiAddSharedOwner(PERESOURCE Resource)
        DPRINT("EiAddSharedOwner() = TRUE\n");
        return(TRUE);
      }
-   
-   /* 
-    * now, we must search if this thread has already acquired this resource 
-    * then increase ownercount if found, else create new entry or reuse free 
+
+   /*
+    * now, we must search if this thread has already acquired this resource
+    * then increase ownercount if found, else create new entry or reuse free
     * entry
     */
    if (Resource->OwnerTable == NULL)
      {
        DPRINT("Creating owner table\n");
-       
+
        /* allocate ownertable,memset to 0, initialize first entry */
-       Resource->OwnerTable = ExAllocatePool(NonPagedPool,
-                                             sizeof(OWNER_ENTRY)*3);
+       Resource->OwnerTable =
+         ExAllocatePoolWithTag(NonPagedPool, sizeof(OWNER_ENTRY)*3,
+                               TAG_OWNER_TABLE);
        if (Resource->OwnerTable == NULL)
          {
-            KeBugCheck(0);
+            KEBUGCHECK(0);
             return(FALSE);
          }
-       memset(Resource->OwnerTable,sizeof(OWNER_ENTRY)*3,0);
+       memset(Resource->OwnerTable,0,sizeof(OWNER_ENTRY)*3);
        memcpy(&Resource->OwnerTable[0], &Resource->OwnerThreads[1],
               sizeof(OWNER_ENTRY));
-       
+
        Resource->OwnerThreads[1].OwnerThread = 0;
-       Resource->OwnerThreads[1].a.TableSize = 3;
-       
+    Resource->OwnerThreads[1].TableSize = 3;
+
        Resource->OwnerTable[1].OwnerThread = CurrentThread;
-       Resource->OwnerTable[1].a.OwnerCount = 1;
-       
+    Resource->OwnerTable[1].OwnerCount = 1;
+        Resource->ActiveCount++;
+
        return(TRUE);
      }
-   
+
    DPRINT("Search free entries\n");
-   
-   DPRINT("Number of entries %d\n", 
-         Resource->OwnerThreads[1].a.TableSize);
-   
+
+   DPRINT("Number of entries %d\n",
+      Resource->OwnerThreads[1].TableSize);
+
    freeEntry = NULL;
-   for (i=0; i<Resource->OwnerThreads[1].a.TableSize; i++)
+   for (i=0; i<Resource->OwnerThreads[1].TableSize; i++)
      {
        if (Resource->OwnerTable[i].OwnerThread == CurrentThread)
          {
             DPRINT("Thread already owns resource\n");
-            Resource->OwnerTable[i].a.OwnerCount++;
+         Resource->OwnerTable[i].OwnerCount++;
             return(TRUE);
          }
        if (Resource->OwnerTable[i].OwnerThread == 0)
          {
             freeEntry = &Resource->OwnerTable[i];
+            break;
          }
      }
-   
+
    DPRINT("Found free entry %x\n", freeEntry);
-   
+
    if (!freeEntry)
      {
        DPRINT("Allocating new entry\n");
-       
+
        /* reallocate ownertable with one more entry */
-       freeEntry = ExAllocatePool(NonPagedPool,
-                                  sizeof(OWNER_ENTRY)*
-                                  (Resource->OwnerThreads[1].a.TableSize+1));
+       freeEntry =
+         ExAllocatePoolWithTag(NonPagedPool,
+                               sizeof(OWNER_ENTRY)*
+                (Resource->OwnerThreads[1].TableSize+1),
+                               TAG_OWNER_TABLE);
        if (freeEntry == NULL)
          {
-            KeBugCheck(0);
+            KEBUGCHECK(0);
             return(FALSE);
          }
        memcpy(freeEntry,Resource->OwnerTable,
-              sizeof(OWNER_ENTRY)*(Resource->OwnerThreads[1].a.TableSize));
+           sizeof(OWNER_ENTRY)*(Resource->OwnerThreads[1].TableSize));
        ExFreePool(Resource->OwnerTable);
        Resource->OwnerTable=freeEntry;
-       freeEntry=&Resource->OwnerTable[Resource->OwnerThreads[1].a.TableSize];
-       Resource->OwnerThreads[1].a.TableSize++;
+    freeEntry=&Resource->OwnerTable[Resource->OwnerThreads[1].TableSize];
+    Resource->OwnerThreads[1].TableSize++;
      }
    DPRINT("Creating entry\n");
    freeEntry->OwnerThread=ExGetCurrentResourceThread();
-   freeEntry->a.OwnerCount=1;
+   freeEntry->OwnerCount=1;
    Resource->ActiveCount++;
    return(TRUE);
 }
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 ExAcquireResourceSharedLite (
@@ -318,39 +345,51 @@ ExAcquireResourceSharedLite (
  */
 {
    KIRQL oldIrql;
-   
+
    DPRINT("ExAcquireResourceSharedLite(Resource %x, Wait %d)\n",
          Resource, Wait);
-   
+
+   ASSERT_IRQL_LESS(DISPATCH_LEVEL);
+
+/* undefed for now, since cdfs must be fixed first */
+#if 0
+   /* At least regular kmode APC's must be disabled
+    * Note that this requirement is missing in old DDK's
+    */
+   ASSERT(KeGetCurrentThread() == NULL || /* <-Early in the boot process the current thread is obseved to be NULL */
+          KeGetCurrentThread()->KernelApcDisable ||
+          KeGetCurrentIrql() == APC_LEVEL);
+#endif
+
    KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
-   
+
    /* first, resolve trivial cases */
-   if (Resource->ActiveCount == 0) 
+   if (Resource->ActiveCount == 0)
      {
        EiAddSharedOwner(Resource);
        KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
        DPRINT("ExAcquireResourceSharedLite() = TRUE\n");
        return(TRUE);
      }
-   
+
    if ((Resource->Flag & ResourceOwnedExclusive)
        && Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread())
      {
        /* exclusive, but by same thread : it's ok */
-       /* 
-        * NOTE: Is this correct? Seems the same as ExConvertExclusiveToShared 
+       /*
+        * NOTE: Is this correct? Seems the same as ExConvertExclusiveToShared
         */
-       Resource->OwnerThreads[0].a.OwnerCount++;
+    Resource->OwnerThreads[0].OwnerCount++;
        KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
        DPRINT("ExAcquireResourceSharedLite() = TRUE\n");
        return(TRUE);
      }
-   
+
    if ((Resource->Flag & ResourceOwnedExclusive)
        || Resource->NumberOfExclusiveWaiters)
-     { 
+     {
        /* exclusive by another thread , or thread waiting for exclusive */
-       if (!Wait) 
+       if (!Wait)
          {
             KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
             DPRINT("ExAcquireResourceSharedLite() = FALSE\n");
@@ -358,21 +397,30 @@ ExAcquireResourceSharedLite (
          }
        else
          {
-            Resource->NumberOfSharedWaiters++;
-            /* wait for the semaphore */
-            KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
-            KeWaitForSingleObject(Resource->SharedWaiters,0,0,0,0);
-            KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
-            Resource->NumberOfSharedWaiters--;
+           Resource->NumberOfSharedWaiters++;
+           do
+           {
+              /* wait for the semaphore */
+              KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
+              KeWaitForSingleObject(Resource->SharedWaiters,0, KernelMode, FALSE, NULL);
+              KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
+              /* the spin lock was released we must check again */
+           }
+           while ((Resource->Flag & ResourceOwnedExclusive)
+               || Resource->NumberOfExclusiveWaiters);
+           Resource->NumberOfSharedWaiters--;
          }
      }
-   
+
    EiAddSharedOwner(Resource);
    KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
    DPRINT("ExAcquireResourceSharedLite() = TRUE\n");
    return(TRUE);
 }
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 ExConvertExclusiveToSharedLite (
@@ -389,40 +437,43 @@ ExConvertExclusiveToSharedLite (
 {
    ULONG oldWaiters;
    KIRQL oldIrql;
-   
+
    DPRINT("ExConvertExclusiveToSharedLite(Resource %x)\n", Resource);
-   
+
    KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
-   
+
    oldWaiters = Resource->NumberOfSharedWaiters;
-   
+
    if (!(Resource->Flag & ResourceOwnedExclusive))
      {
        /* Might not be what the caller expects, better bug check */
-       KeBugCheck(0);
+       KEBUGCHECK(0);
        KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
        return;
      }
-   
+
    //transfer infos from entry 0 to entry 1 and erase entry 0
    Resource->OwnerThreads[1].OwnerThread=Resource->OwnerThreads[0].OwnerThread;
-   Resource->OwnerThreads[1].a.OwnerCount=Resource->OwnerThreads[0].a.OwnerCount;
+   Resource->OwnerThreads[1].OwnerCount=Resource->OwnerThreads[0].OwnerCount;
    Resource->OwnerThreads[0].OwnerThread=0;
-   Resource->OwnerThreads[0].a.OwnerCount=0;
+   Resource->OwnerThreads[0].OwnerCount=0;
    /* erase exclusive flag */
    Resource->Flag &= (~ResourceOwnedExclusive);
    /* if no shared waiters, that's all */
-   if (!oldWaiters) 
+   if (!oldWaiters)
      {
        KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
        return;
      }
    /* else, awake the waiters */
-   KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
    KeReleaseSemaphore(Resource->SharedWaiters,0,oldWaiters,0);
+   KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
    DPRINT("ExConvertExclusiveToSharedLite() finished\n");
 }
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 ExDisableResourceBoostLite (
@@ -432,6 +483,9 @@ ExDisableResourceBoostLite (
    Resource->Flag |= ResourceDisableBoost;
 }
 
+/*
+ * @implemented
+ */
 ULONG
 STDCALL
 ExGetExclusiveWaiterCount (
@@ -441,6 +495,9 @@ ExGetExclusiveWaiterCount (
   return(Resource->NumberOfExclusiveWaiters);
 }
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 ExAcquireSharedStarveExclusive (
@@ -461,37 +518,37 @@ ExAcquireSharedStarveExclusive (
  */
 {
    KIRQL oldIrql;
-   
+
    DPRINT("ExAcquireSharedStarveExclusive(Resource %x, Wait %d)\n",
          Resource, Wait);
-   
+
    KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
-   
+
    /* no owner, it's easy */
-   if (Resource->ActiveCount == 0) 
+   if (Resource->ActiveCount == 0)
      {
        Resource->OwnerThreads[1].OwnerThread=ExGetCurrentResourceThread();
-       Resource->OwnerThreads[1].a.OwnerCount=1;
+    Resource->OwnerThreads[1].OwnerCount=1;
        Resource->ActiveCount=1;
        KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
        DPRINT("ExAcquireSharedStarveExclusive() = TRUE\n");
        return(TRUE);
      }
-   
+
    if ((Resource->Flag & ResourceOwnedExclusive)
        &&  Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread())
-     { 
+     {
        /* exclusive, but by same thread : it's ok */
-       Resource->OwnerThreads[0].a.OwnerCount++;
+    Resource->OwnerThreads[0].OwnerCount++;
        KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
        DPRINT("ExAcquireSharedStarveExclusive() = TRUE\n");
        return(TRUE);
      }
-   
+
    if (Resource->Flag & ResourceOwnedExclusive)
-     { 
+     {
        /* exclusive by another thread */
-       if (!Wait) 
+       if (!Wait)
          {
             KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
             DPRINT("ExAcquireSharedStarveExclusive() = FALSE\n");
@@ -513,6 +570,9 @@ ExAcquireSharedStarveExclusive (
    return(TRUE);
 }
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 ExAcquireSharedWaitForExclusive (
@@ -523,6 +583,15 @@ ExAcquireSharedWaitForExclusive (
   return(ExAcquireResourceSharedLite(Resource,Wait));
 }
 
+
+#ifdef ExDeleteResource
+#undef ExDeleteResource
+#endif
+
+
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 ExDeleteResource (
@@ -532,6 +601,9 @@ ExDeleteResource (
    return(ExDeleteResourceLite(Resource));
 }
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 ExDeleteResourceLite (
@@ -542,9 +614,12 @@ ExDeleteResourceLite (
    if (Resource->OwnerTable) ExFreePool(Resource->OwnerTable);
    if (Resource->SharedWaiters) ExFreePool(Resource->SharedWaiters);
    if (Resource->ExclusiveWaiters) ExFreePool(Resource->ExclusiveWaiters);
-   return(STATUS_SUCCESS);;
+   return(STATUS_SUCCESS);
 }
 
+/*
+ * @implemented
+ */
 ULONG
 STDCALL
 ExGetSharedWaiterCount (
@@ -554,6 +629,14 @@ ExGetSharedWaiterCount (
    return(Resource->NumberOfSharedWaiters);
 }
 
+
+#ifdef ExInitializeResource
+#undef ExInitializeResource
+#endif
+
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 ExInitializeResource (
@@ -563,11 +646,11 @@ ExInitializeResource (
    return(ExInitializeResourceLite(Resource));
 }
 
-NTSTATUS
-STDCALL
-ExInitializeResourceLite (
-       PERESOURCE      Resource
-       )
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+ExInitializeResourceLite (PERESOURCE   Resource)
 {
    DPRINT("ExInitializeResourceLite(Resource %x)\n", Resource);
    memset(Resource,0,sizeof(ERESOURCE));
@@ -575,16 +658,21 @@ ExInitializeResourceLite (
    Resource->NumberOfExclusiveWaiters = 0;
    KeInitializeSpinLock(&Resource->SpinLock);
    Resource->Flag = 0;
-   Resource->ExclusiveWaiters = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
+   Resource->ExclusiveWaiters =
+     ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_EXCLUSIVE_LOCK);
    KeInitializeEvent(Resource->ExclusiveWaiters,
                     SynchronizationEvent,
                     FALSE);
-   Resource->SharedWaiters = ExAllocatePool(NonPagedPool ,sizeof(KSEMAPHORE));
+   Resource->SharedWaiters =
+     ExAllocatePoolWithTag(NonPagedPool ,sizeof(KSEMAPHORE), TAG_SHARED_SEM);
    KeInitializeSemaphore(Resource->SharedWaiters,0,0x7fffffff);
    Resource->ActiveCount = 0;
    return(0);
 }
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 ExIsResourceAcquiredExclusiveLite (
@@ -603,11 +691,23 @@ ExIsResourceAcquiredExclusiveLite (
          && Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread());
 }
 
-ULONG
-STDCALL
-ExIsResourceAcquiredSharedLite (
-       PERESOURCE      Resource
-       )
+
+
+#ifdef ExIsResourceAcquiredSharedLite
+#undef ExIsResourceAcquiredSharedLite
+#endif
+
+
+/*
+ * @implemented
+ */
+
+
+//NTOSAPI
+//DDKAPI
+USHORT STDCALL
+ExIsResourceAcquiredSharedLite(
+  IN PERESOURCE  Resource)
 /*
  * FUNCTION: Returns whether the current thread has shared access to a given
  *           resource
@@ -615,31 +715,34 @@ ExIsResourceAcquiredSharedLite (
  *      Resource = Points to the resource to be queried
  * RETURNS: The number of times the caller has acquired shared access to the
  *          given resource
- */ 
+ */
 {
    ULONG i;
    if (Resource->OwnerThreads[0].OwnerThread == ExGetCurrentResourceThread())
      {
-       return(Resource->OwnerThreads[0].a.OwnerCount);
+    return (USHORT)(Resource->OwnerThreads[0].OwnerCount);
      }
    if (Resource->OwnerThreads[1].OwnerThread == ExGetCurrentResourceThread())
      {
-       return(Resource->OwnerThreads[1].a.OwnerCount);
+    return (USHORT)(Resource->OwnerThreads[1].OwnerCount);
      }
-   if (!Resource->OwnerThreads[1].a.TableSize) 
+   if (!Resource->OwnerThreads[1].TableSize)
      {
        return(0);
      }
-   for (i=0; i<Resource->OwnerThreads[1].a.TableSize; i++)
+   for (i=0; i<Resource->OwnerThreads[1].TableSize; i++)
      {
        if (Resource->OwnerTable[i].OwnerThread==ExGetCurrentResourceThread())
          {
-            return Resource->OwnerTable[i].a.OwnerCount;
+         return (USHORT)Resource->OwnerTable[i].OwnerCount;
          }
      }
    return(0);
 }
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 ExReinitializeResourceLite (
@@ -654,26 +757,39 @@ ExReinitializeResourceLite (
                     FALSE);
    KeInitializeSemaphore(Resource->SharedWaiters,0,0x7fffffff);
    Resource->ActiveCount = 0;
-   if (Resource->OwnerTable) 
+   if (Resource->OwnerTable)
      {
        ExFreePool(Resource->OwnerTable);
      }
    Resource->OwnerThreads[0].OwnerThread=0;
-   Resource->OwnerThreads[0].a.OwnerCount=0;
+   Resource->OwnerThreads[0].OwnerCount=0;
    Resource->OwnerThreads[1].OwnerThread=0;
-   Resource->OwnerThreads[1].a.OwnerCount=0;
+   Resource->OwnerThreads[1].OwnerCount=0;
 }
 
+/*
+ * @implemented
+ */
 VOID
-STDCALL
+FASTCALL
 ExReleaseResourceLite (
        PERESOURCE      Resource
        )
 {
-  return(ExReleaseResourceForThreadLite(Resource,
-                                       ExGetCurrentResourceThread()));
+  ExReleaseResourceForThreadLite(Resource,
+                                       ExGetCurrentResourceThread());
 }
 
+
+
+#ifdef ExReleaseResourceForThread
+#undef ExReleaseResourceForThread
+#endif
+
+
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 ExReleaseResourceForThread (
@@ -681,9 +797,13 @@ ExReleaseResourceForThread (
        ERESOURCE_THREAD        ResourceThreadId
        )
 {
-  return(ExReleaseResourceForThreadLite(Resource,ResourceThreadId));
+  ExReleaseResourceForThreadLite(Resource,ResourceThreadId);
 }
 
+
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 ExReleaseResourceForThreadLite (
@@ -701,35 +821,37 @@ ExReleaseResourceForThreadLite (
  */
 {
    KIRQL oldIrql;
-   
+
    DPRINT("ExReleaseResourceForThreadLite(Resource %x, ResourceThreadId %x)\n",
          Resource, ResourceThreadId);
-   
+
+   ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+
    KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
-   
+
    if (Resource->Flag & ResourceOwnedExclusive)
      {
        DPRINT("Releasing from exclusive access\n");
-       
-       Resource->OwnerThreads[0].a.OwnerCount--;
-       if (Resource->OwnerThreads[0].a.OwnerCount > 0)
+
+    Resource->OwnerThreads[0].OwnerCount--;
+    if (Resource->OwnerThreads[0].OwnerCount > 0)
          {
             KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
             DPRINT("ExReleaseResourceForThreadLite() finished\n");
             return;
          }
-       
+
        Resource->OwnerThreads[0].OwnerThread = 0;
        Resource->ActiveCount--;
        Resource->Flag &=(~ResourceOwnedExclusive);
-       assert(Resource->ActiveCount == 0);
+       ASSERT(Resource->ActiveCount == 0);
        DPRINT("Resource->NumberOfExclusiveWaiters %d\n",
               Resource->NumberOfExclusiveWaiters);
        if (Resource->NumberOfExclusiveWaiters)
          {
             /* get resource to first exclusive waiter */
-            KeSetEvent(Resource->ExclusiveWaiters, 
-                       IO_NO_INCREMENT, 
+            KeSetEvent(Resource->ExclusiveWaiters,
+                       IO_NO_INCREMENT,
                        FALSE);
             KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
             DPRINT("ExReleaseResourceForThreadLite() finished\n");
@@ -749,25 +871,28 @@ ExReleaseResourceForThreadLite (
        DPRINT("ExReleaseResourceForThreadLite() finished\n");
        return;
      }
-  
+
    EiRemoveSharedOwner(Resource, ResourceThreadId);
-   
+
    if (Resource->ActiveCount == 0)
      {
        if (Resource->NumberOfExclusiveWaiters)
-         { 
+         {
             /* get resource to first exclusive waiter */
             KeSetEvent(Resource->ExclusiveWaiters,
                        IO_NO_INCREMENT,
                        FALSE);
          }
      }
-     
+
    KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
    DPRINT("ExReleaseResourceForThreadLite() finished\n");
 }
 
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 ExSetResourceOwnerPointer (
@@ -775,7 +900,57 @@ ExSetResourceOwnerPointer (
        IN      PVOID           OwnerPointer
        )
 {
+    PKTHREAD CurrentThread;
+    KIRQL OldIrql;
+    POWNER_ENTRY OwnerEntry;
+
+    CurrentThread = KeGetCurrentThread();
+
+    /* Lock the resource */
+    KeAcquireSpinLock(&Resource->SpinLock, &OldIrql);
+
+    /* Check if it's exclusive */
+    if (Resource->Flag & ResourceOwnedExclusive) {
+
+        /* If it's exclusive, set the first entry no matter what */
+        Resource->OwnerThreads[0].OwnerThread = (ULONG_PTR)OwnerPointer;
+
+    } else {
+
+        /* Check both entries and see which one matches the current thread */
+        if (Resource->OwnerThreads[0].OwnerThread == (ULONG_PTR)CurrentThread) {
+
+            Resource->OwnerThreads[0].OwnerThread = (ULONG_PTR)OwnerPointer;
+
+        } else if (Resource->OwnerThreads[1].OwnerThread == (ULONG_PTR)CurrentThread) {
+
+            Resource->OwnerThreads[1].OwnerThread = (ULONG_PTR)OwnerPointer;
+
+        } else { /* None of the entries match, so we need to do a lookup */
+
+            /* Get the first Entry */
+            OwnerEntry = Resource->OwnerTable;
+
+            /* Check if the Current Thread is in the Resource Table Entry */
+            if ((CurrentThread->ResourceIndex >= OwnerEntry->TableSize) ||
+                (OwnerEntry[CurrentThread->ResourceIndex].OwnerThread != (ULONG_PTR)CurrentThread)) {
+
+                /* Loop until we find the current thread in an entry */
+                for (;OwnerEntry->OwnerThread == (ULONG_PTR)CurrentThread;OwnerEntry++);
+
+            } else {
+
+                /* It's in the current RTE, so set it */
+                OwnerEntry = &OwnerEntry[CurrentThread->ResourceIndex];
+            }
+
+            /* Now that we went to the right entry, set the Owner Pointer */
+            OwnerEntry->OwnerThread = (ULONG_PTR)OwnerPointer;
+        }
+    }
 
+    /* Release the resource */
+    KeReleaseSpinLock(&Resource->SpinLock, OldIrql);
 }
 
 /* EOF */