ntdll: Implemenent ObjectTypeInformation class support in NtQueryObject.
This commit is contained in:
parent
d6a044c86a
commit
71080cc081
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 );
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
Loading…
Reference in New Issue