Added patch to implement querying for object types and their indices.

This commit is contained in:
Sebastian Lackner 2017-03-19 22:27:07 +01:00
parent d79b66338e
commit 8ef379ecc8
12 changed files with 1570 additions and 58 deletions

View File

@ -310,6 +310,7 @@ patch_enable_all ()
enable_server_LABEL_SECURITY_INFORMATION="$1"
enable_server_Map_EXDEV_Error="$1"
enable_server_Misc_ACL="$1"
enable_server_Object_Types="$1"
enable_server_PeekMessage="$1"
enable_server_Pipe_ObjectName="$1"
enable_server_Realtime_Priority="$1"
@ -1151,6 +1152,9 @@ patch_enable ()
server-Misc_ACL)
enable_server_Misc_ACL="$2"
;;
server-Object_Types)
enable_server_Object_Types="$2"
;;
server-PeekMessage)
enable_server_PeekMessage="$2"
;;
@ -2134,6 +2138,31 @@ if test "$enable_shell32_Progress_Dialog" -eq 1; then
enable_shell32_SHFileOperation_Move=1
fi
if test "$enable_server_Realtime_Priority" -eq 1; then
if test "$enable_ntdll_ThreadTime" -gt 1; then
abort "Patchset ntdll-ThreadTime disabled, but server-Realtime_Priority depends on that."
fi
enable_ntdll_ThreadTime=1
fi
if test "$enable_server_Pipe_ObjectName" -eq 1; then
if test "$enable_kernel32_Named_Pipe" -gt 1; then
abort "Patchset kernel32-Named_Pipe disabled, but server-Pipe_ObjectName depends on that."
fi
enable_kernel32_Named_Pipe=1
fi
if test "$enable_server_Object_Types" -eq 1; then
if test "$enable_server_Misc_ACL" -gt 1; then
abort "Patchset server-Misc_ACL disabled, but server-Object_Types depends on that."
fi
if test "$enable_server_Shared_Memory" -gt 1; then
abort "Patchset server-Shared_Memory disabled, but server-Object_Types depends on that."
fi
enable_server_Misc_ACL=1
enable_server_Shared_Memory=1
fi
if test "$enable_server_Shared_Memory" -eq 1; then
if test "$enable_ntdll_Threading" -gt 1; then
abort "Patchset ntdll-Threading disabled, but server-Shared_Memory depends on that."
@ -2157,20 +2186,6 @@ if test "$enable_server_Shared_Memory" -eq 1; then
enable_server_Signal_Thread=1
fi
if test "$enable_server_Realtime_Priority" -eq 1; then
if test "$enable_ntdll_ThreadTime" -gt 1; then
abort "Patchset ntdll-ThreadTime disabled, but server-Realtime_Priority depends on that."
fi
enable_ntdll_ThreadTime=1
fi
if test "$enable_server_Pipe_ObjectName" -eq 1; then
if test "$enable_kernel32_Named_Pipe" -gt 1; then
abort "Patchset kernel32-Named_Pipe disabled, but server-Pipe_ObjectName depends on that."
fi
enable_kernel32_Named_Pipe=1
fi
if test "$enable_server_LABEL_SECURITY_INFORMATION" -eq 1; then
if test "$enable_advapi32_GetExplicitEntriesFromAclW" -gt 1; then
abort "Patchset advapi32-GetExplicitEntriesFromAclW disabled, but server-LABEL_SECURITY_INFORMATION depends on that."
@ -6699,50 +6714,6 @@ if test "$enable_server_PeekMessage" -eq 1; then
) >> "$patchlist"
fi
# Patchset server-Pipe_ObjectName
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * server-Desktop_Refcount, kernel32-Named_Pipe
# |
# | Modified files:
# | * dlls/ntdll/tests/om.c, server/named_pipe.c, server/object.c, server/object.h
# |
if test "$enable_server_Pipe_ObjectName" -eq 1; then
patch_apply server-Pipe_ObjectName/0001-server-Store-a-reference-to-the-parent-object-for-pi.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "server: Store a reference to the parent object for pipe servers.", 2 },';
) >> "$patchlist"
fi
# Patchset server-Realtime_Priority
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * ntdll-ThreadTime
# |
# | Modified files:
# | * server/Makefile.in, server/main.c, server/scheduler.c, server/thread.c, server/thread.h
# |
if test "$enable_server_Realtime_Priority" -eq 1; then
patch_apply server-Realtime_Priority/0001-wineserver-Draft-to-implement-priority-levels-throug.patch
(
printf '%s\n' '+ { "Joakim Hernberg", "wineserver: Draft to implement priority levels through POSIX scheduling policies on linux.", 1 },';
) >> "$patchlist"
fi
# Patchset server-Registry_Notifications
# |
# | Modified files:
# | * dlls/ntdll/tests/reg.c, server/registry.c
# |
if test "$enable_server_Registry_Notifications" -eq 1; then
patch_apply server-Registry_Notifications/0001-server-Allow-multiple-registry-notifications-for-the.patch
patch_apply server-Registry_Notifications/0002-server-Introduce-refcounting-for-registry-notificati.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "server: Allow multiple registry notifications for the same key.", 1 },';
printf '%s\n' '+ { "Sebastian Lackner", "server: Introduce refcounting for registry notifications.", 1 },';
) >> "$patchlist"
fi
# Patchset server-Signal_Thread
# |
# | Modified files:
@ -6789,6 +6760,88 @@ if test "$enable_server_Shared_Memory" -eq 1; then
) >> "$patchlist"
fi
# Patchset server-Object_Types
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * server-Misc_ACL, ntdll-Threading, server-ClipCursor, server-Key_State, server-PeekMessage, server-Signal_Thread, server-
# | Shared_Memory
# |
# | Modified files:
# | * dlls/ntdll/nt.c, dlls/ntdll/om.c, dlls/ntdll/tests/info.c, dlls/ntdll/tests/om.c, include/winternl.h,
# | server/completion.c, server/directory.c, server/event.c, server/file.c, server/handle.c, server/mailslot.c,
# | server/main.c, server/mapping.c, server/mutex.c, server/named_pipe.c, server/object.c, server/object.h,
# | server/process.c, server/protocol.def, server/registry.c, server/semaphore.c, server/symlink.c, server/thread.c,
# | server/timer.c, server/token.c, server/winstation.c
# |
if test "$enable_server_Object_Types" -eq 1; then
patch_apply server-Object_Types/0001-ntdll-Implement-SystemExtendedHandleInformation-in-N.patch
patch_apply server-Object_Types/0002-ntdll-Implement-ObjectTypesInformation-in-NtQueryObj.patch
patch_apply server-Object_Types/0003-server-Register-types-during-startup.patch
patch_apply server-Object_Types/0004-server-Rename-ObjectType-to-Type.patch
patch_apply server-Object_Types/0005-server-Add-type-Token.patch
patch_apply server-Object_Types/0006-server-Add-type-Process.patch
patch_apply server-Object_Types/0007-server-Add-type-Thread.patch
patch_apply server-Object_Types/0008-ntdll-Set-TypeIndex-for-ObjectTypeInformation-in-NtQ.patch
patch_apply server-Object_Types/0009-ntdll-Set-object-type-for-System-Extended-HandleInfo.patch
patch_apply server-Object_Types/0010-ntdll-Mimic-object-type-behavior-for-different-windo.patch
(
printf '%s\n' '+ { "Michael Müller", "ntdll: Implement SystemExtendedHandleInformation in NtQuerySystemInformation.", 1 },';
printf '%s\n' '+ { "Michael Müller", "ntdll: Implement ObjectTypesInformation in NtQueryObject.", 1 },';
printf '%s\n' '+ { "Michael Müller", "server: Register types during startup.", 1 },';
printf '%s\n' '+ { "Michael Müller", "server: Rename ObjectType to Type.", 1 },';
printf '%s\n' '+ { "Michael Müller", "server: Add type Token.", 1 },';
printf '%s\n' '+ { "Michael Müller", "server: Add type Process.", 1 },';
printf '%s\n' '+ { "Michael Müller", "server: Add type Thread.", 1 },';
printf '%s\n' '+ { "Michael Müller", "ntdll: Set TypeIndex for ObjectTypeInformation in NtQueryObject.", 1 },';
printf '%s\n' '+ { "Michael Müller", "ntdll: Set object type for System(Extended)HandleInformation in NtQuerySystemInformation.", 1 },';
printf '%s\n' '+ { "Michael Müller", "ntdll: Mimic object type behavior for different windows versions.", 1 },';
) >> "$patchlist"
fi
# Patchset server-Pipe_ObjectName
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * server-Desktop_Refcount, kernel32-Named_Pipe
# |
# | Modified files:
# | * dlls/ntdll/tests/om.c, server/named_pipe.c, server/object.c, server/object.h
# |
if test "$enable_server_Pipe_ObjectName" -eq 1; then
patch_apply server-Pipe_ObjectName/0001-server-Store-a-reference-to-the-parent-object-for-pi.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "server: Store a reference to the parent object for pipe servers.", 2 },';
) >> "$patchlist"
fi
# Patchset server-Realtime_Priority
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * ntdll-ThreadTime
# |
# | Modified files:
# | * server/Makefile.in, server/main.c, server/scheduler.c, server/thread.c, server/thread.h
# |
if test "$enable_server_Realtime_Priority" -eq 1; then
patch_apply server-Realtime_Priority/0001-wineserver-Draft-to-implement-priority-levels-throug.patch
(
printf '%s\n' '+ { "Joakim Hernberg", "wineserver: Draft to implement priority levels through POSIX scheduling policies on linux.", 1 },';
) >> "$patchlist"
fi
# Patchset server-Registry_Notifications
# |
# | Modified files:
# | * dlls/ntdll/tests/reg.c, server/registry.c
# |
if test "$enable_server_Registry_Notifications" -eq 1; then
patch_apply server-Registry_Notifications/0001-server-Allow-multiple-registry-notifications-for-the.patch
patch_apply server-Registry_Notifications/0002-server-Introduce-refcounting-for-registry-notificati.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "server: Allow multiple registry notifications for the same key.", 1 },';
printf '%s\n' '+ { "Sebastian Lackner", "server: Introduce refcounting for registry notifications.", 1 },';
) >> "$patchlist"
fi
# Patchset server-Timestamp_Compat
# |
# | Modified files:

