Added patch to implement SystemHandleInformation info class.

This commit is contained in:
Sebastian Lackner 2015-10-31 22:29:13 +01:00
parent d4e3581847
commit d9bb5a1e45
6 changed files with 294 additions and 1 deletions

View File

@ -34,7 +34,7 @@ Wine. All those differences are also documented on the
Included bug fixes and improvements
-----------------------------------
**Bug fixes and features included in the next upcoming release [11]:**
**Bug fixes and features included in the next upcoming release [12]:**
* Add stub for SetCoalescableTimer ([Wine Bug #39509](https://bugs.winehq.org/show_bug.cgi?id=39509))
* Add stub for SetConsoleKeyShortcuts ([Wine Bug #35702](https://bugs.winehq.org/show_bug.cgi?id=35702))
@ -43,6 +43,7 @@ Included bug fixes and improvements
* Fix multiple issues in widl typelib generation
* IEnumSTATSTG::Next should zero out returned stats when enumeration ends
* Implement FileNamesInformation class support for NtQueryDirectoryFile
* Implement SystemHandleInformation info class
* Implement hal.KeQueryPerformanceCounter ([Wine Bug #39500](https://bugs.winehq.org/show_bug.cgi?id=39500))
* Implement kernel32.GetConsoleFontSize
* Implement stub for ProcessQuotaLimits info class

1
debian/changelog vendored
View File

@ -25,6 +25,7 @@ wine-staging (1.7.54) UNRELEASED; urgency=low
* Added patch to fix multiple issues in widl typelib generation.
* Added patch for SetConsoleKeyShortcuts stub function.
* Added patch to implement kernel32.GetConsoleFontSize.
* Added patch to implement SystemHandleInformation info class.
* Removed patch to implement kernel32.GetPhysicallyInstalledSystemMemory
(accepted upstream).
* Partially removed patches for ws2_32 TransmitFile (accepted upstream).

View File

@ -0,0 +1,72 @@
From b63f6580710ea93ed81219bcad3f9cfab7f6c742 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 31 Oct 2015 22:06:57 +0100
Subject: ntdll/tests: Add more tests for SystemHandleInformation.
---
dlls/ntdll/tests/info.c | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 83fdd53..8e0a806 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -477,27 +477,47 @@ static void test_query_handle(void)
ULONG ReturnLength;
ULONG SystemInformationLength = sizeof(SYSTEM_HANDLE_INFORMATION);
SYSTEM_HANDLE_INFORMATION* shi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength);
+ HANDLE event_handle;
+
+ event_handle = CreateEventA(NULL, FALSE, FALSE, NULL);
+ ok( event_handle != NULL, "CreateEventA failed %u\n", GetLastError() );
/* 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( ReturnLength != 0xdeadbeef, "Expected valid ReturnLength\n" );
SystemInformationLength = ReturnLength;
shi = HeapReAlloc(GetProcessHeap(), 0, shi , SystemInformationLength);
+
+ ReturnLength = 0xdeadbeef;
status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength);
if (status != STATUS_INFO_LENGTH_MISMATCH) /* vista */
{
- ok( status == STATUS_SUCCESS,
- "Expected STATUS_SUCCESS, got %08x\n", status);
-
- /* Check if we have some return values */
- trace("Number of Handles : %d\n", shi->Count);
- todo_wine
+ ULONG ExpectedLength = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION, Handle[shi->Count]);
+ unsigned int i;
+ BOOL found = FALSE;
+
+ ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status );
+ todo_wine ok( ReturnLength == ExpectedLength, "Expected length %u, got %u\n", ExpectedLength, ReturnLength );
+ todo_wine ok( shi->Count > 1, "Expected more than 1 handles, got %u\n", shi->Count );
+ for (i = 0; i < shi->Count; i++)
{
- /* our implementation is a stub for now */
- ok( shi->Count > 1, "Expected more than 1 handles, got (%d)\n", shi->Count);
+ if (shi->Handle[i].OwnerPid == GetCurrentProcessId() &&
+ (HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == event_handle)
+ {
+ found = TRUE;
+ break;
+ }
}
+ todo_wine ok( found, "Expected to find event handle in handle list\n" );
}
+
+ status = pNtQuerySystemInformation(SystemHandleInformation, NULL, SystemInformationLength, &ReturnLength);
+ ok( status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status );
+
+ CloseHandle(event_handle);
HeapFree( GetProcessHeap(), 0, shi);
}
--
2.6.1

View File

@ -0,0 +1,200 @@
From 0df43162220f42efb66def6176a29ac89a2618f4 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 31 Oct 2015 22:17:43 +0100
Subject: server: Implement wineserver call for SystemHandleInformation.
---
dlls/ntdll/nt.c | 49 +++++++++++++++++++++++++++++++++++++--------
dlls/ntdll/tests/info.c | 8 ++++----
server/handle.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++
server/protocol.def | 16 +++++++++++++++
4 files changed, 114 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 8ea1ddd..6d360c3 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -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 < 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:
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 8e0a806..c0e2b1a 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -485,7 +485,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;
@@ -500,8 +500,8 @@ static void test_query_handle(void)
BOOL found = FALSE;
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status );
- todo_wine ok( ReturnLength == ExpectedLength, "Expected length %u, got %u\n", ExpectedLength, ReturnLength );
- todo_wine ok( shi->Count > 1, "Expected more than 1 handles, got %u\n", shi->Count );
+ ok( ReturnLength == ExpectedLength, "Expected length %u, got %u\n", ExpectedLength, ReturnLength );
+ ok( shi->Count > 1, "Expected more than 1 handles, got %u\n", shi->Count );
for (i = 0; i < shi->Count; i++)
{
if (shi->Handle[i].OwnerPid == GetCurrentProcessId() &&
@@ -511,7 +511,7 @@ static void test_query_handle(void)
break;
}
}
- todo_wine ok( found, "Expected to find event handle in handle list\n" );
+ ok( found, "Expected to find event handle in handle list\n" );
}
status = pNtQuerySystemInformation(SystemHandleInformation, NULL, SystemInformationLength, &ReturnLength);
diff --git a/server/handle.c b/server/handle.c
index 5043ff7..666814c 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -745,3 +745,56 @@ 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;
+
+ if (!info->handle)
+ {
+ info->count += table->count;
+ return 0;
+ }
+
+ for (i = 0, entry = table->entries; i <= table->last; i++, entry++)
+ {
+ if (!entry->ptr) 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;
+ data_size_t max_handles = get_reply_max_size() / sizeof(struct handle_entry);
+
+ 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 ((info.handle = set_reply_data_size( info.count * sizeof(struct handle_entry) )))
+ enum_processes( enum_handles, &info );
+}
diff --git a/server/protocol.def b/server/protocol.def
index 5b45078..200a2e9 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3259,6 +3259,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,bytes); /* array of handle_infos */
+@END
+
+
/* Create a mailslot */
@REQ(create_mailslot)
unsigned int access; /* wanted access rights */
--
2.6.1

