Alexandre Julliard : ntdll: Implement ProcessImageInformation class in NtQueryInformationProcess().

Alexandre Julliard julliard at winehq.org
Tue May 26 17:17:06 CDT 2020


Module: wine
Branch: master
Commit: 54a7e592e44622ecd61160498fb5148a46b2e8db
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=54a7e592e44622ecd61160498fb5148a46b2e8db

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue May 26 13:23:21 2020 +0200

ntdll: Implement ProcessImageInformation class in NtQueryInformationProcess().

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/process.c           | 23 +++++++++++++++++++++++
 dlls/ntdll/tests/info.c        | 32 ++++++++++++++++++++++++++++++++
 include/wine/server_protocol.h |  3 ++-
 server/file.h                  |  1 +
 server/mapping.c               | 11 +++++++++++
 server/process.c               |  7 +++++++
 server/protocol.def            |  1 +
 server/trace.c                 |  1 +
 8 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index 637bef0b65..1bef51b00b 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -621,6 +621,29 @@ NTSTATUS WINAPI NtQueryInformationProcess(
         else
             ret = STATUS_INVALID_PARAMETER;
         break;
+
+    case ProcessImageInformation:
+        len = sizeof(SECTION_IMAGE_INFORMATION);
+        if (ProcessInformationLength == len)
+        {
+            if (ProcessInformation)
+            {
+                pe_image_info_t pe_info;
+
+                SERVER_START_REQ( get_process_info )
+                {
+                    req->handle = wine_server_obj_handle( ProcessHandle );
+                    wine_server_set_reply( req, &pe_info, sizeof(pe_info) );
+                    if ((ret = wine_server_call( req )) == STATUS_SUCCESS)
+                        virtual_fill_image_information( &pe_info, ProcessInformation );
+                }
+                SERVER_END_REQ;
+            }
+            else ret = STATUS_ACCESS_VIOLATION;
+        }
+        else ret = STATUS_INFO_LENGTH_MISMATCH;
+        break;
+
     default:
         FIXME("(%p,info_class=%d,%p,0x%08x,%p) Unknown information class\n",
               ProcessHandle,ProcessInformationClass,
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index f923cc7743..cf3f7b9f6f 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -1821,6 +1821,34 @@ todo_wine
     heap_free(buffer);
 }
 
+static void test_query_process_image_info(void)
+{
+    IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress );
+    NTSTATUS status;
+    SECTION_IMAGE_INFORMATION info;
+    ULONG len;
+
+    status = pNtQueryInformationProcess( NULL, ProcessImageInformation, &info, sizeof(info), &len );
+    ok( status == STATUS_INVALID_HANDLE || broken(status == STATUS_INVALID_PARAMETER), /* winxp */
+        "got %08x\n", status);
+
+    status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageInformation, &info, sizeof(info)-1, &len );
+    ok( status == STATUS_INFO_LENGTH_MISMATCH, "got %08x\n", status);
+
+    status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageInformation, &info, sizeof(info)+1, &len );
+    ok( status == STATUS_INFO_LENGTH_MISMATCH, "got %08x\n", status);
+
+    memset( &info, 0xcc, sizeof(info) );
+    status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageInformation, &info, sizeof(info), &len );
+    ok( status == STATUS_SUCCESS, "got %08x\n", status);
+    ok( len == sizeof(info), "wrong len %u\n", len );
+
+    ok( info.SubsystemVersionHigh == nt->OptionalHeader.MajorSubsystemVersion, "wrong major version %x/%x\n",
+        info.SubsystemVersionHigh, nt->OptionalHeader.MajorSubsystemVersion );
+    ok( info.SubsystemVersionLow == nt->OptionalHeader.MinorSubsystemVersion, "wrong minor version %x/%x\n",
+        info.SubsystemVersionLow, nt->OptionalHeader.MinorSubsystemVersion );
+}
+
 static void test_query_process_debug_object_handle(int argc, char **argv)
 {
     char cmdline[MAX_PATH];
@@ -2741,6 +2769,10 @@ START_TEST(info)
     trace("Starting test_process_debug_flags()\n");
     test_query_process_debug_flags(argc, argv);
 
+    /* 0x25 ProcessImageInformation */
+    trace("Starting test_process_image_info()\n");
+    test_query_process_image_info();
+
     /* 0x4C SystemFirmwareTableInformation */
     trace("Starting test_query_firmware()\n");
     test_query_firmware();
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 2419671f0d..3e205d4165 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -962,6 +962,7 @@ struct get_process_info_reply
     client_cpu_t cpu;
     short int    debugger_present;
     short int    debug_children;
+    /* VARARG(image,pe_image_info); */
 };
 
 
