Merge trunk head (r43756)
[reactos.git] / reactos / ntoskrnl / rtl / libsupp.c
index 9247ed5..8ff65d5 100644 (file)
@@ -11,7 +11,9 @@
 
 #include <ntoskrnl.h>
 #define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
+
+#define TAG_ATMT 'TotA' /* Atom table */
 
 extern ULONG NtGlobalFlag;
 
@@ -22,9 +24,34 @@ typedef struct _RTL_RANGE_ENTRY
 } RTL_RANGE_ENTRY, *PRTL_RANGE_ENTRY;
 
 PAGED_LOOKASIDE_LIST RtlpRangeListEntryLookasideList;
+SIZE_T RtlpAllocDeallocQueryBufferSize = 128;
 
 /* FUNCTIONS *****************************************************************/
 
+PVOID
+NTAPI
+RtlpLookupModuleBase(
+    PVOID Address)
+{
+    PLDR_DATA_TABLE_ENTRY LdrEntry;
+    BOOLEAN InSystem;
+    PVOID p;
+
+    /* Get the base for this file */
+    if ((ULONG_PTR)Address > (ULONG_PTR)MmHighestUserAddress)
+    {
+        /* We are in kernel */
+        p = KiPcToFileHeader(Address, &LdrEntry, FALSE, &InSystem);
+    }
+    else
+    {
+        /* We are in user land */
+        p = KiRosPcToUserFileHeader(Address, &LdrEntry);
+    }
+
+    return p;
+}
+
 VOID
 NTAPI
 RtlInitializeRangeListPackage(VOID)
@@ -35,16 +62,16 @@ RtlInitializeRangeListPackage(VOID)
                                    NULL,
                                    POOL_COLD_ALLOCATION,
                                    sizeof(RTL_RANGE_ENTRY),
-                                   TAG('R', 'R', 'l', 'e'),
+                                   'elRR',
                                    16);
 }
 
 BOOLEAN
 NTAPI
-RtlpCheckForActiveDebugger(BOOLEAN Type)
+RtlpCheckForActiveDebugger(VOID)
 {
     /* This check is meaningless in kernel-mode */
-    return Type;
+    return FALSE;
 }
 
 BOOLEAN
@@ -56,14 +83,14 @@ RtlpSetInDbgPrint(IN BOOLEAN NewValue)
 }
 
 KPROCESSOR_MODE
-STDCALL
+NTAPI
 RtlpGetMode()
 {
    return KernelMode;
 }
 
 PVOID
