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 | 32 ++++++++++++++++++++++++++++++++ dlls/ntdll/ntdll.spec | 1 + 2 files changed, 33 insertions(+)
diff --git a/dlls/ntdll/misc.c b/dlls/ntdll/misc.c index ab01c77531c..b5286fefd13 100644 --- a/dlls/ntdll/misc.c +++ b/dlls/ntdll/misc.c @@ -501,3 +501,35 @@ 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 ) +{ + static LPARAM (WINAPI *pDefWindowProcA)(HWND,UINT,WPARAM,LPARAM); /* DefWindowProcA */ + + UNICODE_STRING name; + NTSTATUS status; + HMODULE module; + + if (pDefWindowProcA) return pDefWindowProcA( hwnd, msg, wParam, lParam ); + + RtlCreateUnicodeString( &name, L"user32.dll" ); + if (( status = LdrLoadDll( NULL, 0, &name, &module ))) + { + ERR("Failed to load user32.dll, status %ld\n", status); + if (name.Buffer) RtlFreeUnicodeString( &name ); + return 1; /* FIXME: Is this a good way to indicate failure? */ + } + + if (name.Buffer) RtlFreeUnicodeString( &name ); + pDefWindowProcA = RtlFindExportedRoutineByName( module, "DefWindowProcA" ); + if (!pDefWindowProcA) + { + ERR("Failed to load the function\n"); + return 1; + } + + return pDefWindowProcA( hwnd, msg, wParam, lParam ); +} diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 66995346e57..7dde0c91297 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -209,6 +209,7 @@ @ stdcall -syscall NtDeleteValueKey(long ptr) @ stdcall -syscall NtDeviceIoControlFile(long long ptr ptr ptr long ptr long ptr long) @ stdcall -syscall NtDisplayString(ptr) +@ stdcall NtdllDefWindowProc_A(long long long long) @ stdcall -syscall NtDuplicateObject(long long long ptr long long long) @ stdcall -syscall NtDuplicateToken(long long ptr long long ptr) # @ stub NtEnumerateBootEntries