Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2021
- 83 participants
- 2620 messages
[PATCH] kernel32: Correctly restore protection in set_entry_point().
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
Passing NULL old protection results in VirtualProtect failure.
dlls/kernel32/kernel_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/kernel32/kernel_main.c b/dlls/kernel32/kernel_main.c
index 89394e16430..4467af739e0 100644
--- a/dlls/kernel32/kernel_main.c
+++ b/dlls/kernel32/kernel_main.c
@@ -65,7 +65,7 @@ static void set_entry_point( HMODULE module, const char *name, DWORD rva )
TRACE( "setting %s at %p to %08x\n", name, &functions[ordinal], rva );
VirtualProtect( functions + ordinal, sizeof(*functions), PAGE_READWRITE, &oldprot );
functions[ordinal] = rva;
- VirtualProtect( functions + ordinal, sizeof(*functions), oldprot, NULL );
+ VirtualProtect( functions + ordinal, sizeof(*functions), oldprot, &oldprot );
return;
}
if (res > 0) max = pos - 1;
--
2.31.1
Nov. 2, 2021
Re: [PATCH vkd3d v3 5/6] tests: Test implicit conversions for return statements.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
Nov. 2, 2021
[PATCH] winevulkan: Update to VK spec version 1.2.197.
by Georg Lehmann
Signed-off-by: Georg Lehmann <dadschoorse(a)gmail.com>
---
dlls/winevulkan/make_vulkan | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index 0a22834dc4d..e84442d7a79 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -64,7 +64,7 @@ from enum import Enum
LOGGER = logging.Logger("vulkan")
LOGGER.addHandler(logging.StreamHandler())
-VK_XML_VERSION = "1.2.196"
+VK_XML_VERSION = "1.2.197"
WINE_VK_VERSION = (1, 2)
# Filenames to create.
--
2.33.1
Nov. 2, 2021
[PATCH 5/5] ntdll: Don't add dependencies for system dlls.
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/kernel32/tests/module.c | 4 ++--
dlls/ntdll/loader.c | 17 ++++++++++++++++-
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/tests/module.c b/dlls/kernel32/tests/module.c
index 466ff3e8d38..2ee23595f55 100644
--- a/dlls/kernel32/tests/module.c
+++ b/dlls/kernel32/tests/module.c
@@ -1409,7 +1409,7 @@ static void test_ddag_node(void)
}
mod2 = CONTAINING_RECORD(dep_node->Modules.Flink, LDR_DATA_TABLE_ENTRY, NodeModuleLink);
- todo_wine ok( !lstrcmpW( mod2->BaseDllName.Buffer, expected_exe_dependencies[i].dllname ),
+ ok( !lstrcmpW( mod2->BaseDllName.Buffer, expected_exe_dependencies[i].dllname ),
"Got unexpected module %s.\n", debugstr_w(mod2->BaseDllName.Buffer));
se2 = dep_node->IncomingDependencies.Tail;
@@ -1428,7 +1428,7 @@ static void test_ddag_node(void)
winetest_pop_context();
prev_node = dep_node;
}
- todo_wine ok( se == node->Dependencies.Tail, "Expected end of the list.\n" );
+ ok( se == node->Dependencies.Tail, "Expected end of the list.\n" );
}
START_TEST(module)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index cf188f4395e..0d831488fe8 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -182,6 +182,8 @@ static WINE_MODREF *cached_modref;
static WINE_MODREF *current_modref;
static WINE_MODREF *last_failed_modref;
+static LDR_DDAG_NODE *node_ntdll, *node_kernel32;
+
static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WCHAR *default_ext,
DWORD flags, WINE_MODREF** pwm );
static NTSTATUS process_attach( LDR_DDAG_NODE *node, LPVOID lpReserved );
@@ -1280,7 +1282,10 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
imp = NULL;
status = STATUS_DLL_NOT_FOUND;
}
- else add_module_dependency_after( wm->ldr.DdagNode, imp->ldr.DdagNode, dep_after );
+ else if (!is_import_dll_system( &wm->ldr, &imports[i] ))
+ {
+ add_module_dependency_after( wm->ldr.DdagNode, imp->ldr.DdagNode, dep_after );
+ }
}
current_modref = prev;
if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie );
@@ -2075,6 +2080,7 @@ static void build_ntdll_module(void)
wm = alloc_module( meminfo.AllocationBase, &nt_name, TRUE );
assert( wm );
wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS;
+ node_ntdll = wm->ldr.DdagNode;
if (TRACE_ON(relay)) RELAY_SetupDLL( meminfo.AllocationBase );
}
@@ -4003,6 +4009,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
NtTerminateProcess( GetCurrentProcess(), status );
}
kernel32_handle = kernel32->ldr.DllBase;
+ node_kernel32 = kernel32->ldr.DdagNode;
RtlInitAnsiString( &func_name, "BaseThreadInitThunk" );
if ((status = LdrGetProcedureAddress( kernel32_handle, &func_name,
0, (void **)&pBaseThreadInitThunk )) != STATUS_SUCCESS)
@@ -4052,6 +4059,14 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
if (wm->ldr.ActivationContext)
RtlActivateActivationContext( 0, wm->ldr.ActivationContext, &cookie );
+ if ((status = process_attach( node_ntdll, context ))
+ || (status = process_attach( node_kernel32, context )))
+ {
+ ERR( "Initializing system dll for %s failed, status %x\n",
+ debugstr_w(NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer), status );
+ NtTerminateProcess( GetCurrentProcess(), status );
+ }
+
if ((status = walk_node_dependencies( wm->ldr.DdagNode, context, process_attach )))
{
if (last_failed_modref)
--
2.31.1
Nov. 2, 2021
[PATCH 4/5] ntdll: Factor out is_import_dll_system() function.
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/ntdll/loader.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 3b5d1de0f3e..cf188f4395e 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -585,6 +585,16 @@ static WINE_MODREF *find_fileid_module( const struct file_id *id )
return NULL;
}
+/***********************************************************************
+ * is_import_dll_system
+ */
+static BOOL is_import_dll_system( LDR_DATA_TABLE_ENTRY *mod, const IMAGE_IMPORT_DESCRIPTOR *import )
+{
+ const char *name = get_rva( mod->DllBase, import->Name );
+
+ return !strcmp( name, "ntdll.dll" ) || !strcmp( name, "kernel32.dll" );
+}
+
/**********************************************************************
* insert_single_list_tail
*/
@@ -1066,7 +1076,6 @@ static BOOL is_dll_native_subsystem( LDR_DATA_TABLE_ENTRY *mod, const IMAGE_NT_H
{
const IMAGE_IMPORT_DESCRIPTOR *imports;
DWORD i, size;
- WCHAR buffer[16];
if (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_NATIVE) return FALSE;
if (nt->OptionalHeader.SectionAlignment < page_size) return TRUE;
@@ -1076,17 +1085,11 @@ static BOOL is_dll_native_subsystem( LDR_DATA_TABLE_ENTRY *mod, const IMAGE_NT_H
IMAGE_DIRECTORY_ENTRY_IMPORT, &size )))
{
for (i = 0; imports[i].Name; i++)
- {
- const char *name = get_rva( mod->DllBase, imports[i].Name );
- DWORD len = strlen(name);
- if (len * sizeof(WCHAR) >= sizeof(buffer)) continue;
- ascii_to_unicode( buffer, name, len + 1 );
- if (!wcsicmp( buffer, L"ntdll.dll" ) || !wcsicmp( buffer, L"kernel32.dll" ))
+ if (is_import_dll_system( mod, &imports[i] ))
{
- TRACE( "%s imports %s, assuming not native\n", debugstr_w(filename), debugstr_w(buffer) );
+ TRACE( "%s imports system dll, assuming not native\n", debugstr_w(filename) );
return FALSE;
}
- }
}
return TRUE;
}
--
2.31.1
Nov. 2, 2021
[PATCH 3/5] ntdll: Store module dependencies in DDAG structure.
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/kernel32/tests/module.c | 12 +--
dlls/ntdll/loader.c | 201 +++++++++++++++++++++++++----------
include/winternl.h | 4 +-
3 files changed, 152 insertions(+), 65 deletions(-)
diff --git a/dlls/kernel32/tests/module.c b/dlls/kernel32/tests/module.c
index 7c4b690fb39..466ff3e8d38 100644
--- a/dlls/kernel32/tests/module.c
+++ b/dlls/kernel32/tests/module.c
@@ -1376,14 +1376,14 @@ static void test_ddag_node(void)
ok( !node->IncomingDependencies.Tail, "Expected empty incoming dependencies list.\n" );
/* node->Dependencies.Tail is NULL on Windows 10 1507-1607 32 bit test, maybe due to broken structure layout. */
- todo_wine ok( !!node->Dependencies.Tail || broken( sizeof(void *) == 4 && !node->Dependencies.Tail ),
+ ok( !!node->Dependencies.Tail || broken( sizeof(void *) == 4 && !node->Dependencies.Tail ),
"Expected nonempty dependencies list.\n" );
if (!node->Dependencies.Tail)
{
- skip( "Empty dependencies list.\n" );
+ win_skip( "Empty dependencies list.\n" );
return;
}
- ok( node->LoadCount == -1, "Got unexpected LoadCount %d.\n", node->LoadCount );
+ todo_wine ok( node->LoadCount == -1, "Got unexpected LoadCount %d.\n", node->LoadCount );
prev_node = NULL;
se = node->Dependencies.Tail;
@@ -1409,7 +1409,7 @@ static void test_ddag_node(void)
}
mod2 = CONTAINING_RECORD(dep_node->Modules.Flink, LDR_DATA_TABLE_ENTRY, NodeModuleLink);
- ok( !lstrcmpW( mod2->BaseDllName.Buffer, expected_exe_dependencies[i].dllname ),
+ todo_wine ok( !lstrcmpW( mod2->BaseDllName.Buffer, expected_exe_dependencies[i].dllname ),
"Got unexpected module %s.\n", debugstr_w(mod2->BaseDllName.Buffer));
se2 = dep_node->IncomingDependencies.Tail;
@@ -1422,13 +1422,13 @@ static void test_ddag_node(void)
while (dep2 != dep && se2 != dep_node->IncomingDependencies.Tail);
ok( dep2 == dep, "Dependency not found in incoming deps list.\n" );
- ok( dep_node->LoadCount > 0 || broken(!dep_node->LoadCount) /* Win8 */,
+ todo_wine ok( dep_node->LoadCount > 0 || broken(!dep_node->LoadCount) /* Win8 */,
"Got unexpected LoadCount %d.\n", dep_node->LoadCount );
winetest_pop_context();
prev_node = dep_node;
}
- ok( se == node->Dependencies.Tail, "Expected end of the list.\n" );
+ todo_wine ok( se == node->Dependencies.Tail, "Expected end of the list.\n" );
}
START_TEST(module)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 23f5a982798..3b5d1de0f3e 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -133,9 +133,6 @@ typedef struct _wine_modref
{
LDR_DATA_TABLE_ENTRY ldr;
struct file_id id;
- int alloc_deps;
- int nDeps;
- struct _wine_modref **deps;
ULONG CheckSum;
} WINE_MODREF;
@@ -588,26 +585,112 @@ static WINE_MODREF *find_fileid_module( const struct file_id *id )
return NULL;
}
+/**********************************************************************
+ * insert_single_list_tail
+ */
+static void insert_single_list_after( LDRP_CSLIST *list, SINGLE_LIST_ENTRY *prev, SINGLE_LIST_ENTRY *entry )
+{
+ if (!list->Tail)
+ {
+ assert( !prev );
+ entry->Next = entry;
+ list->Tail = entry;
+ return;
+ }
+ if (!prev)
+ {
+ /* Insert at head. */
+ entry->Next = list->Tail->Next;
+ list->Tail->Next = entry;
+ return;
+ }
+ entry->Next = prev->Next;
+ prev->Next = entry;
+ if (prev == list->Tail) list->Tail = entry;
+}
-/*************************************************************************
- * grow_module_deps
+/**********************************************************************
+ * remove_single_list_entry
*/
-static WINE_MODREF **grow_module_deps( WINE_MODREF *wm, int count )
+static void remove_single_list_entry( LDRP_CSLIST *list, SINGLE_LIST_ENTRY *entry )
{
- WINE_MODREF **deps;
+ SINGLE_LIST_ENTRY *prev;
- if (wm->alloc_deps)
- deps = RtlReAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, wm->deps,
- (wm->alloc_deps + count) * sizeof(*deps) );
- else
- deps = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(*deps) );
+ assert( list->Tail );
- if (deps)
+ if (entry->Next == entry)
{
- wm->deps = deps;
- wm->alloc_deps += count;
+ assert( list->Tail == entry );
+ list->Tail = NULL;
+ return;
}
- return deps;
+
+ prev = list->Tail->Next;
+ while (prev->Next != entry && prev != list->Tail)
+ prev = prev->Next;
+ assert( prev->Next == entry );
+ prev->Next = entry->Next;
+ if (list->Tail == entry) list->Tail = prev;
+ entry->Next = NULL;
+}
+
+/**********************************************************************
+ * add_module_dependency_after
+ */
+static BOOL add_module_dependency_after( LDR_DDAG_NODE *from, LDR_DDAG_NODE *to,
+ SINGLE_LIST_ENTRY *dep_after )
+{
+ LDR_DEPENDENCY *dep;
+
+ if (!(dep = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*dep) ))) return FALSE;
+
+ dep->dependency_from = from;
+ insert_single_list_after( &from->Dependencies, dep_after, &dep->dependency_to_entry );
+ dep->dependency_to = to;
+ insert_single_list_after( &to->IncomingDependencies, NULL, &dep->dependency_from_entry );
+
+ return TRUE;
+}
+
+/**********************************************************************
+ * add_module_dependency
+ */
+static BOOL add_module_dependency( LDR_DDAG_NODE *from, LDR_DDAG_NODE *to )
+{
+ return add_module_dependency_after( from, to, from->Dependencies.Tail );
+}
+
+/**********************************************************************
+ * remove_module_dependency
+ */
+static void remove_module_dependency( LDR_DEPENDENCY *dep )
+{
+ remove_single_list_entry( &dep->dependency_to->IncomingDependencies, &dep->dependency_from_entry );
+ remove_single_list_entry( &dep->dependency_from->Dependencies, &dep->dependency_to_entry );
+ RtlFreeHeap( GetProcessHeap(), 0, dep );
+}
+
+/**********************************************************************
+ * walk_node_dependencies
+ */
+static NTSTATUS walk_node_dependencies( LDR_DDAG_NODE *node, void *context,
+ NTSTATUS (*callback)( LDR_DDAG_NODE *, void * ))
+{
+ SINGLE_LIST_ENTRY *entry;
+ LDR_DEPENDENCY *dep;
+ NTSTATUS status;
+
+ if (!(entry = node->Dependencies.Tail)) return STATUS_SUCCESS;
+
+ do
+ {
+ entry = entry->Next;
+ dep = CONTAINING_RECORD( entry, LDR_DEPENDENCY, dependency_to_entry );
+ assert( dep->dependency_from == node );
+ if ((status = callback( dep->dependency_to, context ))) break;
+ } while (entry != node->Dependencies.Tail);
+
+ return status;
}
/*************************************************************************
@@ -645,8 +728,7 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWS
{
if (!imports_fixup_done && current_modref)
{
- WINE_MODREF **deps = grow_module_deps( current_modref, 1 );
- if (deps) deps[current_modref->nDeps++] = wm;
+ add_module_dependency( current_modref->ldr.DdagNode, wm->ldr.DdagNode );
}
else if (process_attach( wm->ldr.DdagNode, NULL ) != STATUS_SUCCESS)
{
@@ -1125,12 +1207,12 @@ static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void *
if (!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) return STATUS_SUCCESS; /* already done */
wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS;
- if (!grow_module_deps( wm, 1 )) return STATUS_NO_MEMORY;
- wm->nDeps = 1;
-
prev = current_modref;
current_modref = wm;
- if (!(status = load_dll( load_path, L"mscoree.dll", NULL, 0, &imp ))) wm->deps[0] = imp;
+ assert( !wm->ldr.DdagNode->Dependencies.Tail );
+ if (!(status = load_dll( load_path, L"mscoree.dll", NULL, 0, &imp ))
+ && !add_module_dependency_after( wm->ldr.DdagNode, imp->ldr.DdagNode, NULL ))
+ status = STATUS_NO_MEMORY;
current_modref = prev;
if (status)
{
@@ -1156,9 +1238,10 @@ static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void *
*/
static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
{
- int i, dep, nb_imports;
const IMAGE_IMPORT_DESCRIPTOR *imports;
+ SINGLE_LIST_ENTRY *dep_after;
WINE_MODREF *prev, *imp;
+ int i, nb_imports;
DWORD size;
NTSTATUS status;
ULONG_PTR cookie;
@@ -1176,7 +1259,6 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
while (imports[nb_imports].Name && imports[nb_imports].FirstThunk) nb_imports++;
if (!nb_imports) return STATUS_SUCCESS; /* no imports */
- if (!grow_module_deps( wm, nb_imports )) return STATUS_NO_MEMORY;
if (!create_module_activation_context( &wm->ldr ))
RtlActivateActivationContext( 0, wm->ldr.ActivationContext, &cookie );
@@ -1189,14 +1271,13 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
status = STATUS_SUCCESS;
for (i = 0; i < nb_imports; i++)
{
- dep = wm->nDeps++;
-
+ dep_after = wm->ldr.DdagNode->Dependencies.Tail;
if (!import_dll( wm->ldr.DllBase, &imports[i], load_path, &imp ))
{
imp = NULL;
status = STATUS_DLL_NOT_FOUND;
}
- wm->deps[dep] = imp;
+ else add_module_dependency_after( wm->ldr.DdagNode, imp->ldr.DdagNode, dep_after );
}
current_modref = prev;
if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie );
@@ -1443,7 +1524,6 @@ static NTSTATUS process_attach( LDR_DDAG_NODE *node, LPVOID lpReserved )
LDR_DATA_TABLE_ENTRY *mod;
ULONG_PTR cookie;
WINE_MODREF *wm;
- int i;
if (process_detaching) return status;
@@ -1463,11 +1543,7 @@ static NTSTATUS process_attach( LDR_DDAG_NODE *node, LPVOID lpReserved )
if (wm->ldr.ActivationContext) RtlActivateActivationContext( 0, wm->ldr.ActivationContext, &cookie );
/* Recursively attach all DLLs this one depends on */
- for ( i = 0; i < wm->nDeps; i++ )
- {
- if (!wm->deps[i]) continue;
- if ((status = process_attach( wm->deps[i]->ldr.DdagNode, lpReserved )) != STATUS_SUCCESS) break;
- }
+ walk_node_dependencies( node, lpReserved, process_attach );
if (!wm->ldr.InInitializationOrderLinks.Flink)
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList,
@@ -3527,11 +3603,28 @@ void WINAPI LdrShutdownThread(void)
*/
static void free_modref( WINE_MODREF *wm )
{
+ SINGLE_LIST_ENTRY *entry;
+ LDR_DEPENDENCY *dep;
+
RemoveEntryList(&wm->ldr.InLoadOrderLinks);
RemoveEntryList(&wm->ldr.InMemoryOrderLinks);
if (wm->ldr.InInitializationOrderLinks.Flink)
RemoveEntryList(&wm->ldr.InInitializationOrderLinks);
+ while ((entry = wm->ldr.DdagNode->Dependencies.Tail))
+ {
+ dep = CONTAINING_RECORD( entry, LDR_DEPENDENCY, dependency_to_entry );
+ assert( dep->dependency_from == wm->ldr.DdagNode );
+ remove_module_dependency( dep );
+ }
+
+ while ((entry = wm->ldr.DdagNode->IncomingDependencies.Tail))
+ {
+ dep = CONTAINING_RECORD( entry, LDR_DEPENDENCY, dependency_from_entry );
+ assert( dep->dependency_to == wm->ldr.DdagNode );
+ remove_module_dependency( dep );
+ }
+
RemoveEntryList(&wm->ldr.NodeModuleLink);
if (IsListEmpty(&wm->ldr.DdagNode->Modules))
RtlFreeHeap( GetProcessHeap(), 0, wm->ldr.DdagNode );
@@ -3547,7 +3640,6 @@ static void free_modref( WINE_MODREF *wm )
NtUnmapViewOfSection( NtCurrentProcess(), wm->ldr.DllBase );
if (cached_modref == wm) cached_modref = NULL;
RtlFreeUnicodeString( &wm->ldr.FullDllName );
- RtlFreeHeap( GetProcessHeap(), 0, wm->deps );
RtlFreeHeap( GetProcessHeap(), 0, wm );
}
@@ -3590,15 +3682,19 @@ static void MODULE_FlushModrefs(void)
*
* The loader_section must be locked while calling this function.
*/
-static void MODULE_DecRefCount( WINE_MODREF *wm )
+static NTSTATUS MODULE_DecRefCount( LDR_DDAG_NODE *node, void *context )
{
- int i;
+ LDR_DATA_TABLE_ENTRY *mod;
+ WINE_MODREF *wm;
+
+ mod = CONTAINING_RECORD( node->Modules.Flink, LDR_DATA_TABLE_ENTRY, NodeModuleLink );
+ wm = CONTAINING_RECORD( mod, WINE_MODREF, ldr );
if ( wm->ldr.Flags & LDR_UNLOAD_IN_PROGRESS )
- return;
+ return STATUS_SUCCESS;
if ( wm->ldr.LoadCount <= 0 )
- return;
+ return STATUS_SUCCESS;
--wm->ldr.LoadCount;
TRACE("(%s) ldr.LoadCount: %d\n", debugstr_w(wm->ldr.BaseDllName.Buffer), wm->ldr.LoadCount );
@@ -3606,15 +3702,11 @@ static void MODULE_DecRefCount( WINE_MODREF *wm )
if ( wm->ldr.LoadCount == 0 )
{
wm->ldr.Flags |= LDR_UNLOAD_IN_PROGRESS;
-
- for ( i = 0; i < wm->nDeps; i++ )
- if ( wm->deps[i] )
- MODULE_DecRefCount( wm->deps[i] );
-
+ walk_node_dependencies( node, context, MODULE_DecRefCount );
wm->ldr.Flags &= ~LDR_UNLOAD_IN_PROGRESS;
-
module_push_unload_trace( wm );
}
+ return STATUS_SUCCESS;
}
/******************************************************************
@@ -3639,7 +3731,7 @@ NTSTATUS WINAPI LdrUnloadDll( HMODULE hModule )
TRACE("(%s) - START\n", debugstr_w(wm->ldr.BaseDllName.Buffer));
/* Recursively decrement reference counts */
- MODULE_DecRefCount( wm );
+ MODULE_DecRefCount( wm->ldr.DdagNode, NULL );
/* Call process detach notifications */
if ( free_lib_count <= 1 )
@@ -3854,7 +3946,6 @@ static void release_address_space(void)
void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR unknown3, ULONG_PTR unknown4 )
{
static int attach_done;
- int i;
NTSTATUS status;
ULONG_PTR cookie;
WINE_MODREF *wm;
@@ -3958,18 +4049,14 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
if (wm->ldr.ActivationContext)
RtlActivateActivationContext( 0, wm->ldr.ActivationContext, &cookie );
- for (i = 0; i < wm->nDeps; i++)
+ if ((status = walk_node_dependencies( wm->ldr.DdagNode, context, process_attach )))
{
- if (!wm->deps[i]) continue;
- if ((status = process_attach( wm->deps[i]->ldr.DdagNode, context )) != STATUS_SUCCESS)
- {
- if (last_failed_modref)
- ERR( "%s failed to initialize, aborting\n",
- debugstr_w(last_failed_modref->ldr.BaseDllName.Buffer) + 1 );
- ERR( "Initializing dlls for %s failed, status %x\n",
- debugstr_w(NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer), status );
- NtTerminateProcess( GetCurrentProcess(), status );
- }
+ if (last_failed_modref)
+ ERR( "%s failed to initialize, aborting\n",
+ debugstr_w(last_failed_modref->ldr.BaseDllName.Buffer) + 1 );
+ ERR( "Initializing dlls for %s failed, status %x\n",
+ debugstr_w(NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer), status );
+ NtTerminateProcess( GetCurrentProcess(), status );
}
release_address_space();
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.DllBase, DLL_PROCESS_ATTACH );
diff --git a/include/winternl.h b/include/winternl.h
index 7a34629edb0..eea97f1238b 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -3274,9 +3274,9 @@ typedef struct _LDRP_CSLIST
typedef struct _LDR_DEPENDENCY
{
- LDRP_CSLIST dependency_to_entry;
+ SINGLE_LIST_ENTRY dependency_to_entry;
struct _LDR_DDAG_NODE *dependency_to;
- LDRP_CSLIST dependency_from_entry;
+ SINGLE_LIST_ENTRY dependency_from_entry;
struct _LDR_DDAG_NODE *dependency_from;
} LDR_DEPENDENCY, *PLDR_DEPENDENCY;
--
2.31.1
Nov. 2, 2021
[PATCH 2/5] ntdll: Pass DDAG node to process_attach().
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/ntdll/loader.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index c946b39574a..23f5a982798 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -187,7 +187,7 @@ static WINE_MODREF *last_failed_modref;
static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WCHAR *default_ext,
DWORD flags, WINE_MODREF** pwm );
-static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved );
+static NTSTATUS process_attach( LDR_DDAG_NODE *node, LPVOID lpReserved );
static FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
DWORD exp_size, DWORD ordinal, LPCWSTR load_path );
static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
@@ -648,7 +648,7 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWS
WINE_MODREF **deps = grow_module_deps( current_modref, 1 );
if (deps) deps[current_modref->nDeps++] = wm;
}
- else if (process_attach( wm, NULL ) != STATUS_SUCCESS)
+ else if (process_attach( wm->ldr.DdagNode, NULL ) != STATUS_SUCCESS)
{
LdrUnloadDll( wm->ldr.DllBase );
wm = NULL;
@@ -1437,14 +1437,19 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved
*
* The loader_section must be locked while calling this function.
*/
-static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved )
+static NTSTATUS process_attach( LDR_DDAG_NODE *node, LPVOID lpReserved )
{
NTSTATUS status = STATUS_SUCCESS;
+ LDR_DATA_TABLE_ENTRY *mod;
ULONG_PTR cookie;
+ WINE_MODREF *wm;
int i;
if (process_detaching) return status;
+ mod = CONTAINING_RECORD( node->Modules.Flink, LDR_DATA_TABLE_ENTRY, NodeModuleLink );
+ wm = CONTAINING_RECORD( mod, WINE_MODREF, ldr );
+
/* prevent infinite recursion in case of cyclical dependencies */
if ( ( wm->ldr.Flags & LDR_LOAD_IN_PROGRESS )
|| ( wm->ldr.Flags & LDR_PROCESS_ATTACHED ) )
@@ -1461,7 +1466,7 @@ static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved )
for ( i = 0; i < wm->nDeps; i++ )
{
if (!wm->deps[i]) continue;
- if ((status = process_attach( wm->deps[i], lpReserved )) != STATUS_SUCCESS) break;
+ if ((status = process_attach( wm->deps[i]->ldr.DdagNode, lpReserved )) != STATUS_SUCCESS) break;
}
if (!wm->ldr.InInitializationOrderLinks.Flink)
@@ -2993,7 +2998,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
if (nts == STATUS_SUCCESS && !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
{
- nts = process_attach( wm, NULL );
+ nts = process_attach( wm->ldr.DdagNode, NULL );
if (nts != STATUS_SUCCESS)
{
LdrUnloadDll(wm->ldr.DllBase);
@@ -3956,7 +3961,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
for (i = 0; i < wm->nDeps; i++)
{
if (!wm->deps[i]) continue;
- if ((status = process_attach( wm->deps[i], context )) != STATUS_SUCCESS)
+ if ((status = process_attach( wm->deps[i]->ldr.DdagNode, context )) != STATUS_SUCCESS)
{
if (last_failed_modref)
ERR( "%s failed to initialize, aborting\n",
--
2.31.1
Nov. 2, 2021
[PATCH 1/5] ntdll: Allocate DDAG node for module.
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/kernel32/tests/module.c | 6 +++---
dlls/ntdll/loader.c | 15 ++++++++++++++-
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/module.c b/dlls/kernel32/tests/module.c
index fd369ff33e9..7c4b690fb39 100644
--- a/dlls/kernel32/tests/module.c
+++ b/dlls/kernel32/tests/module.c
@@ -1358,7 +1358,7 @@ static void test_ddag_node(void)
if (!(node = mod->DdagNode))
{
- skip( "DdagNode is NULL, skipping tests.\n" );
+ win_skip( "DdagNode is NULL, skipping tests.\n" );
return;
}
@@ -1376,11 +1376,11 @@ static void test_ddag_node(void)
ok( !node->IncomingDependencies.Tail, "Expected empty incoming dependencies list.\n" );
/* node->Dependencies.Tail is NULL on Windows 10 1507-1607 32 bit test, maybe due to broken structure layout. */
- ok( !!node->Dependencies.Tail || broken( sizeof(void *) == 4 && !node->Dependencies.Tail),
+ todo_wine ok( !!node->Dependencies.Tail || broken( sizeof(void *) == 4 && !node->Dependencies.Tail ),
"Expected nonempty dependencies list.\n" );
if (!node->Dependencies.Tail)
{
- win_skip( "Empty dependencies list.\n" );
+ skip( "Empty dependencies list.\n" );
return;
}
ok( node->LoadCount == -1, "Got unexpected LoadCount %d.\n", node->LoadCount );
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index dd41d6b66d2..c946b39574a 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1203,7 +1203,6 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
return status;
}
-
/*************************************************************************
* alloc_module
*
@@ -1232,6 +1231,16 @@ static WINE_MODREF *alloc_module( HMODULE hModule, const UNICODE_STRING *nt_name
RtlFreeHeap( GetProcessHeap(), 0, wm );
return NULL;
}
+
+ if (!(wm->ldr.DdagNode = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wm->ldr.DdagNode) )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, buffer );
+ RtlFreeHeap( GetProcessHeap(), 0, wm );
+ return NULL;
+ }
+ InitializeListHead(&wm->ldr.DdagNode->Modules);
+ InsertTailList(&wm->ldr.DdagNode->Modules, &wm->ldr.NodeModuleLink);
+
memcpy( buffer, nt_name->Buffer + 4 /* \??\ prefix */, nt_name->Length - 4 * sizeof(WCHAR) );
buffer[nt_name->Length/sizeof(WCHAR) - 4] = 0;
if ((p = wcsrchr( buffer, '\\' ))) p++;
@@ -3518,6 +3527,10 @@ static void free_modref( WINE_MODREF *wm )
if (wm->ldr.InInitializationOrderLinks.Flink)
RemoveEntryList(&wm->ldr.InInitializationOrderLinks);
+ RemoveEntryList(&wm->ldr.NodeModuleLink);
+ if (IsListEmpty(&wm->ldr.DdagNode->Modules))
+ RtlFreeHeap( GetProcessHeap(), 0, wm->ldr.DdagNode );
+
TRACE(" unloading %s\n", debugstr_w(wm->ldr.FullDllName.Buffer));
if (!TRACE_ON(module))
TRACE_(loaddll)("Unloaded module %s : %s\n",
--
2.31.1
Nov. 2, 2021
Re: libFAudio-dev -build requirement
by Alexandre Julliard
Sveinar Søpler <cybermax(a)dexter.no> writes:
> PS. I am aware that libFAudio.so.0 would still be required for <
> wine-devel/staging-6.19 and wine-stable-6.0, but the above would (to
> me) indicate that configure no longer checks for the systemlib
> development package, and thus build-depends: libFAudio-dev could be
> dropped when building packages.
Yes, all such library dependencies can be dropped, both from
build-depends and from runtime Depends/Recommends. That's true for
FAudio, libmpg123, libgsm, libpng, libjpeg, libtiff, zlib, liblcms2,
libjxr, libxml and libxslt.
--
Alexandre Julliard
julliard(a)winehq.org
Nov. 2, 2021
[PATCH vkd3d 5/5] vkd3d-shader/hlsl: Fix typo in error message.
by Giovanni Mascellani
Signed-off-by: Giovanni Mascellani <gmascellani(a)codeweavers.com>
---
libs/vkd3d-shader/hlsl.y | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index aae0ebce..7c1ae447 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -2146,7 +2146,7 @@ struct_declaration:
"Anonymous struct type must declare a variable.");
if (modifiers)
hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
- "Modifiers are not allowed on struct type declataions.");
+ "Modifiers are not allowed on struct type declarations.");
}
if (!(type = apply_type_modifiers(ctx, $2, &modifiers, @1)))
--
2.33.1
Nov. 2, 2021