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... ============================================================================== --- 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);