View File

@ -0,0 +1 @@
Fixes: Implement SystemHandleInformation info class

View File

@ -208,6 +208,7 @@ patch_enable_all ()
enable_ntdll_Stack_Fault="$1"
enable_ntdll_Status_Mapping="$1"
enable_ntdll_Syscall_Wrappers="$1"
enable_ntdll_SystemHandleInformation="$1"
enable_ntdll_SystemRoot_Symlink="$1"
enable_ntdll_ThreadTime="$1"
enable_ntdll_Threading="$1"
@ -726,6 +727,9 @@ patch_enable ()
ntdll-Syscall_Wrappers)
enable_ntdll_Syscall_Wrappers="$2"
;;
ntdll-SystemHandleInformation)
enable_ntdll_SystemHandleInformation="$2"
;;
ntdll-SystemRoot_Symlink)
enable_ntdll_SystemRoot_Symlink="$2"
;;
@ -4336,6 +4340,20 @@ if test "$enable_ntdll_Status_Mapping" -eq 1; then
) >> "$patchlist"
fi
# Patchset ntdll-SystemHandleInformation
# |
# | Modified files:
# | * dlls/ntdll/nt.c, dlls/ntdll/tests/info.c, server/handle.c, server/protocol.def
# |
if test "$enable_ntdll_SystemHandleInformation" -eq 1; then
patch_apply ntdll-SystemHandleInformation/0001-ntdll-tests-Add-more-tests-for-SystemHandleInformati.patch
patch_apply ntdll-SystemHandleInformation/0002-server-Implement-wineserver-call-for-SystemHandleInf.patch
(
echo '+ { "Sebastian Lackner", "ntdll/tests: Add more tests for SystemHandleInformation.", 1 },';
echo '+ { "Sebastian Lackner", "server: Implement wineserver call for SystemHandleInformation.", 1 },';
) >> "$patchlist"
fi
# Patchset ntdll-SystemRoot_Symlink
# |
# | This patchset has the following (direct or indirect) dependencies: