Author: dchapyshev
Date: Fri Jul 17 17:53:15 2009
New Revision: 42004
URL:
http://svn.reactos.org/svn/reactos?rev=42004&view=rev
Log:
- Implement LOAD_LIBRARY_AS_DATAFILE flag for LoadLibraryExW (based on Wine code).
Modified:
trunk/reactos/dll/win32/kernel32/misc/ldr.c
Modified: trunk/reactos/dll/win32/kernel32/misc/ldr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/ld…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/misc/ldr.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/misc/ldr.c [iso-8859-1] Fri Jul 17 17:53:15 2009
@@ -161,6 +161,49 @@
}
+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 @@
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 @@
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 @@
/* 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);