[PATCH] server, ntoskrnl: correctly implement PsGetCurrentThread/ProcessId (try 2)

Bernhard Loos bernhardloos at googlemail.com
Wed Aug 24 23:50:07 CDT 2011


---
 dlls/ntoskrnl.exe/ntoskrnl.c |   77 ++++++++++++++++++++++++++++++++++++++++--
 server/device.c              |    3 ++
 server/protocol.def          |    2 +
 server/request.h             |    8 +++--
 server/trace.c               |    2 +
 5 files changed, 86 insertions(+), 6 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index e5668fd..461604c 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -68,6 +68,13 @@ struct IrpInstance
     IRP *irp;
 };

+static DWORD thread_info_tls;
+
+struct thread_info {
+    DWORD tid;
+    DWORD pid;
+};
+
 #ifdef __i386__
 #define DEFINE_FASTCALL1_ENTRYPOINT( name ) \
     __ASM_STDCALL_FUNC( name, 4, \
@@ -125,6 +132,26 @@ static HANDLE get_device_manager(void)
     return ret;
 }

+NTSTATUS set_current_pidtid(DWORD pid, DWORD tid)
+{
+    struct thread_info *ti = TlsGetValue(thread_info_tls);
+
+    if (!ti) {
+        if (!(ti = LocalAlloc(sizeof(*ti), 0)))
+            return STATUS_NO_MEMORY;
+
+        if (!TlsSetValue(thread_info_tls, ti)) {
+            LocalFree(ti);
+            return STATUS_NO_MEMORY;
+        }
+    }
+
+    ti->pid = pid;
+    ti->tid = tid;
+
+    return STATUS_SUCCESS;
+}
+
 /* process an ioctl request for a given device */
 static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code,
void *in_buff, ULONG in_size,
                                void *out_buff, ULONG *out_size )
@@ -196,6 +223,7 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
     DEVICE_OBJECT *device = NULL;
     ULONG in_size = 4096, out_size = 0;
     HANDLE handles[2];
+    DWORD pid = 0, tid = 0;

     if (!(in_buff = HeapAlloc( GetProcessHeap(), 0, in_size )))
     {
@@ -220,6 +248,8 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
                 code     = reply->code;
                 ioctl    = reply->next;
                 device   = wine_server_get_ptr( reply->user_ptr );
+                pid      = reply->client_pid;
+                tid      = reply->client_tid;
                 in_size  = reply->in_size;
                 out_size = reply->out_size;
             }
@@ -238,6 +268,8 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
             HeapFree( GetProcessHeap(), 0, out_buff );
             if (out_size) out_buff = HeapAlloc( GetProcessHeap(), 0,
out_size );
             else out_buff = NULL;
+            if ((status = set_current_pidtid(pid, tid)))
+                break;
             status = process_ioctl( device, code, in_buff, in_size,
out_buff, &out_size );
             break;
         case STATUS_BUFFER_OVERFLOW:
@@ -1465,7 +1497,11 @@ NTSTATUS WINAPI PsCreateSystemThread(PHANDLE
ThreadHandle, ULONG DesiredAccess,
  */
 HANDLE WINAPI PsGetCurrentProcessId(void)
 {
-    return UlongToHandle(GetCurrentProcessId());  /* FIXME: not quite
right... */
+    struct thread_info *ti = TlsGetValue(thread_info_tls);
+
+    if (ti)
+        return UlongToHandle(ti->pid);
+    return UlongToHandle(GetCurrentProcessId());
 }


@@ -1474,7 +1510,11 @@ HANDLE WINAPI PsGetCurrentProcessId(void)
  */
 HANDLE WINAPI PsGetCurrentThreadId(void)
 {
-    return UlongToHandle(GetCurrentThreadId());  /* FIXME: not quite
right... */
+    struct thread_info *ti = TlsGetValue(thread_info_tls);
+
+    if (ti)
+        return UlongToHandle(ti->tid);
+    return UlongToHandle(GetCurrentThreadId());
 }


@@ -1640,6 +1680,35 @@ BOOLEAN WINAPI IoSetThreadHardErrorMode(BOOLEAN
EnableHardErrors)
     return FALSE;
 }