-STDCALL
+NTAPI
 RtlpAllocateMemory(ULONG Bytes,
                    ULONG Tag)
 {
@@ -73,19 +100,24 @@ RtlpAllocateMemory(ULONG Bytes,
 }
 
 
+#define TAG_USTR        'RTSU'
+#define TAG_ASTR        'RTSA'
+#define TAG_OSTR        'RTSO'
 VOID
-STDCALL
+NTAPI
 RtlpFreeMemory(PVOID Mem,
                ULONG Tag)
 {
-    ExFreePoolWithTag(Mem,
-                      Tag);
+    if (Tag == TAG_ASTR || Tag == TAG_OSTR || Tag == TAG_USTR)
+        ExFreePool(Mem);
+    else
+        ExFreePoolWithTag(Mem, Tag);
 }
 
 /*
  * @implemented
  */
-VOID STDCALL
+VOID NTAPI
 RtlAcquirePebLock(VOID)
 {
 
@@ -94,14 +126,14 @@ RtlAcquirePebLock(VOID)
 /*
  * @implemented
  */
-VOID STDCALL
+VOID NTAPI
 RtlReleasePebLock(VOID)
 {
 
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 LdrShutdownThread(VOID)
 {
     return STATUS_SUCCESS;
@@ -109,56 +141,56 @@ LdrShutdownThread(VOID)
 
 
 PPEB
-STDCALL
-RtlpCurrentPeb(VOID)
+NTAPI
+RtlGetCurrentPeb(VOID)
 {
    return ((PEPROCESS)(KeGetCurrentThread()->ApcState.Process))->Peb;
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 RtlDeleteHeapLock(
     PRTL_CRITICAL_SECTION CriticalSection)
 {
-    KEBUGCHECK(0);
+    ASSERT(FALSE);
     return STATUS_SUCCESS;
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 RtlEnterHeapLock(
     PRTL_CRITICAL_SECTION CriticalSection)
 {
-    KEBUGCHECK(0);
+    ASSERT(FALSE);
     return STATUS_SUCCESS;
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 RtlInitializeHeapLock(
     PRTL_CRITICAL_SECTION CriticalSection)
 {
-   KEBUGCHECK(0);
+   ASSERT(FALSE);
    return STATUS_SUCCESS;
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 RtlLeaveHeapLock(
     PRTL_CRITICAL_SECTION CriticalSection)
 {
-    KEBUGCHECK(0);
+    ASSERT(FALSE);
     return STATUS_SUCCESS;
 }
 
-#ifdef DBG
+#if DBG
 VOID FASTCALL
 CHECK_PAGED_CODE_RTL(char *file, int line)
 {
   if(KeGetCurrentIrql() > APC_LEVEL)
   {
     DbgPrint("%s:%i: Pagable code called at IRQL > APC_LEVEL (%d)\n", file, line, KeGetCurrentIrql());
-    KEBUGCHECK(0);
+    ASSERT(FALSE);
   }
 }
 #endif
@@ -210,6 +242,8 @@ RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame,
     return FALSE;
 }
 
+#if !defined(_ARM_) && !defined(_AMD64_)
+
 BOOLEAN
 NTAPI
 RtlpCaptureStackLimits(IN ULONG_PTR Ebp,
@@ -220,11 +254,11 @@ RtlpCaptureStackLimits(IN ULONG_PTR Ebp,
 
     /* Don't even try at ISR level or later */
     if (KeGetCurrentIrql() > DISPATCH_LEVEL) return FALSE;
-    
+
     /* Start with defaults */
     *StackBegin = Thread->StackLimit;
     *StackEnd = (ULONG_PTR)Thread->StackBase;
-    
+
     /* Check if EBP is inside the stack */
     if ((*StackBegin <= Ebp) && (Ebp <= *StackEnd))
     {
@@ -236,7 +270,7 @@ RtlpCaptureStackLimits(IN ULONG_PTR Ebp,
         /* Now we're going to assume we're on the DPC stack */
         *StackEnd = (ULONG_PTR)(KeGetPcr()->Prcb->DpcStack);
         *StackBegin = *StackEnd - KERNEL_STACK_SIZE;
-        
+
         /* Check if we seem to be on the DPC stack */
         if ((*StackEnd) && (*StackBegin < Ebp) && (Ebp <= *StackEnd))
         {
@@ -264,14 +298,14 @@ RtlWalkFrameChain(OUT PVOID *Callers,
                   IN ULONG Count,
                   IN ULONG Flags)
 {
-    ULONG_PTR Stack, NewStack, StackBegin, StackEnd;
+    ULONG_PTR Stack, NewStack, StackBegin, StackEnd = 0;
     ULONG Eip;
     BOOLEAN Result, StopSearch = FALSE;
     ULONG i = 0;
     PKTHREAD Thread = KeGetCurrentThread();
     PTEB Teb;
     PKTRAP_FRAME TrapFrame;
-    
+
     /* Get current EBP */
 #if defined(_M_IX86)
 #if defined __GNUC__
@@ -283,13 +317,15 @@ RtlWalkFrameChain(OUT PVOID *Callers,
         __asm__("move $sp, %0" : "=r" (Stack) : );
 #elif defined(_M_PPC)
     __asm__("mr %0,1" : "=r" (Stack) : );
+#elif defined(_M_ARM)
+    __asm__("mov sp, %0" : "=r"(Stack) : );
 #else
 #error Unknown architecture
 #endif
-    
+
     /* Set it as the stack begin limit as well */
     StackBegin = (ULONG_PTR)Stack;
-    
+
     /* Check if we're called for non-logging mode */
     if (!Flags)
     {
@@ -299,23 +335,23 @@ RtlWalkFrameChain(OUT PVOID *Callers,
                                         &StackEnd);
         if (!Result) return 0;
     }
-    
+
     /* Use a SEH block for maximum protection */
-    _SEH_TRY
+    _SEH2_TRY
     {
         /* Check if we want the user-mode stack frame */
         if (Flags == 1)
         {
-            /* Get the trap frame and TEB */          
+            /* Get the trap frame and TEB */
             TrapFrame = Thread->TrapFrame;
             Teb = Thread->Teb;
-            
+
             /* Make sure we can trust the TEB and trap frame */
-            if (!(Teb) || 
-                !((PVOID)((ULONG_PTR)TrapFrame & 0x80000000)) || 
+            if (!(Teb) ||
+                !((PVOID)((ULONG_PTR)TrapFrame & 0x80000000)) ||
                 ((PVOID)TrapFrame <= (PVOID)Thread->StackLimit) ||
                 ((PVOID)TrapFrame >= (PVOID)Thread->StackBase) ||
-                (KeIsAttachedProcess()) || 
+                (KeIsAttachedProcess()) ||
                 (KeGetCurrentIrql() >= DISPATCH_LEVEL))
             {
                 /* Invalid or unsafe attempt to get the stack */
@@ -329,6 +365,8 @@ RtlWalkFrameChain(OUT PVOID *Callers,
             Stack = TrapFrame->Ebp;
 #elif defined(_M_PPC)
             Stack = TrapFrame->Gpr1;
+#else
+#error Unknown architecture
 #endif
 
             /* Validate them */
@@ -337,7 +375,7 @@ RtlWalkFrameChain(OUT PVOID *Callers,
                          StackEnd - StackBegin,
                          sizeof(CHAR));
         }
-        
+
         /* Loop the frames */
         for (i = 0; i < Count; i++)
         {
@@ -353,27 +391,27 @@ RtlWalkFrameChain(OUT PVOID *Callers,
                 /* We're done or hit a bad address */
                 break;
             }
-            
+
             /* Get new stack and EIP */
             NewStack = *(PULONG_PTR)Stack;
             Eip = *(PULONG_PTR)(Stack + sizeof(ULONG_PTR));
-            
+
             /* Check if the new pointer is above the oldone and past the end */
             if (!((Stack < NewStack) && (NewStack < StackEnd)))
             {
                 /* Stop searching after this entry */
                 StopSearch = TRUE;
             }
-            
+
             /* Also make sure that the EIP isn't a stack address */
             if ((StackBegin < Eip) && (Eip < StackEnd)) break;
-            
+
             /* Check if we reached a user-mode address */
             if (!(Flags) && !(Eip & 0x80000000)) break;
-            
+
             /* Save this frame */
             Callers[i] = (PVOID)Eip;
-            
+
             /* Check if we should continue */
             if (StopSearch)
             {
@@ -381,21 +419,36 @@ RtlWalkFrameChain(OUT PVOID *Callers,
                 i++;
                 break;
             }
-            
+
             /* Move to the next stack */
             Stack = NewStack;
         }
     }
-    _SEH_HANDLE
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
         /* No index */
         i = 0;
     }
-    _SEH_END;
-    
+    _SEH2_END;
+
     /* Return frames parsed */
-    return i;    
+    return i;
+}
+
+#endif
+
+#ifdef _AMD64_
+VOID
+NTAPI
+RtlpGetStackLimits(
+    OUT PULONG_PTR LowLimit,
+    OUT PULONG_PTR HighLimit)
+{
+    PKTHREAD CurrentThread = KeGetCurrentThread();
+    *HighLimit = (ULONG_PTR)CurrentThread->InitialStack;
+    *LowLimit = (ULONG_PTR)CurrentThread->StackLimit;
 }
+#endif
 
 /* RTL Atom Tables ************************************************************/
 
@@ -457,7 +510,7 @@ RtlpAllocAtomTable(ULONG Size)
       RtlZeroMemory(Table,
                     Size);
    }
-   
+
    return Table;
 }
 
@@ -470,21 +523,21 @@ RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable)
 PRTL_ATOM_TABLE_ENTRY
 RtlpAllocAtomTableEntry(ULONG Size)
 {
-   PRTL_ATOM_TABLE_ENTRY Entry = ExAllocatePool(NonPagedPool,
-                                                Size);
-   if (Entry != NULL)
-   {
-      RtlZeroMemory(Entry,
-                    Size);
-   }
+    PRTL_ATOM_TABLE_ENTRY Entry;
 
-   return Entry;
+    Entry = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_ATMT);
+    if (Entry != NULL)
+    {
+        RtlZeroMemory(Entry, Size);
+    }
+
+    return Entry;
 }
 
 VOID
 RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry)
 {
-   ExFreePool(Entry);
+    ExFreePoolWithTag(Entry, TAG_ATMT);
 }
 
 VOID
@@ -501,30 +554,37 @@ RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
    HANDLE_TABLE_ENTRY ExEntry;
    HANDLE Handle;
    USHORT HandleIndex;
-   
+
+   /* Initialize ex handle table entry */
    ExEntry.Object = Entry;
    ExEntry.GrantedAccess = 0x1; /* FIXME - valid handle */
-   
+
+   /* Create ex handle */
    Handle = ExCreateHandle(AtomTable->ExHandleTable,
-                                &ExEntry);
-   if (Handle != NULL)
+                           &ExEntry);
+   if (!Handle) return FALSE;
+
+   /* Calculate HandleIndex (by getting rid of the first two bits) */
+   HandleIndex = (USHORT)((ULONG_PTR)Handle >> 2);
+
+   /* Index must be less than 0xC000 */
+   if (HandleIndex >= 0xC000)
    {
-      HandleIndex = (USHORT)((ULONG_PTR)Handle >> 2);
-      /* FIXME - Handle Indexes >= 0xC000 ?! */
-      if ((ULONG_PTR)HandleIndex >> 2 < 0xC000)
-      {
-         Entry->HandleIndex = HandleIndex;
-         Entry->Atom = 0xC000 + HandleIndex;
-         
-         return TRUE;
-      }
-      else
-         ExDestroyHandle(AtomTable->ExHandleTable,
-                         Handle,
-                         NULL);
+       /* Destroy ex handle */
+       ExDestroyHandle(AtomTable->ExHandleTable,
+                       Handle,
+                       NULL);
+
+       /* Return failure */
+       return FALSE;
    }
-   
-   return FALSE;
+
+   /* Initialize atom table entry */
+   Entry->HandleIndex = HandleIndex;
+   Entry->Atom = 0xC000 + HandleIndex;
+
+   /* Return success */
+   return TRUE;
 }
 
 PRTL_ATOM_TABLE_ENTRY
@@ -532,46 +592,22 @@ 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,
                                   (HANDLE)((ULONG_PTR)Index << 2));
    if (ExEntry != NULL)
    {
       Entry = ExEntry->Object;
-      
+
       ExUnlockHandleTableEntry(AtomTable->ExHandleTable,
                                ExEntry);
    }
-   
-   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 = (USHORT)Length;
-   UniDest->Length = (USHORT)Length - sizeof (WCHAR);
-
-   return TRUE;
+   return Entry;
 }
 
 /*