Author: mjmartin
Date: Mon Dec 7 04:50:26 2009
New Revision: 44451
URL:
http://svn.reactos.org/svn/reactos?rev=44451&view=rev
Log:
[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.
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] Mon Dec 7 04:50:26 2009
@@ -5,6 +5,7 @@
* PURPOSE: Process startup for PE executables
* PROGRAMMERS: Jean Michault
* Rex Jolliff (rex(a)lvcablemodem.com)
+ * Michael Martin
*/
/*
@@ -659,9 +660,12 @@
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 @@
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
ULONG len;
+ ULONG ImagePathLen;
DPRINT("LdrpMapDllImageFile() called\n");
if (SearchPath == NULL)
{
/* get application running path */
-
- wcscpy (SearchPathBuffer,
NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer);
-
- len = wcslen (SearchPathBuffer);
-
- while (len && SearchPathBuffer[len - 1] != L'\\')
- len--;
-
- if (len) SearchPathBuffer[len-1] = L'\0';
-
+ ImagePathNameBufferPtr =
NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer;
+
+ /* Length of ImagePathName */
+ ImagePathLen = wcslen(ImagePathNameBufferPtr);
+
+ /* Subtract application name leaveing only the directory length */
+ while (ImagePathLen && ImagePathNameBufferPtr[ImagePathLen - 1] !=
L'\\')
+ ImagePathLen--;
+
+ /* Length of directory + semicolon */
+ len = ImagePathLen + 1;
+
+ /* 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;
}