Allocate a tem buffer for the module names in LdrpQueryModuleInformation, because...
[reactos.git] / reactos / ntoskrnl / ldr / loader.c
index 9210dc8..0f47e69 100644 (file)
 #define NDEBUG
 #include <internal/debug.h>
 
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, LdrInit1)
+#pragma alloc_text(INIT, LdrInitModuleManagement)
+#pragma alloc_text(INIT, LdrSafePEProcessModule)
+#endif
+
 /* GLOBALS *******************************************************************/
 
 LIST_ENTRY ModuleListHead;
@@ -89,18 +95,23 @@ LdrPEFixupImports ( PLDR_DATA_TABLE_ENTRY Module );
 /* FUNCTIONS *****************************************************************/
 
 VOID
+NTAPI
 LdrInitDebug ( PLOADER_MODULE Module, PWCH Name )
 {
 }
 
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
 LdrInit1 ( VOID )
 {
     /* Hook for KDB on initialization of the loader. */
     KDB_LOADERINIT_HOOK(&NtoskrnlModuleObject, &HalModuleObject);
 }
 
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
 LdrInitModuleManagement ( VOID )
 {
     PIMAGE_NT_HEADERS NtHeader;
@@ -138,6 +149,7 @@ LdrInitModuleManagement ( VOID )
 }
 
 NTSTATUS
