ntoskrnl.exe: Support waiting on kernel objects.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2019-03-25 14:38:57 +01:00 committed by Alexandre Julliard
parent 0decadd62a
commit f57a383d09
9 changed files with 95 additions and 8 deletions

View File

@ -367,6 +367,20 @@ static void ObReferenceObject( void *obj )
LeaveCriticalSection( &obref_cs );
}
HANDLE kernel_object_handle( void *obj, unsigned int access )
{
HANDLE handle = NULL;
SERVER_START_REQ( get_kernel_object_handle )
{
req->manager = wine_server_obj_handle( get_device_manager() );
req->user_ptr = wine_server_client_ptr( obj );
req->access = access;
if (!wine_server_call( req )) handle = wine_server_ptr_handle( reply->handle );
}
SERVER_END_REQ;
return handle;
}
static const POBJECT_TYPE *known_types[] =
{
&ExEventObjectType,

View File

@ -28,6 +28,7 @@ struct _OBJECT_TYPE {
};
void *alloc_kernel_object( POBJECT_TYPE type, HANDLE handle, SIZE_T size, LONG ref ) DECLSPEC_HIDDEN;
HANDLE kernel_object_handle( void *obj, unsigned int access ) DECLSPEC_HIDDEN;
extern POBJECT_TYPE ExEventObjectType;
extern POBJECT_TYPE ExSemaphoreObjectType;

View File

@ -78,8 +78,7 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
{
if (objs[i]->WaitListHead.Blink == INVALID_HANDLE_VALUE)
{
FIXME("unsupported on kernel objects\n");
handles[i] = INVALID_HANDLE_VALUE;
handles[i] = kernel_object_handle( objs[i], SYNCHRONIZE );
continue;
}
@ -134,9 +133,11 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
}
}
if (objs[i]->WaitListHead.Blink == INVALID_HANDLE_VALUE) continue;
if (!--*((ULONG_PTR *)&objs[i]->WaitListHead.Flink))
if (objs[i]->WaitListHead.Blink == INVALID_HANDLE_VALUE)
{
NtClose( handles[i] );
}
else if (!--*((ULONG_PTR *)&objs[i]->WaitListHead.Flink))
{
switch (objs[i]->Type)
{

View File

@ -458,10 +458,10 @@ static void test_sync(void)
ok(!ret, "ObReferenceObjectByHandle failed: %#x\n", ret);
ret = wait_single(event, 0);
todo_wine
ok(ret == 0, "got %#x\n", ret);
KeResetEvent(event);
ret = wait_single(event, 0);
todo_wine
ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
ret = wait_single_handle(handle, 0);
todo_wine
@ -469,7 +469,6 @@ static void test_sync(void)
KeSetEvent(event, 0, FALSE);
ret = wait_single(event, 0);
todo_wine
ok(ret == 0, "got %#x\n", ret);
ret = wait_single_handle(handle, 0);
ok(!ret, "got %#x\n", ret);

View File

@ -5309,6 +5309,23 @@ struct release_kernel_object_reply
struct get_kernel_object_handle_request
{
struct request_header __header;
obj_handle_t manager;
client_ptr_t user_ptr;
unsigned int access;
char __pad_28[4];
};
struct get_kernel_object_handle_reply
{
struct reply_header __header;
obj_handle_t handle;
char __pad_12[4];
};
struct make_process_system_request
{
struct request_header __header;
@ -5999,6 +6016,7 @@ enum request
REQ_set_kernel_object_ptr,
REQ_grab_kernel_object,
REQ_release_kernel_object,
REQ_get_kernel_object_handle,
REQ_make_process_system,
REQ_get_token_statistics,
REQ_create_completion,
@ -6301,6 +6319,7 @@ union generic_request
struct set_kernel_object_ptr_request set_kernel_object_ptr_request;
struct grab_kernel_object_request grab_kernel_object_request;
struct release_kernel_object_request release_kernel_object_request;
struct get_kernel_object_handle_request get_kernel_object_handle_request;
struct make_process_system_request make_process_system_request;
struct get_token_statistics_request get_token_statistics_request;
struct create_completion_request create_completion_request;
@ -6601,6 +6620,7 @@ union generic_reply
struct set_kernel_object_ptr_reply set_kernel_object_ptr_reply;
struct grab_kernel_object_reply grab_kernel_object_reply;
struct release_kernel_object_reply release_kernel_object_reply;
struct get_kernel_object_handle_reply get_kernel_object_handle_reply;
struct make_process_system_reply make_process_system_reply;
struct get_token_statistics_reply get_token_statistics_reply;
struct create_completion_reply create_completion_reply;
@ -6630,6 +6650,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply;
};
#define SERVER_PROTOCOL_VERSION 575
#define SERVER_PROTOCOL_VERSION 576
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -969,3 +969,22 @@ DECL_HANDLER(release_kernel_object)
release_object( manager );
}
/* get handle from kernel object pointer */
DECL_HANDLER(get_kernel_object_handle)
{
struct device_manager *manager;
struct kernel_object *ref;
if (!(manager = (struct device_manager *)get_handle_obj( current->process, req->manager,
0, &device_manager_ops )))
return;
if ((ref = kernel_object_from_ptr( manager, req->user_ptr )))
reply->handle = alloc_handle( current->process, ref->object, req->access, 0 );
else
set_error( STATUS_INVALID_HANDLE );
release_object( manager );
}

View File

@ -3660,6 +3660,16 @@ struct handle_info
@END
/* Get handle from kernel object pointer */
@REQ(get_kernel_object_handle)
obj_handle_t manager; /* handle to the device manager */
client_ptr_t user_ptr; /* kernel object pointer */
unsigned int access; /* wanted access rights */
@REPLY
obj_handle_t handle; /* kernel object handle */
@END
/* Make the current process a system process */
@REQ(make_process_system)
@REPLY

View File

@ -380,6 +380,7 @@ DECL_HANDLER(get_kernel_object_ptr);
DECL_HANDLER(set_kernel_object_ptr);
DECL_HANDLER(grab_kernel_object);
DECL_HANDLER(release_kernel_object);
DECL_HANDLER(get_kernel_object_handle);
DECL_HANDLER(make_process_system);
DECL_HANDLER(get_token_statistics);
DECL_HANDLER(create_completion);
@ -681,6 +682,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_set_kernel_object_ptr,
(req_handler)req_grab_kernel_object,
(req_handler)req_release_kernel_object,
(req_handler)req_get_kernel_object_handle,
(req_handler)req_make_process_system,
(req_handler)req_get_token_statistics,
(req_handler)req_create_completion,
@ -2308,6 +2310,12 @@ C_ASSERT( sizeof(struct grab_kernel_object_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct release_kernel_object_request, manager) == 12 );
C_ASSERT( FIELD_OFFSET(struct release_kernel_object_request, user_ptr) == 16 );
C_ASSERT( sizeof(struct release_kernel_object_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_kernel_object_handle_request, manager) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_kernel_object_handle_request, user_ptr) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_kernel_object_handle_request, access) == 24 );
C_ASSERT( sizeof(struct get_kernel_object_handle_request) == 32 );
C_ASSERT( FIELD_OFFSET(struct get_kernel_object_handle_reply, handle) == 8 );
C_ASSERT( sizeof(struct get_kernel_object_handle_reply) == 16 );
C_ASSERT( sizeof(struct make_process_system_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct make_process_system_reply, event) == 8 );
C_ASSERT( sizeof(struct make_process_system_reply) == 16 );

