Add tests for object type IoCompletionReserve and UserApcReserve.
-- v2: ntdll/tests: Add NtAllocateReserveObject() tests. ntdll: Implement NtAllocateReserveObject(). ntdll/tests: Add reserve object tests. gitlab: Update generated files for static analysis.
From: Zhiyi Zhang zzhang@codeweavers.com
--- tools/gitlab/build.yml | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/tools/gitlab/build.yml b/tools/gitlab/build.yml index 02be45e7b73..184957fd6e3 100644 --- a/tools/gitlab/build.yml +++ b/tools/gitlab/build.yml @@ -90,6 +90,10 @@ build-sast: -Xclang -analyzer-disable-checker=deadcode.DeadStores -Xclang -analyzer-disable-checker=unix.Malloc script: + - ./tools/make_requests + - ./tools/make_specfiles + - ./tools/make_makefiles + - autoreconf -f - cd build64 - ../configure -q -C --enable-sast --enable-win64 - make -s gl-code-quality-report.json SASTFLAGS="${SASTFLAGS}"
From: Zhiyi Zhang zzhang@codeweavers.com
Add tests for object type IoCompletionReserve and UserApcReserve. --- dlls/ntdll/tests/om.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index fb45fe777b7..61847e40887 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -2206,6 +2206,10 @@ static void test_token(void) #define IO_COMPLETION_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE) #define IO_COMPLETION_GENERIC_READ (STANDARD_RIGHTS_READ|IO_COMPLETION_QUERY_STATE) #define IO_COMPLETION_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|IO_COMPLETION_MODIFY_STATE) +#define IO_COMPLETION_RESERVE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE) +#define IO_COMPLETION_RESERVE_GENERIC_READ (STANDARD_RIGHTS_READ|0x1) +#define IO_COMPLETION_RESERVE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|0x2) +#define IO_COMPLETION_RESERVE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x3) #define JOB_OBJECT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE) #define JOB_OBJECT_GENERIC_READ (STANDARD_RIGHTS_READ|JOB_OBJECT_QUERY) #define JOB_OBJECT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|JOB_OBJECT_TERMINATE|\ @@ -2253,6 +2257,10 @@ static void test_token(void) #define TYPE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE) #define TYPE_GENERIC_READ (STANDARD_RIGHTS_READ) #define TYPE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE) +#define USER_APC_RESERVE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE) +#define USER_APC_RESERVE_GENERIC_READ (STANDARD_RIGHTS_READ|0x1) +#define USER_APC_RESERVE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|0x2) +#define USER_APC_RESERVE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x3) #define WINSTA_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|WINSTA_EXITWINDOWS|WINSTA_ACCESSGLOBALATOMS) #define WINSTA_GENERIC_READ (STANDARD_RIGHTS_READ|WINSTA_READSCREEN|WINSTA_ENUMERATE|\ WINSTA_READATTRIBUTES|WINSTA_ENUMDESKTOPS) @@ -2318,6 +2326,7 @@ static void test_object_types(void) TYPE( L"Event", EVENT, 0, 0 ), TYPE( L"File", FILE, 0, 0 ), TYPE( L"IoCompletion", IO_COMPLETION, 0, 0 ), + TYPE( L"IoCompletionReserve", IO_COMPLETION_RESERVE, 0, 0 ), TYPE( L"Job", JOB_OBJECT, 0, JOB_OBJECT_IMPERSONATE ), TYPE( L"Key", KEY, SYNCHRONIZE, 0 ), TYPE( L"KeyedEvent", KEYEDEVENT, SYNCHRONIZE, 0 ), @@ -2330,6 +2339,7 @@ static void test_object_types(void) TYPE( L"Timer", TIMER, 0, 0 ), TYPE( L"Token", TOKEN, SYNCHRONIZE, 0 ), TYPE( L"Type", TYPE, SYNCHRONIZE, 0 ), + TYPE( L"UserApcReserve", USER_APC_RESERVE, 0, 0 ), TYPE( L"WindowStation", WINSTA, 0, 0 ), #undef TYPE }; @@ -2390,6 +2400,8 @@ static void test_object_types(void) tested[j] = TRUE; break; } + + todo_wine_if(!lstrcmpW( tests[i].name, L"IoCompletionReserve" ) || !lstrcmpW( tests[i].name, L"UserApcReserve" )) ok( j < ARRAY_SIZE(all_types), "type %s not found\n", debugstr_w(tests[i].name) ); } for (j = 0; j < ARRAY_SIZE(all_types); j++)
From: Zhiyi Zhang zzhang@codeweavers.com
React Native applications need a real kernel handle from NtAllocateReserveObject(). NtAllocateReserveObject() pre-allocates memory for objects to deal with low memory situations. Due to no APIs in Wine actually uses NtAllocateReserveObject(), for now no memory is reserved. --- dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/signal_arm64ec.c | 1 + dlls/ntdll/tests/om.c | 1 - dlls/ntdll/unix/server.c | 25 +++++++ dlls/wow64/syscall.c | 17 +++++ include/winternl.h | 7 ++ server/directory.c | 2 + server/object.c | 145 ++++++++++++++++++++++++++++++++++++ server/object.h | 2 + server/protocol.def | 9 +++ 10 files changed, 209 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 1234205cf1a..5fe8dcc4a0b 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -145,6 +145,7 @@ @ stdcall -syscall NtAlertThread(long) @ stdcall -syscall NtAlertThreadByThreadId(ptr) @ stdcall -syscall NtAllocateLocallyUniqueId(ptr) +@ stdcall -syscall NtAllocateReserveObject(ptr long long) # @ stub NtAllocateUserPhysicalPages @ stdcall -syscall NtAllocateUuids(ptr ptr ptr ptr) @ stdcall -syscall NtAllocateVirtualMemory(long ptr long ptr long long) diff --git a/dlls/ntdll/signal_arm64ec.c b/dlls/ntdll/signal_arm64ec.c index 65eaf010e4d..438dfe8d439 100644 --- a/dlls/ntdll/signal_arm64ec.c +++ b/dlls/ntdll/signal_arm64ec.c @@ -251,6 +251,7 @@ DEFINE_SYSCALL(NtAlertResumeThread, (HANDLE handle, ULONG *count)) DEFINE_SYSCALL(NtAlertThread, (HANDLE handle)) DEFINE_SYSCALL(NtAlertThreadByThreadId, (HANDLE tid)) DEFINE_SYSCALL(NtAllocateLocallyUniqueId, (LUID *luid)) +DEFINE_SYSCALL(NtAllocateReserveObject, (HANDLE *handle, const OBJECT_ATTRIBUTES *attr, MEMORY_RESERVE_OBJECT_TYPE type)) 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)) diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index 61847e40887..1b6cabb0528 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -2401,7 +2401,6 @@ static void test_object_types(void) break; }
- todo_wine_if(!lstrcmpW( tests[i].name, L"IoCompletionReserve" ) || !lstrcmpW( tests[i].name, L"UserApcReserve" )) ok( j < ARRAY_SIZE(all_types), "type %s not found\n", debugstr_w(tests[i].name) ); } for (j = 0; j < ARRAY_SIZE(all_types); j++) diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index f3ffd99c3fc..f03d008e2ae 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -1719,6 +1719,31 @@ void server_init_thread( void *entry_point, BOOL *suspend ) close( reply_pipe ); }
+NTSTATUS WINAPI NtAllocateReserveObject( HANDLE *handle, const OBJECT_ATTRIBUTES *attr, + MEMORY_RESERVE_OBJECT_TYPE type ) +{ + struct object_attributes *objattr; + unsigned int ret; + data_size_t len; + + TRACE("(%p, %p, %d)\n", handle, attr, type); + + *handle = 0; + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; + + SERVER_START_REQ( allocate_reserve_object ) + { + req->type = type; + wine_server_add_data( req, objattr, len ); + if (!(ret = wine_server_call( req ))) + *handle = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; + + free( objattr ); + return ret; +} +
/****************************************************************************** * NtDuplicateObject diff --git a/dlls/wow64/syscall.c b/dlls/wow64/syscall.c index fc60ae37816..add5c6b9ed7 100644 --- a/dlls/wow64/syscall.c +++ b/dlls/wow64/syscall.c @@ -424,6 +424,23 @@ NTSTATUS WINAPI wow64_NtAllocateLocallyUniqueId( UINT *args ) return NtAllocateLocallyUniqueId( luid ); }
+/********************************************************************** + * wow64_NtAllocateReserveObject + */ +NTSTATUS WINAPI wow64_NtAllocateReserveObject( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + MEMORY_RESERVE_OBJECT_TYPE type = get_ulong( &args ); + NTSTATUS status; + + struct object_attr64 attr; + HANDLE handle = 0; + + status = NtAllocateReserveObject( &handle, objattr_32to64_redirect( &attr, attr32 ), type); + put_handle( handle_ptr, handle ); + return status; +}
/********************************************************************** * wow64_NtAllocateUuids diff --git a/include/winternl.h b/include/winternl.h index 4f24a921bb1..53f11b18486 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2553,6 +2553,12 @@ typedef struct _KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 { UCHAR Data[1]; } KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, *PKEY_VALUE_PARTIAL_INFORMATION_ALIGN64;
+typedef enum _MEMORY_RESERVE_OBJECT_TYPE +{ + MemoryReserveObjectTypeUserApc, + MemoryReserveObjectTypeIoCompletion +} MEMORY_RESERVE_OBJECT_TYPE, PMEMORY_RESERVE_OBJECT_TYPE; + #ifndef __OBJECT_ATTRIBUTES_DEFINED__ #define __OBJECT_ATTRIBUTES_DEFINED__ typedef struct _OBJECT_ATTRIBUTES { @@ -4441,6 +4447,7 @@ NTSYSAPI NTSTATUS WINAPI NtAlertResumeThread(HANDLE,PULONG); NTSYSAPI NTSTATUS WINAPI NtAlertThread(HANDLE ThreadHandle); NTSYSAPI NTSTATUS WINAPI NtAlertThreadByThreadId(HANDLE); NTSYSAPI NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID lpLuid); +NTSYSAPI NTSTATUS WINAPI NtAllocateReserveObject(HANDLE *handle,const OBJECT_ATTRIBUTES *attr,MEMORY_RESERVE_OBJECT_TYPE type); 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); diff --git a/server/directory.c b/server/directory.c index b3f055dfd01..b37ec969a9e 100644 --- a/server/directory.c +++ b/server/directory.c @@ -161,6 +161,8 @@ static struct type_descr *types[] = &file_type, &mapping_type, &key_type, + &apc_reserve_type, + &completion_reserve_type, };
static void object_type_dump( struct object *obj, int verbose ) diff --git a/server/object.c b/server/object.c index 1a3bff65969..04f334ffcf5 100644 --- a/server/object.c +++ b/server/object.c @@ -41,6 +41,8 @@ #include "thread.h" #include "unicode.h" #include "security.h" +#include "handle.h" +#include "request.h"
struct namespace @@ -62,6 +64,90 @@ struct type_descr no_type = }, };
+struct reserve +{ + struct object obj; /* object header */ + int type; /* reserve object type. See MEMORY_RESERVE_OBJECT_TYPE */ + /* BYTE *memory */; /* reserved memory */ +}; + +static const WCHAR apc_reserve_type_name[] = {'U','s','e','r','A','p','c','R','e','s','e','r','v','e'}; +static const WCHAR completion_reserve_name[] = {'I','o','C','o','m','p','l','e','t','i','o','n','R','e','s','e','r','v','e'}; + +struct type_descr apc_reserve_type = +{ + { apc_reserve_type_name, sizeof(apc_reserve_type_name) }, /* name */ + STANDARD_RIGHTS_REQUIRED | 0x3, /* valid_access */ + { /* mapping */ + STANDARD_RIGHTS_READ | 0x1, + STANDARD_RIGHTS_WRITE | 0x2, + STANDARD_RIGHTS_EXECUTE, + STANDARD_RIGHTS_REQUIRED | 0x3 + }, +}; + +struct type_descr completion_reserve_type = +{ + { completion_reserve_name, sizeof(completion_reserve_name) }, /* name */ + STANDARD_RIGHTS_REQUIRED | 0x3, /* valid_access */ + { /* mapping */ + STANDARD_RIGHTS_READ | 0x1, + STANDARD_RIGHTS_WRITE | 0x2, + STANDARD_RIGHTS_EXECUTE, + STANDARD_RIGHTS_REQUIRED | 0x3 + }, +}; + +static void dump_reserve( struct object *obj, int verbose ); + +static const struct object_ops apc_reserve_ops = +{ + sizeof(struct reserve), /* size */ + &apc_reserve_type, /* type */ + dump_reserve, /* dump */ + no_add_queue, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + no_satisfied, /* satisfied */ + no_signal, /* signal */ + no_get_fd, /* get_fd */ + default_map_access, /* map_access */ + default_get_sd, /* get_sd */ + default_set_sd, /* set_sd */ + default_get_full_name, /* get_full_name */ + no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ + no_close_handle, /* close_handle */ + no_destroy /* destroy */ +}; + +static const struct object_ops completion_reserve_ops = +{ + sizeof(struct reserve), /* size */ + &completion_reserve_type, /* type */ + dump_reserve, /* dump */ + no_add_queue, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + no_satisfied, /* satisfied */ + no_signal, /* signal */ + no_get_fd, /* get_fd */ + default_map_access, /* map_access */ + default_get_sd, /* get_sd */ + default_set_sd, /* set_sd */ + default_get_full_name, /* get_full_name */ + no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ + no_close_handle, /* close_handle */ + no_destroy /* destroy */ +}; + #ifdef DEBUG_OBJECTS static struct list object_list = LIST_INIT(object_list);
@@ -729,3 +815,62 @@ int no_close_handle( struct object *obj, struct process *process, obj_handle_t h void no_destroy( struct object *obj ) { } + +static void dump_reserve( struct object *obj, int verbose ) +{ + struct reserve *reserve = (struct reserve *) obj; + + assert( obj->ops == &apc_reserve_ops || obj->ops == &completion_reserve_ops ); + fprintf( stderr, "reserve type=%d\n", reserve->type); +} + +struct reserve *create_reserve( struct object *root, const struct unicode_str *name, + unsigned int attr, int type, const struct security_descriptor *sd ) +{ + struct reserve *reserve; + + if (name->len) + { + set_error( STATUS_OBJECT_NAME_INVALID ); + return NULL; + } + + if (type == MemoryReserveObjectTypeUserApc) + { + reserve = create_named_object( root, &apc_reserve_ops, name, attr, sd ); + } + else if (type == MemoryReserveObjectTypeIoCompletion) + { + reserve = create_named_object( root, &completion_reserve_ops, name, attr, sd ); + } + else + { + set_error( STATUS_INVALID_PARAMETER ); + return NULL; + } + + if (reserve && get_error() != STATUS_OBJECT_NAME_EXISTS) reserve->type = type; + + return reserve; +} + +/* Allocate a reserve object for pre-allocating memory for object types */ +DECL_HANDLER(allocate_reserve_object) +{ + struct unicode_str name; + struct object *root; + const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); + struct reserve *reserve; + + if (!objattr) return; + + if ((reserve = create_reserve( root, &name, objattr->attributes, req->type, sd ))) + { + reply->handle = alloc_handle_no_access_check( current->process, reserve, GENERIC_READ | GENERIC_WRITE, + objattr->attributes ); + release_object( reserve ); + } + + if (root) release_object( root ); +} diff --git a/server/object.h b/server/object.h index e35edfa68f4..6222e3352ed 100644 --- a/server/object.h +++ b/server/object.h @@ -331,6 +331,8 @@ extern struct type_descr completion_type; extern struct type_descr file_type; extern struct type_descr mapping_type; extern struct type_descr key_type; +extern struct type_descr apc_reserve_type; +extern struct type_descr completion_reserve_type;
#define KEYEDEVENT_WAIT 0x0001 #define KEYEDEVENT_WAKE 0x0002 diff --git a/server/protocol.def b/server/protocol.def index c6af7379f17..a4f25e805f8 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1254,6 +1254,15 @@ typedef struct @END
+/* Allocate a reserve object for pre-allocating memory for object types */ +@REQ(allocate_reserve_object) + int type; /* reserve object type. See MEMORY_RESERVE_OBJECT_TYPE */ + VARARG(objattr,object_attributes); /* object attributes */ +@REPLY + obj_handle_t handle; /* reserve object handle */ +@END + + /* Test if two handles refer to the same object */ @REQ(compare_objects) obj_handle_t first; /* first object handle */
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/ntdll/tests/om.c | 67 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index 1b6cabb0528..82f49376a97 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -33,6 +33,7 @@ #include "wine/test.h"
static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR ); +static NTSTATUS (WINAPI *pNtAllocateReserveObject)( HANDLE *, const OBJECT_ATTRIBUTES *, MEMORY_RESERVE_OBJECT_TYPE ); static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, EVENT_TYPE, BOOLEAN); static NTSTATUS (WINAPI *pNtOpenEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES); static NTSTATUS (WINAPI *pNtCreateJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES ); @@ -3391,10 +3392,75 @@ static void test_object_permanence(void) ok( status == STATUS_SUCCESS, "NtSetInformationThread returned %08lx\n", status ); }
+static void test_NtAllocateReserveObject(void) +{ + UNICODE_STRING name = RTL_CONSTANT_STRING(L"\BaseNamedObjects\test_NtAllocateReserveObject_name"); + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + HANDLE handle; + int i; + + static const struct + { + MEMORY_RESERVE_OBJECT_TYPE type; + const WCHAR *type_name; + } + tests[] = + { + {MemoryReserveObjectTypeUserApc, L"UserApcReserve"}, + {MemoryReserveObjectTypeIoCompletion, L"IoCompletionReserve"}, + }; + + if (!pNtAllocateReserveObject) + { + win_skip("NtAllocateReserveObject is unavailable.\n"); + return; + } + + InitializeObjectAttributes(&attr, &name, 0, NULL, NULL); + + /* Parameter checks */ + status = pNtAllocateReserveObject(NULL, &attr, MemoryReserveObjectTypeUserApc); + ok(status == STATUS_ACCESS_VIOLATION, "Got unexpected status %#lx.\n", status); + + status = pNtAllocateReserveObject(&handle, NULL, MemoryReserveObjectTypeUserApc); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + status = NtClose(handle); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + + status = pNtAllocateReserveObject(&handle, NULL, MemoryReserveObjectTypeIoCompletion + 1); + ok(status == STATUS_INVALID_PARAMETER, "Got unexpected status %#lx.\n", status); + + status = pNtAllocateReserveObject(&handle, &attr, MemoryReserveObjectTypeUserApc); + ok(status == STATUS_OBJECT_NAME_INVALID, "Got unexpected status %#lx.\n", status); + + attr.ObjectName = NULL; + status = pNtAllocateReserveObject(&handle, &attr, MemoryReserveObjectTypeUserApc); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + status = NtClose(handle); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + + /* Test creating objects */ + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + winetest_push_context("type %d", tests[i].type); + + status = pNtAllocateReserveObject(&handle, NULL, tests[i].type); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + + test_object_type(handle, tests[i].type_name); + + status = NtClose(handle); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + winetest_pop_context(); + } +} + START_TEST(om) { HMODULE hntdll = GetModuleHandleA("ntdll.dll");
+ pNtAllocateReserveObject= (void *)GetProcAddress(hntdll, "NtAllocateReserveObject"); pNtCreateEvent = (void *)GetProcAddress(hntdll, "NtCreateEvent"); pNtCreateJobObject = (void *)GetProcAddress(hntdll, "NtCreateJobObject"); pNtOpenJobObject = (void *)GetProcAddress(hntdll, "NtOpenJobObject"); @@ -3455,4 +3521,5 @@ START_TEST(om) test_object_identity(); test_query_directory(); test_object_permanence(); + test_NtAllocateReserveObject(); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=149093
Your paranoid android.
=== debian11 (build log) ===
/usr/bin/i686-w64-mingw32-ld: tmp672c1e94/ntdll-00000000.spec.o:fake:(.edata+0x200): undefined reference to `NtAllocateReserveObject@12' collect2: error: ld returned 1 exit status Task: The win32 Wine build failed
=== debian11b (build log) ===
/usr/bin/x86_64-w64-mingw32-ld: tmp674635d8/ntdll-00000000.spec.o:fake:(.edata+0x200): undefined reference to `NtAllocateReserveObject' collect2: error: ld returned 1 exit status Task: The wow64 Wine build failed
v2: - Update generated files for static analysis. - Remove generated ntsyscalls.h changes