server: Add support for object counts in the object type information.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c6f2aacb57
commit
dc4e881834
|
@ -6596,37 +6596,37 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
|
|||
case ObjectTypeInformation:
|
||||
{
|
||||
OBJECT_TYPE_INFORMATION *p = ptr;
|
||||
char buffer[sizeof(struct object_type_info) + 64];
|
||||
struct object_type_info *info = (struct object_type_info *)buffer;
|
||||
|
||||
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) );
|
||||
wine_server_set_reply( req, buffer, sizeof(buffer) );
|
||||
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;
|
||||
if (status) break;
|
||||
if (sizeof(*p) + info->name_len + sizeof(WCHAR) <= len)
|
||||
{
|
||||
memset( p, 0, sizeof(*p) );
|
||||
p->TypeName.Buffer = (WCHAR *)(p + 1);
|
||||
p->TypeName.Length = info->name_len;
|
||||
p->TypeName.MaximumLength = info->name_len + sizeof(WCHAR);
|
||||
p->TotalNumberOfObjects = info->obj_count;
|
||||
p->TotalNumberOfHandles = info->handle_count;
|
||||
p->HighWaterNumberOfObjects = info->obj_max;
|
||||
p->HighWaterNumberOfHandles = info->handle_max;
|
||||
p->TypeIndex = info->index + 2;
|
||||
memcpy( p->TypeName.Buffer, info + 1, info->name_len );
|
||||
p->TypeName.Buffer[info->name_len / sizeof(WCHAR)] = 0;
|
||||
if (used_len) *used_len = sizeof(*p) + p->TypeName.MaximumLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (used_len) *used_len = sizeof(*p) + info->name_len + sizeof(WCHAR);
|
||||
status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -399,6 +399,17 @@ struct object_attributes
|
|||
|
||||
};
|
||||
|
||||
struct object_type_info
|
||||
{
|
||||
data_size_t name_len;
|
||||
unsigned int index;
|
||||
unsigned int obj_count;
|
||||
unsigned int handle_count;
|
||||
unsigned int obj_max;
|
||||
unsigned int handle_max;
|
||||
|
||||
};
|
||||
|
||||
struct token_groups
|
||||
{
|
||||
unsigned int count;
|
||||
|
@ -4740,9 +4751,7 @@ struct get_object_type_request
|
|||
struct get_object_type_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
data_size_t total;
|
||||
/* VARARG(type,unicode_str); */
|
||||
char __pad_12[4];
|
||||
/* VARARG(info,object_type_info); */
|
||||
};
|
||||
|
||||
|
||||
|
@ -6234,7 +6243,7 @@ union generic_reply
|
|||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 665
|
||||
#define SERVER_PROTOCOL_VERSION 666
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
|
|
|
@ -1599,7 +1599,28 @@ typedef struct _OBJECT_NAME_INFORMATION {
|
|||
|
||||
typedef struct __OBJECT_TYPE_INFORMATION {
|
||||
UNICODE_STRING TypeName;
|
||||
ULONG Reserved [22];
|
||||
ULONG TotalNumberOfObjects;
|
||||
ULONG TotalNumberOfHandles;
|
||||
ULONG TotalPagedPoolUsage;
|
||||
ULONG TotalNonPagedPoolUsage;
|
||||
ULONG TotalNamePoolUsage;
|
||||
ULONG TotalHandleTableUsage;
|
||||
ULONG HighWaterNumberOfObjects;
|
||||
ULONG HighWaterNumberOfHandles;
|
||||
ULONG HighWaterPagedPoolUsage;
|
||||
ULONG HighWaterNonPagedPoolUsage;
|
||||
ULONG HighWaterNamePoolUsage;
|
||||
ULONG HighWaterHandleTableUsage;
|
||||
ULONG InvalidAttributes;
|
||||
GENERIC_MAPPING GenericMapping;
|
||||
ULONG ValidAccessMask;
|
||||
BOOLEAN SecurityRequired;
|
||||
BOOLEAN MaintainHandleCount;
|
||||
UCHAR TypeIndex;
|
||||
CHAR ReservedByte;
|
||||
ULONG PoolType;
|
||||
ULONG DefaultPagedPoolCharge;
|
||||
ULONG DefaultNonPagedPoolCharge;
|
||||
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
|
||||
|
||||
typedef struct _PROCESS_BASIC_INFORMATION {
|
||||
|
|
|
@ -553,11 +553,25 @@ DECL_HANDLER(get_object_type)
|
|||
{
|
||||
struct object *obj;
|
||||
struct type_descr *type;
|
||||
struct object_type_info *info;
|
||||
|
||||
if (!(obj = get_handle_obj( current->process, req->handle, 0, NULL ))) return;
|
||||
|
||||
type = obj->ops->type;
|
||||
reply->total = type->name.len;
|
||||
set_reply_data( type->name.str, min( reply->total, get_reply_max_size() ) );
|
||||
if (sizeof(*info) + type->name.len <= get_reply_max_size())
|
||||
{
|
||||
if ((info = set_reply_data_size( sizeof(*info) + type->name.len )))
|
||||
{
|
||||
info->name_len = type->name.len;
|
||||
info->index = type->index;
|
||||
info->obj_count = type->obj_count;
|
||||
info->handle_count = type->handle_count;
|
||||
info->obj_max = type->obj_max;
|
||||
info->handle_max = type->handle_max;
|
||||
memcpy( info + 1, type->name.str, type->name.len );
|
||||
}
|
||||
}
|
||||
else set_error( STATUS_BUFFER_OVERFLOW );
|
||||
|
||||
release_object( obj );
|
||||
}
|
||||
|
|
|
@ -101,6 +101,8 @@ static inline obj_handle_t handle_global_to_local( obj_handle_t handle )
|
|||
static struct object *grab_object_for_handle( struct object *obj )
|
||||
{
|
||||
obj->handle_count++;
|
||||
obj->ops->type->handle_count++;
|
||||
obj->ops->type->handle_max = max( obj->ops->type->handle_max, obj->ops->type->handle_count );
|
||||
return grab_object( obj );
|
||||
}
|
||||
|
||||
|
@ -108,6 +110,7 @@ static struct object *grab_object_for_handle( struct object *obj )
|
|||
static void release_object_from_handle( struct object *obj )
|
||||
{
|
||||
assert( obj->handle_count );
|
||||
obj->ops->type->handle_count--;
|
||||
obj->handle_count--;
|
||||
release_object( obj );
|
||||
}
|
||||
|
|
|
@ -199,6 +199,8 @@ void *alloc_object( const struct object_ops *ops )
|
|||
#ifdef DEBUG_OBJECTS
|
||||
list_add_head( &object_list, &obj->obj_list );
|
||||
#endif
|
||||
obj->ops->type->obj_count++;
|
||||
obj->ops->type->obj_max = max( obj->ops->type->obj_max, obj->ops->type->obj_count );
|
||||
return obj;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -208,6 +210,7 @@ void *alloc_object( const struct object_ops *ops )
|
|||
static void free_object( struct object *obj )
|
||||
{
|
||||
free( obj->sd );
|
||||
obj->ops->type->obj_count--;
|
||||
#ifdef DEBUG_OBJECTS
|
||||
list_remove( &obj->obj_list );
|
||||
memset( obj, 0xaa, obj->ops->size );
|
||||
|
|
|
@ -58,6 +58,10 @@ struct type_descr
|
|||
{
|
||||
struct unicode_str name; /* type name */
|
||||
unsigned int index; /* index in global array of types */
|
||||
unsigned int obj_count; /* count of objects of this type */
|
||||
unsigned int handle_count; /* count of handles of this type */
|
||||
unsigned int obj_max; /* max count of objects of this type */
|
||||
unsigned int handle_max; /* max count of handles of this type */
|
||||
};
|
||||
|
||||
/* operations valid on all objects */
|
||||
|
|
|
@ -415,6 +415,17 @@ struct object_attributes
|
|||
/* VARARG(name,unicode_str); */
|
||||
};
|
||||
|
||||
struct object_type_info
|
||||
{
|
||||
data_size_t name_len; /* length of the name string */
|
||||
unsigned int index; /* type index in global table */
|
||||
unsigned int obj_count; /* count of objects of this type */
|
||||
unsigned int handle_count; /* count of handles of this type */
|
||||
unsigned int obj_max; /* max count of objects of this type */
|
||||
unsigned int handle_max; /* max count of handles of this type */
|
||||
/* VARARG(name,unicode_str); */
|
||||
};
|
||||
|
||||
struct token_groups
|
||||
{
|
||||
unsigned int count;
|
||||
|
@ -3309,8 +3320,7 @@ struct handle_info
|
|||
@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 */
|
||||
VARARG(info,object_type_info); /* type information */
|
||||
@END
|
||||
|
||||
|
||||
|
|
|
@ -2055,8 +2055,7 @@ 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( sizeof(struct get_object_type_reply) == 8 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_token_impersonation_level_request, handle) == 12 );
|
||||
C_ASSERT( sizeof(struct get_token_impersonation_level_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_token_impersonation_level_reply, impersonation_level) == 8 );
|
||||
|
|
|
@ -1214,6 +1214,29 @@ static void dump_varargs_object_attributes( const char *prefix, data_size_t size
|
|||
fputc( '}', stderr );
|
||||
}
|
||||
|
||||
static void dump_varargs_object_type_info( const char *prefix, data_size_t size )
|
||||
{
|
||||
const struct object_type_info *info = cur_data;
|
||||
|
||||
fprintf( stderr,"%s{", prefix );
|
||||
if (size)
|
||||
{
|
||||
if (size < sizeof(*info) || (size - sizeof(*info) < info->name_len))
|
||||
{
|
||||
fprintf( stderr, "***invalid***}" );
|
||||
remove_data( size );
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf( stderr, "index=%u,obj_count=%u,handle_count=%u,obj_max=%u,handle_max=%u,name=L\"",
|
||||
info->index,info->obj_count, info->handle_count, info->obj_max, info->handle_max );
|
||||
dump_strW( (const WCHAR *)(info + 1), info->name_len, stderr, "\"\"" );
|
||||
fputc( '\"', stderr );
|
||||
remove_data( min( size, sizeof(*info) + ((info->name_len + 2) & ~3 )));
|
||||
}
|
||||
fputc( '}', stderr );
|
||||
}
|
||||
|
||||
static void dump_varargs_filesystem_event( const char *prefix, data_size_t size )
|
||||
{
|
||||
static const char * const actions[] = {
|
||||
|
@ -4021,8 +4044,7 @@ static void dump_get_object_type_request( const struct get_object_type_request *
|
|||
|
||||
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 );
|
||||
dump_varargs_object_type_info( " info=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_get_token_impersonation_level_request( const struct get_token_impersonation_level_request *req )
|
||||
|
|
Loading…
Reference in New Issue