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
34 #ifdef HAVE_PTHREAD_NP_H
35 # include <pthread_np.h>
45 #include <sys/types.h>
47 #include <sys/socket.h>
52 #ifdef HAVE_SYS_PRCTL_H
53 # include <sys/prctl.h>
56 #ifdef HAVE_SYS_SYSCALL_H
57 # include <sys/syscall.h>
67 #include <crt_externs.h>
69 #ifndef _POSIX_SPAWN_DISABLE_ASLR
70 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100
75 #define WIN32_NO_STATUS
79 #include "wine/server.h"
80 #include "wine/debug.h"
81 #include "unix_private.h"
84 WINE_DEFAULT_DEBUG_CHANNEL(server
);
86 #ifndef MSG_CMSG_CLOEXEC
87 #define MSG_CMSG_CLOEXEC 0
90 #define SOCKETNAME "socket" /* name of the socket file */
91 #define LOCKNAME "lock" /* name of the lock file */
93 static const char *server_dir
;
95 unsigned int supported_machines_count
= 0;
96 USHORT supported_machines
[8] = { 0 };
97 USHORT native_machine
= 0;
98 BOOL process_exiting
= FALSE
;
100 BOOL is_wow64
= FALSE
;
103 timeout_t server_start_time
= 0; /* time of server startup */
105 sigset_t server_block_set
; /* signals to block during server calls */
106 static int fd_socket
= -1; /* socket to exchange file descriptors with the server */
107 static int initial_cwd
= -1;
108 static pid_t server_pid
;
109 static pthread_mutex_t fd_cache_mutex
= PTHREAD_MUTEX_INITIALIZER
;
111 /* atomically exchange a 64-bit value */
112 static inline LONG64
interlocked_xchg64( LONG64
*dest
, LONG64 val
)
115 return (LONG64
)InterlockedExchangePointer( (void **)dest
, (void *)val
);
118 while (InterlockedCompareExchange64( dest
, val
, tmp
) != tmp
) tmp
= *dest
;
124 static void fatal_error( const char *err
, ... ) __attribute__((noreturn
, format(printf
,1,2)));
125 static void fatal_perror( const char *err
, ... ) __attribute__((noreturn
, format(printf
,1,2)));
126 static void server_connect_error( const char *serverdir
) __attribute__((noreturn
));
129 /* die on a fatal error; use only during initialization */
130 static void fatal_error( const char *err
, ... )
134 va_start( args
, err
);
135 fprintf( stderr
, "wine: " );
136 vfprintf( stderr
, err
, args
);
141 /* die on a fatal error; use only during initialization */
142 static void fatal_perror( const char *err
, ... )
146 va_start( args
, err
);
147 fprintf( stderr
, "wine: " );
148 vfprintf( stderr
, err
, args
);
154 /***********************************************************************
155 * server_protocol_error
157 static DECLSPEC_NORETURN
void server_protocol_error( const char *err
, ... )
161 va_start( args
, err
);
162 fprintf( stderr
, "wine client error:%x: ", GetCurrentThreadId() );
163 vfprintf( stderr
, err
, args
);
169 /***********************************************************************
170 * server_protocol_perror
172 static DECLSPEC_NORETURN
void server_protocol_perror( const char *err
)
174 fprintf( stderr
, "wine client error:%x: ", GetCurrentThreadId() );
180 /***********************************************************************
183 * Send a request to the server.
185 static unsigned int send_request( const struct __server_request_info
*req
)
190 if (!req
->u
.req
.request_header
.request_size
)
192 if ((ret
= write( ntdll_get_thread_data()->request_fd
, &req
->u
.req
,
193 sizeof(req
->u
.req
) )) == sizeof(req
->u
.req
)) return STATUS_SUCCESS
;
198 struct iovec vec
[__SERVER_MAX_DATA
+1];
200 vec
[0].iov_base
= (void *)&req
->u
.req
;
201 vec
[0].iov_len
= sizeof(req
->u
.req
);
202 for (i
= 0; i
< req
->data_count
; i
++)
204 vec
[i
+1].iov_base
= (void *)req
->data
[i
].ptr
;
205 vec
[i
+1].iov_len
= req
->data
[i
].size
;
207 if ((ret
= writev( ntdll_get_thread_data()->request_fd
, vec
, i
+1 )) ==
208 req
->u
.req
.request_header
.request_size
+ sizeof(req
->u
.req
)) return STATUS_SUCCESS
;
211 if (ret
>= 0) server_protocol_error( "partial write %d\n", ret
);
212 if (errno
== EPIPE
) abort_thread(0);
213 if (errno
== EFAULT
) return STATUS_ACCESS_VIOLATION
;
214 server_protocol_perror( "write" );
218 /***********************************************************************
221 * Read data from the reply buffer; helper for wait_reply.
223 static void read_reply_data( void *buffer
, size_t size
)
229 if ((ret
= read( ntdll_get_thread_data()->reply_fd
, buffer
, size
)) > 0)
231 if (!(size
-= ret
)) return;
232 buffer
= (char *)buffer
+ ret
;
236 if (errno
== EINTR
) continue;
237 if (errno
== EPIPE
) break;
238 server_protocol_perror("read");
240 /* the server closed the connection; time to die... */
245 /***********************************************************************
248 * Wait for a reply from the server.
250 static inline unsigned int wait_reply( struct __server_request_info
*req
)
252 read_reply_data( &req
->u
.reply
, sizeof(req
->u
.reply
) );
253 if (req
->u
.reply
.reply_header
.reply_size
)
254 read_reply_data( req
->reply_data
, req
->u
.reply
.reply_header
.reply_size
);
255 return req
->u
.reply
.reply_header
.error
;
259 /***********************************************************************
260 * server_call_unlocked
262 unsigned int server_call_unlocked( void *req_ptr
)
264 struct __server_request_info
* const req
= req_ptr
;
267 if ((ret
= send_request( req
))) return ret
;
268 return wait_reply( req
);
272 /***********************************************************************
275 * Perform a server call.
277 unsigned int CDECL
wine_server_call( void *req_ptr
)
282 pthread_sigmask( SIG_BLOCK
, &server_block_set
, &old_set
);
283 ret
= server_call_unlocked( req_ptr
);
284 pthread_sigmask( SIG_SETMASK
, &old_set
, NULL
);
289 /***********************************************************************
290 * server_enter_uninterrupted_section
292 void server_enter_uninterrupted_section( pthread_mutex_t
*mutex
, sigset_t
*sigset
)
294 pthread_sigmask( SIG_BLOCK
, &server_block_set
, sigset
);
299 /***********************************************************************
300 * server_leave_uninterrupted_section
302 void server_leave_uninterrupted_section( pthread_mutex_t
*mutex
, sigset_t
*sigset
)
304 mutex_unlock( mutex
);
305 pthread_sigmask( SIG_SETMASK
, sigset
, NULL
);
309 /***********************************************************************
312 * Wait for a reply on the waiting pipe of the current thread.
314 static int wait_select_reply( void *cookie
)
317 struct wake_up_reply reply
;
321 ret
= read( ntdll_get_thread_data()->wait_fd
[0], &reply
, sizeof(reply
) );
322 if (ret
== sizeof(reply
))
324 if (!reply
.cookie
) abort_thread( reply
.signaled
); /* thread got killed */
325 if (wine_server_get_ptr(reply
.cookie
) == cookie
) return reply
.signaled
;
326 /* we stole another reply, wait for the real one */
327 signaled
= wait_select_reply( cookie
);
328 /* and now put the wrong one back in the pipe */
331 ret
= write( ntdll_get_thread_data()->wait_fd
[1], &reply
, sizeof(reply
) );
332 if (ret
== sizeof(reply
)) break;
333 if (ret
>= 0) server_protocol_error( "partial wakeup write %d\n", ret
);
334 if (errno
== EINTR
) continue;
335 server_protocol_perror("wakeup write");
339 if (ret
>= 0) server_protocol_error( "partial wakeup read %d\n", ret
);
340 if (errno
== EINTR
) continue;
341 server_protocol_perror("wakeup read");
346 /***********************************************************************
349 static NTSTATUS
invoke_user_apc( CONTEXT
*context
, const user_apc_t
*apc
, NTSTATUS status
)
351 return call_user_apc_dispatcher( context
, apc
->args
[0], apc
->args
[1], apc
->args
[2],
352 wine_server_get_ptr( apc
->func
), status
);
356 /***********************************************************************
359 static void invoke_system_apc( const apc_call_t
*call
, apc_result_t
*result
, BOOL self
)
364 memset( result
, 0, sizeof(*result
) );
372 struct async_fileio
*user
= wine_server_get_ptr( call
->async_io
.user
);
373 ULONG_PTR info
= call
->async_io
.result
;
376 result
->type
= call
->type
;
377 status
= call
->async_io
.status
;
378 if (user
->callback( user
, &info
, &status
))
380 result
->async_io
.status
= status
;
381 result
->async_io
.total
= info
;
382 /* the server will pass us NULL if a call failed synchronously */
383 set_async_iosb( call
->async_io
.sb
, result
->async_io
.status
, info
);
385 else result
->async_io
.status
= STATUS_PENDING
; /* restart it */
388 case APC_VIRTUAL_ALLOC
:
389 result
->type
= call
->type
;
390 addr
= wine_server_get_ptr( call
->virtual_alloc
.addr
);
391 size
= call
->virtual_alloc
.size
;
392 bits
= call
->virtual_alloc
.zero_bits
;
393 if ((ULONG_PTR
)addr
== call
->virtual_alloc
.addr
&& size
== call
->virtual_alloc
.size
&&
394 bits
== call
->virtual_alloc
.zero_bits
)
396 result
->virtual_alloc
.status
= NtAllocateVirtualMemory( NtCurrentProcess(), &addr
, bits
, &size
,
397 call
->virtual_alloc
.op_type
,
398 call
->virtual_alloc
.prot
);
399 result
->virtual_alloc
.addr
= wine_server_client_ptr( addr
);
400 result
->virtual_alloc
.size
= size
;
402 else result
->virtual_alloc
.status
= STATUS_WORKING_SET_LIMIT_RANGE
;
404 case APC_VIRTUAL_FREE
:
405 result
->type
= call
->type
;
406 addr
= wine_server_get_ptr( call
->virtual_free
.addr
);
407 size
= call
->virtual_free
.size
;
408 if ((ULONG_PTR
)addr
== call
->virtual_free
.addr
&& size
== call
->virtual_free
.size
)
410 result
->virtual_free
.status
= NtFreeVirtualMemory( NtCurrentProcess(), &addr
, &size
,
411 call
->virtual_free
.op_type
);
412 result
->virtual_free
.addr
= wine_server_client_ptr( addr
);
413 result
->virtual_free
.size
= size
;
415 else result
->virtual_free
.status
= STATUS_INVALID_PARAMETER
;
417 case APC_VIRTUAL_QUERY
:
419 MEMORY_BASIC_INFORMATION info
;
420 result
->type
= call
->type
;
421 addr
= wine_server_get_ptr( call
->virtual_query
.addr
);
422 if ((ULONG_PTR
)addr
== call
->virtual_query
.addr
)
423 result
->virtual_query
.status
= NtQueryVirtualMemory( NtCurrentProcess(),
424 addr
, MemoryBasicInformation
, &info
,
425 sizeof(info
), NULL
);
427 result
->virtual_query
.status
= STATUS_WORKING_SET_LIMIT_RANGE
;
429 if (result
->virtual_query
.status
== STATUS_SUCCESS
)
431 result
->virtual_query
.base
= wine_server_client_ptr( info
.BaseAddress
);
432 result
->virtual_query
.alloc_base
= wine_server_client_ptr( info
.AllocationBase
);
433 result
->virtual_query
.size
= info
.RegionSize
;
434 result
->virtual_query
.prot
= info
.Protect
;
435 result
->virtual_query
.alloc_prot
= info
.AllocationProtect
;
436 result
->virtual_query
.state
= info
.State
>> 12;
437 result
->virtual_query
.alloc_type
= info
.Type
>> 16;
441 case APC_VIRTUAL_PROTECT
:
442 result
->type
= call
->type
;
443 addr
= wine_server_get_ptr( call
->virtual_protect
.addr
);
444 size
= call
->virtual_protect
.size
;
445 if ((ULONG_PTR
)addr
== call
->virtual_protect
.addr
&& size
== call
->virtual_protect
.size
)
447 result
->virtual_protect
.status
= NtProtectVirtualMemory( NtCurrentProcess(), &addr
, &size
,
448 call
->virtual_protect
.prot
,
449 &result
->virtual_protect
.prot
);
450 result
->virtual_protect
.addr
= wine_server_client_ptr( addr
);
451 result
->virtual_protect
.size
= size
;
453 else result
->virtual_protect
.status
= STATUS_INVALID_PARAMETER
;
455 case APC_VIRTUAL_FLUSH
:
456 result
->type
= call
->type
;
457 addr
= wine_server_get_ptr( call
->virtual_flush
.addr
);
458 size
= call
->virtual_flush
.size
;
459 if ((ULONG_PTR
)addr
== call
->virtual_flush
.addr
&& size
== call
->virtual_flush
.size
)
461 result
->virtual_flush
.status
= NtFlushVirtualMemory( NtCurrentProcess(),
462 (const void **)&addr
, &size
, 0 );
463 result
->virtual_flush
.addr
= wine_server_client_ptr( addr
);
464 result
->virtual_flush
.size
= size
;
466 else result
->virtual_flush
.status
= STATUS_INVALID_PARAMETER
;
468 case APC_VIRTUAL_LOCK
:
469 result
->type
= call
->type
;
470 addr
= wine_server_get_ptr( call
->virtual_lock
.addr
);
471 size
= call
->virtual_lock
.size
;
472 if ((ULONG_PTR
)addr
== call
->virtual_lock
.addr
&& size
== call
->virtual_lock
.size
)
474 result
->virtual_lock
.status
= NtLockVirtualMemory( NtCurrentProcess(), &addr
, &size
, 0 );
475 result
->virtual_lock
.addr
= wine_server_client_ptr( addr
);
476 result
->virtual_lock
.size
= size
;
478 else result
->virtual_lock
.status
= STATUS_INVALID_PARAMETER
;
480 case APC_VIRTUAL_UNLOCK
:
481 result
->type
= call
->type
;
482 addr
= wine_server_get_ptr( call
->virtual_unlock
.addr
);
483 size
= call
->virtual_unlock
.size
;
484 if ((ULONG_PTR
)addr
== call
->virtual_unlock
.addr
&& size
== call
->virtual_unlock
.size
)
486 result
->virtual_unlock
.status
= NtUnlockVirtualMemory( NtCurrentProcess(), &addr
, &size
, 0 );
487 result
->virtual_unlock
.addr
= wine_server_client_ptr( addr
);
488 result
->virtual_unlock
.size
= size
;
490 else result
->virtual_unlock
.status
= STATUS_INVALID_PARAMETER
;
493 result
->type
= call
->type
;
494 addr
= wine_server_get_ptr( call
->map_view
.addr
);
495 size
= call
->map_view
.size
;
496 bits
= call
->map_view
.zero_bits
;
497 if ((ULONG_PTR
)addr
== call
->map_view
.addr
&& size
== call
->map_view
.size
&&
498 bits
== call
->map_view
.zero_bits
)
500 LARGE_INTEGER offset
;
501 offset
.QuadPart
= call
->map_view
.offset
;
502 result
->map_view
.status
= NtMapViewOfSection( wine_server_ptr_handle(call
->map_view
.handle
),
504 &addr
, bits
, 0, &offset
, &size
, 0,
505 call
->map_view
.alloc_type
, call
->map_view
.prot
);
506 result
->map_view
.addr
= wine_server_client_ptr( addr
);
507 result
->map_view
.size
= size
;
509 else result
->map_view
.status
= STATUS_INVALID_PARAMETER
;
510 if (!self
) NtClose( wine_server_ptr_handle(call
->map_view
.handle
) );
513 result
->type
= call
->type
;
514 addr
= wine_server_get_ptr( call
->unmap_view
.addr
);
515 if ((ULONG_PTR
)addr
== call
->unmap_view
.addr
)
516 result
->unmap_view
.status
= NtUnmapViewOfSection( NtCurrentProcess(), addr
);
518 result
->unmap_view
.status
= STATUS_INVALID_PARAMETER
;
520 case APC_CREATE_THREAD
:
522 ULONG_PTR buffer
[offsetof( PS_ATTRIBUTE_LIST
, Attributes
[2] ) / sizeof(ULONG_PTR
)];
523 PS_ATTRIBUTE_LIST
*attr
= (PS_ATTRIBUTE_LIST
*)buffer
;
527 ULONG_PTR zero_bits
= call
->create_thread
.zero_bits
;
528 SIZE_T reserve
= call
->create_thread
.reserve
;
529 SIZE_T commit
= call
->create_thread
.commit
;
530 void *func
= wine_server_get_ptr( call
->create_thread
.func
);
531 void *arg
= wine_server_get_ptr( call
->create_thread
.arg
);
533 result
->type
= call
->type
;
534 if (reserve
== call
->create_thread
.reserve
&& commit
== call
->create_thread
.commit
&&
535 (ULONG_PTR
)func
== call
->create_thread
.func
&& (ULONG_PTR
)arg
== call
->create_thread
.arg
)
538 /* FIXME: hack for debugging 32-bit process without a 64-bit ntdll */
539 if (is_wow64
&& func
== (void *)0x7ffe1000) func
= pDbgUiRemoteBreakin
;
541 attr
->TotalLength
= sizeof(buffer
);
542 attr
->Attributes
[0].Attribute
= PS_ATTRIBUTE_CLIENT_ID
;
543 attr
->Attributes
[0].Size
= sizeof(id
);
544 attr
->Attributes
[0].ValuePtr
= &id
;
545 attr
->Attributes
[0].ReturnLength
= NULL
;
546 attr
->Attributes
[1].Attribute
= PS_ATTRIBUTE_TEB_ADDRESS
;
547 attr
->Attributes
[1].Size
= sizeof(teb
);
548 attr
->Attributes
[1].ValuePtr
= &teb
;
549 attr
->Attributes
[1].ReturnLength
= NULL
;
550 result
->create_thread
.status
= NtCreateThreadEx( &handle
, THREAD_ALL_ACCESS
, NULL
,
551 NtCurrentProcess(), func
, arg
,
552 call
->create_thread
.flags
, zero_bits
,
553 commit
, reserve
, attr
);
554 result
->create_thread
.handle
= wine_server_obj_handle( handle
);
555 result
->create_thread
.pid
= HandleToULong(id
.UniqueProcess
);
556 result
->create_thread
.tid
= HandleToULong(id
.UniqueThread
);
557 result
->create_thread
.teb
= wine_server_client_ptr( teb
);
559 else result
->create_thread
.status
= STATUS_INVALID_PARAMETER
;
564 HANDLE dst_handle
= NULL
;
566 result
->type
= call
->type
;
568 result
->dup_handle
.status
= NtDuplicateObject( NtCurrentProcess(),
569 wine_server_ptr_handle(call
->dup_handle
.src_handle
),
570 wine_server_ptr_handle(call
->dup_handle
.dst_process
),
571 &dst_handle
, call
->dup_handle
.access
,
572 call
->dup_handle
.attributes
, call
->dup_handle
.options
);
573 result
->dup_handle
.handle
= wine_server_obj_handle( dst_handle
);
574 if (!self
) NtClose( wine_server_ptr_handle(call
->dup_handle
.dst_process
) );
578 server_protocol_error( "get_apc_request: bad type %d\n", call
->type
);
584 /***********************************************************************
587 unsigned int server_select( const select_op_t
*select_op
, data_size_t size
, UINT flags
,
588 timeout_t abs_timeout
, context_t
*context
, user_apc_t
*user_apc
)
592 obj_handle_t apc_handle
= 0;
593 BOOL suspend_context
= !!context
;
599 memset( &result
, 0, sizeof(result
) );
603 pthread_sigmask( SIG_BLOCK
, &server_block_set
, &old_set
);
606 SERVER_START_REQ( select
)
609 req
->cookie
= wine_server_client_ptr( &cookie
);
610 req
->prev_apc
= apc_handle
;
611 req
->timeout
= abs_timeout
;
613 wine_server_add_data( req
, &result
, sizeof(result
) );
614 wine_server_add_data( req
, select_op
, size
);
617 data_size_t ctx_size
= (context
[1].machine
? 2 : 1) * sizeof(*context
);
618 wine_server_add_data( req
, context
, ctx_size
);
619 suspend_context
= FALSE
; /* server owns the context now */
621 if (context
) wine_server_set_reply( req
, context
, 2 * sizeof(*context
) );
622 ret
= server_call_unlocked( req
);
623 signaled
= reply
->signaled
;
624 apc_handle
= reply
->apc_handle
;
629 if (ret
!= STATUS_KERNEL_APC
) break;
630 invoke_system_apc( &call
, &result
, FALSE
);
632 /* don't signal multiple times */
633 if (size
>= sizeof(select_op
->signal_and_wait
) && select_op
->op
== SELECT_SIGNAL_AND_WAIT
)
634 size
= offsetof( select_op_t
, signal_and_wait
.signal
);
636 pthread_sigmask( SIG_SETMASK
, &old_set
, NULL
);
639 ret
= wait_select_reply( &cookie
);
641 while (ret
== STATUS_USER_APC
|| ret
== STATUS_KERNEL_APC
);
643 if (ret
== STATUS_USER_APC
) *user_apc
= call
.user
;
648 /***********************************************************************
651 unsigned int server_wait( const select_op_t
*select_op
, data_size_t size
, UINT flags
,
652 const LARGE_INTEGER
*timeout
)
654 timeout_t abs_timeout
= timeout
? timeout
->QuadPart
: TIMEOUT_INFINITE
;
662 NtQueryPerformanceCounter( &now
, NULL
);
663 abs_timeout
-= now
.QuadPart
;
666 ret
= server_select( select_op
, size
, flags
, abs_timeout
, NULL
, &apc
);
667 if (ret
== STATUS_USER_APC
) return invoke_user_apc( NULL
, &apc
, ret
);
669 /* A test on Windows 2000 shows that Windows always yields during
670 a wait, but a wait that is hit by an event gets a priority
671 boost as well. This seems to model that behavior the closest. */
672 if (ret
== STATUS_TIMEOUT
) NtYieldExecution();
677 /***********************************************************************
678 * NtContinue (NTDLL.@)
680 NTSTATUS WINAPI
NtContinue( CONTEXT
*context
, BOOLEAN alertable
)
687 status
= server_select( NULL
, 0, SELECT_INTERRUPTIBLE
| SELECT_ALERTABLE
, 0, NULL
, &apc
);
688 if (status
== STATUS_USER_APC
) return invoke_user_apc( context
, &apc
, status
);
690 return signal_set_full_context( context
);
694 /***********************************************************************
695 * NtTestAlert (NTDLL.@)
697 NTSTATUS WINAPI
NtTestAlert(void)
702 status
= server_select( NULL
, 0, SELECT_INTERRUPTIBLE
| SELECT_ALERTABLE
, 0, NULL
, &apc
);
703 if (status
== STATUS_USER_APC
) invoke_user_apc( NULL
, &apc
, STATUS_SUCCESS
);
704 return STATUS_SUCCESS
;
708 /***********************************************************************
709 * server_queue_process_apc
711 unsigned int server_queue_process_apc( HANDLE process
, const apc_call_t
*call
, apc_result_t
*result
)
719 SERVER_START_REQ( queue_apc
)
721 req
->handle
= wine_server_obj_handle( process
);
723 if (!(ret
= wine_server_call( req
)))
725 handle
= wine_server_ptr_handle( reply
->handle
);
730 if (ret
!= STATUS_SUCCESS
) return ret
;
734 invoke_system_apc( call
, result
, TRUE
);
738 NtWaitForSingleObject( handle
, FALSE
, NULL
);
740 SERVER_START_REQ( get_apc_result
)
742 req
->handle
= wine_server_obj_handle( handle
);
743 if (!(ret
= wine_server_call( req
))) *result
= reply
->result
;
747 if (!ret
&& result
->type
== APC_NONE
) continue; /* APC didn't run, try again */
754 /***********************************************************************
755 * wine_server_send_fd
757 * Send a file descriptor to the server.
759 void wine_server_send_fd( int fd
)
762 struct msghdr msghdr
;
766 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
767 msghdr
.msg_accrights
= (void *)&fd
;
768 msghdr
.msg_accrightslen
= sizeof(fd
);
769 #else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
770 char cmsg_buffer
[256];
771 struct cmsghdr
*cmsg
;
772 msghdr
.msg_control
= cmsg_buffer
;
773 msghdr
.msg_controllen
= sizeof(cmsg_buffer
);
774 msghdr
.msg_flags
= 0;
775 cmsg
= CMSG_FIRSTHDR( &msghdr
);
776 cmsg
->cmsg_len
= CMSG_LEN( sizeof(fd
) );
777 cmsg
->cmsg_level
= SOL_SOCKET
;
778 cmsg
->cmsg_type
= SCM_RIGHTS
;
779 *(int *)CMSG_DATA(cmsg
) = fd
;
780 msghdr
.msg_controllen
= cmsg
->cmsg_len
;
781 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
783 msghdr
.msg_name
= NULL
;
784 msghdr
.msg_namelen
= 0;
785 msghdr
.msg_iov
= &vec
;
786 msghdr
.msg_iovlen
= 1;
788 vec
.iov_base
= (void *)&data
;
789 vec
.iov_len
= sizeof(data
);
791 data
.tid
= GetCurrentThreadId();
796 if ((ret
= sendmsg( fd_socket
, &msghdr
, 0 )) == sizeof(data
)) return;
797 if (ret
>= 0) server_protocol_error( "partial write %d\n", ret
);
798 if (errno
== EINTR
) continue;
799 if (errno
== EPIPE
) abort_thread(0);
800 server_protocol_perror( "sendmsg" );
805 /***********************************************************************
808 * Receive a file descriptor passed from the server.
810 static int receive_fd( obj_handle_t
*handle
)
813 struct msghdr msghdr
;
816 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
817 msghdr
.msg_accrights
= (void *)&fd
;
818 msghdr
.msg_accrightslen
= sizeof(fd
);
819 #else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
820 char cmsg_buffer
[256];
821 msghdr
.msg_control
= cmsg_buffer
;
822 msghdr
.msg_controllen
= sizeof(cmsg_buffer
);
823 msghdr
.msg_flags
= 0;
824 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
826 msghdr
.msg_name
= NULL
;
827 msghdr
.msg_namelen
= 0;
828 msghdr
.msg_iov
= &vec
;
829 msghdr
.msg_iovlen
= 1;
830 vec
.iov_base
= (void *)handle
;
831 vec
.iov_len
= sizeof(*handle
);
835 if ((ret
= recvmsg( fd_socket
, &msghdr
, MSG_CMSG_CLOEXEC
)) > 0)
837 #ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
838 struct cmsghdr
*cmsg
;
839 for (cmsg
= CMSG_FIRSTHDR( &msghdr
); cmsg
; cmsg
= CMSG_NXTHDR( &msghdr
, cmsg
))
841 if (cmsg
->cmsg_level
!= SOL_SOCKET
) continue;
842 if (cmsg
->cmsg_type
== SCM_RIGHTS
) fd
= *(int *)CMSG_DATA(cmsg
);
843 #ifdef SCM_CREDENTIALS
844 else if (cmsg
->cmsg_type
== SCM_CREDENTIALS
)
846 struct ucred
*ucred
= (struct ucred
*)CMSG_DATA(cmsg
);
847 server_pid
= ucred
->pid
;
851 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
852 if (fd
!= -1) fcntl( fd
, F_SETFD
, FD_CLOEXEC
); /* in case MSG_CMSG_CLOEXEC is not supported */
856 if (errno
== EINTR
) continue;
857 if (errno
== EPIPE
) break;
858 server_protocol_perror("recvmsg");
860 /* the server closed the connection; time to die... */
865 /***********************************************************************/
866 /* fd cache support */
874 enum server_fd_type type
: 5;
875 unsigned int access
: 3;
876 unsigned int options
: 24;
880 C_ASSERT( sizeof(union fd_cache_entry
) == sizeof(LONG64
) );
882 #define FD_CACHE_BLOCK_SIZE (65536 / sizeof(union fd_cache_entry))
883 #define FD_CACHE_ENTRIES 128
885 static union fd_cache_entry
*fd_cache
[FD_CACHE_ENTRIES
];
886 static union fd_cache_entry fd_cache_initial_block
[FD_CACHE_BLOCK_SIZE
];
888 static inline unsigned int handle_to_index( HANDLE handle
, unsigned int *entry
)
890 unsigned int idx
= (wine_server_obj_handle(handle
) >> 2) - 1;
891 *entry
= idx
/ FD_CACHE_BLOCK_SIZE
;
892 return idx
% FD_CACHE_BLOCK_SIZE
;
896 /***********************************************************************
899 * Caller must hold fd_cache_mutex.
901 static BOOL
add_fd_to_cache( HANDLE handle
, int fd
, enum server_fd_type type
,
902 unsigned int access
, unsigned int options
)
904 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
905 union fd_cache_entry cache
;
907 if (entry
>= FD_CACHE_ENTRIES
)
909 FIXME( "too many allocated handles, not caching %p\n", handle
);
913 if (!fd_cache
[entry
]) /* do we need to allocate a new block of entries? */
915 if (!entry
) fd_cache
[0] = fd_cache_initial_block
;
918 void *ptr
= anon_mmap_alloc( FD_CACHE_BLOCK_SIZE
* sizeof(union fd_cache_entry
),
919 PROT_READ
| PROT_WRITE
);
920 if (ptr
== MAP_FAILED
) return FALSE
;
921 fd_cache
[entry
] = ptr
;
925 /* store fd+1 so that 0 can be used as the unset value */
928 cache
.s
.access
= access
;
929 cache
.s
.options
= options
;
930 cache
.data
= interlocked_xchg64( &fd_cache
[entry
][idx
].data
, cache
.data
);
931 assert( !cache
.s
.fd
);
936 /***********************************************************************
939 static inline NTSTATUS
get_cached_fd( HANDLE handle
, int *fd
, enum server_fd_type
*type
,
940 unsigned int *access
, unsigned int *options
)
942 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
943 union fd_cache_entry cache
;
945 if (entry
>= FD_CACHE_ENTRIES
|| !fd_cache
[entry
]) return STATUS_INVALID_HANDLE
;
947 cache
.data
= InterlockedCompareExchange64( &fd_cache
[entry
][idx
].data
, 0, 0 );
948 if (!cache
.data
) return STATUS_INVALID_HANDLE
;
950 /* if fd type is invalid, fd stores an error value */
951 if (cache
.s
.type
== FD_TYPE_INVALID
) return cache
.s
.fd
- 1;
953 *fd
= cache
.s
.fd
- 1;
954 if (type
) *type
= cache
.s
.type
;
955 if (access
) *access
= cache
.s
.access
;
956 if (options
) *options
= cache
.s
.options
;
957 return STATUS_SUCCESS
;
961 /***********************************************************************
962 * remove_fd_from_cache
964 static int remove_fd_from_cache( HANDLE handle
)
966 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
969 if (entry
< FD_CACHE_ENTRIES
&& fd_cache
[entry
])
971 union fd_cache_entry cache
;
972 cache
.data
= interlocked_xchg64( &fd_cache
[entry
][idx
].data
, 0 );
973 if (cache
.s
.type
!= FD_TYPE_INVALID
) fd
= cache
.s
.fd
- 1;
980 /***********************************************************************
983 * The returned unix_fd should be closed iff needs_close is non-zero.
985 int server_get_unix_fd( HANDLE handle
, unsigned int wanted_access
, int *unix_fd
,
986 int *needs_close
, enum server_fd_type
*type
, unsigned int *options
)
989 obj_handle_t fd_handle
;
991 unsigned int access
= 0;
995 wanted_access
&= FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_APPEND_DATA
;
997 ret
= get_cached_fd( handle
, &fd
, type
, &access
, options
);
998 if (ret
!= STATUS_INVALID_HANDLE
) goto done
;
1000 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1001 ret
= get_cached_fd( handle
, &fd
, type
, &access
, options
);
1002 if (ret
== STATUS_INVALID_HANDLE
)
1004 SERVER_START_REQ( get_handle_fd
)
1006 req
->handle
= wine_server_obj_handle( handle
);
1007 if (!(ret
= wine_server_call( req
)))
1009 if (type
) *type
= reply
->type
;
1010 if (options
) *options
= reply
->options
;
1011 access
= reply
->access
;
1012 if ((fd
= receive_fd( &fd_handle
)) != -1)
1014 assert( wine_server_ptr_handle(fd_handle
) == handle
);
1015 *needs_close
= (!reply
->cacheable
||
1016 !add_fd_to_cache( handle
, fd
, reply
->type
,
1017 reply
->access
, reply
->options
));
1019 else ret
= STATUS_TOO_MANY_OPENED_FILES
;
1021 else if (reply
->cacheable
)
1023 add_fd_to_cache( handle
, ret
, FD_TYPE_INVALID
, 0, 0 );
1028 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1031 if (!ret
&& ((access
& wanted_access
) != wanted_access
))
1033 ret
= STATUS_ACCESS_DENIED
;
1034 if (*needs_close
) close( fd
);
1036 if (!ret
) *unix_fd
= fd
;
1041 /***********************************************************************
1042 * wine_server_fd_to_handle
1044 NTSTATUS CDECL
wine_server_fd_to_handle( int fd
, unsigned int access
, unsigned int attributes
, HANDLE
*handle
)
1049 wine_server_send_fd( fd
);
1051 SERVER_START_REQ( alloc_file_handle
)
1053 req
->access
= access
;
1054 req
->attributes
= attributes
;
1056 if (!(ret
= wine_server_call( req
))) *handle
= wine_server_ptr_handle( reply
->handle
);
1063 /***********************************************************************
1064 * wine_server_handle_to_fd
1066 * Retrieve the file descriptor corresponding to a file handle.
1068 NTSTATUS CDECL
wine_server_handle_to_fd( HANDLE handle
, unsigned int access
, int *unix_fd
,
1069 unsigned int *options
)
1072 NTSTATUS ret
= server_get_unix_fd( handle
, access
, unix_fd
, &needs_close
, NULL
, options
);
1074 if (!ret
&& !needs_close
)
1076 if ((*unix_fd
= dup(*unix_fd
)) == -1) ret
= STATUS_TOO_MANY_OPENED_FILES
;
1082 /***********************************************************************
1085 * Create a pipe for communicating with the server.
1087 int server_pipe( int fd
[2] )
1091 static BOOL have_pipe2
= TRUE
;
1095 if (!(ret
= pipe2( fd
, O_CLOEXEC
))) return ret
;
1096 if (errno
== ENOSYS
|| errno
== EINVAL
) have_pipe2
= FALSE
; /* don't try again */
1099 if (!(ret
= pipe( fd
)))
1101 fcntl( fd
[0], F_SETFD
, FD_CLOEXEC
);
1102 fcntl( fd
[1], F_SETFD
, FD_CLOEXEC
);
1108 /***********************************************************************
1111 static const char *init_server_dir( dev_t dev
, ino_t ino
)
1114 size_t len
= sizeof("/server-") + 2 * sizeof(dev
) + 2 * sizeof(ino
) + 2;
1116 #ifdef __ANDROID__ /* there's no /tmp dir on Android */
1117 len
+= strlen( config_dir
) + sizeof("/.wineserver");
1118 dir
= malloc( len
);
1119 strcpy( dir
, config_dir
);
1120 strcat( dir
, "/.wineserver/server-" );
1122 len
+= sizeof("/tmp/.wine-") + 12;
1123 dir
= malloc( len
);
1124 sprintf( dir
, "/tmp/.wine-%u/server-", getuid() );
1126 p
= dir
+ strlen( dir
);
1127 if (dev
!= (unsigned long)dev
)
1128 p
+= sprintf( p
, "%lx%08lx-", (unsigned long)((unsigned long long)dev
>> 32), (unsigned long)dev
);
1130 p
+= sprintf( p
, "%lx-", (unsigned long)dev
);
1132 if (ino
!= (unsigned long)ino
)
1133 sprintf( p
, "%lx%08lx", (unsigned long)((unsigned long long)ino
>> 32), (unsigned long)ino
);
1135 sprintf( p
, "%lx", (unsigned long)ino
);
1140 /***********************************************************************
1143 * Setup the wine configuration dir.
1145 static int setup_config_dir(void)
1149 int fd_cwd
= open( ".", O_RDONLY
);
1151 if (chdir( config_dir
) == -1)
1153 if (errno
!= ENOENT
) fatal_perror( "cannot use directory %s", config_dir
);
1154 if ((p
= strrchr( config_dir
, '/' )) && p
!= config_dir
)
1156 while (p
> config_dir
+ 1 && p
[-1] == '/') p
--;
1158 if (!stat( config_dir
, &st
) && st
.st_uid
!= getuid())
1159 fatal_error( "'%s' is not owned by you, refusing to create a configuration directory there\n",
1163 mkdir( config_dir
, 0777 );
1164 if (chdir( config_dir
) == -1) fatal_perror( "chdir to %s", config_dir
);
1165 MESSAGE( "wine: created the configuration directory '%s'\n", config_dir
);
1168 if (stat( ".", &st
) == -1) fatal_perror( "stat %s", config_dir
);
1169 if (st
.st_uid
!= getuid()) fatal_error( "'%s' is not owned by you\n", config_dir
);
1171 server_dir
= init_server_dir( st
.st_dev
, st
.st_ino
);
1173 if (!mkdir( "dosdevices", 0777 ))
1175 mkdir( "drive_c", 0777 );
1176 symlink( "../drive_c", "dosdevices/c:" );
1177 symlink( "/", "dosdevices/z:" );
1179 else if (errno
!= EEXIST
) fatal_perror( "cannot create %s/dosdevices", config_dir
);
1181 if (fd_cwd
== -1) fd_cwd
= open( "dosdevices/c:", O_RDONLY
);
1182 fcntl( fd_cwd
, F_SETFD
, FD_CLOEXEC
);
1187 /***********************************************************************
1188 * server_connect_error
1190 * Try to display a meaningful explanation of why we couldn't connect
1193 static void server_connect_error( const char *serverdir
)
1198 if ((fd
= open( LOCKNAME
, O_WRONLY
)) == -1)
1199 fatal_error( "for some mysterious reason, the wine server never started.\n" );
1201 fl
.l_type
= F_WRLCK
;
1202 fl
.l_whence
= SEEK_SET
;
1205 if (fcntl( fd
, F_GETLK
, &fl
) != -1)
1207 if (fl
.l_type
== F_WRLCK
) /* the file is locked */
1208 fatal_error( "a wine server seems to be running, but I cannot connect to it.\n"
1209 " You probably need to kill that process (it might be pid %d).\n",
1211 fatal_error( "for some mysterious reason, the wine server failed to run.\n" );
1213 fatal_error( "the file system of '%s' doesn't support locks,\n"
1214 " and there is a 'socket' file in that directory that prevents wine from starting.\n"
1215 " You should make sure no wine server is running, remove that file and try again.\n",
1220 /***********************************************************************
1223 * Attempt to connect to an existing server socket.
1225 static int server_connect(void)
1227 struct sockaddr_un addr
;
1231 initial_cwd
= setup_config_dir();
1233 /* chdir to the server directory */
1234 if (chdir( server_dir
) == -1)
1236 if (errno
!= ENOENT
) fatal_perror( "chdir to %s", server_dir
);
1237 start_server( TRACE_ON(server
) );
1238 if (chdir( server_dir
) == -1) fatal_perror( "chdir to %s", server_dir
);
1241 /* make sure we are at the right place */
1242 if (stat( ".", &st
) == -1) fatal_perror( "stat %s", server_dir
);
1243 if (st
.st_uid
!= getuid()) fatal_error( "'%s' is not owned by you\n", server_dir
);
1244 if (st
.st_mode
& 077) fatal_error( "'%s' must not be accessible by other users\n", server_dir
);
1246 for (retry
= 0; retry
< 6; retry
++)
1248 /* if not the first try, wait a bit to leave the previous server time to exit */
1251 usleep( 100000 * retry
* retry
);
1252 start_server( TRACE_ON(server
) );
1253 if (lstat( SOCKETNAME
, &st
) == -1) continue; /* still no socket, wait a bit more */
1255 else if (lstat( SOCKETNAME
, &st
) == -1) /* check for an already existing socket */
1257 if (errno
!= ENOENT
) fatal_perror( "lstat %s/%s", server_dir
, SOCKETNAME
);
1258 start_server( TRACE_ON(server
) );
1259 if (lstat( SOCKETNAME
, &st
) == -1) continue; /* still no socket, wait a bit more */
1262 /* make sure the socket is sane (ISFIFO needed for Solaris) */
1263 if (!S_ISSOCK(st
.st_mode
) && !S_ISFIFO(st
.st_mode
))
1264 fatal_error( "'%s/%s' is not a socket\n", server_dir
, SOCKETNAME
);
1265 if (st
.st_uid
!= getuid())
1266 fatal_error( "'%s/%s' is not owned by you\n", server_dir
, SOCKETNAME
);
1268 /* try to connect to it */
1269 addr
.sun_family
= AF_UNIX
;
1270 strcpy( addr
.sun_path
, SOCKETNAME
);
1271 slen
= sizeof(addr
) - sizeof(addr
.sun_path
) + strlen(addr
.sun_path
) + 1;
1272 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
1273 addr
.sun_len
= slen
;
1275 if ((s
= socket( AF_UNIX
, SOCK_STREAM
, 0 )) == -1) fatal_perror( "socket" );
1280 setsockopt( s
, SOL_SOCKET
, SO_PASSCRED
, &enable
, sizeof(enable
) );
1283 if (connect( s
, (struct sockaddr
*)&addr
, slen
) != -1)
1285 fchdir( initial_cwd
); /* switch back to the starting directory */
1286 fcntl( s
, F_SETFD
, FD_CLOEXEC
);
1291 server_connect_error( server_dir
);
1296 #include <mach/mach.h>
1297 #include <mach/mach_error.h>
1298 #include <servers/bootstrap.h>
1300 /* send our task port to the server */
1301 static void send_server_task_port(void)
1303 mach_port_t bootstrap_port
, wineserver_port
;
1307 mach_msg_header_t header
;
1308 mach_msg_body_t body
;
1309 mach_msg_port_descriptor_t task_port
;
1312 if (task_get_bootstrap_port(mach_task_self(), &bootstrap_port
) != KERN_SUCCESS
) return;
1317 stat( config_dir
, &st
);
1318 server_dir
= init_server_dir( st
.st_dev
, st
.st_ino
);
1320 kret
= bootstrap_look_up(bootstrap_port
, server_dir
, &wineserver_port
);
1321 if (kret
!= KERN_SUCCESS
)
1322 fatal_error( "cannot find the server port: 0x%08x\n", kret
);
1324 mach_port_deallocate(mach_task_self(), bootstrap_port
);
1326 msg
.header
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, 0) | MACH_MSGH_BITS_COMPLEX
;
1327 msg
.header
.msgh_size
= sizeof(msg
);
1328 msg
.header
.msgh_remote_port
= wineserver_port
;
1329 msg
.header
.msgh_local_port
= MACH_PORT_NULL
;
1331 msg
.body
.msgh_descriptor_count
= 1;
1332 msg
.task_port
.name
= mach_task_self();
1333 msg
.task_port
.disposition
= MACH_MSG_TYPE_COPY_SEND
;
1334 msg
.task_port
.type
= MACH_MSG_PORT_DESCRIPTOR
;
1336 kret
= mach_msg_send(&msg
.header
);
1337 if (kret
!= KERN_SUCCESS
)
1338 server_protocol_error( "mach_msg_send failed: 0x%08x\n", kret
);
1340 mach_port_deallocate(mach_task_self(), wineserver_port
);
1342 #endif /* __APPLE__ */
1345 /***********************************************************************
1348 * Retrieve the Unix tid to use on the server side for the current thread.
1350 static int get_unix_tid(void)
1353 #ifdef HAVE_PTHREAD_GETTHREADID_NP
1354 ret
= pthread_getthreadid_np();
1355 #elif defined(linux)
1356 ret
= syscall( __NR_gettid
);
1357 #elif defined(__sun)
1358 ret
= pthread_self();
1359 #elif defined(__APPLE__)
1360 ret
= mach_thread_self();
1361 mach_port_deallocate(mach_task_self(), ret
);
1362 #elif defined(__NetBSD__)
1364 #elif defined(__FreeBSD__)
1368 #elif defined(__DragonFly__)
1375 /***********************************************************************
1378 * Create the server->client communication pipe.
1380 static int init_thread_pipe(void)
1385 ss
.ss_sp
= get_signal_stack();
1386 ss
.ss_size
= signal_stack_size
;
1388 sigaltstack( &ss
, NULL
);
1390 if (server_pipe( reply_pipe
) == -1) server_protocol_perror( "pipe" );
1391 if (server_pipe( ntdll_get_thread_data()->wait_fd
) == -1) server_protocol_perror( "pipe" );
1392 wine_server_send_fd( reply_pipe
[1] );
1393 wine_server_send_fd( ntdll_get_thread_data()->wait_fd
[1] );
1394 ntdll_get_thread_data()->reply_fd
= reply_pipe
[0];
1395 return reply_pipe
[1];
1399 /***********************************************************************
1400 * process_exit_wrapper
1402 * Close server socket and exit process normally.
1404 void process_exit_wrapper( int status
)
1411 /***********************************************************************
1412 * server_init_process
1414 * Start the server and create the initial socket pair.
1416 size_t server_init_process(void)
1418 const char *arch
= getenv( "WINEARCH" );
1419 const char *env_socket
= getenv( "WINESERVERSOCKET" );
1420 obj_handle_t version
;
1422 int ret
, reply_pipe
;
1423 struct sigaction sig_act
;
1430 fd_socket
= atoi( env_socket
);
1431 if (fcntl( fd_socket
, F_SETFD
, FD_CLOEXEC
) == -1)
1432 fatal_perror( "Bad server socket %d", fd_socket
);
1433 unsetenv( "WINESERVERSOCKET" );
1437 const char *arch
= getenv( "WINEARCH" );
1439 if (arch
&& strcmp( arch
, "win32" ) && strcmp( arch
, "win64" ))
1440 fatal_error( "WINEARCH set to invalid value '%s', it must be either win32 or win64.\n", arch
);
1442 fd_socket
= server_connect();
1445 /* setup the signal mask */
1446 sigemptyset( &server_block_set
);
1447 sigaddset( &server_block_set
, SIGALRM
);
1448 sigaddset( &server_block_set
, SIGIO
);
1449 sigaddset( &server_block_set
, SIGINT
);
1450 sigaddset( &server_block_set
, SIGHUP
);
1451 sigaddset( &server_block_set
, SIGUSR1
);
1452 sigaddset( &server_block_set
, SIGUSR2
);
1453 sigaddset( &server_block_set
, SIGCHLD
);
1454 pthread_sigmask( SIG_BLOCK
, &server_block_set
, NULL
);
1456 /* receive the first thread request fd on the main socket */
1457 ntdll_get_thread_data()->request_fd
= receive_fd( &version
);
1460 /* now that we hopefully received the server_pid, disable SO_PASSCRED */
1463 setsockopt( fd_socket
, SOL_SOCKET
, SO_PASSCRED
, &enable
, sizeof(enable
) );
1467 if (version
!= SERVER_PROTOCOL_VERSION
)
1468 server_protocol_error( "version mismatch %d/%d.\n"
1469 "Your %s binary was not upgraded correctly,\n"
1470 "or you have an older one somewhere in your PATH.\n"
1471 "Or maybe the wrong wineserver is still running?\n",
1472 version
, SERVER_PROTOCOL_VERSION
,
1473 (version
> SERVER_PROTOCOL_VERSION
) ? "wine" : "wineserver" );
1474 #if defined(__linux__) && defined(HAVE_PRCTL)
1475 /* work around Ubuntu's ptrace breakage */
1476 if (server_pid
!= -1) prctl( 0x59616d61 /* PR_SET_PTRACER */, server_pid
);
1479 /* ignore SIGPIPE so that we get an EPIPE error instead */
1480 sig_act
.sa_handler
= SIG_IGN
;
1481 sig_act
.sa_flags
= 0;
1482 sigemptyset( &sig_act
.sa_mask
);
1483 sigaction( SIGPIPE
, &sig_act
, NULL
);
1485 reply_pipe
= init_thread_pipe();
1487 SERVER_START_REQ( init_first_thread
)
1489 req
->unix_pid
= getpid();
1490 req
->unix_tid
= get_unix_tid();
1491 req
->reply_fd
= reply_pipe
;
1492 req
->wait_fd
= ntdll_get_thread_data()->wait_fd
[1];
1493 req
->debug_level
= (TRACE_ON(server
) != 0);
1494 wine_server_set_reply( req
, supported_machines
, sizeof(supported_machines
) );
1495 ret
= wine_server_call( req
);
1498 peb
->SessionId
= reply
->session_id
;
1499 info_size
= reply
->info_size
;
1500 server_start_time
= reply
->server_start
;
1501 supported_machines_count
= wine_server_reply_size( reply
) / sizeof(*supported_machines
);
1504 close( reply_pipe
);
1506 if (ret
) server_protocol_error( "init_first_thread failed with status %x\n", ret
);
1508 if (!supported_machines_count
)
1509 fatal_error( "'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.\n",
1512 native_machine
= supported_machines
[0];
1513 if (is_machine_64bit( native_machine
))
1515 if (arch
&& !strcmp( arch
, "win32" ))
1516 fatal_error( "WINEARCH set to win32 but '%s' is a 64-bit installation.\n", config_dir
);
1519 NtCurrentTeb()->GdiBatchCount
= PtrToUlong( (char *)NtCurrentTeb() - teb_offset
);
1520 NtCurrentTeb()->WowTebOffset
= -teb_offset
;
1521 wow_peb
= (PEB64
*)((char *)peb
- page_size
);
1527 fatal_error( "'%s' is a 32-bit installation, it cannot support 64-bit applications.\n", config_dir
);
1528 if (arch
&& !strcmp( arch
, "win64" ))
1529 fatal_error( "WINEARCH set to win64 but '%s' is a 32-bit installation.\n", config_dir
);
1532 set_thread_id( NtCurrentTeb(), pid
, tid
);
1534 for (i
= 0; i
< supported_machines_count
; i
++)
1535 if (supported_machines
[i
] == current_machine
) return info_size
;
1537 fatal_error( "wineserver doesn't support the %04x architecture\n", current_machine
);
1541 /***********************************************************************
1542 * server_init_process_done
1544 void server_init_process_done(void)
1549 FILE_FS_DEVICE_INFORMATION info
;
1551 if (!get_device_info( initial_cwd
, &info
) && (info
.Characteristics
& FILE_REMOVABLE_MEDIA
))
1553 close( initial_cwd
);
1556 send_server_task_port();
1558 if (main_image_info
.ImageCharacteristics
& IMAGE_FILE_LARGE_ADDRESS_AWARE
)
1559 virtual_set_large_address_space();
1561 /* Install signal handlers; this cannot be done earlier, since we cannot
1562 * send exceptions to the debugger before the create process event that
1563 * is sent by init_process_done */
1564 signal_init_process();
1566 /* always send the native TEB */
1567 if (!(teb
= NtCurrentTeb64())) teb
= NtCurrentTeb();
1569 /* Signal the parent process to continue */
1570 SERVER_START_REQ( init_process_done
)
1572 req
->teb
= wine_server_client_ptr( teb
);
1573 req
->peb
= NtCurrentTeb64() ? NtCurrentTeb64()->Peb
: wine_server_client_ptr( peb
);
1575 req
->ldt_copy
= wine_server_client_ptr( &__wine_ldt_copy
);
1577 status
= wine_server_call( req
);
1578 suspend
= reply
->suspend
;
1579 entry
= wine_server_get_ptr( reply
->entry
);
1584 signal_start_thread( entry
, peb
, suspend
, NtCurrentTeb() );
1588 /***********************************************************************
1589 * server_init_thread
1591 * Send an init thread request.
1593 void server_init_thread( void *entry_point
, BOOL
*suspend
)
1596 int reply_pipe
= init_thread_pipe();
1598 /* always send the native TEB */
1599 if (!(teb
= NtCurrentTeb64())) teb
= NtCurrentTeb();
1601 SERVER_START_REQ( init_thread
)
1603 req
->unix_tid
= get_unix_tid();
1604 req
->teb
= wine_server_client_ptr( teb
);
1605 req
->entry
= wine_server_client_ptr( entry_point
);
1606 req
->reply_fd
= reply_pipe
;
1607 req
->wait_fd
= ntdll_get_thread_data()->wait_fd
[1];
1608 wine_server_call( req
);
1609 *suspend
= reply
->suspend
;
1612 close( reply_pipe
);
1616 /******************************************************************************
1619 NTSTATUS WINAPI
NtDuplicateObject( HANDLE source_process
, HANDLE source
, HANDLE dest_process
, HANDLE
*dest
,
1620 ACCESS_MASK access
, ULONG attributes
, ULONG options
)
1626 if (dest
) *dest
= 0;
1628 if ((options
& DUPLICATE_CLOSE_SOURCE
) && source_process
!= NtCurrentProcess())
1631 apc_result_t result
;
1633 memset( &call
, 0, sizeof(call
) );
1635 call
.dup_handle
.type
= APC_DUP_HANDLE
;
1636 call
.dup_handle
.src_handle
= wine_server_obj_handle( source
);
1637 call
.dup_handle
.dst_process
= wine_server_obj_handle( dest_process
);
1638 call
.dup_handle
.access
= access
;
1639 call
.dup_handle
.attributes
= attributes
;
1640 call
.dup_handle
.options
= options
;
1641 ret
= server_queue_process_apc( source_process
, &call
, &result
);
1642 if (ret
!= STATUS_SUCCESS
) return ret
;
1644 if (!result
.dup_handle
.status
)
1645 *dest
= wine_server_ptr_handle( result
.dup_handle
.handle
);
1646 return result
.dup_handle
.status
;
1649 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1651 /* always remove the cached fd; if the server request fails we'll just
1652 * retrieve it again */
1653 if (options
& DUPLICATE_CLOSE_SOURCE
)
1654 fd
= remove_fd_from_cache( source
);
1656 SERVER_START_REQ( dup_handle
)
1658 req
->src_process
= wine_server_obj_handle( source_process
);
1659 req
->src_handle
= wine_server_obj_handle( source
);
1660 req
->dst_process
= wine_server_obj_handle( dest_process
);
1661 req
->access
= access
;
1662 req
->attributes
= attributes
;
1663 req
->options
= options
;
1664 if (!(ret
= wine_server_call( req
)))
1666 if (dest
) *dest
= wine_server_ptr_handle( reply
->handle
);
1671 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1673 if (fd
!= -1) close( fd
);
1678 /**************************************************************************
1679 * NtCompareObjects (NTDLL.@)
1681 NTSTATUS WINAPI
NtCompareObjects( HANDLE first
, HANDLE second
)
1685 SERVER_START_REQ( compare_objects
)
1687 req
->first
= wine_server_obj_handle( first
);
1688 req
->second
= wine_server_obj_handle( second
);
1689 status
= wine_server_call( req
);
1697 /**************************************************************************
1700 NTSTATUS WINAPI
NtClose( HANDLE handle
)
1707 if (HandleToLong( handle
) >= ~5 && HandleToLong( handle
) <= ~0)
1708 return STATUS_SUCCESS
;
1710 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1712 /* always remove the cached fd; if the server request fails we'll just
1713 * retrieve it again */
1714 fd
= remove_fd_from_cache( handle
);
1716 SERVER_START_REQ( close_handle
)
1718 req
->handle
= wine_server_obj_handle( handle
);
1719 ret
= wine_server_call( req
);
1723 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1725 if (fd
!= -1) close( fd
);
1727 if (ret
!= STATUS_INVALID_HANDLE
|| !handle
) return ret
;
1728 if (!peb
->BeingDebugged
) return ret
;
1729 if (!NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort
, &port
, sizeof(port
), NULL
) && port
)
1731 NtCurrentTeb()->ExceptionCode
= ret
;
1732 call_raise_user_exception_dispatcher();