Alexandre Julliard : ntdll: Use NtAreMappedFilesTheSame() to find duplicated module mappings.
Alexandre Julliard
julliard at winehq.org
Mon Mar 22 17:15:52 CDT 2021
Module: wine
Branch: master
Commit: 0ea5772113684f5884b44cd7e76d45508ef3fbd7
URL: https://source.winehq.org/git/wine.git/?a=commit;h=0ea5772113684f5884b44cd7e76d45508ef3fbd7
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Mar 22 20:38:25 2021 +0100
ntdll: Use NtAreMappedFilesTheSame() to find duplicated module mappings.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/loader.c | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 092c47eac3b..c7e7c86e88f 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1167,6 +1167,8 @@ static WINE_MODREF *alloc_module( HMODULE hModule, const UNICODE_STRING *nt_name
wm->ldr.Flags = LDR_DONT_RESOLVE_REFS | (builtin ? LDR_WINE_INTERNAL : 0);
wm->ldr.TlsIndex = -1;
wm->ldr.LoadCount = 1;
+ wm->ldr.CheckSum = nt->OptionalHeader.CheckSum;
+ wm->ldr.TimeDateStamp = nt->FileHeader.TimeDateStamp;
if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0, nt_name->Length - 3 * sizeof(WCHAR) )))
{
@@ -2274,6 +2276,33 @@ static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, WINE_MODREF **pwm, HANDL
}
+/******************************************************************************
+ * find_existing_module
+ *
+ * Find an existing module that is the same mapping as the new module.
+ */
+static WINE_MODREF *find_existing_module( HMODULE module )
+{
+ WINE_MODREF *wm;
+ LIST_ENTRY *mark, *entry;
+ LDR_DATA_TABLE_ENTRY *mod;
+ IMAGE_NT_HEADERS *nt = RtlImageNtHeader( module );
+
+ if ((wm = get_modref( module ))) return wm;
+
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ for (entry = mark->Flink; entry != mark; entry = entry->Flink)
+ {
+ mod = CONTAINING_RECORD( entry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks );
+ if (mod->TimeDateStamp != nt->FileHeader.TimeDateStamp) continue;
+ if (mod->CheckSum != nt->OptionalHeader.CheckSum) continue;
+ if (NtAreMappedFilesTheSame( mod->DllBase, module ) != STATUS_SUCCESS) continue;
+ return CONTAINING_RECORD( mod, WINE_MODREF, ldr );
+ }
+ return NULL;
+}
+
+
/******************************************************************************
* load_native_dll (internal)
*/
@@ -2351,12 +2380,13 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, UNICODE_STRING *nt_name,
status = unix_funcs->load_builtin_dll( nt_name, &module, &image_info, prefer_native );
if (status) return status;
- if ((*pwm = get_modref( module ))) /* already loaded */
+ if ((*pwm = find_existing_module( module ))) /* already loaded */
{
if ((*pwm)->ldr.LoadCount != -1) (*pwm)->ldr.LoadCount++;
TRACE( "Found %s for %s at %p, count=%d\n",
debugstr_us(&(*pwm)->ldr.FullDllName), debugstr_us(nt_name),
(*pwm)->ldr.DllBase, (*pwm)->ldr.LoadCount);
+ if (module != (*pwm)->ldr.DllBase) NtUnmapViewOfSection( NtCurrentProcess(), module );
return STATUS_SUCCESS;
}
More information about the wine-cvs
mailing list