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