View File

@ -0,0 +1,187 @@
From 0384d32afa328e76bff7f8e508201ce2535ee763 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Tue, 7 Mar 2017 18:30:33 +0100
Subject: ntdll: Implement SystemExtendedHandleInformation in
NtQuerySystemInformation.
---
dlls/ntdll/nt.c | 51 +++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/tests/info.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
include/winternl.h | 21 +++++++++++++++++
3 files changed, 132 insertions(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index de8f16f9a0..a939298d19 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -2294,6 +2294,57 @@ NTSTATUS WINAPI NtQuerySystemInformation(
RtlFreeHeap( GetProcessHeap(), 0, info );
}
break;
+ case SystemExtendedHandleInformation:
+ {
+ struct handle_info *info;
+ DWORD i, num_handles;
+
+ if (Length < sizeof(SYSTEM_HANDLE_INFORMATION_EX))
+ {
+ ret = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ if (!SystemInformation)
+ {
+ ret = STATUS_ACCESS_VIOLATION;
+ break;
+ }
+
+ num_handles = (Length - FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION_EX, Handle ));
+ num_handles /= sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX);
+ 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_EX *shi = SystemInformation;
+ shi->Count = wine_server_reply_size( req ) / sizeof(*info);
+ shi->Reserved = 0;
+ len = FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION_EX, Handle[shi->Count] );
+ for (i = 0; i < shi->Count; i++)
+ {
+ memset( &shi->Handle[i], 0, sizeof(shi->Handle[i]) );
+ shi->Handle[i].UniqueProcessId = info[i].owner;
+ shi->Handle[i].HandleValue = info[i].handle;
+ shi->Handle[i].GrantedAccess = info[i].access;
+ /* FIXME: Fill out remaining fields */
+ }
+ }
+ else if (ret == STATUS_BUFFER_TOO_SMALL)
+ {
+ len = FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION_EX, Handle[reply->count] );
+ ret = STATUS_INFO_LENGTH_MISMATCH;
+ }
+ }
+ SERVER_END_REQ;
+
+ RtlFreeHeap( GetProcessHeap(), 0, info );
+ }
+ break;
case SystemCacheInformation:
{
SYSTEM_CACHE_INFORMATION sci;
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 32cb4f5a5d..c65a74bf5e 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -561,6 +561,62 @@ done:
HeapFree( GetProcessHeap(), 0, shi);
}
+static void test_query_handle_ex(void)
+{
+ NTSTATUS status;
+ ULONG ExpectedLength, ReturnLength;
+ ULONG SystemInformationLength = sizeof(SYSTEM_HANDLE_INFORMATION_EX);
+ SYSTEM_HANDLE_INFORMATION_EX* shi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength);
+ HANDLE EventHandle;
+ BOOL found;
+ INT i;
+
+ EventHandle = CreateEventA(NULL, FALSE, FALSE, NULL);
+ ok( EventHandle != NULL, "CreateEventA failed %u\n", GetLastError() );
+
+ ReturnLength = 0xdeadbeef;
+ status = pNtQuerySystemInformation(SystemExtendedHandleInformation, shi, SystemInformationLength, &ReturnLength);
+ 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);
+ memset(shi, 0x55, SystemInformationLength);
+
+ ReturnLength = 0xdeadbeef;
+ status = pNtQuerySystemInformation(SystemExtendedHandleInformation, shi, SystemInformationLength, &ReturnLength);
+ ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status );
+ ExpectedLength = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX, Handle[shi->Count]);
+ ok( ReturnLength == ExpectedLength, "Expected length %u, got %u\n", ExpectedLength, ReturnLength );
+ ok( shi->Count > 1, "Expected more than 1 handle, got %u\n", (DWORD)shi->Count );
+
+ for (i = 0, found = FALSE; i < shi->Count && !found; i++)
+ found = (shi->Handle[i].UniqueProcessId == GetCurrentProcessId()) &&
+ ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle);
+ ok( found, "Expected to find event handle %p (pid %x) in handle list\n", EventHandle, GetCurrentProcessId() );
+
+ if (!found)
+ {
+ for (i = 0; i < shi->Count; i++)
+ trace( "%d: handle %x pid %x\n", i, (DWORD)shi->Handle[i].HandleValue, (DWORD)shi->Handle[i].UniqueProcessId );
+ }
+
+ CloseHandle(EventHandle);
+
+ ReturnLength = 0xdeadbeef;
+ status = pNtQuerySystemInformation(SystemExtendedHandleInformation, shi, SystemInformationLength, &ReturnLength);
+ ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status );
+ for (i = 0, found = FALSE; i < shi->Count && !found; i++)
+ found = (shi->Handle[i].UniqueProcessId == GetCurrentProcessId()) &&
+ ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle);
+ ok( !found, "Unexpectedly found event handle in handle list\n" );
+
+ status = pNtQuerySystemInformation(SystemExtendedHandleInformation, NULL, SystemInformationLength, &ReturnLength);
+ ok( status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status );
+
+ HeapFree( GetProcessHeap(), 0, shi);
+}
+
static void test_query_cache(void)
{
NTSTATUS status;
@@ -2147,6 +2203,10 @@ START_TEST(info)
trace("Starting test_query_handle()\n");
test_query_handle();
+ /* 0x40 SystemHandleInformation */
+ trace("Starting test_query_handle_ex()\n");
+ test_query_handle_ex();
+
/* 0x15 SystemCacheInformation */
trace("Starting test_query_cache()\n");
test_query_cache();
diff --git a/include/winternl.h b/include/winternl.h
index 87b2c4d253..7ffe4f6c81 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1442,6 +1442,27 @@ typedef struct _SYSTEM_HANDLE_INFORMATION {
SYSTEM_HANDLE_ENTRY Handle[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
+/* System Information Class 0x40 */
+
+typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
+{
+ PVOID Object;
+ ULONG_PTR UniqueProcessId;
+ ULONG_PTR HandleValue;
+ ULONG GrantedAccess;
+ USHORT CreatorBackTraceIndex;
+ USHORT ObjectTypeIndex;
+ ULONG HandleAttributes;
+ ULONG Reserved;
+} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;
+
+typedef struct _SYSTEM_HANDLE_INFORMATION_EX
+{
+ ULONG_PTR Count;
+ ULONG_PTR Reserved;
+ SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handle[1];
+} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
+
/* System Information Class 0x15 */
typedef struct _SYSTEM_CACHE_INFORMATION {
--
2.11.0

View File

@ -0,0 +1,278 @@
From b3286b1c7ea9b507918c96f901d8e2c1311a4a1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 02:12:37 +0100
Subject: ntdll: Implement ObjectTypesInformation in NtQueryObject.
---
dlls/ntdll/om.c | 51 +++++++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/tests/om.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
include/winternl.h | 30 +++++++++++++++++++++++++--
server/directory.c | 19 ++++++++++++++++-
server/protocol.def | 9 ++++++++
5 files changed, 163 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
index 0f21800df6..8911a28b20 100644
--- a/dlls/ntdll/om.c
+++ b/dlls/ntdll/om.c
@@ -43,6 +43,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
+#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))
/*
* Generic object functions
@@ -188,6 +189,56 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
SERVER_END_REQ;
}
break;
+ case ObjectTypesInformation:
+ {
+ OBJECT_TYPES_INFORMATION *p = ptr;
+ OBJECT_TYPE_INFORMATION *type = (OBJECT_TYPE_INFORMATION *)(p + 1);
+ ULONG count, type_len, req_len = sizeof(OBJECT_TYPES_INFORMATION);
+
+ for (count = 0, status = STATUS_SUCCESS; !status; count++)
+ {
+ SERVER_START_REQ( get_object_type_by_index )
+ {
+ req->index = count;
+ if (len > sizeof(*type))
+ wine_server_set_reply( req, type + 1, len - sizeof(*type) );
+ status = wine_server_call( req );
+ if (status == STATUS_SUCCESS)
+ {
+ type_len = sizeof(*type);
+ if (reply->total)
+ type_len += ROUND_UP( reply->total + sizeof(WCHAR), sizeof(DWORD_PTR) );
+ req_len += type_len;
+ }
+ if (status == STATUS_SUCCESS && len >= req_len)
+ {
+ ULONG res = wine_server_reply_size( reply );
+ memset( type, 0, sizeof(*type) );
+ if (reply->total)
+ {
+ type->TypeName.Buffer = (WCHAR *)(type + 1);
+ type->TypeName.Length = res;
+ type->TypeName.MaximumLength = res + sizeof(WCHAR);
+ type->TypeName.Buffer[res / sizeof(WCHAR)] = 0;
+ }
+ type->TypeIndex = count;
+ type = (OBJECT_TYPE_INFORMATION *)((char *)type + type_len);
+ }
+ }
+ SERVER_END_REQ;
+ }
+
+ if (status != STATUS_NO_MORE_ENTRIES)
+ return status;
+
+ if (used_len) *used_len = req_len;
+ if (len < req_len)
+ return STATUS_INFO_LENGTH_MISMATCH;
+
+ p->NumberOfTypes = count - 1;
+ status = STATUS_SUCCESS;
+ }
+ break;
case ObjectDataInformation:
{
OBJECT_DATA_INFORMATION* p = ptr;
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index 9a1ba670ab..534cb514f9 100644
--- a/dlls/ntdll/tests/om.c
+++ b/dlls/ntdll/tests/om.c
@@ -74,6 +74,21 @@ static NTSTATUS (WINAPI *pNtOpenIoCompletion)( PHANDLE, ACCESS_MASK, POBJECT_ATT
#define KEYEDEVENT_WAKE 0x0002
#define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x0003)
+#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))
+
+static LPCSTR wine_dbgstr_us( const UNICODE_STRING *us )
+{
+ if (!us) return "(null)";
+ return wine_dbgstr_wn(us->Buffer, us->Length / sizeof(WCHAR));
+}
+
+static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
+{
+ if (n <= 0) return 0;
+ while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
+ return *str1 - *str2;
+}
+
static void test_case_sensitive (void)
{
static const WCHAR buffer1[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','t','e','s','t',0};
@@ -1524,6 +1539,47 @@ static void test_query_object(void)
pRtlFreeUnicodeString( &session );
}
+static void test_query_object_types(void)
+{
+ static const WCHAR typeW[] = {'T','y','p','e'};
+ OBJECT_TYPES_INFORMATION *buffer;
+ OBJECT_TYPE_INFORMATION *type;
+ NTSTATUS status;
+ ULONG len, i;
+
+ buffer = HeapAlloc( GetProcessHeap(), 0, sizeof(OBJECT_TYPES_INFORMATION) );
+ ok( buffer != NULL, "Failed to allocate memory\n" );
+
+ status = pNtQueryObject( NULL, ObjectTypesInformation, buffer, sizeof(OBJECT_TYPES_INFORMATION), &len );
+ ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
+ ok( len, "len is zero\n");
+
+ buffer = HeapReAlloc( GetProcessHeap(), 0, buffer, len );
+ ok( buffer != NULL, "Failed to allocate memory\n" );
+
+ memset( buffer, 0, len );
+ status = pNtQueryObject( NULL, ObjectTypesInformation, buffer, len, &len );
+ ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
+ ok( buffer->NumberOfTypes, "NumberOfTypes is zero\n" );
+
+ type = (OBJECT_TYPE_INFORMATION *)(buffer + 1);
+ for (i = 0; i < buffer->NumberOfTypes; i++)
+ {
+ USHORT length = type->TypeName.MaximumLength;
+ trace( "Type %u: %s\n", i, wine_dbgstr_us(&type->TypeName) );
+
+ if (i == 0)
+ {
+ todo_wine ok( type->TypeName.Length == sizeof(typeW) && !strncmpW(typeW, type->TypeName.Buffer, 4),
+ "Expected 'Type' as first type, got %s\n", wine_dbgstr_us(&type->TypeName) );
+ }
+
+ type = (OBJECT_TYPE_INFORMATION *)ROUND_UP( (DWORD_PTR)(type + 1) + length, sizeof(DWORD_PTR) );
+ }
+
+ HeapFree( GetProcessHeap(), 0, buffer );
+}
+
static void test_type_mismatch(void)
{
HANDLE h;
@@ -2036,6 +2092,7 @@ START_TEST(om)
test_directory();
test_symboliclink();
test_query_object();
+ test_query_object_types();
test_type_mismatch();
test_event();
test_mutant();
diff --git a/include/winternl.h b/include/winternl.h
index 7ffe4f6c81..0a2e323c5b 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -790,7 +790,7 @@ typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
- ObjectAllInformation,
+ ObjectTypesInformation,
ObjectDataInformation
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
@@ -1208,9 +1208,35 @@ typedef struct _OBJECT_NAME_INFORMATION {
typedef struct __OBJECT_TYPE_INFORMATION {
UNICODE_STRING TypeName;
- ULONG Reserved [22];
+ ULONG TotalNumberOfObjects;
+ ULONG TotalNumberOfHandles;
+ ULONG TotalPagedPoolUsage;
+ ULONG TotalNonPagedPoolUsage;
+ ULONG TotalNamePoolUsage;
+ ULONG TotalHandleTableUsage;
+ ULONG HighWaterNumberOfObjects;
+ ULONG HighWaterNumberOfHandles;
+ ULONG HighWaterPagedPoolUsage;
+ ULONG HighWaterNonPagedPoolUsage;
+ ULONG HighWaterNamePoolUsage;
+ ULONG HighWaterHandleTableUsage;
+ ULONG InvalidAttributes;
+ GENERIC_MAPPING GenericMapping;
+ ULONG ValidAccessMask;
+ BOOLEAN SecurityRequired;
+ BOOLEAN MaintainHandleCount;
+ UCHAR TypeIndex;
+ CHAR Reserved;
+ ULONG PoolType;
+ ULONG DefaultPagedPoolCharge;
+ ULONG DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
+typedef struct _OBJECT_TYPES_INFORMATION
+{
+ ULONG NumberOfTypes;
+} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION;
+
typedef struct _PROCESS_BASIC_INFORMATION {
#ifdef __WINESRC__
DWORD_PTR ExitStatus;
diff --git a/server/directory.c b/server/directory.c
index d903ff283c..ebec63e6c6 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -72,6 +72,8 @@ static const struct object_ops object_type_ops =
no_destroy /* destroy */
};
+static struct object_type *object_type_list[64];
+static unsigned int object_type_count;
struct directory
{
@@ -238,7 +240,8 @@ struct object_type *get_object_type( const struct unicode_str *name )
{
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
- grab_object( type );
+ assert( object_type_count < sizeof(object_type_list)/sizeof(object_type_list[0]) );
+ object_type_list[ object_type_count++ ] = (struct object_type *)grab_object( type );
make_object_static( &type->obj );
}
clear_error();
@@ -531,3 +534,17 @@ DECL_HANDLER(get_object_type)
}
release_object( obj );
}
+
+/* query object type name information by index */
+DECL_HANDLER(get_object_type_by_index)
+{
+ struct object_type *type;
+ const WCHAR *name;
+
+ if (req->index < object_type_count && (type = object_type_list[ req->index ]))
+ {
+ if ((name = get_object_name( &type->obj, &reply->total )))
+ set_reply_data( name, min( reply->total, get_reply_max_size() ) );
+ }
+ else set_error( STATUS_NO_MORE_ENTRIES );
+}
diff --git a/server/protocol.def b/server/protocol.def
index 071129723f..98c4c58a4e 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3548,6 +3548,15 @@ struct handle_info
@END
+/* Query object type name information */
+@REQ(get_object_type_by_index)
+ unsigned int index; /* index of the type */
+@REPLY
+ data_size_t total; /* needed size for type name */
+ VARARG(type,unicode_str); /* type name */
+@END
+
+
/* Unlink a named object */
@REQ(unlink_object)
obj_handle_t handle; /* handle to the object */
--
2.11.0

View File

@ -0,0 +1,342 @@
From 35a8bfa127fa1195bbb6454a79d8ff1a794ee9d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 03:32:43 +0100
Subject: server: Register types during startup.
---
server/completion.c | 3 +--
server/directory.c | 6 ++----
server/event.c | 6 ++----
server/file.c | 3 +--
server/mailslot.c | 3 +--
server/main.c | 1 +
server/mapping.c | 3 +--
server/mutex.c | 3 +--
server/named_pipe.c | 3 +--
server/object.c | 36 ++++++++++++++++++++++++++++++++++++
server/object.h | 21 +++++++++++++++++++++
server/process.c | 3 +--
server/registry.c | 3 +--
server/semaphore.c | 3 +--
server/symlink.c | 3 +--
server/timer.c | 3 +--
server/winstation.c | 6 ++----
17 files changed, 75 insertions(+), 34 deletions(-)
diff --git a/server/completion.c b/server/completion.c
index 72dbc5b821..af4a3f74e1 100644
--- a/server/completion.c
+++ b/server/completion.c
@@ -110,8 +110,7 @@ static void completion_dump( struct object *obj, int verbose )
static struct object_type *completion_get_type( struct object *obj )
{
- static const WCHAR name[] = {'I','o','C','o','m','p','l','e','t','i','o','n'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_IoCompletion, sizeof(type_IoCompletion) };
return get_object_type( &str );
}
diff --git a/server/directory.c b/server/directory.c
index ebec63e6c6..98dd2defa3 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -121,8 +121,7 @@ static void object_type_dump( struct object *obj, int verbose )
static struct object_type *object_type_get_type( struct object *obj )
{
- static const WCHAR name[] = {'O','b','j','e','c','t','T','y','p','e'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_ObjectType, sizeof(type_ObjectType) };
return get_object_type( &str );
}
@@ -133,8 +132,7 @@ static void directory_dump( struct object *obj, int verbose )
static struct object_type *directory_get_type( struct object *obj )
{
- static const WCHAR name[] = {'D','i','r','e','c','t','o','r','y'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_Directory, sizeof(type_Directory) };
return get_object_type( &str );
}
diff --git a/server/event.c b/server/event.c
index 608fafb94d..04ebda60a5 100644
--- a/server/event.c
+++ b/server/event.c
@@ -161,8 +161,7 @@ static void event_dump( struct object *obj, int verbose )
static struct object_type *event_get_type( struct object *obj )
{
- static const WCHAR name[] = {'E','v','e','n','t'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_Event, sizeof(type_Event) };
return get_object_type( &str );
}
@@ -231,8 +230,7 @@ static void keyed_event_dump( struct object *obj, int verbose )
static struct object_type *keyed_event_get_type( struct object *obj )
{
- static const WCHAR name[] = {'K','e','y','e','d','E','v','e','n','t'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_KeyedEvent, sizeof(type_KeyedEvent) };
return get_object_type( &str );
}
diff --git a/server/file.c b/server/file.c
index babbcc6a63..5c3ae775b3 100644
--- a/server/file.c
+++ b/server/file.c
@@ -456,8 +456,7 @@ static void file_dump( struct object *obj, int verbose )
static struct object_type *file_get_type( struct object *obj )
{
- static const WCHAR name[] = {'F','i','l','e'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_File, sizeof(type_File) };
return get_object_type( &str );
}
diff --git a/server/mailslot.c b/server/mailslot.c
index 04c4b9f50c..b69c957595 100644
--- a/server/mailslot.c
+++ b/server/mailslot.c
@@ -349,8 +349,7 @@ static void mailslot_device_dump( struct object *obj, int verbose )
static struct object_type *mailslot_device_get_type( struct object *obj )
{
- static const WCHAR name[] = {'D','e','v','i','c','e'};
- static const struct unicode_str str = { name, sizeof(name) };
+ const struct unicode_str str = { type_Device, sizeof(type_Device) };
return get_object_type( &str );
}
diff --git a/server/main.c b/server/main.c
index 313039a308..13af3b9feb 100644
--- a/server/main.c
+++ b/server/main.c
@@ -148,6 +148,7 @@ int main( int argc, char *argv[] )
init_directories();
init_registry();
init_shared_memory();
+ init_types();
main_loop();
return 0;
}
diff --git a/server/mapping.c b/server/mapping.c
index 44fbe63793..9691dd832c 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -728,8 +728,7 @@ static void mapping_dump( struct object *obj, int verbose )
static struct object_type *mapping_get_type( struct object *obj )
{
- static const WCHAR name[] = {'S','e','c','t','i','o','n'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_Section, sizeof(type_Section) };
return get_object_type( &str );
}
diff --git a/server/mutex.c b/server/mutex.c
index a2a0a24bdc..7ca41316ab 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -142,8 +142,7 @@ static void mutex_dump( struct object *obj, int verbose )
static struct object_type *mutex_get_type( struct object *obj )
{
- static const WCHAR name[] = {'M','u','t','a','n','t'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_Mutant, sizeof(type_Mutant) };
return get_object_type( &str );
}
diff --git a/server/named_pipe.c b/server/named_pipe.c
index bc4b6f08fd..e3ebb4571e 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -524,8 +524,7 @@ static void named_pipe_device_dump( struct object *obj, int verbose )
static struct object_type *named_pipe_device_get_type( struct object *obj )
{
- static const WCHAR name[] = {'D','e','v','i','c','e'};
- static const struct unicode_str str = { name, sizeof(name) };
+ const struct unicode_str str = { type_Device, sizeof(type_Device) };
return get_object_type( &str );
}
diff --git a/server/object.c b/server/object.c
index 7281ef82ec..e6d20196a9 100644
--- a/server/object.c
+++ b/server/object.c
@@ -710,3 +710,39 @@ int no_close_handle( struct object *obj, struct process *process, obj_handle_t h
void no_destroy( struct object *obj )
{
}
+
+static const struct unicode_str type_array[] =
+{
+ {type_ObjectType, sizeof(type_ObjectType)},
+ {type_Directory, sizeof(type_Directory)},
+ {type_SymbolicLink, sizeof(type_SymbolicLink)},
+ /* Token */
+ {type_Job, sizeof(type_Job)},
+ /* Process */
+ /* Thread */
+ {type_Event, sizeof(type_Event)},
+ {type_Mutant, sizeof(type_Mutant)},
+ {type_Semaphore, sizeof(type_Semaphore)},
+ {type_Timer, sizeof(type_Timer)},
+ {type_KeyedEvent, sizeof(type_KeyedEvent)},
+ {type_WindowStation, sizeof(type_WindowStation)},
+ {type_Desktop, sizeof(type_Desktop)},
+ {type_Device, sizeof(type_Device)},
+ /* Driver */
+ {type_IoCompletion, sizeof(type_IoCompletion)},
+ {type_File, sizeof(type_File)},
+ {type_Section, sizeof(type_Section)},
+ {type_Key, sizeof(type_Key)},
+};
+
+void init_types(void)
+{
+ struct object_type *type;
+ unsigned int i;
+
+ for (i = 0; i < sizeof(type_array) / sizeof(type_array[0]); i++)
+ {
+ type = get_object_type(&type_array[i]);
+ if (type) release_object(type);
+ }
+}
diff --git a/server/object.h b/server/object.h
index 498186bc92..be71c705c5 100644
--- a/server/object.h
+++ b/server/object.h
@@ -241,6 +241,27 @@ extern struct object_type *get_object_type( const struct unicode_str *name );
extern int directory_link_name( struct object *obj, struct object_name *name, struct object *parent );
extern void init_directories(void);
+/* type functions */
+
+static const WCHAR type_Desktop[] = {'D','e','s','k','t','o','p'};
+static const WCHAR type_Device[] = {'D','e','v','i','c','e'};
+static const WCHAR type_Directory[] = {'D','i','r','e','c','t','o','r','y'};
+static const WCHAR type_Event[] = {'E','v','e','n','t'};
+static const WCHAR type_File[] = {'F','i','l','e'};
+static const WCHAR type_IoCompletion[] = {'I','o','C','o','m','p','l','e','t','i','o','n'};
+static const WCHAR type_Job[] = {'J','o','b'};
+static const WCHAR type_Key[] = {'K','e','y'};
+static const WCHAR type_KeyedEvent[] = {'K','e','y','e','d','E','v','e','n','t'};
+static const WCHAR type_Mutant[] = {'M','u','t','a','n','t'};
+static const WCHAR type_ObjectType[] = {'O','b','j','e','c','t','T','y','p','e'};
+static const WCHAR type_Section[] = {'S','e','c','t','i','o','n'};
+static const WCHAR type_Semaphore[] = {'S','e','m','a','p','h','o','r','e'};
+static const WCHAR type_SymbolicLink[] = {'S','y','m','b','o','l','i','c','L','i','n','k'};
+static const WCHAR type_Timer[] = {'T','i','m','e','r'};
+static const WCHAR type_WindowStation[] = {'W','i','n','d','o','w','S','t','a','t','i','o','n'};
+
+extern void init_types(void);
+
/* symbolic link functions */
extern struct object *create_obj_symlink( struct object *root, const struct unicode_str *name,
diff --git a/server/process.c b/server/process.c
index a59be6cfad..df1e9f1b0d 100644
--- a/server/process.c
+++ b/server/process.c
@@ -214,8 +214,7 @@ static struct job *get_job_obj( struct process *process, obj_handle_t handle, un
static struct object_type *job_get_type( struct object *obj )
{
- static const WCHAR name[] = {'J','o','b'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_Job, sizeof(type_Job) };
return get_object_type( &str );
};
diff --git a/server/registry.c b/server/registry.c
index 368a56abcf..3a45f4f081 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -314,8 +314,7 @@ static void key_dump( struct object *obj, int verbose )
static struct object_type *key_get_type( struct object *obj )
{
- static const WCHAR name[] = {'K','e','y'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_Key, sizeof(type_Key) };
return get_object_type( &str );
}
diff --git a/server/semaphore.c b/server/semaphore.c
index 15e7392513..60940aaa76 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -128,8 +128,7 @@ static void semaphore_dump( struct object *obj, int verbose )
static struct object_type *semaphore_get_type( struct object *obj )
{
- static const WCHAR name[] = {'S','e','m','a','p','h','o','r','e'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_Semaphore, sizeof(type_Semaphore) };
return get_object_type( &str );
}
diff --git a/server/symlink.c b/server/symlink.c
index ecc0e4300c..33efdaa699 100644
--- a/server/symlink.c
+++ b/server/symlink.c
@@ -87,8 +87,7 @@ static void symlink_dump( struct object *obj, int verbose )
static struct object_type *symlink_get_type( struct object *obj )
{
- static const WCHAR name[] = {'S','y','m','b','o','l','i','c','L','i','n','k'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_SymbolicLink, sizeof(type_SymbolicLink) };
return get_object_type( &str );
}
diff --git a/server/timer.c b/server/timer.c
index 23c613b3cb..cb686b90f9 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -190,8 +190,7 @@ static void timer_dump( struct object *obj, int verbose )
static struct object_type *timer_get_type( struct object *obj )
{
- static const WCHAR name[] = {'T','i','m','e','r'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_Timer, sizeof(type_Timer) };
return get_object_type( &str );
}
diff --git a/server/winstation.c b/server/winstation.c
index 39131d538e..d449ec667d 100644
--- a/server/winstation.c
+++ b/server/winstation.c
@@ -166,8 +166,7 @@ static void winstation_dump( struct object *obj, int verbose )
static struct object_type *winstation_get_type( struct object *obj )
{
- static const WCHAR name[] = {'W','i','n','d','o','w','S','t','a','t','i','o','n'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_WindowStation, sizeof(type_WindowStation) };
return get_object_type( &str );
}
@@ -271,8 +270,7 @@ static void desktop_dump( struct object *obj, int verbose )
static struct object_type *desktop_get_type( struct object *obj )
{
- static const WCHAR name[] = {'D','e','s','k','t','o','p'};
- static const struct unicode_str str = { name, sizeof(name) };
+ static const struct unicode_str str = { type_Desktop, sizeof(type_Desktop) };
return get_object_type( &str );
}
--
2.11.0

View File

@ -0,0 +1,71 @@
From 0498c01e0c379ccf5874b07fbbf3ec86b34f97ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 03:44:19 +0100
Subject: server: Rename ObjectType to Type.
---
dlls/ntdll/tests/om.c | 2 +-
server/directory.c | 2 +-
server/object.c | 2 +-
server/object.h | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index 534cb514f9..02d83016e2 100644
--- a/dlls/ntdll/tests/om.c
+++ b/dlls/ntdll/tests/om.c
@@ -1570,7 +1570,7 @@ static void test_query_object_types(void)
if (i == 0)
{
- todo_wine ok( type->TypeName.Length == sizeof(typeW) && !strncmpW(typeW, type->TypeName.Buffer, 4),
+ ok( type->TypeName.Length == sizeof(typeW) && !strncmpW(typeW, type->TypeName.Buffer, 4),
"Expected 'Type' as first type, got %s\n", wine_dbgstr_us(&type->TypeName) );
}
diff --git a/server/directory.c b/server/directory.c
index 98dd2defa3..b4f53e2edf 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -121,7 +121,7 @@ static void object_type_dump( struct object *obj, int verbose )
static struct object_type *object_type_get_type( struct object *obj )
{
- static const struct unicode_str str = { type_ObjectType, sizeof(type_ObjectType) };
+ static const struct unicode_str str = { type_Type, sizeof(type_Type) };
return get_object_type( &str );
}
diff --git a/server/object.c b/server/object.c
index e6d20196a9..960422df1c 100644
--- a/server/object.c
+++ b/server/object.c
@@ -713,7 +713,7 @@ void no_destroy( struct object *obj )
static const struct unicode_str type_array[] =
{
- {type_ObjectType, sizeof(type_ObjectType)},
+ {type_Type, sizeof(type_Type)},
{type_Directory, sizeof(type_Directory)},
{type_SymbolicLink, sizeof(type_SymbolicLink)},
/* Token */
diff --git a/server/object.h b/server/object.h
index be71c705c5..0ed46b159d 100644
--- a/server/object.h
+++ b/server/object.h
@@ -253,11 +253,11 @@ static const WCHAR type_Job[] = {'J','o','b'};
static const WCHAR type_Key[] = {'K','e','y'};
static const WCHAR type_KeyedEvent[] = {'K','e','y','e','d','E','v','e','n','t'};
static const WCHAR type_Mutant[] = {'M','u','t','a','n','t'};
-static const WCHAR type_ObjectType[] = {'O','b','j','e','c','t','T','y','p','e'};
static const WCHAR type_Section[] = {'S','e','c','t','i','o','n'};
static const WCHAR type_Semaphore[] = {'S','e','m','a','p','h','o','r','e'};
static const WCHAR type_SymbolicLink[] = {'S','y','m','b','o','l','i','c','L','i','n','k'};
static const WCHAR type_Timer[] = {'T','i','m','e','r'};
+static const WCHAR type_Type[] = {'T','y','p','e'};
static const WCHAR type_WindowStation[] = {'W','i','n','d','o','w','S','t','a','t','i','o','n'};
extern void init_types(void);
--
2.11.0

View File

@ -0,0 +1,73 @@
From b4ba31df8d342f736a590977ba950d6f07f2377c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 03:48:02 +0100
Subject: server: Add type Token.
---
server/object.c | 2 +-
server/object.h | 1 +
server/token.c | 9 ++++++++-
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/server/object.c b/server/object.c
index 960422df1c..c2c877f692 100644
--- a/server/object.c
+++ b/server/object.c
@@ -716,7 +716,7 @@ static const struct unicode_str type_array[] =
{type_Type, sizeof(type_Type)},
{type_Directory, sizeof(type_Directory)},
{type_SymbolicLink, sizeof(type_SymbolicLink)},
- /* Token */
+ {type_Token, sizeof(type_Token)},
{type_Job, sizeof(type_Job)},
/* Process */
/* Thread */
diff --git a/server/object.h b/server/object.h
index 0ed46b159d..46a9f770ca 100644
--- a/server/object.h
+++ b/server/object.h
@@ -257,6 +257,7 @@ static const WCHAR type_Section[] = {'S','e','c','t','i','o','n'};
static const WCHAR type_Semaphore[] = {'S','e','m','a','p','h','o','r','e'};
static const WCHAR type_SymbolicLink[] = {'S','y','m','b','o','l','i','c','L','i','n','k'};
static const WCHAR type_Timer[] = {'T','i','m','e','r'};
+static const WCHAR type_Token[] = {'T','o','k','e','n'};
static const WCHAR type_Type[] = {'T','y','p','e'};
static const WCHAR type_WindowStation[] = {'W','i','n','d','o','w','S','t','a','t','i','o','n'};
diff --git a/server/token.c b/server/token.c
index 3b5c498147..f0afb95868 100644
--- a/server/token.c
+++ b/server/token.c
@@ -150,6 +150,7 @@ struct group
};
static void token_dump( struct object *obj, int verbose );
+static struct object_type *token_get_type( struct object *obj );
static unsigned int token_map_access( struct object *obj, unsigned int access );
static void token_destroy( struct object *obj );
@@ -157,7 +158,7 @@ static const struct object_ops token_ops =
{
sizeof(struct token), /* size */
token_dump, /* dump */
- no_get_type, /* get_type */
+ token_get_type, /* get_type */
no_add_queue, /* add_queue */
NULL, /* remove_queue */
NULL, /* signaled */
@@ -183,6 +184,12 @@ static void token_dump( struct object *obj, int verbose )
/* FIXME: dump token members */
}
+static struct object_type *token_get_type( struct object *obj )
+{
+ static const struct unicode_str str = { type_Token, sizeof(type_Token) };
+ return get_object_type( &str );
+}
+
static unsigned int token_map_access( struct object *obj, unsigned int access )
{
if (access & GENERIC_READ) access |= TOKEN_READ;
--
2.11.0

View File

@ -0,0 +1,73 @@
From 97057ab129833bd9fdcf683e05a44c0d06330edd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 03:52:47 +0100
Subject: server: Add type Process.
---
server/object.c | 2 +-
server/object.h | 1 +
server/process.c | 9 ++++++++-
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/server/object.c b/server/object.c
index c2c877f692..f7c249689f 100644
--- a/server/object.c
+++ b/server/object.c
@@ -718,7 +718,7 @@ static const struct unicode_str type_array[] =
{type_SymbolicLink, sizeof(type_SymbolicLink)},
{type_Token, sizeof(type_Token)},
{type_Job, sizeof(type_Job)},
- /* Process */
+ {type_Process, sizeof(type_Process)},
/* Thread */
{type_Event, sizeof(type_Event)},
{type_Mutant, sizeof(type_Mutant)},
diff --git a/server/object.h b/server/object.h
index 46a9f770ca..cca12b6cf0 100644
--- a/server/object.h
+++ b/server/object.h
@@ -253,6 +253,7 @@ static const WCHAR type_Job[] = {'J','o','b'};
static const WCHAR type_Key[] = {'K','e','y'};
static const WCHAR type_KeyedEvent[] = {'K','e','y','e','d','E','v','e','n','t'};
static const WCHAR type_Mutant[] = {'M','u','t','a','n','t'};
+static const WCHAR type_Process[] = {'P','r','o','c','e','s','s'};
static const WCHAR type_Section[] = {'S','e','c','t','i','o','n'};
static const WCHAR type_Semaphore[] = {'S','e','m','a','p','h','o','r','e'};
static const WCHAR type_SymbolicLink[] = {'S','y','m','b','o','l','i','c','L','i','n','k'};
diff --git a/server/process.c b/server/process.c
index df1e9f1b0d..de3e926717 100644
--- a/server/process.c
+++ b/server/process.c
@@ -60,6 +60,7 @@ static int shutdown_stage; /* current stage in the shutdown process */
/* process operations */
static void process_dump( struct object *obj, int verbose );
+static struct object_type *process_get_type( struct object *obj );
static int process_signaled( struct object *obj, struct wait_queue_entry *entry );
static unsigned int process_map_access( struct object *obj, unsigned int access );
static struct security_descriptor *process_get_sd( struct object *obj );
@@ -71,7 +72,7 @@ static const struct object_ops process_ops =
{
sizeof(struct process), /* size */
process_dump, /* dump */
- no_get_type, /* get_type */
+ process_get_type, /* get_type */
add_queue, /* add_queue */
remove_queue, /* remove_queue */
process_signaled, /* signaled */
@@ -655,6 +656,12 @@ static void process_dump( struct object *obj, int verbose )
fprintf( stderr, "Process id=%04x handles=%p\n", process->id, process->handles );
}
+static struct object_type *process_get_type( struct object *obj )
+{
+ static const struct unicode_str str = { type_Process, sizeof(type_Process) };
+ return get_object_type( &str );
+}
+
static int process_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct process *process = (struct process *)obj;
--
2.11.0

View File

@ -0,0 +1,73 @@
From ef0142aadbcbd3e36ff3e2473dca76e68ba5ecba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 03:56:00 +0100
Subject: server: Add type Thread.
---
server/object.c | 2 +-
server/object.h | 1 +
server/thread.c | 9 ++++++++-
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/server/object.c b/server/object.c
index f7c249689f..37ac0adce6 100644
--- a/server/object.c
+++ b/server/object.c
@@ -719,7 +719,7 @@ static const struct unicode_str type_array[] =
{type_Token, sizeof(type_Token)},
{type_Job, sizeof(type_Job)},
{type_Process, sizeof(type_Process)},
- /* Thread */
+ {type_Thread, sizeof(type_Thread)},
{type_Event, sizeof(type_Event)},
{type_Mutant, sizeof(type_Mutant)},
{type_Semaphore, sizeof(type_Semaphore)},
diff --git a/server/object.h b/server/object.h
index cca12b6cf0..3ba3f4b431 100644
--- a/server/object.h
+++ b/server/object.h
@@ -257,6 +257,7 @@ static const WCHAR type_Process[] = {'P','r','o','c','e','s','s'};
static const WCHAR type_Section[] = {'S','e','c','t','i','o','n'};
static const WCHAR type_Semaphore[] = {'S','e','m','a','p','h','o','r','e'};
static const WCHAR type_SymbolicLink[] = {'S','y','m','b','o','l','i','c','L','i','n','k'};
+static const WCHAR type_Thread[] = {'T','h','r','e','a','d'};
static const WCHAR type_Timer[] = {'T','i','m','e','r'};
static const WCHAR type_Token[] = {'T','o','k','e','n'};
static const WCHAR type_Type[] = {'T','y','p','e'};
diff --git a/server/thread.c b/server/thread.c
index 53e94fda42..108444ebc5 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -129,6 +129,7 @@ static const struct object_ops thread_apc_ops =
/* thread operations */
static void dump_thread( struct object *obj, int verbose );
+static struct object_type *thread_get_type( struct object *obj );
static int thread_signaled( struct object *obj, struct wait_queue_entry *entry );
static unsigned int thread_map_access( struct object *obj, unsigned int access );
static void thread_poll_event( struct fd *fd, int event );
@@ -138,7 +139,7 @@ static const struct object_ops thread_ops =
{
sizeof(struct thread), /* size */
dump_thread, /* dump */
- no_get_type, /* get_type */
+ thread_get_type, /* get_type */
add_queue, /* add_queue */
remove_queue, /* remove_queue */
thread_signaled, /* signaled */
@@ -344,6 +345,12 @@ static void dump_thread( struct object *obj, int verbose )
thread->id, thread->unix_pid, thread->unix_tid, thread->state );
}
+static struct object_type *thread_get_type( struct object *obj )
+{
+ static const struct unicode_str str = { type_Thread, sizeof(type_Thread) };
+ return get_object_type( &str );
+}
+
static int thread_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct thread *mythread = (struct thread *)obj;
--
2.11.0

View File

@ -0,0 +1,71 @@
From 1e3e93483b223c6e0e9d712fff4a8874c503c973 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 17:41:11 +0100
Subject: ntdll: Set TypeIndex for ObjectTypeInformation in NtQueryObject.
---
dlls/ntdll/om.c | 4 ++++
server/directory.c | 5 ++++-
server/protocol.def | 1 +
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
index 8911a28b20..8f54d4f49f 100644
--- a/dlls/ntdll/om.c
+++ b/dlls/ntdll/om.c
@@ -184,6 +184,10 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
p->TypeName.Buffer[res / sizeof(WCHAR)] = 0;
if (used_len) *used_len = sizeof(*p) + p->TypeName.MaximumLength;
}
+ if (status == STATUS_SUCCESS)
+ {
+ p->TypeIndex = reply->index;
+ }
}
}
SERVER_END_REQ;
diff --git a/server/directory.c b/server/directory.c
index b4f53e2edf..59c8194d09 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -44,6 +44,7 @@
struct object_type
{
struct object obj; /* object header */
+ unsigned int index; /* type index */
};
static void object_type_dump( struct object *obj, int verbose );
@@ -239,7 +240,8 @@ struct object_type *get_object_type( const struct unicode_str *name )
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
assert( object_type_count < sizeof(object_type_list)/sizeof(object_type_list[0]) );
- object_type_list[ object_type_count++ ] = (struct object_type *)grab_object( type );
+ type->index = object_type_count++;
+ object_type_list[ type->index ] = (struct object_type *)grab_object( type );
make_object_static( &type->obj );
}
clear_error();
@@ -528,6 +530,7 @@ DECL_HANDLER(get_object_type)
{
if ((name = get_object_name( &type->obj, &reply->total )))
set_reply_data( name, min( reply->total, get_reply_max_size() ) );
+ reply->index = type->index;
release_object( type );
}
release_object( obj );
diff --git a/server/protocol.def b/server/protocol.def
index 98c4c58a4e..d6847f8d55 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3543,6 +3543,7 @@ struct handle_info
@REQ(get_object_type)
obj_handle_t handle; /* handle to the object */
@REPLY
+ unsigned int index; /* type index */
data_size_t total; /* needed size for type name */
VARARG(type,unicode_str); /* type name */
@END
--
2.11.0

View File

@ -0,0 +1,108 @@
From ba10e334a375c7dde7cd890554fbbade1be81a9d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 17:44:17 +0100
Subject: ntdll: Set object type for System(Extended)HandleInformation in
NtQuerySystemInformation.
---
dlls/ntdll/nt.c | 4 +++-
server/directory.c | 6 ++++++
server/handle.c | 10 ++++++++++
server/object.h | 1 +
server/protocol.def | 1 +
5 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index a939298d19..211b67f98b 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -2280,7 +2280,8 @@ NTSTATUS WINAPI NtQuerySystemInformation(
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 */
+ shi->Handle[i].ObjectType = info[i].type;
+ /* FIXME: Fill out HandleFlags, ObjectPointer */
}
}
else if (ret == STATUS_BUFFER_TOO_SMALL)
@@ -2331,6 +2332,7 @@ NTSTATUS WINAPI NtQuerySystemInformation(
shi->Handle[i].UniqueProcessId = info[i].owner;
shi->Handle[i].HandleValue = info[i].handle;
shi->Handle[i].GrantedAccess = info[i].access;
+ shi->Handle[i].ObjectTypeIndex = info[i].type;
/* FIXME: Fill out remaining fields */
}
}
diff --git a/server/directory.c b/server/directory.c
index 59c8194d09..f61a5cecf1 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -249,6 +249,12 @@ struct object_type *get_object_type( const struct unicode_str *name )
return type;
}
+/* retrieve the object type index */
+unsigned int type_get_index( struct object_type *type )
+{
+ return type->index;
+}
+
/* Global initialization */
static void create_session( unsigned int id )
diff --git a/server/handle.c b/server/handle.c
index 0e909ff27e..e29cead46b 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -971,6 +971,7 @@ static int enum_handles( struct process *process, void *user )
struct handle_table *table = process->handles;
struct handle_entry *entry;
struct handle_info *handle;
+ struct object_type *type;
unsigned int i;
if (!table)
@@ -989,6 +990,15 @@ static int enum_handles( struct process *process, void *user )
handle->owner = process->id;
handle->handle = index_to_handle(i);
handle->access = entry->access & ~RESERVED_ALL;
+
+ if ((type = entry->ptr->ops->get_type(entry->ptr)))
+ {
+ handle->type = type_get_index(type);
+ release_object(type);
+ }
+ else
+ handle->type = 0;
+
info->count--;
}
diff --git a/server/object.h b/server/object.h
index 3ba3f4b431..4a5d282a47 100644
--- a/server/object.h
+++ b/server/object.h
@@ -264,6 +264,7 @@ static const WCHAR type_Type[] = {'T','y','p','e'};
static const WCHAR type_WindowStation[] = {'W','i','n','d','o','w','S','t','a','t','i','o','n'};
extern void init_types(void);
+extern unsigned int type_get_index( struct object_type *type );
/* symbolic link functions */
diff --git a/server/protocol.def b/server/protocol.def
index d6847f8d55..35730d60cb 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3433,6 +3433,7 @@ struct handle_info
process_id_t owner;
obj_handle_t handle;
unsigned int access;
+ unsigned int type;
};
/* Return a list of all opened handles */
--
2.11.0

