ntdll: Implemenent ObjectTypeInformation class support in NtQueryObject.

This commit is contained in:
Qian Hong 2015-06-02 22:09:48 +08:00 committed by Alexandre Julliard
parent d6a044c86a
commit 71080cc081
7 changed files with 113 additions and 13 deletions

View File

@ -150,6 +150,42 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
SERVER_END_REQ; SERVER_END_REQ;
} }
break; break;
case ObjectTypeInformation:
{
OBJECT_TYPE_INFORMATION *p = ptr;
SERVER_START_REQ( get_object_type )
{
req->handle = wine_server_obj_handle( handle );
if (len > sizeof(*p)) wine_server_set_reply( req, p + 1, len - sizeof(*p) );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
if (!reply->total) /* no name */
{
if (sizeof(*p) > len) status = STATUS_INFO_LENGTH_MISMATCH;
else memset( p, 0, sizeof(*p) );
if (used_len) *used_len = sizeof(*p);
}
else if (sizeof(*p) + reply->total + sizeof(WCHAR) > len)
{
if (used_len) *used_len = sizeof(*p) + reply->total + sizeof(WCHAR);
status = STATUS_INFO_LENGTH_MISMATCH;
}
else
{
ULONG res = wine_server_reply_size( reply );
p->TypeName.Buffer = (WCHAR *)(p + 1);
p->TypeName.Length = res;
p->TypeName.MaximumLength = res + sizeof(WCHAR);
p->TypeName.Buffer[res / sizeof(WCHAR)] = 0;
if (used_len) *used_len = sizeof(*p) + p->TypeName.MaximumLength;
}
}
}
SERVER_END_REQ;
}
break;
case ObjectDataInformation: case ObjectDataInformation:
{ {
OBJECT_DATA_INFORMATION* p = ptr; OBJECT_DATA_INFORMATION* p = ptr;

View File

@ -690,8 +690,8 @@ static void test_query_object(void)
len = 0; len = 0;
status = pNtQueryObject( handle, ObjectTypeInformation, buffer, 0, &len ); status = pNtQueryObject( handle, ObjectTypeInformation, buffer, 0, &len );
todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status ); ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len ); ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
len = 0; len = 0;
status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len ); status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
@ -700,8 +700,8 @@ static void test_query_object(void)
len = 0; len = 0;
status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(OBJECT_TYPE_INFORMATION), &len ); status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(OBJECT_TYPE_INFORMATION), &len );
todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status ); ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len ); ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
len = 0; len = 0;
status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
@ -722,17 +722,17 @@ static void test_query_object(void)
len = 0; len = 0;
memset( buffer, 0, sizeof(buffer) ); memset( buffer, 0, sizeof(buffer) );
status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len ); status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
todo_wine ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status ); ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
todo_wine ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len ); ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
str = (UNICODE_STRING *)buffer; str = (UNICODE_STRING *)buffer;
todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR), "unexpected len %u\n", len ); ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR), "unexpected len %u\n", len );
todo_wine ok( str->Buffer && !memcmp( str->Buffer, type_event, sizeof(type_event) ), ok( str->Buffer && !memcmp( str->Buffer, type_event, sizeof(type_event) ),
"wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer ); "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
len -= sizeof(WCHAR); len -= sizeof(WCHAR);
status = pNtQueryObject( handle, ObjectTypeInformation, buffer, len, &len ); status = pNtQueryObject( handle, ObjectTypeInformation, buffer, len, &len );
todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status ); ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len ); ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
pNtClose( handle ); pNtClose( handle );
@ -777,7 +777,7 @@ static void test_query_object(void)
len = 0; len = 0;
memset( buffer, 0, sizeof(buffer) ); memset( buffer, 0, sizeof(buffer) );
status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len ); status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
todo_wine ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status ); ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
todo_wine ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len ); todo_wine ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
str = (UNICODE_STRING *)buffer; str = (UNICODE_STRING *)buffer;
expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR); expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);

View File

