Commit c0d1080d authored by Zebediah Figura's avatar Zebediah Figura Committed by Vitaly Lipatov

ntdll: Implement NtOpenSemaphore().

parent 0516d4d7
......@@ -329,6 +329,45 @@ static NTSTATUS create_esync( enum esync_type type, HANDLE *handle, ACCESS_MASK
return ret;
}
static NTSTATUS open_esync( enum esync_type type, HANDLE *handle,
ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
{
NTSTATUS ret;
obj_handle_t fd_handle;
unsigned int shm_idx;
sigset_t sigset;
int fd;
server_enter_uninterrupted_section( &fd_cache_mutex, &sigset );
SERVER_START_REQ( open_esync )
{
req->access = access;
req->attributes = attr->Attributes;
req->rootdir = wine_server_obj_handle( attr->RootDirectory );
req->type = type;
if (attr->ObjectName)
wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length );
if (!(ret = wine_server_call( req )))
{
*handle = wine_server_ptr_handle( reply->handle );
type = reply->type;
shm_idx = reply->shm_idx;
fd = receive_fd( &fd_handle );
assert( wine_server_ptr_handle(fd_handle) == *handle );
}
}
SERVER_END_REQ;
server_leave_uninterrupted_section( &fd_cache_mutex, &sigset );
if (!ret)
{
add_to_list( *handle, type, fd, shm_idx ? get_shm( shm_idx ) : 0 );
TRACE("-> handle %p, fd %d.\n", *handle, fd);
}
return ret;
}
extern NTSTATUS esync_create_semaphore(HANDLE *handle, ACCESS_MASK access,
const OBJECT_ATTRIBUTES *attr, LONG initial, LONG max)
{
......@@ -338,6 +377,14 @@ extern NTSTATUS esync_create_semaphore(HANDLE *handle, ACCESS_MASK access,
return create_esync( ESYNC_SEMAPHORE, handle, access, attr, initial, max );
}
NTSTATUS esync_open_semaphore( HANDLE *handle, ACCESS_MASK access,
const OBJECT_ATTRIBUTES *attr )
{
TRACE("name %s.\n", debugstr_us(attr->ObjectName));
return open_esync( ESYNC_SEMAPHORE, handle, access, attr );
}
NTSTATUS esync_release_semaphore( HANDLE handle, ULONG count, ULONG *prev )
{
struct esync *obj;
......
......@@ -24,6 +24,8 @@ extern NTSTATUS esync_close( HANDLE handle ) DECLSPEC_HIDDEN;
extern NTSTATUS esync_create_semaphore(HANDLE *handle, ACCESS_MASK access,
const OBJECT_ATTRIBUTES *attr, LONG initial, LONG max) DECLSPEC_HIDDEN;
extern NTSTATUS esync_open_semaphore( HANDLE *handle, ACCESS_MASK access,
const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN;
extern NTSTATUS esync_release_semaphore( HANDLE handle, ULONG count, ULONG *prev ) DECLSPEC_HIDDEN;
extern NTSTATUS esync_create_event( HANDLE *handle, ACCESS_MASK access,
......
......@@ -301,6 +301,10 @@ NTSTATUS WINAPI NtOpenSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJEC
NTSTATUS ret;
*handle = 0;
if (do_esync())
return esync_open_semaphore( handle, access, attr );
if ((ret = validate_open_object_attributes( attr ))) return ret;
SERVER_START_REQ( open_semaphore )
......
......@@ -5507,6 +5507,25 @@ struct create_esync_reply
char __pad_20[4];
};
struct open_esync_request
{
struct request_header __header;
unsigned int access;
unsigned int attributes;
obj_handle_t rootdir;
int type;
/* VARARG(name,unicode_str); */
char __pad_28[4];
};
struct open_esync_reply
{
struct reply_header __header;
obj_handle_t handle;
int type;
unsigned int shm_idx;
char __pad_20[4];
};
struct get_esync_fd_request
{
......@@ -5812,6 +5831,7 @@ enum request
REQ_resume_process,
REQ_get_next_thread,
REQ_create_esync,
REQ_open_esync,
REQ_get_esync_fd,
REQ_esync_msgwait,
REQ_NB_REQUESTS
......@@ -6099,6 +6119,7 @@ union generic_request
struct resume_process_request resume_process_request;
struct get_next_thread_request get_next_thread_request;
struct create_esync_request create_esync_request;
struct open_esync_request open_esync_request;
struct get_esync_fd_request get_esync_fd_request;
struct esync_msgwait_request esync_msgwait_request;
};
......@@ -6384,13 +6405,14 @@ union generic_reply
struct resume_process_reply resume_process_reply;
struct get_next_thread_reply get_next_thread_reply;
struct create_esync_reply create_esync_reply;
struct open_esync_reply open_esync_reply;
struct get_esync_fd_reply get_esync_fd_reply;
struct esync_msgwait_reply esync_msgwait_reply;
};
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 760
#define SERVER_PROTOCOL_VERSION 761
/* ### protocol_version end ### */
......
......@@ -410,6 +410,37 @@ DECL_HANDLER(create_esync)
if (root) release_object( root );
}
DECL_HANDLER(open_esync)
{
struct unicode_str name = get_req_unicode_str();
reply->handle = open_object( current->process, req->rootdir, req->access,
&esync_ops, &name, req->attributes );
/* send over the fd */
if (reply->handle)
{
struct esync *esync;
if (!(esync = (struct esync *)get_handle_obj( current->process, reply->handle,
0, &esync_ops )))
return;
if (!type_matches( req->type, esync->type ))
{
set_error( STATUS_OBJECT_TYPE_MISMATCH );
release_object( esync );
return;
}
reply->type = esync->type;
reply->shm_idx = esync->shm_idx;
send_client_fd( current->process, esync->fd, reply->handle );
release_object( esync );
}
}
/* Retrieve a file descriptor for an esync object which will be signaled by the
* server. The client should only read from (i.e. wait on) this object. */
DECL_HANDLER(get_esync_fd)
......
......@@ -3790,6 +3790,18 @@ enum esync_type
unsigned int shm_idx;
@END
@REQ(open_esync)
unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */
obj_handle_t rootdir; /* root directory */
int type; /* type of esync object (above) */
VARARG(name,unicode_str); /* object name */
@REPLY
obj_handle_t handle; /* handle to the event */
int type; /* type of esync object (above) */
unsigned int shm_idx; /* this object's index into the shm section */
@END
/* Retrieve the esync fd for an object. */
@REQ(get_esync_fd)
obj_handle_t handle; /* handle to the object */
......
......@@ -397,6 +397,7 @@ DECL_HANDLER(suspend_process);
DECL_HANDLER(resume_process);
DECL_HANDLER(get_next_thread);
DECL_HANDLER(create_esync);
DECL_HANDLER(open_esync);
DECL_HANDLER(get_esync_fd);
DECL_HANDLER(esync_msgwait);
......@@ -683,6 +684,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_resume_process,
(req_handler)req_get_next_thread,
(req_handler)req_create_esync,
(req_handler)req_open_esync,
(req_handler)req_get_esync_fd,
(req_handler)req_esync_msgwait,
};
......@@ -2283,6 +2285,15 @@ C_ASSERT( FIELD_OFFSET(struct create_esync_reply, handle) == 8 );
C_ASSERT( FIELD_OFFSET(struct create_esync_reply, type) == 12 );
C_ASSERT( FIELD_OFFSET(struct create_esync_reply, shm_idx) == 16 );
C_ASSERT( sizeof(struct create_esync_reply) == 24 );
C_ASSERT( FIELD_OFFSET(struct open_esync_request, access) == 12 );
C_ASSERT( FIELD_OFFSET(struct open_esync_request, attributes) == 16 );
C_ASSERT( FIELD_OFFSET(struct open_esync_request, rootdir) == 20 );
C_ASSERT( FIELD_OFFSET(struct open_esync_request, type) == 24 );
C_ASSERT( sizeof(struct open_esync_request) == 32 );
C_ASSERT( FIELD_OFFSET(struct open_esync_reply, handle) == 8 );
C_ASSERT( FIELD_OFFSET(struct open_esync_reply, type) == 12 );
C_ASSERT( FIELD_OFFSET(struct open_esync_reply, shm_idx) == 16 );
C_ASSERT( sizeof(struct open_esync_reply) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_esync_fd_request, handle) == 12 );
C_ASSERT( sizeof(struct get_esync_fd_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_esync_fd_reply, type) == 8 );
......
......@@ -4516,6 +4516,22 @@ static void dump_create_esync_reply( const struct create_esync_reply *req )
fprintf( stderr, ", shm_idx=%08x", req->shm_idx );
}
static void dump_open_esync_request( const struct open_esync_request *req )
{
fprintf( stderr, " access=%08x", req->access );
fprintf( stderr, ", attributes=%08x", req->attributes );
fprintf( stderr, ", rootdir=%04x", req->rootdir );
fprintf( stderr, ", type=%d", req->type );
dump_varargs_unicode_str( ", name=", cur_size );
}
static void dump_open_esync_reply( const struct open_esync_reply *req )
{
fprintf( stderr, " handle=%04x", req->handle );
fprintf( stderr, ", type=%d", req->type );
fprintf( stderr, ", shm_idx=%08x", req->shm_idx );
}
static void dump_get_esync_fd_request( const struct get_esync_fd_request *req )
{
fprintf( stderr, " handle=%04x", req->handle );
......@@ -4811,6 +4827,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_resume_process_request,
(dump_func)dump_get_next_thread_request,
(dump_func)dump_create_esync_request,
(dump_func)dump_open_esync_request,
(dump_func)dump_get_esync_fd_request,
(dump_func)dump_esync_msgwait_request,
};
......@@ -5094,6 +5111,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
NULL,
(dump_func)dump_get_next_thread_reply,
(dump_func)dump_create_esync_reply,
(dump_func)dump_open_esync_reply,
(dump_func)dump_get_esync_fd_reply,
NULL,
};
......@@ -5377,6 +5395,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"resume_process",
"get_next_thread",
"create_esync",
"open_esync",
"get_esync_fd",
"esync_msgwait",
};
......
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