[RTL]
[reactos.git] / reactos / lib / rtl / handle.c
index 241a8c3..7e884dc 100644 (file)
@@ -2,7 +2,7 @@
  * PROJECT:         ReactOS system libraries
  * PURPOSE:         Handle table
  * FILE:            lib/rtl/handle.c
- * PROGRAMER:       Eric Kohl
+ * PROGRAMMER:      Eric Kohl
  */
 
 /* INCLUDES *****************************************************************/
 
 /* GLOBALS ******************************************************************/
 
-VOID NTAPI
-RtlInitializeHandleTable(ULONG TableSize,
-                        ULONG HandleSize,
-                        PRTL_HANDLE_TABLE HandleTable)
+VOID
+NTAPI
+RtlInitializeHandleTable(
+    ULONG TableSize,
+    ULONG HandleSize,
+    PRTL_HANDLE_TABLE HandleTable)
 {
-   /* initialize handle table */
-   memset(HandleTable,
-         0,
-         sizeof(RTL_HANDLE_TABLE));
-   HandleTable->MaximumNumberOfHandles = TableSize;
-   HandleTable->SizeOfHandleTableEntry = HandleSize;
+    /* Initialize handle table */
+    memset(HandleTable, 0, sizeof(RTL_HANDLE_TABLE));
+    HandleTable->MaximumNumberOfHandles = TableSize;
+    HandleTable->SizeOfHandleTableEntry = HandleSize;
 }
 
 
 /*
  * @implemented
  */
-VOID NTAPI
-RtlDestroyHandleTable(PRTL_HANDLE_TABLE HandleTable)
+VOID
+NTAPI
+RtlDestroyHandleTable(
+    PRTL_HANDLE_TABLE HandleTable)
 {
-   PVOID ArrayPointer;
-   SIZE_T ArraySize;
+    PVOID ArrayPointer;
+    SIZE_T ArraySize = 0;
 
-   /* free handle array */
-   if (HandleTable->CommittedHandles)
-     {
+    /* free handle array */
+    if (HandleTable->CommittedHandles)
+    {
         ArrayPointer = (PVOID)HandleTable->CommittedHandles;
-        ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
         NtFreeVirtualMemory(NtCurrentProcess(),
-                           &ArrayPointer,
-                           &ArraySize,
-                           MEM_RELEASE);
-     }
+                            &ArrayPointer,
+                            &ArraySize,
+                            MEM_RELEASE);
+    }
 }
 
 
 /*
  * @implemented
  */
