diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c index 2234f870d66..4bfa7620bb6 100644 --- a/dlls/ntdll/om.c +++ b/dlls/ntdll/om.c @@ -476,8 +476,18 @@ NTSTATUS WINAPI NtAllocateUuids( ULARGE_INTEGER *time, ULONG *delta, ULONG *sequ * Success: STATUS_SUCCESS. * Failure: An NTSTATUS error code. */ -NTSTATUS WINAPI NtMakeTemporaryObject( HANDLE Handle ) +NTSTATUS WINAPI NtMakeTemporaryObject( HANDLE handle ) { - FIXME("(%p), stub.\n", Handle); - return STATUS_SUCCESS; + NTSTATUS ret; + + TRACE("%p\n", handle); + + SERVER_START_REQ( make_temporary ) + { + req->handle = wine_server_obj_handle( handle ); + ret = wine_server_call( req ); + } + SERVER_END_REQ; + + return ret; } diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index 72d2272d5cc..0671a56efc7 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -2056,20 +2056,20 @@ static void test_permanence(void) status = ZwClose( handle ); ok(!status, "got %#x\n", status); status = ZwOpenDirectoryObject( &handle, 0, &attr ); - todo_wine ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %#x\n", status); + ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %#x\n", status); status = ZwCreateDirectoryObject( &handle, GENERIC_ALL, &attr ); - todo_wine ok(!status, "got %#x\n", status); + ok(!status, "got %#x\n", status); attr.Attributes = OBJ_PERMANENT; status = ZwOpenDirectoryObject( &handle2, 0, &attr ); ok(status == STATUS_SUCCESS, "got %#x\n", status); status = ZwClose( handle2 ); ok(!status, "got %#x\n", status); status = ZwClose( handle ); - todo_wine ok(!status, "got %#x\n", status); + ok(!status, "got %#x\n", status); attr.Attributes = 0; status = ZwOpenDirectoryObject( &handle, 0, &attr ); - todo_wine ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %#x\n", status); + ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %#x\n", status); } static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack) diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index e6e772553cf..fc808774be2 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -1218,6 +1218,18 @@ struct dup_handle_reply +struct make_temporary_request +{ + struct request_header __header; + obj_handle_t handle; +}; +struct make_temporary_reply +{ + struct reply_header __header; +}; + + + struct open_process_request { struct request_header __header; @@ -5600,6 +5612,7 @@ enum request REQ_close_handle, REQ_set_handle_info, REQ_dup_handle, + REQ_make_temporary, REQ_open_process, REQ_open_thread, REQ_select, @@ -5894,6 +5907,7 @@ union generic_request struct close_handle_request close_handle_request; struct set_handle_info_request set_handle_info_request; struct dup_handle_request dup_handle_request; + struct make_temporary_request make_temporary_request; struct open_process_request open_process_request; struct open_thread_request open_thread_request; struct select_request select_request; @@ -6186,6 +6200,7 @@ union generic_reply struct close_handle_reply close_handle_reply; struct set_handle_info_reply set_handle_info_reply; struct dup_handle_reply dup_handle_reply; + struct make_temporary_reply make_temporary_reply; struct open_process_reply open_process_reply; struct open_thread_reply open_thread_reply; struct select_reply select_reply; @@ -6452,7 +6467,7 @@ union generic_reply /* ### protocol_version begin ### */ -#define SERVER_PROTOCOL_VERSION 626 +#define SERVER_PROTOCOL_VERSION 627 /* ### protocol_version end ### */ diff --git a/server/handle.c b/server/handle.c index a2a8bb5479c..9ae99cd0c63 100644 --- a/server/handle.c +++ b/server/handle.c @@ -833,3 +833,17 @@ DECL_HANDLER(get_system_handles) enum_processes( enum_handles, &info ); } } + +DECL_HANDLER(make_temporary) +{ + struct object *obj; + + if (!(obj = get_handle_obj( current->process, req->handle, 0, NULL ))) return; + + if (obj->is_permanent) + { + make_object_temporary( obj ); + release_object( obj ); + } + release_object( obj ); +} diff --git a/server/object.c b/server/object.c index 6c0bb9be3ab..8ec6609f69d 100644 --- a/server/object.c +++ b/server/object.c @@ -414,6 +414,16 @@ void make_object_static( struct object *obj ) #endif } +/* mark an object as no longer static */ +void make_object_temporary( struct object *obj ) +{ + obj->is_permanent = 0; +#ifdef DEBUG_OBJECTS + list_remove( &obj->obj_list ); + list_add_head( &object_list, &obj->obj_list ); +#endif +} + /* grab an object (i.e. increment its refcount) and return the object */ struct object *grab_object( void *ptr ) { diff --git a/server/object.h b/server/object.h index fac35f0984e..1f5c4a5f061 100644 --- a/server/object.h +++ b/server/object.h @@ -144,6 +144,7 @@ extern void *open_named_object( struct object *parent, const struct object_ops * const struct unicode_str *name, unsigned int attributes ); extern void unlink_named_object( struct object *obj ); extern void make_object_static( struct object *obj ); +extern void make_object_temporary( struct object *obj ); extern struct namespace *create_namespace( unsigned int hash_size ); extern void free_kernel_objects( struct object *obj ); /* grab/release_object can take any pointer, but you better make sure */ diff --git a/server/protocol.def b/server/protocol.def index 03e567c3dd4..9c8aec6960b 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1080,6 +1080,12 @@ struct rawinput_device #define DUP_HANDLE_MAKE_GLOBAL 0x80000000 /* Not a Windows flag */ +/* Make an object temporary */ +@REQ(make_temporary) + obj_handle_t handle; /* handle to the object */ +@END + + /* Open a handle to a process */ @REQ(open_process) process_id_t pid; /* process id to open */ diff --git a/server/request.h b/server/request.h index 0b271b8479a..2dfa76f9399 100644 --- a/server/request.h +++ b/server/request.h @@ -144,6 +144,7 @@ DECL_HANDLER(get_apc_result); DECL_HANDLER(close_handle); DECL_HANDLER(set_handle_info); DECL_HANDLER(dup_handle); +DECL_HANDLER(make_temporary); DECL_HANDLER(open_process); DECL_HANDLER(open_thread); DECL_HANDLER(select); @@ -437,6 +438,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_close_handle, (req_handler)req_set_handle_info, (req_handler)req_dup_handle, + (req_handler)req_make_temporary, (req_handler)req_open_process, (req_handler)req_open_thread, (req_handler)req_select, @@ -904,6 +906,8 @@ C_ASSERT( FIELD_OFFSET(struct dup_handle_reply, handle) == 8 ); C_ASSERT( FIELD_OFFSET(struct dup_handle_reply, self) == 12 ); C_ASSERT( FIELD_OFFSET(struct dup_handle_reply, closed) == 16 ); C_ASSERT( sizeof(struct dup_handle_reply) == 24 ); +C_ASSERT( FIELD_OFFSET(struct make_temporary_request, handle) == 12 ); +C_ASSERT( sizeof(struct make_temporary_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct open_process_request, pid) == 12 ); C_ASSERT( FIELD_OFFSET(struct open_process_request, access) == 16 ); C_ASSERT( FIELD_OFFSET(struct open_process_request, attributes) == 20 ); diff --git a/server/trace.c b/server/trace.c index 7acab95efe9..5fd68111955 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1590,6 +1590,11 @@ static void dump_dup_handle_reply( const struct dup_handle_reply *req ) fprintf( stderr, ", closed=%d", req->closed ); } +static void dump_make_temporary_request( const struct make_temporary_request *req ) +{ + fprintf( stderr, " handle=%04x", req->handle ); +} + static void dump_open_process_request( const struct open_process_request *req ) { fprintf( stderr, " pid=%04x", req->pid ); @@ -4522,6 +4527,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_close_handle_request, (dump_func)dump_set_handle_info_request, (dump_func)dump_dup_handle_request, + (dump_func)dump_make_temporary_request, (dump_func)dump_open_process_request, (dump_func)dump_open_thread_request, (dump_func)dump_select_request, @@ -4812,6 +4818,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { NULL, (dump_func)dump_set_handle_info_reply, (dump_func)dump_dup_handle_reply, + NULL, (dump_func)dump_open_process_reply, (dump_func)dump_open_thread_reply, (dump_func)dump_select_reply, @@ -5102,6 +5109,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "close_handle", "set_handle_info", "dup_handle", + "make_temporary", "open_process", "open_thread", "select",