ntdll: Implement NtQuerySystemInformation(SystemExtendedHandleInformation).
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
(cherry picked from commit 835f5fff71
)
Signed-off-by: Michael Stefaniuc <mstefani@winehq.org>
This commit is contained in:
parent
c3674b30f2
commit
dc85e95017
|
@ -603,6 +603,84 @@ done:
|
|||
HeapFree( GetProcessHeap(), 0, shi);
|
||||
}
|
||||
|
||||
static void test_query_handle_ex(void)
|
||||
{
|
||||
SYSTEM_HANDLE_INFORMATION_EX *info = malloc(sizeof(SYSTEM_HANDLE_INFORMATION_EX));
|
||||
ULONG size, expect_size;
|
||||
NTSTATUS status;
|
||||
unsigned int i;
|
||||
HANDLE event;
|
||||
BOOL found, ret;
|
||||
|
||||
event = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
ok(event != NULL, "failed to create event, error %u\n", GetLastError());
|
||||
ret = SetHandleInformation(event, HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE,
|
||||
HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE);
|
||||
ok(ret, "got error %u\n", GetLastError());
|
||||
|
||||
size = 0;
|
||||
status = pNtQuerySystemInformation(SystemExtendedHandleInformation, info, sizeof(SYSTEM_HANDLE_INFORMATION_EX), &size);
|
||||
ok(status == STATUS_INFO_LENGTH_MISMATCH, "got %#x\n", status);
|
||||
ok(size > sizeof(SYSTEM_HANDLE_INFORMATION_EX), "got size %u\n", size);
|
||||
|
||||
while (status == STATUS_INFO_LENGTH_MISMATCH)
|
||||
{
|
||||
info = realloc(info, size);
|
||||
status = pNtQuerySystemInformation(SystemExtendedHandleInformation, info, size, &size);
|
||||
}
|
||||
ok(!status, "got %#x\n", status);
|
||||
expect_size = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX, Handles[info->NumberOfHandles]);
|
||||
ok(size == expect_size, "expected size %u, got %u\n", expect_size, size);
|
||||
ok(info->NumberOfHandles > 1, "got %Iu handles\n", info->NumberOfHandles);
|
||||
|
||||
found = FALSE;
|
||||
for (i = 0; i < info->NumberOfHandles; ++i)
|
||||
{
|
||||
if (info->Handles[i].UniqueProcessId == GetCurrentProcessId()
|
||||
&& (HANDLE)info->Handles[i].HandleValue == event)
|
||||
{
|
||||
todo_wine ok(info->Handles[i].HandleAttributes == (OBJ_INHERIT | OBJ_PROTECT_CLOSE),
|
||||
"got flags %#x\n", info->Handles[i].HandleAttributes);
|
||||
ok(info->Handles[i].GrantedAccess == EVENT_ALL_ACCESS, "got access %#x\n", info->Handles[i].GrantedAccess);
|
||||
found = TRUE;
|
||||
}
|
||||
ok(!info->Handles[i].CreatorBackTraceIndex, "got backtrace index %u\n", info->Handles[i].CreatorBackTraceIndex);
|
||||
}
|
||||
ok(found, "event handle not found\n");
|
||||
|
||||
ret = SetHandleInformation(event, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0);
|
||||
ok(ret, "got error %u\n", GetLastError());
|
||||
CloseHandle(event);
|
||||
|
||||
status = pNtQuerySystemInformation(SystemExtendedHandleInformation, info, size, &size);
|
||||
while (status == STATUS_INFO_LENGTH_MISMATCH)
|
||||
{
|
||||
info = realloc(info, size);
|
||||
status = pNtQuerySystemInformation(SystemExtendedHandleInformation, info, size, &size);
|
||||
}
|
||||
ok(!status, "got %#x\n", status);
|
||||
expect_size = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX, Handles[info->NumberOfHandles]);
|
||||
ok(size == expect_size, "expected size %u, got %u\n", expect_size, size);
|
||||
ok(info->NumberOfHandles > 1, "got %Iu handles\n", info->NumberOfHandles);
|
||||
|
||||
found = FALSE;
|
||||
for (i = 0; i < info->NumberOfHandles; ++i)
|
||||
{
|
||||
if (info->Handles[i].UniqueProcessId == GetCurrentProcessId()
|
||||
&& (HANDLE)info->Handles[i].HandleValue == event)
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(!found, "event handle found\n");
|
||||
|
||||
status = pNtQuerySystemInformation(SystemExtendedHandleInformation, NULL, sizeof(SYSTEM_HANDLE_INFORMATION_EX), &size);
|
||||
ok( status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status );
|
||||
|
||||
free(info);
|
||||
}
|
||||
|
||||
static void test_query_cache(void)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
@ -2762,6 +2840,7 @@ START_TEST(info)
|
|||
test_query_procperf();
|
||||
test_query_module();
|
||||
test_query_handle();
|
||||
test_query_handle_ex();
|
||||
test_query_cache();
|
||||
test_query_interrupt();
|
||||
test_time_adjustment();
|
||||
|
|
|
@ -2461,6 +2461,56 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
|
|||
break;
|
||||
}
|
||||
|
||||
case SystemExtendedHandleInformation:
|
||||
{
|
||||
struct handle_info *handle_info;
|
||||
DWORD i, num_handles;
|
||||
|
||||
if (size < sizeof(SYSTEM_HANDLE_INFORMATION_EX))
|
||||
{
|
||||
ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!info)
|
||||
{
|
||||
ret = STATUS_ACCESS_VIOLATION;
|
||||
break;
|
||||
}
|
||||
|
||||
num_handles = (size - FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION_EX, Handles ))
|
||||
/ sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX);
|
||||
if (!(handle_info = malloc( sizeof(*handle_info) * num_handles ))) return STATUS_NO_MEMORY;
|
||||
|
||||
SERVER_START_REQ( get_system_handles )
|
||||
{
|
||||
wine_server_set_reply( req, handle_info, sizeof(*handle_info) * num_handles );
|
||||
if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
SYSTEM_HANDLE_INFORMATION_EX *shi = info;
|
||||
shi->NumberOfHandles = wine_server_reply_size( req ) / sizeof(*handle_info);
|
||||
len = FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION_EX, Handles[shi->NumberOfHandles] );
|
||||
for (i = 0; i < shi->NumberOfHandles; i++)
|
||||
{
|
||||
memset( &shi->Handles[i], 0, sizeof(shi->Handles[i]) );
|
||||
shi->Handles[i].UniqueProcessId = handle_info[i].owner;
|
||||
shi->Handles[i].HandleValue = handle_info[i].handle;
|
||||
shi->Handles[i].GrantedAccess = handle_info[i].access;
|
||||
/* FIXME: Fill out Object, HandleAttributes, ObjectTypeIndex */
|
||||
}
|
||||
}
|
||||
else if (ret == STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
len = FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION_EX, Handles[reply->count] );
|
||||
ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
free( handle_info );
|
||||
break;
|
||||
}
|
||||
|
||||
case SystemCacheInformation:
|
||||
{
|
||||
SYSTEM_CACHE_INFORMATION sci = { 0 };
|
||||
|
|
|
@ -1867,6 +1867,25 @@ typedef struct _SYSTEM_HANDLE_INFORMATION {
|
|||
SYSTEM_HANDLE_ENTRY Handle[1];
|
||||
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
|
||||
{
|
||||
void *Object;
|
||||
ULONG_PTR UniqueProcessId;
|
||||
ULONG_PTR HandleValue;
|
||||
ULONG GrantedAccess;
|
||||
USHORT CreatorBackTraceIndex;
|
||||
USHORT ObjectTypeIndex;
|
||||
ULONG HandleAttributes;
|
||||
ULONG Reserved;
|
||||
} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;
|
||||
|
||||
typedef struct _SYSTEM_HANDLE_INFORMATION_EX
|
||||
{
|
||||
ULONG_PTR NumberOfHandles;
|
||||
ULONG_PTR Reserved;
|
||||
SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1];
|
||||
} SYSTEM_HANDLE_INFORMATION_EX;
|
||||
|
||||
/* System Information Class 0x15 */
|
||||
|
||||
typedef struct _SYSTEM_CACHE_INFORMATION {
|
||||
|
@ -2244,6 +2263,7 @@ typedef struct _RTL_HANDLE_TABLE
|
|||
|
||||
#define LOGONID_CURRENT ((ULONG)-1)
|
||||
|
||||
#define OBJ_PROTECT_CLOSE 0x00000001
|
||||
#define OBJ_INHERIT 0x00000002
|
||||
#define OBJ_PERMANENT 0x00000010
|
||||
#define OBJ_EXCLUSIVE 0x00000020
|
||||
|
|
Loading…
Reference in New Issue