ntdll-ThreadQuerySetWin32StartAddress: Update patchset with revision 2.

This commit is contained in:
Sebastian Lackner 2015-07-27 23:13:09 +02:00
parent d9d1380650
commit a66e263db0
7 changed files with 175 additions and 233 deletions

View File

@ -1,16 +1,15 @@
From 1896eceb640a7488c09c3cd6dadd63ecca8f510d Mon Sep 17 00:00:00 2001
From e2a835f8bd13694cf23c833548f0f55eabdca09a Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Mon, 27 Jul 2015 06:12:30 +0200
Date: Mon, 27 Jul 2015 18:30:53 +0200
Subject: server: Use a separate wineserver call to fetch thread times.
(resend)
By moving the creation_time / exit_time to a separate wineserver call, we can
safe a couple of bytes required for the following patches. Thats not the only
purpose, this patch is also in preparation for a proper implementation of
NtQueryInformationThread(..., ThreadTimes, ...). The wineserver can use
/proc/<pid>/task/<tid>/stat to obtain precise thread time information, which
means we'll need space for two additional timeout_t values. Since accessing
/proc might have some overhead, its better to do it only when really required.
The values can afterwards be cached for some short amount of time.
Changes in v2:
* I saw that we already pass the entry point in init_thread() to the wineserver,
so no need to change wineserver calls. Patch 2 and 3 have been merged because
the code looks much easier now.
No changes in this patch.
---
dlls/ntdll/thread.c | 6 ++----
server/protocol.def | 11 +++++++++--

View File