View File

@ -0,0 +1,180 @@
From c157e1ed4e1a3f373471bb49f1a8c536ea0ce2cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 19:39:29 +0100
Subject: ntdll: Mimic object type behavior for different windows versions.
---
dlls/ntdll/nt.c | 17 ++++++++++++--
dlls/ntdll/om.c | 5 +++-
dlls/ntdll/tests/om.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 83 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 211b67f98b..1dd890c4bd 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -70,6 +70,19 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
+static DWORD translate_object_index(DWORD index)
+{
+ WORD version = MAKEWORD(NtCurrentTeb()->Peb->OSMinorVersion, NtCurrentTeb()->Peb->OSMajorVersion);
+
+ /* Process Hacker depends on this logic */
+ if (version >= 0x0602)
+ return index;
+ else if (version == 0x0601)
+ return index + 2;
+ else
+ return index + 1;
+}
+
/*
* Token
*/
@@ -2280,7 +2293,7 @@ NTSTATUS WINAPI NtQuerySystemInformation(
shi->Handle[i].OwnerPid = info[i].owner;
shi->Handle[i].HandleValue = info[i].handle;
shi->Handle[i].AccessMask = info[i].access;
- shi->Handle[i].ObjectType = info[i].type;
+ shi->Handle[i].ObjectType = translate_object_index(info[i].type);
/* FIXME: Fill out HandleFlags, ObjectPointer */
}
}
@@ -2332,7 +2345,7 @@ NTSTATUS WINAPI NtQuerySystemInformation(
shi->Handle[i].UniqueProcessId = info[i].owner;
shi->Handle[i].HandleValue = info[i].handle;
shi->Handle[i].GrantedAccess = info[i].access;
- shi->Handle[i].ObjectTypeIndex = info[i].type;
+ shi->Handle[i].ObjectTypeIndex = translate_object_index(info[i].type);
/* FIXME: Fill out remaining fields */
}
}
diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
index 8f54d4f49f..92fc654448 100644
--- a/dlls/ntdll/om.c
+++ b/dlls/ntdll/om.c
@@ -186,7 +186,10 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
}
if (status == STATUS_SUCCESS)
{
- p->TypeIndex = reply->index;
+ WORD version = MAKEWORD(NtCurrentTeb()->Peb->OSMinorVersion,
+ NtCurrentTeb()->Peb->OSMajorVersion);
+ if (version >= 0x0602)
+ p->TypeIndex = reply->index;
}
}
}
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index 02d83016e2..84b783b80a 100644
--- a/dlls/ntdll/tests/om.c
+++ b/dlls/ntdll/tests/om.c
@@ -69,6 +69,7 @@ static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, c
static NTSTATUS (WINAPI *pNtReleaseKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG);
static NTSTATUS (WINAPI *pNtOpenIoCompletion)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
+static NTSTATUS (WINAPI *pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
#define KEYEDEVENT_WAIT 0x0001
#define KEYEDEVENT_WAKE 0x0002
@@ -1539,13 +1540,31 @@ static void test_query_object(void)
pRtlFreeUnicodeString( &session );
}
+static BOOL winver_equal_or_newer(WORD major, WORD minor)
+{
+ OSVERSIONINFOEXW info = {sizeof(info)};
+ ULONGLONG mask = 0;
+
+ info.dwMajorVersion = major;
+ info.dwMinorVersion = minor;
+
+ VER_SET_CONDITION(mask, VER_MAJORVERSION, VER_GREATER_EQUAL);
+ VER_SET_CONDITION(mask, VER_MINORVERSION, VER_GREATER_EQUAL);
+
+ return VerifyVersionInfoW(&info, VER_MAJORVERSION | VER_MINORVERSION, mask);
+}
+
static void test_query_object_types(void)
{
static const WCHAR typeW[] = {'T','y','p','e'};
+ static const WCHAR eventW[] = {'E','v','e','n','t'};
+ SYSTEM_HANDLE_INFORMATION_EX *shi;
OBJECT_TYPES_INFORMATION *buffer;
OBJECT_TYPE_INFORMATION *type;
NTSTATUS status;
- ULONG len, i;
+ HANDLE handle;
+ BOOL found;
+ ULONG len, i, event_type_index = 0;
buffer = HeapAlloc( GetProcessHeap(), 0, sizeof(OBJECT_TYPES_INFORMATION) );
ok( buffer != NULL, "Failed to allocate memory\n" );
@@ -1573,11 +1592,54 @@ static void test_query_object_types(void)
ok( type->TypeName.Length == sizeof(typeW) && !strncmpW(typeW, type->TypeName.Buffer, 4),
"Expected 'Type' as first type, got %s\n", wine_dbgstr_us(&type->TypeName) );
}
+ if (type->TypeName.Length == sizeof(eventW) && !strncmpW(eventW, type->TypeName.Buffer, 5))
+ {
+ if (winver_equal_or_newer( 6, 2 ))
+ event_type_index = type->TypeIndex;
+ else
+ event_type_index = winver_equal_or_newer( 6, 1 ) ? i + 2 : i + 1;
+ }
type = (OBJECT_TYPE_INFORMATION *)ROUND_UP( (DWORD_PTR)(type + 1) + length, sizeof(DWORD_PTR) );
}
HeapFree( GetProcessHeap(), 0, buffer );
+
+ ok( event_type_index, "Could not find object type for events\n" );
+
+ handle = CreateEventA( NULL, FALSE, FALSE, NULL );
+ ok( handle != NULL, "Failed to create event\n" );
+
+ shi = HeapAlloc( GetProcessHeap(), 0, sizeof(*shi) );
+ ok( shi != NULL, "Failed to allocate memory\n" );
+
+ status = pNtQuerySystemInformation( SystemExtendedHandleInformation, shi, sizeof(*shi), &len );
+ ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status );
+
+ shi = HeapReAlloc( GetProcessHeap(), 0, shi, len );
+ ok( shi != NULL, "Failed to allocate memory\n" );
+
+ status = pNtQuerySystemInformation( SystemExtendedHandleInformation, shi, len, &len );
+ ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status );
+
+ found = FALSE;
+ for (i = 0; i < shi->Count; i++)
+ {
+ if (shi->Handle[i].UniqueProcessId != GetCurrentProcessId())
+ continue;
+ if ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue != handle)
+ continue;
+
+ ok( shi->Handle[i].ObjectTypeIndex == event_type_index, "Event type does not match: %u vs %u\n",
+ shi->Handle[i].ObjectTypeIndex, event_type_index );
+
+ found = TRUE;
+ break;
+ }
+ ok( found, "Expected to find event handle %p (pid %x) in handle list\n", handle, GetCurrentProcessId() );
+
+ HeapFree( GetProcessHeap(), 0, shi );
+ CloseHandle( handle );
}
static void test_type_mismatch(void)
@@ -2084,6 +2146,7 @@ START_TEST(om)
pNtReleaseKeyedEvent = (void *)GetProcAddress(hntdll, "NtReleaseKeyedEvent");
pNtCreateIoCompletion = (void *)GetProcAddress(hntdll, "NtCreateIoCompletion");
pNtOpenIoCompletion = (void *)GetProcAddress(hntdll, "NtOpenIoCompletion");
+ pNtQuerySystemInformation = (void *)GetProcAddress(hntdll, "NtQuerySystemInformation");
test_case_sensitive();
test_namespace_pipe();
--
2.11.0

View File

@ -0,0 +1,3 @@
Fixes: Implement querying for object types and their indices
Depends: server-Shared_Memory
Depends: server-Misc_ACL