implemented sweeping of handle tables
[reactos.git] / reactos / ntoskrnl / rtl / libsupp.c
index 944a1a5..d966de6 100644 (file)
@@ -1,32 +1,65 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/rtl/libsupp.c
- * PURPOSE:         Rtl library support routines
- *
- * PROGRAMMERS:     No programmer listed.
+ * PURPOSE:         RTL Support Routines
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  Gunnar Dalsnes
  */
 
 /* INCLUDES ******************************************************************/
 
 #include <ntoskrnl.h>
-#include <internal/ps.h>
 #define NDEBUG
 #include <internal/debug.h>
 
-//FIXME: sort this out somehow. IAI: Sorted in new header branch
-#define PRTL_CRITICAL_SECTION PVOID
+extern ULONG NtGlobalFlag;
 
 /* FUNCTIONS *****************************************************************/
 
+BOOLEAN
+NTAPI
+RtlpCheckForActiveDebugger(BOOLEAN Type)
+{
+    /* This check is meaningless in kernel-mode */
+    return Type;
+}
+
+BOOLEAN
+NTAPI
+RtlpSetInDbgPrint(IN BOOLEAN NewValue)
+{
+    /* This check is meaningless in kernel-mode */
+    return FALSE;
+}
 
 KPROCESSOR_MODE
+STDCALL
 RtlpGetMode()
 {
    return KernelMode;
 }
 
+PVOID
+STDCALL
+RtlpAllocateMemory(UINT Bytes,
+                   ULONG Tag)
+{
+    return ExAllocatePoolWithTag(PagedPool,
+                                 (SIZE_T)Bytes,
+                                 Tag);
+}
+
+
+VOID
+STDCALL
+RtlpFreeMemory(PVOID Mem,
+               ULONG Tag)
+{
+    ExFreePoolWithTag(Mem,
+                      Tag);
+}
+
 /*
  * @implemented
  */
@@ -45,6 +78,13 @@ RtlReleasePebLock(VOID)
 
 }
 
+NTSTATUS
+STDCALL
+LdrShutdownThread(VOID)
+{
+    return STATUS_SUCCESS;
+}
+
 
 PPEB
 STDCALL
@@ -55,69 +95,40 @@ RtlpCurrentPeb(VOID)
 
 NTSTATUS
 STDCALL
-RtlDeleteCriticalSection(
+RtlDeleteHeapLock(
     PRTL_CRITICAL_SECTION CriticalSection)
 {
+    KEBUGCHECK(0);
     return STATUS_SUCCESS;
 }
 
-DWORD
-STDCALL
-RtlSetCriticalSectionSpinCount(
-   PRTL_CRITICAL_SECTION CriticalSection,
-   DWORD SpinCount
-   )
-{
-   return 0;
-}
-
 NTSTATUS
 STDCALL
-RtlEnterCriticalSection(
+RtlEnterHeapLock(
     PRTL_CRITICAL_SECTION CriticalSection)
 {
-    ExAcquireFastMutex((PFAST_MUTEX) CriticalSection);
+    KEBUGCHECK(0);
     return STATUS_SUCCESS;
 }
 
 NTSTATUS
 STDCALL
-RtlInitializeCriticalSection(
+RtlInitializeHeapLock(
     PRTL_CRITICAL_SECTION CriticalSection)
 {
-   ExInitializeFastMutex((PFAST_MUTEX)CriticalSection );
+   KEBUGCHECK(0);
    return STATUS_SUCCESS;
 }
 
 NTSTATUS
 STDCALL
-RtlLeaveCriticalSection(
-    PRTL_CRITICAL_SECTION CriticalSection)
-{
-    ExReleaseFastMutex((PFAST_MUTEX) CriticalSection );
-    return STATUS_SUCCESS;
-}
-
-BOOLEAN
-STDCALL
-RtlTryEnterCriticalSection(
+RtlLeaveHeapLock(
     PRTL_CRITICAL_SECTION CriticalSection)
 {
-    return ExTryToAcquireFastMutex((PFAST_MUTEX) CriticalSection );
-}
-
-
-NTSTATUS
-STDCALL
-RtlInitializeCriticalSectionAndSpinCount(
-    PRTL_CRITICAL_SECTION CriticalSection,
-    ULONG SpinCount)
-{
-    ExInitializeFastMutex((PFAST_MUTEX)CriticalSection );
+    KEBUGCHECK(0);
     return STATUS_SUCCESS;
 }
 
-
 #ifdef DBG
 VOID FASTCALL
 CHECK_PAGED_CODE_RTL(char *file, int line)
@@ -130,6 +141,53 @@ CHECK_PAGED_CODE_RTL(char *file, int line)
 }
 #endif
 
+VOID
+NTAPI
+RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord,
+                      IN PCONTEXT ContextRecord,
+                      IN PVOID ContextData,
+                      IN ULONG Size)
+{
+    /* Check the global flag */
+    if (NtGlobalFlag & FLG_ENABLE_EXCEPTION_LOGGING)
+    {
+        /* FIXME: Log this exception */
+    }
+}
+
+BOOLEAN
+NTAPI
+RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame,
+                            IN ULONG_PTR RegistrationFrameEnd,
+                            IN OUT PULONG_PTR StackLow,
+                            IN OUT PULONG_PTR StackHigh)
+{
+    PKPRCB Prcb;
+    ULONG_PTR DpcStack;
+
+    /* Check if we are at DISPATCH or higher */
+    if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
+    {
+        /* Get the PRCB and DPC Stack */
+        Prcb = KeGetCurrentPrcb();
+        DpcStack = (ULONG_PTR)Prcb->DpcStack;
+
+        /* Check if we are in a DPC and the stack matches */
+        if ((Prcb->DpcRoutineActive) &&
+            (RegistrationFrameEnd <= DpcStack) &&
+            ((ULONG_PTR)RegistrationFrame >= DpcStack - 4096))
+        {
+            /* Update the limits to the DPC Stack's */
+            *StackHigh = DpcStack;
+            *StackLow = DpcStack - 4096;
+            return TRUE;
+        }
+    }
+
+    /* Not in DPC stack */
+    return FALSE;
+}
+
 /* RTL Atom Tables ************************************************************/
 
 NTSTATUS
@@ -167,23 +225,15 @@ RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
    return (AtomTable->ExHandleTable != NULL);
 }
 
