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:
parent
0decadd62a
commit
f57a383d09
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue