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: RICHEDIT: use buffers rather than linked lists for input and out buffers
by Ge van Geldorp
> From: Mike McCormack
>
> This patch writes the output of the RTF parser into the edit
> control in
> 1024 byte chunks, and reads the input via a char[1024] buffer, rather
> than a linked list of single characters.
Not that it should matter very much, but the MS control always seems to
read the input in 4096 byte chunks. Maybe you could enlarge InputBuffer
from 0x400 to 0x1000?
Ge van Geldorp.
Aug. 27, 2004
Re: CreateRemoteThread and related stuff (patch)
by Dmitry Timoshkov
"Roger Olson" <u60(a)comcast.net> wrote:
> I am wondering why delete the CreateThread() code and refer all such
> requests
> to CreateRemoteThread()? It would appear to me that retaining the
> CreateThread()
> code in addition to and compliant with the patch changes would be more
> expeditious
> for apps that do not need a call for Remote Operations.
Because if an optimization is needed regarding taking into account
current (local) process CreateRemoteThread can do it internally,
and of course avoiding code duplication. That's how for instance
VirtualAlloc is implemented via a call to VirtualAllocEx.
--
Dmitry.
Aug. 27, 2004
Re: Localizing shell32/shv_item_cmenu.c:ISvItemCm_fnQueryContextMenu
by Mike Hearn
> if I right click in the file open dialog, select a file and right click,
> I get a context menu with English menu items.
> Expected: I'll get a localized menu (e.g. in German).
>
> Any idea how to get a localized version?
You'd have to internationalize that piece of code. As you already found,
it'd need to be unicodified :) and then you can use the Win32 string
loading APIs to get the right strings.
Unfortunately the Win32 i10n APIs are far less convenient than gettext,
but there are examples dotted around the source. I think kernel/user has
some?
Feel free to write a patch ...
Aug. 27, 2004
Re: X86/PPC linking (was Re: [Darwine] Re: Wine Emulation: Swapping functions)
by Mike Hearn
> This is the more general project that has emerged from my initial idea
> for Darwine, namely X86/Linux binary compatibility for OS X.
Hmm, what is that useful for? Nearly all software for Linux is open
source and can be ported or sometimes simply recompiled for any given
platform. Do you have any particular programs in mind for this ability,
or is it just for the cool factor?
Doing a binary emulation of Linux is really, really easy compared to
emulating Windows (or MacOS) because all the supporting libraries are
already open source. FreeBSD does it, for instance. You only have to do
the syscalls and maybe the linker/C library.
IIRC there is also a "Line" program that does Linux binary emulation for
Windows though for obvious reasons it was never used much ...
Aug. 27, 2004
Re: CreateRemoteThread and related stuff (patch)
by Roger Olson
Hi All,
I have been using spare time ro study a means to implement this api for
several
months in order to get my app (United Devices) to work but have been on
the usual steep learning curve for Win32/Posix C and how Wine interacts. In
looking at the wonderful work Alexander has submitted with this patch, I can
see this was at least a mile over my head but am gratified to know I was at
least exploring in the appropriate areas.
I have a question however, and by no means is this intended to be a critique
but
rather a newbie inquirey (I am too new to know what I don't know yet) and
am
very happy a developer was willing to take this on. :)
I am wondering why delete the CreateThread() code and refer all such
requests
to CreateRemoteThread()? It would appear to me that retaining the
CreateThread()
code in addition to and compliant with the patch changes would be more
expeditious
for apps that do not need a call for Remote Operations.
I ask this as I performed a cheap hack by copying the CreateThread() code to
CreateRemoteThread(), sprinkled a bunch of Fixme's thru out the appropriate
functions to see what info my app provided and what it may be looking for.
The app
actually worked quite well with the exception of spurious blocked threads
upon closing,
what a surprise :). Any help greatly appreciated and since I'm on the Left
Coast, I
can say "I'll be Back" to hopefully offer some production input.
Thanks, Roger
----- Original Message -----
From: "Alexander Yaworsky" <yaworsky(a)migusoft.ru>
To: "Roger Olson" <u60(a)comcast.net>
Cc: <wine-devel(a)winehq.org>
Sent: Monday, August 23, 2004 4:15 AM
Subject: CreateRemoteThread and related stuff (patch)
> 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_pt
r, 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. 26, 2004
Re: RESEND make sure CryptSetProviderEx doesnt delete the 'Type XXX' key
by Alexandre Julliard
James Hawkins <truiken(a)gmail.com> writes:
> This is a resend of this patch...it's been through a couple times. If
> there is anything keeping the patch from being committed, please let
> me know. Thanks.
One problem I see is that you never close the key handles that you
open.
--
Alexandre Julliard
julliard(a)winehq.org
Aug. 26, 2004
Re: X86/PPC linking (was Re: [Darwine] Re: Wine Emulation: Swapping functions)
by Jim White
Mike Hearn wrote:
> ...
>> As for swapping functions, the preceding discussion reiterates my
>> belief that we should confine such fussy business to the relatively
>> small bit of code that calls into OS X, will be relatively stable over
>> the long haul, and over which we have full control. And as for the
>> concern over having Wine be X86 and hence incurring emulation
>> overhead, this would be one of the first bits of code which would be a
>> candidate for having its emulator-compiled code cached.
>
> If you look at how many native imports Wine requires on Linux to get
> full functionality I don't think you can say it's relatively small. It's
> many thousands of functions, possibly more. It's hard to measure because
> so much is dynamically loaded.
This is the more general project that has emerged from my initial idea
for Darwine, namely X86/Linux binary compatibility for OS X. There are
quite a few folks working on various combinations of
Linux/BSD/Darwin/Mach compatibility, but only for the native processor.
While there has been a ton of end user interest in Darwine in order to
run Windows apps, I have found that integrating CPU emulation into the
kernel compatibility layer attracts broad developer interest. As we
work through the implementation of Darwine I believe we will have
solutions for all these problems and OS X will indeed become quite the
Swiss Army knife of platforms.
Jim White
Aug. 26, 2004
Re: Something broke winetest?
by Paul Millar
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Thursday 26 August 2004 19:10, Stefan Leichter wrote:
> Am Mittwoch, 25. August 2004 14:12 schrieb Paul Millar:
> > Looks like something broke building cross-compiled tests
>
> the attach patch makes it working for me again
Ta!
> But i fear it will not help you.
"I must not fear.
Fear is the mind-killer..."
(sorry, couldn't resist ;)
> The name of the mingw binary indicates that you are not using the rpms
> provided by Hans Leidekker.
No fear, I just rolling my own :) So, I just dropped the new file in, ran the
build script and made a cup of coffee. The new tool-chain was built and
installed and is working fine.
The test-build just completed correctly so tomorrow's real build should work
fine.
Cheers,
Paul.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD8DBQFBLmIT/9JwS78PA+kRAiUvAJ9VmravZ0oN7QjGO9IcsDrkjNU8iQCeIFcT
X2W5NT7W41HPHi7GgAeB6qI=
=R5W8
-----END PGP SIGNATURE-----
Aug. 26, 2004
Re: Non-perfect epoll patch
by Shachar Shemesh
Shachar Shemesh wrote:
> Hi all,
>
> Attached is a non-perfect patch for review. This is a migration of the
> wineserver to use epoll instead of poll (if it's available).
>
> current known issue with this patch:
> 1. Will not compile if HAVE_SYS_EPOLL_H is not 1 (i.e. - won't compile
> if epoll not available at compile time)
> 2. Segfaults on wine exit.
> 3. Lots of debug asserts.
>
> Comments welcome.
> Shachar
>
The patch is not yet ready for commit, but I do have preliminary benchmarks:
The attached program (compiled as winelib) was used. ulimit -n was
raised to 10240.
With the current wine code:
real 0m41.076s
user 0m5.070s
sys 0m7.722s
the main wine process was taking 10% CPU time, and wineserver was taking
over 60% cpu time. load average was over 2
With my preliminary path:
real 0m20.985s
user 0m5.316s
sys 0m11.421s
main wine process was still taking 10%, but so was wineserver. load
average was about 1.5.
We can see that there is a significant drop in actual execution time,
even though there is an INCREASE in user+system processing time. I
believe this is not a fluke (results are pretty consistent), but rather
that the poll behavior was taking a huge toll on the system in areas
where it wasn't attributed towards wine, even though it was wine
related. I would take the real time measurement as the indicative one.
Ideas for better benchmarks would be greatly appreciated.
Shachar
--
Shachar Shemesh
Lingnu Open Source Consulting ltd.
http://www.lingnu.com/
### Generated by Winemaker
SRCDIR = .
SUBDIRS =
DLLS =
EXES = threadtest.exe
### Common settings
#CEXTRA = -mno-cygwin
#CXXEXTRA = -mno-cygwin
CEXTRA =
CXXEXTRA =
RCEXTRA =
INCLUDE_PATH = -I/home/sun/sources/wine/wine/include
DLL_PATH =
LIBRARY_PATH =
LIBRARIES =
### threadtest.exe sources and settings
threadtest_exe_MODULE = threadtest.exe
threadtest_exe_C_SRCS = main.c
threadtest_exe_CXX_SRCS=
threadtest_exe_RC_SRCS=
#threadtest_exe_LDFLAGS= -mconsole \
# -mno-cygwin
threadtest_exe_LDFLAGS= -mconsole
threadtest_exe_DLL_PATH=
threadtest_exe_DLLS =
threadtest_exe_LIBRARY_PATH= -L/home/sun/sources/wine/wine/libs -L/home/sun/sources/wine/wine/dlls
threadtest_exe_LIBRARIES= uuid
threadtest_exe_OBJS = $(threadtest_exe_C_SRCS:.c=.o) \
$(threadtest_exe_CXX_SRCS:.cpp=.o) \
$(threadtest_exe_RC_SRCS:.rc=.res)
### Global source lists
C_SRCS = $(threadtest_exe_C_SRCS)
CXX_SRCS = $(threadtest_exe_CXX_SRCS)
RC_SRCS = $(threadtest_exe_RC_SRCS)
### Tools
CC = winegcc
CXX = winegcc
RC = wrc
WINEBUILD = winebuild
### Generic targets
all: $(SUBDIRS) $(DLLS:%=%.so) $(EXES:%=%.so)
### Build rules
.PHONY: all clean dummy
$(SUBDIRS): dummy
@cd $@ && $(MAKE)
# Implicit rules
.SUFFIXES: .cpp .rc .res
DEFINCL = $(INCLUDE_PATH) $(DEFINES) $(OPTIONS)
.c.o:
$(CC) -c $(CFLAGS) $(CEXTRA) $(DEFINCL) -o $@ $<
.cpp.o:
$(CXX) -c $(CXXFLAGS) $(CXXEXTRA) $(DEFINCL) -o $@ $<
.cxx.o:
$(CXX) -c $(CXXFLAGS) $(CXXEXTRA) $(DEFINCL) -o $@ $<
.rc.res:
$(RC) $(RCFLAGS) $(RCEXTRA) $(DEFINCL) -fo$@ $<
# Rules for cleaning
CLEAN_FILES = *.dbg.c y.tab.c y.tab.h lex.yy.c \
core *.orig *.rej \
\\\#*\\\# *~ *% .\\\#*
clean:: $(SUBDIRS:%=%/__clean__) $(EXTRASUBDIRS:%=%/__clean__)
$(RM) $(CLEAN_FILES) $(RC_SRCS:.rc=.res) $(C_SRCS:.c=.o) $(CXX_SRCS:.cpp=.o)
$(RM) $(DLLS:%=%.dbg.o) $(DLLS:%=%.so)
$(RM) $(EXES:%=%.dbg.o) $(EXES:%=%.so) $(EXES:%.exe=%)
$(SUBDIRS:%=%/__clean__): dummy
cd `dirname $@` && $(MAKE) clean
$(EXTRASUBDIRS:%=%/__clean__): dummy
-cd `dirname $@` && $(RM) $(CLEAN_FILES)
### Target specific build rules
$(threadtest_exe_MODULE).dbg.c: $(threadtest_exe_C_SRCS) $(threadtest_exe_CXX_SRCS)
$(WINEBUILD) -o $@ --debug -C$(SRCDIR) $(threadtest_exe_C_SRCS) $(threadtest_exe_CXX_SRCS)
$(threadtest_exe_MODULE).so: $(threadtest_exe_MODULE).dbg.o $(threadtest_exe_OBJS)
$(CXX) $(threadtest_exe_LDFLAGS) -o $@ $(threadtest_exe_OBJS) $(threadtest_exe_MODULE).dbg.o $(threadtest_exe_LIBRARY_PATH) $(LIBRARY_PATH) $(threadtest_exe_DLLS:%=-l%) $(threadtest_exe_LIBRARIES:%=-l%)
Aug. 26, 2004
Re: Patch for CreateDIBitmap: Don't create monochrome bitmaps (help wanted)
by Michael Kaufmann
Hi!
>Could you integrate the DIB-Testcase program with the conformance
>framework? It seems like it would be a valuable addition and a good
>complement to your patch.
>
>
Currently I don't have the time to do this, but I'll try it eventually.
By the way: I've found some more incompatibilities:
- CreateCompatibleBitmap: If a DIB is selected into the device context,
CreateCompatibleBitmap should create a copy of this DIB. I don't know
how to implement this (how do we detect whether a DIB is selected?). I
found code to copy a DIB in dlls/gdi/brush.c
- CreatePatternBrush: The specification of this function has been
changed! Look at the function description (
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/brushe…
). Microsoft replaced "cannot be a DIB" with "can be a DIB"!
Maybe the specification of many more API functions has been changed. It
would be a good thing to check this systematically.
Regards
Michael
Aug. 26, 2004