From 376921465e31ae021fe0acfc50901266ee23aebd Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Mon, 7 Dec 2009 03:50:26 +0000 Subject: [PATCH] [dll/ntdll] - LdrpMapDllImageFile: Supported finding and loading dlls from the path environment variable as needed. See MSDN for details. OO 3.0 no longer warns of dlls not found (sal3.dll) and at least allows configuration dialog to work. svn path=/trunk/; revision=44451 --- reactos/dll/ntdll/ldr/utils.c | 76 +++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 8 deletions(-) diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index f1ce796ea72..0d6a4201fd3 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -5,6 +5,7 @@ * PURPOSE: Process startup for PE executables * PROGRAMMERS: Jean Michault * Rex Jolliff (rex@lvcablemodem.com) + * Michael Martin */ /* @@ -659,9 +660,12 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL, IN BOOLEAN MapAsDataFile, OUT PHANDLE SectionHandle) { - WCHAR SearchPathBuffer[MAX_PATH]; + WCHAR *SearchPathBuffer = NULL; + WCHAR *ImagePathNameBufferPtr = NULL; WCHAR DosName[MAX_PATH]; UNICODE_STRING FullNtFileName; + UNICODE_STRING PathEnvironmentVar_U; + UNICODE_STRING PathName_U; OBJECT_ATTRIBUTES FileObjectAttributes; HANDLE FileHandle; char BlockBuffer [1024]; @@ -670,28 +674,84 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL, IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status; ULONG len; + ULONG ImagePathLen; DPRINT("LdrpMapDllImageFile() called\n"); if (SearchPath == NULL) { /* get application running path */ + ImagePathNameBufferPtr = NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer; - wcscpy (SearchPathBuffer, NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer); + /* Length of ImagePathName */ + ImagePathLen = wcslen(ImagePathNameBufferPtr); - len = wcslen (SearchPathBuffer); + /* Subtract application name leaveing only the directory length */ + while (ImagePathLen && ImagePathNameBufferPtr[ImagePathLen - 1] != L'\\') + ImagePathLen--; - while (len && SearchPathBuffer[len - 1] != L'\\') - len--; + /* Length of directory + semicolon */ + len = ImagePathLen + 1; - if (len) SearchPathBuffer[len-1] = L'\0'; + /* Length of SystemRoot + "//system32" + semicolon*/ + len += wcslen(SharedUserData->NtSystemRoot) + 10; + /* Length of SystemRoot + semicolon */ + len += wcslen(SharedUserData->NtSystemRoot) + 1; + RtlInitUnicodeString (&PathName_U, L"PATH"); + PathEnvironmentVar_U.Length = 0; + PathEnvironmentVar_U.MaximumLength = 0; + PathEnvironmentVar_U.Buffer = NULL; + + /* Get the path environment variable */ + Status = RtlQueryEnvironmentVariable_U(NULL, &PathName_U, &PathEnvironmentVar_U); + + /* Check that valid information was returned */ + if ((Status == STATUS_BUFFER_TOO_SMALL) && (PathEnvironmentVar_U.Length > 0)) + { + /* Allocate memory for the path env var */ + PathEnvironmentVar_U.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, PathEnvironmentVar_U.Length + sizeof(WCHAR)); + if (!PathEnvironmentVar_U.Buffer) + { + DPRINT1("Fatal! Out of Memory!!\n"); + return STATUS_NO_MEMORY; + } + PathEnvironmentVar_U.MaximumLength = PathEnvironmentVar_U.Length + sizeof(WCHAR); + + /* Retry */ + Status = RtlQueryEnvironmentVariable_U(NULL, &PathName_U, &PathEnvironmentVar_U); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Unable to get path environment string!\n"); + ASSERT(FALSE); + } + /* Length of path evn var + semicolon */ + len += (PathEnvironmentVar_U.Length / sizeof(WCHAR)) + 1; + } + + /* Allocate the size needed to hold all the above paths + period */ + SearchPathBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, (len + 2) * sizeof(WCHAR)); + if (!SearchPathBuffer) + { + DPRINT1("Fatal! Out of Memory!!\n"); + return STATUS_NO_MEMORY; + } + + wcsncpy(SearchPathBuffer, ImagePathNameBufferPtr, ImagePathLen); wcscat (SearchPathBuffer, L";"); - wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot); wcscat (SearchPathBuffer, L"\\system32;"); wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot); - wcscat (SearchPathBuffer, L";."); + wcscat (SearchPathBuffer, L";"); + + if (PathEnvironmentVar_U.Buffer) + { + wcscat (SearchPathBuffer, PathEnvironmentVar_U.Buffer); + wcscat (SearchPathBuffer, L";"); + RtlFreeHeap(RtlGetProcessHeap(), 0, PathEnvironmentVar_U.Buffer); + } + wcscat (SearchPathBuffer, L"."); SearchPath = SearchPathBuffer; }