server: Implement wineserver call for SystemHandleInformation.

Signed-off-by: Sebastian Lackner <sebastian@fds-team.de>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Sebastian Lackner 2015-12-24 13:08:50 +01:00 committed by Alexandre Julliard
parent d90ec79be2
commit 08706ef357
7 changed files with 181 additions and 15 deletions

View File

@ -2004,18 +2004,51 @@ NTSTATUS WINAPI NtQuerySystemInformation(
break;
case SystemHandleInformation:
{
SYSTEM_HANDLE_INFORMATION shi;
struct handle_info *info;
DWORD i, num_handles;
memset(&shi, 0, sizeof(shi));
len = sizeof(shi);
if ( Length >= len)
if (Length < sizeof(SYSTEM_HANDLE_INFORMATION))
{
if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
else memcpy( SystemInformation, &shi, len);
ret = STATUS_INFO_LENGTH_MISMATCH;
break;
}
else ret = STATUS_INFO_LENGTH_MISMATCH;
FIXME("info_class SYSTEM_HANDLE_INFORMATION\n");
if (!SystemInformation)
{
ret = STATUS_ACCESS_VIOLATION;
break;
}
num_handles = (Length - FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION, Handle )) / sizeof(SYSTEM_HANDLE_ENTRY);
if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*info) * num_handles )))
return STATUS_NO_MEMORY;
SERVER_START_REQ( get_system_handles )
{
wine_server_set_reply( req, info, sizeof(*info) * num_handles );
if (!(ret = wine_server_call( req )))
{
SYSTEM_HANDLE_INFORMATION *shi = SystemInformation;
shi->Count = wine_server_reply_size( req ) / sizeof(*info);
len = FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION, Handle[shi->Count] );
for (i = 0; i < shi->Count; i++)
{
memset( &shi->Handle[i], 0, sizeof(shi->Handle[i]) );
shi->Handle[i].OwnerPid = info[i].owner;
shi->Handle[i].HandleValue = info[i].handle;
shi->Handle[i].AccessMask = info[i].access;
/* FIXME: Fill out ObjectType, HandleFlags, ObjectPointer */
}
}
else if (ret == STATUS_BUFFER_TOO_SMALL)
{
len = FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION, Handle[reply->count] );
ret = STATUS_INFO_LENGTH_MISMATCH;
}
}
SERVER_END_REQ;
RtlFreeHeap( GetProcessHeap(), 0, info );
}
break;
case SystemCacheInformation:

View File

@ -487,7 +487,7 @@ static void test_query_handle(void)
/* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */
ReturnLength = 0xdeadbeef;
status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength);
todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
ok( ReturnLength != 0xdeadbeef, "Expected valid ReturnLength\n" );
SystemInformationLength = ReturnLength;
@ -503,13 +503,13 @@ static void test_query_handle(void)
}
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status );
ExpectedLength = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION, Handle[shi->Count]);
todo_wine ok( ReturnLength == ExpectedLength || broken(ReturnLength == ExpectedLength - sizeof(DWORD)), /* Vista / 2008 */
"Expected length %u, got %u\n", ExpectedLength, ReturnLength );
todo_wine ok( shi->Count > 1, "Expected more than 1 handle, got %u\n", shi->Count );
ok( ReturnLength == ExpectedLength || broken(ReturnLength == ExpectedLength - sizeof(DWORD)), /* Vista / 2008 */
"Expected length %u, got %u\n", ExpectedLength, ReturnLength );
ok( shi->Count > 1, "Expected more than 1 handle, got %u\n", shi->Count );
for (i = 0, found = FALSE; i < shi->Count && !found; i++)
found = (shi->Handle[i].OwnerPid == GetCurrentProcessId()) &&
((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle);
todo_wine ok( found, "Expected to find event handle in handle list\n" );
ok( found, "Expected to find event handle in handle list\n" );
CloseHandle(EventHandle);

View File

@ -4655,6 +4655,29 @@ struct get_security_object_reply
};
struct handle_info
{
process_id_t owner;
obj_handle_t handle;
unsigned int access;
};
struct get_system_handles_request
{
struct request_header __header;
char __pad_12[4];
};
struct get_system_handles_reply
{
struct reply_header __header;
unsigned int count;
/* VARARG(data,handle_infos); */
char __pad_12[4];
};
struct create_mailslot_request
{
struct request_header __header;
@ -5560,6 +5583,7 @@ enum request
REQ_set_token_default_dacl,
REQ_set_security_object,
REQ_get_security_object,
REQ_get_system_handles,
REQ_create_mailslot,
REQ_set_mailslot_info,
REQ_create_directory,
@ -5836,6 +5860,7 @@ union generic_request
struct set_token_default_dacl_request set_token_default_dacl_request;
struct set_security_object_request set_security_object_request;
struct get_security_object_request get_security_object_request;
struct get_system_handles_request get_system_handles_request;
struct create_mailslot_request create_mailslot_request;
struct set_mailslot_info_request set_mailslot_info_request;
struct create_directory_request create_directory_request;
@ -6110,6 +6135,7 @@ union generic_reply
struct set_token_default_dacl_reply set_token_default_dacl_reply;
struct set_security_object_reply set_security_object_reply;
struct get_security_object_reply get_security_object_reply;
struct get_system_handles_reply get_system_handles_reply;
struct create_mailslot_reply create_mailslot_reply;
struct set_mailslot_info_reply set_mailslot_info_reply;
struct create_directory_reply create_directory_reply;
@ -6154,6 +6180,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply;
};
#define SERVER_PROTOCOL_VERSION 491
#define SERVER_PROTOCOL_VERSION 492
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -745,3 +745,59 @@ DECL_HANDLER(get_security_object)
release_object( obj );
}
struct enum_handle_info
{
unsigned int count;
struct handle_info *handle;
};
static int enum_handles( struct process *process, void *user )
{
struct enum_handle_info *info = user;
struct handle_table *table = process->handles;
struct handle_entry *entry;
struct handle_info *handle;
unsigned int i;
if (!table)
return 0;
for (i = 0, entry = table->entries; i <= table->last; i++, entry++)
{
if (!entry->ptr) continue;
if (!info->handle)
{
info->count++;
continue;
}
assert( info->count );
handle = info->handle++;
handle->owner = process->id;
handle->handle = index_to_handle(i);
handle->access = entry->access & ~RESERVED_ALL;
info->count--;
}
return 0;
}
DECL_HANDLER(get_system_handles)
{
struct enum_handle_info info;
struct handle_info *handle;
data_size_t max_handles = get_reply_max_size() / sizeof(*handle);
info.handle = NULL;
info.count = 0;
enum_processes( enum_handles, &info );
reply->count = info.count;
if (max_handles < info.count)
set_error( STATUS_BUFFER_TOO_SMALL );
else if ((handle = set_reply_data_size( info.count * sizeof(*handle) )))
{
info.handle = handle;
enum_processes( enum_handles, &info );
}
}

