Commit f57a383d authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

ntoskrnl.exe: Support waiting on kernel objects.

parent 0decadd6
...@@ -367,6 +367,20 @@ static void ObReferenceObject( void *obj ) ...@@ -367,6 +367,20 @@ static void ObReferenceObject( void *obj )
LeaveCriticalSection( &obref_cs ); 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[] = static const POBJECT_TYPE *known_types[] =
{ {
&ExEventObjectType, &ExEventObjectType,
......
...@@ -28,6 +28,7 @@ struct _OBJECT_TYPE { ...@@ -28,6 +28,7 @@ struct _OBJECT_TYPE {
}; };
void *alloc_kernel_object( POBJECT_TYPE type, HANDLE handle, SIZE_T size, LONG ref ) DECLSPEC_HIDDEN; 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 ExEventObjectType;
extern POBJECT_TYPE ExSemaphoreObjectType; extern POBJECT_TYPE ExSemaphoreObjectType;
......
...@@ -78,8 +78,7 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[], ...@@ -78,8 +78,7 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
{ {
if (objs[i]->WaitListHead.Blink == INVALID_HANDLE_VALUE) if (objs[i]->WaitListHead.Blink == INVALID_HANDLE_VALUE)
{ {
FIXME("unsupported on kernel objects\n"); handles[i] = kernel_object_handle( objs[i], SYNCHRONIZE );
handles[i] = INVALID_HANDLE_VALUE;
continue; continue;
} }
...@@ -134,9 +133,11 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[], ...@@ -134,9 +133,11 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
} }
} }
if (objs[i]->WaitListHead.Blink == INVALID_HANDLE_VALUE) continue; if (objs[i]->WaitListHead.Blink == INVALID_HANDLE_VALUE)
{
if (!--*((ULONG_PTR *)&objs[i]->WaitListHead.Flink)) NtClose( handles[i] );
}
else if (!--*((ULONG_PTR *)&objs[i]->WaitListHead.Flink))
{ {
switch (objs[i]->Type) switch (objs[i]->Type)
{ {
......
...@@ -458,10 +458,10 @@ static void test_sync(void) ...@@ -458,10 +458,10 @@ static void test_sync(void)
ok(!ret, "ObReferenceObjectByHandle failed: %#x\n", ret); ok(!ret, "ObReferenceObjectByHandle failed: %#x\n", ret);
ret = wait_single(event, 0); ret = wait_single(event, 0);
todo_wine
ok(ret == 0, "got %#x\n", ret); ok(ret == 0, "got %#x\n", ret);
KeResetEvent(event); KeResetEvent(event);
ret = wait_single(event, 0); ret = wait_single(event, 0);
todo_wine
ok(ret == STATUS_TIMEOUT, "got %#x\n", ret); ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
ret = wait_single_handle(handle, 0); ret = wait_single_handle(handle, 0);
todo_wine todo_wine
...@@ -469,7 +469,6 @@ static void test_sync(void) ...@@ -469,7 +469,6 @@ static void test_sync(void)
KeSetEvent(event, 0, FALSE); KeSetEvent(event, 0, FALSE);
ret = wait_single(event, 0); ret = wait_single(event, 0);
todo_wine
ok(ret == 0, "got %#x\n", ret); ok(ret == 0, "got %#x\n", ret);
ret = wait_single_handle(handle, 0); ret = wait_single_handle(handle, 0);
ok(!ret, "got %#x\n", ret); ok(!ret, "got %#x\n", ret);
......
...@@ -5309,6 +5309,23 @@ struct release_kernel_object_reply ...@@ -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 make_process_system_request
{ {
struct request_header __header; struct request_header __header;
...@@ -5999,6 +6016,7 @@ enum request ...@@ -5999,6 +6016,7 @@ enum request
REQ_set_kernel_object_ptr, REQ_set_kernel_object_ptr,
REQ_grab_kernel_object, REQ_grab_kernel_object,
REQ_release_kernel_object, REQ_release_kernel_object,
REQ_get_kernel_object_handle,
REQ_make_process_system, REQ_make_process_system,
REQ_get_token_statistics, REQ_get_token_statistics,
REQ_create_completion, REQ_create_completion,
...@@ -6301,6 +6319,7 @@ union generic_request ...@@ -6301,6 +6319,7 @@ union generic_request
struct set_kernel_object_ptr_request set_kernel_object_ptr_request; struct set_kernel_object_ptr_request set_kernel_object_ptr_request;
struct grab_kernel_object_request grab_kernel_object_request; struct grab_kernel_object_request grab_kernel_object_request;
struct release_kernel_object_request release_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 make_process_system_request make_process_system_request;
struct get_token_statistics_request get_token_statistics_request; struct get_token_statistics_request get_token_statistics_request;
struct create_completion_request create_completion_request; struct create_completion_request create_completion_request;
...@@ -6601,6 +6620,7 @@ union generic_reply ...@@ -6601,6 +6620,7 @@ union generic_reply
struct set_kernel_object_ptr_reply set_kernel_object_ptr_reply; struct set_kernel_object_ptr_reply set_kernel_object_ptr_reply;
struct grab_kernel_object_reply grab_kernel_object_reply; struct grab_kernel_object_reply grab_kernel_object_reply;
struct release_kernel_object_reply release_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 make_process_system_reply make_process_system_reply;
struct get_token_statistics_reply get_token_statistics_reply; struct get_token_statistics_reply get_token_statistics_reply;
struct create_completion_reply create_completion_reply; struct create_completion_reply create_completion_reply;
...@@ -6630,6 +6650,6 @@ union generic_reply ...@@ -6630,6 +6650,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply; struct terminate_job_reply terminate_job_reply;
}; };
#define SERVER_PROTOCOL_VERSION 575 #define SERVER_PROTOCOL_VERSION 576
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -969,3 +969,22 @@ DECL_HANDLER(release_kernel_object) ...@@ -969,3 +969,22 @@ DECL_HANDLER(release_kernel_object)
release_object( manager ); 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 ...@@ -3660,6 +3660,16 @@ struct handle_info
@END @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 */ /* Make the current process a system process */
@REQ(make_process_system) @REQ(make_process_system)
@REPLY @REPLY
......
...@@ -380,6 +380,7 @@ DECL_HANDLER(get_kernel_object_ptr); ...@@ -380,6 +380,7 @@ DECL_HANDLER(get_kernel_object_ptr);
DECL_HANDLER(set_kernel_object_ptr); DECL_HANDLER(set_kernel_object_ptr);
DECL_HANDLER(grab_kernel_object); DECL_HANDLER(grab_kernel_object);
DECL_HANDLER(release_kernel_object); DECL_HANDLER(release_kernel_object);
DECL_HANDLER(get_kernel_object_handle);
DECL_HANDLER(make_process_system); DECL_HANDLER(make_process_system);
DECL_HANDLER(get_token_statistics); DECL_HANDLER(get_token_statistics);
DECL_HANDLER(create_completion); DECL_HANDLER(create_completion);
...@@ -681,6 +682,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -681,6 +682,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_set_kernel_object_ptr, (req_handler)req_set_kernel_object_ptr,
(req_handler)req_grab_kernel_object, (req_handler)req_grab_kernel_object,
(req_handler)req_release_kernel_object, (req_handler)req_release_kernel_object,
(req_handler)req_get_kernel_object_handle,
(req_handler)req_make_process_system, (req_handler)req_make_process_system,
(req_handler)req_get_token_statistics, (req_handler)req_get_token_statistics,
(req_handler)req_create_completion, (req_handler)req_create_completion,
...@@ -2308,6 +2310,12 @@ C_ASSERT( sizeof(struct grab_kernel_object_request) == 24 ); ...@@ -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, manager) == 12 );
C_ASSERT( FIELD_OFFSET(struct release_kernel_object_request, user_ptr) == 16 ); C_ASSERT( FIELD_OFFSET(struct release_kernel_object_request, user_ptr) == 16 );
C_ASSERT( sizeof(struct release_kernel_object_request) == 24 ); 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( sizeof(struct make_process_system_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct make_process_system_reply, event) == 8 ); C_ASSERT( FIELD_OFFSET(struct make_process_system_reply, event) == 8 );
C_ASSERT( sizeof(struct make_process_system_reply) == 16 ); 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 ...@@ -4328,6 +4328,18 @@ static void dump_release_kernel_object_request( const struct release_kernel_obje
dump_uint64( ", user_ptr=", &req->user_ptr ); 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 ) 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] = { ...@@ -4845,6 +4857,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_set_kernel_object_ptr_request, (dump_func)dump_set_kernel_object_ptr_request,
(dump_func)dump_grab_kernel_object_request, (dump_func)dump_grab_kernel_object_request,
(dump_func)dump_release_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_make_process_system_request,
(dump_func)dump_get_token_statistics_request, (dump_func)dump_get_token_statistics_request,
(dump_func)dump_create_completion_request, (dump_func)dump_create_completion_request,
...@@ -5143,6 +5156,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -5143,6 +5156,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
NULL, NULL,
NULL, NULL,
NULL, NULL,
(dump_func)dump_get_kernel_object_handle_reply,
(dump_func)dump_make_process_system_reply, (dump_func)dump_make_process_system_reply,
(dump_func)dump_get_token_statistics_reply, (dump_func)dump_get_token_statistics_reply,
(dump_func)dump_create_completion_reply, (dump_func)dump_create_completion_reply,
...@@ -5441,6 +5455,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -5441,6 +5455,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"set_kernel_object_ptr", "set_kernel_object_ptr",
"grab_kernel_object", "grab_kernel_object",
"release_kernel_object", "release_kernel_object",
"get_kernel_object_handle",
"make_process_system", "make_process_system",
"get_token_statistics", "get_token_statistics",
"create_completion", "create_completion",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment