[PATCH 0/7] MR10492: include: Add some ALPC definitions.
For React Native. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10492
From: Zhiyi Zhang <zzhang@codeweavers.com> --- include/winternl.h | 168 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/include/winternl.h b/include/winternl.h index 4dab894954d..a20aca55a0e 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -4507,10 +4507,166 @@ typedef struct _KCONTINUE_ARGUMENT #define HASH_STRING_ALGORITHM_X65599 1 #define HASH_STRING_ALGORITHM_INVALID 0xffffffff +/* ALPC */ +/* Connection flags */ +#define ALPC_SYNC_CONNECTION 0x00020000 /* Synchronous connection request message, note that this doesn't affect normal messages */ + +/* Port attribute flags */ +#define ALPC_PORTFLG_ALLOWIMPERSONATION 0x00010000 /* Allow server to impersonate the client */ +#define ALPC_PORTFLG_NON_BLOCKING_RECEIVE 0x00040000 /* Return immediately when there is no data to receive */ +#define ALPC_PORTFLG_ALLOW_DUP_OBJECT 0x00080000 /* Allow duplicating objects */ + +/* Message flags */ +#define ALPC_MSGFLG_NONE 0x00000000 +#define ALPC_MSGFLG_REPLY_MESSAGE 0x00010000 /* Message is a reply */ +#define ALPC_MSGFLG_SYNC_REQUEST 0x00020000 /* Synchronously send and receive message */ + +/* Message attribute flags */ +#define ALPC_MESSAGE_SECURITY_ATTRIBUTE 0x80000000 +#define ALPC_MESSAGE_VIEW_ATTRIBUTE 0x40000000 +#define ALPC_MESSAGE_CONTEXT_ATTRIBUTE 0x20000000 +#define ALPC_MESSAGE_HANDLE_ATTRIBUTE 0x10000000 +#define ALPC_MESSAGE_TOKEN_ATTRIBUTE 0x08000000 +#define ALPC_MESSAGE_DIRECT_ATTRIBUTE 0x04000000 +#define ALPC_MESSAGE_WORK_ON_BEHALF_ATTRIBUTE 0x02000000 +#define ALPC_MESSAGE_ATTRIBUTE_ALL 0xfe000000 + +/* Message types */ +typedef enum _ALPC_MESSAGE_TYPE +{ + ALPC_MESSAGE_TYPE_REQUEST = 1, + ALPC_MESSAGE_TYPE_REPLY, + ALPC_MESSAGE_TYPE_DATAGRAM, + ALPC_MESSAGE_TYPE_LOST_REPLY, + ALPC_MESSAGE_TYPE_PORT_CLOSED, + ALPC_MESSAGE_TYPE_CLIENT_DIED, + ALPC_MESSAGE_TYPE_EXCEPTION, + ALPC_MESSAGE_TYPE_DEBUG_EVENT, + ALPC_MESSAGE_TYPE_ERROR_EVENT, + ALPC_MESSAGE_TYPE_CONNECTION_REQUEST, + ALPC_MESSAGE_TYPE_CONNECTION_REPLY, + ALPC_MESSAGE_TYPE_CANCELED, + ALPC_MESSAGE_TYPE_UNREGISTER_PROCESS +} ALPC_MESSAGE_TYPE; + +typedef struct _ALPC_PORT_MESSAGE +{ + union + { + struct + { + USHORT DataLength; + USHORT TotalLength; + } DUMMYSTRUCTNAME1; + ULONG Length; + } DUMMYUNIONNAME1; + union + { + struct + { + USHORT Type; + USHORT DataInfoOffset; + } DUMMYSTRUCTNAME2; + ULONG ZeroInit; + } DUMMYUNIONNAME2; + union + { + CLIENT_ID ClientId; + double DoNotUseThisField; + } DUMMYUNIONNAME3; + ULONG MessageId; + union + { + SIZE_T ClientViewSize; + ULONG CallbackId; + } DUMMYUNIONNAME4; +} ALPC_PORT_MESSAGE, *PALPC_PORT_MESSAGE, ALPC_PORT_MESSAGE_HEADER, *PALPC_PORT_MESSAGE_HEADER; + +typedef struct _ALPC_MESSAGE_ATTRIBUTES +{ + ULONG AllocatedAttributes; + ULONG ValidAttributes; +} ALPC_MESSAGE_ATTRIBUTES, *PALPC_MESSAGE_ATTRIBUTES; + +typedef struct _ALPC_SECURITY_ATTR +{ + ULONG Flags; + SECURITY_QUALITY_OF_SERVICE *QoS; + HANDLE ContextHandle; +} ALPC_SECURITY_ATTR, *PALPC_SECURITY_ATTR; + +typedef struct _ALPC_VIEW_ATTR +{ + ULONG Flags; + HANDLE SectionHandle; + void *ViewBase; + SIZE_T ViewSize; +} ALPC_VIEW_ATTR, *PALPC_VIEW_ATTR; + +typedef struct _ALPC_CONTEXT_ATTR +{ + void *PortContext; + void *MessageContext; + ULONG Sequence; + ULONG MessageId; + ULONG CallbackId; +} ALPC_CONTEXT_ATTR, * PALPC_CONTEXT_ATTR; + +typedef struct _ALPC_HANDLE_ATTR +{ + ULONG Flags; + HANDLE Handle; + ULONG ObjectType; + ACCESS_MASK DesiredAccess; +} ALPC_HANDLE_ATTR, *PALPC_HANDLE_ATTR; + +typedef struct _ALPC_TOKEN_ATTR +{ + ULONGLONG TokenId; + ULONGLONG AuthenticationId; + ULONGLONG ModifiedId; +} ALPC_TOKEN_ATTR, *PALPC_TOKEN_ATTR; + +typedef struct _ALPC_DIRECT_ATTR +{ + HANDLE Event; +} ALPC_DIRECT_ATTR, *PALPC_DIRECT_ATTR; + +typedef struct _ALPC_WORK_ON_BEHALF_ATTR +{ + ULONGLONG Ticket; +} ALPC_WORK_ON_BEHALF_ATTR, *PALPC_WORK_ON_BEHALF_ATTR; + +typedef struct _ALPC_BASIC_INFORMATION +{ + ULONG Flags; + ULONG SequenceNo; + PVOID PortContext; +} ALPC_BASIC_INFORMATION, *PALPC_BASIC_INFORMATION; + +typedef struct _ALPC_PORT_ATTRIBUTES +{ + ULONG Flags; + SECURITY_QUALITY_OF_SERVICE SecurityQos; + SIZE_T MaxMessageLength; + SIZE_T MemoryBandwidth; + SIZE_T MaxPoolUsage; + SIZE_T MaxSectionSize; + SIZE_T MaxViewSize; + SIZE_T MaxTotalSectionSize; + ULONG DupObjectTypes; +#ifdef _WIN64 + ULONG Reserved; +#endif +} ALPC_PORT_ATTRIBUTES, *PALPC_PORT_ATTRIBUTES; + /*********************************************************************** * Function declarations */ +NTSYSAPI SIZE_T WINAPI AlpcGetHeaderSize(ULONG); +NTSYSAPI void * WINAPI AlpcGetMessageAttribute(ALPC_MESSAGE_ATTRIBUTES *,ULONG); +NTSYSAPI NTSTATUS WINAPI AlpcInitializeMessageAttribute(ULONG,ALPC_MESSAGE_ATTRIBUTES *,SIZE_T,SIZE_T *); NTSYSAPI NTSTATUS WINAPI ApiSetQueryApiSetPresence(const UNICODE_STRING*,BOOLEAN*); NTSYSAPI NTSTATUS WINAPI ApiSetQueryApiSetPresenceEx(const UNICODE_STRING*,BOOLEAN*,BOOLEAN*); NTSYSAPI void WINAPI DbgBreakPoint(void); @@ -4570,6 +4726,18 @@ NTSYSAPI NTSTATUS WINAPI NtAllocateReserveObject(HANDLE *handle,const OBJECT_AT NTSYSAPI NTSTATUS WINAPI NtAllocateUuids(PULARGE_INTEGER,PULONG,PULONG,PUCHAR); NTSYSAPI NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE,PVOID*,ULONG_PTR,SIZE_T*,ULONG,ULONG); NTSYSAPI NTSTATUS WINAPI NtAllocateVirtualMemoryEx(HANDLE,PVOID*,SIZE_T*,ULONG,ULONG,MEM_EXTENDED_PARAMETER*,ULONG); +NTSYSAPI NTSTATUS WINAPI NtAlpcAcceptConnectPort(HANDLE*,HANDLE,DWORD,OBJECT_ATTRIBUTES*,ALPC_PORT_ATTRIBUTES*,void*,ALPC_PORT_MESSAGE*,ALPC_MESSAGE_ATTRIBUTES*,BOOLEAN); +NTSYSAPI NTSTATUS WINAPI NtAlpcConnectPort(HANDLE*,UNICODE_STRING*,OBJECT_ATTRIBUTES*,ALPC_PORT_ATTRIBUTES*,DWORD,PSID,ALPC_PORT_MESSAGE*,SIZE_T*, ALPC_MESSAGE_ATTRIBUTES*,ALPC_MESSAGE_ATTRIBUTES*,LARGE_INTEGER*); +NTSYSAPI NTSTATUS WINAPI NtAlpcCreatePort(HANDLE*,OBJECT_ATTRIBUTES*,ALPC_PORT_ATTRIBUTES*); +NTSYSAPI NTSTATUS WINAPI NtAlpcCreatePortSection(HANDLE,ULONG,HANDLE,SIZE_T,HANDLE*,SIZE_T*); +NTSYSAPI NTSTATUS WINAPI NtAlpcCreateSectionView(HANDLE,ULONG,ALPC_VIEW_ATTR *); +NTSYSAPI NTSTATUS WINAPI NtAlpcCreateSecurityContext(HANDLE,ULONG,ALPC_SECURITY_ATTR *); +NTSYSAPI NTSTATUS WINAPI NtAlpcDeletePortSection(HANDLE, ULONG, HANDLE); +NTSYSAPI NTSTATUS WINAPI NtAlpcDeleteSectionView(HANDLE,ULONG,PVOID); +NTSYSAPI NTSTATUS WINAPI NtAlpcDeleteSecurityContext(HANDLE,ULONG,HANDLE); +NTSYSAPI NTSTATUS WINAPI NtAlpcDisconnectPort(HANDLE,ULONG); +NTSYSAPI NTSTATUS WINAPI NtAlpcImpersonateClientOfPort(HANDLE,ALPC_PORT_MESSAGE*,void*); +NTSYSAPI NTSTATUS WINAPI NtAlpcSendWaitReceivePort(HANDLE,DWORD,ALPC_PORT_MESSAGE*,ALPC_MESSAGE_ATTRIBUTES*,ALPC_PORT_MESSAGE*, SIZE_T*,ALPC_MESSAGE_ATTRIBUTES*,LARGE_INTEGER*); NTSYSAPI NTSTATUS WINAPI NtAreMappedFilesTheSame(PVOID,PVOID); NTSYSAPI NTSTATUS WINAPI NtAssignProcessToJobObject(HANDLE,HANDLE); NTSYSAPI NTSTATUS WINAPI NtCallbackReturn(PVOID,ULONG,NTSTATUS); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10492
From: Zhiyi Zhang <zzhang@codeweavers.com> --- dlls/ntdll/tests/Makefile.in | 1 + dlls/ntdll/tests/alpc.c | 137 +++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 dlls/ntdll/tests/alpc.c diff --git a/dlls/ntdll/tests/Makefile.in b/dlls/ntdll/tests/Makefile.in index 42d663777ea..96265a69344 100644 --- a/dlls/ntdll/tests/Makefile.in +++ b/dlls/ntdll/tests/Makefile.in @@ -2,6 +2,7 @@ TESTDLL = ntdll.dll IMPORTS = user32 advapi32 SOURCES = \ + alpc.c \ atom.c \ change.c \ directory.c \ diff --git a/dlls/ntdll/tests/alpc.c b/dlls/ntdll/tests/alpc.c new file mode 100644 index 00000000000..1bf0bdfea72 --- /dev/null +++ b/dlls/ntdll/tests/alpc.c @@ -0,0 +1,137 @@ +/* + * Advanced Local Procedure Call tests + * + * Copyright 2026 Zhiyi Zhang for CodeWeavers + * + * 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 <stdarg.h> +#include <windef.h> +#include <winternl.h> +#include "wine/test.h" + +#define DECL_FUNCPTR(f) static typeof(f) *p##f; + +DECL_FUNCPTR(AlpcGetHeaderSize) + +#undef DECL_FUNCPTR + +static void init_functions(void) +{ + HMODULE ntdll; + + ntdll = GetModuleHandleA("ntdll.dll"); + ok(ntdll != NULL, "GetModuleHandleA failed.\n"); + +#define LOAD_FUNCPTR(f) p##f = (void *)GetProcAddress(ntdll, #f); + + LOAD_FUNCPTR(AlpcGetHeaderSize) + +#undef LOAD_FUNCPTR +} + +static void test_AlpcGetHeaderSize(void) +{ + unsigned int i, j; + SIZE_T size; + + static const struct + { + ULONG attribute; + SIZE_T size; + } + tests[] = + { + {0, 0}, + {1u << 1, 0}, + {1u << 2, 0}, + {1u << 3, 0}, + {1u << 4, 0}, + {1u << 5, 0}, + {1u << 6, 0}, + {1u << 7, 0}, + {1u << 8, 0}, + {1u << 9, 0}, + {1u << 10, 0}, + {1u << 11, 0}, + {1u << 12, 0}, + {1u << 13, 0}, + {1u << 14, 0}, + {1u << 15, 0}, + {1u << 16, 0}, + {1u << 17, 0}, + {1u << 18, 0}, + {1u << 19, 0}, + {1u << 20, 0}, + {1u << 21, 0}, + {1u << 22, 0}, + {1u << 23, 0}, + {1u << 24, 0}, + {1u << 25, sizeof(ALPC_WORK_ON_BEHALF_ATTR)}, /* ALPC_MESSAGE_WORK_ON_BEHALF_ATTRIBUTE */ + {1u << 26, sizeof(ALPC_DIRECT_ATTR)}, /* ALPC_MESSAGE_DIRECT_ATTRIBUTE */ + {1u << 27, sizeof(ALPC_TOKEN_ATTR)}, /* ALPC_MESSAGE_TOKEN_ATTRIBUTE */ + {1u << 28, sizeof(ALPC_HANDLE_ATTR)}, /* ALPC_MESSAGE_HANDLE_ATTRIBUTE */ + {1u << 29, sizeof(ALPC_CONTEXT_ATTR)}, /* ALPC_MESSAGE_CONTEXT_ATTRIBUTE */ + {1u << 30, sizeof(ALPC_VIEW_ATTR)}, /* ALPC_MESSAGE_VIEW_ATTRIBUTE */ + {1u << 31, sizeof(ALPC_SECURITY_ATTR)}, /* ALPC_MESSAGE_SECURITY_ATTRIBUTE */ + {0xffffffff, sizeof(ALPC_WORK_ON_BEHALF_ATTR) + + sizeof(ALPC_DIRECT_ATTR) + + sizeof(ALPC_TOKEN_ATTR) + + sizeof(ALPC_HANDLE_ATTR) + + sizeof(ALPC_CONTEXT_ATTR) + + sizeof(ALPC_VIEW_ATTR) + + sizeof(ALPC_SECURITY_ATTR)}, /* All attributes */ + }; + + if (!pAlpcGetHeaderSize) + { + todo_wine + win_skip("AlpcGetHeaderSize is unavailable.\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + winetest_push_context("i %d", i); + + /* Single attribute */ + size = pAlpcGetHeaderSize(tests[i].attribute); + ok(size == sizeof(ALPC_MESSAGE_ATTRIBUTES) + tests[i].size, "Got unexpected size %Ix.\n", size); + + /* Two attributes */ + for (j = 0; j < ARRAY_SIZE(tests); j++) + { + if (tests[i].attribute & tests[j].attribute) + continue; + + winetest_push_context("j %d", j); + + size = pAlpcGetHeaderSize(tests[i].attribute | tests[j].attribute); + ok(size == sizeof(ALPC_MESSAGE_ATTRIBUTES) + tests[i].size + tests[j].size, + "Got unexpected size %Ix.\n", size); + + winetest_pop_context(); + } + winetest_pop_context(); + } +} + +START_TEST(alpc) +{ + init_functions(); + + test_AlpcGetHeaderSize(); +} -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10492
From: Zhiyi Zhang <zzhang@codeweavers.com> --- dlls/ntdll/Makefile.in | 1 + dlls/ntdll/alpc.c | 58 +++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/tests/alpc.c | 1 - 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 dlls/ntdll/alpc.c diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in index ad5c3bdc60f..4a912adaa82 100644 --- a/dlls/ntdll/Makefile.in +++ b/dlls/ntdll/Makefile.in @@ -15,6 +15,7 @@ VER_PRODUCTVERSION = 6,1,7601,24059 SOURCES = \ actctx.c \ + alpc.c \ atom.c \ crypt.c \ debugbuffer.c \ diff --git a/dlls/ntdll/alpc.c b/dlls/ntdll/alpc.c new file mode 100644 index 00000000000..730d2942890 --- /dev/null +++ b/dlls/ntdll/alpc.c @@ -0,0 +1,58 @@ +/* + * Advanced Local Procedure Call + * + * Copyright 2026 Zhiyi Zhang for CodeWeavers + * + * 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 <stdarg.h> +#include <windef.h> +#include <winternl.h> +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(alpc); + +SIZE_T WINAPI AlpcGetHeaderSize(ULONG attribute_flags) +{ + static const struct + { + ULONG attribute; + SIZE_T size; + } attribute_sizes[] = + { + /* Attribute with a higher bit is stored before that with a lower bit */ + {ALPC_MESSAGE_SECURITY_ATTRIBUTE, sizeof(ALPC_SECURITY_ATTR)}, + {ALPC_MESSAGE_VIEW_ATTRIBUTE, sizeof(ALPC_VIEW_ATTR)}, + {ALPC_MESSAGE_CONTEXT_ATTRIBUTE, sizeof(ALPC_CONTEXT_ATTR)}, + {ALPC_MESSAGE_HANDLE_ATTRIBUTE, sizeof(ALPC_HANDLE_ATTR)}, + {ALPC_MESSAGE_TOKEN_ATTRIBUTE, sizeof(ALPC_TOKEN_ATTR)}, + {ALPC_MESSAGE_DIRECT_ATTRIBUTE, sizeof(ALPC_DIRECT_ATTR)}, + {ALPC_MESSAGE_WORK_ON_BEHALF_ATTRIBUTE, sizeof(ALPC_WORK_ON_BEHALF_ATTR)}, + }; + unsigned int i; + SIZE_T size; + + TRACE("%#lx.\n", attribute_flags); + + size = sizeof(ALPC_MESSAGE_ATTRIBUTES); + for (i = 0; i < ARRAY_SIZE(attribute_sizes); i++) + { + if (attribute_flags & attribute_sizes[i].attribute) + size += attribute_sizes[i].size; + } + + return size; +} diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index f289709f68d..55a05d084e8 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -6,6 +6,7 @@ @ stdcall A_SHAFinal(ptr ptr) @ stdcall A_SHAInit(ptr) @ stdcall A_SHAUpdate(ptr ptr long) +@ stdcall AlpcGetHeaderSize(long) @ stdcall ApiSetQueryApiSetPresence(ptr ptr) @ stdcall ApiSetQueryApiSetPresenceEx(ptr ptr ptr) @ stub CsrAllocateCaptureBuffer diff --git a/dlls/ntdll/tests/alpc.c b/dlls/ntdll/tests/alpc.c index 1bf0bdfea72..d7921e67b50 100644 --- a/dlls/ntdll/tests/alpc.c +++ b/dlls/ntdll/tests/alpc.c @@ -98,7 +98,6 @@ static void test_AlpcGetHeaderSize(void) if (!pAlpcGetHeaderSize) { - todo_wine win_skip("AlpcGetHeaderSize is unavailable.\n"); return; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10492
From: Zhiyi Zhang <zzhang@codeweavers.com> --- dlls/ntdll/tests/alpc.c | 116 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/dlls/ntdll/tests/alpc.c b/dlls/ntdll/tests/alpc.c index d7921e67b50..504b47fda4d 100644 --- a/dlls/ntdll/tests/alpc.c +++ b/dlls/ntdll/tests/alpc.c @@ -21,11 +21,13 @@ #include <stdarg.h> #include <windef.h> #include <winternl.h> +#include <ntstatus.h> #include "wine/test.h" #define DECL_FUNCPTR(f) static typeof(f) *p##f; DECL_FUNCPTR(AlpcGetHeaderSize) +DECL_FUNCPTR(AlpcInitializeMessageAttribute) #undef DECL_FUNCPTR @@ -39,6 +41,7 @@ static void init_functions(void) #define LOAD_FUNCPTR(f) p##f = (void *)GetProcAddress(ntdll, #f); LOAD_FUNCPTR(AlpcGetHeaderSize) + LOAD_FUNCPTR(AlpcInitializeMessageAttribute) #undef LOAD_FUNCPTR } @@ -128,9 +131,122 @@ static void test_AlpcGetHeaderSize(void) } } +static void test_AlpcInitializeMessageAttribute(void) +{ + unsigned char buffer[1024]; + ALPC_MESSAGE_ATTRIBUTES *attr = (ALPC_MESSAGE_ATTRIBUTES *)buffer; + SIZE_T required_size, size; + unsigned int i, j, k; + NTSTATUS status; + + static const ULONG attributes[] = + { + 0, + ALPC_MESSAGE_WORK_ON_BEHALF_ATTRIBUTE, + ALPC_MESSAGE_DIRECT_ATTRIBUTE, + ALPC_MESSAGE_TOKEN_ATTRIBUTE, + ALPC_MESSAGE_HANDLE_ATTRIBUTE, + ALPC_MESSAGE_CONTEXT_ATTRIBUTE, + ALPC_MESSAGE_VIEW_ATTRIBUTE, + ALPC_MESSAGE_SECURITY_ATTRIBUTE, + 0xffffffff, + }; + + if (!pAlpcInitializeMessageAttribute) + { + todo_wine + win_skip("AlpcInitializeMessageAttribute is unavailable.\n"); + return; + } + + /* Check parameters */ + for (i = 0; i < ARRAY_SIZE(attributes); i++) + { + winetest_push_context("i %d", i); + + size = pAlpcGetHeaderSize(attributes[i]); + + /* Null message pointer */ + required_size = 0; + status = pAlpcInitializeMessageAttribute(attributes[i], NULL, size, &required_size); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + ok(required_size == size, "Expected %Ix, got %Ix.\n", size, required_size); + + /* Buffer too small */ + attr->AllocatedAttributes = 0xdeadbeef; + attr->ValidAttributes = 0xdeadbeef; + required_size = 0; + status = pAlpcInitializeMessageAttribute(attributes[i], attr, size - 1, &required_size); + ok(status == STATUS_BUFFER_TOO_SMALL, "Got unexpected status %#lx.\n", status); + ok(attr->AllocatedAttributes == 0xdeadbeef, "Got unexpected %#lx.\n", attr->AllocatedAttributes); + ok(attr->ValidAttributes == 0xdeadbeef, "Got unexpected %#lx.\n", attr->ValidAttributes); + ok(required_size == size, "Expected %Ix, got %Ix.\n", size, required_size); + + /* Buffer too large */ + attr->AllocatedAttributes = 0xdeadbeef; + attr->ValidAttributes = 0xdeadbeef; + required_size = 0; + status = pAlpcInitializeMessageAttribute(attributes[i], attr, size + 1, &required_size); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + ok(attr->AllocatedAttributes == attributes[i], "Got unexpected %#lx.\n", attr->AllocatedAttributes); + ok(attr->ValidAttributes == 0, "Got unexpected %#lx.\n", attr->ValidAttributes); + ok(required_size == size, "Expected %Ix, got %Ix.\n", size, required_size); + + /* Correct buffer size */ + memset(buffer, 0xa1, sizeof(buffer)); + required_size = 0; + status = pAlpcInitializeMessageAttribute(attributes[i], attr, size, &required_size); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + ok(attr->AllocatedAttributes == attributes[i], "Got unexpected %#lx.\n", attr->AllocatedAttributes); + ok(attr->ValidAttributes == 0, "Got unexpected %#lx.\n", attr->ValidAttributes); + ok(required_size == size, "Expected %Ix, got %Ix.\n", size, required_size); + /* Test that AlpcInitializeMessageAttribute() only sets AllocatedAttributes and ValidAttributes */ + for (k = sizeof(*attr); k < sizeof(buffer); k++) + { + if (buffer[k] != 0xa1) + { + ok(0, "Marker got overwritten at %d.\n", k); + break; + } + } + + /* Two attributes */ + for (j = 0; j < ARRAY_SIZE(attributes); j++) + { + if (attributes[i] & attributes[j]) + continue; + + winetest_push_context("j %d", j); + + memset(buffer, 0xb2, sizeof(buffer)); + size = pAlpcGetHeaderSize(attributes[i] | attributes[j]); + required_size = 0; + status = pAlpcInitializeMessageAttribute(attributes[i] | attributes[j], attr, size, &required_size); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + ok(attr->AllocatedAttributes == (attributes[i] | attributes[j]), + "Got unexpected %#lx.\n", attr->AllocatedAttributes); + ok(attr->ValidAttributes == 0, "Got unexpected %#lx.\n", attr->ValidAttributes); + ok(required_size == size, "Expected %Ix, got %Ix.\n", size, required_size); + /* Test that AlpcInitializeMessageAttribute() only sets AllocatedAttributes and ValidAttributes */ + for (k = sizeof(*attr); k < sizeof(buffer); k++) + { + if (buffer[k] != 0xb2) + { + ok(0, "Marker got overwritten at %d.\n", k); + break; + } + } + + winetest_pop_context(); + } + winetest_pop_context(); + } +} + START_TEST(alpc) { init_functions(); test_AlpcGetHeaderSize(); + test_AlpcInitializeMessageAttribute(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10492
From: Zhiyi Zhang <zzhang@codeweavers.com> --- dlls/ntdll/alpc.c | 21 +++++++++++++++++++++ dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/tests/alpc.c | 1 - 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/alpc.c b/dlls/ntdll/alpc.c index 730d2942890..81e4641876d 100644 --- a/dlls/ntdll/alpc.c +++ b/dlls/ntdll/alpc.c @@ -21,6 +21,7 @@ #include <stdarg.h> #include <windef.h> #include <winternl.h> +#include <ntstatus.h> #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(alpc); @@ -56,3 +57,23 @@ SIZE_T WINAPI AlpcGetHeaderSize(ULONG attribute_flags) return size; } + +NTSTATUS WINAPI AlpcInitializeMessageAttribute(ULONG attribute_flags, ALPC_MESSAGE_ATTRIBUTES *buffer, + SIZE_T buffer_size, SIZE_T *required_buffer_size) +{ + TRACE("%#lx, %p, %Ix, %p.\n", attribute_flags, buffer, buffer_size, required_buffer_size); + + *required_buffer_size = AlpcGetHeaderSize(attribute_flags); + + if (buffer_size < *required_buffer_size) + return STATUS_BUFFER_TOO_SMALL; + + if (buffer) + { + buffer->AllocatedAttributes = attribute_flags; + buffer->ValidAttributes = 0; + } + + return STATUS_SUCCESS; + +} diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 55a05d084e8..578bfc7963e 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -7,6 +7,7 @@ @ stdcall A_SHAInit(ptr) @ stdcall A_SHAUpdate(ptr ptr long) @ stdcall AlpcGetHeaderSize(long) +@ stdcall AlpcInitializeMessageAttribute(long ptr long ptr) @ stdcall ApiSetQueryApiSetPresence(ptr ptr) @ stdcall ApiSetQueryApiSetPresenceEx(ptr ptr ptr) @ stub CsrAllocateCaptureBuffer diff --git a/dlls/ntdll/tests/alpc.c b/dlls/ntdll/tests/alpc.c index 504b47fda4d..9b10926f27e 100644 --- a/dlls/ntdll/tests/alpc.c +++ b/dlls/ntdll/tests/alpc.c @@ -154,7 +154,6 @@ static void test_AlpcInitializeMessageAttribute(void) if (!pAlpcInitializeMessageAttribute) { - todo_wine win_skip("AlpcInitializeMessageAttribute is unavailable.\n"); return; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10492
From: Zhiyi Zhang <zzhang@codeweavers.com> --- dlls/ntdll/tests/alpc.c | 102 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/dlls/ntdll/tests/alpc.c b/dlls/ntdll/tests/alpc.c index 9b10926f27e..667a2899ec5 100644 --- a/dlls/ntdll/tests/alpc.c +++ b/dlls/ntdll/tests/alpc.c @@ -27,6 +27,7 @@ #define DECL_FUNCPTR(f) static typeof(f) *p##f; DECL_FUNCPTR(AlpcGetHeaderSize) +DECL_FUNCPTR(AlpcGetMessageAttribute) DECL_FUNCPTR(AlpcInitializeMessageAttribute) #undef DECL_FUNCPTR @@ -41,6 +42,7 @@ static void init_functions(void) #define LOAD_FUNCPTR(f) p##f = (void *)GetProcAddress(ntdll, #f); LOAD_FUNCPTR(AlpcGetHeaderSize) + LOAD_FUNCPTR(AlpcGetMessageAttribute) LOAD_FUNCPTR(AlpcInitializeMessageAttribute) #undef LOAD_FUNCPTR @@ -131,6 +133,105 @@ static void test_AlpcGetHeaderSize(void) } } +static void test_AlpcGetMessageAttribute(void) +{ + unsigned char buffer[1024]; + ALPC_MESSAGE_ATTRIBUTES *attr = (ALPC_MESSAGE_ATTRIBUTES *)buffer; + unsigned int i, j; + void *ptr; + + static const ULONG attributes[] = + { + 0, + ALPC_MESSAGE_WORK_ON_BEHALF_ATTRIBUTE, + ALPC_MESSAGE_DIRECT_ATTRIBUTE, + ALPC_MESSAGE_TOKEN_ATTRIBUTE, + ALPC_MESSAGE_HANDLE_ATTRIBUTE, + ALPC_MESSAGE_CONTEXT_ATTRIBUTE, + ALPC_MESSAGE_VIEW_ATTRIBUTE, + ALPC_MESSAGE_SECURITY_ATTRIBUTE, + }; + + if (!pAlpcGetMessageAttribute) + { + todo_wine + win_skip("AlpcGetMessageAttribute is unavailable.\n"); + return; + } + + /* Invalid flag */ + attr->AllocatedAttributes = ALPC_MESSAGE_ATTRIBUTE_ALL; + attr->ValidAttributes = ALPC_MESSAGE_ATTRIBUTE_ALL; + ptr = pAlpcGetMessageAttribute(attr, 0x1); + ok(ptr == NULL, "Got unexpected ptr.\n"); + + for (i = 0; i < ARRAY_SIZE(attributes); i++) + { + winetest_push_context("%#lx", attributes[i]); + + /* The message has no allocated attributes */ + attr->AllocatedAttributes = 0; + attr->ValidAttributes = attributes[i]; + ptr = pAlpcGetMessageAttribute(attr, attributes[i]); + ok(ptr == NULL, "Got unexpected ptr.\n"); + + /* The message has no valid attributes */ + attr->AllocatedAttributes = attributes[i]; + attr->ValidAttributes = 0; + ptr = pAlpcGetMessageAttribute(attr, attributes[i]); + if (attributes[i]) + ok(ptr == ((unsigned char *)attr + sizeof(*attr)), "Got unexpected ptr.\n"); + else + ok(ptr == NULL, "Got unexpected ptr.\n"); + + /* Normal calls */ + attr->AllocatedAttributes = attributes[i]; + attr->ValidAttributes = attributes[i]; + ptr = pAlpcGetMessageAttribute(attr, attributes[i]); + if (attributes[i]) + ok(ptr == ((unsigned char *)attr + sizeof(*attr)), "Got unexpected ptr.\n"); + else + ok(ptr == NULL, "Got unexpected ptr.\n"); + + /* The message has full attributes */ + attr->AllocatedAttributes = ALPC_MESSAGE_ATTRIBUTE_ALL; + attr->ValidAttributes = ALPC_MESSAGE_ATTRIBUTE_ALL; + ptr = pAlpcGetMessageAttribute(attr, attributes[i]); + if (attributes[i]) + ok(ptr == ((unsigned char *)attr + pAlpcGetHeaderSize(attr->AllocatedAttributes & ~(attributes[i] | (attributes[i] - 1)))), + "Got unexpected ptr.\n"); + else + ok(ptr == NULL, "Got unexpected ptr.\n"); + + /* The message has some valid attributes */ + for (j = 0; j < ARRAY_SIZE(attributes); j++) + { + attr->AllocatedAttributes = ALPC_MESSAGE_ATTRIBUTE_ALL; + attr->ValidAttributes = ALPC_MESSAGE_ATTRIBUTE_ALL & ~attributes[j]; + ptr = pAlpcGetMessageAttribute(attr, attributes[i]); + if (attributes[i]) + ok(ptr == ((unsigned char *)attr + pAlpcGetHeaderSize(attr->AllocatedAttributes & ~(attributes[i] | (attributes[i] - 1)))), + "Got unexpected ptr.\n"); + else + ok(ptr == NULL, "Got unexpected ptr.\n"); + } + + /* Two attributes are passed to AlpcGetMessageAttribute() */ + for (j = 0; j < ARRAY_SIZE(attributes); j++) + { + if (!attributes[i] || !attributes[j] || attributes[i] == attributes[j]) + continue; + + attr->AllocatedAttributes = ALPC_MESSAGE_ATTRIBUTE_ALL; + attr->ValidAttributes = ALPC_MESSAGE_ATTRIBUTE_ALL; + ptr = pAlpcGetMessageAttribute(attr, attributes[i] | attributes[j]); + ok(ptr == NULL, "Got unexpected ptr.\n"); + } + + winetest_pop_context(); + } +} + static void test_AlpcInitializeMessageAttribute(void) { unsigned char buffer[1024]; @@ -247,5 +348,6 @@ START_TEST(alpc) init_functions(); test_AlpcGetHeaderSize(); + test_AlpcGetMessageAttribute(); test_AlpcInitializeMessageAttribute(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10492
From: Zhiyi Zhang <zzhang@codeweavers.com> --- dlls/ntdll/alpc.c | 19 +++++++++++++++++++ dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/tests/alpc.c | 1 - 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/alpc.c b/dlls/ntdll/alpc.c index 81e4641876d..cba85e19a83 100644 --- a/dlls/ntdll/alpc.c +++ b/dlls/ntdll/alpc.c @@ -58,6 +58,25 @@ SIZE_T WINAPI AlpcGetHeaderSize(ULONG attribute_flags) return size; } +void * WINAPI AlpcGetMessageAttribute(ALPC_MESSAGE_ATTRIBUTES *attributes, ULONG attribute_flag) +{ + TRACE("%p, %lx.\n", attributes, attribute_flag); + + /* If no flag is specified */ + if (!attribute_flag) + return NULL; + + /* If more than one flag is specified */ + if (attribute_flag & (attribute_flag - 1)) + return NULL; + + /* If the specified flag is not in allocated attributes */ + if ((attribute_flag & attributes->AllocatedAttributes & ALPC_MESSAGE_ATTRIBUTE_ALL) != attribute_flag) + return NULL; + + return (unsigned char *)attributes + AlpcGetHeaderSize(attributes->AllocatedAttributes & ~(attribute_flag | (attribute_flag - 1))); +} + NTSTATUS WINAPI AlpcInitializeMessageAttribute(ULONG attribute_flags, ALPC_MESSAGE_ATTRIBUTES *buffer, SIZE_T buffer_size, SIZE_T *required_buffer_size) { diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 578bfc7963e..f396c334e2d 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -8,6 +8,7 @@ @ stdcall A_SHAUpdate(ptr ptr long) @ stdcall AlpcGetHeaderSize(long) @ stdcall AlpcInitializeMessageAttribute(long ptr long ptr) +@ stdcall AlpcGetMessageAttribute(ptr long) @ stdcall ApiSetQueryApiSetPresence(ptr ptr) @ stdcall ApiSetQueryApiSetPresenceEx(ptr ptr ptr) @ stub CsrAllocateCaptureBuffer diff --git a/dlls/ntdll/tests/alpc.c b/dlls/ntdll/tests/alpc.c index 667a2899ec5..f34da209041 100644 --- a/dlls/ntdll/tests/alpc.c +++ b/dlls/ntdll/tests/alpc.c @@ -154,7 +154,6 @@ static void test_AlpcGetMessageAttribute(void) if (!pAlpcGetMessageAttribute) { - todo_wine win_skip("AlpcGetMessageAttribute is unavailable.\n"); return; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10492
participants (2)
-
Zhiyi Zhang -
Zhiyi Zhang (@zhiyi)