2 * Wine server communication
4 * Copyright (C) 1998 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "wine/port.h"
35 #ifdef HAVE_PTHREAD_NP_H
36 # include <pthread_np.h>
45 #include <sys/types.h>
46 #ifdef HAVE_SYS_SOCKET_H
47 # include <sys/socket.h>
49 #ifdef HAVE_SYS_WAIT_H
55 #ifdef HAVE_SYS_MMAN_H
58 #ifdef HAVE_SYS_PRCTL_H
59 # include <sys/prctl.h>
61 #ifdef HAVE_SYS_STAT_H
62 # include <sys/stat.h>
64 #ifdef HAVE_SYS_SYSCALL_H
65 # include <sys/syscall.h>
77 #include <crt_externs.h>
79 #ifndef _POSIX_SPAWN_DISABLE_ASLR
80 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100
85 #define WIN32_NO_STATUS
88 #include "wine/library.h"
89 #include "wine/server.h"
90 #include "wine/debug.h"
91 #include "unix_private.h"
94 WINE_DEFAULT_DEBUG_CHANNEL(server
);
96 #ifndef MSG_CMSG_CLOEXEC
97 #define MSG_CMSG_CLOEXEC 0
100 #define SOCKETNAME "socket" /* name of the socket file */
101 #define LOCKNAME "lock" /* name of the lock file */
103 static const BOOL is_win64
= (sizeof(void *) > sizeof(int));
105 static const char *server_dir
;
107 unsigned int server_cpus
= 0;
108 BOOL is_wow64
= FALSE
;
110 timeout_t server_start_time
= 0; /* time of server startup */
112 sigset_t server_block_set
; /* signals to block during server calls */
113 static int fd_socket
= -1; /* socket to exchange file descriptors with the server */
114 static pid_t server_pid
;
115 static pthread_mutex_t fd_cache_mutex
= PTHREAD_MUTEX_INITIALIZER
;
117 /* atomically exchange a 64-bit value */
118 static inline LONG64
interlocked_xchg64( LONG64
*dest
, LONG64 val
)
121 return (LONG64
)InterlockedExchangePointer( (void **)dest
, (void *)val
);
124 while (InterlockedCompareExchange64( dest
, val
, tmp
) != tmp
) tmp
= *dest
;
130 static void fatal_error( const char *err
, ... ) __attribute__((noreturn
, format(printf
,1,2)));
131 static void fatal_perror( const char *err
, ... ) __attribute__((noreturn
, format(printf
,1,2)));
132 static void server_connect_error( const char *serverdir
) __attribute__((noreturn
));
135 /* die on a fatal error; use only during initialization */
136 static void fatal_error( const char *err
, ... )
140 va_start( args
, err
);
141 fprintf( stderr
, "wine: " );
142 vfprintf( stderr
, err
, args
);
147 /* die on a fatal error; use only during initialization */
148 static void fatal_perror( const char *err
, ... )
152 va_start( args
, err
);
153 fprintf( stderr
, "wine: " );
154 vfprintf( stderr
, err
, args
);
160 /***********************************************************************
161 * server_protocol_error
163 static DECLSPEC_NORETURN
void server_protocol_error( const char *err
, ... )
167 va_start( args
, err
);
168 fprintf( stderr
, "wine client error:%x: ", GetCurrentThreadId() );
169 vfprintf( stderr
, err
, args
);
175 /***********************************************************************
176 * server_protocol_perror
178 static DECLSPEC_NORETURN
void server_protocol_perror( const char *err
)
180 fprintf( stderr
, "wine client error:%x: ", GetCurrentThreadId() );
186 /***********************************************************************
189 * Send a request to the server.
191 static unsigned int send_request( const struct __server_request_info
*req
)
196 if (!req
->u
.req
.request_header
.request_size
)
198 if ((ret
= write( ntdll_get_thread_data()->request_fd
, &req
->u
.req
,
199 sizeof(req
->u
.req
) )) == sizeof(req
->u
.req
)) return STATUS_SUCCESS
;
204 struct iovec vec
[__SERVER_MAX_DATA
+1];
206 vec
[0].iov_base
= (void *)&req
->u
.req
;
207 vec
[0].iov_len
= sizeof(req
->u
.req
);
208 for (i
= 0; i
< req
->data_count
; i
++)
210 vec
[i
+1].iov_base
= (void *)req
->data
[i
].ptr
;
211 vec
[i
+1].iov_len
= req
->data
[i
].size
;
213 if ((ret
= writev( ntdll_get_thread_data()->request_fd
, vec
, i
+1 )) ==
214 req
->u
.req
.request_header
.request_size
+ sizeof(req
->u
.req
)) return STATUS_SUCCESS
;
217 if (ret
>= 0) server_protocol_error( "partial write %d\n", ret
);
218 if (errno
== EPIPE
) abort_thread(0);
219 if (errno
== EFAULT
) return STATUS_ACCESS_VIOLATION
;
220 server_protocol_perror( "write" );
224 /***********************************************************************
227 * Read data from the reply buffer; helper for wait_reply.
229 static void read_reply_data( void *buffer
, size_t size
)
235 if ((ret
= read( ntdll_get_thread_data()->reply_fd
, buffer
, size
)) > 0)
237 if (!(size
-= ret
)) return;
238 buffer
= (char *)buffer
+ ret
;
242 if (errno
== EINTR
) continue;
243 if (errno
== EPIPE
) break;
244 server_protocol_perror("read");
246 /* the server closed the connection; time to die... */
251 /***********************************************************************
254 * Wait for a reply from the server.
256 static inline unsigned int wait_reply( struct __server_request_info
*req
)
258 read_reply_data( &req
->u
.reply
, sizeof(req
->u
.reply
) );
259 if (req
->u
.reply
.reply_header
.reply_size
)
260 read_reply_data( req
->reply_data
, req
->u
.reply
.reply_header
.reply_size
);
261 return req
->u
.reply
.reply_header
.error
;
265 /***********************************************************************
266 * server_call_unlocked
268 unsigned int server_call_unlocked( void *req_ptr
)
270 struct __server_request_info
* const req
= req_ptr
;
273 if ((ret
= send_request( req
))) return ret
;
274 return wait_reply( req
);
278 /***********************************************************************
281 * Perform a server call.
283 unsigned int CDECL
wine_server_call( void *req_ptr
)
288 pthread_sigmask( SIG_BLOCK
, &server_block_set
, &old_set
);
289 ret
= server_call_unlocked( req_ptr
);
290 pthread_sigmask( SIG_SETMASK
, &old_set
, NULL
);
295 /***********************************************************************
296 * server_enter_uninterrupted_section
298 void server_enter_uninterrupted_section( pthread_mutex_t
*mutex
, sigset_t
*sigset
)
300 pthread_sigmask( SIG_BLOCK
, &server_block_set
, sigset
);
301 pthread_mutex_lock( mutex
);
305 /***********************************************************************
306 * server_leave_uninterrupted_section
308 void server_leave_uninterrupted_section( pthread_mutex_t
*mutex
, sigset_t
*sigset
)
310 pthread_mutex_unlock( mutex
);
311 pthread_sigmask( SIG_SETMASK
, sigset
, NULL
);
315 /***********************************************************************
318 * Wait for a reply on the waiting pipe of the current thread.
320 static int wait_select_reply( void *cookie
)
323 struct wake_up_reply reply
;
327 ret
= read( ntdll_get_thread_data()->wait_fd
[0], &reply
, sizeof(reply
) );
328 if (ret
== sizeof(reply
))
330 if (!reply
.cookie
) abort_thread( reply
.signaled
); /* thread got killed */
331 if (wine_server_get_ptr(reply
.cookie
) == cookie
) return reply
.signaled
;
332 /* we stole another reply, wait for the real one */
333 signaled
= wait_select_reply( cookie
);
334 /* and now put the wrong one back in the pipe */
337 ret
= write( ntdll_get_thread_data()->wait_fd
[1], &reply
, sizeof(reply
) );
338 if (ret
== sizeof(reply
)) break;
339 if (ret
>= 0) server_protocol_error( "partial wakeup write %d\n", ret
);
340 if (errno
== EINTR
) continue;
341 server_protocol_perror("wakeup write");
345 if (ret
>= 0) server_protocol_error( "partial wakeup read %d\n", ret
);
346 if (errno
== EINTR
) continue;
347 server_protocol_perror("wakeup read");
352 static void invoke_apc( const user_apc_t
*apc
)
358 void (WINAPI
*func
)(ULONG_PTR
,ULONG_PTR
,ULONG_PTR
) = wine_server_get_ptr( apc
->user
.func
);
359 func( apc
->user
.args
[0], apc
->user
.args
[1], apc
->user
.args
[2] );
364 void (WINAPI
*func
)(void*, unsigned int, unsigned int) = wine_server_get_ptr( apc
->user
.func
);
365 func( wine_server_get_ptr( apc
->user
.args
[1] ),
366 (DWORD
)apc
->timer
.time
, (DWORD
)(apc
->timer
.time
>> 32) );
370 server_protocol_error( "get_apc_request: bad type %d\n", apc
->type
);
375 /***********************************************************************
378 * Invoke a single APC.
381 static void invoke_system_apc( const apc_call_t
*call
, apc_result_t
*result
)
386 memset( result
, 0, sizeof(*result
) );
394 IO_STATUS_BLOCK
*iosb
= wine_server_get_ptr( call
->async_io
.sb
);
395 NTSTATUS (**user
)(void *, IO_STATUS_BLOCK
*, NTSTATUS
) = wine_server_get_ptr( call
->async_io
.user
);
396 result
->type
= call
->type
;
397 result
->async_io
.status
= (*user
)( user
, iosb
, call
->async_io
.status
);
398 if (result
->async_io
.status
!= STATUS_PENDING
)
399 result
->async_io
.total
= iosb
->Information
;
402 case APC_VIRTUAL_ALLOC
:
403 result
->type
= call
->type
;
404 addr
= wine_server_get_ptr( call
->virtual_alloc
.addr
);
405 size
= call
->virtual_alloc
.size
;
406 bits
= call
->virtual_alloc
.zero_bits
;
407 if ((ULONG_PTR
)addr
== call
->virtual_alloc
.addr
&& size
== call
->virtual_alloc
.size
&&
408 bits
== call
->virtual_alloc
.zero_bits
)
410 result
->virtual_alloc
.status
= NtAllocateVirtualMemory( NtCurrentProcess(), &addr
, bits
, &size
,
411 call
->virtual_alloc
.op_type
,
412 call
->virtual_alloc
.prot
);
413 result
->virtual_alloc
.addr
= wine_server_client_ptr( addr
);
414 result
->virtual_alloc
.size
= size
;
416 else result
->virtual_alloc
.status
= STATUS_WORKING_SET_LIMIT_RANGE
;
418 case APC_VIRTUAL_FREE
:
419 result
->type
= call
->type
;
420 addr
= wine_server_get_ptr( call
->virtual_free
.addr
);
421 size
= call
->virtual_free
.size
;
422 if ((ULONG_PTR
)addr
== call
->virtual_free
.addr
&& size
== call
->virtual_free
.size
)
424 result
->virtual_free
.status
= NtFreeVirtualMemory( NtCurrentProcess(), &addr
, &size
,
425 call
->virtual_free
.op_type
);
426 result
->virtual_free
.addr
= wine_server_client_ptr( addr
);
427 result
->virtual_free
.size
= size
;
429 else result
->virtual_free
.status
= STATUS_INVALID_PARAMETER
;
431 case APC_VIRTUAL_QUERY
:
433 MEMORY_BASIC_INFORMATION info
;
434 result
->type
= call
->type
;
435 addr
= wine_server_get_ptr( call
->virtual_query
.addr
);
436 if ((ULONG_PTR
)addr
== call
->virtual_query
.addr
)
437 result
->virtual_query
.status
= NtQueryVirtualMemory( NtCurrentProcess(),
438 addr
, MemoryBasicInformation
, &info
,
439 sizeof(info
), NULL
);
441 result
->virtual_query
.status
= STATUS_WORKING_SET_LIMIT_RANGE
;
443 if (result
->virtual_query
.status
== STATUS_SUCCESS
)
445 result
->virtual_query
.base
= wine_server_client_ptr( info
.BaseAddress
);
446 result
->virtual_query
.alloc_base
= wine_server_client_ptr( info
.AllocationBase
);
447 result
->virtual_query
.size
= info
.RegionSize
;
448 result
->virtual_query
.prot
= info
.Protect
;
449 result
->virtual_query
.alloc_prot
= info
.AllocationProtect
;
450 result
->virtual_query
.state
= info
.State
>> 12;
451 result
->virtual_query
.alloc_type
= info
.Type
>> 16;
455 case APC_VIRTUAL_PROTECT
:
456 result
->type
= call
->type
;
457 addr
= wine_server_get_ptr( call
->virtual_protect
.addr
);
458 size
= call
->virtual_protect
.size
;
459 if ((ULONG_PTR
)addr
== call
->virtual_protect
.addr
&& size
== call
->virtual_protect
.size
)
461 result
->virtual_protect
.status
= NtProtectVirtualMemory( NtCurrentProcess(), &addr
, &size
,
462 call
->virtual_protect
.prot
,
463 &result
->virtual_protect
.prot
);
464 result
->virtual_protect
.addr
= wine_server_client_ptr( addr
);
465 result
->virtual_protect
.size
= size
;
467 else result
->virtual_protect
.status
= STATUS_INVALID_PARAMETER
;
469 case APC_VIRTUAL_FLUSH
:
470 result
->type
= call
->type
;
471 addr
= wine_server_get_ptr( call
->virtual_flush
.addr
);
472 size
= call
->virtual_flush
.size
;
473 if ((ULONG_PTR
)addr
== call
->virtual_flush
.addr
&& size
== call
->virtual_flush
.size
)
475 result
->virtual_flush
.status
= NtFlushVirtualMemory( NtCurrentProcess(),
476 (const void **)&addr
, &size
, 0 );
477 result
->virtual_flush
.addr
= wine_server_client_ptr( addr
);
478 result
->virtual_flush
.size
= size
;
480 else result
->virtual_flush
.status
= STATUS_INVALID_PARAMETER
;
482 case APC_VIRTUAL_LOCK
:
483 result
->type
= call
->type
;
484 addr
= wine_server_get_ptr( call
->virtual_lock
.addr
);
485 size
= call
->virtual_lock
.size
;
486 if ((ULONG_PTR
)addr
== call
->virtual_lock
.addr
&& size
== call
->virtual_lock
.size
)
488 result
->virtual_lock
.status
= NtLockVirtualMemory( NtCurrentProcess(), &addr
, &size
, 0 );
489 result
->virtual_lock
.addr
= wine_server_client_ptr( addr
);
490 result
->virtual_lock
.size
= size
;
492 else result
->virtual_lock
.status
= STATUS_INVALID_PARAMETER
;
494 case APC_VIRTUAL_UNLOCK
:
495 result
->type
= call
->type
;
496 addr
= wine_server_get_ptr( call
->virtual_unlock
.addr
);
497 size
= call
->virtual_unlock
.size
;
498 if ((ULONG_PTR
)addr
== call
->virtual_unlock
.addr
&& size
== call
->virtual_unlock
.size
)
500 result
->virtual_unlock
.status
= NtUnlockVirtualMemory( NtCurrentProcess(), &addr
, &size
, 0 );
501 result
->virtual_unlock
.addr
= wine_server_client_ptr( addr
);
502 result
->virtual_unlock
.size
= size
;
504 else result
->virtual_unlock
.status
= STATUS_INVALID_PARAMETER
;
507 result
->type
= call
->type
;
508 addr
= wine_server_get_ptr( call
->map_view
.addr
);
509 size
= call
->map_view
.size
;
510 bits
= call
->map_view
.zero_bits
;
511 if ((ULONG_PTR
)addr
== call
->map_view
.addr
&& size
== call
->map_view
.size
&&
512 bits
== call
->map_view
.zero_bits
)
514 LARGE_INTEGER offset
;
515 offset
.QuadPart
= call
->map_view
.offset
;
516 result
->map_view
.status
= NtMapViewOfSection( wine_server_ptr_handle(call
->map_view
.handle
),
518 &addr
, bits
, 0, &offset
, &size
, 0,
519 call
->map_view
.alloc_type
, call
->map_view
.prot
);
520 result
->map_view
.addr
= wine_server_client_ptr( addr
);
521 result
->map_view
.size
= size
;
523 else result
->map_view
.status
= STATUS_INVALID_PARAMETER
;
524 NtClose( wine_server_ptr_handle(call
->map_view
.handle
) );
527 result
->type
= call
->type
;
528 addr
= wine_server_get_ptr( call
->unmap_view
.addr
);
529 if ((ULONG_PTR
)addr
== call
->unmap_view
.addr
)
530 result
->unmap_view
.status
= NtUnmapViewOfSection( NtCurrentProcess(), addr
);
532 result
->unmap_view
.status
= STATUS_INVALID_PARAMETER
;
534 case APC_CREATE_THREAD
:
536 ULONG_PTR buffer
[offsetof( PS_ATTRIBUTE_LIST
, Attributes
[2] ) / sizeof(ULONG_PTR
)];
537 PS_ATTRIBUTE_LIST
*attr
= (PS_ATTRIBUTE_LIST
*)buffer
;
541 SIZE_T reserve
= call
->create_thread
.reserve
;
542 SIZE_T commit
= call
->create_thread
.commit
;
543 void *func
= wine_server_get_ptr( call
->create_thread
.func
);
544 void *arg
= wine_server_get_ptr( call
->create_thread
.arg
);
546 result
->type
= call
->type
;
547 if (reserve
== call
->create_thread
.reserve
&& commit
== call
->create_thread
.commit
&&
548 (ULONG_PTR
)func
== call
->create_thread
.func
&& (ULONG_PTR
)arg
== call
->create_thread
.arg
)
550 attr
->TotalLength
= sizeof(buffer
);
551 attr
->Attributes
[0].Attribute
= PS_ATTRIBUTE_CLIENT_ID
;
552 attr
->Attributes
[0].Size
= sizeof(id
);
553 attr
->Attributes
[0].ValuePtr
= &id
;
554 attr
->Attributes
[0].ReturnLength
= NULL
;
555 attr
->Attributes
[1].Attribute
= PS_ATTRIBUTE_TEB_ADDRESS
;
556 attr
->Attributes
[1].Size
= sizeof(teb
);
557 attr
->Attributes
[1].ValuePtr
= &teb
;
558 attr
->Attributes
[1].ReturnLength
= NULL
;
559 result
->create_thread
.status
= NtCreateThreadEx( &handle
, THREAD_ALL_ACCESS
, NULL
,
560 NtCurrentProcess(), func
, arg
,
561 call
->create_thread
.flags
, 0,
562 commit
, reserve
, attr
);
563 result
->create_thread
.handle
= wine_server_obj_handle( handle
);
564 result
->create_thread
.pid
= HandleToULong(id
.UniqueProcess
);
565 result
->create_thread
.tid
= HandleToULong(id
.UniqueThread
);
566 result
->create_thread
.teb
= wine_server_client_ptr( teb
);
568 else result
->create_thread
.status
= STATUS_INVALID_PARAMETER
;
571 case APC_BREAK_PROCESS
:
575 result
->type
= APC_BREAK_PROCESS
;
576 result
->break_process
.status
= NtCreateThreadEx( &handle
, THREAD_ALL_ACCESS
, NULL
,
577 NtCurrentProcess(), pDbgUiRemoteBreakin
, NULL
,
579 if (!result
->break_process
.status
) NtClose( handle
);
583 server_protocol_error( "get_apc_request: bad type %d\n", call
->type
);
589 /***********************************************************************
592 unsigned int server_select( const select_op_t
*select_op
, data_size_t size
, UINT flags
,
593 timeout_t abs_timeout
, CONTEXT
*context
, pthread_mutex_t
*mutex
,
594 user_apc_t
*user_apc
)
598 obj_handle_t apc_handle
= 0;
599 context_t server_context
;
600 BOOL suspend_context
= FALSE
;
605 memset( &result
, 0, sizeof(result
) );
608 suspend_context
= TRUE
;
609 context_to_server( &server_context
, context
);
614 pthread_sigmask( SIG_BLOCK
, &server_block_set
, &old_set
);
617 SERVER_START_REQ( select
)
620 req
->cookie
= wine_server_client_ptr( &cookie
);
621 req
->prev_apc
= apc_handle
;
622 req
->timeout
= abs_timeout
;
624 wine_server_add_data( req
, &result
, sizeof(result
) );
625 wine_server_add_data( req
, select_op
, size
);
628 wine_server_add_data( req
, &server_context
, sizeof(server_context
) );
629 suspend_context
= FALSE
; /* server owns the context now */
631 if (context
) wine_server_set_reply( req
, &server_context
, sizeof(server_context
) );
632 ret
= server_call_unlocked( req
);
633 apc_handle
= reply
->apc_handle
;
635 if (wine_server_reply_size( reply
))
637 DWORD context_flags
= context
->ContextFlags
; /* unchanged registers are still available */
638 context_from_server( context
, &server_context
);
639 context
->ContextFlags
|= context_flags
;
644 if (ret
!= STATUS_KERNEL_APC
) break;
645 invoke_system_apc( &call
, &result
);
647 /* don't signal multiple times */
648 if (size
>= sizeof(select_op
->signal_and_wait
) && select_op
->op
== SELECT_SIGNAL_AND_WAIT
)
649 size
= offsetof( select_op_t
, signal_and_wait
.signal
);
651 pthread_sigmask( SIG_SETMASK
, &old_set
, NULL
);
654 pthread_mutex_unlock( mutex
);
657 if (ret
!= STATUS_PENDING
) break;
659 ret
= wait_select_reply( &cookie
);
661 while (ret
== STATUS_USER_APC
|| ret
== STATUS_KERNEL_APC
);
663 if (ret
== STATUS_USER_APC
) *user_apc
= call
.user
;
668 /***********************************************************************
671 unsigned int server_wait( const select_op_t
*select_op
, data_size_t size
, UINT flags
,
672 const LARGE_INTEGER
*timeout
)
674 timeout_t abs_timeout
= timeout
? timeout
->QuadPart
: TIMEOUT_INFINITE
;
675 BOOL user_apc
= FALSE
;
683 NtQueryPerformanceCounter( &now
, NULL
);
684 abs_timeout
-= now
.QuadPart
;
689 ret
= server_select( select_op
, size
, flags
, abs_timeout
, NULL
, NULL
, &apc
);
690 if (ret
!= STATUS_USER_APC
) break;
693 /* if we ran a user apc we have to check once more if additional apcs are queued,
694 * but we don't want to wait */
698 /* don't signal multiple times */
699 if (size
>= sizeof(select_op
->signal_and_wait
) && select_op
->op
== SELECT_SIGNAL_AND_WAIT
)
700 size
= offsetof( select_op_t
, signal_and_wait
.signal
);
703 if (ret
== STATUS_TIMEOUT
&& user_apc
) ret
= STATUS_USER_APC
;
705 /* A test on Windows 2000 shows that Windows always yields during
706 a wait, but a wait that is hit by an event gets a priority
707 boost as well. This seems to model that behavior the closest. */
708 if (ret
== STATUS_TIMEOUT
) NtYieldExecution();
714 /***********************************************************************
715 * server_queue_process_apc
717 unsigned int server_queue_process_apc( HANDLE process
, const apc_call_t
*call
, apc_result_t
*result
)
725 SERVER_START_REQ( queue_apc
)
727 req
->handle
= wine_server_obj_handle( process
);
729 if (!(ret
= wine_server_call( req
)))
731 handle
= wine_server_ptr_handle( reply
->handle
);
736 if (ret
!= STATUS_SUCCESS
) return ret
;
740 invoke_system_apc( call
, result
);
744 NtWaitForSingleObject( handle
, FALSE
, NULL
);
746 SERVER_START_REQ( get_apc_result
)
748 req
->handle
= wine_server_obj_handle( handle
);
749 if (!(ret
= wine_server_call( req
))) *result
= reply
->result
;
753 if (!ret
&& result
->type
== APC_NONE
) continue; /* APC didn't run, try again */
760 /***********************************************************************
763 * Send a file descriptor to the server.
765 void CDECL
server_send_fd( int fd
)
768 struct msghdr msghdr
;
772 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
773 msghdr
.msg_accrights
= (void *)&fd
;
774 msghdr
.msg_accrightslen
= sizeof(fd
);
775 #else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
776 char cmsg_buffer
[256];
777 struct cmsghdr
*cmsg
;
778 msghdr
.msg_control
= cmsg_buffer
;
779 msghdr
.msg_controllen
= sizeof(cmsg_buffer
);
780 msghdr
.msg_flags
= 0;
781 cmsg
= CMSG_FIRSTHDR( &msghdr
);
782 cmsg
->cmsg_len
= CMSG_LEN( sizeof(fd
) );
783 cmsg
->cmsg_level
= SOL_SOCKET
;
784 cmsg
->cmsg_type
= SCM_RIGHTS
;
785 *(int *)CMSG_DATA(cmsg
) = fd
;
786 msghdr
.msg_controllen
= cmsg
->cmsg_len
;
787 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
789 msghdr
.msg_name
= NULL
;
790 msghdr
.msg_namelen
= 0;
791 msghdr
.msg_iov
= &vec
;
792 msghdr
.msg_iovlen
= 1;
794 vec
.iov_base
= (void *)&data
;
795 vec
.iov_len
= sizeof(data
);
797 data
.tid
= GetCurrentThreadId();
802 if ((ret
= sendmsg( fd_socket
, &msghdr
, 0 )) == sizeof(data
)) return;
803 if (ret
>= 0) server_protocol_error( "partial write %d\n", ret
);
804 if (errno
== EINTR
) continue;
805 if (errno
== EPIPE
) abort_thread(0);
806 server_protocol_perror( "sendmsg" );
811 /***********************************************************************
814 * Receive a file descriptor passed from the server.
816 static int receive_fd( obj_handle_t
*handle
)
819 struct msghdr msghdr
;
822 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
823 msghdr
.msg_accrights
= (void *)&fd
;
824 msghdr
.msg_accrightslen
= sizeof(fd
);
825 #else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
826 char cmsg_buffer
[256];
827 msghdr
.msg_control
= cmsg_buffer
;
828 msghdr
.msg_controllen
= sizeof(cmsg_buffer
);
829 msghdr
.msg_flags
= 0;
830 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
832 msghdr
.msg_name
= NULL
;
833 msghdr
.msg_namelen
= 0;
834 msghdr
.msg_iov
= &vec
;
835 msghdr
.msg_iovlen
= 1;
836 vec
.iov_base
= (void *)handle
;
837 vec
.iov_len
= sizeof(*handle
);
841 if ((ret
= recvmsg( fd_socket
, &msghdr
, MSG_CMSG_CLOEXEC
)) > 0)
843 #ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
844 struct cmsghdr
*cmsg
;
845 for (cmsg
= CMSG_FIRSTHDR( &msghdr
); cmsg
; cmsg
= CMSG_NXTHDR( &msghdr
, cmsg
))
847 if (cmsg
->cmsg_level
!= SOL_SOCKET
) continue;
848 if (cmsg
->cmsg_type
== SCM_RIGHTS
) fd
= *(int *)CMSG_DATA(cmsg
);
849 #ifdef SCM_CREDENTIALS
850 else if (cmsg
->cmsg_type
== SCM_CREDENTIALS
)
852 struct ucred
*ucred
= (struct ucred
*)CMSG_DATA(cmsg
);
853 server_pid
= ucred
->pid
;
857 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
858 if (fd
!= -1) fcntl( fd
, F_SETFD
, FD_CLOEXEC
); /* in case MSG_CMSG_CLOEXEC is not supported */
862 if (errno
== EINTR
) continue;
863 if (errno
== EPIPE
) break;
864 server_protocol_perror("recvmsg");
866 /* the server closed the connection; time to die... */
871 /***********************************************************************/
872 /* fd cache support */
880 enum server_fd_type type
: 5;
881 unsigned int access
: 3;
882 unsigned int options
: 24;
886 C_ASSERT( sizeof(union fd_cache_entry
) == sizeof(LONG64
) );
888 #define FD_CACHE_BLOCK_SIZE (65536 / sizeof(union fd_cache_entry))
889 #define FD_CACHE_ENTRIES 128
891 static union fd_cache_entry
*fd_cache
[FD_CACHE_ENTRIES
];
892 static union fd_cache_entry fd_cache_initial_block
[FD_CACHE_BLOCK_SIZE
];
894 static inline unsigned int handle_to_index( HANDLE handle
, unsigned int *entry
)
896 unsigned int idx
= (wine_server_obj_handle(handle
) >> 2) - 1;
897 *entry
= idx
/ FD_CACHE_BLOCK_SIZE
;
898 return idx
% FD_CACHE_BLOCK_SIZE
;
902 /***********************************************************************
905 * Caller must hold fd_cache_mutex.
907 static BOOL
add_fd_to_cache( HANDLE handle
, int fd
, enum server_fd_type type
,
908 unsigned int access
, unsigned int options
)
910 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
911 union fd_cache_entry cache
;
913 if (entry
>= FD_CACHE_ENTRIES
)
915 FIXME( "too many allocated handles, not caching %p\n", handle
);
919 if (!fd_cache
[entry
]) /* do we need to allocate a new block of entries? */
921 if (!entry
) fd_cache
[0] = fd_cache_initial_block
;
924 void *ptr
= wine_anon_mmap( NULL
, FD_CACHE_BLOCK_SIZE
* sizeof(union fd_cache_entry
),
925 PROT_READ
| PROT_WRITE
, 0 );
926 if (ptr
== MAP_FAILED
) return FALSE
;
927 fd_cache
[entry
] = ptr
;
931 /* store fd+1 so that 0 can be used as the unset value */
934 cache
.s
.access
= access
;
935 cache
.s
.options
= options
;
936 cache
.data
= interlocked_xchg64( &fd_cache
[entry
][idx
].data
, cache
.data
);
937 assert( !cache
.s
.fd
);
942 /***********************************************************************
945 static inline NTSTATUS
get_cached_fd( HANDLE handle
, int *fd
, enum server_fd_type
*type
,
946 unsigned int *access
, unsigned int *options
)
948 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
949 union fd_cache_entry cache
;
951 if (entry
>= FD_CACHE_ENTRIES
|| !fd_cache
[entry
]) return STATUS_INVALID_HANDLE
;
953 cache
.data
= InterlockedCompareExchange64( &fd_cache
[entry
][idx
].data
, 0, 0 );
954 if (!cache
.data
) return STATUS_INVALID_HANDLE
;
956 /* if fd type is invalid, fd stores an error value */
957 if (cache
.s
.type
== FD_TYPE_INVALID
) return cache
.s
.fd
- 1;
959 *fd
= cache
.s
.fd
- 1;
960 if (type
) *type
= cache
.s
.type
;
961 if (access
) *access
= cache
.s
.access
;
962 if (options
) *options
= cache
.s
.options
;
963 return STATUS_SUCCESS
;
967 /***********************************************************************
968 * remove_fd_from_cache
970 static int remove_fd_from_cache( HANDLE handle
)
972 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
975 if (entry
< FD_CACHE_ENTRIES
&& fd_cache
[entry
])
977 union fd_cache_entry cache
;
978 cache
.data
= interlocked_xchg64( &fd_cache
[entry
][idx
].data
, 0 );
979 if (cache
.s
.type
!= FD_TYPE_INVALID
) fd
= cache
.s
.fd
- 1;
986 /***********************************************************************
989 * The returned unix_fd should be closed iff needs_close is non-zero.
991 int server_get_unix_fd( HANDLE handle
, unsigned int wanted_access
, int *unix_fd
,
992 int *needs_close
, enum server_fd_type
*type
, unsigned int *options
)
995 obj_handle_t fd_handle
;
997 unsigned int access
= 0;
1001 wanted_access
&= FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_APPEND_DATA
;
1003 ret
= get_cached_fd( handle
, &fd
, type
, &access
, options
);
1004 if (ret
!= STATUS_INVALID_HANDLE
) goto done
;
1006 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1007 ret
= get_cached_fd( handle
, &fd
, type
, &access
, options
);
1008 if (ret
== STATUS_INVALID_HANDLE
)
1010 SERVER_START_REQ( get_handle_fd
)
1012 req
->handle
= wine_server_obj_handle( handle
);
1013 if (!(ret
= wine_server_call( req
)))
1015 if (type
) *type
= reply
->type
;
1016 if (options
) *options
= reply
->options
;
1017 access
= reply
->access
;
1018 if ((fd
= receive_fd( &fd_handle
)) != -1)
1020 assert( wine_server_ptr_handle(fd_handle
) == handle
);
1021 *needs_close
= (!reply
->cacheable
||
1022 !add_fd_to_cache( handle
, fd
, reply
->type
,
1023 reply
->access
, reply
->options
));
1025 else ret
= STATUS_TOO_MANY_OPENED_FILES
;
1027 else if (reply
->cacheable
)
1029 add_fd_to_cache( handle
, ret
, FD_TYPE_INVALID
, 0, 0 );
1034 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1037 if (!ret
&& ((access
& wanted_access
) != wanted_access
))
1039 ret
= STATUS_ACCESS_DENIED
;
1040 if (*needs_close
) close( fd
);
1042 if (!ret
) *unix_fd
= fd
;
1047 /***********************************************************************
1048 * server_fd_to_handle
1050 NTSTATUS CDECL
server_fd_to_handle( int fd
, unsigned int access
, unsigned int attributes
, HANDLE
*handle
)
1055 server_send_fd( fd
);
1057 SERVER_START_REQ( alloc_file_handle
)
1059 req
->access
= access
;
1060 req
->attributes
= attributes
;
1062 if (!(ret
= wine_server_call( req
))) *handle
= wine_server_ptr_handle( reply
->handle
);
1069 /***********************************************************************
1070 * server_handle_to_fd
1072 * Retrieve the file descriptor corresponding to a file handle.
1074 NTSTATUS CDECL
server_handle_to_fd( HANDLE handle
, unsigned int access
, int *unix_fd
,
1075 unsigned int *options
)
1078 NTSTATUS ret
= server_get_unix_fd( handle
, access
, unix_fd
, &needs_close
, NULL
, options
);
1080 if (!ret
&& !needs_close
)
1082 if ((*unix_fd
= dup(*unix_fd
)) == -1) ret
= STATUS_TOO_MANY_OPENED_FILES
;
1088 /***********************************************************************
1091 void CDECL
server_release_fd( HANDLE handle
, int unix_fd
)
1097 /***********************************************************************
1100 * Create a pipe for communicating with the server.
1102 int server_pipe( int fd
[2] )
1106 static BOOL have_pipe2
= TRUE
;
1110 if (!(ret
= pipe2( fd
, O_CLOEXEC
))) return ret
;
1111 if (errno
== ENOSYS
|| errno
== EINVAL
) have_pipe2
= FALSE
; /* don't try again */
1114 if (!(ret
= pipe( fd
)))
1116 fcntl( fd
[0], F_SETFD
, FD_CLOEXEC
);
1117 fcntl( fd
[1], F_SETFD
, FD_CLOEXEC
);
1123 /***********************************************************************
1126 static const char *init_server_dir( dev_t dev
, ino_t ino
)
1129 size_t len
= sizeof("/server-") + 2 * sizeof(dev
) + 2 * sizeof(ino
) + 2;
1131 #ifdef __ANDROID__ /* there's no /tmp dir on Android */
1132 len
+= strlen( config_dir
) + sizeof("/.wineserver");
1133 dir
= malloc( len
);
1134 strcpy( dir
, config_dir
);
1135 strcat( dir
, "/.wineserver/server-" );
1137 len
+= sizeof("/tmp/.wine-") + 12;
1138 dir
= malloc( len
);
1139 sprintf( dir
, "/tmp/.wine-%u/server-", getuid() );
1141 p
= dir
+ strlen( dir
);
1142 if (dev
!= (unsigned long)dev
)
1143 p
+= sprintf( p
, "%lx%08lx-", (unsigned long)((unsigned long long)dev
>> 32), (unsigned long)dev
);
1145 p
+= sprintf( p
, "%lx-", (unsigned long)dev
);
1147 if (ino
!= (unsigned long)ino
)
1148 sprintf( p
, "%lx%08lx", (unsigned long)((unsigned long long)ino
>> 32), (unsigned long)ino
);
1150 sprintf( p
, "%lx", (unsigned long)ino
);
1155 /***********************************************************************
1158 * Setup the wine configuration dir.
1160 static int setup_config_dir(void)
1164 int fd_cwd
= open( ".", O_RDONLY
);
1166 if (chdir( config_dir
) == -1)
1168 if (errno
!= ENOENT
) fatal_perror( "cannot use directory %s", config_dir
);
1169 if ((p
= strrchr( config_dir
, '/' )) && p
!= config_dir
)
1171 while (p
> config_dir
+ 1 && p
[-1] == '/') p
--;
1173 if (!stat( config_dir
, &st
) && st
.st_uid
!= getuid())
1174 fatal_error( "'%s' is not owned by you, refusing to create a configuration directory there\n",
1178 mkdir( config_dir
, 0777 );
1179 if (chdir( config_dir
) == -1) fatal_perror( "chdir to %s", config_dir
);
1180 MESSAGE( "wine: created the configuration directory '%s'\n", config_dir
);
1183 if (stat( ".", &st
) == -1) fatal_perror( "stat %s", config_dir
);
1184 if (st
.st_uid
!= getuid()) fatal_error( "'%s' is not owned by you\n", config_dir
);
1186 server_dir
= init_server_dir( st
.st_dev
, st
.st_ino
);
1188 if (!mkdir( "dosdevices", 0777 ))
1190 mkdir( "drive_c", 0777 );
1191 symlink( "../drive_c", "dosdevices/c:" );
1192 symlink( "/", "dosdevices/z:" );
1194 else if (errno
!= EEXIST
) fatal_perror( "cannot create %s/dosdevices", config_dir
);
1196 if (fd_cwd
== -1) fd_cwd
= open( "dosdevices/c:", O_RDONLY
);
1197 fcntl( fd_cwd
, F_SETFD
, FD_CLOEXEC
);
1202 /***********************************************************************
1203 * server_connect_error
1205 * Try to display a meaningful explanation of why we couldn't connect
1208 static void server_connect_error( const char *serverdir
)
1213 if ((fd
= open( LOCKNAME
, O_WRONLY
)) == -1)
1214 fatal_error( "for some mysterious reason, the wine server never started.\n" );
1216 fl
.l_type
= F_WRLCK
;
1217 fl
.l_whence
= SEEK_SET
;
1220 if (fcntl( fd
, F_GETLK
, &fl
) != -1)
1222 if (fl
.l_type
== F_WRLCK
) /* the file is locked */
1223 fatal_error( "a wine server seems to be running, but I cannot connect to it.\n"
1224 " You probably need to kill that process (it might be pid %d).\n",
1226 fatal_error( "for some mysterious reason, the wine server failed to run.\n" );
1228 fatal_error( "the file system of '%s' doesn't support locks,\n"
1229 " and there is a 'socket' file in that directory that prevents wine from starting.\n"
1230 " You should make sure no wine server is running, remove that file and try again.\n",
1235 /***********************************************************************
1238 * Attempt to connect to an existing server socket.
1239 * We need to be in the server directory already.
1241 static int server_connect(void)
1243 struct sockaddr_un addr
;
1245 int s
, slen
, retry
, fd_cwd
;
1247 fd_cwd
= setup_config_dir();
1249 /* chdir to the server directory */
1250 if (chdir( server_dir
) == -1)
1252 if (errno
!= ENOENT
) fatal_perror( "chdir to %s", server_dir
);
1253 start_server( TRACE_ON(server
) );
1254 if (chdir( server_dir
) == -1) fatal_perror( "chdir to %s", server_dir
);
1257 /* make sure we are at the right place */
1258 if (stat( ".", &st
) == -1) fatal_perror( "stat %s", server_dir
);
1259 if (st
.st_uid
!= getuid()) fatal_error( "'%s' is not owned by you\n", server_dir
);
1260 if (st
.st_mode
& 077) fatal_error( "'%s' must not be accessible by other users\n", server_dir
);
1262 for (retry
= 0; retry
< 6; retry
++)
1264 /* if not the first try, wait a bit to leave the previous server time to exit */
1267 usleep( 100000 * retry
* retry
);
1268 start_server( TRACE_ON(server
) );
1269 if (lstat( SOCKETNAME
, &st
) == -1) continue; /* still no socket, wait a bit more */
1271 else if (lstat( SOCKETNAME
, &st
) == -1) /* check for an already existing socket */
1273 if (errno
!= ENOENT
) fatal_perror( "lstat %s/%s", server_dir
, SOCKETNAME
);
1274 start_server( TRACE_ON(server
) );
1275 if (lstat( SOCKETNAME
, &st
) == -1) continue; /* still no socket, wait a bit more */
1278 /* make sure the socket is sane (ISFIFO needed for Solaris) */
1279 if (!S_ISSOCK(st
.st_mode
) && !S_ISFIFO(st
.st_mode
))
1280 fatal_error( "'%s/%s' is not a socket\n", server_dir
, SOCKETNAME
);
1281 if (st
.st_uid
!= getuid())
1282 fatal_error( "'%s/%s' is not owned by you\n", server_dir
, SOCKETNAME
);
1284 /* try to connect to it */
1285 addr
.sun_family
= AF_UNIX
;
1286 strcpy( addr
.sun_path
, SOCKETNAME
);
1287 slen
= sizeof(addr
) - sizeof(addr
.sun_path
) + strlen(addr
.sun_path
) + 1;
1288 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
1289 addr
.sun_len
= slen
;
1291 if ((s
= socket( AF_UNIX
, SOCK_STREAM
, 0 )) == -1) fatal_perror( "socket" );
1296 setsockopt( s
, SOL_SOCKET
, SO_PASSCRED
, &enable
, sizeof(enable
) );
1299 if (connect( s
, (struct sockaddr
*)&addr
, slen
) != -1)
1301 /* switch back to the starting directory */
1307 fcntl( s
, F_SETFD
, FD_CLOEXEC
);
1312 server_connect_error( server_dir
);
1317 #include <mach/mach.h>
1318 #include <mach/mach_error.h>
1319 #include <servers/bootstrap.h>
1321 /* send our task port to the server */
1322 static void send_server_task_port(void)
1324 mach_port_t bootstrap_port
, wineserver_port
;
1328 mach_msg_header_t header
;
1329 mach_msg_body_t body
;
1330 mach_msg_port_descriptor_t task_port
;
1333 if (task_get_bootstrap_port(mach_task_self(), &bootstrap_port
) != KERN_SUCCESS
) return;
1338 stat( config_dir
, &st
);
1339 server_dir
= init_server_dir( st
.st_dev
, st
.st_ino
);
1341 kret
= bootstrap_look_up(bootstrap_port
, server_dir
, &wineserver_port
);
1342 if (kret
!= KERN_SUCCESS
)
1343 fatal_error( "cannot find the server port: 0x%08x\n", kret
);
1345 mach_port_deallocate(mach_task_self(), bootstrap_port
);
1347 msg
.header
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, 0) | MACH_MSGH_BITS_COMPLEX
;
1348 msg
.header
.msgh_size
= sizeof(msg
);
1349 msg
.header
.msgh_remote_port
= wineserver_port
;
1350 msg
.header
.msgh_local_port
= MACH_PORT_NULL
;
1352 msg
.body
.msgh_descriptor_count
= 1;
1353 msg
.task_port
.name
= mach_task_self();
1354 msg
.task_port
.disposition
= MACH_MSG_TYPE_COPY_SEND
;
1355 msg
.task_port
.type
= MACH_MSG_PORT_DESCRIPTOR
;
1357 kret
= mach_msg_send(&msg
.header
);
1358 if (kret
!= KERN_SUCCESS
)
1359 server_protocol_error( "mach_msg_send failed: 0x%08x\n", kret
);
1361 mach_port_deallocate(mach_task_self(), wineserver_port
);
1363 #endif /* __APPLE__ */
1366 /***********************************************************************
1369 * Retrieve the Unix tid to use on the server side for the current thread.
1371 static int get_unix_tid(void)
1374 #ifdef HAVE_PTHREAD_GETTHREADID_NP
1375 ret
= pthread_getthreadid_np();
1376 #elif defined(linux)
1377 ret
= syscall( __NR_gettid
);
1378 #elif defined(__sun)
1379 ret
= pthread_self();
1380 #elif defined(__APPLE__)
1381 ret
= mach_thread_self();
1382 mach_port_deallocate(mach_task_self(), ret
);
1383 #elif defined(__NetBSD__)
1385 #elif defined(__FreeBSD__)
1389 #elif defined(__DragonFly__)
1396 /***********************************************************************
1397 * server_init_process
1399 * Start the server and create the initial socket pair.
1401 void server_init_process(void)
1403 obj_handle_t version
;
1404 const char *env_socket
= getenv( "WINESERVERSOCKET" );
1409 fd_socket
= atoi( env_socket
);
1410 if (fcntl( fd_socket
, F_SETFD
, FD_CLOEXEC
) == -1)
1411 fatal_perror( "Bad server socket %d", fd_socket
);
1412 unsetenv( "WINESERVERSOCKET" );
1416 const char *arch
= getenv( "WINEARCH" );
1418 if (arch
&& strcmp( arch
, "win32" ) && strcmp( arch
, "win64" ))
1419 fatal_error( "WINEARCH set to invalid value '%s', it must be either win32 or win64.\n", arch
);
1421 fd_socket
= server_connect();
1424 /* setup the signal mask */
1425 sigemptyset( &server_block_set
);
1426 sigaddset( &server_block_set
, SIGALRM
);
1427 sigaddset( &server_block_set
, SIGIO
);
1428 sigaddset( &server_block_set
, SIGINT
);
1429 sigaddset( &server_block_set
, SIGHUP
);
1430 sigaddset( &server_block_set
, SIGUSR1
);
1431 sigaddset( &server_block_set
, SIGUSR2
);
1432 sigaddset( &server_block_set
, SIGCHLD
);
1433 pthread_sigmask( SIG_BLOCK
, &server_block_set
, NULL
);
1435 /* receive the first thread request fd on the main socket */
1436 ntdll_get_thread_data()->request_fd
= receive_fd( &version
);
1439 /* now that we hopefully received the server_pid, disable SO_PASSCRED */
1442 setsockopt( fd_socket
, SOL_SOCKET
, SO_PASSCRED
, &enable
, sizeof(enable
) );
1446 if (version
!= SERVER_PROTOCOL_VERSION
)
1447 server_protocol_error( "version mismatch %d/%d.\n"
1448 "Your %s binary was not upgraded correctly,\n"
1449 "or you have an older one somewhere in your PATH.\n"
1450 "Or maybe the wrong wineserver is still running?\n",
1451 version
, SERVER_PROTOCOL_VERSION
,
1452 (version
> SERVER_PROTOCOL_VERSION
) ? "wine" : "wineserver" );
1453 #if defined(__linux__) && defined(HAVE_PRCTL)
1454 /* work around Ubuntu's ptrace breakage */
1455 if (server_pid
!= -1) prctl( 0x59616d61 /* PR_SET_PTRACER */, server_pid
);
1460 /***********************************************************************
1461 * server_init_process_done
1463 void CDECL
server_init_process_done( void *relay
)
1465 PEB
*peb
= NtCurrentTeb()->Peb
;
1466 IMAGE_NT_HEADERS
*nt
= get_exe_nt_header();
1467 void *entry
= (char *)peb
->ImageBaseAddress
+ nt
->OptionalHeader
.AddressOfEntryPoint
;
1472 send_server_task_port();
1474 if (nt
->FileHeader
.Characteristics
& IMAGE_FILE_LARGE_ADDRESS_AWARE
) virtual_set_large_address_space();
1476 /* Install signal handlers; this cannot be done earlier, since we cannot
1477 * send exceptions to the debugger before the create process event that
1478 * is sent by init_process_done */
1479 signal_init_process();
1481 /* Signal the parent process to continue */
1482 SERVER_START_REQ( init_process_done
)
1484 req
->module
= wine_server_client_ptr( peb
->ImageBaseAddress
);
1486 req
->ldt_copy
= wine_server_client_ptr( &__wine_ldt_copy
);
1488 req
->entry
= wine_server_client_ptr( entry
);
1489 req
->gui
= (nt
->OptionalHeader
.Subsystem
!= IMAGE_SUBSYSTEM_WINDOWS_CUI
);
1490 status
= wine_server_call( req
);
1491 suspend
= reply
->suspend
;
1496 signal_start_thread( entry
, peb
, suspend
, relay
, NtCurrentTeb() );
1500 /***********************************************************************
1501 * server_init_thread
1503 * Send an init thread request.
1505 size_t server_init_thread( void *entry_point
, BOOL
*suspend
)
1507 static const char *cpu_names
[] = { "x86", "x86_64", "PowerPC", "ARM", "ARM64" };
1508 const char *arch
= getenv( "WINEARCH" );
1511 struct sigaction sig_act
;
1515 /* ignore SIGPIPE so that we get an EPIPE error instead */
1516 sig_act
.sa_handler
= SIG_IGN
;
1517 sig_act
.sa_flags
= 0;
1518 sigemptyset( &sig_act
.sa_mask
);
1519 sigaction( SIGPIPE
, &sig_act
, NULL
);
1521 ss
.ss_sp
= get_signal_stack();
1522 ss
.ss_size
= signal_stack_size
;
1524 sigaltstack( &ss
, NULL
);
1526 /* create the server->client communication pipes */
1527 if (server_pipe( reply_pipe
) == -1) server_protocol_perror( "pipe" );
1528 if (server_pipe( ntdll_get_thread_data()->wait_fd
) == -1) server_protocol_perror( "pipe" );
1529 server_send_fd( reply_pipe
[1] );
1530 server_send_fd( ntdll_get_thread_data()->wait_fd
[1] );
1531 ntdll_get_thread_data()->reply_fd
= reply_pipe
[0];
1532 close( reply_pipe
[1] );
1534 SERVER_START_REQ( init_thread
)
1536 req
->unix_pid
= getpid();
1537 req
->unix_tid
= get_unix_tid();
1538 req
->teb
= wine_server_client_ptr( NtCurrentTeb() );
1539 req
->entry
= wine_server_client_ptr( entry_point
);
1540 req
->reply_fd
= reply_pipe
[1];
1541 req
->wait_fd
= ntdll_get_thread_data()->wait_fd
[1];
1542 req
->debug_level
= (TRACE_ON(server
) != 0);
1543 req
->cpu
= client_cpu
;
1544 ret
= wine_server_call( req
);
1545 NtCurrentTeb()->ClientId
.UniqueProcess
= ULongToHandle(reply
->pid
);
1546 NtCurrentTeb()->ClientId
.UniqueThread
= ULongToHandle(reply
->tid
);
1547 info_size
= reply
->info_size
;
1548 server_start_time
= reply
->server_start
;
1549 server_cpus
= reply
->all_cpus
;
1550 *suspend
= reply
->suspend
;
1554 is_wow64
= !is_win64
&& (server_cpus
& ((1 << CPU_x86_64
) | (1 << CPU_ARM64
))) != 0;
1555 ntdll_get_thread_data()->wow64_redir
= is_wow64
;
1559 case STATUS_SUCCESS
:
1562 if (!strcmp( arch
, "win32" ) && (is_win64
|| is_wow64
))
1563 fatal_error( "WINEARCH set to win32 but '%s' is a 64-bit installation.\n", config_dir
);
1564 if (!strcmp( arch
, "win64" ) && !is_win64
&& !is_wow64
)
1565 fatal_error( "WINEARCH set to win64 but '%s' is a 32-bit installation.\n", config_dir
);
1568 case STATUS_INVALID_IMAGE_WIN_64
:
1569 fatal_error( "'%s' is a 32-bit installation, it cannot support 64-bit applications.\n", config_dir
);
1570 case STATUS_NOT_SUPPORTED
:
1571 fatal_error( "'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.\n", config_dir
);
1572 case STATUS_INVALID_IMAGE_FORMAT
:
1573 fatal_error( "wineserver doesn't support the %s architecture\n", cpu_names
[client_cpu
] );
1575 server_protocol_error( "init_thread failed with status %x\n", ret
);
1580 /***********************************************************************
1581 * DbgUiIssueRemoteBreakin
1583 NTSTATUS WINAPI
DbgUiIssueRemoteBreakin( HANDLE process
)
1586 apc_result_t result
;
1589 memset( &call
, 0, sizeof(call
) );
1590 call
.type
= APC_BREAK_PROCESS
;
1591 status
= server_queue_process_apc( process
, &call
, &result
);
1592 if (status
) return status
;
1593 return result
.break_process
.status
;
1597 /******************************************************************************
1600 NTSTATUS WINAPI
NtDuplicateObject( HANDLE source_process
, HANDLE source
, HANDLE dest_process
, HANDLE
*dest
,
1601 ACCESS_MASK access
, ULONG attributes
, ULONG options
)
1605 SERVER_START_REQ( dup_handle
)
1607 req
->src_process
= wine_server_obj_handle( source_process
);
1608 req
->src_handle
= wine_server_obj_handle( source
);
1609 req
->dst_process
= wine_server_obj_handle( dest_process
);
1610 req
->access
= access
;
1611 req
->attributes
= attributes
;
1612 req
->options
= options
;
1613 if (!(ret
= wine_server_call( req
)))
1615 if (dest
) *dest
= wine_server_ptr_handle( reply
->handle
);
1616 if (reply
->closed
&& reply
->self
)
1618 int fd
= remove_fd_from_cache( source
);
1619 if (fd
!= -1) close( fd
);
1628 /**************************************************************************
1631 NTSTATUS WINAPI
NtClose( HANDLE handle
)
1635 int fd
= remove_fd_from_cache( handle
);
1637 SERVER_START_REQ( close_handle
)
1639 req
->handle
= wine_server_obj_handle( handle
);
1640 ret
= wine_server_call( req
);
1643 if (fd
!= -1) close( fd
);
1645 if (ret
!= STATUS_INVALID_HANDLE
|| !handle
) return ret
;
1646 if (!NtCurrentTeb()->Peb
->BeingDebugged
) return ret
;
1647 if (!NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort
, &port
, sizeof(port
), NULL
) && port
)
1649 NtCurrentTeb()->ExceptionCode
= ret
;
1650 pKiRaiseUserExceptionDispatcher();