@ -4760,6 +4760,21 @@ struct get_object_info_reply
struct get_object_type_request
{
struct request_header __header;
obj_handle_t handle;
};
struct get_object_type_reply
{
struct reply_header __header;
data_size_t total;
/* VARARG(type,unicode_str); */
char __pad_12[4];
};
struct unlink_object_request struct unlink_object_request
{ {
struct request_header __header; struct request_header __header;
@ -5469,6 +5484,7 @@ enum request
REQ_open_symlink, REQ_open_symlink,
REQ_query_symlink, REQ_query_symlink,
REQ_get_object_info, REQ_get_object_info,
REQ_get_object_type,
REQ_unlink_object, REQ_unlink_object,
REQ_get_token_impersonation_level, REQ_get_token_impersonation_level,
REQ_allocate_locally_unique_id, REQ_allocate_locally_unique_id,
@ -5740,6 +5756,7 @@ union generic_request
struct open_symlink_request open_symlink_request; struct open_symlink_request open_symlink_request;
struct query_symlink_request query_symlink_request; struct query_symlink_request query_symlink_request;
struct get_object_info_request get_object_info_request; struct get_object_info_request get_object_info_request;
struct get_object_type_request get_object_type_request;
struct unlink_object_request unlink_object_request; struct unlink_object_request unlink_object_request;
struct get_token_impersonation_level_request get_token_impersonation_level_request; struct get_token_impersonation_level_request get_token_impersonation_level_request;
struct allocate_locally_unique_id_request allocate_locally_unique_id_request; struct allocate_locally_unique_id_request allocate_locally_unique_id_request;
@ -6009,6 +6026,7 @@ union generic_reply
struct open_symlink_reply open_symlink_reply; struct open_symlink_reply open_symlink_reply;
struct query_symlink_reply query_symlink_reply; struct query_symlink_reply query_symlink_reply;
struct get_object_info_reply get_object_info_reply; struct get_object_info_reply get_object_info_reply;
struct get_object_type_reply get_object_type_reply;
struct unlink_object_reply unlink_object_reply; struct unlink_object_reply unlink_object_reply;
struct get_token_impersonation_level_reply get_token_impersonation_level_reply; struct get_token_impersonation_level_reply get_token_impersonation_level_reply;
struct allocate_locally_unique_id_reply allocate_locally_unique_id_reply; struct allocate_locally_unique_id_reply allocate_locally_unique_id_reply;
@ -6041,6 +6059,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply; struct terminate_job_reply terminate_job_reply;
}; };
#define SERVER_PROTOCOL_VERSION 474 #define SERVER_PROTOCOL_VERSION 475
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -577,3 +577,21 @@ DECL_HANDLER(unlink_object)
release_object( obj ); release_object( obj );
} }
} }
/* query object type name information */
DECL_HANDLER(get_object_type)
{
struct object *obj;
struct object_type *type;
const WCHAR *name;
if (!(obj = get_handle_obj( current->process, req->handle, 0, NULL ))) return;
if ((type = obj->ops->get_type( obj )))
{
if ((name = get_object_name( &type->obj, &reply->total )))
set_reply_data( name, min( reply->total, get_reply_max_size() ) );
release_object( type );
}
release_object( obj );
}

View File

@ -3325,6 +3325,15 @@ enum coords_relative
@END @END
/* Query object type name information */
@REQ(get_object_type)
obj_handle_t handle; /* handle to the object */
@REPLY
data_size_t total; /* needed size for type name */
VARARG(type,unicode_str); /* type name */
@END
/* Unlink a named object */ /* Unlink a named object */
@REQ(unlink_object) @REQ(unlink_object)
obj_handle_t handle; /* handle to the object */ obj_handle_t handle; /* handle to the object */

View File

@ -340,6 +340,7 @@ DECL_HANDLER(create_symlink);
DECL_HANDLER(open_symlink); DECL_HANDLER(open_symlink);
DECL_HANDLER(query_symlink); DECL_HANDLER(query_symlink);
DECL_HANDLER(get_object_info); DECL_HANDLER(get_object_info);
DECL_HANDLER(get_object_type);
DECL_HANDLER(unlink_object); DECL_HANDLER(unlink_object);
DECL_HANDLER(get_token_impersonation_level); DECL_HANDLER(get_token_impersonation_level);
DECL_HANDLER(allocate_locally_unique_id); DECL_HANDLER(allocate_locally_unique_id);
@ -610,6 +611,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_open_symlink, (req_handler)req_open_symlink,
(req_handler)req_query_symlink, (req_handler)req_query_symlink,
(req_handler)req_get_object_info, (req_handler)req_get_object_info,
(req_handler)req_get_object_type,
(req_handler)req_unlink_object, (req_handler)req_unlink_object,
(req_handler)req_get_token_impersonation_level, (req_handler)req_get_token_impersonation_level,
(req_handler)req_allocate_locally_unique_id, (req_handler)req_allocate_locally_unique_id,
@ -2118,6 +2120,10 @@ C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, ref_count) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, handle_count) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, handle_count) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, total) == 20 ); C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, total) == 20 );
C_ASSERT( sizeof(struct get_object_info_reply) == 24 ); C_ASSERT( sizeof(struct get_object_info_reply) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_object_type_request, handle) == 12 );
C_ASSERT( sizeof(struct get_object_type_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_object_type_reply, total) == 8 );
C_ASSERT( sizeof(struct get_object_type_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct unlink_object_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct unlink_object_request, handle) == 12 );
C_ASSERT( sizeof(struct unlink_object_request) == 16 ); C_ASSERT( sizeof(struct unlink_object_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_token_impersonation_level_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_token_impersonation_level_request, handle) == 12 );