@ -0,0 +1,111 @@
From 11c840163c21b92b8e67844f18ade51f0f6905e0 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Mon, 27 Jul 2015 18:31:11 +0200
Subject: ntdll: Implement ThreadQuerySetWin32StartAddress info class in
NtSetInformationThread. (v2)
This implements the pre-Vista version, where the entry point can be changed.
---
dlls/ntdll/thread.c | 16 ++++++++++++++--
server/protocol.def | 8 +++++---
server/thread.c | 4 ++++
server/thread.h | 1 +
4 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 2781827..3e95fd4 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -1203,14 +1203,26 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
case ThreadHideFromDebugger:
/* pretend the call succeeded to satisfy some code protectors */
return STATUS_SUCCESS;
-
+ case ThreadQuerySetWin32StartAddress:
+ {
+ const PRTL_THREAD_START_ROUTINE *entry = data;
+ if (length != sizeof(PRTL_THREAD_START_ROUTINE)) return STATUS_INVALID_PARAMETER;
+ SERVER_START_REQ( set_thread_info )
+ {
+ req->handle = wine_server_obj_handle( handle );
+ req->mask = SET_THREAD_INFO_ENTRYPOINT;
+ req->entry_point = wine_server_client_ptr( *entry );
+ status = wine_server_call( req );
+ }
+ SERVER_END_REQ;
+ }
+ return status;
case ThreadBasicInformation:
case ThreadTimes:
case ThreadPriority:
case ThreadDescriptorTableEntry:
case ThreadEnableAlignmentFaultFixup:
case ThreadEventPair_Reusable:
- case ThreadQuerySetWin32StartAddress:
case ThreadPerformanceCount:
case ThreadAmILastThread:
case ThreadIdealProcessor:
diff --git a/server/protocol.def b/server/protocol.def
index 3d7f7be..47cedff 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -864,10 +864,12 @@ struct rawinput_device
int priority; /* priority class */
affinity_t affinity; /* affinity mask */
obj_handle_t token; /* impersonation token */
+ client_ptr_t entry_point; /* thread entry point */
@END
-#define SET_THREAD_INFO_PRIORITY 0x01
-#define SET_THREAD_INFO_AFFINITY 0x02
-#define SET_THREAD_INFO_TOKEN 0x04
+#define SET_THREAD_INFO_PRIORITY 0x01
+#define SET_THREAD_INFO_AFFINITY 0x02
+#define SET_THREAD_INFO_TOKEN 0x04
+#define SET_THREAD_INFO_ENTRYPOINT 0x08
/* Retrieve information about a module */
diff --git a/server/thread.c b/server/thread.c
index b8c73c6..f020908 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -175,6 +175,7 @@ static inline void init_thread_structure( struct thread *thread )
thread->context = NULL;
thread->suspend_context = NULL;
thread->teb = 0;
+ thread->entry_point = 0;
thread->debug_ctx = NULL;
thread->debug_event = NULL;
thread->debug_break = 0;
@@ -497,6 +498,8 @@ static void set_thread_info( struct thread *thread,
}
if (req->mask & SET_THREAD_INFO_TOKEN)
security_set_thread_token( thread, req->token );
+ if (req->mask & SET_THREAD_INFO_ENTRYPOINT)
+ thread->entry_point = req->entry_point;
}
/* stop a thread (at the Unix level) */
@@ -1284,6 +1287,7 @@ DECL_HANDLER(init_thread)
current->unix_pid = req->unix_pid;
current->unix_tid = req->unix_tid;
current->teb = req->teb;
+ current->entry_point = req->entry;
if (!process->peb) /* first thread, initialize the process too */
{
diff --git a/server/thread.h b/server/thread.h
index 996d95b..2821991 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -79,6 +79,7 @@ struct thread
context_t *context; /* current context if in an exception handler */
context_t *suspend_context; /* current context if suspended */
client_ptr_t teb; /* TEB address (in client address space) */
+ client_ptr_t entry_point; /* entry point (in client address space) */
affinity_t affinity; /* affinity mask */
int priority; /* priority level */
int suspend; /* suspend count */
--
2.4.5

View File

@ -1,86 +0,0 @@
From 41252878d2e43bb874bcf32a81216f61f25bfca6 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Mon, 27 Jul 2015 06:12:39 +0200
Subject: server: Store thread entry points in server.
For the main thread we store it in the init_process_done handler, for
all other threads in the new_thread handler.
---
dlls/ntdll/thread.c | 1 +
server/process.c | 1 +
server/protocol.def | 1 +
server/thread.c | 2 ++
server/thread.h | 1 +
5 files changed, 6 insertions(+)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 2781827..ef4029a 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -494,6 +494,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
SERVER_START_REQ( new_thread )
{
+ req->entry = wine_server_client_ptr( start );
req->access = THREAD_ALL_ACCESS;
req->attributes = 0; /* FIXME */
req->suspend = suspended;
diff --git a/server/process.c b/server/process.c
index 0bf7194..7252497 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1295,6 +1295,7 @@ DECL_HANDLER(init_process_done)
process->ldt_copy = req->ldt_copy;
process->start_time = current_time;
+ current->entry_point = req->entry;
generate_startup_debug_events( process, req->entry );
set_process_startup_state( process, STARTUP_DONE );
diff --git a/server/protocol.def b/server/protocol.def
index 3d7f7be..0e1756c 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -737,6 +737,7 @@ struct rawinput_device
/* Create a new thread from the context of the parent */
@REQ(new_thread)
+ client_ptr_t entry; /* entry point (in client address space) */
unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */
int suspend; /* new thread should be suspended on creation */
diff --git a/server/thread.c b/server/thread.c
index b8c73c6..afcb2dc 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -175,6 +175,7 @@ static inline void init_thread_structure( struct thread *thread )
thread->context = NULL;
thread->suspend_context = NULL;
thread->teb = 0;
+ thread->entry_point = 0;
thread->debug_ctx = NULL;
thread->debug_event = NULL;
thread->debug_break = 0;
@@ -1235,6 +1236,7 @@ DECL_HANDLER(new_thread)
if ((thread = create_thread( request_fd, current->process )))
{
+ thread->entry_point = req->entry;
if (req->suspend) thread->suspend++;
reply->tid = get_thread_id( thread );
if ((reply->handle = alloc_handle( current->process, thread, req->access, req->attributes )))
diff --git a/server/thread.h b/server/thread.h
index 996d95b..2821991 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -79,6 +79,7 @@ struct thread
context_t *context; /* current context if in an exception handler */
context_t *suspend_context; /* current context if suspended */
client_ptr_t teb; /* TEB address (in client address space) */
+ client_ptr_t entry_point; /* entry point (in client address space) */
affinity_t affinity; /* affinity mask */
int priority; /* priority level */
int suspend; /* suspend count */
--
2.4.5

View File

@ -1,82 +1,74 @@
From 96ae4f590b53e5c418adc1b6b503aa85e7399f8d Mon Sep 17 00:00:00 2001
From f9566dfc2af3bcef3d3164daaea612ad141b5c33 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Mon, 27 Jul 2015 06:12:48 +0200
Date: Mon, 27 Jul 2015 18:31:33 +0200
Subject: ntdll: Implement ThreadQuerySetWin32StartAddress info class in
NtSetInformationThread.
NtQueryInformationThread. (resend)
This implements the pre-Vista version, where the entry point can be changed.
No changes in this patch.
---
dlls/ntdll/thread.c | 16 ++++++++++++++--
server/protocol.def | 8 +++++---
server/thread.c | 2 ++
3 files changed, 21 insertions(+), 5 deletions(-)
dlls/ntdll/thread.c | 18 +++++++++++++++++-
server/protocol.def | 1 +
server/thread.c | 1 +
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index ef4029a..74d512a 100644
index 3e95fd4..0a8a7b9 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -1204,14 +1204,26 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
case ThreadHideFromDebugger:
/* pretend the call succeeded to satisfy some code protectors */
return STATUS_SUCCESS;
-
@@ -1086,12 +1086,28 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
SERVER_END_REQ;
return status;
}
+ case ThreadQuerySetWin32StartAddress:
+ {
+ const PRTL_THREAD_START_ROUTINE *entry = data;
+ if (length != sizeof(PRTL_THREAD_START_ROUTINE)) return STATUS_INVALID_PARAMETER;
+ SERVER_START_REQ( set_thread_info )
+ SERVER_START_REQ( get_thread_info )
+ {
+ req->handle = wine_server_obj_handle( handle );
+ req->mask = SET_THREAD_INFO_ENTRYPOINT;
+ req->entry_point = wine_server_client_ptr( *entry );
+ req->handle = wine_server_obj_handle( handle );
+ req->tid_in = 0;
+ status = wine_server_call( req );
+ if (status == STATUS_SUCCESS)
+ {
+ PRTL_THREAD_START_ROUTINE entry = wine_server_get_ptr( reply->entry_point );
+ if (data) memcpy( data, &entry, min( length, sizeof(entry) ) );
+ if (ret_len) *ret_len = min( length, sizeof(entry) );
+ }
+ }
+ SERVER_END_REQ;
+ return status;
+ }
+ return status;
case ThreadBasicInformation:
case ThreadTimes:
case ThreadPriority:
case ThreadDescriptorTableEntry:
case ThreadBasePriority:
case ThreadImpersonationToken:
case ThreadEnableAlignmentFaultFixup:
case ThreadEventPair_Reusable:
- case ThreadQuerySetWin32StartAddress:
case ThreadZeroTlsCell:
case ThreadPerformanceCount:
case ThreadAmILastThread:
case ThreadIdealProcessor:
diff --git a/server/protocol.def b/server/protocol.def
index 0e1756c..a1ab2613 100644
index 47cedff..3e25e40 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -865,10 +865,12 @@ struct rawinput_device
int priority; /* priority class */
affinity_t affinity; /* affinity mask */
obj_handle_t token; /* impersonation token */
+ client_ptr_t entry_point; /* thread entry point */
@END
-#define SET_THREAD_INFO_PRIORITY 0x01
-#define SET_THREAD_INFO_AFFINITY 0x02
-#define SET_THREAD_INFO_TOKEN 0x04
+#define SET_THREAD_INFO_PRIORITY 0x01
+#define SET_THREAD_INFO_AFFINITY 0x02
+#define SET_THREAD_INFO_TOKEN 0x04
+#define SET_THREAD_INFO_ENTRYPOINT 0x08
/* Retrieve information about a module */
@@ -841,6 +841,7 @@ struct rawinput_device
process_id_t pid; /* server process id */
thread_id_t tid; /* server thread id */
client_ptr_t teb; /* thread teb pointer */
+ client_ptr_t entry_point; /* thread entry point */
affinity_t affinity; /* thread affinity mask */
int exit_code; /* thread exit code */
int priority; /* thread priority level */
diff --git a/server/thread.c b/server/thread.c
index afcb2dc..0311966 100644
index f020908..981bcc1 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -498,6 +498,8 @@ static void set_thread_info( struct thread *thread,
}
if (req->mask & SET_THREAD_INFO_TOKEN)
security_set_thread_token( thread, req->token );
+ if (req->mask & SET_THREAD_INFO_ENTRYPOINT)
+ thread->entry_point = req->entry_point;
}
/* stop a thread (at the Unix level) */
@@ -1375,6 +1375,7 @@ DECL_HANDLER(get_thread_info)
reply->pid = get_process_id( thread->process );
reply->tid = get_thread_id( thread );
reply->teb = thread->teb;
+ reply->entry_point = thread->entry_point;
reply->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STATUS_PENDING;
reply->priority = thread->priority;
reply->affinity = thread->affinity;
--
2.4.5

View File

@ -1,73 +0,0 @@
From 3e3090001558c228e96a3ff64166294398b40380 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Mon, 27 Jul 2015 06:13:00 +0200
Subject: ntdll: Implement ThreadQuerySetWin32StartAddress info class in
NtQueryInformationThread.
---
dlls/ntdll/thread.c | 18 +++++++++++++++++-
server/protocol.def | 1 +
server/thread.c | 1 +
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 74d512a..95b7add 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -1087,12 +1087,28 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
SERVER_END_REQ;
return status;
}
+ case ThreadQuerySetWin32StartAddress:
+ {
+ SERVER_START_REQ( get_thread_info )
+ {
+ req->handle = wine_server_obj_handle( handle );
+ req->tid_in = 0;
+ status = wine_server_call( req );
+ if (status == STATUS_SUCCESS)
+ {
+ PRTL_THREAD_START_ROUTINE entry = wine_server_get_ptr( reply->entry_point );
+ if (data) memcpy( data, &entry, min( length, sizeof(entry) ) );
+ if (ret_len) *ret_len = min( length, sizeof(entry) );
+ }
+ }
+ SERVER_END_REQ;
+ return status;
+ }
case ThreadPriority:
case ThreadBasePriority:
case ThreadImpersonationToken:
case ThreadEnableAlignmentFaultFixup:
case ThreadEventPair_Reusable:
- case ThreadQuerySetWin32StartAddress:
case ThreadZeroTlsCell:
case ThreadPerformanceCount:
case ThreadIdealProcessor:
diff --git a/server/protocol.def b/server/protocol.def
index a1ab2613..15735e0 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -842,6 +842,7 @@ struct rawinput_device
process_id_t pid; /* server process id */
thread_id_t tid; /* server thread id */
client_ptr_t teb; /* thread teb pointer */
+ client_ptr_t entry_point; /* thread entry point */
affinity_t affinity; /* thread affinity mask */
int exit_code; /* thread exit code */
int priority; /* thread priority level */
diff --git a/server/thread.c b/server/thread.c
index 0311966..902848e 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -1375,6 +1375,7 @@ DECL_HANDLER(get_thread_info)
reply->pid = get_process_id( thread->process );
reply->tid = get_thread_id( thread );
reply->teb = thread->teb;
+ reply->entry_point = thread->entry_point;
reply->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STATUS_PENDING;
reply->priority = thread->priority;
reply->affinity = thread->affinity;
--
2.4.5

