server: Implement NtOpenJobObject.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c3d602949c
commit
b3064d748b
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
Loading…
Reference in New Issue