Commit b6f774df authored by Alexandre Julliard's avatar Alexandre Julliard

server: Add a request to return all object types.

parent d6ef9401
......@@ -6491,6 +6491,30 @@ NTSTATUS WINAPI NtSetEaFile( HANDLE handle, IO_STATUS_BLOCK *io, void *buffer, U
}
/* convert type information from server format; helper for NtQueryObject */
static void *put_object_type_info( OBJECT_TYPE_INFORMATION *p, struct object_type_info *info )
{
const ULONG align = sizeof(DWORD_PTR) - 1;
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;
p->GenericMapping.GenericRead = info->mapping.read;
p->GenericMapping.GenericWrite = info->mapping.write;
p->GenericMapping.GenericExecute = info->mapping.exec;
p->GenericMapping.GenericAll = info->mapping.all;
p->ValidAccessMask = info->valid_access;
memcpy( p->TypeName.Buffer, info + 1, info->name_len );
p->TypeName.Buffer[info->name_len / sizeof(WCHAR)] = 0;
return (char *)(p + 1) + ((p->TypeName.MaximumLength + align) & ~align);
}
/**************************************************************************
* NtQueryObject (NTDLL.@)
*/
......@@ -6609,22 +6633,7 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
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;
p->GenericMapping.GenericRead = info->mapping.read;
p->GenericMapping.GenericWrite = info->mapping.write;
p->GenericMapping.GenericExecute = info->mapping.exec;
p->GenericMapping.GenericAll = info->mapping.all;
p->ValidAccessMask = info->valid_access;
memcpy( p->TypeName.Buffer, info + 1, info->name_len );
p->TypeName.Buffer[info->name_len / sizeof(WCHAR)] = 0;
put_object_type_info( p, info );
if (used_len) *used_len = sizeof(*p) + p->TypeName.MaximumLength;
}
else
......@@ -6635,6 +6644,44 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
break;
}
case ObjectTypesInformation:
{
OBJECT_TYPES_INFORMATION *types = ptr;
OBJECT_TYPE_INFORMATION *p;
struct object_type_info *buffer;
/* assume at most 32 types, with an average 16-char name */
ULONG size = 32 * (sizeof(struct object_type_info) + 16 * sizeof(WCHAR));
ULONG i, count, pos, total, align = sizeof(DWORD_PTR) - 1;
buffer = malloc( size );
SERVER_START_REQ( get_object_types )
{
wine_server_set_reply( req, buffer, size );
status = wine_server_call( req );
count = reply->count;
}
SERVER_END_REQ;
if (!status)
{
if (len >= sizeof(*types)) types->NumberOfTypes = count;
total = (sizeof(*types) + align) & ~align;
p = (OBJECT_TYPE_INFORMATION *)((char *)ptr + total);
for (i = pos = 0; i < count; i++)
{
struct object_type_info *info = (struct object_type_info *)((char *)buffer + pos);
pos += sizeof(*info) + ((info->name_len + 3) & ~3);
total += sizeof(*p) + ((info->name_len + sizeof(WCHAR) + align) & ~align);
if (total <= len) p = put_object_type_info( p, info );
}
if (used_len) *used_len = total;
if (total > len) status = STATUS_INFO_LENGTH_MISMATCH;
}
else if (status == STATUS_BUFFER_OVERFLOW) FIXME( "size %u too small\n", size );
free( buffer );
break;
}
case ObjectDataInformation:
{
OBJECT_DATA_INFORMATION* p = ptr;
......
......@@ -4758,6 +4758,21 @@ struct get_object_type_reply
struct get_object_types_request
{
struct request_header __header;
char __pad_12[4];
};
struct get_object_types_reply
{
struct reply_header __header;
int count;
/* VARARG(info,object_types_info); */
char __pad_12[4];
};
struct get_token_impersonation_level_request
{
struct request_header __header;
......@@ -5635,6 +5650,7 @@ enum request
REQ_query_symlink,
REQ_get_object_info,
REQ_get_object_type,
REQ_get_object_types,
REQ_get_token_impersonation_level,
REQ_allocate_locally_unique_id,
REQ_create_device_manager,
......@@ -5918,6 +5934,7 @@ union generic_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 get_object_types_request get_object_types_request;
struct get_token_impersonation_level_request get_token_impersonation_level_request;
struct allocate_locally_unique_id_request allocate_locally_unique_id_request;
struct create_device_manager_request create_device_manager_request;
......@@ -6199,6 +6216,7 @@ union generic_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 get_object_types_reply get_object_types_reply;
struct get_token_impersonation_level_reply get_token_impersonation_level_reply;
struct allocate_locally_unique_id_reply allocate_locally_unique_id_reply;
struct create_device_manager_reply create_device_manager_reply;
......@@ -6245,7 +6263,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 667
#define SERVER_PROTOCOL_VERSION 668
/* ### protocol_version end ### */
......
......@@ -1160,7 +1160,7 @@ typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
ObjectAllInformation,
ObjectTypesInformation,
ObjectDataInformation
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
......@@ -1623,6 +1623,11 @@ typedef struct __OBJECT_TYPE_INFORMATION {
ULONG DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
typedef struct _OBJECT_TYPES_INFORMATION
{
ULONG NumberOfTypes;
} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION;
typedef struct _PROCESS_BASIC_INFORMATION {
#ifdef __WINESRC__
DWORD_PTR ExitStatus;
......
......@@ -591,3 +591,42 @@ DECL_HANDLER(get_object_type)
release_object( obj );
}
/* query type information for all types */
DECL_HANDLER(get_object_types)
{
struct object_type_info *info;
data_size_t size = ARRAY_SIZE(types) * sizeof(*info);
unsigned int i;
char *next;
for (i = 0; i < ARRAY_SIZE(types); i++) size += (types[i]->name.len + 3) & ~3;
if (size <= get_reply_max_size())
{
if ((info = set_reply_data_size( size )))
{
for (i = 0; i < ARRAY_SIZE(types); i++)
{
info->name_len = types[i]->name.len;
info->index = types[i]->index;
info->obj_count = types[i]->obj_count;
info->handle_count = types[i]->handle_count;
info->obj_max = types[i]->obj_max;
info->handle_max = types[i]->handle_max;
info->valid_access = types[i]->valid_access;
info->mapping = types[i]->mapping;
memcpy( info + 1, types[i]->name.str, types[i]->name.len );
next = (char *)(info + 1) + types[i]->name.len;
if (types[i]->name.len & 3)
{
memset( next, 0, 4 - (types[i]->name.len & 3) );
next += 4 - (types[i]->name.len & 3);
}
info = (struct object_type_info *)next;
}
reply->count = i;
}
}
else set_error( STATUS_BUFFER_OVERFLOW );
}
......@@ -3326,6 +3326,14 @@ struct handle_info
@END
/* Query type information for all types */
@REQ(get_object_types)
@REPLY
int count; /* total count of object types */
VARARG(info,object_types_info); /* type information */
@END
/* Query the impersonation level of an impersonation token */
@REQ(get_token_impersonation_level)
obj_handle_t handle; /* handle to the object */
......
......@@ -353,6 +353,7 @@ DECL_HANDLER(open_symlink);
DECL_HANDLER(query_symlink);
DECL_HANDLER(get_object_info);
DECL_HANDLER(get_object_type);
DECL_HANDLER(get_object_types);
DECL_HANDLER(get_token_impersonation_level);
DECL_HANDLER(allocate_locally_unique_id);
DECL_HANDLER(create_device_manager);
......@@ -635,6 +636,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_query_symlink,
(req_handler)req_get_object_info,
(req_handler)req_get_object_type,
(req_handler)req_get_object_types,
(req_handler)req_get_token_impersonation_level,
(req_handler)req_allocate_locally_unique_id,
(req_handler)req_create_device_manager,
......@@ -2056,6 +2058,9 @@ 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( sizeof(struct get_object_type_reply) == 8 );
C_ASSERT( sizeof(struct get_object_types_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_object_types_reply, count) == 8 );
C_ASSERT( sizeof(struct get_object_types_reply) == 16 );
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 );
......
......@@ -1240,6 +1240,13 @@ static void dump_varargs_object_type_info( const char *prefix, data_size_t size
fputc( '}', stderr );
}
static void dump_varargs_object_types_info( const char *prefix, data_size_t size )
{
fprintf( stderr,"%s{", prefix );
while (cur_size) dump_varargs_object_type_info( ",", cur_size );
fputc( '}', stderr );
}
static void dump_varargs_filesystem_event( const char *prefix, data_size_t size )
{
static const char * const actions[] = {
......@@ -4050,6 +4057,16 @@ static void dump_get_object_type_reply( const struct get_object_type_reply *req
dump_varargs_object_type_info( " info=", cur_size );
}
static void dump_get_object_types_request( const struct get_object_types_request *req )
{
}
static void dump_get_object_types_reply( const struct get_object_types_reply *req )
{
fprintf( stderr, " count=%d", req->count );
dump_varargs_object_types_info( ", info=", cur_size );
}
static void dump_get_token_impersonation_level_request( const struct get_token_impersonation_level_request *req )
{
fprintf( stderr, " handle=%04x", req->handle );
......@@ -4677,6 +4694,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_query_symlink_request,
(dump_func)dump_get_object_info_request,
(dump_func)dump_get_object_type_request,
(dump_func)dump_get_object_types_request,
(dump_func)dump_get_token_impersonation_level_request,
(dump_func)dump_allocate_locally_unique_id_request,
(dump_func)dump_create_device_manager_request,
......@@ -4956,6 +4974,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_query_symlink_reply,
(dump_func)dump_get_object_info_reply,
(dump_func)dump_get_object_type_reply,
(dump_func)dump_get_object_types_reply,
(dump_func)dump_get_token_impersonation_level_reply,
(dump_func)dump_allocate_locally_unique_id_reply,
(dump_func)dump_create_device_manager_reply,
......@@ -5235,6 +5254,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"query_symlink",
"get_object_info",
"get_object_type",
"get_object_types",
"get_token_impersonation_level",
"allocate_locally_unique_id",
"create_device_manager",
......
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