-PRTL_HANDLE_TABLE_ENTRY NTAPI
-RtlAllocateHandle(PRTL_HANDLE_TABLE HandleTable,
-                 PULONG Index)
+PRTL_HANDLE_TABLE_ENTRY
+NTAPI
+RtlAllocateHandle(
+    PRTL_HANDLE_TABLE HandleTable,
+    PULONG Index)
 {
-   PRTL_HANDLE_TABLE_ENTRY *pp_new, *pph, ph;
-   NTSTATUS Status;
-   PRTL_HANDLE_TABLE_ENTRY retval;
-   PVOID ArrayPointer;
-   SIZE_T ArraySize;
-
-   pp_new = &HandleTable->FreeHandles;
-
-   if (HandleTable->FreeHandles == NULL)
-     {
-       /* no free handle available */
-       if (HandleTable->UnCommittedHandles == NULL)
-         {
-            /* allocate handle array */
-            ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
-            ArrayPointer = NULL;
-
-            /* FIXME - only reserve handles here! */
-            Status = NtAllocateVirtualMemory(NtCurrentProcess(),
-                                             (PVOID*)&ArrayPointer,
-                                             0,
-                                             &ArraySize,
-                                             MEM_RESERVE | MEM_COMMIT,
-                                             PAGE_READWRITE);
-            if (!NT_SUCCESS(Status))
-              return NULL;
-
-            /* update handle array pointers */
-            HandleTable->FreeHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
-            HandleTable->MaxReservedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);
-            HandleTable->CommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
-            HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
-         }
-
-        /* FIXME - should check if handles need to be committed */
-
-       /* build free list in handle array */
-       ph = HandleTable->FreeHandles;
-       pph = pp_new;
-       while (ph < HandleTable->MaxReservedHandles)
-         {
-            *pph = ph;
-            pph = &ph->NextFree;
-            ph = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ph + HandleTable->SizeOfHandleTableEntry);
-         }
-       *pph = 0;
-     }
-
-   /* remove handle from free list */
-   retval = *pp_new;
-   *pp_new = retval->NextFree;
-   retval->NextFree = NULL;
-
-   if (Index)
-     *Index = ((ULONG)((ULONG_PTR)retval - (ULONG_PTR)HandleTable->CommittedHandles) /
-               HandleTable->SizeOfHandleTableEntry);
-
-   return retval;
+    PRTL_HANDLE_TABLE_ENTRY CurrentEntry, NextEntry;
+    NTSTATUS Status;
+    PRTL_HANDLE_TABLE_ENTRY HandleEntry;
+    PVOID ArrayPointer;
+    SIZE_T ArraySize;
+    ULONG i, NumberOfEntries;
+
+    /* Check if we are out of free handles entries */
+    if (HandleTable->FreeHandles == NULL)
+    {
+        /* Check if we don't have uncomitted handle entries yet */
+        if (HandleTable->UnCommittedHandles == NULL)
+        {
+            /* Use the maximum number of handle entries */
+            ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
+            ArrayPointer = NULL;
+
+            /* Reserve memory */
+            Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+                                             &ArrayPointer,
+                                             0,
+                                             &ArraySize,
+                                             MEM_RESERVE,
+                                             PAGE_READWRITE);
+            if (!NT_SUCCESS(Status))
+                return NULL;
+
+            /* Update handle array pointers */
+            HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
+            HandleTable->MaxReservedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);
+        }
+
+        /* Commit one reserved handle entry page */
+        ArraySize = PAGE_SIZE;
+        ArrayPointer = HandleTable->UnCommittedHandles;
+        Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+                                         &ArrayPointer,
+                                         0,
+                                         &ArraySize,
+                                         MEM_COMMIT,
+                                         PAGE_READWRITE);
+        if (!NT_SUCCESS(Status))
+            return NULL;
+
+        /* Update handle array pointers */
+        HandleTable->FreeHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
+        HandleTable->CommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
+        HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);
+
+        /* Calculate the number of entries we can store in the array */
+        NumberOfEntries = ArraySize / HandleTable->SizeOfHandleTableEntry;
+
+        /* Loop all entries, except the last one */
+        CurrentEntry = HandleTable->FreeHandles;
+        for (i = 0; i < NumberOfEntries - 1; i++)
+        {
+            /* Calculate the address of the next handle entry */
+            NextEntry = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)CurrentEntry +
+                                                  HandleTable->SizeOfHandleTableEntry);
+
+            /* Link the next entry */
+            CurrentEntry->NextFree = NextEntry;
+
+            /* Continue with the next entry */
+            CurrentEntry = NextEntry;
+        }
+
+        /* CurrentEntry now points to the last entry, terminate the list here */
+        CurrentEntry->NextFree = NULL;
+    }
+
+    /* remove handle from free list */
+    HandleEntry = HandleTable->FreeHandles;
+    HandleTable->FreeHandles = HandleEntry->NextFree;
+    HandleEntry->NextFree = NULL;
+
+    if (Index)
+    {
+        *Index = ((ULONG)((ULONG_PTR)HandleEntry - (ULONG_PTR)HandleTable->CommittedHandles) /
+                  HandleTable->SizeOfHandleTableEntry);
+    }
+
+    return HandleEntry;
 }
 
 
 /*
  * @implemented
  */
-BOOLEAN NTAPI
-RtlFreeHandle(PRTL_HANDLE_TABLE HandleTable,
-             PRTL_HANDLE_TABLE_ENTRY Handle)
+BOOLEAN
+NTAPI
+RtlFreeHandle(
+    PRTL_HANDLE_TABLE HandleTable,
+    PRTL_HANDLE_TABLE_ENTRY Handle)
 {
 #if DBG
-   /* check if handle is valid */
-   if (!RtlIsValidHandle(HandleTable, Handle))
-   {
-     DPRINT1("Invalid Handle! HandleTable=0x%p, Handle=0x%p, Handle->Flags=0x%x\n",
-             HandleTable, Handle, Handle ? Handle->Flags : 0);
-     return FALSE;
-   }
+    /* check if handle is valid */
+    if (!RtlIsValidHandle(HandleTable, Handle))
+    {
+        DPRINT1("Invalid Handle! HandleTable=0x%p, Handle=0x%p, Handle->Flags=0x%x\n",
+                HandleTable, Handle, Handle ? Handle->Flags : 0);
+        return FALSE;
+    }
 #endif
 
-   /* clear handle */
-   memset(Handle, 0, HandleTable->SizeOfHandleTableEntry);
+    /* clear handle */
+    memset(Handle, 0, HandleTable->SizeOfHandleTableEntry);
 
-   /* add handle to free list */
-   Handle->NextFree = HandleTable->FreeHandles;
-   HandleTable->FreeHandles = Handle;
+    /* add handle to free list */
+    Handle->NextFree = HandleTable->FreeHandles;
+    HandleTable->FreeHandles = Handle;
 
-   return TRUE;
+    return TRUE;
 }
 
 
 /*
  * @implemented
  */
-BOOLEAN NTAPI
-RtlIsValidHandle(PRTL_HANDLE_TABLE HandleTable,
-                PRTL_HANDLE_TABLE_ENTRY Handle)
+BOOLEAN
+NTAPI
+RtlIsValidHandle(
+    PRTL_HANDLE_TABLE HandleTable,
+    PRTL_HANDLE_TABLE_ENTRY Handle)
 {
-   if ((HandleTable != NULL)
-       && (Handle >= HandleTable->CommittedHandles)
-       && (Handle < HandleTable->MaxReservedHandles)
-       && (Handle->Flags & RTL_HANDLE_VALID))
-     return TRUE;
-   return FALSE;
+    if ((HandleTable != NULL)
+            && (Handle >= HandleTable->CommittedHandles)
+            && (Handle < HandleTable->MaxReservedHandles)
+            && (Handle->Flags & RTL_HANDLE_VALID))
+    {
+        return TRUE;
+    }
+    return FALSE;
 }
 
 
 /*
  * @implemented
  */
-BOOLEAN NTAPI
-RtlIsValidIndexHandle(IN PRTL_HANDLE_TABLE HandleTable,
-                     IN ULONG Index,
-                     OUT PRTL_HANDLE_TABLE_ENTRY *Handle)
+BOOLEAN
+NTAPI
+RtlIsValidIndexHandle(
+    IN PRTL_HANDLE_TABLE HandleTable,
+    IN ULONG Index,
+    OUT PRTL_HANDLE_TABLE_ENTRY *Handle)
 {
-   PRTL_HANDLE_TABLE_ENTRY InternalHandle;
+    PRTL_HANDLE_TABLE_ENTRY InternalHandle;
 
-   DPRINT("RtlIsValidIndexHandle(HandleTable %p Index 0x%lx Handle %p)\n", HandleTable, Index, Handle);
+    DPRINT("RtlIsValidIndexHandle(HandleTable %p Index 0x%lx Handle %p)\n", HandleTable, Index, Handle);
 
-   if (HandleTable == NULL)
-     return FALSE;
+    if (HandleTable == NULL)
+        return FALSE;
 
-   DPRINT("Handles %p HandleSize 0x%lx\n",
-         HandleTable->CommittedHandles, HandleTable->SizeOfHandleTableEntry);
+    DPRINT("Handles %p HandleSize 0x%lx\n",
+           HandleTable->CommittedHandles, HandleTable->SizeOfHandleTableEntry);
 
-   InternalHandle = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)HandleTable->CommittedHandles +
-                                              (HandleTable->SizeOfHandleTableEntry * Index));
-   if (!RtlIsValidHandle(HandleTable, InternalHandle))
-     return FALSE;
+    InternalHandle = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)HandleTable->CommittedHandles +
+                     (HandleTable->SizeOfHandleTableEntry * Index));
+    if (!RtlIsValidHandle(HandleTable, InternalHandle))
+        return FALSE;
 
-   DPRINT("InternalHandle %p\n", InternalHandle);
+    DPRINT("InternalHandle %p\n", InternalHandle);
 
-   if (Handle != NULL)
-     *Handle = InternalHandle;
+    if (Handle != NULL)
+        *Handle = InternalHandle;
 
-  return TRUE;
+    return TRUE;
 }
 
 /* EOF */