+BOOL setup_Ps_system(DWORD reason)
+{
+    switch(reason)
+    {
+        case DLL_PROCESS_ATTACH:
+            if ((thread_info_tls = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+                return FALSE;
+            break;
+        case DLL_THREAD_DETACH:
+        {
+            struct thread_info *ti = TlsGetValue(thread_info_tls);
+
+            if (ti)
+                LocalFree(ti);
+            break;
+        }
+        case DLL_PROCESS_DETACH:
+        {
+            struct thread_info *ti = TlsGetValue(thread_info_tls);
+
+            if (ti)
+                LocalFree(ti);
+            TlsFree(thread_info_tls);
+        }
+    }
+
+    return TRUE;
+}
+
 /*****************************************************
  *           DllMain
  */
@@ -1648,10 +1717,12 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD
reason, LPVOID reserved )
     static void *handler;
     LARGE_INTEGER count;

+    if (!setup_Ps_system(reason))
+        return FALSE;
+
     switch(reason)
     {
     case DLL_PROCESS_ATTACH:
-        DisableThreadLibraryCalls( inst );
 #ifdef __i386__
         handler = RtlAddVectoredExceptionHandler( TRUE, vectored_handler );
 #endif
diff --git a/server/device.c b/server/device.c
index 4d134a3..2c1dfbd 100644
--- a/server/device.c
+++ b/server/device.c
@@ -32,6 +32,7 @@
 #include "file.h"
 #include "handle.h"
 #include "request.h"
+#include "process.h"

 struct ioctl_call
 {
@@ -510,6 +511,8 @@ DECL_HANDLER(get_next_device_request)
         ioctl = LIST_ENTRY( ptr, struct ioctl_call, mgr_entry );
         reply->code = ioctl->code;
         reply->user_ptr = ioctl->device->user_ptr;
+        reply->client_pid = get_process_id(ioctl->thread->process);
+        reply->client_tid = get_thread_id(ioctl->thread);
         reply->in_size = ioctl->in_size;
         reply->out_size = ioctl->out_size;
         if (ioctl->in_size > get_reply_max_size()) set_error(
STATUS_BUFFER_OVERFLOW );
diff --git a/server/protocol.def b/server/protocol.def
index 123f16a..f07a6fb 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3201,6 +3201,8 @@ enum coords_relative
     obj_handle_t next;            /* handle to the next ioctl */
     ioctl_code_t code;            /* ioctl code */
     client_ptr_t user_ptr;        /* opaque ptr for the device */
+    process_id_t client_pid;      /* pid of process calling ioctl */
+    thread_id_t  client_tid;      /* tid of thread calling ioctl */
     data_size_t  in_size;         /* total needed input size */
     data_size_t  out_size;        /* needed output size */
     VARARG(next_data,bytes);      /* input data of the next ioctl */
diff --git a/server/request.h b/server/request.h
index d2ca2f6..275e490 100644
--- a/server/request.h
+++ b/server/request.h
@@ -2044,9 +2044,11 @@ C_ASSERT( sizeof(struct
get_next_device_request_request) == 24 );
 C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, next) == 8 );
 C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, code) == 12 );
 C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, user_ptr) == 16 );
-C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, in_size) == 24 );
-C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, out_size) == 28 );
-C_ASSERT( sizeof(struct get_next_device_request_reply) == 32 );
+C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply,
client_pid) == 24 );
+C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply,
client_tid) == 28 );
+C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, in_size) == 32 );
+C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, out_size) == 36 );
+C_ASSERT( sizeof(struct get_next_device_request_reply) == 40 );
 C_ASSERT( sizeof(struct make_process_system_request) == 16 );
 C_ASSERT( FIELD_OFFSET(struct make_process_system_reply, event) == 8 );
 C_ASSERT( sizeof(struct make_process_system_reply) == 16 );
diff --git a/server/trace.c b/server/trace.c
index 37ea216..347b599 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3729,6 +3729,8 @@ static void dump_get_next_device_request_reply(
const struct get_next_device_req
     fprintf( stderr, " next=%04x", req->next );
     dump_ioctl_code( ", code=", &req->code );
     dump_uint64( ", user_ptr=", &req->user_ptr );
+    fprintf( stderr, ", client_pid=%04x", req->client_pid );
+    fprintf( stderr, ", client_tid=%04x", req->client_tid );
     fprintf( stderr, ", in_size=%u", req->in_size );
     fprintf( stderr, ", out_size=%u", req->out_size );
     dump_varargs_bytes( ", next_data=", cur_size );
-- 
1.7.6



More information about the wine-patches mailing list