Correct DLL loading order and honour the LOAD_WITH_ALTERED_SEARCH_PATH flag.
Modified: trunk/reactos/lib/kernel32/misc/ldr.c

Modified: trunk/reactos/lib/kernel32/misc/ldr.c
--- trunk/reactos/lib/kernel32/misc/ldr.c	2005-03-27 08:29:25 UTC (rev 14342)
+++ trunk/reactos/lib/kernel32/misc/ldr.c	2005-03-27 11:00:41 UTC (rev 14343)
@@ -21,6 +21,70 @@
 
 /* FUNCTIONS ****************************************************************/
 
+/**
+ * @name GetDllLoadPath
+ *
+ * Internal function to compute the load path to use for a given dll.
+ *
+ * @remarks Returned pointer must be freed by caller.
+ */
+
+LPWSTR STDCALL
+GetDllLoadPath(LPCWSTR lpModule)
+{
+        ULONG Pos = 0, Length = 0;
+        PWCHAR EnvironmentBufferW = NULL;
+        LPCWSTR lpModuleEnd = NULL;
+        UNICODE_STRING ModuleName;
+
+	if (lpModule != NULL)
+	{
+		lpModuleEnd = lpModule + wcslen(lpModule);
+	}
+	else
+	{
+	        ModuleName = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName;
+	        lpModule = ModuleName.Buffer;
+	        lpModuleEnd = lpModule + (ModuleName.Length / sizeof(WCHAR));
+	}
+
+	if (lpModule != NULL)
+	{
+	        while (lpModuleEnd > lpModule && *lpModuleEnd != L'/' &&
+	               *lpModuleEnd != L'\\' && *lpModuleEnd != L':')
+			--lpModuleEnd;
+		Length = (lpModuleEnd - lpModule) + 1;		
+	}
+
+	Length += GetCurrentDirectoryW(0, NULL) + 1;
+	Length += GetSystemDirectoryW(NULL, 0) + 1;
+	Length += GetWindowsDirectoryW(NULL, 0) + 1;
+	Length += GetEnvironmentVariableW(L"PATH", NULL, 0) + 1;
+
+	EnvironmentBufferW = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+                                             Length * sizeof(WCHAR));
+	if (EnvironmentBufferW == NULL)
+		return NULL;
+
+	if (lpModule)
+	{
+		RtlCopyMemory(EnvironmentBufferW, lpModule,
+		              (lpModuleEnd - lpModule) * sizeof(WCHAR));
+		Pos += lpModuleEnd - lpModule;
+		EnvironmentBufferW[Pos++] = L';';
+	}
+	Pos += GetCurrentDirectoryW(Length, EnvironmentBufferW + Pos);
+	EnvironmentBufferW[Pos++] = L';';
+	Pos += GetSystemDirectoryW(EnvironmentBufferW + Pos, Length - Pos);
+	EnvironmentBufferW[Pos++] = L';';
+	Pos += GetWindowsDirectoryW(EnvironmentBufferW + Pos, Length - Pos);
+	EnvironmentBufferW[Pos++] = L';';
+	Pos += GetEnvironmentVariableW(L"PATH", EnvironmentBufferW + Pos, Length - Pos);
+	EnvironmentBufferW[Pos] = 0;
+
+	return EnvironmentBufferW;
+}
+
 /*
  * @implemented
  */
@@ -66,40 +130,12 @@
 	DWORD	dwFlags
 	)
 {
-	UNICODE_STRING LibFileNameU;
-	ANSI_STRING LibFileName;
-	HINSTANCE hInst;
-	NTSTATUS Status;
+   PWCHAR FileNameW;
+   
+   if (!(FileNameW = FilenameA2W(lpLibFileName, FALSE)))
+      return FALSE;
 
-        (void)hFile;
-
-	RtlInitAnsiString (&LibFileName,
-	                   (LPSTR)lpLibFileName);
-
-	/* convert ansi (or oem) string to unicode */
-	if (bIsFileApiAnsi)
-		RtlAnsiStringToUnicodeString (&LibFileNameU,
-		                              &LibFileName,
-		                              TRUE);
-	else
-		RtlOemStringToUnicodeString (&LibFileNameU,
-		                             &LibFileName,
-		                             TRUE);
-
-	Status = LdrLoadDll(NULL,
-			    dwFlags,
-			    &LibFileNameU,
-			    (PVOID*)&hInst);
-
-	RtlFreeUnicodeString (&LibFileNameU);
-
-	if ( !NT_SUCCESS(Status))
-	{
-		SetLastErrorByStatus (Status);
-		return NULL;
-	}
-
-	return hInst;
+   return LoadLibraryExW(FileNameW, hFile, dwFlags);
 }
 
 
@@ -130,6 +166,7 @@
 	UNICODE_STRING DllName;
 	HINSTANCE hInst;
 	NTSTATUS Status;
+	PWSTR SearchPath;
 
         (void)hFile;
 
@@ -141,8 +178,11 @@
 	  LOAD_LIBRARY_AS_DATAFILE |
 	  LOAD_WITH_ALTERED_SEARCH_PATH;
 
+	SearchPath = GetDllLoadPath(
+	  dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH ? lpLibFileName : NULL);
+
 	RtlInitUnicodeString (&DllName, (LPWSTR)lpLibFileName);
-	Status = LdrLoadDll(NULL, dwFlags, &DllName, (PVOID*)&hInst);
+	Status = LdrLoadDll(SearchPath, dwFlags, &DllName, (PVOID*)&hInst);
 	if ( !NT_SUCCESS(Status))
 	{
 		SetLastErrorByStatus (Status);