Author: dchapyshev
Date: Fri May 15 21:48:18 2009
New Revision: 40931

URL: http://svn.reactos.org/svn/reactos?rev=40931&view=rev
Log:
- Add support of additional paths of loading dlls (fixes loading dlls in X-Chat)
See issue #4201 for more details.

Modified:
    trunk/reactos/dll/ntdll/ldr/utils.c

Modified: trunk/reactos/dll/ntdll/ldr/utils.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ldr/utils.c?rev=40931&r1=40930&r2=40931&view=diff
==============================================================================
--- trunk/reactos/dll/ntdll/ldr/utils.c [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/ldr/utils.c [iso-8859-1] Fri May 15 21:48:18 2009
@@ -178,6 +178,108 @@
      }
    LdrpTlsCallback(Module, dwReason);
    return  ((PDLLMAIN_FUNC)Module->EntryPoint)(Module->DllBase, dwReason, 
lpReserved);
+}
+
+static PWSTR
+LdrpQueryAppPaths(IN PCWSTR ImageName)
+{
+    PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    WCHAR SearchPathBuffer[MAX_PATH];
+    UNICODE_STRING ValueNameString;
+    UNICODE_STRING KeyName;
+    WCHAR NameBuffer[256];
+    ULONG KeyInfoSize;
+    ULONG ResultSize;
+    ULONG len;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+    PWSTR Path = NULL;
+
+    swprintf(NameBuffer,
+             
L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\App 
Paths\\%s", ImageName);
+
+    RtlInitUnicodeString(&KeyName, NameBuffer);
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+
+    Status = NtOpenKey(&KeyHandle,
+                       KEY_READ,
+                       &ObjectAttributes);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT ("NtOpenKey() failed (Status %lx)\n", Status);
+        return NULL;
+    }
+
+    KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 256 * sizeof(WCHAR);
+
+    KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, KeyInfoSize);
+    if (KeyInfo == NULL)
+    {
+        DPRINT("RtlAllocateHeap() failed\n");
+        NtClose(KeyHandle);
+        return NULL;
+    }
+
+    RtlInitUnicodeString(&ValueNameString,
+                         L"Path");
+
+    Status = NtQueryValueKey(KeyHandle,
+                             &ValueNameString,
+                             KeyValuePartialInformation,
+                             KeyInfo,
+                             KeyInfoSize,
+                             &ResultSize);
+
+    if (NT_SUCCESS(Status))
+    {
+        RtlCopyMemory(SearchPathBuffer,
+                      &KeyInfo->Data,
+                      KeyInfo->DataLength);
+
+        /* get application running path */
+        wcscat(SearchPathBuffer, L";");
+        wcscat (SearchPathBuffer, 
NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer);
+
+        len = wcslen (SearchPathBuffer);
+
+        while (len && SearchPathBuffer[len - 1] != L'\\')
+            len--;
+
+        if (len) SearchPathBuffer[len-1] = L'\0';
+
+        wcscat (SearchPathBuffer, L";");
+
+        wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot);
+        wcscat (SearchPathBuffer, L"\\system32;");
+        wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot);
+        wcscat (SearchPathBuffer, L";.");
+
+        Path = RtlAllocateHeap(RtlGetProcessHeap(),
+                               0,
+                               wcslen(SearchPathBuffer) * sizeof(WCHAR));
+
+        if (Path == NULL)
+        {
+            DPRINT("RtlAllocateHeap() failed\n");
+            RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
+            NtClose(KeyHandle);
+            return NULL;
+        }
+
+        Path = SearchPathBuffer;
+    }
+
+    RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
+
+    NtClose(KeyHandle);
+
+    return Path;
 }
 
 static NTSTATUS
@@ -1676,6 +1778,7 @@
    NTSTATUS Status;
    PLDR_DATA_TABLE_ENTRY ImportedModule;
    PCHAR ImportedName;
+   PWSTR ModulePath;
    ULONG Size;
 
    DPRINT("LdrFixupImports(SearchPath %S, Module %p)\n", SearchPath, Module);
@@ -1855,12 +1958,22 @@
            ImportedName = (PCHAR)Module->DllBase + 
ImportModuleDirectoryCurrent->Name;
            TRACE_LDR("%wZ imports functions from %s\n", &Module->BaseDllName, 
ImportedName);
 
+           if (SearchPath == NULL)
+           {
+                ModulePath = LdrpQueryAppPaths(Module->BaseDllName.Buffer);
+
+                Status = LdrpGetOrLoadModule(ModulePath, ImportedName, 
&ImportedModule, TRUE);
+                if (ModulePath != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, 
ModulePath);
+                if (NT_SUCCESS(Status)) goto Success;
+           }
+
            Status = LdrpGetOrLoadModule(SearchPath, ImportedName, 
&ImportedModule, TRUE);
            if (!NT_SUCCESS(Status))
              {
                DPRINT1("failed to load %s\n", ImportedName);
                return Status;
              }
+Success:
            if (Module == ImportedModule)
              {
                LdrpDecrementLoadCount(Module, FALSE);

Reply via email to