Jinoh Kang (@iamahuman) commented about server/thread.c:
+ if (is_pending || !thread->context->regs[CTX_WOW].machine) + { + context_t *ctx = &thread->context->regs[CTX_NATIVE]; + flags = contexts[CTX_NATIVE].flags & ~native_flags; + copy_context( ctx, &contexts[CTX_NATIVE], flags ); + ctx->flags |= flags; } - flags = context->flags; - if (native_flags && ctx != CTX_NATIVE) /* some regs are always set from the native context */ + if (is_pending || (ctx_count == 2 && thread->context->regs[CTX_WOW].machine)) { - copy_context( &thread->context->regs[CTX_NATIVE], &contexts[CTX_NATIVE], native_flags ); - thread->context->regs[CTX_NATIVE].flags |= native_flags; - flags &= ~native_flags; + context_t *ctx = &thread->context->regs[CTX_WOW]; + flags = contexts[CTX_WOW].flags & ~native_flags; If `ctx_count == 1`, then `contexts[CTX_WOW]` does not exist.
This happens when a 64-bit (native) process calls `NtSetContextThread` on a 32-bit (WoW64) thread whose context is still pending. In this case, `is_pending` will be true but `ctx_count == 1`. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/3566#note_43295