mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Added patch to implement querying for object types and their indices.
This commit is contained in:
parent
d79b66338e
commit
8ef379ecc8
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
73
patches/server-Object_Types/0005-server-Add-type-Token.patch
Normal file
73
patches/server-Object_Types/0005-server-Add-type-Token.patch
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
3
patches/server-Object_Types/definition
Normal file
3
patches/server-Object_Types/definition
Normal file
@ -0,0 +1,3 @@
|
||||
Fixes: Implement querying for object types and their indices
|
||||
Depends: server-Shared_Memory
|
||||
Depends: server-Misc_ACL
|
Loading…
Reference in New Issue
Block a user