Jinoh Kang (@iamahuman) commented about dlls/ntdll/misc.c:
- 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" );
This leads to data race, since nothing prevents `NtdllDefWindowProc_A` from being called by multiple threads. Since we don't want to keep user32.dll loaded (this should be the application's responsibility), `pDefWindowProcA` should be a local variable instead (i.e., no caching, no `static`).