I've tried implementing this before but importing user32 from ntdll isn't a reliable thing (so I recently rewrote it using the ntdll equivalents of LoadLibrary() and GetProcAddress())
Note: This is a weird way to implement this function (Windows implements this in ntdll instead) but that would probably require a user32/ntdll rewrite (so this is the next best tning to get the application working)
-- v4: ntdll: Implement NtdllDefWindowProc_A().
From: Aida Jonikienė aidas957@gmail.com
The Crinkler linker redirects the DefWindowProcA calls to the NtdllDefWindowProc_A function (which doesn't exist on Wine) and so it picks the first export in ntdll (which is A_SHAFinal right now) which obviously causes a segfault (this is problematic for the application listed in the bug report).
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53321 --- dlls/ntdll/misc.c | 26 ++++++++++++++++++++++++++ dlls/ntdll/ntdll.spec | 1 + 2 files changed, 27 insertions(+)
diff --git a/dlls/ntdll/misc.c b/dlls/ntdll/misc.c index ab01c77531c..a2037ebd4de 100644 --- a/dlls/ntdll/misc.c +++ b/dlls/ntdll/misc.c @@ -501,3 +501,29 @@ ULONG WINAPIV EtwTraceMessage( TRACEHANDLE handle, ULONG flags, LPGUID guid, /*U va_end( valist ); return ret; } + +/****************************************************************************** + * NtdllDefWindowProc_A (NTDLL.@) + */ +LRESULT WINAPI NtdllDefWindowProc_A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + LPARAM (WINAPI *pDefWindowProcA)(HWND,UINT,WPARAM,LPARAM); /* DefWindowProcA */ + const UNICODE_STRING name = RTL_CONSTANT_STRING( L"user32.dll" ); + NTSTATUS status; + HMODULE module; + + if ((status = LdrGetDllHandle( NULL, 0, &name, &module ))) + { + ERR("Failed to get user32.dll handle, status %08lx\n", status); + return 0; /* FIXME: Is this a good way to indicate failure? */ + } + + pDefWindowProcA = RtlFindExportedRoutineByName( module, "DefWindowProcA" ); + if (!pDefWindowProcA) + { + ERR("Cannot find the function\n"); + return 0; /* FIXME: Is this a good way to indicate failure? */ + } + + return pDefWindowProcA( hwnd, msg, wParam, lParam ); +} diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 014c221e59f..79bcfbe2e74 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -455,6 +455,7 @@ # @ stub NtWriteRequestData @ stdcall -syscall NtWriteVirtualMemory(long ptr ptr long ptr) @ stdcall -syscall NtYieldExecution() +@ stdcall NtdllDefWindowProc_A(long long long long) @ stub PfxFindPrefix @ stub PfxInitialize @ stub PfxInsertPrefix
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=144277
Your paranoid android.
=== debian11b (64 bit WoW report) ===
ntoskrnl.exe: ntoskrnl.c:1656: Test failed: got hardware IDs "ROOT\WINETEST\0\x00etest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}\x00\x00\x00\x00$\x00\x00\x00\x00\x00D\xf2!\x00\x00\x00\x00\x00@\xf2!\x00\x00\x00\x00\x00\xa6\xaa\xc6\xff\xffo\x00\x00p\x10A\x00\x00\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\xd0\xcb\xb6\x00\x00\x00\x00\x00\x00\xf0!\x00#\x00"... ntoskrnl.c:1671: Test failed: got compatible IDs "ROOT\WINETEST\0\x00etest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}\x00\x00\x00\x00$\x00\x00\x00\x00\x00D\xf2!\x00\x00\x00\x00\x00@\xf2!\x00\x00\x00\x00\x00\xa6\xaa\xc6\xff\xffo\x00\x00p\x10A\x00\x00\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\xd0\xcb\xb6\x00\x00\x00\x00\x00\x00\xf0!\x00#\x00"...
On Thu Mar 21 16:00:28 2024 +0000, Jinoh Kang wrote:
No. On Windows it works completely differently: https://stackoverflow.com/questions/30871183/getprocaddressgetmodulehandleuser32-dll-defwindowprocw-returns-address. IMHO this is a good enough approximation until we can refactor user32 to move DefWindowProc to ntdll.
I agree with Jinoh/LukeGPT :frog:
This merge request was approved by Jinoh Kang.
On Thu Mar 21 16:03:06 2024 +0000, Aida Jonikienė wrote:
I agree with Jinoh/LukeGPT :frog:
There's no reason to move the implementation to ntdll, that's not how it works. user32 should simply store a callback somewhere in ntdll.
On Thu Mar 21 16:31:30 2024 +0000, Alexandre Julliard wrote:
There's no reason to move the implementation to ntdll, that's not how it works. user32 should simply store a callback somewhere in ntdll.
I see RtlInitializeNtUserPfn() in Windows 10 NTDLL export list, shall we use this to implement upcalls? Do you have something else in mind?
I see RtlInitializeNtUserPfn() in Windows 10 NTDLL export list
@iamahuman We would have to figure out the function signature for that first :frog:
I see RtlInitializeNtUserPfn() in Windows 10 NTDLL export list, shall we use this to implement upcalls?
Yes, it should do essentially the same thing as NtUserInitializeClientPfnArrays.
On Thu Mar 21 18:16:47 2024 +0000, Alexandre Julliard wrote:
I see RtlInitializeNtUserPfn() in Windows 10 NTDLL export list, shall
we use this to implement upcalls? Yes, it should do essentially the same thing as NtUserInitializeClientPfnArrays.
We probably don't really need it to have a compatible prototype.
This merge request was closed by Aida Jonikienė.
9f9ce9fa46a6575d4c78f112707ed879648db17a implements this MR in a different way