diff --git a/dlls/wow64/Makefile.in b/dlls/wow64/Makefile.in index 8dc4dac5ba7..76e3ff97d6b 100644 --- a/dlls/wow64/Makefile.in +++ b/dlls/wow64/Makefile.in @@ -5,4 +5,5 @@ IMPORTS = ntdll winecrt0 EXTRADLLFLAGS = -nodefaultlibs -mno-cygwin -Wl,--image-base,0x6f000000 C_SRCS = \ + sync.c \ syscall.c diff --git a/dlls/wow64/struct32.h b/dlls/wow64/struct32.h new file mode 100644 index 00000000000..e8b2e22cdcf --- /dev/null +++ b/dlls/wow64/struct32.h @@ -0,0 +1,34 @@ +/* + * 32-bit version of ntdll structures + * + * Copyright 2021 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WOW64_STRUCT32_H +#define __WOW64_STRUCT32_H + +typedef struct +{ + ULONG Length; + ULONG RootDirectory; + ULONG ObjectName; + ULONG Attributes; + ULONG SecurityDescriptor; + ULONG SecurityQualityOfService; +} OBJECT_ATTRIBUTES32; + +#endif /* __WOW64_STRUCT32_H */ diff --git a/dlls/wow64/sync.c b/dlls/wow64/sync.c new file mode 100644 index 00000000000..d61eed0a22d --- /dev/null +++ b/dlls/wow64/sync.c @@ -0,0 +1,133 @@ +/* + * WoW64 synchronization objects and functions + * + * Copyright 2021 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winternl.h" +#include "wow64_private.h" + + +/********************************************************************** + * wow64_NtClearEvent + */ +NTSTATUS WINAPI wow64_NtClearEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + + return NtClearEvent( handle ); +} + + +/********************************************************************** + * wow64_NtCreateEvent + */ +NTSTATUS WINAPI wow64_NtCreateEvent( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + EVENT_TYPE type = get_ulong( &args ); + BOOLEAN state = get_ulong( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateEvent( &handle, access, objattr_32to64( &attr, attr32 ), type, state ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenEvent + */ +NTSTATUS WINAPI wow64_NtOpenEvent( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenEvent( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtPulseEvent + */ +NTSTATUS WINAPI wow64_NtPulseEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + LONG *prev_state = get_ptr( &args ); + + return NtPulseEvent( handle, prev_state ); +} + + +/********************************************************************** + * wow64_NtQueryEvent + */ +NTSTATUS WINAPI wow64_NtQueryEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + EVENT_INFORMATION_CLASS class = get_ulong( &args ); + void *info = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + return NtQueryEvent( handle, class, info, len, retlen ); +} + + +/********************************************************************** + * wow64_NtResetEvent + */ +NTSTATUS WINAPI wow64_NtResetEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + LONG *prev_state = get_ptr( &args ); + + return NtResetEvent( handle, prev_state ); +} + + +/********************************************************************** + * wow64_NtSetEvent + */ +NTSTATUS WINAPI wow64_NtSetEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + LONG *prev_state = get_ptr( &args ); + + return NtSetEvent( handle, prev_state ); +} diff --git a/dlls/wow64/syscall.h b/dlls/wow64/syscall.h index 583af0db476..df9da2261bb 100644 --- a/dlls/wow64/syscall.h +++ b/dlls/wow64/syscall.h @@ -25,15 +25,22 @@ SYSCALL_ENTRY( NtAddAtom ) \ SYSCALL_ENTRY( NtAllocateLocallyUniqueId ) \ SYSCALL_ENTRY( NtAllocateUuids ) \ + SYSCALL_ENTRY( NtClearEvent ) \ SYSCALL_ENTRY( NtClose ) \ + SYSCALL_ENTRY( NtCreateEvent ) \ SYSCALL_ENTRY( NtDeleteAtom ) \ SYSCALL_ENTRY( NtFindAtom ) \ SYSCALL_ENTRY( NtGetCurrentProcessorNumber ) \ + SYSCALL_ENTRY( NtOpenEvent ) \ + SYSCALL_ENTRY( NtPulseEvent ) \ SYSCALL_ENTRY( NtQueryDefaultLocale ) \ SYSCALL_ENTRY( NtQueryDefaultUILanguage ) \ + SYSCALL_ENTRY( NtQueryEvent ) \ SYSCALL_ENTRY( NtQueryInformationAtom ) \ SYSCALL_ENTRY( NtQueryInstallUILanguage ) \ + SYSCALL_ENTRY( NtResetEvent ) \ SYSCALL_ENTRY( NtSetDefaultLocale ) \ - SYSCALL_ENTRY( NtSetDefaultUILanguage ) + SYSCALL_ENTRY( NtSetDefaultUILanguage ) \ + SYSCALL_ENTRY( NtSetEvent ) #endif /* __WOW64_SYSCALL_H */ diff --git a/dlls/wow64/wow64_private.h b/dlls/wow64/wow64_private.h index c441f1bf481..affd39df03b 100644 --- a/dlls/wow64/wow64_private.h +++ b/dlls/wow64/wow64_private.h @@ -22,6 +22,7 @@ #define __WOW64_PRIVATE_H #include "syscall.h" +#include "struct32.h" #define SYSCALL_ENTRY(func) extern NTSTATUS WINAPI wow64_ ## func( UINT *args ) DECLSPEC_HIDDEN; ALL_SYSCALLS @@ -30,6 +31,13 @@ ALL_SYSCALLS extern USHORT native_machine DECLSPEC_HIDDEN; extern USHORT current_machine DECLSPEC_HIDDEN; +struct object_attr64 +{ + OBJECT_ATTRIBUTES attr; + UNICODE_STRING str; + SECURITY_DESCRIPTOR sd; +}; + static inline void *get_rva( HMODULE module, DWORD va ) { return (void *)((char *)module + va); @@ -53,4 +61,59 @@ static inline ULONG get_ulong( UINT **args ) { return *(*args)++; } static inline HANDLE get_handle( UINT **args ) { return LongToHandle( *(*args)++ ); } static inline void *get_ptr( UINT **args ) { return ULongToPtr( *(*args)++ ); } +static inline UNICODE_STRING *unicode_str_32to64( UNICODE_STRING *str, const UNICODE_STRING32 *str32 ) +{ + if (!str32) return NULL; + str->Length = str32->Length; + str->MaximumLength = str32->MaximumLength; + str->Buffer = ULongToPtr( str32->Buffer ); + return str; +} + +static inline SECURITY_DESCRIPTOR *secdesc_32to64( SECURITY_DESCRIPTOR *out, const SECURITY_DESCRIPTOR *in ) +{ + /* relative descr has the same layout for 32 and 64 */ + const SECURITY_DESCRIPTOR_RELATIVE *sd = (const SECURITY_DESCRIPTOR_RELATIVE *)in; + + if (!in) return NULL; + out->Revision = sd->Revision; + out->Sbz1 = sd->Sbz1; + out->Control = sd->Control & ~SE_SELF_RELATIVE; + if (sd->Control & SE_SELF_RELATIVE) + { + if (sd->Owner) out->Owner = (PSID)((BYTE *)sd + sd->Owner); + if (sd->Group) out->Group = (PSID)((BYTE *)sd + sd->Group); + if ((sd->Control & SE_SACL_PRESENT) && sd->Sacl) out->Sacl = (PSID)((BYTE *)sd + sd->Sacl); + if ((sd->Control & SE_DACL_PRESENT) && sd->Dacl) out->Dacl = (PSID)((BYTE *)sd + sd->Dacl); + } + else + { + out->Owner = ULongToPtr( sd->Owner ); + out->Group = ULongToPtr( sd->Group ); + if (sd->Control & SE_SACL_PRESENT) out->Sacl = ULongToPtr( sd->Sacl ); + if (sd->Control & SE_DACL_PRESENT) out->Dacl = ULongToPtr( sd->Dacl ); + } + return out; +} + +static inline OBJECT_ATTRIBUTES *objattr_32to64( struct object_attr64 *out, const OBJECT_ATTRIBUTES32 *in ) +{ + memset( out, 0, sizeof(*out) ); + if (!in) return NULL; + if (in->Length != sizeof(*in)) return &out->attr; + + out->attr.Length = sizeof(out->attr); + out->attr.RootDirectory = LongToHandle( in->RootDirectory ); + out->attr.Attributes = in->Attributes; + out->attr.ObjectName = unicode_str_32to64( &out->str, ULongToPtr( in->ObjectName )); + out->attr.SecurityQualityOfService = ULongToPtr( in->SecurityQualityOfService ); + out->attr.SecurityDescriptor = secdesc_32to64( &out->sd, ULongToPtr( in->SecurityDescriptor )); + return &out->attr; +} + +static inline void put_handle( ULONG *handle32, HANDLE handle ) +{ + *handle32 = HandleToULong( handle ); +} + #endif /* __WOW64_PRIVATE_H */