View File

@ -4328,6 +4328,18 @@ static void dump_release_kernel_object_request( const struct release_kernel_obje
dump_uint64( ", user_ptr=", &req->user_ptr );
}
static void dump_get_kernel_object_handle_request( const struct get_kernel_object_handle_request *req )
{
fprintf( stderr, " manager=%04x", req->manager );
dump_uint64( ", user_ptr=", &req->user_ptr );
fprintf( stderr, ", access=%08x", req->access );
}
static void dump_get_kernel_object_handle_reply( const struct get_kernel_object_handle_reply *req )
{
fprintf( stderr, " handle=%04x", req->handle );
}
static void dump_make_process_system_request( const struct make_process_system_request *req )
{
}
@ -4845,6 +4857,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_set_kernel_object_ptr_request,
(dump_func)dump_grab_kernel_object_request,
(dump_func)dump_release_kernel_object_request,
(dump_func)dump_get_kernel_object_handle_request,
(dump_func)dump_make_process_system_request,
(dump_func)dump_get_token_statistics_request,
(dump_func)dump_create_completion_request,
@ -5143,6 +5156,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
NULL,
NULL,
NULL,
(dump_func)dump_get_kernel_object_handle_reply,
(dump_func)dump_make_process_system_reply,
(dump_func)dump_get_token_statistics_reply,
(dump_func)dump_create_completion_reply,
@ -5441,6 +5455,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"set_kernel_object_ptr",
"grab_kernel_object",
"release_kernel_object",
"get_kernel_object_handle",
"make_process_system",
"get_token_statistics",
"create_completion",