Jinoh Kang (@iamahuman) commented about server/completion.c:
+ if (packet->in_target_packet_queue || packet->in_completion_queue) + { + release_object( packet ); + set_error( STATUS_INVALID_PARAMETER_1 ); + return; + } + + target = get_handle_obj( current->process, req->target, SYNCHRONIZE, NULL ); + if (!target) + { + release_object( packet ); + return; + } + + /* mutexs and keyed events are not allowed for associating with wait completion packets */ + if (target->ops->type == &mutex_type || target->ops->type == &keyed_event_type) You also need to reject IOCP objects.
Although, now that we have the concept of "sync objects," it might be better to just call `get_obj_sync()` and check if its ops is event_sync or semaphore_sync. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/6911#note_116510