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; }