update for HEAD-2003050101
[reactos.git] / lib / ntdll / ldr / utils.c
index e9cb9ea..151f279 100644 (file)
@@ -227,7 +227,8 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
       *BaseAddress = NtCurrentPeb()->ImageBaseAddress;
       return STATUS_SUCCESS;
     }
-  
+
+
   *BaseAddress = NULL;
   
   DPRINT("LdrLoadDll(Name \"%wZ\" BaseAddress %x)\n",
@@ -417,7 +418,8 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
                                   DLL_PROCESS_ATTACH,
                                   NULL))
             {
-              DPRINT("NTDLL.LDR: DLL \"%wZ\" failed to initialize\n",
+             /* Do this as a DPRINT1 for now, until clean up and fail implemented */
+              DPRINT1("NTDLL.LDR: DLL \"%wZ\" failed to initialize\n",
                      &Module->BaseDllName);
               /* FIXME: should clean up and fail */
             }
@@ -516,6 +518,8 @@ LdrFindEntryForName(PUNICODE_STRING Name,
   PLIST_ENTRY ModuleListHead;
   PLIST_ENTRY Entry;
   PLDR_MODULE ModulePtr;
+  BOOLEAN ContainsPath;
+  unsigned i;
 
   DPRINT("NTDLL.LdrFindEntryForName(Name %wZ)\n", Name);
 
@@ -534,13 +538,22 @@ LdrFindEntryForName(PUNICODE_STRING Name,
       return(STATUS_SUCCESS);
     }
 
+  ContainsPath = (2 <= Name->Length && L':' == Name->Buffer[1]);
+  for (i = 0; ! ContainsPath && i < Name->Length; i++)
+    {
+    ContainsPath = L'\\' == Name->Buffer[i] ||
+                   L'/' == Name->Buffer[i];
+    }
   while (Entry != ModuleListHead)
     {
       ModulePtr = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
 
       DPRINT("Scanning %wZ %wZ\n", &ModulePtr->BaseDllName, Name);
 
-      if (RtlCompareUnicodeString(&ModulePtr->BaseDllName, Name, TRUE) == 0)
+      if ((! ContainsPath &&
+           0 == RtlCompareUnicodeString(&ModulePtr->BaseDllName, Name, TRUE)) ||
+          (ContainsPath &&
+           0 == RtlCompareUnicodeString(&ModulePtr->FullDllName, Name, TRUE)))
         {
           *Module = ModulePtr;
           return(STATUS_SUCCESS);
@@ -659,9 +672,9 @@ LdrGetExportByOrdinal (
         DbgPrint(
                 "LdrGetExportByOrdinal(Ordinal %d) = %x\n",
                 Ordinal,
-                ExFunctions[ExOrdinals[Ordinal - ExportDir->Base]]
+                RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
                 );
-        return(ExFunctions[ExOrdinals[Ordinal - ExportDir->Base]]);
+        return(RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] ));
 }
 
 
@@ -678,6 +691,8 @@ LdrGetExportByOrdinal (
  * REVISIONS
  *
  * NOTE
+ *  AddressOfNames and AddressOfNameOrdinals are paralell tables, 
+ *  both with NumberOfNames entries.
  *
  */
 static PVOID
@@ -697,7 +712,7 @@ LdrGetExportByName(PVOID BaseAddress,
    ULONG ExportDirSize;
    
    DPRINT("LdrGetExportByName %x %s %hu\n", BaseAddress, SymbolName, Hint);
-   
+
    ExportDir = (PIMAGE_EXPORT_DIRECTORY)
      RtlImageDirectoryEntryToData(BaseAddress,
                                   TRUE,
@@ -708,7 +723,15 @@ LdrGetExportByName(PVOID BaseAddress,
         DbgPrint("LdrGetExportByName(): no export directory!\n");
         return NULL;
      }
-   
+
+
+   //The symbol names may be missing entirely
+   if (ExportDir->AddressOfNames == 0)
+   {
+      DPRINT("LdrGetExportByName(): symbol names missing entirely\n");  
+      return NULL;
+   }
+
    /*
     * Get header pointers
     */
@@ -722,7 +745,7 @@ LdrGetExportByName(PVOID BaseAddress,
    /*
     * Check the hint first
     */
-   if (Hint < ExportDir->NumberOfFunctions)
+   if (Hint < ExportDir->NumberOfNames)
      {
         ExName = RVA(BaseAddress, ExNames[Hint]);
         if (strcmp(ExName, SymbolName) == 0)
@@ -744,7 +767,7 @@ LdrGetExportByName(PVOID BaseAddress,
     * Try a binary search first
     */
    minn = 0;
-   maxn = ExportDir->NumberOfFunctions;
+   maxn = ExportDir->NumberOfNames;
    while (minn <= maxn)
      {
         ULONG mid;
@@ -786,7 +809,7 @@ LdrGetExportByName(PVOID BaseAddress,
     * Fall back on a linear search
     */
    DPRINT("LdrGetExportByName(): Falling back on a linear search of export table\n");
-   for (i = 0; i < ExportDir->NumberOfFunctions; i++)
+   for (i = 0; i < ExportDir->NumberOfNames; i++)
      {
         ExName = RVA(BaseAddress, ExNames[i]);
         if (strcmp(ExName,SymbolName) == 0)
@@ -838,6 +861,7 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS        NTHeaders,
   int                   i;
   PIMAGE_DATA_DIRECTORY RelocationDDir;
   ULONG OldProtect;
+  ULONG OldProtect2;
   NTSTATUS Status;
   PIMAGE_SECTION_HEADER Sections;
   ULONG MaxExtend;
@@ -860,7 +884,7 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS        NTHeaders,
   RelocationDDir = 
     &NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
   RelocationRVA = RelocationDDir->VirtualAddress;
-   
+
   if (RelocationRVA)
     {
       RelocationDir = 
@@ -895,6 +919,27 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS        NTHeaders,
               DPRINT1("Failed to unprotect relocation target.\n");
               return(Status);
             }
+
+          if (RelocationDir->VirtualAddress + PAGE_SIZE < MaxExtend)
+            {
+                 Status = NtProtectVirtualMemory(NtCurrentProcess(),
+                                                 ImageBase + 
+                                                 RelocationDir->VirtualAddress + PAGE_SIZE,
+                                                 PAGE_SIZE,
+                                                 PAGE_READWRITE,
+                                                 &OldProtect2);
+                 if (!NT_SUCCESS(Status))
+                   {
+                     DPRINT1("Failed to unprotect relocation target (2).\n");
+                  NtProtectVirtualMemory(NtCurrentProcess(),
+                                        ImageBase + 
+                                        RelocationDir->VirtualAddress,
+                                        PAGE_SIZE,
+                                        OldProtect,
+                                        &OldProtect);
+                     return(Status);
+                   }
+              }
                 
           for (i = 0; i < NumberOfEntries; i++)
             {
@@ -948,6 +993,21 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS        NTHeaders,
               return(Status);
             }
 
+          if (RelocationDir->VirtualAddress + PAGE_SIZE < MaxExtend)
+            {
+                 Status = NtProtectVirtualMemory(NtCurrentProcess(),
+                                                 ImageBase + 
+                                                 RelocationDir->VirtualAddress + PAGE_SIZE,
+                                                 PAGE_SIZE,
+                                                 OldProtect2,
+                                                 &OldProtect2);
+                 if (!NT_SUCCESS(Status))
+                   {
+                     DPRINT1("Failed to protect relocation target2.\n");
+                     return(Status);
+                   }
+            }
+
           RelocationRVA += RelocationDir->SizeOfBlock;
           RelocationDir = 
             (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA);
@@ -1032,7 +1092,7 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS       NTHeaders,
         /*
          * Get the import address list.
          */
-        ImportAddressList = (PVOID *)(NTHeaders->OptionalHeader.ImageBase
+        ImportAddressList = (PVOID *)(ImageBase
                         + ImportModuleDirectory->dwRVAFunctionAddressList);
         
         /*
@@ -1685,7 +1745,7 @@ LdrGetProcedureAddress (IN PVOID BaseAddress,
                   return STATUS_SUCCESS;
                }
           }
-        DbgPrint("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
+        DPRINT("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
      }
    else
      {
@@ -1696,7 +1756,7 @@ LdrGetProcedureAddress (IN PVOID BaseAddress,
              *ProcedureAddress = (PVOID)((ULONG)BaseAddress + (ULONG)AddressPtr[Ordinal - ExportDir->Base]);
              return STATUS_SUCCESS;
           }
-        DbgPrint("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal);
+        DPRINT("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal);
   }
 
    return STATUS_PROCEDURE_NOT_FOUND;