View File

@ -3266,6 +3266,22 @@ enum coords_relative
VARARG(sd,security_descriptor); /* retrieved security descriptor */
@END
struct handle_info
{
process_id_t owner;
obj_handle_t handle;
unsigned int access;
};
/* Return a list of all opened handles */
@REQ(get_system_handles)
@REPLY
unsigned int count; /* number of handles */
VARARG(data,handle_infos); /* array of handle_infos */
@END
/* Create a mailslot */
@REQ(create_mailslot)
unsigned int access; /* wanted access rights */

View File

@ -333,6 +333,7 @@ DECL_HANDLER(get_token_default_dacl);
DECL_HANDLER(set_token_default_dacl);
DECL_HANDLER(set_security_object);
DECL_HANDLER(get_security_object);
DECL_HANDLER(get_system_handles);
DECL_HANDLER(create_mailslot);
DECL_HANDLER(set_mailslot_info);
DECL_HANDLER(create_directory);
@ -608,6 +609,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_set_token_default_dacl,
(req_handler)req_set_security_object,
(req_handler)req_get_security_object,
(req_handler)req_get_system_handles,
(req_handler)req_create_mailslot,
(req_handler)req_set_mailslot_info,
(req_handler)req_create_directory,
@ -2083,6 +2085,9 @@ C_ASSERT( FIELD_OFFSET(struct get_security_object_request, security_info) == 16
C_ASSERT( sizeof(struct get_security_object_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_security_object_reply, sd_len) == 8 );
C_ASSERT( sizeof(struct get_security_object_reply) == 16 );
C_ASSERT( sizeof(struct get_system_handles_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_system_handles_reply, count) == 8 );
C_ASSERT( sizeof(struct get_system_handles_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct create_mailslot_request, access) == 12 );
C_ASSERT( FIELD_OFFSET(struct create_mailslot_request, attributes) == 16 );
C_ASSERT( FIELD_OFFSET(struct create_mailslot_request, rootdir) == 20 );

View File

@ -1142,6 +1142,23 @@ static void dump_varargs_rawinput_devices(const char *prefix, data_size_t size )
fputc( '}', stderr );
}
static void dump_varargs_handle_infos( const char *prefix, data_size_t size )
{
const struct handle_info *handle;
fprintf( stderr, "%s{", prefix );
while (size >= sizeof(*handle))
{
handle = cur_data;
fprintf( stderr, "{owner=%04x,handle=%04x,access=%08x}",
handle->owner, handle->handle, handle->access );
size -= sizeof(*handle);
remove_data( sizeof(*handle) );
if (size) fputc( ',', stderr );
}
fputc( '}', stderr );
}
typedef void (*dump_func)( const void *req );
/* Everything below this line is generated automatically by tools/make_requests */
@ -3838,6 +3855,16 @@ static void dump_get_security_object_reply( const struct get_security_object_rep
dump_varargs_security_descriptor( ", sd=", cur_size );
}
static void dump_get_system_handles_request( const struct get_system_handles_request *req )
{
}
static void dump_get_system_handles_reply( const struct get_system_handles_reply *req )
{
fprintf( stderr, " count=%08x", req->count );
dump_varargs_handle_infos( ", data=", cur_size );
}
static void dump_create_mailslot_request( const struct create_mailslot_request *req )
{
fprintf( stderr, " access=%08x", req->access );
@ -4501,6 +4528,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_set_token_default_dacl_request,
(dump_func)dump_set_security_object_request,
(dump_func)dump_get_security_object_request,
(dump_func)dump_get_system_handles_request,
(dump_func)dump_create_mailslot_request,
(dump_func)dump_set_mailslot_info_request,
(dump_func)dump_create_directory_request,
@ -4773,6 +4801,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
NULL,
NULL,
(dump_func)dump_get_security_object_reply,
(dump_func)dump_get_system_handles_reply,
(dump_func)dump_create_mailslot_reply,
(dump_func)dump_set_mailslot_info_reply,
(dump_func)dump_create_directory_reply,
@ -5045,6 +5074,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"set_token_default_dacl",
"set_security_object",
"get_security_object",
"get_system_handles",
"create_mailslot",
"set_mailslot_info",
"create_directory",