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 < sizeof(SYSTEM_HANDLE_INFORMATION))
+ {
+ ret = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
- if ( Length >= len)
+ if (!SystemInformation)
{
- if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
- else memcpy( SystemInformation, &shi, len);
+ ret = STATUS_ACCESS_VIOLATION;
+ break;
}
- else ret = STATUS_INFO_LENGTH_MISMATCH;
- FIXME("info_class SYSTEM_HANDLE_INFORMATION\n");
+
+ 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:
/* 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;
}
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);
};
+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;
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,
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;
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;
struct terminate_job_reply terminate_job_reply;
};
-#define SERVER_PROTOCOL_VERSION 491
+#define SERVER_PROTOCOL_VERSION 492
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
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 );
+ }
+}
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 */
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);
(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,
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 );
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 */
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 );
(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,
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,
"set_token_default_dacl",
"set_security_object",
"get_security_object",
+ "get_system_handles",
"create_mailslot",
"set_mailslot_info",
"create_directory",