-static VOID STDCALL
-AtomDeleteHandleCallback(PHANDLE_TABLE HandleTable,
-                         PVOID Object,
-                         ULONG GrantedAccess,
-                         PVOID Context)
-{
-   return;
-}
-
 VOID
 RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
 {
    if (AtomTable->ExHandleTable)
    {
-      ExDestroyHandleTable(AtomTable->ExHandleTable,
-                           AtomDeleteHandleCallback,
-                           AtomTable);
+      ExSweepHandleTable(AtomTable->ExHandleTable,
+                         NULL,
+                         NULL);
+      ExDestroyHandleTable(AtomTable->ExHandleTable);
       AtomTable->ExHandleTable = NULL;
    }
 }
@@ -232,33 +282,35 @@ VOID
 RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
 {
    ExDestroyHandle(AtomTable->ExHandleTable,
-                   (LONG)Entry->HandleIndex);
+                   (HANDLE)((ULONG_PTR)Entry->HandleIndex << 2));
 }
 
 BOOLEAN
 RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
 {
    HANDLE_TABLE_ENTRY ExEntry;
-   LONG HandleIndex;
+   HANDLE Handle;
+   USHORT HandleIndex;
    
    ExEntry.u1.Object = Entry;
    ExEntry.u2.GrantedAccess = 0x1; /* FIXME - valid handle */
    
-   HandleIndex = ExCreateHandle(AtomTable->ExHandleTable,
+   Handle = ExCreateHandle(AtomTable->ExHandleTable,
                                 &ExEntry);
-   if (HandleIndex != 0)
+   if (Handle != NULL)
    {
+      HandleIndex = (USHORT)((ULONG_PTR)Handle >> 2);
       /* FIXME - Handle Indexes >= 0xC000 ?! */
-      if (HandleIndex < 0xC000)
+      if ((ULONG_PTR)HandleIndex >> 2 < 0xC000)
       {
-         Entry->HandleIndex = (USHORT)HandleIndex;
-         Entry->Atom = 0xC000 + (USHORT)HandleIndex;
+         Entry->HandleIndex = HandleIndex;
+         Entry->Atom = 0xC000 + HandleIndex;
          
          return TRUE;
       }
       else
          ExDestroyHandle(AtomTable->ExHandleTable,
-                         HandleIndex);
+                         Handle);
    }
    
    return FALSE;
@@ -268,21 +320,47 @@ PRTL_ATOM_TABLE_ENTRY
 RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index)
 {
    PHANDLE_TABLE_ENTRY ExEntry;
+   PRTL_ATOM_TABLE_ENTRY Entry = NULL;
+   
+   /* NOTE: There's no need to explicitly enter a critical region because it's
+            guaranteed that we're in a critical region right now (as we hold
+            the atom table lock) */
    
    ExEntry = ExMapHandleToPointer(AtomTable->ExHandleTable,
-                                  (LONG)Index);
+                                  (HANDLE)((ULONG_PTR)Index << 2));
    if (ExEntry != NULL)
    {
-      PRTL_ATOM_TABLE_ENTRY Entry;
-      
       Entry = ExEntry->u1.Object;
       
       ExUnlockHandleTableEntry(AtomTable->ExHandleTable,
                                ExEntry);
-      return Entry;
    }
    
-   return NULL;
+   return Entry;
+}
+
+/* FIXME - RtlpCreateUnicodeString is obsolete and should be removed ASAP! */
+BOOLEAN FASTCALL
+RtlpCreateUnicodeString(
+   IN OUT PUNICODE_STRING UniDest,
+   IN PCWSTR  Source,
+   IN POOL_TYPE PoolType)
+{
+   ULONG Length;
+
+   Length = (wcslen (Source) + 1) * sizeof(WCHAR);
+   UniDest->Buffer = ExAllocatePoolWithTag(PoolType, Length, TAG('U', 'S', 'T', 'R'));
+   if (UniDest->Buffer == NULL)
+      return FALSE;
+
+   RtlCopyMemory (UniDest->Buffer,
+                  Source,
+                  Length);
+
+   UniDest->MaximumLength = Length;
+   UniDest->Length = Length - sizeof (WCHAR);
+
+   return TRUE;
 }
 
 /* EOF */