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 timeout_t server_start_time
= 0; /* time of server startup */
102 sigset_t server_block_set
; /* signals to block during server calls */
103 static int fd_socket
= -1; /* socket to exchange file descriptors with the server */
104 static int initial_cwd
= -1;
105 static pid_t server_pid
;
106 static pthread_mutex_t fd_cache_mutex
= PTHREAD_MUTEX_INITIALIZER
;
108 /* atomically exchange a 64-bit value */
109 static inline LONG64
interlocked_xchg64( LONG64
*dest
, LONG64 val
)
112 return (LONG64
)InterlockedExchangePointer( (void **)dest
, (void *)val
);
115 while (InterlockedCompareExchange64( dest
, val
, tmp
) != tmp
) tmp
= *dest
;
121 static void fatal_error( const char *err
, ... ) __attribute__((noreturn
, format(printf
,1,2)));
122 static void fatal_perror( const char *err
, ... ) __attribute__((noreturn
, format(printf
,1,2)));
123 static void server_connect_error( const char *serverdir
) __attribute__((noreturn
));
126 /* die on a fatal error; use only during initialization */
127 static void fatal_error( const char *err
, ... )
131 va_start( args
, err
);
132 fprintf( stderr
, "wine: " );
133 vfprintf( stderr
, err
, args
);
138 /* die on a fatal error; use only during initialization */
139 static void fatal_perror( const char *err
, ... )
143 va_start( args
, err
);
144 fprintf( stderr
, "wine: " );
145 vfprintf( stderr
, err
, args
);
151 /***********************************************************************
152 * server_protocol_error
154 static DECLSPEC_NORETURN
void server_protocol_error( const char *err
, ... )
158 va_start( args
, err
);
159 fprintf( stderr
, "wine client error:%x: ", (int)GetCurrentThreadId() );
160 vfprintf( stderr
, err
, args
);
166 /***********************************************************************
167 * server_protocol_perror
169 static DECLSPEC_NORETURN
void server_protocol_perror( const char *err
)
171 fprintf( stderr
, "wine client error:%x: ", (int)GetCurrentThreadId() );
177 /***********************************************************************
180 * Send a request to the server.
182 static unsigned int send_request( const struct __server_request_info
*req
)
187 if (!req
->u
.req
.request_header
.request_size
)
189 if ((ret
= write( ntdll_get_thread_data()->request_fd
, &req
->u
.req
,
190 sizeof(req
->u
.req
) )) == sizeof(req
->u
.req
)) return STATUS_SUCCESS
;
195 struct iovec vec
[__SERVER_MAX_DATA
+1];
197 vec
[0].iov_base
= (void *)&req
->u
.req
;
198 vec
[0].iov_len
= sizeof(req
->u
.req
);
199 for (i
= 0; i
< req
->data_count
; i
++)
201 vec
[i
+1].iov_base
= (void *)req
->data
[i
].ptr
;
202 vec
[i
+1].iov_len
= req
->data
[i
].size
;
204 if ((ret
= writev( ntdll_get_thread_data()->request_fd
, vec
, i
+1 )) ==
205 req
->u
.req
.request_header
.request_size
+ sizeof(req
->u
.req
)) return STATUS_SUCCESS
;
208 if (ret
>= 0) server_protocol_error( "partial write %d\n", ret
);
209 if (errno
== EPIPE
) abort_thread(0);
210 if (errno
== EFAULT
) return STATUS_ACCESS_VIOLATION
;
211 server_protocol_perror( "write" );
215 /***********************************************************************
218 * Read data from the reply buffer; helper for wait_reply.
220 static void read_reply_data( void *buffer
, size_t size
)
226 if ((ret
= read( ntdll_get_thread_data()->reply_fd
, buffer
, size
)) > 0)
228 if (!(size
-= ret
)) return;
229 buffer
= (char *)buffer
+ ret
;
233 if (errno
== EINTR
) continue;
234 if (errno
== EPIPE
) break;
235 server_protocol_perror("read");
237 /* the server closed the connection; time to die... */
242 /***********************************************************************
245 * Wait for a reply from the server.
247 static inline unsigned int wait_reply( struct __server_request_info
*req
)
249 read_reply_data( &req
->u
.reply
, sizeof(req
->u
.reply
) );
250 if (req
->u
.reply
.reply_header
.reply_size
)
251 read_reply_data( req
->reply_data
, req
->u
.reply
.reply_header
.reply_size
);
252 return req
->u
.reply
.reply_header
.error
;
256 /***********************************************************************
257 * server_call_unlocked
259 unsigned int server_call_unlocked( void *req_ptr
)
261 struct __server_request_info
* const req
= req_ptr
;
264 if ((ret
= send_request( req
))) return ret
;
265 return wait_reply( req
);
269 /***********************************************************************
272 * Perform a server call.
274 unsigned int CDECL
wine_server_call( void *req_ptr
)
279 pthread_sigmask( SIG_BLOCK
, &server_block_set
, &old_set
);
280 ret
= server_call_unlocked( req_ptr
);
281 pthread_sigmask( SIG_SETMASK
, &old_set
, NULL
);
286 /***********************************************************************
287 * unixcall_wine_server_call
289 * Perform a server call.
291 NTSTATUS
unixcall_wine_server_call( void *args
)
293 return wine_server_call( args
);
297 /***********************************************************************
298 * server_enter_uninterrupted_section
300 void server_enter_uninterrupted_section( pthread_mutex_t
*mutex
, sigset_t
*sigset
)
302 pthread_sigmask( SIG_BLOCK
, &server_block_set
, sigset
);
307 /***********************************************************************
308 * server_leave_uninterrupted_section
310 void server_leave_uninterrupted_section( pthread_mutex_t
*mutex
, sigset_t
*sigset
)
312 mutex_unlock( mutex
);
313 pthread_sigmask( SIG_SETMASK
, sigset
, NULL
);
317 /***********************************************************************
320 * Wait for a reply on the waiting pipe of the current thread.
322 static int wait_select_reply( void *cookie
)
325 struct wake_up_reply reply
;
329 ret
= read( ntdll_get_thread_data()->wait_fd
[0], &reply
, sizeof(reply
) );
330 if (ret
== sizeof(reply
))
332 if (!reply
.cookie
) abort_thread( reply
.signaled
); /* thread got killed */
333 if (wine_server_get_ptr(reply
.cookie
) == cookie
) return reply
.signaled
;
334 /* we stole another reply, wait for the real one */
335 signaled
= wait_select_reply( cookie
);
336 /* and now put the wrong one back in the pipe */
339 ret
= write( ntdll_get_thread_data()->wait_fd
[1], &reply
, sizeof(reply
) );
340 if (ret
== sizeof(reply
)) break;
341 if (ret
>= 0) server_protocol_error( "partial wakeup write %d\n", ret
);
342 if (errno
== EINTR
) continue;
343 server_protocol_perror("wakeup write");
347 if (ret
>= 0) server_protocol_error( "partial wakeup read %d\n", ret
);
348 if (errno
== EINTR
) continue;
349 server_protocol_perror("wakeup read");
354 /***********************************************************************
357 static NTSTATUS
invoke_user_apc( CONTEXT
*context
, const user_apc_t
*apc
, NTSTATUS status
)
359 return call_user_apc_dispatcher( context
, apc
->args
[0], apc
->args
[1], apc
->args
[2],
360 wine_server_get_ptr( apc
->func
), status
);
364 /***********************************************************************
367 static void invoke_system_apc( const apc_call_t
*call
, apc_result_t
*result
, BOOL self
)
372 memset( result
, 0, sizeof(*result
) );
380 struct async_fileio
*user
= wine_server_get_ptr( call
->async_io
.user
);
381 ULONG_PTR info
= call
->async_io
.result
;
384 result
->type
= call
->type
;
385 status
= call
->async_io
.status
;
386 if (user
->callback( user
, &info
, &status
))
388 result
->async_io
.status
= status
;
389 result
->async_io
.total
= info
;
390 /* the server will pass us NULL if a call failed synchronously */
391 set_async_iosb( call
->async_io
.sb
, result
->async_io
.status
, info
);
393 else result
->async_io
.status
= STATUS_PENDING
; /* restart it */
396 case APC_VIRTUAL_ALLOC
:
397 result
->type
= call
->type
;
398 addr
= wine_server_get_ptr( call
->virtual_alloc
.addr
);
399 size
= call
->virtual_alloc
.size
;
400 bits
= call
->virtual_alloc
.zero_bits
;
401 if ((ULONG_PTR
)addr
== call
->virtual_alloc
.addr
&& size
== call
->virtual_alloc
.size
&&
402 bits
== call
->virtual_alloc
.zero_bits
)
404 result
->virtual_alloc
.status
= NtAllocateVirtualMemory( NtCurrentProcess(), &addr
, bits
, &size
,
405 call
->virtual_alloc
.op_type
,
406 call
->virtual_alloc
.prot
);
407 result
->virtual_alloc
.addr
= wine_server_client_ptr( addr
);
408 result
->virtual_alloc
.size
= size
;
410 else result
->virtual_alloc
.status
= STATUS_WORKING_SET_LIMIT_RANGE
;
412 case APC_VIRTUAL_ALLOC_EX
:
414 MEM_ADDRESS_REQUIREMENTS r
;
415 MEM_EXTENDED_PARAMETER ext
[2];
418 result
->type
= call
->type
;
419 addr
= wine_server_get_ptr( call
->virtual_alloc_ex
.addr
);
420 size
= call
->virtual_alloc_ex
.size
;
421 if ((ULONG_PTR
)addr
!= call
->virtual_alloc_ex
.addr
|| size
!= call
->virtual_alloc_ex
.size
)
423 result
->virtual_alloc_ex
.status
= STATUS_WORKING_SET_LIMIT_RANGE
;
426 if (call
->virtual_alloc_ex
.limit
|| call
->virtual_alloc_ex
.align
)
428 SYSTEM_BASIC_INFORMATION sbi
;
431 virtual_get_system_info( &sbi
, is_wow64() );
432 limit
= min( (ULONG_PTR
)sbi
.HighestUserAddress
, call
->virtual_alloc_ex
.limit
);
433 align
= call
->virtual_alloc_ex
.align
;
434 if (align
!= call
->virtual_alloc_ex
.align
)
436 result
->virtual_alloc_ex
.status
= STATUS_WORKING_SET_LIMIT_RANGE
;
439 r
.LowestStartingAddress
= NULL
;
440 r
.HighestEndingAddress
= (void *)limit
;
442 ext
[count
].Type
= MemExtendedParameterAddressRequirements
;
443 ext
[count
].Pointer
= &r
;
446 if (call
->virtual_alloc_ex
.attributes
)
448 ext
[count
].Type
= MemExtendedParameterAttributeFlags
;
449 ext
[count
].ULong64
= call
->virtual_alloc_ex
.attributes
;
452 result
->virtual_alloc_ex
.status
= NtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr
, &size
,
453 call
->virtual_alloc_ex
.op_type
,
454 call
->virtual_alloc_ex
.prot
,
456 result
->virtual_alloc_ex
.addr
= wine_server_client_ptr( addr
);
457 result
->virtual_alloc_ex
.size
= size
;
460 case APC_VIRTUAL_FREE
:
461 result
->type
= call
->type
;
462 addr
= wine_server_get_ptr( call
->virtual_free
.addr
);
463 size
= call
->virtual_free
.size
;
464 if ((ULONG_PTR
)addr
== call
->virtual_free
.addr
&& size
== call
->virtual_free
.size
)
466 result
->virtual_free
.status
= NtFreeVirtualMemory( NtCurrentProcess(), &addr
, &size
,
467 call
->virtual_free
.op_type
);
468 result
->virtual_free
.addr
= wine_server_client_ptr( addr
);
469 result
->virtual_free
.size
= size
;
471 else result
->virtual_free
.status
= STATUS_INVALID_PARAMETER
;
473 case APC_VIRTUAL_QUERY
:
475 MEMORY_BASIC_INFORMATION info
;
476 result
->type
= call
->type
;
477 addr
= wine_server_get_ptr( call
->virtual_query
.addr
);
478 if ((ULONG_PTR
)addr
== call
->virtual_query
.addr
)
479 result
->virtual_query
.status
= NtQueryVirtualMemory( NtCurrentProcess(),
480 addr
, MemoryBasicInformation
, &info
,
481 sizeof(info
), NULL
);
483 result
->virtual_query
.status
= STATUS_WORKING_SET_LIMIT_RANGE
;
485 if (result
->virtual_query
.status
== STATUS_SUCCESS
)
487 result
->virtual_query
.base
= wine_server_client_ptr( info
.BaseAddress
);
488 result
->virtual_query
.alloc_base
= wine_server_client_ptr( info
.AllocationBase
);
489 result
->virtual_query
.size
= info
.RegionSize
;
490 result
->virtual_query
.prot
= info
.Protect
;
491 result
->virtual_query
.alloc_prot
= info
.AllocationProtect
;
492 result
->virtual_query
.state
= info
.State
>> 12;
493 result
->virtual_query
.alloc_type
= info
.Type
>> 16;
497 case APC_VIRTUAL_PROTECT
:
498 result
->type
= call
->type
;
499 addr
= wine_server_get_ptr( call
->virtual_protect
.addr
);
500 size
= call
->virtual_protect
.size
;
501 if ((ULONG_PTR
)addr
== call
->virtual_protect
.addr
&& size
== call
->virtual_protect
.size
)
504 result
->virtual_protect
.status
= NtProtectVirtualMemory( NtCurrentProcess(), &addr
, &size
,
505 call
->virtual_protect
.prot
, &prot
);
506 result
->virtual_protect
.addr
= wine_server_client_ptr( addr
);
507 result
->virtual_protect
.size
= size
;
508 result
->virtual_protect
.prot
= prot
;
510 else result
->virtual_protect
.status
= STATUS_INVALID_PARAMETER
;
512 case APC_VIRTUAL_FLUSH
:
513 result
->type
= call
->type
;
514 addr
= wine_server_get_ptr( call
->virtual_flush
.addr
);
515 size
= call
->virtual_flush
.size
;
516 if ((ULONG_PTR
)addr
== call
->virtual_flush
.addr
&& size
== call
->virtual_flush
.size
)
518 result
->virtual_flush
.status
= NtFlushVirtualMemory( NtCurrentProcess(),
519 (const void **)&addr
, &size
, 0 );
520 result
->virtual_flush
.addr
= wine_server_client_ptr( addr
);
521 result
->virtual_flush
.size
= size
;
523 else result
->virtual_flush
.status
= STATUS_INVALID_PARAMETER
;
525 case APC_VIRTUAL_LOCK
:
526 result
->type
= call
->type
;
527 addr
= wine_server_get_ptr( call
->virtual_lock
.addr
);
528 size
= call
->virtual_lock
.size
;
529 if ((ULONG_PTR
)addr
== call
->virtual_lock
.addr
&& size
== call
->virtual_lock
.size
)
531 result
->virtual_lock
.status
= NtLockVirtualMemory( NtCurrentProcess(), &addr
, &size
, 0 );
532 result
->virtual_lock
.addr
= wine_server_client_ptr( addr
);
533 result
->virtual_lock
.size
= size
;
535 else result
->virtual_lock
.status
= STATUS_INVALID_PARAMETER
;
537 case APC_VIRTUAL_UNLOCK
:
538 result
->type
= call
->type
;
539 addr
= wine_server_get_ptr( call
->virtual_unlock
.addr
);
540 size
= call
->virtual_unlock
.size
;
541 if ((ULONG_PTR
)addr
== call
->virtual_unlock
.addr
&& size
== call
->virtual_unlock
.size
)
543 result
->virtual_unlock
.status
= NtUnlockVirtualMemory( NtCurrentProcess(), &addr
, &size
, 0 );
544 result
->virtual_unlock
.addr
= wine_server_client_ptr( addr
);
545 result
->virtual_unlock
.size
= size
;
547 else result
->virtual_unlock
.status
= STATUS_INVALID_PARAMETER
;
550 result
->type
= call
->type
;
551 addr
= wine_server_get_ptr( call
->map_view
.addr
);
552 size
= call
->map_view
.size
;
553 bits
= call
->map_view
.zero_bits
;
554 if ((ULONG_PTR
)addr
== call
->map_view
.addr
&& size
== call
->map_view
.size
&&
555 bits
== call
->map_view
.zero_bits
)
557 LARGE_INTEGER offset
;
558 offset
.QuadPart
= call
->map_view
.offset
;
559 result
->map_view
.status
= NtMapViewOfSection( wine_server_ptr_handle(call
->map_view
.handle
),
561 &addr
, bits
, 0, &offset
, &size
, 0,
562 call
->map_view
.alloc_type
, call
->map_view
.prot
);
563 result
->map_view
.addr
= wine_server_client_ptr( addr
);
564 result
->map_view
.size
= size
;
566 else result
->map_view
.status
= STATUS_INVALID_PARAMETER
;
567 if (!self
) NtClose( wine_server_ptr_handle(call
->map_view
.handle
) );
569 case APC_MAP_VIEW_EX
:
571 MEM_ADDRESS_REQUIREMENTS addr_req
;
572 MEM_EXTENDED_PARAMETER ext
[2];
574 LARGE_INTEGER offset
;
576 result
->type
= call
->type
;
577 addr
= wine_server_get_ptr( call
->map_view_ex
.addr
);
578 size
= call
->map_view_ex
.size
;
579 offset
.QuadPart
= call
->map_view_ex
.offset
;
580 if ((ULONG_PTR
)addr
!= call
->map_view_ex
.addr
|| size
!= call
->map_view_ex
.size
)
582 result
->map_view_ex
.status
= STATUS_WORKING_SET_LIMIT_RANGE
;
585 if (call
->map_view_ex
.limit
)
587 SYSTEM_BASIC_INFORMATION sbi
;
590 virtual_get_system_info( &sbi
, is_wow64() );
591 limit
= min( (ULONG_PTR
)sbi
.HighestUserAddress
, call
->map_view_ex
.limit
);
592 addr_req
.LowestStartingAddress
= NULL
;
593 addr_req
.HighestEndingAddress
= (void *)limit
;
594 addr_req
.Alignment
= 0;
595 ext
[count
].Type
= MemExtendedParameterAddressRequirements
;
596 ext
[count
].Pointer
= &addr_req
;
599 if (call
->map_view_ex
.machine
)
601 ext
[count
].Type
= MemExtendedParameterImageMachine
;
602 ext
[count
].ULong
= call
->map_view_ex
.machine
;
605 result
->map_view_ex
.status
= NtMapViewOfSectionEx( wine_server_ptr_handle(call
->map_view_ex
.handle
),
606 NtCurrentProcess(), &addr
, &offset
, &size
,
607 call
->map_view_ex
.alloc_type
,
608 call
->map_view_ex
.prot
, ext
, count
);
609 result
->map_view_ex
.addr
= wine_server_client_ptr( addr
);
610 result
->map_view_ex
.size
= size
;
611 if (!self
) NtClose( wine_server_ptr_handle(call
->map_view_ex
.handle
) );
615 result
->type
= call
->type
;
616 addr
= wine_server_get_ptr( call
->unmap_view
.addr
);
617 if ((ULONG_PTR
)addr
== call
->unmap_view
.addr
)
618 result
->unmap_view
.status
= NtUnmapViewOfSectionEx( NtCurrentProcess(), addr
, call
->unmap_view
.flags
);
620 result
->unmap_view
.status
= STATUS_INVALID_PARAMETER
;
622 case APC_CREATE_THREAD
:
624 ULONG_PTR buffer
[offsetof( PS_ATTRIBUTE_LIST
, Attributes
[2] ) / sizeof(ULONG_PTR
)];
625 PS_ATTRIBUTE_LIST
*attr
= (PS_ATTRIBUTE_LIST
*)buffer
;
629 ULONG_PTR zero_bits
= call
->create_thread
.zero_bits
;
630 SIZE_T reserve
= call
->create_thread
.reserve
;
631 SIZE_T commit
= call
->create_thread
.commit
;
632 void *func
= wine_server_get_ptr( call
->create_thread
.func
);
633 void *arg
= wine_server_get_ptr( call
->create_thread
.arg
);
635 result
->type
= call
->type
;
636 if (reserve
== call
->create_thread
.reserve
&& commit
== call
->create_thread
.commit
&&
637 (ULONG_PTR
)func
== call
->create_thread
.func
&& (ULONG_PTR
)arg
== call
->create_thread
.arg
)
639 /* FIXME: hack for debugging 32-bit process without a 64-bit ntdll */
640 if (is_old_wow64() && func
== (void *)0x7ffe1000) func
= pDbgUiRemoteBreakin
;
641 attr
->TotalLength
= sizeof(buffer
);
642 attr
->Attributes
[0].Attribute
= PS_ATTRIBUTE_CLIENT_ID
;
643 attr
->Attributes
[0].Size
= sizeof(id
);
644 attr
->Attributes
[0].ValuePtr
= &id
;
645 attr
->Attributes
[0].ReturnLength
= NULL
;
646 attr
->Attributes
[1].Attribute
= PS_ATTRIBUTE_TEB_ADDRESS
;
647 attr
->Attributes
[1].Size
= sizeof(teb
);
648 attr
->Attributes
[1].ValuePtr
= &teb
;
649 attr
->Attributes
[1].ReturnLength
= NULL
;
650 result
->create_thread
.status
= NtCreateThreadEx( &handle
, THREAD_ALL_ACCESS
, NULL
,
651 NtCurrentProcess(), func
, arg
,
652 call
->create_thread
.flags
, zero_bits
,
653 commit
, reserve
, attr
);
654 result
->create_thread
.handle
= wine_server_obj_handle( handle
);
655 result
->create_thread
.pid
= HandleToULong(id
.UniqueProcess
);
656 result
->create_thread
.tid
= HandleToULong(id
.UniqueThread
);
657 result
->create_thread
.teb
= wine_server_client_ptr( teb
);
659 else result
->create_thread
.status
= STATUS_INVALID_PARAMETER
;
664 HANDLE dst_handle
= NULL
;
666 result
->type
= call
->type
;
668 result
->dup_handle
.status
= NtDuplicateObject( NtCurrentProcess(),
669 wine_server_ptr_handle(call
->dup_handle
.src_handle
),
670 wine_server_ptr_handle(call
->dup_handle
.dst_process
),
671 &dst_handle
, call
->dup_handle
.access
,
672 call
->dup_handle
.attributes
, call
->dup_handle
.options
);
673 result
->dup_handle
.handle
= wine_server_obj_handle( dst_handle
);
674 if (!self
) NtClose( wine_server_ptr_handle(call
->dup_handle
.dst_process
) );
678 server_protocol_error( "get_apc_request: bad type %d\n", call
->type
);
684 /***********************************************************************
687 unsigned int server_select( const select_op_t
*select_op
, data_size_t size
, UINT flags
,
688 timeout_t abs_timeout
, context_t
*context
, user_apc_t
*user_apc
)
692 obj_handle_t apc_handle
= 0;
693 BOOL suspend_context
= !!context
;
699 memset( &result
, 0, sizeof(result
) );
703 pthread_sigmask( SIG_BLOCK
, &server_block_set
, &old_set
);
706 SERVER_START_REQ( select
)
709 req
->cookie
= wine_server_client_ptr( &cookie
);
710 req
->prev_apc
= apc_handle
;
711 req
->timeout
= abs_timeout
;
713 wine_server_add_data( req
, &result
, sizeof(result
) );
714 wine_server_add_data( req
, select_op
, size
);
717 data_size_t ctx_size
= (context
[1].machine
? 2 : 1) * sizeof(*context
);
718 wine_server_add_data( req
, context
, ctx_size
);
719 suspend_context
= FALSE
; /* server owns the context now */
721 if (context
) wine_server_set_reply( req
, context
, 2 * sizeof(*context
) );
722 ret
= server_call_unlocked( req
);
723 signaled
= reply
->signaled
;
724 apc_handle
= reply
->apc_handle
;
729 if (ret
!= STATUS_KERNEL_APC
) break;
730 invoke_system_apc( &call
, &result
, FALSE
);
732 /* don't signal multiple times */
733 if (size
>= sizeof(select_op
->signal_and_wait
) && select_op
->op
== SELECT_SIGNAL_AND_WAIT
)
734 size
= offsetof( select_op_t
, signal_and_wait
.signal
);
736 pthread_sigmask( SIG_SETMASK
, &old_set
, NULL
);
739 ret
= wait_select_reply( &cookie
);
741 while (ret
== STATUS_USER_APC
|| ret
== STATUS_KERNEL_APC
);
743 if (ret
== STATUS_USER_APC
) *user_apc
= call
.user
;
748 /***********************************************************************
751 unsigned int server_wait( const select_op_t
*select_op
, data_size_t size
, UINT flags
,
752 const LARGE_INTEGER
*timeout
)
754 timeout_t abs_timeout
= timeout
? timeout
->QuadPart
: TIMEOUT_INFINITE
;
762 NtQueryPerformanceCounter( &now
, NULL
);
763 abs_timeout
-= now
.QuadPart
;
766 ret
= server_select( select_op
, size
, flags
, abs_timeout
, NULL
, &apc
);
767 if (ret
== STATUS_USER_APC
) return invoke_user_apc( NULL
, &apc
, ret
);
769 /* A test on Windows 2000 shows that Windows always yields during
770 a wait, but a wait that is hit by an event gets a priority
771 boost as well. This seems to model that behavior the closest. */
772 if (ret
== STATUS_TIMEOUT
) NtYieldExecution();
777 /***********************************************************************
778 * NtContinue (NTDLL.@)
780 NTSTATUS WINAPI
NtContinue( CONTEXT
*context
, BOOLEAN alertable
)
787 status
= server_select( NULL
, 0, SELECT_INTERRUPTIBLE
| SELECT_ALERTABLE
, 0, NULL
, &apc
);
788 if (status
== STATUS_USER_APC
) return invoke_user_apc( context
, &apc
, status
);
790 return signal_set_full_context( context
);
794 /***********************************************************************
795 * NtTestAlert (NTDLL.@)
797 NTSTATUS WINAPI
NtTestAlert(void)
802 status
= server_select( NULL
, 0, SELECT_INTERRUPTIBLE
| SELECT_ALERTABLE
, 0, NULL
, &apc
);
803 if (status
== STATUS_USER_APC
) invoke_user_apc( NULL
, &apc
, STATUS_SUCCESS
);
804 return STATUS_SUCCESS
;
808 /***********************************************************************
809 * server_queue_process_apc
811 unsigned int server_queue_process_apc( HANDLE process
, const apc_call_t
*call
, apc_result_t
*result
)
819 SERVER_START_REQ( queue_apc
)
821 req
->handle
= wine_server_obj_handle( process
);
822 wine_server_add_data( req
, call
, sizeof(*call
) );
823 if (!(ret
= wine_server_call( req
)))
825 handle
= wine_server_ptr_handle( reply
->handle
);
830 if (ret
!= STATUS_SUCCESS
) return ret
;
834 invoke_system_apc( call
, result
, TRUE
);
838 NtWaitForSingleObject( handle
, FALSE
, NULL
);
840 SERVER_START_REQ( get_apc_result
)
842 req
->handle
= wine_server_obj_handle( handle
);
843 if (!(ret
= wine_server_call( req
))) *result
= reply
->result
;
847 if (!ret
&& result
->type
== APC_NONE
) continue; /* APC didn't run, try again */
854 /***********************************************************************
855 * wine_server_send_fd
857 * Send a file descriptor to the server.
859 void wine_server_send_fd( int fd
)
862 struct msghdr msghdr
;
866 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
867 msghdr
.msg_accrights
= (void *)&fd
;
868 msghdr
.msg_accrightslen
= sizeof(fd
);
869 #else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
870 char cmsg_buffer
[256];
871 struct cmsghdr
*cmsg
;
872 msghdr
.msg_control
= cmsg_buffer
;
873 msghdr
.msg_controllen
= sizeof(cmsg_buffer
);
874 msghdr
.msg_flags
= 0;
875 cmsg
= CMSG_FIRSTHDR( &msghdr
);
876 cmsg
->cmsg_len
= CMSG_LEN( sizeof(fd
) );
877 cmsg
->cmsg_level
= SOL_SOCKET
;
878 cmsg
->cmsg_type
= SCM_RIGHTS
;
879 *(int *)CMSG_DATA(cmsg
) = fd
;
880 msghdr
.msg_controllen
= cmsg
->cmsg_len
;
881 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
883 msghdr
.msg_name
= NULL
;
884 msghdr
.msg_namelen
= 0;
885 msghdr
.msg_iov
= &vec
;
886 msghdr
.msg_iovlen
= 1;
888 vec
.iov_base
= (void *)&data
;
889 vec
.iov_len
= sizeof(data
);
891 data
.tid
= GetCurrentThreadId();
896 if ((ret
= sendmsg( fd_socket
, &msghdr
, 0 )) == sizeof(data
)) return;
897 if (ret
>= 0) server_protocol_error( "partial write %d\n", ret
);
898 if (errno
== EINTR
) continue;
899 if (errno
== EPIPE
) abort_thread(0);
900 server_protocol_perror( "sendmsg" );
905 /***********************************************************************
908 * Receive a file descriptor passed from the server.
910 static int receive_fd( obj_handle_t
*handle
)
913 struct msghdr msghdr
;
916 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
917 msghdr
.msg_accrights
= (void *)&fd
;
918 msghdr
.msg_accrightslen
= sizeof(fd
);
919 #else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
920 char cmsg_buffer
[256];
921 msghdr
.msg_control
= cmsg_buffer
;
922 msghdr
.msg_controllen
= sizeof(cmsg_buffer
);
923 msghdr
.msg_flags
= 0;
924 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
926 msghdr
.msg_name
= NULL
;
927 msghdr
.msg_namelen
= 0;
928 msghdr
.msg_iov
= &vec
;
929 msghdr
.msg_iovlen
= 1;
930 vec
.iov_base
= (void *)handle
;
931 vec
.iov_len
= sizeof(*handle
);
935 if ((ret
= recvmsg( fd_socket
, &msghdr
, MSG_CMSG_CLOEXEC
)) > 0)
937 #ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
938 struct cmsghdr
*cmsg
;
939 for (cmsg
= CMSG_FIRSTHDR( &msghdr
); cmsg
; cmsg
= CMSG_NXTHDR( &msghdr
, cmsg
))
941 if (cmsg
->cmsg_level
!= SOL_SOCKET
) continue;
942 if (cmsg
->cmsg_type
== SCM_RIGHTS
) fd
= *(int *)CMSG_DATA(cmsg
);
943 #ifdef SCM_CREDENTIALS
944 else if (cmsg
->cmsg_type
== SCM_CREDENTIALS
)
946 struct ucred
*ucred
= (struct ucred
*)CMSG_DATA(cmsg
);
947 server_pid
= ucred
->pid
;
951 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
952 if (fd
!= -1) fcntl( fd
, F_SETFD
, FD_CLOEXEC
); /* in case MSG_CMSG_CLOEXEC is not supported */
956 if (errno
== EINTR
) continue;
957 if (errno
== EPIPE
) break;
958 server_protocol_perror("recvmsg");
960 /* the server closed the connection; time to die... */
965 /***********************************************************************/
966 /* fd cache support */
974 enum server_fd_type type
: 5;
975 unsigned int access
: 3;
976 unsigned int options
: 24;
980 C_ASSERT( sizeof(union fd_cache_entry
) == sizeof(LONG64
) );
982 #define FD_CACHE_BLOCK_SIZE (65536 / sizeof(union fd_cache_entry))
983 #define FD_CACHE_ENTRIES 128
985 static union fd_cache_entry
*fd_cache
[FD_CACHE_ENTRIES
];
986 static union fd_cache_entry fd_cache_initial_block
[FD_CACHE_BLOCK_SIZE
];
988 static inline unsigned int handle_to_index( HANDLE handle
, unsigned int *entry
)
990 unsigned int idx
= (wine_server_obj_handle(handle
) >> 2) - 1;
991 *entry
= idx
/ FD_CACHE_BLOCK_SIZE
;
992 return idx
% FD_CACHE_BLOCK_SIZE
;
996 /***********************************************************************
999 * Caller must hold fd_cache_mutex.
1001 static BOOL
add_fd_to_cache( HANDLE handle
, int fd
, enum server_fd_type type
,
1002 unsigned int access
, unsigned int options
)
1004 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
1005 union fd_cache_entry cache
;
1007 if (entry
>= FD_CACHE_ENTRIES
)
1009 FIXME( "too many allocated handles, not caching %p\n", handle
);
1013 if (!fd_cache
[entry
]) /* do we need to allocate a new block of entries? */
1015 if (!entry
) fd_cache
[0] = fd_cache_initial_block
;
1018 void *ptr
= anon_mmap_alloc( FD_CACHE_BLOCK_SIZE
* sizeof(union fd_cache_entry
),
1019 PROT_READ
| PROT_WRITE
);
1020 if (ptr
== MAP_FAILED
) return FALSE
;
1021 fd_cache
[entry
] = ptr
;
1025 /* store fd+1 so that 0 can be used as the unset value */
1026 cache
.s
.fd
= fd
+ 1;
1027 cache
.s
.type
= type
;
1028 cache
.s
.access
= access
;
1029 cache
.s
.options
= options
;
1030 cache
.data
= interlocked_xchg64( &fd_cache
[entry
][idx
].data
, cache
.data
);
1031 assert( !cache
.s
.fd
);
1036 /***********************************************************************
1039 static inline NTSTATUS
get_cached_fd( HANDLE handle
, int *fd
, enum server_fd_type
*type
,
1040 unsigned int *access
, unsigned int *options
)
1042 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
1043 union fd_cache_entry cache
;
1045 if (entry
>= FD_CACHE_ENTRIES
|| !fd_cache
[entry
]) return STATUS_INVALID_HANDLE
;
1047 cache
.data
= InterlockedCompareExchange64( &fd_cache
[entry
][idx
].data
, 0, 0 );
1048 if (!cache
.data
) return STATUS_INVALID_HANDLE
;
1050 /* if fd type is invalid, fd stores an error value */
1051 if (cache
.s
.type
== FD_TYPE_INVALID
) return cache
.s
.fd
- 1;
1053 *fd
= cache
.s
.fd
- 1;
1054 if (type
) *type
= cache
.s
.type
;
1055 if (access
) *access
= cache
.s
.access
;
1056 if (options
) *options
= cache
.s
.options
;
1057 return STATUS_SUCCESS
;
1061 /***********************************************************************
1062 * remove_fd_from_cache
1064 static int remove_fd_from_cache( HANDLE handle
)
1066 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
1069 if (entry
< FD_CACHE_ENTRIES
&& fd_cache
[entry
])
1071 union fd_cache_entry cache
;
1072 cache
.data
= interlocked_xchg64( &fd_cache
[entry
][idx
].data
, 0 );
1073 if (cache
.s
.type
!= FD_TYPE_INVALID
) fd
= cache
.s
.fd
- 1;
1080 /***********************************************************************
1081 * server_get_unix_fd
1083 * The returned unix_fd should be closed iff needs_close is non-zero.
1085 int server_get_unix_fd( HANDLE handle
, unsigned int wanted_access
, int *unix_fd
,
1086 int *needs_close
, enum server_fd_type
*type
, unsigned int *options
)
1089 obj_handle_t fd_handle
;
1091 unsigned int access
= 0;
1095 wanted_access
&= FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_APPEND_DATA
;
1097 ret
= get_cached_fd( handle
, &fd
, type
, &access
, options
);
1098 if (ret
!= STATUS_INVALID_HANDLE
) goto done
;
1100 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1101 ret
= get_cached_fd( handle
, &fd
, type
, &access
, options
);
1102 if (ret
== STATUS_INVALID_HANDLE
)
1104 SERVER_START_REQ( get_handle_fd
)
1106 req
->handle
= wine_server_obj_handle( handle
);
1107 if (!(ret
= wine_server_call( req
)))
1109 if (type
) *type
= reply
->type
;
1110 if (options
) *options
= reply
->options
;
1111 access
= reply
->access
;
1112 if ((fd
= receive_fd( &fd_handle
)) != -1)
1114 assert( wine_server_ptr_handle(fd_handle
) == handle
);
1115 *needs_close
= (!reply
->cacheable
||
1116 !add_fd_to_cache( handle
, fd
, reply
->type
,
1117 reply
->access
, reply
->options
));
1119 else ret
= STATUS_TOO_MANY_OPENED_FILES
;
1121 else if (reply
->cacheable
)
1123 add_fd_to_cache( handle
, ret
, FD_TYPE_INVALID
, 0, 0 );
1128 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1131 if (!ret
&& ((access
& wanted_access
) != wanted_access
))
1133 ret
= STATUS_ACCESS_DENIED
;
1134 if (*needs_close
) close( fd
);
1136 if (!ret
) *unix_fd
= fd
;
1141 /***********************************************************************
1142 * wine_server_fd_to_handle
1144 NTSTATUS CDECL
wine_server_fd_to_handle( int fd
, unsigned int access
, unsigned int attributes
, HANDLE
*handle
)
1149 wine_server_send_fd( fd
);
1151 SERVER_START_REQ( alloc_file_handle
)
1153 req
->access
= access
;
1154 req
->attributes
= attributes
;
1156 if (!(ret
= wine_server_call( req
))) *handle
= wine_server_ptr_handle( reply
->handle
);
1163 /***********************************************************************
1164 * unixcall_wine_server_fd_to_handle
1166 NTSTATUS
unixcall_wine_server_fd_to_handle( void *args
)
1168 struct wine_server_fd_to_handle_params
*params
= args
;
1170 return wine_server_fd_to_handle( params
->fd
, params
->access
, params
->attributes
, params
->handle
);
1174 /***********************************************************************
1175 * wine_server_handle_to_fd
1177 * Retrieve the file descriptor corresponding to a file handle.
1179 NTSTATUS CDECL
wine_server_handle_to_fd( HANDLE handle
, unsigned int access
, int *unix_fd
,
1180 unsigned int *options
)
1183 NTSTATUS ret
= server_get_unix_fd( handle
, access
, unix_fd
, &needs_close
, NULL
, options
);
1185 if (!ret
&& !needs_close
)
1187 if ((*unix_fd
= dup(*unix_fd
)) == -1) ret
= STATUS_TOO_MANY_OPENED_FILES
;
1193 /***********************************************************************
1194 * unixcall_wine_server_handle_to_fd
1196 NTSTATUS
unixcall_wine_server_handle_to_fd( void *args
)
1198 struct wine_server_handle_to_fd_params
*params
= args
;
1200 return wine_server_handle_to_fd( params
->handle
, params
->access
, params
->unix_fd
, params
->options
);
1204 /***********************************************************************
1207 * Create a pipe for communicating with the server.
1209 int server_pipe( int fd
[2] )
1213 static BOOL have_pipe2
= TRUE
;
1217 if (!(ret
= pipe2( fd
, O_CLOEXEC
))) return ret
;
1218 if (errno
== ENOSYS
|| errno
== EINVAL
) have_pipe2
= FALSE
; /* don't try again */
1221 if (!(ret
= pipe( fd
)))
1223 fcntl( fd
[0], F_SETFD
, FD_CLOEXEC
);
1224 fcntl( fd
[1], F_SETFD
, FD_CLOEXEC
);
1230 /***********************************************************************
1233 static const char *init_server_dir( dev_t dev
, ino_t ino
)
1236 size_t len
= sizeof("/server-") + 2 * sizeof(dev
) + 2 * sizeof(ino
) + 2;
1238 #ifdef __ANDROID__ /* there's no /tmp dir on Android */
1239 len
+= strlen( config_dir
) + sizeof("/.wineserver");
1240 dir
= malloc( len
);
1241 strcpy( dir
, config_dir
);
1242 strcat( dir
, "/.wineserver/server-" );
1244 len
+= sizeof("/tmp/.wine-") + 12;
1245 dir
= malloc( len
);
1246 sprintf( dir
, "/tmp/.wine-%u/server-", getuid() );
1248 p
= dir
+ strlen( dir
);
1249 if (dev
!= (unsigned long)dev
)
1250 p
+= sprintf( p
, "%lx%08lx-", (unsigned long)((unsigned long long)dev
>> 32), (unsigned long)dev
);
1252 p
+= sprintf( p
, "%lx-", (unsigned long)dev
);
1254 if (ino
!= (unsigned long)ino
)
1255 sprintf( p
, "%lx%08lx", (unsigned long)((unsigned long long)ino
>> 32), (unsigned long)ino
);
1257 sprintf( p
, "%lx", (unsigned long)ino
);
1262 /***********************************************************************
1265 * Setup the wine configuration dir.
1267 static int setup_config_dir(void)
1271 int fd_cwd
= open( ".", O_RDONLY
);
1273 if (chdir( config_dir
) == -1)
1275 if (errno
!= ENOENT
) fatal_perror( "cannot use directory %s", config_dir
);
1276 if ((p
= strrchr( config_dir
, '/' )) && p
!= config_dir
)
1278 while (p
> config_dir
+ 1 && p
[-1] == '/') p
--;
1280 if (!stat( config_dir
, &st
) && st
.st_uid
!= getuid())
1281 fatal_error( "'%s' is not owned by you, refusing to create a configuration directory there\n",
1285 mkdir( config_dir
, 0777 );
1286 if (chdir( config_dir
) == -1) fatal_perror( "chdir to %s", config_dir
);
1287 MESSAGE( "wine: created the configuration directory '%s'\n", config_dir
);
1290 if (stat( ".", &st
) == -1) fatal_perror( "stat %s", config_dir
);
1291 if (st
.st_uid
!= getuid()) fatal_error( "'%s' is not owned by you\n", config_dir
);
1293 server_dir
= init_server_dir( st
.st_dev
, st
.st_ino
);
1295 if (!mkdir( "dosdevices", 0777 ))
1297 mkdir( "drive_c", 0777 );
1298 symlink( "../drive_c", "dosdevices/c:" );
1299 symlink( "/", "dosdevices/z:" );
1301 else if (errno
!= EEXIST
) fatal_perror( "cannot create %s/dosdevices", config_dir
);
1303 if (fd_cwd
== -1) fd_cwd
= open( "dosdevices/c:", O_RDONLY
);
1304 fcntl( fd_cwd
, F_SETFD
, FD_CLOEXEC
);
1309 /***********************************************************************
1310 * server_connect_error
1312 * Try to display a meaningful explanation of why we couldn't connect
1315 static void server_connect_error( const char *serverdir
)
1320 if ((fd
= open( LOCKNAME
, O_WRONLY
)) == -1)
1321 fatal_error( "for some mysterious reason, the wine server never started.\n" );
1323 fl
.l_type
= F_WRLCK
;
1324 fl
.l_whence
= SEEK_SET
;
1327 if (fcntl( fd
, F_GETLK
, &fl
) != -1)
1329 if (fl
.l_type
== F_WRLCK
) /* the file is locked */
1330 fatal_error( "a wine server seems to be running, but I cannot connect to it.\n"
1331 " You probably need to kill that process (it might be pid %d).\n",
1333 fatal_error( "for some mysterious reason, the wine server failed to run.\n" );
1335 fatal_error( "the file system of '%s' doesn't support locks,\n"
1336 " and there is a 'socket' file in that directory that prevents wine from starting.\n"
1337 " You should make sure no wine server is running, remove that file and try again.\n",
1342 /***********************************************************************
1345 * Attempt to connect to an existing server socket.
1347 static int server_connect(void)
1349 struct sockaddr_un addr
;
1353 initial_cwd
= setup_config_dir();
1355 /* chdir to the server directory */
1356 if (chdir( server_dir
) == -1)
1358 if (errno
!= ENOENT
) fatal_perror( "chdir to %s", server_dir
);
1359 start_server( TRACE_ON(server
) );
1360 if (chdir( server_dir
) == -1) fatal_perror( "chdir to %s", server_dir
);
1363 /* make sure we are at the right place */
1364 if (stat( ".", &st
) == -1) fatal_perror( "stat %s", server_dir
);
1365 if (st
.st_uid
!= getuid()) fatal_error( "'%s' is not owned by you\n", server_dir
);
1366 if (st
.st_mode
& 077) fatal_error( "'%s' must not be accessible by other users\n", server_dir
);
1368 for (retry
= 0; retry
< 6; retry
++)
1370 /* if not the first try, wait a bit to leave the previous server time to exit */
1373 usleep( 100000 * retry
* retry
);
1374 start_server( TRACE_ON(server
) );
1375 if (lstat( SOCKETNAME
, &st
) == -1) continue; /* still no socket, wait a bit more */
1377 else if (lstat( SOCKETNAME
, &st
) == -1) /* check for an already existing socket */
1379 if (errno
!= ENOENT
) fatal_perror( "lstat %s/%s", server_dir
, SOCKETNAME
);
1380 start_server( TRACE_ON(server
) );
1381 if (lstat( SOCKETNAME
, &st
) == -1) continue; /* still no socket, wait a bit more */
1384 /* make sure the socket is sane (ISFIFO needed for Solaris) */
1385 if (!S_ISSOCK(st
.st_mode
) && !S_ISFIFO(st
.st_mode
))
1386 fatal_error( "'%s/%s' is not a socket\n", server_dir
, SOCKETNAME
);
1387 if (st
.st_uid
!= getuid())
1388 fatal_error( "'%s/%s' is not owned by you\n", server_dir
, SOCKETNAME
);
1390 /* try to connect to it */
1391 addr
.sun_family
= AF_UNIX
;
1392 strcpy( addr
.sun_path
, SOCKETNAME
);
1393 slen
= sizeof(addr
) - sizeof(addr
.sun_path
) + strlen(addr
.sun_path
) + 1;
1394 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
1395 addr
.sun_len
= slen
;
1397 if ((s
= socket( AF_UNIX
, SOCK_STREAM
, 0 )) == -1) fatal_perror( "socket" );
1402 setsockopt( s
, SOL_SOCKET
, SO_PASSCRED
, &enable
, sizeof(enable
) );
1405 if (connect( s
, (struct sockaddr
*)&addr
, slen
) != -1)
1407 fchdir( initial_cwd
); /* switch back to the starting directory */
1408 fcntl( s
, F_SETFD
, FD_CLOEXEC
);
1413 server_connect_error( server_dir
);
1418 #include <mach/mach.h>
1419 #include <mach/mach_error.h>
1420 #include <servers/bootstrap.h>
1422 /* send our task port to the server */
1423 static void send_server_task_port(void)
1425 mach_port_t bootstrap_port
, wineserver_port
;
1429 mach_msg_header_t header
;
1430 mach_msg_body_t body
;
1431 mach_msg_port_descriptor_t task_port
;
1434 if (task_get_bootstrap_port(mach_task_self(), &bootstrap_port
) != KERN_SUCCESS
) return;
1439 stat( config_dir
, &st
);
1440 server_dir
= init_server_dir( st
.st_dev
, st
.st_ino
);
1442 kret
= bootstrap_look_up(bootstrap_port
, server_dir
, &wineserver_port
);
1443 if (kret
!= KERN_SUCCESS
)
1444 fatal_error( "cannot find the server port: 0x%08x\n", kret
);
1446 mach_port_deallocate(mach_task_self(), bootstrap_port
);
1448 msg
.header
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, 0) | MACH_MSGH_BITS_COMPLEX
;
1449 msg
.header
.msgh_size
= sizeof(msg
);
1450 msg
.header
.msgh_remote_port
= wineserver_port
;
1451 msg
.header
.msgh_local_port
= MACH_PORT_NULL
;
1453 msg
.body
.msgh_descriptor_count
= 1;
1454 msg
.task_port
.name
= mach_task_self();
1455 msg
.task_port
.disposition
= MACH_MSG_TYPE_COPY_SEND
;
1456 msg
.task_port
.type
= MACH_MSG_PORT_DESCRIPTOR
;
1458 kret
= mach_msg_send(&msg
.header
);
1459 if (kret
!= KERN_SUCCESS
)
1460 server_protocol_error( "mach_msg_send failed: 0x%08x\n", kret
);
1462 mach_port_deallocate(mach_task_self(), wineserver_port
);
1464 #endif /* __APPLE__ */
1467 /***********************************************************************
1470 * Retrieve the Unix tid to use on the server side for the current thread.
1472 static int get_unix_tid(void)
1475 #ifdef HAVE_PTHREAD_GETTHREADID_NP
1476 ret
= pthread_getthreadid_np();
1477 #elif defined(linux)
1478 ret
= syscall( __NR_gettid
);
1479 #elif defined(__sun)
1480 ret
= pthread_self();
1481 #elif defined(__APPLE__)
1482 ret
= mach_thread_self();
1483 mach_port_deallocate(mach_task_self(), ret
);
1484 #elif defined(__NetBSD__)
1486 #elif defined(__FreeBSD__)
1490 #elif defined(__DragonFly__)
1497 /***********************************************************************
1500 * Create the server->client communication pipe.
1502 static int init_thread_pipe(void)
1507 ss
.ss_sp
= get_signal_stack();
1508 ss
.ss_size
= signal_stack_size
;
1510 sigaltstack( &ss
, NULL
);
1512 if (server_pipe( reply_pipe
) == -1) server_protocol_perror( "pipe" );
1513 if (server_pipe( ntdll_get_thread_data()->wait_fd
) == -1) server_protocol_perror( "pipe" );
1514 wine_server_send_fd( reply_pipe
[1] );
1515 wine_server_send_fd( ntdll_get_thread_data()->wait_fd
[1] );
1516 ntdll_get_thread_data()->reply_fd
= reply_pipe
[0];
1517 return reply_pipe
[1];
1521 /***********************************************************************
1522 * process_exit_wrapper
1524 * Close server socket and exit process normally.
1526 void process_exit_wrapper( int status
)
1533 /***********************************************************************
1534 * server_init_process
1536 * Start the server and create the initial socket pair.
1538 size_t server_init_process(void)
1540 const char *arch
= getenv( "WINEARCH" );
1541 const char *env_socket
= getenv( "WINESERVERSOCKET" );
1542 obj_handle_t version
;
1544 int ret
, reply_pipe
;
1545 struct sigaction sig_act
;
1552 fd_socket
= atoi( env_socket
);
1553 if (fcntl( fd_socket
, F_SETFD
, FD_CLOEXEC
) == -1)
1554 fatal_perror( "Bad server socket %d", fd_socket
);
1555 unsetenv( "WINESERVERSOCKET" );
1559 const char *arch
= getenv( "WINEARCH" );
1561 if (arch
&& strcmp( arch
, "win32" ) && strcmp( arch
, "win64" ))
1562 fatal_error( "WINEARCH set to invalid value '%s', it must be either win32 or win64.\n", arch
);
1564 fd_socket
= server_connect();
1567 /* setup the signal mask */
1568 sigemptyset( &server_block_set
);
1569 sigaddset( &server_block_set
, SIGALRM
);
1570 sigaddset( &server_block_set
, SIGIO
);
1571 sigaddset( &server_block_set
, SIGINT
);
1572 sigaddset( &server_block_set
, SIGHUP
);
1573 sigaddset( &server_block_set
, SIGUSR1
);
1574 sigaddset( &server_block_set
, SIGUSR2
);
1575 sigaddset( &server_block_set
, SIGCHLD
);
1576 pthread_sigmask( SIG_BLOCK
, &server_block_set
, NULL
);
1578 /* receive the first thread request fd on the main socket */
1579 ntdll_get_thread_data()->request_fd
= receive_fd( &version
);
1582 /* now that we hopefully received the server_pid, disable SO_PASSCRED */
1585 setsockopt( fd_socket
, SOL_SOCKET
, SO_PASSCRED
, &enable
, sizeof(enable
) );
1589 if (version
!= SERVER_PROTOCOL_VERSION
)
1590 server_protocol_error( "version mismatch %d/%d.\n"
1591 "Your %s binary was not upgraded correctly,\n"
1592 "or you have an older one somewhere in your PATH.\n"
1593 "Or maybe the wrong wineserver is still running?\n",
1594 version
, SERVER_PROTOCOL_VERSION
,
1595 (version
> SERVER_PROTOCOL_VERSION
) ? "wine" : "wineserver" );
1596 #if defined(__linux__) && defined(HAVE_PRCTL)
1597 /* work around Ubuntu's ptrace breakage */
1598 if (server_pid
!= -1) prctl( 0x59616d61 /* PR_SET_PTRACER */, server_pid
);
1601 /* ignore SIGPIPE so that we get an EPIPE error instead */
1602 sig_act
.sa_handler
= SIG_IGN
;
1603 sig_act
.sa_flags
= 0;
1604 sigemptyset( &sig_act
.sa_mask
);
1605 sigaction( SIGPIPE
, &sig_act
, NULL
);
1607 reply_pipe
= init_thread_pipe();
1609 SERVER_START_REQ( init_first_thread
)
1611 req
->unix_pid
= getpid();
1612 req
->unix_tid
= get_unix_tid();
1613 req
->reply_fd
= reply_pipe
;
1614 req
->wait_fd
= ntdll_get_thread_data()->wait_fd
[1];
1615 req
->debug_level
= (TRACE_ON(server
) != 0);
1616 wine_server_set_reply( req
, supported_machines
, sizeof(supported_machines
) );
1617 ret
= wine_server_call( req
);
1620 peb
->SessionId
= reply
->session_id
;
1621 info_size
= reply
->info_size
;
1622 server_start_time
= reply
->server_start
;
1623 supported_machines_count
= wine_server_reply_size( reply
) / sizeof(*supported_machines
);
1626 close( reply_pipe
);
1628 if (ret
) server_protocol_error( "init_first_thread failed with status %x\n", ret
);
1630 if (!supported_machines_count
)
1631 fatal_error( "'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.\n",
1634 native_machine
= supported_machines
[0];
1635 if (is_machine_64bit( native_machine
))
1637 if (arch
&& !strcmp( arch
, "win32" ))
1638 fatal_error( "WINEARCH set to win32 but '%s' is a 64-bit installation.\n", config_dir
);
1640 NtCurrentTeb()->GdiBatchCount
= PtrToUlong( (char *)NtCurrentTeb() - teb_offset
);
1641 NtCurrentTeb()->WowTebOffset
= -teb_offset
;
1642 wow_peb
= (PEB64
*)((char *)peb
- page_size
);
1648 fatal_error( "'%s' is a 32-bit installation, it cannot support 64-bit applications.\n", config_dir
);
1649 if (arch
&& !strcmp( arch
, "win64" ))
1650 fatal_error( "WINEARCH set to win64 but '%s' is a 32-bit installation.\n", config_dir
);
1653 set_thread_id( NtCurrentTeb(), pid
, tid
);
1655 for (i
= 0; i
< supported_machines_count
; i
++)
1656 if (supported_machines
[i
] == current_machine
) return info_size
;
1658 fatal_error( "wineserver doesn't support the %04x architecture\n", current_machine
);
1662 /***********************************************************************
1663 * server_init_process_done
1665 void server_init_process_done(void)
1668 unsigned int status
;
1670 FILE_FS_DEVICE_INFORMATION info
;
1672 if (!get_device_info( initial_cwd
, &info
) && (info
.Characteristics
& FILE_REMOVABLE_MEDIA
))
1674 close( initial_cwd
);
1677 send_server_task_port();
1679 if (main_image_info
.ImageCharacteristics
& IMAGE_FILE_LARGE_ADDRESS_AWARE
)
1680 virtual_set_large_address_space();
1682 /* Install signal handlers; this cannot be done earlier, since we cannot
1683 * send exceptions to the debugger before the create process event that
1684 * is sent by init_process_done */
1685 signal_init_process();
1687 /* always send the native TEB */
1688 if (!(teb
= NtCurrentTeb64())) teb
= NtCurrentTeb();
1690 /* Signal the parent process to continue */
1691 SERVER_START_REQ( init_process_done
)
1693 req
->teb
= wine_server_client_ptr( teb
);
1694 req
->peb
= NtCurrentTeb64() ? NtCurrentTeb64()->Peb
: wine_server_client_ptr( peb
);
1696 req
->ldt_copy
= wine_server_client_ptr( &__wine_ldt_copy
);
1698 status
= wine_server_call( req
);
1699 suspend
= reply
->suspend
;
1700 entry
= wine_server_get_ptr( reply
->entry
);
1705 signal_start_thread( entry
, peb
, suspend
, NtCurrentTeb() );
1709 /***********************************************************************
1710 * server_init_thread
1712 * Send an init thread request.
1714 void server_init_thread( void *entry_point
, BOOL
*suspend
)
1717 int reply_pipe
= init_thread_pipe();
1719 /* always send the native TEB */
1720 if (!(teb
= NtCurrentTeb64())) teb
= NtCurrentTeb();
1722 SERVER_START_REQ( init_thread
)
1724 req
->unix_tid
= get_unix_tid();
1725 req
->teb
= wine_server_client_ptr( teb
);
1726 req
->entry
= wine_server_client_ptr( entry_point
);
1727 req
->reply_fd
= reply_pipe
;
1728 req
->wait_fd
= ntdll_get_thread_data()->wait_fd
[1];
1729 wine_server_call( req
);
1730 *suspend
= reply
->suspend
;
1733 close( reply_pipe
);
1737 /******************************************************************************
1740 NTSTATUS WINAPI
NtDuplicateObject( HANDLE source_process
, HANDLE source
, HANDLE dest_process
, HANDLE
*dest
,
1741 ACCESS_MASK access
, ULONG attributes
, ULONG options
)
1747 if (dest
) *dest
= 0;
1749 if ((options
& DUPLICATE_CLOSE_SOURCE
) && source_process
!= NtCurrentProcess())
1752 apc_result_t result
;
1754 memset( &call
, 0, sizeof(call
) );
1756 call
.dup_handle
.type
= APC_DUP_HANDLE
;
1757 call
.dup_handle
.src_handle
= wine_server_obj_handle( source
);
1758 call
.dup_handle
.dst_process
= wine_server_obj_handle( dest_process
);
1759 call
.dup_handle
.access
= access
;
1760 call
.dup_handle
.attributes
= attributes
;
1761 call
.dup_handle
.options
= options
;
1762 ret
= server_queue_process_apc( source_process
, &call
, &result
);
1763 if (ret
!= STATUS_SUCCESS
) return ret
;
1765 if (!result
.dup_handle
.status
)
1766 *dest
= wine_server_ptr_handle( result
.dup_handle
.handle
);
1767 return result
.dup_handle
.status
;
1770 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1772 /* always remove the cached fd; if the server request fails we'll just
1773 * retrieve it again */
1774 if (options
& DUPLICATE_CLOSE_SOURCE
)
1775 fd
= remove_fd_from_cache( source
);
1777 SERVER_START_REQ( dup_handle
)
1779 req
->src_process
= wine_server_obj_handle( source_process
);
1780 req
->src_handle
= wine_server_obj_handle( source
);
1781 req
->dst_process
= wine_server_obj_handle( dest_process
);
1782 req
->access
= access
;
1783 req
->attributes
= attributes
;
1784 req
->options
= options
;
1785 if (!(ret
= wine_server_call( req
)))
1787 if (dest
) *dest
= wine_server_ptr_handle( reply
->handle
);
1792 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1794 if (fd
!= -1) close( fd
);
1799 /**************************************************************************
1800 * NtCompareObjects (NTDLL.@)
1802 NTSTATUS WINAPI
NtCompareObjects( HANDLE first
, HANDLE second
)
1804 unsigned int status
;
1806 SERVER_START_REQ( compare_objects
)
1808 req
->first
= wine_server_obj_handle( first
);
1809 req
->second
= wine_server_obj_handle( second
);
1810 status
= wine_server_call( req
);
1818 /**************************************************************************
1821 NTSTATUS WINAPI
NtClose( HANDLE handle
)
1828 if (HandleToLong( handle
) >= ~5 && HandleToLong( handle
) <= ~0)
1829 return STATUS_SUCCESS
;
1831 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1833 /* always remove the cached fd; if the server request fails we'll just
1834 * retrieve it again */
1835 fd
= remove_fd_from_cache( handle
);
1837 SERVER_START_REQ( close_handle
)
1839 req
->handle
= wine_server_obj_handle( handle
);
1840 ret
= wine_server_call( req
);
1844 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1846 if (fd
!= -1) close( fd
);
1848 if (ret
!= STATUS_INVALID_HANDLE
|| !handle
) return ret
;
1849 if (!peb
->BeingDebugged
) return ret
;
1850 if (!NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort
, &port
, sizeof(port
), NULL
) && port
)
1852 NtCurrentTeb()->ExceptionCode
= ret
;
1853 call_raise_user_exception_dispatcher();
1860 struct __server_request_info32
1864 union generic_request req
;
1865 union generic_reply reply
;
1867 unsigned int data_count
;
1869 struct { ULONG ptr
; data_size_t size
; } data
[__SERVER_MAX_DATA
];
1872 /**********************************************************************
1873 * wow64_wine_server_call
1875 NTSTATUS
wow64_wine_server_call( void *args
)
1877 struct __server_request_info32
*req32
= args
;
1880 struct __server_request_info req
;
1882 req
.u
.req
= req32
->u
.req
;
1883 req
.data_count
= req32
->data_count
;
1884 for (i
= 0; i
< req
.data_count
; i
++)
1886 req
.data
[i
].ptr
= ULongToPtr( req32
->data
[i
].ptr
);
1887 req
.data
[i
].size
= req32
->data
[i
].size
;
1889 req
.reply_data
= ULongToPtr( req32
->reply_data
);
1890 status
= wine_server_call( &req
);
1891 req32
->u
.reply
= req
.u
.reply
;
1895 /***********************************************************************
1896 * wow64_wine_server_fd_to_handle
1898 NTSTATUS
wow64_wine_server_fd_to_handle( void *args
)
1903 unsigned int access
;
1904 unsigned int attributes
;
1906 } const *params32
= args
;
1908 ULONG
*handle32
= ULongToPtr( params32
->handle
);
1912 ret
= wine_server_fd_to_handle( params32
->fd
, params32
->access
, params32
->attributes
, &handle
);
1913 *handle32
= HandleToULong( handle
);
1917 /**********************************************************************
1918 * wow64_wine_server_handle_to_fd
1920 NTSTATUS
wow64_wine_server_handle_to_fd( void *args
)
1925 unsigned int access
;
1928 } const *params32
= args
;
1930 return wine_server_handle_to_fd( ULongToHandle( params32
->handle
), params32
->access
,
1931 ULongToPtr( params32
->unix_fd
), ULongToPtr( params32
->options
));