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=…
==============================================================================
--- 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);