Rob Shearman : server: Change the get_dll_info server request to allow retrieving the image file name of a process .

Alexandre Julliard julliard at winehq.org
Tue Nov 20 10:54:57 CST 2007


Module: wine
Branch: master
Commit: bf2a35b78d93fc5762d711fc889aca51eb01ea0e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bf2a35b78d93fc5762d711fc889aca51eb01ea0e

Author: Rob Shearman <rob at codeweavers.com>
Date:   Tue Nov 20 09:30:50 2007 +0000

server: Change the get_dll_info server request to allow retrieving the image file name of a process.

Implement NtQueryInformationProcess(ProcessImageFileName).

---

 dlls/ntdll/process.c           |   22 +++++++++++++++++++++-
 dlls/ntdll/tests/info.c        |   36 ++++++++++++++++++++++++++++++++++++
 include/wine/server_protocol.h |    3 ++-
 server/process.c               |   15 ++++++++++++---
 server/protocol.def            |    1 +
 server/trace.c                 |    1 +
 6 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index b059c94..b5e6a64 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -137,7 +137,6 @@ NTSTATUS WINAPI NtQueryInformationProcess(
     UNIMPLEMENTED_INFO_CLASS(ProcessDeviceMap);
     UNIMPLEMENTED_INFO_CLASS(ProcessSessionInformation);
     UNIMPLEMENTED_INFO_CLASS(ProcessForegroundInformation);
-    UNIMPLEMENTED_INFO_CLASS(ProcessImageFileName);
     UNIMPLEMENTED_INFO_CLASS(ProcessLUIDDeviceMapsEnabled);
     UNIMPLEMENTED_INFO_CLASS(ProcessBreakOnTermination);
     UNIMPLEMENTED_INFO_CLASS(ProcessDebugObjectHandle);
@@ -309,6 +308,27 @@ NTSTATUS WINAPI NtQueryInformationProcess(
         }
         else ret = STATUS_INFO_LENGTH_MISMATCH;
         break;
+    case ProcessImageFileName:
+        SERVER_START_REQ(get_dll_info)
+        {
+            UNICODE_STRING *image_file_name_str = ProcessInformation;
+
+            req->handle = ProcessHandle;
+            req->base_address = NULL; /* main module */
+            wine_server_set_reply( req, image_file_name_str ? image_file_name_str + 1 : NULL,
+                                   ProcessInformationLength > sizeof(UNICODE_STRING) ? ProcessInformationLength - sizeof(UNICODE_STRING) : 0 );
+            ret = wine_server_call( req );
+            if (ret == STATUS_BUFFER_TOO_SMALL) ret = STATUS_INFO_LENGTH_MISMATCH;
+
+            len = sizeof(UNICODE_STRING) + reply->filename_len;
+            if (ret == STATUS_SUCCESS)
+            {
+                image_file_name_str->MaximumLength = image_file_name_str->Length = reply->filename_len;
+                image_file_name_str->Buffer = (PWSTR)(image_file_name_str + 1);
+            }
+        }
+        SERVER_END_REQ;
+        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 526c62e..08ab192 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -19,6 +19,7 @@
  */
 
 #include "ntdll_test.h"
+#include <winnls.h>
 
 static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
 static NTSTATUS (WINAPI * pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
@@ -754,6 +755,37 @@ static void test_query_process_handlecount(void)
     }
 }
 
