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:
parent
d90ec79be2
commit
08706ef357
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue