Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
August 2004
- 121 participants
- 732 messages
Re: CreateRemoteThread and related stuff (patch)
by Mike Hearn
Alexander Yaworsky wrote:
> Hello
>
> This is a basic framework. Not finished, not really tested -- just stable point. It does no harm for applications I'm using. I would
> be glad to get some comments and suggestions.
Looks OK to me but it's missing the most important part :) How are you
intending to make the client do a remote op - signals? ptrace? worker
thread? (I think Alexandre dislikes such worker threads, but it'd seem
to be the simplest/most understandable solution)
cool!
-mike
Aug. 23, 2004
Re: [QUARTZDRV] Preliminary support for native OS X graphics
by Mike Hearn
> Well, by 'the entire Wine development team' you mean Alexandre :-) ?
Not so, quite a few people work on the x11drv. For instance Alexs
winedesktop work, various NETWM interop patches from me, fullscreening
windows (not applied yet, but ...), system tray integration and so on.
Plus all the work to make OpenGL/DirectX go of course! :)
> I, for one, am happy that people are using our driver model to write new
> drivers as it could serve as a proof of concept that our driver model is
> sound (think about GL / Cairo / 'DBI engine' kind of drivers).... Heck, if
> we only wanted to support one driver, why do all the job of doing a clean
> separation and not include X11 in Wine's GDI directly ?
Well the driver model is lifted from Windows so I think it is sound. And
as for why we use separate drivers, well, when the DLL separation is
complete it means we can make a real Windows box display via X11 which
is Just Plain Cool :)
It also allows for portability to operating systems that don't have X11.
MacOS X *does* have X, in fact it's a modified XFree but with some
proprietary bits added. So I'm thinking the added effort is not worth
the gain. I'm not a Mac user though so who knows, maybe the extra
native-ness is worth all the pain ....
Aug. 23, 2004
CreateRemoteThread and related stuff (patch)
by Alexander Yaworsky
Hello
This is a basic framework. Not finished, not really tested -- just stable point. It does no harm for applications I'm using. I would
be glad to get some comments and suggestions.
This patch does not contain files generated by tools/make_requests
Index: dlls/kernel/kernel_private.h
===================================================================
RCS file: /home/wine/wine/dlls/kernel/kernel_private.h,v
retrieving revision 1.20
diff -u -r1.20 kernel_private.h
--- dlls/kernel/kernel_private.h 14 May 2004 21:43:18 -0000 1.20
+++ dlls/kernel/kernel_private.h 23 Aug 2004 09:28:39 -0000
@@ -91,4 +91,6 @@
} INSTANCEDATA;
#include "poppack.h"
+extern void CALLBACK THREAD_Start( void *ptr );
+
#endif
Index: dlls/kernel/process.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/process.c,v
retrieving revision 1.71
diff -u -r1.71 process.c
--- dlls/kernel/process.c 18 Aug 2004 21:03:32 -0000 1.71
+++ dlls/kernel/process.c 23 Aug 2004 09:29:03 -0000
@@ -894,6 +894,7 @@
{
req->peb = peb;
req->ldt_copy = &wine_ldt_copy;
+ req->kernel_thread_start = THREAD_Start;
if ((ret = !wine_server_call_err( req )))
{
main_exe_file = reply->exe_file;
Index: dlls/kernel/thread.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/thread.c,v
retrieving revision 1.19
diff -u -r1.19 thread.c
--- dlls/kernel/thread.c 7 Jul 2004 00:49:34 -0000 1.19
+++ dlls/kernel/thread.c 23 Aug 2004 09:29:08 -0000
@@ -90,13 +90,13 @@
*
* Start execution of a newly created thread. Does not return.
*/
-static void CALLBACK THREAD_Start( void *ptr )
+void CALLBACK THREAD_Start( void *ptr )
{
struct new_thread_info *info = ptr;
LPTHREAD_START_ROUTINE func = info->func;
void *arg = info->arg;
- RtlFreeHeap( GetProcessHeap(), 0, info );
+ VirtualFree( info, 0, MEM_RELEASE );
if (TRACE_ON(relay))
DPRINTF("%04lx:Starting thread (entryproc=%p)\n", GetCurrentThreadId(), func );
@@ -121,39 +121,8 @@
LPTHREAD_START_ROUTINE start, LPVOID param,
DWORD flags, LPDWORD id )
{
- HANDLE handle;
- CLIENT_ID client_id;
- NTSTATUS status;
- SIZE_T stack_reserve = 0, stack_commit = 0;
- struct new_thread_info *info;
-
- if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*info) )))
- {
- SetLastError( ERROR_NOT_ENOUGH_MEMORY );
- return 0;
- }
- info->func = start;
- info->arg = param;
-
- if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack;
- else stack_commit = stack;
-
- status = RtlCreateUserThread( GetCurrentProcess(), NULL, (flags & CREATE_SUSPENDED) != 0,
- NULL, stack_reserve, stack_commit,
- THREAD_Start, info, &handle, &client_id );
- if (status == STATUS_SUCCESS)
- {
- if (id) *id = (DWORD)client_id.UniqueThread;
- if (sa && (sa->nLength >= sizeof(*sa)) && sa->bInheritHandle)
- SetHandleInformation( handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT );
- }
- else
- {
- RtlFreeHeap( GetProcessHeap(), 0, info );
- SetLastError( RtlNtStatusToDosError(status) );
- handle = 0;
- }
- return handle;
+ return CreateRemoteThread( GetCurrentProcess(),
+ sa, stack, start, param, flags, id );
}
@@ -168,16 +137,68 @@
* Success: Handle to the new thread.
* Failure: NULL. Use GetLastError() to find the error cause.
*
- * BUGS
- * Unimplemented
*/
HANDLE WINAPI CreateRemoteThread( HANDLE hProcess, SECURITY_ATTRIBUTES *sa, SIZE_T stack,
LPTHREAD_START_ROUTINE start, LPVOID param,
DWORD flags, LPDWORD id )
{
- FIXME("(): stub, Write Me.\n");
+ extern BOOL __wine_is_current_process( HANDLE hProcess );
+
+ HANDLE handle;
+ CLIENT_ID client_id;
+ NTSTATUS status;
+ SIZE_T stack_reserve = 0, stack_commit = 0;
+ struct new_thread_info *info;
+ PRTL_THREAD_START_ROUTINE start_addr;
+
+ if (!(info = VirtualAllocEx( hProcess, NULL, sizeof(*info),
+ MEM_COMMIT, PAGE_READWRITE )))
+ return 0;
+
+ if( __wine_is_current_process( hProcess ) )
+ {
+ info->func = start;
+ info->arg = param;
+ start_addr = (void*) THREAD_Start;
+ }
+ else
+ {
+ struct new_thread_info local_info;
+ DWORD written;
+
+ local_info.func = start;
+ local_info.arg = param;
+ if( ! WriteProcessMemory( hProcess, &info, &local_info,
+ sizeof(struct new_thread_info), &written ) )
+ return NULL;
+ SERVER_START_REQ( get_kernel_thread_start )
+ {
+ req->handle = hProcess;
+ if (!(status = wine_server_call( req )))
+ start_addr = (PRTL_THREAD_START_ROUTINE) reply->address;
+ }
+ SERVER_END_REQ;
+ if (status)
+ goto error;
+ }
+
+ if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack;
+ else stack_commit = stack;
+
+ status = RtlCreateUserThread( hProcess, NULL, (flags & CREATE_SUSPENDED) != 0,
+ NULL, stack_reserve, stack_commit,
+ start_addr, info, &handle, &client_id );
+ if (status)
+ goto error;
+
+ if (id) *id = (DWORD)client_id.UniqueThread;
+ if (sa && (sa->nLength >= sizeof(*sa)) && sa->bInheritHandle)
+ SetHandleInformation( handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT );
+ return handle;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+error:
+ VirtualFreeEx( hProcess, info, 0, MEM_RELEASE );
+ SetLastError( RtlNtStatusToDosError(status) );
return NULL;
}
Index: dlls/ntdll/ntdll.spec
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/ntdll.spec,v
retrieving revision 1.162
diff -u -r1.162 ntdll.spec
--- dlls/ntdll/ntdll.spec 18 Aug 2004 00:04:58 -0000 1.162
+++ dlls/ntdll/ntdll.spec 23 Aug 2004 09:29:22 -0000
@@ -1135,6 +1135,9 @@
@ cdecl wine_nt_to_unix_file_name(ptr ptr long long)
@ cdecl __wine_init_windows_dir(wstr wstr)
+# remote operations
+@ cdecl __wine_is_current_process(long)
+
################################################################
# Wine dll separation hacks, these will go away, don't use them
#
Index: dlls/ntdll/ntdll_misc.h
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/ntdll_misc.h,v
retrieving revision 1.48
diff -u -r1.48 ntdll_misc.h
--- dlls/ntdll/ntdll_misc.h 15 Jul 2004 22:07:21 -0000 1.48
+++ dlls/ntdll/ntdll_misc.h 23 Aug 2004 09:29:22 -0000
@@ -98,4 +98,9 @@
extern int ntdll_wcstoumbs(DWORD flags, const WCHAR* src, int srclen, char* dst, int dstlen,
const char* defchar, int *used );
+/* remote operations */
+extern BOOL __wine_is_current_process( HANDLE handle );
+extern NTSTATUS remote_op( HANDLE process, int type,
+ void* params, int params_size, void* result, int* result_size );
+
#endif
Index: dlls/ntdll/thread.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/thread.c,v
retrieving revision 1.20
diff -u -r1.20 thread.c
--- dlls/ntdll/thread.c 13 Aug 2004 23:20:27 -0000 1.20
+++ dlls/ntdll/thread.c 23 Aug 2004 09:29:26 -0000
@@ -215,6 +215,29 @@
ULONG size;
int request_pipe[2];
NTSTATUS status;
+
+ if( ! __wine_is_current_process( process ) )
+ {
+ struct remote_op_params_new_thread op_params;
+ struct remote_op_result_new_thread op_result;
+ int result_size = sizeof(struct remote_op_result_new_thread);
+
+ op_params.suspend = suspended;
+ op_params.stack_addr = stack_addr;
+ op_params.stack_reserve = stack_reserve;
+ op_params.stack_commit = stack_commit;
+ op_params.start = start;
+ op_params.param = param;
+ status = remote_op( process, REMOTE_OP_NEW_THREAD,
+ &op_params, sizeof(op_params),
+ &op_result, &result_size );
+ if (status)
+ return status;
+
+ handle = op_result.handle;
+ tid = op_result.tid;
+ goto success;
+ }
if (pipe( request_pipe ) == -1) return STATUS_TOO_MANY_OPENED_FILES;
fcntl( request_pipe[1], F_SETFD, 1 ); /* set close on exec flag */
@@ -284,6 +307,7 @@
goto error;
}
+success:
if (id) id->UniqueThread = (HANDLE)tid;
if (handle_ptr) *handle_ptr = handle;
else NtClose( handle );
Index: dlls/ntdll/virtual.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/virtual.c,v
retrieving revision 1.38
diff -u -r1.38 virtual.c
--- dlls/ntdll/virtual.c 18 Aug 2004 00:04:58 -0000 1.38
+++ dlls/ntdll/virtual.c 23 Aug 2004 09:29:36 -0000
@@ -1024,11 +1024,11 @@
/***********************************************************************
- * is_current_process
+ * __wine_is_current_process
*
* Check whether a process handle is for the current process.
*/
-static BOOL is_current_process( HANDLE handle )
+BOOL __wine_is_current_process( HANDLE handle )
{
BOOL ret = FALSE;
@@ -1045,6 +1045,53 @@
/***********************************************************************
+ * remote_op
+ *
+ */
+NTSTATUS remote_op( HANDLE process, int type,
+ void* params, int params_size, void* result, int* result_size )
+{
+ HANDLE event;
+ NTSTATUS status, remote_status;
+
+ /* send params */
+ SERVER_START_REQ( remote_operation )
+ {
+ req->handle = process;
+ req->type = type;
+ if (params) wine_server_add_data( req, params, params_size );
+ if (!(status = wine_server_call( req )))
+ event = reply->event;
+ }
+ SERVER_END_REQ;
+ if (status)
+ return status;
+
+ /* wait for completion */
+ status = NtWaitForMultipleObjects( 1, &event, FALSE, FALSE, NULL );
+ NtClose( event );
+ if (HIWORD(status))
+ return status;
+
+ /* get result */
+ remote_status = 0; /* make compiler happy */
+ SERVER_START_REQ( remote_operation_result )
+ {
+ wine_server_set_reply( req, result, *result_size );
+ if (!(status = wine_server_call( req )))
+ {
+ remote_status = reply->status;
+ if (result)
+ *result_size = wine_server_reply_size( reply );
+ }
+ }
+ SERVER_END_REQ;
+
+ return status? status : remote_status;
+}
+
+
+/***********************************************************************
* virtual_init
*/
void virtual_init(void)
@@ -1158,19 +1205,38 @@
{
void *base;
BYTE vprot;
- DWORD size = *size_ptr;
+ DWORD size;
NTSTATUS status = STATUS_SUCCESS;
struct file_view *view;
- if (!is_current_process( process ))
- {
- ERR("Unsupported on other process\n");
- return STATUS_ACCESS_DENIED;
- }
+ TRACE("%p %p %p %p %lx %08lx\n", process, ret, addr, size_ptr, type, protect );
+
+ /* sanity check */
+ if (NULL == ret || NULL == size_ptr) return STATUS_INVALID_PARAMETER;
+
+ TRACE("size=%08lx\n", *size_ptr );
+ if (!(size = *size_ptr)) return STATUS_INVALID_PARAMETER;
- TRACE("%p %08lx %lx %08lx\n", addr, size, type, protect );
+ if (!__wine_is_current_process( process ))
+ {
+ struct remote_op_params_vm_alloc alloc_params;
+ struct remote_op_result_vm_alloc alloc_result;
+ int result_size = sizeof(struct remote_op_result_vm_alloc);
- if (!size) return STATUS_INVALID_PARAMETER;
+ alloc_params.addr = addr;
+ alloc_params.size = size;
+ alloc_params.type = type;
+ alloc_params.protect = protect;
+ status = remote_op( process, REMOTE_OP_VM_ALLOC,
+ &alloc_params, sizeof(alloc_params),
+ &alloc_result, &result_size );
+ if (!status)
+ {
+ *ret = alloc_result.base;
+ *size_ptr = alloc_result.size;
+ }
+ return status;
+ }
/* Round parameters to a page boundary */
@@ -1265,16 +1331,37 @@
FILE_VIEW *view;
char *base;
NTSTATUS status = STATUS_SUCCESS;
- LPVOID addr = *addr_ptr;
- DWORD size = *size_ptr;
+ LPVOID addr;
+ DWORD size;
- if (!is_current_process( process ))
+ TRACE("%p %p %p %lx\n", process, addr_ptr, size_ptr, type );
+
+ /* sanity check */
+ if (NULL == addr_ptr || NULL == size_ptr) return ERROR_INVALID_PARAMETER;
+
+ addr = *addr_ptr;
+ size = *size_ptr;
+ TRACE("addr=%p size=%08lx\n", addr, size );
+
+ if (!__wine_is_current_process( process ))
{
- ERR("Unsupported on other process\n");
- return STATUS_ACCESS_DENIED;
- }
+ struct remote_op_params_vm_free free_params;
+ struct remote_op_result_vm_free free_result;
+ int result_size = sizeof(struct remote_op_result_vm_free);
- TRACE("%p %08lx %lx\n", addr, size, type );
+ free_params.addr = addr;
+ free_params.size = size;
+ free_params.type = type;
+ status = remote_op( process, REMOTE_OP_VM_FREE,
+ &free_params, sizeof(free_params),
+ &free_result, &result_size );
+ if (!status)
+ {
+ *addr_ptr = free_result.base;
+ *size_ptr = free_result.size;
+ }
+ return status;
+ }
/* Fix the parameters */
@@ -1341,16 +1428,38 @@
char *base;
UINT i;
BYTE vprot, *p;
- DWORD prot, size = *size_ptr;
- LPVOID addr = *addr_ptr;
+ DWORD prot, size;
+ LPVOID addr;
- if (!is_current_process( process ))
+ TRACE("%p %p %p %08lx %p\n", process, addr_ptr, size_ptr, new_prot, old_prot );
+
+ /* sanity check */
+ if (NULL == addr_ptr || NULL == size_ptr) return ERROR_INVALID_PARAMETER;
+
+ addr = *addr_ptr;
+ size = *size_ptr;
+ TRACE("addr=%p size=%08lx\n", addr, size );
+
+ if (!__wine_is_current_process( process ))
{
- ERR("Unsupported on other process\n");
- return STATUS_ACCESS_DENIED;
- }
+ struct remote_op_params_vm_protect protect_params;
+ struct remote_op_result_vm_protect protect_result;
+ int result_size = sizeof(struct remote_op_result_vm_protect);
- TRACE("%p %08lx %08lx\n", addr, size, new_prot );
+ protect_params.addr = addr;
+ protect_params.size = size;
+ protect_params.new_prot = new_prot;
+ status = remote_op( process, REMOTE_OP_VM_PROTECT,
+ &protect_params, sizeof(protect_params),
+ &protect_result, &result_size );
+ if (!status)
+ {
+ *addr_ptr = protect_result.base;
+ *size_ptr = protect_result.size;
+ if (old_prot) *old_prot = protect_result.old_prot;
+ }
+ return status;
+ }
/* Fix the parameters */
@@ -1409,15 +1518,40 @@
UINT size = 0;
MEMORY_BASIC_INFORMATION *info = buffer;
+ TRACE("%p %p %d %p %lu %p\n", process, addr, info_class, buffer, len, res_len );
+
+ /* sanity check */
+ if (NULL == buffer) return ERROR_INVALID_PARAMETER;
+
+ if (!__wine_is_current_process( process ))
+ {
+ struct remote_op_params_vm_query *query_params;
+ int result_size = len;
+ NTSTATUS status;
+
+ query_params = (struct remote_op_params_vm_query*)
+ RtlAllocateHeap( GetProcessHeap(), 0, sizeof(struct remote_op_params_vm_query) + len );
+ if (!query_params)
+ return STATUS_NO_MEMORY;
+
+ query_params->addr = (void*) addr;
+ query_params->info_class = info_class;
+ if (len) memcpy( query_params + 1, buffer, len );
+ status = remote_op( process, REMOTE_OP_VM_QUERY,
+ query_params, sizeof(struct remote_op_params_vm_query) + len,
+ buffer, &result_size );
+ RtlFreeHeap( GetProcessHeap(), 0, query_params );
+ if (!status)
+ if (res_len) *res_len = result_size;
+ return status;
+ }
+
if (info_class != MemoryBasicInformation) return STATUS_INVALID_INFO_CLASS;
if (ADDRESS_SPACE_LIMIT && addr >= ADDRESS_SPACE_LIMIT)
return STATUS_WORKING_SET_LIMIT_RANGE;
- if (!is_current_process( process ))
- {
- ERR("Unsupported on other process\n");
- return STATUS_ACCESS_DENIED;
- }
+ /* sanity check */
+ if (len < sizeof(MEMORY_BASIC_INFORMATION)) return ERROR_INVALID_PARAMETER;
base = ROUND_ADDR( addr, page_mask );
@@ -1497,10 +1631,10 @@
*/
NTSTATUS WINAPI NtLockVirtualMemory( HANDLE process, PVOID *addr, ULONG *size, ULONG unknown )
{
- if (!is_current_process( process ))
+ /* FIXME */
+ if (!__wine_is_current_process( process ))
{
- ERR("Unsupported on other process\n");
- return STATUS_ACCESS_DENIED;
+ return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
@@ -1512,10 +1646,10 @@
*/
NTSTATUS WINAPI NtUnlockVirtualMemory( HANDLE process, PVOID *addr, ULONG *size, ULONG unknown )
{
- if (!is_current_process( process ))
+ /* FIXME */
+ if (!__wine_is_current_process( process ))
{
- ERR("Unsupported on other process\n");
- return STATUS_ACCESS_DENIED;
+ return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
@@ -1608,14 +1742,39 @@
HANDLE shared_file;
BOOL removable = FALSE;
- if (!is_current_process( process ))
- {
- ERR("Unsupported on other process\n");
- return STATUS_ACCESS_DENIED;
- }
+ TRACE("%p %p %p %lu %lu %p %p %d %lu %lx\n", handle, process, addr_ptr, zero_bits,
+ commit_size, offset, size_ptr, inherit, alloc_type, protect );
- TRACE("handle=%p addr=%p off=%lx%08lx size=%x access=%lx\n",
- handle, *addr_ptr, offset->u.HighPart, offset->u.LowPart, size, protect );
+ /* sanity check */
+ if (NULL == addr_ptr || NULL == size_ptr || NULL == offset) return ERROR_INVALID_PARAMETER;
+
+ TRACE("addr=%p off=%lx%08lx\n", *addr_ptr, offset->u.HighPart, offset->u.LowPart );
+
+ if (!__wine_is_current_process( process ))
+ {
+ struct remote_op_params_vm_map map_params;
+ struct remote_op_result_vm_map map_result;
+ int result_size = sizeof(struct remote_op_result_vm_map);
+
+ map_params.addr = *addr_ptr;
+ map_params.zero_bits = zero_bits;
+ map_params.commit_size = commit_size;
+ map_params.offset_low = offset->u.LowPart;
+ map_params.offset_high = offset->u.HighPart;
+ map_params.size = *size_ptr;
+ map_params.inherit = inherit;
+ map_params.alloc_type = alloc_type;
+ map_params.protect = protect;
+ res = remote_op( process, REMOTE_OP_VM_MAP,
+ &map_params, sizeof(map_params),
+ &map_result, &result_size );
+ if (!res)
+ {
+ *addr_ptr = map_result.base;
+ *size_ptr = map_result.size;
+ }
+ return res;
+ }
/* Check parameters */
@@ -1764,11 +1923,14 @@
NTSTATUS status = STATUS_INVALID_PARAMETER;
void *base = ROUND_ADDR( addr, page_mask );
- if (!is_current_process( process ))
+ TRACE("%p %p base=%p\n", process, addr, base );
+
+ if (!__wine_is_current_process( process ))
{
- ERR("Unsupported on other process\n");
- return STATUS_ACCESS_DENIED;
+ return remote_op( process, REMOTE_OP_VM_UNMAP,
+ &addr, sizeof(addr), NULL, NULL );
}
+
RtlEnterCriticalSection( &csVirtual );
if ((view = VIRTUAL_FindView( base )) && (base == view->base))
{
@@ -1789,13 +1951,38 @@
{
FILE_VIEW *view;
NTSTATUS status = STATUS_SUCCESS;
- void *addr = ROUND_ADDR( *addr_ptr, page_mask );
+ void *addr;
+ ULONG size;
- if (!is_current_process( process ))
+ TRACE("%p %p %p %lx\n", process, addr_ptr, size_ptr, unknown );
+
+ /* sanity check */
+ if (NULL == addr_ptr || NULL == size_ptr) return ERROR_INVALID_PARAMETER;
+
+ size = *size_ptr;
+ TRACE("addr=%p size=%08lx\n", *addr_ptr, size );
+
+ if (!__wine_is_current_process( process ))
{
- ERR("Unsupported on other process\n");
- return STATUS_ACCESS_DENIED;
+ struct remote_op_params_vm_flush flush_params;
+ struct remote_op_result_vm_flush flush_result;
+ int result_size = sizeof(struct remote_op_result_vm_flush);
+
+ flush_params.addr = (void*) *addr_ptr;
+ flush_params.size = size;
+ flush_params.unknown = unknown;
+ status = remote_op( process, REMOTE_OP_VM_FLUSH,
+ &flush_params, sizeof(flush_params),
+ &flush_result, &result_size );
+ if (!status)
+ {
+ *addr_ptr = flush_result.base;
+ if (!*size_ptr) *size_ptr = flush_result.size;
+ }
+ return status;
}
+
+ addr = ROUND_ADDR( *addr_ptr, page_mask );
RtlEnterCriticalSection( &csVirtual );
if (!(view = VIRTUAL_FindView( addr ))) status = STATUS_INVALID_PARAMETER;
else
Index: server/process.c
===================================================================
RCS file: /home/wine/wine/server/process.c,v
retrieving revision 1.117
diff -u -r1.117 process.c
--- server/process.c 14 Jun 2004 17:02:00 -0000 1.117
+++ server/process.c 23 Aug 2004 09:30:22 -0000
@@ -45,6 +45,7 @@
#include "request.h"
#include "console.h"
#include "user.h"
+#include "object.h"
/* process structure */
@@ -972,6 +973,7 @@
reply->info_size = 0;
current->process->peb = req->peb;
current->process->ldt_copy = req->ldt_copy;
+ current->process->kernel_thread_start = req->kernel_thread_start;
current->process->startup_info = init_process( reply );
}
@@ -1188,5 +1190,136 @@
reply->event = alloc_handle( current->process, process->idle_event,
EVENT_ALL_ACCESS, 0 );
release_object( process );
+ }
+}
+
+/* return address of internal thread start function in kernel32 */
+DECL_HANDLER(get_kernel_thread_start)
+{
+ struct process *process;
+
+ /* because this is used for CreateRemoteThread,
+ required access rights must be the same
+ */
+ if ((process = get_process_from_handle( req->handle,
+ PROCESS_CREATE_THREAD
+ | PROCESS_QUERY_INFORMATION
+ | PROCESS_VM_OPERATION
+ | PROCESS_VM_READ | PROCESS_VM_WRITE )))
+ {
+ reply->address = process->kernel_thread_start;
+ release_object( process );
+ }
+}
+
+/* Accept parameters for remote operation and start it */
+DECL_HANDLER(remote_operation)
+{
+ int access;
+ struct process *process;
+ struct event *event;
+
+ /* define required access rights */
+ switch( req->type )
+ {
+ case REMOTE_OP_NEW_THREAD:
+ access = PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION
+ | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE;
+ break;
+ case REMOTE_OP_VM_ALLOC: access = PROCESS_VM_OPERATION; break;
+ case REMOTE_OP_VM_FREE: access = PROCESS_VM_OPERATION; break;
+ case REMOTE_OP_VM_PROTECT: access = PROCESS_VM_OPERATION; break;
+ case REMOTE_OP_VM_QUERY: access = PROCESS_QUERY_INFORMATION; break;
+ case REMOTE_OP_VM_MAP: access = PROCESS_VM_OPERATION; break;
+ case REMOTE_OP_VM_UNMAP: access = PROCESS_VM_OPERATION; break;
+ case REMOTE_OP_VM_FLUSH: access = PROCESS_VM_OPERATION; break; /* FIXME: is access right? */
+ default:
+ set_error( STATUS_INVALID_PARAMETER );
+ return;
+ }
+
+ /* get process object */
+ if (!(process = get_process_from_handle( req->handle, access ))) return;
+
+ /* dispose result data buffer if allocated */
+ if (current->result_data)
+ {
+ free( current->result_data );
+ current->result_data = NULL;
+ }
+
+ /* create event object */
+ reply->event = NULL;
+ if (current->result_event)
+ {
+ release_object( current->result_event );
+ current->result_event = NULL;
+ }
+ if (!(event = create_event( NULL, 0, 1, 0 )))
+ goto error;
+
+ if (!(reply->event = alloc_handle( current->process, event, EVENT_ALL_ACCESS, FALSE )))
+ goto error;
+
+ /* FIXME: pass somehow operation type, params and originator thread id
+ for some thread in the process and force execution of operation */
+ set_error( STATUS_NOT_IMPLEMENTED );
+
+ /* save event object in thread structure for future set operation;
+ we do not release it here */
+ current->result_event = event;
+ release_object( process );
+ return;
+
+error:
+ if (reply->event) close_handle( current->process, reply->event, NULL );
+ if (event) release_object( event );
+ release_object( process );
+}
+
+/* save result of remote operation and wakeup originator */
+DECL_HANDLER(remote_operation_complete)
+{
+ struct thread *thread = get_thread_from_id( req->originator );
+
+ if (!thread) return;
+
+ /* save status */
+ thread->remote_status = req->status;
+
+ /* allocate buffer for result data, if required */
+ if (thread->result_data)
+ {
+ free( thread->result_data );
+ thread->result_data = NULL;
+ }
+ if ((thread->result_size = get_req_data_size()))
+ {
+ if ((thread->result_data = mem_alloc( thread->result_size )))
+ memcpy( thread->result_data, get_req_data(), thread->result_size );
+ else
+ thread->remote_status = get_error();
+ }
+
+ /* set event */
+ if (thread->result_event)
+ {
+ set_event( thread->result_event );
+ release_object( thread->result_event );
+ thread->result_event = NULL;
+ }
+ release_object( thread );
+}
+
+/* return status and result data from remote opertaion */
+DECL_HANDLER(remote_operation_result)
+{
+ reply->status = current->remote_status;
+
+ if (current->result_data)
+ {
+ void *result = current->result_data;
+ current->result_data = NULL;
+ set_reply_data_ptr( result, current->result_size );
}
}
Index: server/process.h
===================================================================
RCS file: /home/wine/wine/server/process.h,v
retrieving revision 1.42
diff -u -r1.42 process.h
--- server/process.h 10 Dec 2003 04:08:06 -0000 1.42
+++ server/process.h 23 Aug 2004 09:30:24 -0000
@@ -79,6 +79,8 @@
struct process_dll exe; /* main exe file */
void *peb; /* PEB address in client address space */
void *ldt_copy; /* pointer to LDT copy in client addr space */
+ void *kernel_thread_start; /* addr of internal kernel32 thread routine */
+ /* (in client address space) */
};
struct process_snapshot
Index: server/protocol.def
===================================================================
RCS file: /home/wine/wine/server/protocol.def,v
retrieving revision 1.110
diff -u -r1.110 protocol.def
--- server/protocol.def 18 Aug 2004 00:04:58 -0000 1.110
+++ server/protocol.def 23 Aug 2004 09:30:45 -0000
@@ -232,6 +232,7 @@
@REQ(init_process)
void* peb; /* addr of PEB */
void* ldt_copy; /* addr of LDT copy */
+ void* kernel_thread_start; /* addr of internal kernel32 thread routine */
@REPLY
int create_flags; /* creation flags */
unsigned int server_start; /* server start time (GetTickCount) */
@@ -2166,3 +2167,133 @@
#define SET_GLOBAL_SHELL_WINDOWS 0x01 /* set both main shell and listview windows */
#define SET_GLOBAL_PROGMAN_WINDOW 0x02
#define SET_GLOBAL_TASKMAN_WINDOW 0x04
+
+/* Get address of kernel32 internal THREAD_Start function */
+(a)REQ(get_kernel_thread_start)
+ obj_handle_t handle; /* process handle */
+(a)REPLY
+ void* address;
+(a)END
+
+/* Accept parameters for remote operation and start it */
+(a)REQ(remote_operation)
+ obj_handle_t handle; /* process handle */
+ int type; /* operation type (see below) */
+ VARARG(data,bytes); /* operation parameters (see below) */
+(a)REPLY
+ obj_handle_t event; /* originator waits for it */
+(a)END
+enum remote_op_type
+{
+ REMOTE_OP_NEW_THREAD,
+ REMOTE_OP_VM_ALLOC,
+ REMOTE_OP_VM_FREE,
+ REMOTE_OP_VM_PROTECT,
+ REMOTE_OP_VM_QUERY,
+ REMOTE_OP_VM_MAP,
+ REMOTE_OP_VM_UNMAP,
+ REMOTE_OP_VM_FLUSH
+};
+
+/* Notify that remote operation has been complete */
+(a)REQ(remote_operation_complete)
+ thread_id_t originator; /* originator thread id */
+ unsigned int status; /* operation status */
+ VARARG(data,bytes); /* operation result data (see below) */
+(a)END
+
+/* Get result of remote opertaion */
+(a)REQ(remote_operation_result)
+(a)REPLY
+ unsigned int status; /* operation status */
+ VARARG(data,bytes); /* operation result data (see below) */
+(a)END
+
+struct remote_op_params_new_thread
+{
+ int suspend;
+ void *stack_addr;
+ unsigned int stack_reserve;
+ unsigned int stack_commit;
+ void *start;
+ void *param;
+};
+struct remote_op_result_new_thread
+{
+ obj_handle_t handle;
+ thread_id_t tid;
+};
+
+struct remote_op_params_vm_alloc
+{
+ void *addr;
+ unsigned long size;
+ unsigned long type;
+ unsigned long protect;
+};
+struct remote_op_result_vm_alloc
+{
+ void *base;
+ unsigned long size;
+};
+
+struct remote_op_params_vm_free
+{
+ void *addr;
+ unsigned long size;
+ unsigned long type;
+};
+struct remote_op_result_vm_free
+{
+ void *base;
+ unsigned long size;
+};
+
+struct remote_op_params_vm_protect
+{
+ void *addr;
+ unsigned long size;
+ unsigned long new_prot;
+};
+struct remote_op_result_vm_protect
+{
+ void *base;
+ unsigned long size;
+ unsigned long old_prot;
+};
+
+struct remote_op_params_vm_query
+{
+ void *addr;
+ int info_class;
+};
+
+struct remote_op_params_vm_map
+{
+ void *addr;
+ unsigned long zero_bits;
+ unsigned long commit_size;
+ unsigned long offset_low;
+ long offset_high;
+ unsigned long size;
+ int inherit;
+ unsigned long alloc_type;
+ unsigned long protect;
+};
+struct remote_op_result_vm_map
+{
+ void *base;
+ unsigned long size;
+};
+
+struct remote_op_params_vm_flush
+{
+ void *addr;
+ unsigned long size;
+ unsigned long unknown;
+};
+struct remote_op_result_vm_flush
+{
+ void *base;
+ unsigned long size;
+};
Index: server/thread.c
===================================================================
RCS file: /home/wine/wine/server/thread.c,v
retrieving revision 1.103
diff -u -r1.103 thread.c
--- server/thread.c 27 Oct 2003 22:10:22 -0000 1.103
+++ server/thread.c 23 Aug 2004 09:30:54 -0000
@@ -142,6 +142,8 @@
thread->suspend = 0;
thread->creation_time = time(NULL);
thread->exit_time = 0;
+ thread->result_data = NULL;
+ thread->result_event = NULL;
for (i = 0; i < MAX_INFLIGHT_FDS; i++)
thread->inflight[i].server = thread->inflight[i].client = -1;
@@ -210,6 +212,8 @@
if (thread->request_fd) release_object( thread->request_fd );
if (thread->reply_fd) release_object( thread->reply_fd );
if (thread->wait_fd) release_object( thread->wait_fd );
+ if (thread->result_data) free( thread->result_data );
+ if (thread->result_event) release_object( thread->result_event );
free_msg_queue( thread );
cleanup_clipboard_thread(thread);
destroy_thread_windows( thread );
@@ -226,6 +230,8 @@
thread->request_fd = NULL;
thread->reply_fd = NULL;
thread->wait_fd = NULL;
+ thread->result_data = NULL;
+ thread->result_event = NULL;
if (thread == booting_thread) /* killing booting thread */
{
Index: server/thread.h
===================================================================
RCS file: /home/wine/wine/server/thread.h,v
retrieving revision 1.56
diff -u -r1.56 thread.h
--- server/thread.h 10 Dec 2003 01:12:18 -0000 1.56
+++ server/thread.h 23 Aug 2004 09:30:56 -0000
@@ -94,6 +94,10 @@
time_t creation_time; /* Thread creation time */
time_t exit_time; /* Thread exit time */
struct token *token; /* security token associated with this thread */
+ unsigned int remote_status; /* error code from remote operation */
+ void *result_data; /* result data from remote operation */
+ int result_size; /* size of result data */
+ struct event *result_event; /* originator of remote operation waits for it */
};
struct thread_snapshot
Aug. 23, 2004
Re: [QUARTZDRV] Preliminary support for native OS X graphics
by Lionel Ulmer
> Is it? Given the complexity and amount of work done on the x11drv it
> seems silly to duplicate all that effort. The x11drv is worked on by the
> entire Wine development team right now, so any quartzdrv would always be
> playing catchup. Well, if they want to spend their time doing that, fine
> by me ...
Well, by 'the entire Wine development team' you mean Alexandre :-) ?
I, for one, am happy that people are using our driver model to write new
drivers as it could serve as a proof of concept that our driver model is
sound (think about GL / Cairo / 'DBI engine' kind of drivers).... Heck, if
we only wanted to support one driver, why do all the job of doing a clean
separation and not include X11 in Wine's GDI directly ?
Lionel
--
Lionel Ulmer - http://www.bbrox.org/
Aug. 23, 2004
Re: A new regression
by Mike Hearn
http://www.cyborgname.com/cyborger.cgi?acronym=JULLIARD&robotchoice=governo…
;)
But seriously, that patch changed a lot of very important core code in
Wine, and the relevant math is hideously complicated (in fact nobody
does it anymore, we all just copy/paste the X server code). There have
already been several regressions caused by that fixed, the best way to
get more fixed is to describe exactly what you see (with screenshots, if
possible).
If the app isn't free, that's especially critical.
Ivan Leo Puoti wrote:
> For those of you who don't belive A.J. is a human, he does introduce regressions
> from time to time.
> This patch
> http://www.winehq.com/hypermail/wine-cvs/2004/06/0196.html
> Has broken this app
> http://www.anim8or.com
> and at least one user has complained about this regression.
>
> Ivan.
Aug. 23, 2004
Re: MSTS installer - files inside setupenu.dll
by Mike Hearn
What were th efile paths it was looking for?
Frank Eising wrote:
> I am trying to get the Train SImulator setup working. Last time I debugged it I found that the setup looks for jpeg images in a certain directory to set up the setup menu. They are not found, because those files are non-existent on the cdrom. They are inside setupenu.dll.
> Anyone knows what kind of thing needs to be implemented, in order to make files inside a dll accessable by wine? I could not find any errors in the debug messages referring to it.
>
> Frank
>
Aug. 23, 2004
Re: [QUARTZDRV] Preliminary support for native OS X graphics
by Mike Hearn
Roderick Colenbrander wrote:
> Quartz support is ofcourse great but without a patch it isn't very usefull
> ;)
Is it? Given the complexity and amount of work done on the x11drv it
seems silly to duplicate all that effort. The x11drv is worked on by the
entire Wine development team right now, so any quartzdrv would always be
playing catchup. Well, if they want to spend their time doing that, fine
by me ...
Aug. 23, 2004
Re: Optimize Critical Section Functions
by Mike Hearn
> Win2k - 1000ms
> Wine w/ patch - 1346ms
> Wine w/o patch - 1294ms
That's a fascinatingly round number for Win2K, isn't it?
I suspect the slowness is caused by the involution: any cycles saved
from the branch hinting is lost in the double-not.
thanks -mike
Aug. 23, 2004
Re: Take monospace fonts into account in default font selectionalgorithm.
by Mike Hearn
Mike Hearn wrote:
>>This also wouldn't work as you expect. The way to create a fixed
>>pitch font is to use FIXED_PITCH not MONO_FONT. Which app was
>>setting this flag?
>
>
> There wasn't one, I assumed MONO_FONT meant monospace, which is what I
> was trying to stop Wine selecting. I didn't have MSDN handy at the time
> though so it was basically just a guess ...
>
If I resubmit this patch using FIXED_PITCH not MONO_FONT (which seems to
be undocumented) would that be correct?
/me wishing he had MSDN on his laptop ...
Aug. 23, 2004
A new regression
by Ivan Leo Puoti
For those of you who don't belive A.J. is a human, he does introduce regressions
from time to time.
This patch
http://www.winehq.com/hypermail/wine-cvs/2004/06/0196.html
Has broken this app
http://www.anim8or.com
and at least one user has complained about this regression.
Ivan.
Aug. 23, 2004