started moving tags to a private internal header
[reactos.git] / reactos / ntoskrnl / ex / resource.c
index 2dff035..d7e0434 100644 (file)
@@ -1,12 +1,11 @@
-/* $Id: resource.c,v 1.20 2002/09/07 15:12:50 chorns 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.
  */
 
 
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
-
 #define NDEBUG
 #include <internal/debug.h>
 
+/* FUNCTIONS *****************************************************************/
+
 
-/* GLOBALS *******************************************************************/
+BOOLEAN
+STDCALL
+ExTryToAcquireResourceExclusiveLite (
+       PERESOURCE      Resource
+       )
+/*
+ * FUNCTION: Attempts to require the resource for exclusive access
+ * ARGUMENTS:
+ *         Resource = Points to the resource of be acquired
+ * RETURNS: TRUE if the resource was acquired for the caller
+ * NOTES: Must be acquired at IRQL < DISPATCH_LEVEL
+ */
+{
+  return(ExAcquireResourceExclusiveLite(Resource,FALSE));
+}
 
-#define TAG_OWNER_TABLE     TAG('R', 'O', 'W', 'N')
-#define TAG_EXCLUSIVE_LOCK  TAG('E', 'R', 'E', 'L')
-#define TAG_SHARED_SEM      TAG('E', 'R', 'S', 'S')
+#ifdef ExAcquireResourceExclusive
+#undef ExAcquireResourceExclusive
+#endif
+
+/*
+ * @implemented
+ */
+BOOLEAN
+STDCALL
+ExAcquireResourceExclusive (
+       PERESOURCE      Resource,
+       BOOLEAN         Wait
+       )
+{
+   return(ExAcquireResourceExclusiveLite(Resource,Wait));
+}
 
-/* FUNCTIONS *****************************************************************/
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 ExAcquireResourceExclusiveLite (
@@ -70,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 */
@@ -81,7 +121,7 @@ ExAcquireResourceExclusiveLite (
       && Resource->OwnerThreads[0].OwnerThread == ExGetCurrentResourceThread())
      {
        /* it's ok : same lock for same thread */
-       Resource->OwnerThreads[0].OwnerCount++;
+    Resource->OwnerThreads[0].OwnerCount++;
        KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
        DPRINT("ExAcquireResourceExclusiveLite() = TRUE\n");
        return(TRUE);
@@ -93,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);
@@ -124,34 +164,6 @@ ExAcquireResourceExclusiveLite (
    return(TRUE);
 }
 
-BOOLEAN
-STDCALL
-ExTryToAcquireResourceExclusiveLite (
-       PERESOURCE      Resource
-       )
-/*
- * FUNCTION: Attempts to require the resource for exclusive access
- * ARGUMENTS:
- *         Resource = Points to the resource of be acquired
- * RETURNS: TRUE if the resource was acquired for the caller
- * NOTES: Must be acquired at IRQL < DISPATCH_LEVEL
- */
-{
-  return(ExAcquireResourceExclusiveLite(Resource,FALSE));
-}
-
-#undef ExAcquireResourceExclusive
-
-BOOLEAN
-STDCALL
-ExAcquireResourceExclusive (
-       PERESOURCE      Resource,
-       BOOLEAN         Wait
-       )
-{
-   return(ExAcquireResourceExclusiveLite(Resource,Wait));
-}
-
 static BOOLEAN EiRemoveSharedOwner(PERESOURCE Resource,
                                   ERESOURCE_THREAD ResourceThreadId)
 /*
@@ -163,30 +175,30 @@ static BOOLEAN EiRemoveSharedOwner(PERESOURCE Resource,
  */
 {
    ULONG i;
-   
+
    if (Resource->OwnerThreads[1].OwnerThread == ResourceThreadId)
      {
-       Resource->OwnerThreads[1].OwnerCount--;
-       if (Resource->OwnerThreads[1].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].TableSize; i++)
      {
        if (Resource->OwnerTable[i].OwnerThread == ResourceThreadId)
          {
-            Resource->OwnerTable[i].OwnerCount--;
-            if (Resource->OwnerTable[i].OwnerCount == 0)
+         Resource->OwnerTable[i].OwnerCount--;
+         if (Resource->OwnerTable[i].OwnerCount == 0)
               {
                  Resource->ActiveCount--;
                  Resource->OwnerTable[i].OwnerThread = 0;
@@ -209,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].OwnerCount = 1;
+    Resource->OwnerThreads[1].OwnerCount = 1;
        if (Resource->OwnerTable != NULL)
          {
             ExFreePool(Resource->OwnerTable);
@@ -226,51 +238,51 @@ 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 = 
-         ExAllocatePoolWithTag(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,0,sizeof(OWNER_ENTRY)*3);
        memcpy(&Resource->OwnerTable[0], &Resource->OwnerThreads[1],
               sizeof(OWNER_ENTRY));
-       
+
        Resource->OwnerThreads[1].OwnerThread = 0;
-       Resource->OwnerThreads[1].TableSize = 3;
-       
+    Resource->OwnerThreads[1].TableSize = 3;
+
        Resource->OwnerTable[1].OwnerThread = CurrentThread;
-       Resource->OwnerTable[1].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].TableSize);
-   
+
+   DPRINT("Number of entries %d\n",
+      Resource->OwnerThreads[1].TableSize);
+
    freeEntry = NULL;
    for (i=0; i<Resource->OwnerThreads[1].TableSize; i++)
      {
        if (Resource->OwnerTable[i].OwnerThread == CurrentThread)
          {
             DPRINT("Thread already owns resource\n");
-            Resource->OwnerTable[i].OwnerCount++;
+         Resource->OwnerTable[i].OwnerCount++;
             return(TRUE);
          }
        if (Resource->OwnerTable[i].OwnerThread == 0)
@@ -279,30 +291,30 @@ static BOOLEAN EiAddSharedOwner(PERESOURCE Resource)
             break;
          }
      }
-   
+
    DPRINT("Found free entry %x\n", freeEntry);
-   
+
    if (!freeEntry)
      {
        DPRINT("Allocating new entry\n");
-       
+
        /* reallocate ownertable with one more entry */
-       freeEntry = 
+       freeEntry =
          ExAllocatePoolWithTag(NonPagedPool,
                                sizeof(OWNER_ENTRY)*
-                               (Resource->OwnerThreads[1].TableSize+1),
+                (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].TableSize));
+           sizeof(OWNER_ENTRY)*(Resource->OwnerThreads[1].TableSize));
        ExFreePool(Resource->OwnerTable);
        Resource->OwnerTable=freeEntry;
-       freeEntry=&Resource->OwnerTable[Resource->OwnerThreads[1].TableSize];
-       Resource->OwnerThreads[1].TableSize++;
+    freeEntry=&Resource->OwnerTable[Resource->OwnerThreads[1].TableSize];
+    Resource->OwnerThreads[1].TableSize++;
      }
    DPRINT("Creating entry\n");
    freeEntry->OwnerThread=ExGetCurrentResourceThread();