View File

@ -1,9 +1,10 @@
From 128e2e5ac1d05988afcde9c04be5ccb8e3b93808 Mon Sep 17 00:00:00 2001
From 02ac0105e7d1a8142e5773e436424496314993c6 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Mon, 27 Jul 2015 06:13:09 +0200
Date: Mon, 27 Jul 2015 18:31:47 +0200
Subject: ntdll/tests: Add tests for ThreadQuerySetWin32StartAddress info
class.
class. (resend)
No changes, so the tests should still pass. ;)
---
dlls/ntdll/tests/info.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)

View File

@ -3643,20 +3643,18 @@ fi
# | * [#8277] Add support for ThreadQuerySetWin32StartAddress info class
# |
# | Modified files:
# | * dlls/ntdll/tests/info.c, dlls/ntdll/thread.c, server/process.c, server/protocol.def, server/thread.c, server/thread.h
# | * dlls/ntdll/tests/info.c, dlls/ntdll/thread.c, server/protocol.def, server/thread.c, server/thread.h
# |
if test "$enable_ntdll_ThreadQuerySetWin32StartAddress" -eq 1; then
patch_apply ntdll-ThreadQuerySetWin32StartAddress/0001-server-Use-a-separate-wineserver-call-to-fetch-threa.patch
patch_apply ntdll-ThreadQuerySetWin32StartAddress/0002-server-Store-thread-entry-points-in-server.patch
patch_apply ntdll-ThreadQuerySetWin32StartAddress/0002-ntdll-Implement-ThreadQuerySetWin32StartAddress-info.patch
patch_apply ntdll-ThreadQuerySetWin32StartAddress/0003-ntdll-Implement-ThreadQuerySetWin32StartAddress-info.patch
patch_apply ntdll-ThreadQuerySetWin32StartAddress/0004-ntdll-Implement-ThreadQuerySetWin32StartAddress-info.patch
patch_apply ntdll-ThreadQuerySetWin32StartAddress/0005-ntdll-tests-Add-tests-for-ThreadQuerySetWin32StartAd.patch
patch_apply ntdll-ThreadQuerySetWin32StartAddress/0004-ntdll-tests-Add-tests-for-ThreadQuerySetWin32StartAd.patch
(
echo '+ { "Sebastian Lackner", "server: Use a separate wineserver call to fetch thread times.", 1 },';
echo '+ { "Sebastian Lackner", "server: Store thread entry points in server.", 1 },';
echo '+ { "Sebastian Lackner", "ntdll: Implement ThreadQuerySetWin32StartAddress info class in NtSetInformationThread.", 1 },';
echo '+ { "Sebastian Lackner", "ntdll: Implement ThreadQuerySetWin32StartAddress info class in NtQueryInformationThread.", 1 },';
echo '+ { "Sebastian Lackner", "ntdll/tests: Add tests for ThreadQuerySetWin32StartAddress info class.", 1 },';
echo '+ { "Sebastian Lackner", "server: Use a separate wineserver call to fetch thread times. (resend).", 1 },';
echo '+ { "Sebastian Lackner", "ntdll: Implement ThreadQuerySetWin32StartAddress info class in NtSetInformationThread.", 2 },';
echo '+ { "Sebastian Lackner", "ntdll: Implement ThreadQuerySetWin32StartAddress info class in NtQueryInformationThread. (resend).", 1 },';
echo '+ { "Sebastian Lackner", "ntdll/tests: Add tests for ThreadQuerySetWin32StartAddress info class. (resend).", 1 },';
) >> "$patchlist"
fi