server: Implement NtOpenJobObject.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-01-29 01:32:22 +09:00
parent c3d602949c
commit b3064d748b
7 changed files with 89 additions and 7 deletions

View File

@ -552,8 +552,20 @@ NTSTATUS WINAPI NtCreateJobObject( PHANDLE handle, ACCESS_MASK access, const OBJ
*/ */
NTSTATUS WINAPI NtOpenJobObject( PHANDLE handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) NTSTATUS WINAPI NtOpenJobObject( PHANDLE handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
{ {
FIXME( "stub: %p %x %s\n", handle, access, attr ? debugstr_us(attr->ObjectName) : "" ); DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0;
return STATUS_NOT_IMPLEMENTED; NTSTATUS ret;
SERVER_START_REQ( open_job )
{
req->access = access;
req->attributes = attr ? attr->Attributes : 0;
req->rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 );
if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
ret = wine_server_call( req );
*handle = wine_server_ptr_handle( reply->handle );
}
SERVER_END_REQ;
return ret;
} }
/****************************************************************************** /******************************************************************************

View File

@ -468,7 +468,6 @@ static void test_name_limits(void)
ok( status == STATUS_SUCCESS, "%u: NtCreateJobObject failed %x\n", str.Length, status ); ok( status == STATUS_SUCCESS, "%u: NtCreateJobObject failed %x\n", str.Length, status );
attr3.RootDirectory = ret; attr3.RootDirectory = ret;
status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr ); status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr );
todo_wine
ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenJobObject failed %x\n", str.Length, status ); ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenJobObject failed %x\n", str.Length, status );
status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr3 ); status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr3 );
todo_wine todo_wine
@ -603,7 +602,6 @@ static void test_name_limits(void)
status = pNtCreateJobObject( &ret, GENERIC_ALL, &attr ); status = pNtCreateJobObject( &ret, GENERIC_ALL, &attr );
ok( status == STATUS_SUCCESS, "%u: NtCreateJobObject failed %x\n", str.Length, status ); ok( status == STATUS_SUCCESS, "%u: NtCreateJobObject failed %x\n", str.Length, status );
status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr ); status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr );
todo_wine
ok( status == STATUS_SUCCESS, "%u: NtOpenJobObject failed %x\n", str.Length, status ); ok( status == STATUS_SUCCESS, "%u: NtOpenJobObject failed %x\n", str.Length, status );
pNtClose( ret2 ); pNtClose( ret2 );
pNtClose( ret ); pNtClose( ret );
@ -752,7 +750,6 @@ static void test_name_limits(void)
todo_wine todo_wine
ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtOpenJobObject failed %x\n", status ); ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtOpenJobObject failed %x\n", status );
status = pNtOpenJobObject( &ret, GENERIC_ALL, &attr3 ); status = pNtOpenJobObject( &ret, GENERIC_ALL, &attr3 );
todo_wine
ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtOpenJobObject failed %x\n", status ); ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtOpenJobObject failed %x\n", status );
status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, &attr2 ); status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, &attr2 );
ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateDirectoryObject failed %x\n", status ); ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateDirectoryObject failed %x\n", status );

View File

@ -5268,6 +5268,23 @@ struct create_job_reply
struct open_job_request
{
struct request_header __header;
unsigned int access;
unsigned int attributes;
obj_handle_t rootdir;
/* VARARG(name,unicode_str); */
};
struct open_job_reply
{
struct reply_header __header;
obj_handle_t handle;
char __pad_12[4];
};
struct assign_job_request struct assign_job_request
{ {
struct request_header __header; struct request_header __header;
@ -5605,6 +5622,7 @@ enum request
REQ_get_suspend_context, REQ_get_suspend_context,
REQ_set_suspend_context, REQ_set_suspend_context,
REQ_create_job, REQ_create_job,
REQ_open_job,
REQ_assign_job, REQ_assign_job,
REQ_process_in_job, REQ_process_in_job,
REQ_set_job_limits, REQ_set_job_limits,
@ -5882,6 +5900,7 @@ union generic_request
struct get_suspend_context_request get_suspend_context_request; struct get_suspend_context_request get_suspend_context_request;
struct set_suspend_context_request set_suspend_context_request; struct set_suspend_context_request set_suspend_context_request;
struct create_job_request create_job_request; struct create_job_request create_job_request;
struct open_job_request open_job_request;
struct assign_job_request assign_job_request; struct assign_job_request assign_job_request;
struct process_in_job_request process_in_job_request; struct process_in_job_request process_in_job_request;
struct set_job_limits_request set_job_limits_request; struct set_job_limits_request set_job_limits_request;
@ -6157,6 +6176,7 @@ union generic_reply
struct get_suspend_context_reply get_suspend_context_reply; struct get_suspend_context_reply get_suspend_context_reply;
struct set_suspend_context_reply set_suspend_context_reply; struct set_suspend_context_reply set_suspend_context_reply;
struct create_job_reply create_job_reply; struct create_job_reply create_job_reply;
struct open_job_reply open_job_reply;
struct assign_job_reply assign_job_reply; struct assign_job_reply assign_job_reply;
struct process_in_job_reply process_in_job_reply; struct process_in_job_reply process_in_job_reply;
struct set_job_limits_reply set_job_limits_reply; struct set_job_limits_reply set_job_limits_reply;
@ -6164,6 +6184,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply; struct terminate_job_reply terminate_job_reply;
}; };
#define SERVER_PROTOCOL_VERSION 501 #define SERVER_PROTOCOL_VERSION 502
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -1558,6 +1558,24 @@ DECL_HANDLER(create_job)
if (root) release_object( root ); if (root) release_object( root );
} }
/* open a job object */
DECL_HANDLER(open_job)
{
struct job *job;
struct unicode_str name;
struct directory *root = NULL;
get_req_unicode_str( &name );
if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) return;
if ((job = open_object_dir( root, &name, req->attributes, &job_ops )))
{
reply->handle = alloc_handle( current->process, &job->obj, req->access, req->attributes );
release_object( job );
}
if (root) release_object( root );
}
/* assign a job object to a process */ /* assign a job object to a process */
DECL_HANDLER(assign_job) DECL_HANDLER(assign_job)
{ {

View File

@ -3637,6 +3637,17 @@ struct handle_info
@END @END
/* Open a job object */
@REQ(open_job)
unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */
obj_handle_t rootdir; /* root directory */
VARARG(name,unicode_str); /* object name */
@REPLY
obj_handle_t handle; /* handle to the job */
@END
/* Assign a job object to a process */ /* Assign a job object to a process */
@REQ(assign_job) @REQ(assign_job)
obj_handle_t job; /* handle to the job */ obj_handle_t job; /* handle to the job */

View File

@ -374,6 +374,7 @@ DECL_HANDLER(update_rawinput_devices);
DECL_HANDLER(get_suspend_context); DECL_HANDLER(get_suspend_context);
DECL_HANDLER(set_suspend_context); DECL_HANDLER(set_suspend_context);
DECL_HANDLER(create_job); DECL_HANDLER(create_job);
DECL_HANDLER(open_job);
DECL_HANDLER(assign_job); DECL_HANDLER(assign_job);
DECL_HANDLER(process_in_job); DECL_HANDLER(process_in_job);
DECL_HANDLER(set_job_limits); DECL_HANDLER(set_job_limits);
@ -650,6 +651,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_suspend_context, (req_handler)req_get_suspend_context,
(req_handler)req_set_suspend_context, (req_handler)req_set_suspend_context,
(req_handler)req_create_job, (req_handler)req_create_job,
(req_handler)req_open_job,
(req_handler)req_assign_job, (req_handler)req_assign_job,
(req_handler)req_process_in_job, (req_handler)req_process_in_job,
(req_handler)req_set_job_limits, (req_handler)req_set_job_limits,
@ -2265,6 +2267,12 @@ C_ASSERT( FIELD_OFFSET(struct create_job_request, access) == 12 );
C_ASSERT( sizeof(struct create_job_request) == 16 ); C_ASSERT( sizeof(struct create_job_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct create_job_reply, handle) == 8 ); C_ASSERT( FIELD_OFFSET(struct create_job_reply, handle) == 8 );
C_ASSERT( sizeof(struct create_job_reply) == 16 ); C_ASSERT( sizeof(struct create_job_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct open_job_request, access) == 12 );
C_ASSERT( FIELD_OFFSET(struct open_job_request, attributes) == 16 );
C_ASSERT( FIELD_OFFSET(struct open_job_request, rootdir) == 20 );
C_ASSERT( sizeof(struct open_job_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct open_job_reply, handle) == 8 );
C_ASSERT( sizeof(struct open_job_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct assign_job_request, job) == 12 ); C_ASSERT( FIELD_OFFSET(struct assign_job_request, job) == 12 );
C_ASSERT( FIELD_OFFSET(struct assign_job_request, process) == 16 ); C_ASSERT( FIELD_OFFSET(struct assign_job_request, process) == 16 );
C_ASSERT( sizeof(struct assign_job_request) == 24 ); C_ASSERT( sizeof(struct assign_job_request) == 24 );

View File

@ -4255,6 +4255,19 @@ static void dump_create_job_reply( const struct create_job_reply *req )
fprintf( stderr, " handle=%04x", req->handle ); fprintf( stderr, " handle=%04x", req->handle );
} }
static void dump_open_job_request( const struct open_job_request *req )
{
fprintf( stderr, " access=%08x", req->access );
fprintf( stderr, ", attributes=%08x", req->attributes );
fprintf( stderr, ", rootdir=%04x", req->rootdir );
dump_varargs_unicode_str( ", name=", cur_size );
}
static void dump_open_job_reply( const struct open_job_reply *req )
{
fprintf( stderr, " handle=%04x", req->handle );
}
static void dump_assign_job_request( const struct assign_job_request *req ) static void dump_assign_job_request( const struct assign_job_request *req )
{ {
fprintf( stderr, " job=%04x", req->job ); fprintf( stderr, " job=%04x", req->job );
@ -4552,6 +4565,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_suspend_context_request, (dump_func)dump_get_suspend_context_request,
(dump_func)dump_set_suspend_context_request, (dump_func)dump_set_suspend_context_request,
(dump_func)dump_create_job_request, (dump_func)dump_create_job_request,
(dump_func)dump_open_job_request,
(dump_func)dump_assign_job_request, (dump_func)dump_assign_job_request,
(dump_func)dump_process_in_job_request, (dump_func)dump_process_in_job_request,
(dump_func)dump_set_job_limits_request, (dump_func)dump_set_job_limits_request,
@ -4825,6 +4839,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_suspend_context_reply, (dump_func)dump_get_suspend_context_reply,
NULL, NULL,
(dump_func)dump_create_job_reply, (dump_func)dump_create_job_reply,
(dump_func)dump_open_job_reply,
NULL, NULL,
NULL, NULL,
NULL, NULL,
@ -5098,6 +5113,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_suspend_context", "get_suspend_context",
"set_suspend_context", "set_suspend_context",
"create_job", "create_job",
"open_job",
"assign_job", "assign_job",
"process_in_job", "process_in_job",
"set_job_limits", "set_job_limits",
@ -5136,7 +5152,6 @@ static const struct
{ "DIRECTORY_NOT_EMPTY", STATUS_DIRECTORY_NOT_EMPTY }, { "DIRECTORY_NOT_EMPTY", STATUS_DIRECTORY_NOT_EMPTY },
{ "DISK_FULL", STATUS_DISK_FULL }, { "DISK_FULL", STATUS_DISK_FULL },
{ "DLL_NOT_FOUND", STATUS_DLL_NOT_FOUND }, { "DLL_NOT_FOUND", STATUS_DLL_NOT_FOUND },
{ "ERROR_NO_MORE_USER_HANDLES", 0xc0010000 | ERROR_NO_MORE_USER_HANDLES },
{ "ERROR_CLASS_ALREADY_EXISTS", 0xc0010000 | ERROR_CLASS_ALREADY_EXISTS }, { "ERROR_CLASS_ALREADY_EXISTS", 0xc0010000 | ERROR_CLASS_ALREADY_EXISTS },
{ "ERROR_CLASS_DOES_NOT_EXIST", 0xc0010000 | ERROR_CLASS_DOES_NOT_EXIST }, { "ERROR_CLASS_DOES_NOT_EXIST", 0xc0010000 | ERROR_CLASS_DOES_NOT_EXIST },
{ "ERROR_CLASS_HAS_WINDOWS", 0xc0010000 | ERROR_CLASS_HAS_WINDOWS }, { "ERROR_CLASS_HAS_WINDOWS", 0xc0010000 | ERROR_CLASS_HAS_WINDOWS },
@ -5146,6 +5161,7 @@ static const struct
{ "ERROR_INVALID_CURSOR_HANDLE", 0xc0010000 | ERROR_INVALID_CURSOR_HANDLE }, { "ERROR_INVALID_CURSOR_HANDLE", 0xc0010000 | ERROR_INVALID_CURSOR_HANDLE },
{ "ERROR_INVALID_INDEX", 0xc0010000 | ERROR_INVALID_INDEX }, { "ERROR_INVALID_INDEX", 0xc0010000 | ERROR_INVALID_INDEX },
{ "ERROR_INVALID_WINDOW_HANDLE", 0xc0010000 | ERROR_INVALID_WINDOW_HANDLE }, { "ERROR_INVALID_WINDOW_HANDLE", 0xc0010000 | ERROR_INVALID_WINDOW_HANDLE },
{ "ERROR_NO_MORE_USER_HANDLES", 0xc0010000 | ERROR_NO_MORE_USER_HANDLES },
{ "ERROR_WINDOW_OF_OTHER_THREAD", 0xc0010000 | ERROR_WINDOW_OF_OTHER_THREAD }, { "ERROR_WINDOW_OF_OTHER_THREAD", 0xc0010000 | ERROR_WINDOW_OF_OTHER_THREAD },
{ "FILE_DELETED", STATUS_FILE_DELETED }, { "FILE_DELETED", STATUS_FILE_DELETED },
{ "FILE_IS_A_DIRECTORY", STATUS_FILE_IS_A_DIRECTORY }, { "FILE_IS_A_DIRECTORY", STATUS_FILE_IS_A_DIRECTORY },