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
)
361 SIZE_T size
, bits
, limit
;
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_ALLOC_EX
:
406 MEM_ADDRESS_REQUIREMENTS r
= { NULL
};
407 MEM_EXTENDED_PARAMETER ext
=
409 .Type
= MemExtendedParameterAddressRequirements
,
412 SYSTEM_BASIC_INFORMATION sbi
;
414 virtual_get_system_info( &sbi
, !!NtCurrentTeb()->WowTebOffset
);
415 result
->type
= call
->type
;
416 addr
= wine_server_get_ptr( call
->virtual_alloc_ex
.addr
);
417 size
= call
->virtual_alloc_ex
.size
;
418 limit
= min( (ULONG_PTR
)sbi
.HighestUserAddress
, call
->virtual_alloc_ex
.limit
);
419 if ((ULONG_PTR
)addr
== call
->virtual_alloc_ex
.addr
&& size
== call
->virtual_alloc_ex
.size
)
421 r
.HighestEndingAddress
= (void *)limit
;
422 result
->virtual_alloc_ex
.status
= NtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr
, &size
,
423 call
->virtual_alloc_ex
.op_type
,
424 call
->virtual_alloc_ex
.prot
, &ext
, 1 );
425 result
->virtual_alloc_ex
.addr
= wine_server_client_ptr( addr
);
426 result
->virtual_alloc_ex
.size
= size
;
428 else result
->virtual_alloc_ex
.status
= STATUS_WORKING_SET_LIMIT_RANGE
;
431 case APC_VIRTUAL_FREE
:
432 result
->type
= call
->type
;
433 addr
= wine_server_get_ptr( call
->virtual_free
.addr
);
434 size
= call
->virtual_free
.size
;
435 if ((ULONG_PTR
)addr
== call
->virtual_free
.addr
&& size
== call
->virtual_free
.size
)
437 result
->virtual_free
.status
= NtFreeVirtualMemory( NtCurrentProcess(), &addr
, &size
,
438 call
->virtual_free
.op_type
);
439 result
->virtual_free
.addr
= wine_server_client_ptr( addr
);
440 result
->virtual_free
.size
= size
;
442 else result
->virtual_free
.status
= STATUS_INVALID_PARAMETER
;
444 case APC_VIRTUAL_QUERY
:
446 MEMORY_BASIC_INFORMATION info
;
447 result
->type
= call
->type
;
448 addr
= wine_server_get_ptr( call
->virtual_query
.addr
);
449 if ((ULONG_PTR
)addr
== call
->virtual_query
.addr
)
450 result
->virtual_query
.status
= NtQueryVirtualMemory( NtCurrentProcess(),
451 addr
, MemoryBasicInformation
, &info
,
452 sizeof(info
), NULL
);
454 result
->virtual_query
.status
= STATUS_WORKING_SET_LIMIT_RANGE
;
456 if (result
->virtual_query
.status
== STATUS_SUCCESS
)
458 result
->virtual_query
.base
= wine_server_client_ptr( info
.BaseAddress
);
459 result
->virtual_query
.alloc_base
= wine_server_client_ptr( info
.AllocationBase
);
460 result
->virtual_query
.size
= info
.RegionSize
;
461 result
->virtual_query
.prot
= info
.Protect
;
462 result
->virtual_query
.alloc_prot
= info
.AllocationProtect
;
463 result
->virtual_query
.state
= info
.State
>> 12;
464 result
->virtual_query
.alloc_type
= info
.Type
>> 16;
468 case APC_VIRTUAL_PROTECT
:
469 result
->type
= call
->type
;
470 addr
= wine_server_get_ptr( call
->virtual_protect
.addr
);
471 size
= call
->virtual_protect
.size
;
472 if ((ULONG_PTR
)addr
== call
->virtual_protect
.addr
&& size
== call
->virtual_protect
.size
)
474 result
->virtual_protect
.status
= NtProtectVirtualMemory( NtCurrentProcess(), &addr
, &size
,
475 call
->virtual_protect
.prot
,
476 &result
->virtual_protect
.prot
);
477 result
->virtual_protect
.addr
= wine_server_client_ptr( addr
);
478 result
->virtual_protect
.size
= size
;
480 else result
->virtual_protect
.status
= STATUS_INVALID_PARAMETER
;
482 case APC_VIRTUAL_FLUSH
:
483 result
->type
= call
->type
;
484 addr
= wine_server_get_ptr( call
->virtual_flush
.addr
);
485 size
= call
->virtual_flush
.size
;
486 if ((ULONG_PTR
)addr
== call
->virtual_flush
.addr
&& size
== call
->virtual_flush
.size
)
488 result
->virtual_flush
.status
= NtFlushVirtualMemory( NtCurrentProcess(),
489 (const void **)&addr
, &size
, 0 );
490 result
->virtual_flush
.addr
= wine_server_client_ptr( addr
);
491 result
->virtual_flush
.size
= size
;
493 else result
->virtual_flush
.status
= STATUS_INVALID_PARAMETER
;
495 case APC_VIRTUAL_LOCK
:
496 result
->type
= call
->type
;
497 addr
= wine_server_get_ptr( call
->virtual_lock
.addr
);
498 size
= call
->virtual_lock
.size
;
499 if ((ULONG_PTR
)addr
== call
->virtual_lock
.addr
&& size
== call
->virtual_lock
.size
)
501 result
->virtual_lock
.status
= NtLockVirtualMemory( NtCurrentProcess(), &addr
, &size
, 0 );
502 result
->virtual_lock
.addr
= wine_server_client_ptr( addr
);
503 result
->virtual_lock
.size
= size
;
505 else result
->virtual_lock
.status
= STATUS_INVALID_PARAMETER
;
507 case APC_VIRTUAL_UNLOCK
:
508 result
->type
= call
->type
;
509 addr
= wine_server_get_ptr( call
->virtual_unlock
.addr
);
510 size
= call
->virtual_unlock
.size
;
511 if ((ULONG_PTR
)addr
== call
->virtual_unlock
.addr
&& size
== call
->virtual_unlock
.size
)
513 result
->virtual_unlock
.status
= NtUnlockVirtualMemory( NtCurrentProcess(), &addr
, &size
, 0 );
514 result
->virtual_unlock
.addr
= wine_server_client_ptr( addr
);
515 result
->virtual_unlock
.size
= size
;
517 else result
->virtual_unlock
.status
= STATUS_INVALID_PARAMETER
;
520 result
->type
= call
->type
;
521 addr
= wine_server_get_ptr( call
->map_view
.addr
);
522 size
= call
->map_view
.size
;
523 bits
= call
->map_view
.zero_bits
;
524 if ((ULONG_PTR
)addr
== call
->map_view
.addr
&& size
== call
->map_view
.size
&&
525 bits
== call
->map_view
.zero_bits
)
527 LARGE_INTEGER offset
;
528 offset
.QuadPart
= call
->map_view
.offset
;
529 result
->map_view
.status
= NtMapViewOfSection( wine_server_ptr_handle(call
->map_view
.handle
),
531 &addr
, bits
, 0, &offset
, &size
, 0,
532 call
->map_view
.alloc_type
, call
->map_view
.prot
);
533 result
->map_view
.addr
= wine_server_client_ptr( addr
);
534 result
->map_view
.size
= size
;
536 else result
->map_view
.status
= STATUS_INVALID_PARAMETER
;
537 if (!self
) NtClose( wine_server_ptr_handle(call
->map_view
.handle
) );
540 result
->type
= call
->type
;
541 addr
= wine_server_get_ptr( call
->unmap_view
.addr
);
542 if ((ULONG_PTR
)addr
== call
->unmap_view
.addr
)
543 result
->unmap_view
.status
= NtUnmapViewOfSection( NtCurrentProcess(), addr
);
545 result
->unmap_view
.status
= STATUS_INVALID_PARAMETER
;
547 case APC_CREATE_THREAD
:
549 ULONG_PTR buffer
[offsetof( PS_ATTRIBUTE_LIST
, Attributes
[2] ) / sizeof(ULONG_PTR
)];
550 PS_ATTRIBUTE_LIST
*attr
= (PS_ATTRIBUTE_LIST
*)buffer
;
554 ULONG_PTR zero_bits
= call
->create_thread
.zero_bits
;
555 SIZE_T reserve
= call
->create_thread
.reserve
;
556 SIZE_T commit
= call
->create_thread
.commit
;
557 void *func
= wine_server_get_ptr( call
->create_thread
.func
);
558 void *arg
= wine_server_get_ptr( call
->create_thread
.arg
);
560 result
->type
= call
->type
;
561 if (reserve
== call
->create_thread
.reserve
&& commit
== call
->create_thread
.commit
&&
562 (ULONG_PTR
)func
== call
->create_thread
.func
&& (ULONG_PTR
)arg
== call
->create_thread
.arg
)
565 /* FIXME: hack for debugging 32-bit process without a 64-bit ntdll */
566 if (is_wow64
&& func
== (void *)0x7ffe1000) func
= pDbgUiRemoteBreakin
;
568 attr
->TotalLength
= sizeof(buffer
);
569 attr
->Attributes
[0].Attribute
= PS_ATTRIBUTE_CLIENT_ID
;
570 attr
->Attributes
[0].Size
= sizeof(id
);
571 attr
->Attributes
[0].ValuePtr
= &id
;
572 attr
->Attributes
[0].ReturnLength
= NULL
;
573 attr
->Attributes
[1].Attribute
= PS_ATTRIBUTE_TEB_ADDRESS
;
574 attr
->Attributes
[1].Size
= sizeof(teb
);
575 attr
->Attributes
[1].ValuePtr
= &teb
;
576 attr
->Attributes
[1].ReturnLength
= NULL
;
577 result
->create_thread
.status
= NtCreateThreadEx( &handle
, THREAD_ALL_ACCESS
, NULL
,
578 NtCurrentProcess(), func
, arg
,
579 call
->create_thread
.flags
, zero_bits
,
580 commit
, reserve
, attr
);
581 result
->create_thread
.handle
= wine_server_obj_handle( handle
);
582 result
->create_thread
.pid
= HandleToULong(id
.UniqueProcess
);
583 result
->create_thread
.tid
= HandleToULong(id
.UniqueThread
);
584 result
->create_thread
.teb
= wine_server_client_ptr( teb
);
586 else result
->create_thread
.status
= STATUS_INVALID_PARAMETER
;
591 HANDLE dst_handle
= NULL
;
593 result
->type
= call
->type
;
595 result
->dup_handle
.status
= NtDuplicateObject( NtCurrentProcess(),
596 wine_server_ptr_handle(call
->dup_handle
.src_handle
),
597 wine_server_ptr_handle(call
->dup_handle
.dst_process
),
598 &dst_handle
, call
->dup_handle
.access
,
599 call
->dup_handle
.attributes
, call
->dup_handle
.options
);
600 result
->dup_handle
.handle
= wine_server_obj_handle( dst_handle
);
601 if (!self
) NtClose( wine_server_ptr_handle(call
->dup_handle
.dst_process
) );
605 server_protocol_error( "get_apc_request: bad type %d\n", call
->type
);
611 /***********************************************************************
614 unsigned int server_select( const select_op_t
*select_op
, data_size_t size
, UINT flags
,
615 timeout_t abs_timeout
, context_t
*context
, user_apc_t
*user_apc
)
619 obj_handle_t apc_handle
= 0;
620 BOOL suspend_context
= !!context
;
626 memset( &result
, 0, sizeof(result
) );
630 pthread_sigmask( SIG_BLOCK
, &server_block_set
, &old_set
);
633 SERVER_START_REQ( select
)
636 req
->cookie
= wine_server_client_ptr( &cookie
);
637 req
->prev_apc
= apc_handle
;
638 req
->timeout
= abs_timeout
;
640 wine_server_add_data( req
, &result
, sizeof(result
) );
641 wine_server_add_data( req
, select_op
, size
);
644 data_size_t ctx_size
= (context
[1].machine
? 2 : 1) * sizeof(*context
);
645 wine_server_add_data( req
, context
, ctx_size
);
646 suspend_context
= FALSE
; /* server owns the context now */
648 if (context
) wine_server_set_reply( req
, context
, 2 * sizeof(*context
) );
649 ret
= server_call_unlocked( req
);
650 signaled
= reply
->signaled
;
651 apc_handle
= reply
->apc_handle
;
656 if (ret
!= STATUS_KERNEL_APC
) break;
657 invoke_system_apc( &call
, &result
, FALSE
);
659 /* don't signal multiple times */
660 if (size
>= sizeof(select_op
->signal_and_wait
) && select_op
->op
== SELECT_SIGNAL_AND_WAIT
)
661 size
= offsetof( select_op_t
, signal_and_wait
.signal
);
663 pthread_sigmask( SIG_SETMASK
, &old_set
, NULL
);
666 ret
= wait_select_reply( &cookie
);
668 while (ret
== STATUS_USER_APC
|| ret
== STATUS_KERNEL_APC
);
670 if (ret
== STATUS_USER_APC
) *user_apc
= call
.user
;
675 /***********************************************************************
678 unsigned int server_wait( const select_op_t
*select_op
, data_size_t size
, UINT flags
,
679 const LARGE_INTEGER
*timeout
)
681 timeout_t abs_timeout
= timeout
? timeout
->QuadPart
: TIMEOUT_INFINITE
;
689 NtQueryPerformanceCounter( &now
, NULL
);
690 abs_timeout
-= now
.QuadPart
;
693 ret
= server_select( select_op
, size
, flags
, abs_timeout
, NULL
, &apc
);
694 if (ret
== STATUS_USER_APC
) return invoke_user_apc( NULL
, &apc
, ret
);
696 /* A test on Windows 2000 shows that Windows always yields during
697 a wait, but a wait that is hit by an event gets a priority
698 boost as well. This seems to model that behavior the closest. */
699 if (ret
== STATUS_TIMEOUT
) NtYieldExecution();
704 /***********************************************************************
705 * NtContinue (NTDLL.@)
707 NTSTATUS WINAPI
NtContinue( CONTEXT
*context
, BOOLEAN alertable
)
714 status
= server_select( NULL
, 0, SELECT_INTERRUPTIBLE
| SELECT_ALERTABLE
, 0, NULL
, &apc
);
715 if (status
== STATUS_USER_APC
) return invoke_user_apc( context
, &apc
, status
);
717 return signal_set_full_context( context
);
721 /***********************************************************************
722 * NtTestAlert (NTDLL.@)
724 NTSTATUS WINAPI
NtTestAlert(void)
729 status
= server_select( NULL
, 0, SELECT_INTERRUPTIBLE
| SELECT_ALERTABLE
, 0, NULL
, &apc
);
730 if (status
== STATUS_USER_APC
) invoke_user_apc( NULL
, &apc
, STATUS_SUCCESS
);
731 return STATUS_SUCCESS
;
735 /***********************************************************************
736 * server_queue_process_apc
738 unsigned int server_queue_process_apc( HANDLE process
, const apc_call_t
*call
, apc_result_t
*result
)
746 SERVER_START_REQ( queue_apc
)
748 req
->handle
= wine_server_obj_handle( process
);
750 if (!(ret
= wine_server_call( req
)))
752 handle
= wine_server_ptr_handle( reply
->handle
);
757 if (ret
!= STATUS_SUCCESS
) return ret
;
761 invoke_system_apc( call
, result
, TRUE
);
765 NtWaitForSingleObject( handle
, FALSE
, NULL
);
767 SERVER_START_REQ( get_apc_result
)
769 req
->handle
= wine_server_obj_handle( handle
);
770 if (!(ret
= wine_server_call( req
))) *result
= reply
->result
;
774 if (!ret
&& result
->type
== APC_NONE
) continue; /* APC didn't run, try again */
781 /***********************************************************************
782 * wine_server_send_fd
784 * Send a file descriptor to the server.
786 void wine_server_send_fd( int fd
)
789 struct msghdr msghdr
;
793 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
794 msghdr
.msg_accrights
= (void *)&fd
;
795 msghdr
.msg_accrightslen
= sizeof(fd
);
796 #else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
797 char cmsg_buffer
[256];
798 struct cmsghdr
*cmsg
;
799 msghdr
.msg_control
= cmsg_buffer
;
800 msghdr
.msg_controllen
= sizeof(cmsg_buffer
);
801 msghdr
.msg_flags
= 0;
802 cmsg
= CMSG_FIRSTHDR( &msghdr
);
803 cmsg
->cmsg_len
= CMSG_LEN( sizeof(fd
) );
804 cmsg
->cmsg_level
= SOL_SOCKET
;
805 cmsg
->cmsg_type
= SCM_RIGHTS
;
806 *(int *)CMSG_DATA(cmsg
) = fd
;
807 msghdr
.msg_controllen
= cmsg
->cmsg_len
;
808 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
810 msghdr
.msg_name
= NULL
;
811 msghdr
.msg_namelen
= 0;
812 msghdr
.msg_iov
= &vec
;
813 msghdr
.msg_iovlen
= 1;
815 vec
.iov_base
= (void *)&data
;
816 vec
.iov_len
= sizeof(data
);
818 data
.tid
= GetCurrentThreadId();
823 if ((ret
= sendmsg( fd_socket
, &msghdr
, 0 )) == sizeof(data
)) return;
824 if (ret
>= 0) server_protocol_error( "partial write %d\n", ret
);
825 if (errno
== EINTR
) continue;
826 if (errno
== EPIPE
) abort_thread(0);
827 server_protocol_perror( "sendmsg" );
832 /***********************************************************************
835 * Receive a file descriptor passed from the server.
837 static int receive_fd( obj_handle_t
*handle
)
840 struct msghdr msghdr
;
843 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
844 msghdr
.msg_accrights
= (void *)&fd
;
845 msghdr
.msg_accrightslen
= sizeof(fd
);
846 #else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
847 char cmsg_buffer
[256];
848 msghdr
.msg_control
= cmsg_buffer
;
849 msghdr
.msg_controllen
= sizeof(cmsg_buffer
);
850 msghdr
.msg_flags
= 0;
851 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
853 msghdr
.msg_name
= NULL
;
854 msghdr
.msg_namelen
= 0;
855 msghdr
.msg_iov
= &vec
;
856 msghdr
.msg_iovlen
= 1;
857 vec
.iov_base
= (void *)handle
;
858 vec
.iov_len
= sizeof(*handle
);
862 if ((ret
= recvmsg( fd_socket
, &msghdr
, MSG_CMSG_CLOEXEC
)) > 0)
864 #ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
865 struct cmsghdr
*cmsg
;
866 for (cmsg
= CMSG_FIRSTHDR( &msghdr
); cmsg
; cmsg
= CMSG_NXTHDR( &msghdr
, cmsg
))
868 if (cmsg
->cmsg_level
!= SOL_SOCKET
) continue;
869 if (cmsg
->cmsg_type
== SCM_RIGHTS
) fd
= *(int *)CMSG_DATA(cmsg
);
870 #ifdef SCM_CREDENTIALS
871 else if (cmsg
->cmsg_type
== SCM_CREDENTIALS
)
873 struct ucred
*ucred
= (struct ucred
*)CMSG_DATA(cmsg
);
874 server_pid
= ucred
->pid
;
878 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
879 if (fd
!= -1) fcntl( fd
, F_SETFD
, FD_CLOEXEC
); /* in case MSG_CMSG_CLOEXEC is not supported */
883 if (errno
== EINTR
) continue;
884 if (errno
== EPIPE
) break;
885 server_protocol_perror("recvmsg");
887 /* the server closed the connection; time to die... */
892 /***********************************************************************/
893 /* fd cache support */
901 enum server_fd_type type
: 5;
902 unsigned int access
: 3;
903 unsigned int options
: 24;
907 C_ASSERT( sizeof(union fd_cache_entry
) == sizeof(LONG64
) );
909 #define FD_CACHE_BLOCK_SIZE (65536 / sizeof(union fd_cache_entry))
910 #define FD_CACHE_ENTRIES 128
912 static union fd_cache_entry
*fd_cache
[FD_CACHE_ENTRIES
];
913 static union fd_cache_entry fd_cache_initial_block
[FD_CACHE_BLOCK_SIZE
];
915 static inline unsigned int handle_to_index( HANDLE handle
, unsigned int *entry
)
917 unsigned int idx
= (wine_server_obj_handle(handle
) >> 2) - 1;
918 *entry
= idx
/ FD_CACHE_BLOCK_SIZE
;
919 return idx
% FD_CACHE_BLOCK_SIZE
;
923 /***********************************************************************
926 * Caller must hold fd_cache_mutex.
928 static BOOL
add_fd_to_cache( HANDLE handle
, int fd
, enum server_fd_type type
,
929 unsigned int access
, unsigned int options
)
931 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
932 union fd_cache_entry cache
;
934 if (entry
>= FD_CACHE_ENTRIES
)
936 FIXME( "too many allocated handles, not caching %p\n", handle
);
940 if (!fd_cache
[entry
]) /* do we need to allocate a new block of entries? */
942 if (!entry
) fd_cache
[0] = fd_cache_initial_block
;
945 void *ptr
= anon_mmap_alloc( FD_CACHE_BLOCK_SIZE
* sizeof(union fd_cache_entry
),
946 PROT_READ
| PROT_WRITE
);
947 if (ptr
== MAP_FAILED
) return FALSE
;
948 fd_cache
[entry
] = ptr
;
952 /* store fd+1 so that 0 can be used as the unset value */
955 cache
.s
.access
= access
;
956 cache
.s
.options
= options
;
957 cache
.data
= interlocked_xchg64( &fd_cache
[entry
][idx
].data
, cache
.data
);
958 assert( !cache
.s
.fd
);
963 /***********************************************************************
966 static inline NTSTATUS
get_cached_fd( HANDLE handle
, int *fd
, enum server_fd_type
*type
,
967 unsigned int *access
, unsigned int *options
)
969 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
970 union fd_cache_entry cache
;
972 if (entry
>= FD_CACHE_ENTRIES
|| !fd_cache
[entry
]) return STATUS_INVALID_HANDLE
;
974 cache
.data
= InterlockedCompareExchange64( &fd_cache
[entry
][idx
].data
, 0, 0 );
975 if (!cache
.data
) return STATUS_INVALID_HANDLE
;
977 /* if fd type is invalid, fd stores an error value */
978 if (cache
.s
.type
== FD_TYPE_INVALID
) return cache
.s
.fd
- 1;
980 *fd
= cache
.s
.fd
- 1;
981 if (type
) *type
= cache
.s
.type
;
982 if (access
) *access
= cache
.s
.access
;
983 if (options
) *options
= cache
.s
.options
;
984 return STATUS_SUCCESS
;
988 /***********************************************************************
989 * remove_fd_from_cache
991 static int remove_fd_from_cache( HANDLE handle
)
993 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
996 if (entry
< FD_CACHE_ENTRIES
&& fd_cache
[entry
])
998 union fd_cache_entry cache
;
999 cache
.data
= interlocked_xchg64( &fd_cache
[entry
][idx
].data
, 0 );
1000 if (cache
.s
.type
!= FD_TYPE_INVALID
) fd
= cache
.s
.fd
- 1;
1007 /***********************************************************************
1008 * server_get_unix_fd
1010 * The returned unix_fd should be closed iff needs_close is non-zero.
1012 int server_get_unix_fd( HANDLE handle
, unsigned int wanted_access
, int *unix_fd
,
1013 int *needs_close
, enum server_fd_type
*type
, unsigned int *options
)
1016 obj_handle_t fd_handle
;
1018 unsigned int access
= 0;
1022 wanted_access
&= FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_APPEND_DATA
;
1024 ret
= get_cached_fd( handle
, &fd
, type
, &access
, options
);
1025 if (ret
!= STATUS_INVALID_HANDLE
) goto done
;
1027 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1028 ret
= get_cached_fd( handle
, &fd
, type
, &access
, options
);
1029 if (ret
== STATUS_INVALID_HANDLE
)
1031 SERVER_START_REQ( get_handle_fd
)
1033 req
->handle
= wine_server_obj_handle( handle
);
1034 if (!(ret
= wine_server_call( req
)))
1036 if (type
) *type
= reply
->type
;
1037 if (options
) *options
= reply
->options
;
1038 access
= reply
->access
;
1039 if ((fd
= receive_fd( &fd_handle
)) != -1)
1041 assert( wine_server_ptr_handle(fd_handle
) == handle
);
1042 *needs_close
= (!reply
->cacheable
||
1043 !add_fd_to_cache( handle
, fd
, reply
->type
,
1044 reply
->access
, reply
->options
));
1046 else ret
= STATUS_TOO_MANY_OPENED_FILES
;
1048 else if (reply
->cacheable
)
1050 add_fd_to_cache( handle
, ret
, FD_TYPE_INVALID
, 0, 0 );
1055 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1058 if (!ret
&& ((access
& wanted_access
) != wanted_access
))
1060 ret
= STATUS_ACCESS_DENIED
;
1061 if (*needs_close
) close( fd
);
1063 if (!ret
) *unix_fd
= fd
;
1068 /***********************************************************************
1069 * wine_server_fd_to_handle
1071 NTSTATUS CDECL
wine_server_fd_to_handle( int fd
, unsigned int access
, unsigned int attributes
, HANDLE
*handle
)
1076 wine_server_send_fd( fd
);
1078 SERVER_START_REQ( alloc_file_handle
)
1080 req
->access
= access
;
1081 req
->attributes
= attributes
;
1083 if (!(ret
= wine_server_call( req
))) *handle
= wine_server_ptr_handle( reply
->handle
);
1090 /***********************************************************************
1091 * wine_server_handle_to_fd
1093 * Retrieve the file descriptor corresponding to a file handle.
1095 NTSTATUS CDECL
wine_server_handle_to_fd( HANDLE handle
, unsigned int access
, int *unix_fd
,
1096 unsigned int *options
)
1099 NTSTATUS ret
= server_get_unix_fd( handle
, access
, unix_fd
, &needs_close
, NULL
, options
);
1101 if (!ret
&& !needs_close
)
1103 if ((*unix_fd
= dup(*unix_fd
)) == -1) ret
= STATUS_TOO_MANY_OPENED_FILES
;
1109 /***********************************************************************
1112 * Create a pipe for communicating with the server.
1114 int server_pipe( int fd
[2] )
1118 static BOOL have_pipe2
= TRUE
;
1122 if (!(ret
= pipe2( fd
, O_CLOEXEC
))) return ret
;
1123 if (errno
== ENOSYS
|| errno
== EINVAL
) have_pipe2
= FALSE
; /* don't try again */
1126 if (!(ret
= pipe( fd
)))
1128 fcntl( fd
[0], F_SETFD
, FD_CLOEXEC
);
1129 fcntl( fd
[1], F_SETFD
, FD_CLOEXEC
);
1135 /***********************************************************************
1138 static const char *init_server_dir( dev_t dev
, ino_t ino
)
1141 size_t len
= sizeof("/server-") + 2 * sizeof(dev
) + 2 * sizeof(ino
) + 2;
1143 #ifdef __ANDROID__ /* there's no /tmp dir on Android */
1144 len
+= strlen( config_dir
) + sizeof("/.wineserver");
1145 dir
= malloc( len
);
1146 strcpy( dir
, config_dir
);
1147 strcat( dir
, "/.wineserver/server-" );
1149 len
+= sizeof("/tmp/.wine-") + 12;
1150 dir
= malloc( len
);
1151 sprintf( dir
, "/tmp/.wine-%u/server-", getuid() );
1153 p
= dir
+ strlen( dir
);
1154 if (dev
!= (unsigned long)dev
)
1155 p
+= sprintf( p
, "%lx%08lx-", (unsigned long)((unsigned long long)dev
>> 32), (unsigned long)dev
);
1157 p
+= sprintf( p
, "%lx-", (unsigned long)dev
);
1159 if (ino
!= (unsigned long)ino
)
1160 sprintf( p
, "%lx%08lx", (unsigned long)((unsigned long long)ino
>> 32), (unsigned long)ino
);
1162 sprintf( p
, "%lx", (unsigned long)ino
);
1167 /***********************************************************************
1170 * Setup the wine configuration dir.
1172 static int setup_config_dir(void)
1176 int fd_cwd
= open( ".", O_RDONLY
);
1178 if (chdir( config_dir
) == -1)
1180 if (errno
!= ENOENT
) fatal_perror( "cannot use directory %s", config_dir
);
1181 if ((p
= strrchr( config_dir
, '/' )) && p
!= config_dir
)
1183 while (p
> config_dir
+ 1 && p
[-1] == '/') p
--;
1185 if (!stat( config_dir
, &st
) && st
.st_uid
!= getuid())
1186 fatal_error( "'%s' is not owned by you, refusing to create a configuration directory there\n",
1190 mkdir( config_dir
, 0777 );
1191 if (chdir( config_dir
) == -1) fatal_perror( "chdir to %s", config_dir
);
1192 MESSAGE( "wine: created the configuration directory '%s'\n", config_dir
);
1195 if (stat( ".", &st
) == -1) fatal_perror( "stat %s", config_dir
);
1196 if (st
.st_uid
!= getuid()) fatal_error( "'%s' is not owned by you\n", config_dir
);
1198 server_dir
= init_server_dir( st
.st_dev
, st
.st_ino
);
1200 if (!mkdir( "dosdevices", 0777 ))
1202 mkdir( "drive_c", 0777 );
1203 symlink( "../drive_c", "dosdevices/c:" );
1204 symlink( "/", "dosdevices/z:" );
1206 else if (errno
!= EEXIST
) fatal_perror( "cannot create %s/dosdevices", config_dir
);
1208 if (fd_cwd
== -1) fd_cwd
= open( "dosdevices/c:", O_RDONLY
);
1209 fcntl( fd_cwd
, F_SETFD
, FD_CLOEXEC
);
1214 /***********************************************************************
1215 * server_connect_error
1217 * Try to display a meaningful explanation of why we couldn't connect
1220 static void server_connect_error( const char *serverdir
)
1225 if ((fd
= open( LOCKNAME
, O_WRONLY
)) == -1)
1226 fatal_error( "for some mysterious reason, the wine server never started.\n" );
1228 fl
.l_type
= F_WRLCK
;
1229 fl
.l_whence
= SEEK_SET
;
1232 if (fcntl( fd
, F_GETLK
, &fl
) != -1)
1234 if (fl
.l_type
== F_WRLCK
) /* the file is locked */
1235 fatal_error( "a wine server seems to be running, but I cannot connect to it.\n"
1236 " You probably need to kill that process (it might be pid %d).\n",
1238 fatal_error( "for some mysterious reason, the wine server failed to run.\n" );
1240 fatal_error( "the file system of '%s' doesn't support locks,\n"
1241 " and there is a 'socket' file in that directory that prevents wine from starting.\n"
1242 " You should make sure no wine server is running, remove that file and try again.\n",
1247 /***********************************************************************
1250 * Attempt to connect to an existing server socket.
1252 static int server_connect(void)
1254 struct sockaddr_un addr
;
1258 initial_cwd
= setup_config_dir();
1260 /* chdir to the server directory */
1261 if (chdir( server_dir
) == -1)
1263 if (errno
!= ENOENT
) fatal_perror( "chdir to %s", server_dir
);
1264 start_server( TRACE_ON(server
) );
1265 if (chdir( server_dir
) == -1) fatal_perror( "chdir to %s", server_dir
);
1268 /* make sure we are at the right place */
1269 if (stat( ".", &st
) == -1) fatal_perror( "stat %s", server_dir
);
1270 if (st
.st_uid
!= getuid()) fatal_error( "'%s' is not owned by you\n", server_dir
);
1271 if (st
.st_mode
& 077) fatal_error( "'%s' must not be accessible by other users\n", server_dir
);
1273 for (retry
= 0; retry
< 6; retry
++)
1275 /* if not the first try, wait a bit to leave the previous server time to exit */
1278 usleep( 100000 * retry
* retry
);
1279 start_server( TRACE_ON(server
) );
1280 if (lstat( SOCKETNAME
, &st
) == -1) continue; /* still no socket, wait a bit more */
1282 else if (lstat( SOCKETNAME
, &st
) == -1) /* check for an already existing socket */
1284 if (errno
!= ENOENT
) fatal_perror( "lstat %s/%s", server_dir
, SOCKETNAME
);
1285 start_server( TRACE_ON(server
) );
1286 if (lstat( SOCKETNAME
, &st
) == -1) continue; /* still no socket, wait a bit more */
1289 /* make sure the socket is sane (ISFIFO needed for Solaris) */
1290 if (!S_ISSOCK(st
.st_mode
) && !S_ISFIFO(st
.st_mode
))
1291 fatal_error( "'%s/%s' is not a socket\n", server_dir
, SOCKETNAME
);
1292 if (st
.st_uid
!= getuid())
1293 fatal_error( "'%s/%s' is not owned by you\n", server_dir
, SOCKETNAME
);
1295 /* try to connect to it */
1296 addr
.sun_family
= AF_UNIX
;
1297 strcpy( addr
.sun_path
, SOCKETNAME
);
1298 slen
= sizeof(addr
) - sizeof(addr
.sun_path
) + strlen(addr
.sun_path
) + 1;
1299 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
1300 addr
.sun_len
= slen
;
1302 if ((s
= socket( AF_UNIX
, SOCK_STREAM
, 0 )) == -1) fatal_perror( "socket" );
1307 setsockopt( s
, SOL_SOCKET
, SO_PASSCRED
, &enable
, sizeof(enable
) );
1310 if (connect( s
, (struct sockaddr
*)&addr
, slen
) != -1)
1312 fchdir( initial_cwd
); /* switch back to the starting directory */
1313 fcntl( s
, F_SETFD
, FD_CLOEXEC
);
1318 server_connect_error( server_dir
);
1323 #include <mach/mach.h>
1324 #include <mach/mach_error.h>
1325 #include <servers/bootstrap.h>
1327 /* send our task port to the server */
1328 static void send_server_task_port(void)
1330 mach_port_t bootstrap_port
, wineserver_port
;
1334 mach_msg_header_t header
;
1335 mach_msg_body_t body
;
1336 mach_msg_port_descriptor_t task_port
;
1339 if (task_get_bootstrap_port(mach_task_self(), &bootstrap_port
) != KERN_SUCCESS
) return;
1344 stat( config_dir
, &st
);
1345 server_dir
= init_server_dir( st
.st_dev
, st
.st_ino
);
1347 kret
= bootstrap_look_up(bootstrap_port
, server_dir
, &wineserver_port
);
1348 if (kret
!= KERN_SUCCESS
)
1349 fatal_error( "cannot find the server port: 0x%08x\n", kret
);
1351 mach_port_deallocate(mach_task_self(), bootstrap_port
);
1353 msg
.header
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, 0) | MACH_MSGH_BITS_COMPLEX
;
1354 msg
.header
.msgh_size
= sizeof(msg
);
1355 msg
.header
.msgh_remote_port
= wineserver_port
;
1356 msg
.header
.msgh_local_port
= MACH_PORT_NULL
;
1358 msg
.body
.msgh_descriptor_count
= 1;
1359 msg
.task_port
.name
= mach_task_self();
1360 msg
.task_port
.disposition
= MACH_MSG_TYPE_COPY_SEND
;
1361 msg
.task_port
.type
= MACH_MSG_PORT_DESCRIPTOR
;
1363 kret
= mach_msg_send(&msg
.header
);
1364 if (kret
!= KERN_SUCCESS
)
1365 server_protocol_error( "mach_msg_send failed: 0x%08x\n", kret
);
1367 mach_port_deallocate(mach_task_self(), wineserver_port
);
1369 #endif /* __APPLE__ */
1372 /***********************************************************************
1375 * Retrieve the Unix tid to use on the server side for the current thread.
1377 static int get_unix_tid(void)
1380 #ifdef HAVE_PTHREAD_GETTHREADID_NP
1381 ret
= pthread_getthreadid_np();
1382 #elif defined(linux)
1383 ret
= syscall( __NR_gettid
);
1384 #elif defined(__sun)
1385 ret
= pthread_self();
1386 #elif defined(__APPLE__)
1387 ret
= mach_thread_self();
1388 mach_port_deallocate(mach_task_self(), ret
);
1389 #elif defined(__NetBSD__)
1391 #elif defined(__FreeBSD__)
1395 #elif defined(__DragonFly__)
1402 /***********************************************************************
1405 * Create the server->client communication pipe.
1407 static int init_thread_pipe(void)
1412 ss
.ss_sp
= get_signal_stack();
1413 ss
.ss_size
= signal_stack_size
;
1415 sigaltstack( &ss
, NULL
);
1417 if (server_pipe( reply_pipe
) == -1) server_protocol_perror( "pipe" );
1418 if (server_pipe( ntdll_get_thread_data()->wait_fd
) == -1) server_protocol_perror( "pipe" );
1419 wine_server_send_fd( reply_pipe
[1] );
1420 wine_server_send_fd( ntdll_get_thread_data()->wait_fd
[1] );
1421 ntdll_get_thread_data()->reply_fd
= reply_pipe
[0];
1422 return reply_pipe
[1];
1426 /***********************************************************************
1427 * process_exit_wrapper
1429 * Close server socket and exit process normally.
1431 void process_exit_wrapper( int status
)
1438 /***********************************************************************
1439 * server_init_process
1441 * Start the server and create the initial socket pair.
1443 size_t server_init_process(void)
1445 const char *arch
= getenv( "WINEARCH" );
1446 const char *env_socket
= getenv( "WINESERVERSOCKET" );
1447 obj_handle_t version
;
1449 int ret
, reply_pipe
;
1450 struct sigaction sig_act
;
1457 fd_socket
= atoi( env_socket
);
1458 if (fcntl( fd_socket
, F_SETFD
, FD_CLOEXEC
) == -1)
1459 fatal_perror( "Bad server socket %d", fd_socket
);
1460 unsetenv( "WINESERVERSOCKET" );
1464 const char *arch
= getenv( "WINEARCH" );
1466 if (arch
&& strcmp( arch
, "win32" ) && strcmp( arch
, "win64" ))
1467 fatal_error( "WINEARCH set to invalid value '%s', it must be either win32 or win64.\n", arch
);
1469 fd_socket
= server_connect();
1472 /* setup the signal mask */
1473 sigemptyset( &server_block_set
);
1474 sigaddset( &server_block_set
, SIGALRM
);
1475 sigaddset( &server_block_set
, SIGIO
);
1476 sigaddset( &server_block_set
, SIGINT
);
1477 sigaddset( &server_block_set
, SIGHUP
);
1478 sigaddset( &server_block_set
, SIGUSR1
);
1479 sigaddset( &server_block_set
, SIGUSR2
);
1480 sigaddset( &server_block_set
, SIGCHLD
);
1481 pthread_sigmask( SIG_BLOCK
, &server_block_set
, NULL
);
1483 /* receive the first thread request fd on the main socket */
1484 ntdll_get_thread_data()->request_fd
= receive_fd( &version
);
1487 /* now that we hopefully received the server_pid, disable SO_PASSCRED */
1490 setsockopt( fd_socket
, SOL_SOCKET
, SO_PASSCRED
, &enable
, sizeof(enable
) );
1494 if (version
!= SERVER_PROTOCOL_VERSION
)
1495 server_protocol_error( "version mismatch %d/%d.\n"
1496 "Your %s binary was not upgraded correctly,\n"
1497 "or you have an older one somewhere in your PATH.\n"
1498 "Or maybe the wrong wineserver is still running?\n",
1499 version
, SERVER_PROTOCOL_VERSION
,
1500 (version
> SERVER_PROTOCOL_VERSION
) ? "wine" : "wineserver" );
1501 #if defined(__linux__) && defined(HAVE_PRCTL)
1502 /* work around Ubuntu's ptrace breakage */
1503 if (server_pid
!= -1) prctl( 0x59616d61 /* PR_SET_PTRACER */, server_pid
);
1506 /* ignore SIGPIPE so that we get an EPIPE error instead */
1507 sig_act
.sa_handler
= SIG_IGN
;
1508 sig_act
.sa_flags
= 0;
1509 sigemptyset( &sig_act
.sa_mask
);
1510 sigaction( SIGPIPE
, &sig_act
, NULL
);
1512 reply_pipe
= init_thread_pipe();
1514 SERVER_START_REQ( init_first_thread
)
1516 req
->unix_pid
= getpid();
1517 req
->unix_tid
= get_unix_tid();
1518 req
->reply_fd
= reply_pipe
;
1519 req
->wait_fd
= ntdll_get_thread_data()->wait_fd
[1];
1520 req
->debug_level
= (TRACE_ON(server
) != 0);
1521 wine_server_set_reply( req
, supported_machines
, sizeof(supported_machines
) );
1522 ret
= wine_server_call( req
);
1525 peb
->SessionId
= reply
->session_id
;
1526 info_size
= reply
->info_size
;
1527 server_start_time
= reply
->server_start
;
1528 supported_machines_count
= wine_server_reply_size( reply
) / sizeof(*supported_machines
);
1531 close( reply_pipe
);
1533 if (ret
) server_protocol_error( "init_first_thread failed with status %x\n", ret
);
1535 if (!supported_machines_count
)
1536 fatal_error( "'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.\n",
1539 native_machine
= supported_machines
[0];
1540 if (is_machine_64bit( native_machine
))
1542 if (arch
&& !strcmp( arch
, "win32" ))
1543 fatal_error( "WINEARCH set to win32 but '%s' is a 64-bit installation.\n", config_dir
);
1546 NtCurrentTeb()->GdiBatchCount
= PtrToUlong( (char *)NtCurrentTeb() - teb_offset
);
1547 NtCurrentTeb()->WowTebOffset
= -teb_offset
;
1548 wow_peb
= (PEB64
*)((char *)peb
- page_size
);
1554 fatal_error( "'%s' is a 32-bit installation, it cannot support 64-bit applications.\n", config_dir
);
1555 if (arch
&& !strcmp( arch
, "win64" ))
1556 fatal_error( "WINEARCH set to win64 but '%s' is a 32-bit installation.\n", config_dir
);
1559 set_thread_id( NtCurrentTeb(), pid
, tid
);
1561 for (i
= 0; i
< supported_machines_count
; i
++)
1562 if (supported_machines
[i
] == current_machine
) return info_size
;
1564 fatal_error( "wineserver doesn't support the %04x architecture\n", current_machine
);
1568 /***********************************************************************
1569 * server_init_process_done
1571 void server_init_process_done(void)
1576 FILE_FS_DEVICE_INFORMATION info
;
1578 if (!get_device_info( initial_cwd
, &info
) && (info
.Characteristics
& FILE_REMOVABLE_MEDIA
))
1580 close( initial_cwd
);
1583 send_server_task_port();
1585 if (main_image_info
.ImageCharacteristics
& IMAGE_FILE_LARGE_ADDRESS_AWARE
)
1586 virtual_set_large_address_space();
1588 /* Install signal handlers; this cannot be done earlier, since we cannot
1589 * send exceptions to the debugger before the create process event that
1590 * is sent by init_process_done */
1591 signal_init_process();
1593 /* always send the native TEB */
1594 if (!(teb
= NtCurrentTeb64())) teb
= NtCurrentTeb();
1596 /* Signal the parent process to continue */
1597 SERVER_START_REQ( init_process_done
)
1599 req
->teb
= wine_server_client_ptr( teb
);
1600 req
->peb
= NtCurrentTeb64() ? NtCurrentTeb64()->Peb
: wine_server_client_ptr( peb
);
1602 req
->ldt_copy
= wine_server_client_ptr( &__wine_ldt_copy
);
1604 status
= wine_server_call( req
);
1605 suspend
= reply
->suspend
;
1606 entry
= wine_server_get_ptr( reply
->entry
);
1611 signal_start_thread( entry
, peb
, suspend
, NtCurrentTeb() );
1615 /***********************************************************************
1616 * server_init_thread
1618 * Send an init thread request.
1620 void server_init_thread( void *entry_point
, BOOL
*suspend
)
1623 int reply_pipe
= init_thread_pipe();
1625 /* always send the native TEB */
1626 if (!(teb
= NtCurrentTeb64())) teb
= NtCurrentTeb();
1628 SERVER_START_REQ( init_thread
)
1630 req
->unix_tid
= get_unix_tid();
1631 req
->teb
= wine_server_client_ptr( teb
);
1632 req
->entry
= wine_server_client_ptr( entry_point
);
1633 req
->reply_fd
= reply_pipe
;
1634 req
->wait_fd
= ntdll_get_thread_data()->wait_fd
[1];
1635 wine_server_call( req
);
1636 *suspend
= reply
->suspend
;
1639 close( reply_pipe
);
1643 /******************************************************************************
1646 NTSTATUS WINAPI
NtDuplicateObject( HANDLE source_process
, HANDLE source
, HANDLE dest_process
, HANDLE
*dest
,
1647 ACCESS_MASK access
, ULONG attributes
, ULONG options
)
1653 if (dest
) *dest
= 0;
1655 if ((options
& DUPLICATE_CLOSE_SOURCE
) && source_process
!= NtCurrentProcess())
1658 apc_result_t result
;
1660 memset( &call
, 0, sizeof(call
) );
1662 call
.dup_handle
.type
= APC_DUP_HANDLE
;
1663 call
.dup_handle
.src_handle
= wine_server_obj_handle( source
);
1664 call
.dup_handle
.dst_process
= wine_server_obj_handle( dest_process
);
1665 call
.dup_handle
.access
= access
;
1666 call
.dup_handle
.attributes
= attributes
;
1667 call
.dup_handle
.options
= options
;
1668 ret
= server_queue_process_apc( source_process
, &call
, &result
);
1669 if (ret
!= STATUS_SUCCESS
) return ret
;
1671 if (!result
.dup_handle
.status
)
1672 *dest
= wine_server_ptr_handle( result
.dup_handle
.handle
);
1673 return result
.dup_handle
.status
;
1676 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1678 /* always remove the cached fd; if the server request fails we'll just
1679 * retrieve it again */
1680 if (options
& DUPLICATE_CLOSE_SOURCE
)
1681 fd
= remove_fd_from_cache( source
);
1683 SERVER_START_REQ( dup_handle
)
1685 req
->src_process
= wine_server_obj_handle( source_process
);
1686 req
->src_handle
= wine_server_obj_handle( source
);
1687 req
->dst_process
= wine_server_obj_handle( dest_process
);
1688 req
->access
= access
;
1689 req
->attributes
= attributes
;
1690 req
->options
= options
;
1691 if (!(ret
= wine_server_call( req
)))
1693 if (dest
) *dest
= wine_server_ptr_handle( reply
->handle
);
1698 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1700 if (fd
!= -1) close( fd
);
1705 /**************************************************************************
1706 * NtCompareObjects (NTDLL.@)
1708 NTSTATUS WINAPI
NtCompareObjects( HANDLE first
, HANDLE second
)
1712 SERVER_START_REQ( compare_objects
)
1714 req
->first
= wine_server_obj_handle( first
);
1715 req
->second
= wine_server_obj_handle( second
);
1716 status
= wine_server_call( req
);
1724 /**************************************************************************
1727 NTSTATUS WINAPI
NtClose( HANDLE handle
)
1734 if (HandleToLong( handle
) >= ~5 && HandleToLong( handle
) <= ~0)
1735 return STATUS_SUCCESS
;
1737 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1739 /* always remove the cached fd; if the server request fails we'll just
1740 * retrieve it again */
1741 fd
= remove_fd_from_cache( handle
);
1743 SERVER_START_REQ( close_handle
)
1745 req
->handle
= wine_server_obj_handle( handle
);
1746 ret
= wine_server_call( req
);
1750 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1752 if (fd
!= -1) close( fd
);
1754 if (ret
!= STATUS_INVALID_HANDLE
|| !handle
) return ret
;
1755 if (!peb
->BeingDebugged
) return ret
;
1756 if (!NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort
, &port
, sizeof(port
), NULL
) && port
)
1758 NtCurrentTeb()->ExceptionCode
= ret
;
1759 call_raise_user_exception_dispatcher();