View File

@ -3919,6 +3919,17 @@ static void dump_get_object_info_reply( const struct get_object_info_reply *req
dump_varargs_unicode_str( ", name=", cur_size ); dump_varargs_unicode_str( ", name=", cur_size );
} }
static void dump_get_object_type_request( const struct get_object_type_request *req )
{
fprintf( stderr, " handle=%04x", req->handle );
}
static void dump_get_object_type_reply( const struct get_object_type_reply *req )
{
fprintf( stderr, " total=%u", req->total );
dump_varargs_unicode_str( ", type=", cur_size );
}
static void dump_unlink_object_request( const struct unlink_object_request *req ) static void dump_unlink_object_request( const struct unlink_object_request *req )
{ {
fprintf( stderr, " handle=%04x", req->handle ); fprintf( stderr, " handle=%04x", req->handle );
@ -4445,6 +4456,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_open_symlink_request, (dump_func)dump_open_symlink_request,
(dump_func)dump_query_symlink_request, (dump_func)dump_query_symlink_request,
(dump_func)dump_get_object_info_request, (dump_func)dump_get_object_info_request,
(dump_func)dump_get_object_type_request,
(dump_func)dump_unlink_object_request, (dump_func)dump_unlink_object_request,
(dump_func)dump_get_token_impersonation_level_request, (dump_func)dump_get_token_impersonation_level_request,
(dump_func)dump_allocate_locally_unique_id_request, (dump_func)dump_allocate_locally_unique_id_request,
@ -4712,6 +4724,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_open_symlink_reply, (dump_func)dump_open_symlink_reply,
(dump_func)dump_query_symlink_reply, (dump_func)dump_query_symlink_reply,
(dump_func)dump_get_object_info_reply, (dump_func)dump_get_object_info_reply,
(dump_func)dump_get_object_type_reply,
NULL, NULL,
(dump_func)dump_get_token_impersonation_level_reply, (dump_func)dump_get_token_impersonation_level_reply,
(dump_func)dump_allocate_locally_unique_id_reply, (dump_func)dump_allocate_locally_unique_id_reply,
@ -4979,6 +4992,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"open_symlink", "open_symlink",
"query_symlink", "query_symlink",
"get_object_info", "get_object_info",
"get_object_type",
"unlink_object", "unlink_object",
"get_token_impersonation_level", "get_token_impersonation_level",
"allocate_locally_unique_id", "allocate_locally_unique_id",
@ -5081,7 +5095,6 @@ static const struct
{ "NAME_TOO_LONG", STATUS_NAME_TOO_LONG }, { "NAME_TOO_LONG", STATUS_NAME_TOO_LONG },
{ "NETWORK_BUSY", STATUS_NETWORK_BUSY }, { "NETWORK_BUSY", STATUS_NETWORK_BUSY },
{ "NETWORK_UNREACHABLE", STATUS_NETWORK_UNREACHABLE }, { "NETWORK_UNREACHABLE", STATUS_NETWORK_UNREACHABLE },
{ "NOTIFY_ENUM_DIR", STATUS_NOTIFY_ENUM_DIR },
{ "NOT_ALL_ASSIGNED", STATUS_NOT_ALL_ASSIGNED }, { "NOT_ALL_ASSIGNED", STATUS_NOT_ALL_ASSIGNED },
{ "NOT_A_DIRECTORY", STATUS_NOT_A_DIRECTORY }, { "NOT_A_DIRECTORY", STATUS_NOT_A_DIRECTORY },
{ "NOT_FOUND", STATUS_NOT_FOUND }, { "NOT_FOUND", STATUS_NOT_FOUND },