+NTAPI
 LdrpLoadImage (
     PUNICODE_STRING DriverName,
     PVOID *ModuleBase,
@@ -175,6 +187,7 @@ LdrpLoadImage (
 
 
 NTSTATUS
+NTAPI
 LdrpUnloadImage ( PVOID ModuleBase )
 {
     return(STATUS_NOT_IMPLEMENTED);
@@ -182,6 +195,7 @@ LdrpUnloadImage ( PVOID ModuleBase )
 
 
 NTSTATUS
+NTAPI
 LdrpLoadAndCallImage ( PUNICODE_STRING ModuleName )
 {
     PDRIVER_INITIALIZE DriverEntry;
@@ -217,6 +231,7 @@ LdrpLoadAndCallImage ( PUNICODE_STRING ModuleName )
 
 
 NTSTATUS
+NTAPI
 LdrLoadModule(
     PUNICODE_STRING Filename,
     PLDR_DATA_TABLE_ENTRY *ModuleObject )
@@ -249,7 +264,7 @@ LdrLoadModule(
     CHECKPOINT;
     if (!NT_SUCCESS(Status))
     {
-        CPRINT("Could not open module file: %wZ\n", Filename);
+        CPRINT("Could not open module file: %wZ (Status 0x%08lx)\n", Filename, Status);
         return(Status);
     }
     CHECKPOINT;
@@ -321,6 +336,7 @@ LdrLoadModule(
 
 
 NTSTATUS
+NTAPI
 LdrUnloadModule ( PLDR_DATA_TABLE_ENTRY ModuleObject )
 {
     KIRQL Irql;
@@ -365,6 +381,7 @@ LdrProcessModule(
 }
 
 NTSTATUS
+NTAPI
 LdrpQueryModuleInformation (
     PVOID Buffer,
     ULONG Size,
@@ -377,6 +394,9 @@ LdrpQueryModuleInformation (
     ANSI_STRING AnsiName;
     PCHAR p;
     KIRQL Irql;
+    PUNICODE_STRING UnicodeName;
+    ULONG tmpBufferSize = 0;
+    PWCHAR tmpNameBuffer;
 
     KeAcquireSpinLock(&ModuleListLock,&Irql);
 
@@ -385,6 +405,8 @@ LdrpQueryModuleInformation (
     while (current_entry != (&ModuleListHead))
     {
         ModuleCount++;
+        current = CONTAINING_RECORD(current_entry,LDR_DATA_TABLE_ENTRY,InLoadOrderModuleList);
+        tmpBufferSize += current->FullDllName.Length + sizeof(WCHAR) + sizeof(UNICODE_STRING);
         current_entry = current_entry->Flink;
     }
 
@@ -397,6 +419,15 @@ LdrpQueryModuleInformation (
         return(STATUS_INFO_LENGTH_MISMATCH);
     }
 
+    /* allocate a temp buffer to store the module names */
+    UnicodeName = ExAllocatePool(NonPagedPool, tmpBufferSize);
+    if (UnicodeName == NULL)
+    {
+        KeReleaseSpinLock(&ModuleListLock, Irql);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+    tmpNameBuffer = (PWCHAR)((ULONG_PTR)UnicodeName + ModuleCount * sizeof(UNICODE_STRING));
+
     /* fill the buffer */
     memset(Buffer, '=', Size);
 
@@ -417,13 +448,25 @@ LdrpQueryModuleInformation (
         Smi->Module[ModuleCount].Index = (USHORT)ModuleCount;
         Smi->Module[ModuleCount].NameLength = 0;
         Smi->Module[ModuleCount].LoadCount = 0; /* FIXME */
+        UnicodeName[ModuleCount].Buffer = tmpNameBuffer;
+        UnicodeName[ModuleCount].MaximumLength = current->FullDllName.Length + sizeof(WCHAR);
+        tmpNameBuffer += UnicodeName[ModuleCount].MaximumLength / sizeof(WCHAR);
+        RtlCopyUnicodeString(&UnicodeName[ModuleCount], &current->FullDllName);
 
+        ModuleCount++;
+        current_entry = current_entry->Flink;
+    }
+
+    KeReleaseSpinLock(&ModuleListLock, Irql);
+
+    for (ModuleCount = 0; ModuleCount < Smi->Count; ModuleCount++)
+    {
         AnsiName.Length = 0;
-        AnsiName.MaximumLength = 256;
+        AnsiName.MaximumLength = 255;
         AnsiName.Buffer = Smi->Module[ModuleCount].ImageName;
-        RtlUnicodeStringToAnsiString(&AnsiName,
-            &current->FullDllName,
-            FALSE);
+        RtlUnicodeStringToAnsiString(&AnsiName, &UnicodeName[ModuleCount], FALSE);
+        AnsiName.Buffer[AnsiName.Length] = 0;
+        Smi->Module[ModuleCount].NameLength = AnsiName.Length;
 
         p = strrchr(AnsiName.Buffer, '\\');
         if (p == NULL)
@@ -435,12 +478,9 @@ LdrpQueryModuleInformation (
             p++;
             Smi->Module[ModuleCount].PathLength = p - AnsiName.Buffer;
         }
-
-        ModuleCount++;
-        current_entry = current_entry->Flink;
     }
 
-    KeReleaseSpinLock(&ModuleListLock, Irql);
+    ExFreePool(UnicodeName);
 
     return(STATUS_SUCCESS);
 }
@@ -542,6 +582,7 @@ LdrpCompareModuleNames (
 }
 
 PLDR_DATA_TABLE_ENTRY
+NTAPI
 LdrGetModuleObject ( PUNICODE_STRING ModuleName )
 {
     PLDR_DATA_TABLE_ENTRY Module;
@@ -870,7 +911,9 @@ LdrPEProcessModule(
 }
 
 
-PVOID INIT_FUNCTION
+PVOID
+INIT_FUNCTION
+NTAPI
 LdrSafePEProcessModule (
     PVOID ModuleLoadBase,
     PVOID DriverBase,
@@ -1116,7 +1159,7 @@ LdrPEPerformRelocations (
 
             /*
             * Don't relocate within the relocation section itself.
-            * GCC/LD generates sometimes relocation records for the relecotion section.
+            * GCC/LD generates sometimes relocation records for the relocation section.
             * This is a bug in GCC/LD.
             */
             if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir ||
@@ -1242,11 +1285,10 @@ LdrPEGetExportByName (
     PDWORD * ExFunctions;
     PDWORD * ExNames;
     USHORT * ExOrdinals;
-    ULONG i;
     PVOID ExName;
     ULONG Ordinal;
     PVOID Function;
-    LONG minn, maxn;
+    LONG minn, maxn, mid, res;
     ULONG ExportDirSize;
 
     DPRINT("LdrPEGetExportByName %x %s %hu\n", BaseAddress, SymbolName, Hint);
@@ -1305,15 +1347,12 @@ LdrPEGetExportByName (
     }
 
     /*
-    * Try a binary search first
+    * Binary search
     */
     minn = 0;
     maxn = ExportDir->NumberOfNames - 1;
     while (minn <= maxn)
     {
-        LONG mid;
-        LONG res;
-
         mid = (minn + maxn) / 2;
 
         ExName = RVA(BaseAddress, ExNames[mid]);
@@ -1338,11 +1377,6 @@ LdrPEGetExportByName (
                 return Function;
             }
         }
-        else if (minn == maxn)
-        {
-            DPRINT("LdrPEGetExportByName(): binary search failed\n");
-            break;
-        }
         else if (res > 0)
         {
             maxn = mid - 1;
@@ -1353,31 +1387,7 @@ LdrPEGetExportByName (
         }
     }
 
-    /*
-    * Fall back on a linear search
-    */
-    DPRINT("LdrPEGetExportByName(): Falling back on a linear search of export table\n");
-    for (i = 0; i < ExportDir->NumberOfNames; i++)
-    {
-        ExName = RVA(BaseAddress, ExNames[i]);
-        if (strcmp(ExName, (PCHAR)SymbolName) == 0)
-        {
-            Ordinal = ExOrdinals[i];
-            Function = RVA(BaseAddress, ExFunctions[Ordinal]);
-            DPRINT("%x %x %x\n", Function, ExportDir, ExportDir + ExportDirSize);
-            if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
-                (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
-            {
-                DPRINT("Forward: %s\n", (PCHAR)Function);
-                Function = LdrPEFixupForward((PCHAR)Function);
-            }
-            if (Function == NULL)
-            {
-                break;
-            }
-            return Function;
-        }
-    }
+    ExName = RVA(BaseAddress, ExNames[mid]);
     DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
     return (PVOID)NULL;
 }
@@ -1408,8 +1418,8 @@ LdrPEGetExportByOrdinal (
         ? RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
         : NULL;
 
-    if (((ULONG)Function >= (ULONG)ExportDir) &&
-        ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
+    if (((ULONG_PTR)Function >= (ULONG_PTR)ExportDir) &&
+        ((ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize))
     {
         DPRINT("Forward: %s\n", (PCHAR)Function);
         Function = LdrPEFixupForward((PCHAR)Function);