+static void test_query_process_image_file_name(void)
+{
+    DWORD status;
+    ULONG ReturnLength;
+    UNICODE_STRING image_file_name;
+    void *buffer;
+    char *file_nameA;
+    INT len;
+
+    status = pNtQueryInformationProcess(NULL, ProcessImageFileName, &image_file_name, sizeof(image_file_name), NULL);
+    ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status);
+
+    status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName, &image_file_name, 2, &ReturnLength);
+    ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
+
+    status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName, &image_file_name, sizeof(image_file_name), &ReturnLength);
+    ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
+
+    buffer = HeapAlloc(GetProcessHeap(), 0, ReturnLength);
+    status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessImageFileName, buffer, ReturnLength, &ReturnLength);
+    ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
+    memcpy(&image_file_name, buffer, sizeof(image_file_name));
+    len = WideCharToMultiByte(CP_ACP, 0, image_file_name.Buffer, image_file_name.Length/sizeof(WCHAR), NULL, 0, NULL, NULL);
+    file_nameA = HeapAlloc(GetProcessHeap(), 0, len + 1);
+    WideCharToMultiByte(CP_ACP, 0, image_file_name.Buffer, image_file_name.Length/sizeof(WCHAR), file_nameA, len, NULL, NULL);
+    file_nameA[len] = '\0';
+    HeapFree(GetProcessHeap(), 0, buffer);
+    trace("process image file name: %s\n", file_nameA);
+    HeapFree(GetProcessHeap(), 0, file_nameA);
+}
+
 
 static void test_readvirtualmemory(void)
 {
@@ -886,6 +918,10 @@ START_TEST(info)
     trace("Starting test_query_process_handlecount()\n");
     test_query_process_handlecount();
 
+    /* 27 ProcessImageFileName */
+    trace("Starting test_query_process_image_file_name()\n");
+    test_query_process_image_file_name();
+
     /* belongs into it's own file */
     trace("Starting test_readvirtualmemory()\n");
     test_readvirtualmemory();
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 9c56089..5564ae3 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -672,6 +672,7 @@ struct get_dll_info_reply
     struct reply_header __header;
     size_t       size;
     void*        entry_point;
+    data_size_t  filename_len;
     /* VARARG(filename,unicode_str); */
 };
 
@@ -4905,6 +4906,6 @@ union generic_reply
     struct add_fd_completion_reply add_fd_completion_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 331
+#define SERVER_PROTOCOL_VERSION 332
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/process.c b/server/process.c
index 7031e14..e276dc4 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1129,16 +1129,25 @@ DECL_HANDLER(get_dll_info)
 
     if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
     {
-        struct process_dll *dll = find_process_dll( process, req->base_address );
+        struct process_dll *dll;
+
+        if (req->base_address)
+            dll = find_process_dll( process, req->base_address );
+        else /* NULL means main module */
+            dll = list_head( &process->dlls ) ?
+                LIST_ENTRY(list_head( &process->dlls ), struct process_dll, entry) : NULL;
 
         if (dll)
         {
             reply->size = dll->size;
             reply->entry_point = NULL; /* FIXME */
+            reply->filename_len = dll->namelen;
             if (dll->filename)
             {
-                data_size_t len = min( dll->namelen, get_reply_max_size() );
-                set_reply_data( dll->filename, len );
+                if (dll->namelen <= get_reply_max_size())
+                    set_reply_data( dll->filename, dll->namelen );
+                else
+                    set_error( STATUS_BUFFER_TOO_SMALL );
             }
         }
         else
diff --git a/server/protocol.def b/server/protocol.def
index dfb5d48..ae5f2ac 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -620,6 +620,7 @@ typedef union
 @REPLY
     size_t       size;          /* module size */
     void*        entry_point;
+    data_size_t  filename_len;    /* buffer len in bytes required to store filename */
     VARARG(filename,unicode_str); /* file name of module */
 @END
 
diff --git a/server/trace.c b/server/trace.c
index c580139..38a2991 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1004,6 +1004,7 @@ static void dump_get_dll_info_reply( const struct get_dll_info_reply *req )
 {
     fprintf( stderr, " size=%lu,", (unsigned long)req->size );
     fprintf( stderr, " entry_point=%p,", req->entry_point );
+    fprintf( stderr, " filename_len=%u,", req->filename_len );
     fprintf( stderr, " filename=" );
     dump_varargs_unicode_str( cur_size );
 }




More information about the wine-cvs mailing list