@@ -311,6 +323,9 @@ static BOOLEAN EiAddSharedOwner(PERESOURCE Resource)
    return(TRUE);
 }
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 ExAcquireResourceSharedLite (
@@ -330,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].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");
@@ -384,13 +411,16 @@ ExAcquireResourceSharedLite (
            Resource->NumberOfSharedWaiters--;
          }
      }
-   
+
    EiAddSharedOwner(Resource);
    KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
    DPRINT("ExAcquireResourceSharedLite() = TRUE\n");
    return(TRUE);
 }
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 ExConvertExclusiveToSharedLite (
@@ -407,21 +437,21 @@ 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].OwnerCount=Resource->OwnerThreads[0].OwnerCount;
@@ -430,7 +460,7 @@ ExConvertExclusiveToSharedLite (
    /* erase exclusive flag */
    Resource->Flag &= (~ResourceOwnedExclusive);
    /* if no shared waiters, that's all */
-   if (!oldWaiters) 
+   if (!oldWaiters)
      {
        KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
        return;
@@ -441,6 +471,9 @@ ExConvertExclusiveToSharedLite (
    DPRINT("ExConvertExclusiveToSharedLite() finished\n");
 }
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 ExDisableResourceBoostLite (
@@ -450,6 +483,9 @@ ExDisableResourceBoostLite (
    Resource->Flag |= ResourceDisableBoost;
 }
 
+/*
+ * @implemented
+ */
 ULONG
 STDCALL
 ExGetExclusiveWaiterCount (
@@ -459,6 +495,9 @@ ExGetExclusiveWaiterCount (
   return(Resource->NumberOfExclusiveWaiters);
 }
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 ExAcquireSharedStarveExclusive (
@@ -479,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].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].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");
@@ -531,6 +570,9 @@ ExAcquireSharedStarveExclusive (
    return(TRUE);
 }
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 ExAcquireSharedWaitForExclusive (
@@ -541,8 +583,15 @@ ExAcquireSharedWaitForExclusive (
   return(ExAcquireResourceSharedLite(Resource,Wait));
 }
 
+
+#ifdef ExDeleteResource
 #undef ExDeleteResource
+#endif
 
+
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 ExDeleteResource (
@@ -552,6 +601,9 @@ ExDeleteResource (
    return(ExDeleteResourceLite(Resource));
 }
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 ExDeleteResourceLite (
@@ -562,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 (
@@ -574,8 +629,14 @@ ExGetSharedWaiterCount (
    return(Resource->NumberOfSharedWaiters);
 }
 
+
+#ifdef ExInitializeResource
 #undef ExInitializeResource
+#endif
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 ExInitializeResource (
@@ -585,6 +646,9 @@ ExInitializeResource (
    return(ExInitializeResourceLite(Resource));
 }
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 ExInitializeResourceLite (PERESOURCE   Resource)
 {
@@ -594,18 +658,21 @@ ExInitializeResourceLite (PERESOURCE      Resource)
    Resource->NumberOfExclusiveWaiters = 0;
    KeInitializeSpinLock(&Resource->SpinLock);
    Resource->Flag = 0;
-   Resource->ExclusiveWaiters = 
+   Resource->ExclusiveWaiters =
      ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_EXCLUSIVE_LOCK);
    KeInitializeEvent(Resource->ExclusiveWaiters,
                     SynchronizationEvent,
                     FALSE);
-   Resource->SharedWaiters = 
+   Resource->SharedWaiters =
      ExAllocatePoolWithTag(NonPagedPool ,sizeof(KSEMAPHORE), TAG_SHARED_SEM);
    KeInitializeSemaphore(Resource->SharedWaiters,0,0x7fffffff);
    Resource->ActiveCount = 0;
    return(0);
 }
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 ExIsResourceAcquiredExclusiveLite (
@@ -624,11 +691,23 @@ ExIsResourceAcquiredExclusiveLite (
          && Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread());
 }
 
-USHORT
-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
@@ -636,18 +715,18 @@ 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].OwnerCount);
+    return (USHORT)(Resource->OwnerThreads[0].OwnerCount);
      }
    if (Resource->OwnerThreads[1].OwnerThread == ExGetCurrentResourceThread())
      {
-       return(Resource->OwnerThreads[1].OwnerCount);
+    return (USHORT)(Resource->OwnerThreads[1].OwnerCount);
      }
-   if (!Resource->OwnerThreads[1].TableSize) 
+   if (!Resource->OwnerThreads[1].TableSize)
      {
        return(0);
      }
@@ -655,12 +734,15 @@ ExIsResourceAcquiredSharedLite (
      {
        if (Resource->OwnerTable[i].OwnerThread==ExGetCurrentResourceThread())
          {
-            return Resource->OwnerTable[i].OwnerCount;
+         return (USHORT)Resource->OwnerTable[i].OwnerCount;
          }
      }
    return(0);
 }
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 ExReinitializeResourceLite (
@@ -675,7 +757,7 @@ ExReinitializeResourceLite (
                     FALSE);
    KeInitializeSemaphore(Resource->SharedWaiters,0,0x7fffffff);
    Resource->ActiveCount = 0;
-   if (Resource->OwnerTable) 
+   if (Resource->OwnerTable)
      {
        ExFreePool(Resource->OwnerTable);
      }
@@ -685,18 +767,29 @@ ExReinitializeResourceLite (
    Resource->OwnerThreads[1].OwnerCount=0;
 }
 
+/*
+ * @implemented
+ */
 VOID
 FASTCALL
 ExReleaseResourceLite (
        PERESOURCE      Resource
        )
 {
-       ExReleaseResourceForThreadLite(Resource,
-               ExGetCurrentResourceThread());
+  ExReleaseResourceForThreadLite(Resource,
+                                       ExGetCurrentResourceThread());
 }
 
+
+
+#ifdef ExReleaseResourceForThread
 #undef ExReleaseResourceForThread
+#endif
+
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 ExReleaseResourceForThread (
@@ -707,6 +800,10 @@ ExReleaseResourceForThread (
   ExReleaseResourceForThreadLite(Resource,ResourceThreadId);
 }
 
+
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 ExReleaseResourceForThreadLite (
@@ -724,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].OwnerCount--;
-       if (Resource->OwnerThreads[0].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");
@@ -772,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 (
@@ -798,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 */