mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Correct DLL loading order and honour the LOAD_WITH_ALTERED_SEARCH_PATH flag.
svn path=/trunk/; revision=14343
This commit is contained in:
parent
e332bc75f9
commit
5f113d7735
1 changed files with 74 additions and 34 deletions
|
@ -21,6 +21,70 @@ typedef struct tagLOADPARMS32 {
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* 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
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -66,40 +130,12 @@ LoadLibraryExA (
|
||||||
DWORD dwFlags
|
DWORD dwFlags
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UNICODE_STRING LibFileNameU;
|
PWCHAR FileNameW;
|
||||||
ANSI_STRING LibFileName;
|
|
||||||
HINSTANCE hInst;
|
if (!(FileNameW = FilenameA2W(lpLibFileName, FALSE)))
|
||||||
NTSTATUS Status;
|
return FALSE;
|
||||||
|
|
||||||
(void)hFile;
|
return LoadLibraryExW(FileNameW, hFile, dwFlags);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,6 +166,7 @@ LoadLibraryExW (
|
||||||
UNICODE_STRING DllName;
|
UNICODE_STRING DllName;
|
||||||
HINSTANCE hInst;
|
HINSTANCE hInst;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
PWSTR SearchPath;
|
||||||
|
|
||||||
(void)hFile;
|
(void)hFile;
|
||||||
|
|
||||||
|
@ -141,8 +178,11 @@ LoadLibraryExW (
|
||||||
LOAD_LIBRARY_AS_DATAFILE |
|
LOAD_LIBRARY_AS_DATAFILE |
|
||||||
LOAD_WITH_ALTERED_SEARCH_PATH;
|
LOAD_WITH_ALTERED_SEARCH_PATH;
|
||||||
|
|
||||||
|
SearchPath = GetDllLoadPath(
|
||||||
|
dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH ? lpLibFileName : NULL);
|
||||||
|
|
||||||
RtlInitUnicodeString (&DllName, (LPWSTR)lpLibFileName);
|
RtlInitUnicodeString (&DllName, (LPWSTR)lpLibFileName);
|
||||||
Status = LdrLoadDll(NULL, dwFlags, &DllName, (PVOID*)&hInst);
|
Status = LdrLoadDll(SearchPath, dwFlags, &DllName, (PVOID*)&hInst);
|
||||||
if ( !NT_SUCCESS(Status))
|
if ( !NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
SetLastErrorByStatus (Status);
|
SetLastErrorByStatus (Status);
|
||||||
|
|
Loading…
Reference in a new issue