Commit 71080cc0 authored by Qian Hong's avatar Qian Hong Committed by Alexandre Julliard

ntdll: Implemenent ObjectTypeInformation class support in NtQueryObject.

parent d6a044c8
......@@ -150,6 +150,42 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
SERVER_END_REQ;
}
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:
{
OBJECT_DATA_INFORMATION* p = ptr;
......
......@@ -690,8 +690,8 @@ static void test_query_object(void)
len = 0;
status = pNtQueryObject( handle, ObjectTypeInformation, buffer, 0, &len );
todo_wine 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( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
len = 0;
status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
......@@ -700,8 +700,8 @@ static void test_query_object(void)
len = 0;
status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(OBJECT_TYPE_INFORMATION), &len );
todo_wine 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( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
len = 0;
status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
......@@ -722,17 +722,17 @@ static void test_query_object(void)
len = 0;
memset( buffer, 0, sizeof(buffer) );
status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
todo_wine ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
todo_wine ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
str = (UNICODE_STRING *)buffer;
todo_wine 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( len >= sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR), "unexpected len %u\n", len );
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 );
len -= sizeof(WCHAR);
status = pNtQueryObject( handle, ObjectTypeInformation, buffer, len, &len );
todo_wine 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( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
pNtClose( handle );
......@@ -777,7 +777,7 @@ static void test_query_object(void)
len = 0;
memset( buffer, 0, sizeof(buffer) );
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 );
str = (UNICODE_STRING *)buffer;
expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
......
......@@ -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 request_header __header;
......@@ -5469,6 +5484,7 @@ enum request
REQ_open_symlink,
REQ_query_symlink,
REQ_get_object_info,
REQ_get_object_type,
REQ_unlink_object,
REQ_get_token_impersonation_level,
REQ_allocate_locally_unique_id,
......@@ -5740,6 +5756,7 @@ union generic_request
struct open_symlink_request open_symlink_request;
struct query_symlink_request query_symlink_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 get_token_impersonation_level_request get_token_impersonation_level_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 query_symlink_reply query_symlink_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 get_token_impersonation_level_reply get_token_impersonation_level_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;
};
#define SERVER_PROTOCOL_VERSION 474
#define SERVER_PROTOCOL_VERSION 475
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -577,3 +577,21 @@ DECL_HANDLER(unlink_object)
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 );
}
......@@ -3325,6 +3325,15 @@ enum coords_relative
@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 */
@REQ(unlink_object)
obj_handle_t handle; /* handle to the object */
......
......@@ -340,6 +340,7 @@ DECL_HANDLER(create_symlink);
DECL_HANDLER(open_symlink);
DECL_HANDLER(query_symlink);
DECL_HANDLER(get_object_info);
DECL_HANDLER(get_object_type);
DECL_HANDLER(unlink_object);
DECL_HANDLER(get_token_impersonation_level);
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_query_symlink,
(req_handler)req_get_object_info,
(req_handler)req_get_object_type,
(req_handler)req_unlink_object,
(req_handler)req_get_token_impersonation_level,
(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, total) == 20 );
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( sizeof(struct unlink_object_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_token_impersonation_level_request, handle) == 12 );
......
......@@ -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 );
}
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 )
{
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_query_symlink_request,
(dump_func)dump_get_object_info_request,
(dump_func)dump_get_object_type_request,
(dump_func)dump_unlink_object_request,
(dump_func)dump_get_token_impersonation_level_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_query_symlink_reply,
(dump_func)dump_get_object_info_reply,
(dump_func)dump_get_object_type_reply,
NULL,
(dump_func)dump_get_token_impersonation_level_reply,
(dump_func)dump_allocate_locally_unique_id_reply,
......@@ -4979,6 +4992,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"open_symlink",
"query_symlink",
"get_object_info",
"get_object_type",
"unlink_object",
"get_token_impersonation_level",
"allocate_locally_unique_id",
......@@ -5081,7 +5095,6 @@ static const struct
{ "NAME_TOO_LONG", STATUS_NAME_TOO_LONG },
{ "NETWORK_BUSY", STATUS_NETWORK_BUSY },
{ "NETWORK_UNREACHABLE", STATUS_NETWORK_UNREACHABLE },
{ "NOTIFY_ENUM_DIR", STATUS_NOTIFY_ENUM_DIR },
{ "NOT_ALL_ASSIGNED", STATUS_NOT_ALL_ASSIGNED },
{ "NOT_A_DIRECTORY", STATUS_NOT_A_DIRECTORY },
{ "NOT_FOUND", STATUS_NOT_FOUND },
......
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