Connor McAdams (@cmcadams) commented about dlls/uiautomationcore/uia_provider.c:
+ struct uia_node *node; + + TRACE("Removing all nodes.\n"); + EnterCriticalSection(&provider_thread_cs); + LIST_FOR_EACH_SAFE(cursor, cursor2, &provider_thread_nodes_list) + { + prov = LIST_ENTRY(cursor, struct uia_provider_thread_list_entry, entry); + list_remove(cursor); + node = impl_from_IWineUiaNode((IWineUiaNode *)prov->node); + node->in_provider_thread_list = FALSE; + UiaNodeRelease(prov->node); + heap_free(prov); + } + + LeaveCriticalSection(&provider_thread_cs); +} Actually, giving this a look over just now, this function might be unnecessary. It should be assumed that there aren't any nodes in the list when the provider thread shuts down. If a cleanup function like this is necessary, I should probably put it into `uia_stop_provider_thread`, so we don't have a potential case of another provider thread starting while the old one is still shutting down, causing a new node to be removed.
I'll fix this tomorrow and push a new revision. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/908#note_8993