From: Zhiyi Zhang <zzhang@codeweavers.com> --- dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/signal_arm64ec.c | 1 + dlls/ntdll/unix/alpc.c | 13 ++ dlls/wow64/struct32.h | 55 ++++++++ dlls/wow64/syscall.c | 51 +++++++ dlls/wow64/wow64_private.h | 272 ++++++++++++++++++++++++++++++++++++ 6 files changed, 393 insertions(+) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index c317954d125..9c486240b81 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -155,6 +155,7 @@ @ stdcall -syscall NtAllocateUuids(ptr ptr ptr ptr) @ stdcall -syscall=0x0018 NtAllocateVirtualMemory(long ptr long ptr long long) @ stdcall -syscall NtAllocateVirtualMemoryEx(long ptr ptr long long ptr long) +@ stdcall -syscall NtAlpcConnectPort(ptr ptr ptr ptr long ptr ptr ptr ptr ptr ptr) @ stdcall -syscall NtAlpcCreatePort(ptr ptr ptr) @ stub -syscall=0x004c NtApphelpCacheControl @ stdcall -syscall NtAreMappedFilesTheSame(ptr ptr) diff --git a/dlls/ntdll/signal_arm64ec.c b/dlls/ntdll/signal_arm64ec.c index 92549aa9845..922a410f636 100644 --- a/dlls/ntdll/signal_arm64ec.c +++ b/dlls/ntdll/signal_arm64ec.c @@ -364,6 +364,7 @@ DEFINE_SYSCALL(NtAllocateReserveObject, (HANDLE *handle, const OBJECT_ATTRIBUTES DEFINE_SYSCALL(NtAllocateUuids, (ULARGE_INTEGER *time, ULONG *delta, ULONG *sequence, UCHAR *seed)) DEFINE_WRAPPED_SYSCALL(NtAllocateVirtualMemory, (HANDLE process, PVOID *ret, ULONG_PTR zero_bits, SIZE_T *size_ptr, ULONG type, ULONG protect)) DEFINE_WRAPPED_SYSCALL(NtAllocateVirtualMemoryEx, (HANDLE process, PVOID *ret, SIZE_T *size_ptr, ULONG type, ULONG protect, MEM_EXTENDED_PARAMETER *parameters, ULONG count)) +DEFINE_SYSCALL(NtAlpcConnectPort, (HANDLE *port_handle, UNICODE_STRING *port_name, OBJECT_ATTRIBUTES *obj_attr, ALPC_PORT_ATTRIBUTES *port_attr, DWORD flags, PSID required_server_sid, ALPC_PORT_MESSAGE *connect_msg, SIZE_T *connect_msg_size, ALPC_MESSAGE_ATTRIBUTES *send_msg_attr, ALPC_MESSAGE_ATTRIBUTES *recv_msg_attr, LARGE_INTEGER *timeout)) DEFINE_SYSCALL(NtAlpcCreatePort, (HANDLE *port_handle, OBJECT_ATTRIBUTES *obj_attr, ALPC_PORT_ATTRIBUTES *port_attr)) DEFINE_SYSCALL(NtApphelpCacheControl, (ULONG class, void *context)) DEFINE_SYSCALL(NtAreMappedFilesTheSame, (PVOID addr1, PVOID addr2)) diff --git a/dlls/ntdll/unix/alpc.c b/dlls/ntdll/unix/alpc.c index 6aea4daf634..3a55e6cc8fd 100644 --- a/dlls/ntdll/unix/alpc.c +++ b/dlls/ntdll/unix/alpc.c @@ -28,6 +28,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(alpc); +NTSTATUS WINAPI NtAlpcConnectPort( HANDLE *port_handle, UNICODE_STRING *port_name, + OBJECT_ATTRIBUTES *obj_attr, ALPC_PORT_ATTRIBUTES *port_attr, + DWORD flags, PSID required_server_sid, + ALPC_PORT_MESSAGE *connect_msg, SIZE_T *connect_msg_size, + ALPC_MESSAGE_ATTRIBUTES *send_msg_attr, + ALPC_MESSAGE_ATTRIBUTES *recv_msg_attr, LARGE_INTEGER *timeout ) +{ + FIXME( "%p, %s, %p, %p, %#x, %p, %p, %p, %p, %p, %p stub!\n", port_handle, + debugstr_us( port_name ), obj_attr, port_attr, (unsigned int)flags, required_server_sid, + connect_msg, connect_msg_size, send_msg_attr, recv_msg_attr, timeout ); + return STATUS_NOT_IMPLEMENTED; +} + NTSTATUS WINAPI NtAlpcCreatePort( HANDLE *port_handle, OBJECT_ATTRIBUTES *obj_attr, ALPC_PORT_ATTRIBUTES *port_attr ) { FIXME( "%p, %p, %p stub!\n", port_handle, obj_attr, port_attr ); diff --git a/dlls/wow64/struct32.h b/dlls/wow64/struct32.h index 8a490778ae2..ba2bc02523f 100644 --- a/dlls/wow64/struct32.h +++ b/dlls/wow64/struct32.h @@ -803,4 +803,59 @@ typedef struct } DUMMYUNIONNAME4; } ALPC_PORT_MESSAGE32, *PALPC_PORT_MESSAGE32, ALPC_PORT_MESSAGE_HEADER32, *PALPC_PORT_MESSAGE_HEADER32; +typedef struct +{ + ULONG AllocatedAttributes; + ULONG ValidAttributes; +} ALPC_MESSAGE_ATTRIBUTES32, *PALPC_MESSAGE_ATTRIBUTES32; + +typedef struct +{ + ULONG Flags; + ULONG QoSPointer; + ULONG ContextHandle; +} ALPC_SECURITY_ATTR32, *PALPC_SECURITY_ATTR32; + +typedef struct +{ + ULONG Flags; + ULONG SectionHandle; + ULONG ViewBase; + ULONG ViewSize; +} ALPC_VIEW_ATTR32, *PALPC_VIEW_ATTR32; + +typedef struct +{ + ULONG PortContext; + ULONG MessageContext; + ULONG Sequence; + ULONG MessageId; + ULONG CallbackId; +} ALPC_CONTEXT_ATTR32, *PALPC_CONTEXT_ATTR32; + +typedef struct +{ + ULONG Flags; + ULONG Handle; + ULONG ObjectType; + ULONG DesiredAccess; +} ALPC_HANDLE_ATTR32, *PALPC_HANDLE_ATTR32; + +typedef struct +{ + ULONGLONG TokenId; + ULONGLONG AuthenticationId; + ULONGLONG ModifiedId; +} ALPC_TOKEN_ATTR32, *PALPC_TOKEN_ATTR32; + +typedef struct +{ + ULONG Event; +} ALPC_DIRECT_ATTR32, *PALPC_DIRECT_ATTR32; + +typedef struct +{ + ULONGLONG Ticket; +} ALPC_WORK_ON_BEHALF_ATTR32, *PALPC_WORK_ON_BEHALF_ATTR32; + #endif /* __WOW64_STRUCT32_H */ diff --git a/dlls/wow64/syscall.c b/dlls/wow64/syscall.c index 7be7579a088..c8d3c387522 100644 --- a/dlls/wow64/syscall.c +++ b/dlls/wow64/syscall.c @@ -463,6 +463,57 @@ NTSTATUS WINAPI wow64_NtAllocateUuids( UINT *args ) return NtAllocateUuids( time, delta, sequence, seed ); } +/********************************************************************** + * wow64_NtAlpcConnectPort + */ +NTSTATUS WINAPI wow64_NtAlpcConnectPort( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + UNICODE_STRING32 *str32 = get_ptr( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ALPC_PORT_ATTRIBUTES32 *port_attr32 = get_ptr( &args ); + ULONG flags = get_ulong( &args ); + SID *sid = get_ptr( &args ); + ALPC_PORT_MESSAGE32 *msg32 = get_ptr( &args ); + ULONG *size32 = get_ptr( &args ); + ALPC_MESSAGE_ATTRIBUTES32 *send_msg_attr32 = get_ptr( &args ); + ALPC_MESSAGE_ATTRIBUTES32 *recv_msg_attr32 = get_ptr( &args ); + LARGE_INTEGER *timeout = get_ptr( &args ); + NTSTATUS status; + + HANDLE handle = 0; + UNICODE_STRING str; + struct object_attr64 attr; + ALPC_PORT_ATTRIBUTES port_attr; + ALPC_PORT_MESSAGE *msg; + SIZE_T size = size32 ? (*size32 + sizeof(ALPC_PORT_MESSAGE) - sizeof(ALPC_PORT_MESSAGE32)) : 65535; + ALPC_MESSAGE_ATTRIBUTES *send_msg_attr; + ALPC_MESSAGE_ATTRIBUTES *recv_msg_attr; + + if (!handle_ptr) return STATUS_OBJECT_NAME_NOT_FOUND; + + if (port_attr32 && (!port_attr32->MaxMessageLength + || port_attr32->MaxMessageLength > (65535 - (sizeof(ALPC_PORT_MESSAGE) - sizeof(ALPC_PORT_MESSAGE32))))) + return STATUS_INVALID_PARAMETER; + + status = NtAlpcConnectPort( &handle, unicode_str_32to64( &str, str32 ), objattr_32to64( &attr, attr32 ), + alpc_port_attributes_32to64( &port_attr, port_attr32 ), flags, sid, + alpc_port_message_32to64( &msg, size, msg32, TRUE ), &size, + alpc_port_message_attributes_32to64( &send_msg_attr, send_msg_attr32, TRUE ), + alpc_port_message_attributes_32to64( &recv_msg_attr, recv_msg_attr32, FALSE ), timeout); + if (status == STATUS_SUCCESS) + { + put_handle( handle_ptr, handle ); + alpc_port_message_64to32( msg32, msg ); + alpc_port_message_attributes_64to32( recv_msg_attr32, recv_msg_attr ); + } + else if (status == STATUS_BUFFER_TOO_SMALL && size32) + { + put_size( size32, size - (sizeof(ALPC_PORT_MESSAGE) - sizeof(ALPC_PORT_MESSAGE32))); + } + return status; +} + /********************************************************************** * wow64_NtAlpcCreatePort */ diff --git a/dlls/wow64/wow64_private.h b/dlls/wow64/wow64_private.h index f2d55799341..2ac3e51f1f0 100644 --- a/dlls/wow64/wow64_private.h +++ b/dlls/wow64/wow64_private.h @@ -215,6 +215,278 @@ static inline ALPC_PORT_ATTRIBUTES *alpc_port_attributes_32to64( ALPC_PORT_ATTRI return out; } +static inline ALPC_PORT_MESSAGE *alpc_port_message_32to64( ALPC_PORT_MESSAGE **out, SIZE_T out_msg_size, + const ALPC_PORT_MESSAGE32 *in, BOOL copy_msg ) +{ + ALPC_PORT_MESSAGE *msg; + + if (!in || !(msg = Wow64AllocateTemp( out_msg_size ))) + { + *out = NULL; + return NULL; + } + + if (!copy_msg) goto done; + + msg->DataLength = in->DataLength; + msg->TotalLength = sizeof(*msg) + msg->DataLength; + msg->Type = in->Type; + msg->DataInfoOffset = in->DataInfoOffset; + client_id_32to64( &msg->ClientId, &in->ClientId ); + msg->MessageId = in->MessageId; + msg->ClientViewSize = in->ClientViewSize; + memcpy( (unsigned char *)msg + sizeof(*msg), (const unsigned char *)in + sizeof(*in), in->DataLength ); +done: + *out = msg; + return msg; +} + +static inline ALPC_MESSAGE_ATTRIBUTES *alpc_port_message_attributes_32to64( ALPC_MESSAGE_ATTRIBUTES **out, + const ALPC_MESSAGE_ATTRIBUTES32 *in, + BOOL copy_attributes ) +{ + ALPC_MESSAGE_ATTRIBUTES *attr; + const unsigned char *current_from_attr; + + if (!in || !(attr = Wow64AllocateTemp( AlpcGetHeaderSize( in->AllocatedAttributes ) ))) + { + *out = NULL; + return NULL; + } + + attr->AllocatedAttributes = in->AllocatedAttributes; + + if (!copy_attributes) + { + attr->ValidAttributes = 0; + *out = attr; + return attr; + } + + attr->ValidAttributes = in->ValidAttributes; + current_from_attr = (const unsigned char *)in + sizeof(*in); + + if (in->ValidAttributes & ALPC_MESSAGE_SECURITY_ATTRIBUTE) + { + const ALPC_SECURITY_ATTR32 *from_attr = (const ALPC_SECURITY_ATTR32 *)current_from_attr; + ALPC_SECURITY_ATTR *to_attr = AlpcGetMessageAttribute( attr, ALPC_MESSAGE_SECURITY_ATTRIBUTE ); + + to_attr->Flags = from_attr->Flags; + to_attr->ContextHandle = UlongToHandle( from_attr->ContextHandle ); + if (from_attr->QoSPointer) + { + SECURITY_QUALITY_OF_SERVICE32 *qos32 = (SECURITY_QUALITY_OF_SERVICE32 *)ULongToPtr( from_attr->QoSPointer ); + SECURITY_QUALITY_OF_SERVICE *qos = Wow64AllocateTemp( sizeof(*qos) ); + + to_attr->QoS = qos; + qos->Length = qos32->Length; + qos->ImpersonationLevel = qos32->ImpersonationLevel; + qos->ContextTrackingMode = qos32->ContextTrackingMode; + qos->EffectiveOnly = qos32->EffectiveOnly; + } + else + { + to_attr->QoS = NULL; + } + } + if (in->AllocatedAttributes & ALPC_MESSAGE_SECURITY_ATTRIBUTE) + current_from_attr += sizeof(ALPC_SECURITY_ATTR32); + + if (in->ValidAttributes & ALPC_MESSAGE_VIEW_ATTRIBUTE) + { + const ALPC_VIEW_ATTR32 *from_attr = (const ALPC_VIEW_ATTR32 *)current_from_attr; + ALPC_VIEW_ATTR *to_attr = AlpcGetMessageAttribute( attr, ALPC_MESSAGE_VIEW_ATTRIBUTE ); + + to_attr->Flags = from_attr->Flags; + to_attr->SectionHandle = UlongToHandle( from_attr->SectionHandle ); + to_attr->ViewBase = UlongToPtr( from_attr->ViewBase ); + to_attr->ViewSize = from_attr->ViewSize; + } + if (in->AllocatedAttributes & ALPC_MESSAGE_VIEW_ATTRIBUTE) + current_from_attr += sizeof(ALPC_VIEW_ATTR32); + + if (in->ValidAttributes & ALPC_MESSAGE_CONTEXT_ATTRIBUTE) + { + const ALPC_CONTEXT_ATTR32 *from_attr = (const ALPC_CONTEXT_ATTR32 *)current_from_attr; + ALPC_CONTEXT_ATTR *to_attr = AlpcGetMessageAttribute( attr, ALPC_MESSAGE_CONTEXT_ATTRIBUTE ); + + to_attr->PortContext = UlongToPtr( from_attr->PortContext ); + to_attr->MessageContext = UlongToPtr( from_attr->MessageContext ); + to_attr->Sequence = from_attr->Sequence; + to_attr->MessageId = from_attr->MessageId; + to_attr->CallbackId = from_attr->CallbackId; + } + if (in->AllocatedAttributes & ALPC_MESSAGE_CONTEXT_ATTRIBUTE) + current_from_attr += sizeof(ALPC_CONTEXT_ATTR32); + + if (in->ValidAttributes & ALPC_MESSAGE_HANDLE_ATTRIBUTE) + { + const ALPC_HANDLE_ATTR32 *from_attr = (const ALPC_HANDLE_ATTR32 *)current_from_attr; + ALPC_HANDLE_ATTR *to_attr = AlpcGetMessageAttribute( attr, ALPC_MESSAGE_HANDLE_ATTRIBUTE ); + + to_attr->Flags = from_attr->Flags; + to_attr->Handle = UlongToHandle( from_attr->Handle ); + to_attr->ObjectType = from_attr->ObjectType; + to_attr->DesiredAccess = from_attr->DesiredAccess; + } + if (in->AllocatedAttributes & ALPC_MESSAGE_HANDLE_ATTRIBUTE) + current_from_attr += sizeof(ALPC_HANDLE_ATTR32); + + if (in->ValidAttributes & ALPC_MESSAGE_TOKEN_ATTRIBUTE) + { + const ALPC_TOKEN_ATTR32 *from_attr = (const ALPC_TOKEN_ATTR32 *)current_from_attr; + ALPC_TOKEN_ATTR *to_attr = AlpcGetMessageAttribute( attr, ALPC_MESSAGE_TOKEN_ATTRIBUTE ); + + to_attr->TokenId = from_attr->TokenId; + to_attr->AuthenticationId = from_attr->AuthenticationId; + to_attr->ModifiedId = from_attr->ModifiedId; + } + if (in->AllocatedAttributes & ALPC_MESSAGE_TOKEN_ATTRIBUTE) + current_from_attr += sizeof(ALPC_TOKEN_ATTR32); + + if (in->ValidAttributes & ALPC_MESSAGE_DIRECT_ATTRIBUTE) + { + const ALPC_DIRECT_ATTR32 *from_attr = (const ALPC_DIRECT_ATTR32 *)current_from_attr; + ALPC_DIRECT_ATTR *to_attr = AlpcGetMessageAttribute( attr, ALPC_MESSAGE_DIRECT_ATTRIBUTE ); + + to_attr->Event = UlongToHandle( from_attr->Event ); + } + if (in->AllocatedAttributes & ALPC_MESSAGE_DIRECT_ATTRIBUTE) + current_from_attr += sizeof(ALPC_DIRECT_ATTR32); + + if (in->ValidAttributes & ALPC_MESSAGE_WORK_ON_BEHALF_ATTRIBUTE) + { + const ALPC_WORK_ON_BEHALF_ATTR32 *from_attr = (const ALPC_WORK_ON_BEHALF_ATTR32 *)current_from_attr; + ALPC_WORK_ON_BEHALF_ATTR *to_attr = AlpcGetMessageAttribute( attr, ALPC_MESSAGE_WORK_ON_BEHALF_ATTRIBUTE ); + + to_attr->Ticket = from_attr->Ticket; + } + + *out = attr; + return attr; +} + +static inline ALPC_PORT_MESSAGE32 *alpc_port_message_64to32( ALPC_PORT_MESSAGE32 *out, + const ALPC_PORT_MESSAGE *in ) +{ + if (!in) return NULL; + + out->DataLength = in->DataLength; + out->TotalLength = sizeof(*out) + in->DataLength; + out->Type = in->Type; + out->DataInfoOffset = in->DataInfoOffset; + out->ClientId.UniqueProcess = HandleToUlong( in->ClientId.UniqueProcess ); + out->ClientId.UniqueThread = HandleToUlong( in->ClientId.UniqueThread ); + out->MessageId = in->MessageId; + out->ClientViewSize = in->ClientViewSize; + memcpy( (unsigned char *)out + sizeof(*out), (const unsigned char *)in + sizeof(*in), in->DataLength ); + return out; +} + +static inline ALPC_MESSAGE_ATTRIBUTES32 *alpc_port_message_attributes_64to32( ALPC_MESSAGE_ATTRIBUTES32 *out, + ALPC_MESSAGE_ATTRIBUTES *in ) +{ + unsigned char *current_to_attr; + + if (!in) return NULL; + + out->AllocatedAttributes = in->AllocatedAttributes; + out->ValidAttributes = in->ValidAttributes; + + current_to_attr = (unsigned char *)out + sizeof(*out); + + if (in->ValidAttributes & ALPC_MESSAGE_SECURITY_ATTRIBUTE) + { + const ALPC_SECURITY_ATTR *from_attr = AlpcGetMessageAttribute( in, ALPC_MESSAGE_SECURITY_ATTRIBUTE ); + ALPC_SECURITY_ATTR32 *to_attr = (ALPC_SECURITY_ATTR32 *)current_to_attr; + + to_attr->Flags = from_attr->Flags; + to_attr->ContextHandle = HandleToUlong( from_attr->ContextHandle ); + if (to_attr->QoSPointer && from_attr->QoS) + { + SECURITY_QUALITY_OF_SERVICE32 *qos32 = ULongToPtr( to_attr->QoSPointer ); + qos32->ImpersonationLevel = from_attr->QoS->ImpersonationLevel; + qos32->ContextTrackingMode = from_attr->QoS->ContextTrackingMode; + qos32->EffectiveOnly = from_attr->QoS->EffectiveOnly; + } + } + if (out->AllocatedAttributes & ALPC_MESSAGE_SECURITY_ATTRIBUTE) + current_to_attr += sizeof(ALPC_SECURITY_ATTR32); + + if (in->ValidAttributes & ALPC_MESSAGE_VIEW_ATTRIBUTE) + { + const ALPC_VIEW_ATTR *from_attr = AlpcGetMessageAttribute( in, ALPC_MESSAGE_VIEW_ATTRIBUTE ); + ALPC_VIEW_ATTR32 *to_attr = (ALPC_VIEW_ATTR32 *)current_to_attr; + + to_attr->Flags = from_attr->Flags; + to_attr->SectionHandle = HandleToUlong( from_attr->SectionHandle ); + to_attr->ViewBase = PtrToUlong( from_attr->ViewBase ); + to_attr->ViewSize = from_attr->ViewSize; + } + if (out->AllocatedAttributes & ALPC_MESSAGE_VIEW_ATTRIBUTE) + current_to_attr += sizeof(ALPC_VIEW_ATTR32); + + if (in->ValidAttributes & ALPC_MESSAGE_CONTEXT_ATTRIBUTE) + { + const ALPC_CONTEXT_ATTR *from_attr = AlpcGetMessageAttribute( in, ALPC_MESSAGE_CONTEXT_ATTRIBUTE ); + ALPC_CONTEXT_ATTR32 *to_attr = (ALPC_CONTEXT_ATTR32 *)current_to_attr; + + to_attr->PortContext = PtrToUlong( from_attr->PortContext ); + to_attr->MessageContext = PtrToUlong( from_attr->MessageContext ); + to_attr->Sequence = from_attr->Sequence; + /* Should be from_attr->MessageId. But tests show that it's always 0 on 32-bit */ + to_attr->MessageId = 0; + to_attr->CallbackId = from_attr->CallbackId; + } + if (out->AllocatedAttributes & ALPC_MESSAGE_CONTEXT_ATTRIBUTE) + current_to_attr += sizeof(ALPC_CONTEXT_ATTR32); + + if (in->ValidAttributes & ALPC_MESSAGE_HANDLE_ATTRIBUTE) + { + const ALPC_HANDLE_ATTR *from_attr = AlpcGetMessageAttribute( in, ALPC_MESSAGE_HANDLE_ATTRIBUTE ); + ALPC_HANDLE_ATTR32 *to_attr = (ALPC_HANDLE_ATTR32 *)current_to_attr; + + to_attr->Flags = from_attr->Flags; + to_attr->Handle = HandleToUlong( from_attr->Handle ); + to_attr->ObjectType = from_attr->ObjectType; + to_attr->DesiredAccess = from_attr->DesiredAccess; + } + if (out->AllocatedAttributes & ALPC_MESSAGE_HANDLE_ATTRIBUTE) + current_to_attr += sizeof(ALPC_HANDLE_ATTR32); + + if (in->ValidAttributes & ALPC_MESSAGE_TOKEN_ATTRIBUTE) + { + const ALPC_TOKEN_ATTR *from_attr = AlpcGetMessageAttribute( in, ALPC_MESSAGE_TOKEN_ATTRIBUTE ); + ALPC_TOKEN_ATTR32 *to_attr = (ALPC_TOKEN_ATTR32 *)current_to_attr; + + to_attr->TokenId = from_attr->TokenId; + to_attr->AuthenticationId = from_attr->AuthenticationId; + to_attr->ModifiedId = from_attr->ModifiedId; + } + if (out->AllocatedAttributes & ALPC_MESSAGE_TOKEN_ATTRIBUTE) + current_to_attr += sizeof(ALPC_TOKEN_ATTR32); + + if (in->ValidAttributes & ALPC_MESSAGE_DIRECT_ATTRIBUTE) + { + const ALPC_DIRECT_ATTR *from_attr = AlpcGetMessageAttribute( in, ALPC_MESSAGE_DIRECT_ATTRIBUTE ); + ALPC_DIRECT_ATTR32 *to_attr = (ALPC_DIRECT_ATTR32 *)current_to_attr; + + to_attr->Event = HandleToUlong( from_attr->Event ); + } + if (out->AllocatedAttributes & ALPC_MESSAGE_DIRECT_ATTRIBUTE) + current_to_attr += sizeof(ALPC_DIRECT_ATTR32); + + if (in->ValidAttributes & ALPC_MESSAGE_WORK_ON_BEHALF_ATTRIBUTE) + { + const ALPC_WORK_ON_BEHALF_ATTR *from_attr = AlpcGetMessageAttribute( in, ALPC_MESSAGE_WORK_ON_BEHALF_ATTRIBUTE ); + ALPC_WORK_ON_BEHALF_ATTR32 *to_attr = (ALPC_WORK_ON_BEHALF_ATTR32 *)current_to_attr; + + to_attr->Ticket = from_attr->Ticket; + } + + return out; +} + static inline TOKEN_USER *token_user_32to64( TOKEN_USER *out, const TOKEN_USER32 *in ) { out->User.Sid = ULongToPtr( in->User.Sid ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10932