[ros-diffs] [dchapyshev] 42004: - Implement LOAD_LIBRARY_AS_DATAFILE flag for LoadLibraryExW (based on Wine code).

dchapyshev at svn.reactos.org dchapyshev at svn.reactos.org
Fri Jul 17 17:53:15 CEST 2009


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/ldr.c?rev=42004&r1=42003&r2=42004&view=diff
==============================================================================
--- 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);



More information about the Ros-diffs mailing list