- Implement LOAD_LIBRARY_AS_DATAFILE flag for LoadLibraryExW (based on Wine code).

svn path=/trunk/; revision=42004
This commit is contained in:
Dmitry Chapyshev 2009-07-17 15:53:15 +00:00
parent f86de98c40
commit 0e63dbb11d

View file

@ -161,6 +161,49 @@ LoadLibraryW (
}
static
NTSTATUS
LoadLibraryAsDatafile(PWSTR path, LPCWSTR name, HMODULE* hmod)
{
static const WCHAR dotDLL[] = {'.','d','l','l',0};
WCHAR filenameW[MAX_PATH];
HANDLE hFile = INVALID_HANDLE_VALUE;
HANDLE mapping;
HMODULE module;
*hmod = 0;
if (!SearchPathW( path, name, dotDLL, sizeof(filenameW) / sizeof(filenameW[0]),
filenameW, NULL ))
{
return NtCurrentTeb()->LastStatusValue;
}
hFile = CreateFileW( filenameW, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, 0 );
if (hFile == INVALID_HANDLE_VALUE) return NtCurrentTeb()->LastStatusValue;
mapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
CloseHandle( hFile );
if (!mapping) return NtCurrentTeb()->LastStatusValue;
module = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
CloseHandle( mapping );
if (!module) return NtCurrentTeb()->LastStatusValue;
/* make sure it's a valid PE file */
if (!RtlImageNtHeader(module))
{
UnmapViewOfFile( module );
return STATUS_INVALID_IMAGE_FORMAT;
}
*hmod = (HMODULE)((char *)module + 1); /* set low bit of handle to indicate datafile module */
return STATUS_SUCCESS;
}
/*
* @implemented
*/
@ -200,6 +243,7 @@ LoadLibraryExW (
dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH ? lpLibFileName : NULL);
RtlInitUnicodeString(&DllName, (LPWSTR)lpLibFileName);
if (DllName.Buffer[DllName.Length/sizeof(WCHAR) - 1] == L' ')
{
RtlCreateUnicodeString(&DllName, (LPWSTR)lpLibFileName);
@ -211,6 +255,28 @@ LoadLibraryExW (
DllName.Buffer[DllName.Length/sizeof(WCHAR)] = UNICODE_NULL;
FreeString = TRUE;
}
if (dwFlags & LOAD_LIBRARY_AS_DATAFILE)
{
Status = LdrGetDllHandle(SearchPath, NULL, &DllName, (PVOID*)&hInst);
if (!NT_SUCCESS(Status))
{
/* The method in load_library_as_datafile allows searching for the
* 'native' libraries only
*/
Status = LoadLibraryAsDatafile(SearchPath, DllName.Buffer, &hInst);
RtlFreeUnicodeString(&DllName);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return NULL;
}
return hInst;
}
}
/* HACK!!! FIXME */
if (InWindows)
{
/* Call the API Properly */
@ -224,6 +290,7 @@ LoadLibraryExW (
/* Call the ROS API. NOTE: Don't fix this, I have a patch to merge later. */
Status = LdrLoadDll(SearchPath, &dwFlags, &DllName, (PVOID*)&hInst);
}
RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
if (FreeString)
RtlFreeUnicodeString(&DllName);