@@ -6684,7 +6685,7 @@ union generic_reply
 
 /* ### protocol_version begin ### */
 
-#define SERVER_PROTOCOL_VERSION 603
+#define SERVER_PROTOCOL_VERSION 604
 
 /* ### protocol_version end ### */
 
diff --git a/server/file.h b/server/file.h
index aa5f6216c2..45215c588d 100644
--- a/server/file.h
+++ b/server/file.h
@@ -171,6 +171,7 @@ extern struct mapping *get_mapping_obj( struct process *process, obj_handle_t ha
                                         unsigned int access );
 extern struct file *get_mapping_file( struct process *process, client_ptr_t base,
                                       unsigned int access, unsigned int sharing );
+extern const pe_image_info_t *get_mapping_image_info( struct process *process, client_ptr_t base );
 extern void free_mapped_views( struct process *process );
 extern int get_page_size(void);
 
diff --git a/server/mapping.c b/server/mapping.c
index 0fcada7f8f..2c34b8f3c8 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -127,6 +127,7 @@ struct memory_view
     struct fd      *fd;              /* fd for mapped file */
     struct ranges  *committed;       /* list of committed ranges in this mapping */
     struct shared_map *shared;       /* temp file for shared PE mapping */
+    pe_image_info_t image;           /* image info (for PE image mapping) */
     unsigned int    flags;           /* SEC_* flags */
     client_ptr_t    base;            /* view base address (in process addr space) */
     mem_size_t      size;            /* view size */
@@ -894,6 +895,15 @@ struct file *get_mapping_file( struct process *process, client_ptr_t base,
     return create_file_for_fd_obj( view->fd, access, sharing );
 }
 
+/* get the image info for a SEC_IMAGE mapping */
+const pe_image_info_t *get_mapping_image_info( struct process *process, client_ptr_t base )
+{
+    struct memory_view *view = find_mapped_view( process, base );
+
+    if (!view || !(view->flags & SEC_IMAGE)) return NULL;
+    return &view->image;
+}
+
 static void mapping_dump( struct object *obj, int verbose )
 {
     struct mapping *mapping = (struct mapping *)obj;
@@ -1062,6 +1072,7 @@ DECL_HANDLER(map_view)
         view->fd        = !is_fd_removable( mapping->fd ) ? (struct fd *)grab_object( mapping->fd ) : NULL;
         view->committed = mapping->committed ? (struct ranges *)grab_object( mapping->committed ) : NULL;
         view->shared    = mapping->shared ? (struct shared_map *)grab_object( mapping->shared ) : NULL;
+        if (mapping->flags & SEC_IMAGE) view->image = mapping->image;
         list_add_tail( &current->process->views, &view->entry );
     }
 
diff --git a/server/process.c b/server/process.c
index 6722addb09..ab3d448b00 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1447,6 +1447,13 @@ DECL_HANDLER(get_process_info)
         reply->cpu              = process->cpu;
         reply->debugger_present = !!process->debugger;
         reply->debug_children   = process->debug_children;
+        if (get_reply_max_size())
+        {
+            const pe_image_info_t *info;
+            struct process_dll *exe = get_process_exe_module( process );
+            if (exe && (info = get_mapping_image_info( process, exe->base )))
+                set_reply_data( info, min( sizeof(*info), get_reply_max_size() ));
+        }
         release_object( process );
     }
 }
diff --git a/server/protocol.def b/server/protocol.def
index 2fb8e2ec80..86efb01cc3 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -915,6 +915,7 @@ struct rawinput_device
     client_cpu_t cpu;              /* CPU that this process is running on */
     short int    debugger_present; /* process is being debugged */
     short int    debug_children;   /* inherit debugger to child processes */
+    VARARG(image,pe_image_info);   /* image info for main exe */
 @END
 
 
diff --git a/server/trace.c b/server/trace.c
index ca2cbb9074..c5c006ce41 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1389,6 +1389,7 @@ static void dump_get_process_info_reply( const struct get_process_info_reply *re
     dump_client_cpu( ", cpu=", &req->cpu );
     fprintf( stderr, ", debugger_present=%d", req->debugger_present );
     fprintf( stderr, ", debug_children=%d", req->debug_children );
+    dump_varargs_pe_image_info( ", image=", cur_size );
 }
 
 static void dump_get_process_vm_counters_request( const struct get_process_vm_counters_request *req )




More information about the wine-cvs mailing list