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
) );
570 result
->type
= call
->type
;
571 addr
= wine_server_get_ptr( call
->unmap_view
.addr
);
572 if ((ULONG_PTR
)addr
== call
->unmap_view
.addr
)
573 result
->unmap_view
.status
= NtUnmapViewOfSection( NtCurrentProcess(), addr
);
575 result
->unmap_view
.status
= STATUS_INVALID_PARAMETER
;
577 case APC_CREATE_THREAD
:
579 ULONG_PTR buffer
[offsetof( PS_ATTRIBUTE_LIST
, Attributes
[2] ) / sizeof(ULONG_PTR
)];
580 PS_ATTRIBUTE_LIST
*attr
= (PS_ATTRIBUTE_LIST
*)buffer
;
584 ULONG_PTR zero_bits
= call
->create_thread
.zero_bits
;
585 SIZE_T reserve
= call
->create_thread
.reserve
;
586 SIZE_T commit
= call
->create_thread
.commit
;
587 void *func
= wine_server_get_ptr( call
->create_thread
.func
);
588 void *arg
= wine_server_get_ptr( call
->create_thread
.arg
);
590 result
->type
= call
->type
;
591 if (reserve
== call
->create_thread
.reserve
&& commit
== call
->create_thread
.commit
&&
592 (ULONG_PTR
)func
== call
->create_thread
.func
&& (ULONG_PTR
)arg
== call
->create_thread
.arg
)
594 /* FIXME: hack for debugging 32-bit process without a 64-bit ntdll */
595 if (is_old_wow64() && func
== (void *)0x7ffe1000) func
= pDbgUiRemoteBreakin
;
596 attr
->TotalLength
= sizeof(buffer
);
597 attr
->Attributes
[0].Attribute
= PS_ATTRIBUTE_CLIENT_ID
;
598 attr
->Attributes
[0].Size
= sizeof(id
);
599 attr
->Attributes
[0].ValuePtr
= &id
;
600 attr
->Attributes
[0].ReturnLength
= NULL
;
601 attr
->Attributes
[1].Attribute
= PS_ATTRIBUTE_TEB_ADDRESS
;
602 attr
->Attributes
[1].Size
= sizeof(teb
);
603 attr
->Attributes
[1].ValuePtr
= &teb
;
604 attr
->Attributes
[1].ReturnLength
= NULL
;
605 result
->create_thread
.status
= NtCreateThreadEx( &handle
, THREAD_ALL_ACCESS
, NULL
,
606 NtCurrentProcess(), func
, arg
,
607 call
->create_thread
.flags
, zero_bits
,
608 commit
, reserve
, attr
);
609 result
->create_thread
.handle
= wine_server_obj_handle( handle
);
610 result
->create_thread
.pid
= HandleToULong(id
.UniqueProcess
);
611 result
->create_thread
.tid
= HandleToULong(id
.UniqueThread
);
612 result
->create_thread
.teb
= wine_server_client_ptr( teb
);
614 else result
->create_thread
.status
= STATUS_INVALID_PARAMETER
;
619 HANDLE dst_handle
= NULL
;
621 result
->type
= call
->type
;
623 result
->dup_handle
.status
= NtDuplicateObject( NtCurrentProcess(),
624 wine_server_ptr_handle(call
->dup_handle
.src_handle
),
625 wine_server_ptr_handle(call
->dup_handle
.dst_process
),
626 &dst_handle
, call
->dup_handle
.access
,
627 call
->dup_handle
.attributes
, call
->dup_handle
.options
);
628 result
->dup_handle
.handle
= wine_server_obj_handle( dst_handle
);
629 if (!self
) NtClose( wine_server_ptr_handle(call
->dup_handle
.dst_process
) );
633 server_protocol_error( "get_apc_request: bad type %d\n", call
->type
);
639 /***********************************************************************
642 unsigned int server_select( const select_op_t
*select_op
, data_size_t size
, UINT flags
,
643 timeout_t abs_timeout
, context_t
*context
, user_apc_t
*user_apc
)
647 obj_handle_t apc_handle
= 0;
648 BOOL suspend_context
= !!context
;
654 memset( &result
, 0, sizeof(result
) );
658 pthread_sigmask( SIG_BLOCK
, &server_block_set
, &old_set
);
661 SERVER_START_REQ( select
)
664 req
->cookie
= wine_server_client_ptr( &cookie
);
665 req
->prev_apc
= apc_handle
;
666 req
->timeout
= abs_timeout
;
668 wine_server_add_data( req
, &result
, sizeof(result
) );
669 wine_server_add_data( req
, select_op
, size
);
672 data_size_t ctx_size
= (context
[1].machine
? 2 : 1) * sizeof(*context
);
673 wine_server_add_data( req
, context
, ctx_size
);
674 suspend_context
= FALSE
; /* server owns the context now */
676 if (context
) wine_server_set_reply( req
, context
, 2 * sizeof(*context
) );
677 ret
= server_call_unlocked( req
);
678 signaled
= reply
->signaled
;
679 apc_handle
= reply
->apc_handle
;
684 if (ret
!= STATUS_KERNEL_APC
) break;
685 invoke_system_apc( &call
, &result
, FALSE
);
687 /* don't signal multiple times */
688 if (size
>= sizeof(select_op
->signal_and_wait
) && select_op
->op
== SELECT_SIGNAL_AND_WAIT
)
689 size
= offsetof( select_op_t
, signal_and_wait
.signal
);
691 pthread_sigmask( SIG_SETMASK
, &old_set
, NULL
);
694 ret
= wait_select_reply( &cookie
);
696 while (ret
== STATUS_USER_APC
|| ret
== STATUS_KERNEL_APC
);
698 if (ret
== STATUS_USER_APC
) *user_apc
= call
.user
;
703 /***********************************************************************
706 unsigned int server_wait( const select_op_t
*select_op
, data_size_t size
, UINT flags
,
707 const LARGE_INTEGER
*timeout
)
709 timeout_t abs_timeout
= timeout
? timeout
->QuadPart
: TIMEOUT_INFINITE
;
717 NtQueryPerformanceCounter( &now
, NULL
);
718 abs_timeout
-= now
.QuadPart
;
721 ret
= server_select( select_op
, size
, flags
, abs_timeout
, NULL
, &apc
);
722 if (ret
== STATUS_USER_APC
) return invoke_user_apc( NULL
, &apc
, ret
);
724 /* A test on Windows 2000 shows that Windows always yields during
725 a wait, but a wait that is hit by an event gets a priority
726 boost as well. This seems to model that behavior the closest. */
727 if (ret
== STATUS_TIMEOUT
) NtYieldExecution();
732 /***********************************************************************
733 * NtContinue (NTDLL.@)
735 NTSTATUS WINAPI
NtContinue( CONTEXT
*context
, BOOLEAN alertable
)
742 status
= server_select( NULL
, 0, SELECT_INTERRUPTIBLE
| SELECT_ALERTABLE
, 0, NULL
, &apc
);
743 if (status
== STATUS_USER_APC
) return invoke_user_apc( context
, &apc
, status
);
745 return signal_set_full_context( context
);
749 /***********************************************************************
750 * NtTestAlert (NTDLL.@)
752 NTSTATUS WINAPI
NtTestAlert(void)
757 status
= server_select( NULL
, 0, SELECT_INTERRUPTIBLE
| SELECT_ALERTABLE
, 0, NULL
, &apc
);
758 if (status
== STATUS_USER_APC
) invoke_user_apc( NULL
, &apc
, STATUS_SUCCESS
);
759 return STATUS_SUCCESS
;
763 /***********************************************************************
764 * server_queue_process_apc
766 unsigned int server_queue_process_apc( HANDLE process
, const apc_call_t
*call
, apc_result_t
*result
)
774 SERVER_START_REQ( queue_apc
)
776 req
->handle
= wine_server_obj_handle( process
);
778 if (!(ret
= wine_server_call( req
)))
780 handle
= wine_server_ptr_handle( reply
->handle
);
785 if (ret
!= STATUS_SUCCESS
) return ret
;
789 invoke_system_apc( call
, result
, TRUE
);
793 NtWaitForSingleObject( handle
, FALSE
, NULL
);
795 SERVER_START_REQ( get_apc_result
)
797 req
->handle
= wine_server_obj_handle( handle
);
798 if (!(ret
= wine_server_call( req
))) *result
= reply
->result
;
802 if (!ret
&& result
->type
== APC_NONE
) continue; /* APC didn't run, try again */
809 /***********************************************************************
810 * wine_server_send_fd
812 * Send a file descriptor to the server.
814 void wine_server_send_fd( int fd
)
817 struct msghdr msghdr
;
821 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
822 msghdr
.msg_accrights
= (void *)&fd
;
823 msghdr
.msg_accrightslen
= sizeof(fd
);
824 #else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
825 char cmsg_buffer
[256];
826 struct cmsghdr
*cmsg
;
827 msghdr
.msg_control
= cmsg_buffer
;
828 msghdr
.msg_controllen
= sizeof(cmsg_buffer
);
829 msghdr
.msg_flags
= 0;
830 cmsg
= CMSG_FIRSTHDR( &msghdr
);
831 cmsg
->cmsg_len
= CMSG_LEN( sizeof(fd
) );
832 cmsg
->cmsg_level
= SOL_SOCKET
;
833 cmsg
->cmsg_type
= SCM_RIGHTS
;
834 *(int *)CMSG_DATA(cmsg
) = fd
;
835 msghdr
.msg_controllen
= cmsg
->cmsg_len
;
836 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
838 msghdr
.msg_name
= NULL
;
839 msghdr
.msg_namelen
= 0;
840 msghdr
.msg_iov
= &vec
;
841 msghdr
.msg_iovlen
= 1;
843 vec
.iov_base
= (void *)&data
;
844 vec
.iov_len
= sizeof(data
);
846 data
.tid
= GetCurrentThreadId();
851 if ((ret
= sendmsg( fd_socket
, &msghdr
, 0 )) == sizeof(data
)) return;
852 if (ret
>= 0) server_protocol_error( "partial write %d\n", ret
);
853 if (errno
== EINTR
) continue;
854 if (errno
== EPIPE
) abort_thread(0);
855 server_protocol_perror( "sendmsg" );
860 /***********************************************************************
863 * Receive a file descriptor passed from the server.
865 static int receive_fd( obj_handle_t
*handle
)
868 struct msghdr msghdr
;
871 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
872 msghdr
.msg_accrights
= (void *)&fd
;
873 msghdr
.msg_accrightslen
= sizeof(fd
);
874 #else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
875 char cmsg_buffer
[256];
876 msghdr
.msg_control
= cmsg_buffer
;
877 msghdr
.msg_controllen
= sizeof(cmsg_buffer
);
878 msghdr
.msg_flags
= 0;
879 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
881 msghdr
.msg_name
= NULL
;
882 msghdr
.msg_namelen
= 0;
883 msghdr
.msg_iov
= &vec
;
884 msghdr
.msg_iovlen
= 1;
885 vec
.iov_base
= (void *)handle
;
886 vec
.iov_len
= sizeof(*handle
);
890 if ((ret
= recvmsg( fd_socket
, &msghdr
, MSG_CMSG_CLOEXEC
)) > 0)
892 #ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
893 struct cmsghdr
*cmsg
;
894 for (cmsg
= CMSG_FIRSTHDR( &msghdr
); cmsg
; cmsg
= CMSG_NXTHDR( &msghdr
, cmsg
))
896 if (cmsg
->cmsg_level
!= SOL_SOCKET
) continue;
897 if (cmsg
->cmsg_type
== SCM_RIGHTS
) fd
= *(int *)CMSG_DATA(cmsg
);
898 #ifdef SCM_CREDENTIALS
899 else if (cmsg
->cmsg_type
== SCM_CREDENTIALS
)
901 struct ucred
*ucred
= (struct ucred
*)CMSG_DATA(cmsg
);
902 server_pid
= ucred
->pid
;
906 #endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
907 if (fd
!= -1) fcntl( fd
, F_SETFD
, FD_CLOEXEC
); /* in case MSG_CMSG_CLOEXEC is not supported */
911 if (errno
== EINTR
) continue;
912 if (errno
== EPIPE
) break;
913 server_protocol_perror("recvmsg");
915 /* the server closed the connection; time to die... */
920 /***********************************************************************/
921 /* fd cache support */
929 enum server_fd_type type
: 5;
930 unsigned int access
: 3;
931 unsigned int options
: 24;
935 C_ASSERT( sizeof(union fd_cache_entry
) == sizeof(LONG64
) );
937 #define FD_CACHE_BLOCK_SIZE (65536 / sizeof(union fd_cache_entry))
938 #define FD_CACHE_ENTRIES 128
940 static union fd_cache_entry
*fd_cache
[FD_CACHE_ENTRIES
];
941 static union fd_cache_entry fd_cache_initial_block
[FD_CACHE_BLOCK_SIZE
];
943 static inline unsigned int handle_to_index( HANDLE handle
, unsigned int *entry
)
945 unsigned int idx
= (wine_server_obj_handle(handle
) >> 2) - 1;
946 *entry
= idx
/ FD_CACHE_BLOCK_SIZE
;
947 return idx
% FD_CACHE_BLOCK_SIZE
;
951 /***********************************************************************
954 * Caller must hold fd_cache_mutex.
956 static BOOL
add_fd_to_cache( HANDLE handle
, int fd
, enum server_fd_type type
,
957 unsigned int access
, unsigned int options
)
959 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
960 union fd_cache_entry cache
;
962 if (entry
>= FD_CACHE_ENTRIES
)
964 FIXME( "too many allocated handles, not caching %p\n", handle
);
968 if (!fd_cache
[entry
]) /* do we need to allocate a new block of entries? */
970 if (!entry
) fd_cache
[0] = fd_cache_initial_block
;
973 void *ptr
= anon_mmap_alloc( FD_CACHE_BLOCK_SIZE
* sizeof(union fd_cache_entry
),
974 PROT_READ
| PROT_WRITE
);
975 if (ptr
== MAP_FAILED
) return FALSE
;
976 fd_cache
[entry
] = ptr
;
980 /* store fd+1 so that 0 can be used as the unset value */
983 cache
.s
.access
= access
;
984 cache
.s
.options
= options
;
985 cache
.data
= interlocked_xchg64( &fd_cache
[entry
][idx
].data
, cache
.data
);
986 assert( !cache
.s
.fd
);
991 /***********************************************************************
994 static inline NTSTATUS
get_cached_fd( HANDLE handle
, int *fd
, enum server_fd_type
*type
,
995 unsigned int *access
, unsigned int *options
)
997 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
998 union fd_cache_entry cache
;
1000 if (entry
>= FD_CACHE_ENTRIES
|| !fd_cache
[entry
]) return STATUS_INVALID_HANDLE
;
1002 cache
.data
= InterlockedCompareExchange64( &fd_cache
[entry
][idx
].data
, 0, 0 );
1003 if (!cache
.data
) return STATUS_INVALID_HANDLE
;
1005 /* if fd type is invalid, fd stores an error value */
1006 if (cache
.s
.type
== FD_TYPE_INVALID
) return cache
.s
.fd
- 1;
1008 *fd
= cache
.s
.fd
- 1;
1009 if (type
) *type
= cache
.s
.type
;
1010 if (access
) *access
= cache
.s
.access
;
1011 if (options
) *options
= cache
.s
.options
;
1012 return STATUS_SUCCESS
;
1016 /***********************************************************************
1017 * remove_fd_from_cache
1019 static int remove_fd_from_cache( HANDLE handle
)
1021 unsigned int entry
, idx
= handle_to_index( handle
, &entry
);
1024 if (entry
< FD_CACHE_ENTRIES
&& fd_cache
[entry
])
1026 union fd_cache_entry cache
;
1027 cache
.data
= interlocked_xchg64( &fd_cache
[entry
][idx
].data
, 0 );
1028 if (cache
.s
.type
!= FD_TYPE_INVALID
) fd
= cache
.s
.fd
- 1;
1035 /***********************************************************************
1036 * server_get_unix_fd
1038 * The returned unix_fd should be closed iff needs_close is non-zero.
1040 int server_get_unix_fd( HANDLE handle
, unsigned int wanted_access
, int *unix_fd
,
1041 int *needs_close
, enum server_fd_type
*type
, unsigned int *options
)
1044 obj_handle_t fd_handle
;
1046 unsigned int access
= 0;
1050 wanted_access
&= FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_APPEND_DATA
;
1052 ret
= get_cached_fd( handle
, &fd
, type
, &access
, options
);
1053 if (ret
!= STATUS_INVALID_HANDLE
) goto done
;
1055 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1056 ret
= get_cached_fd( handle
, &fd
, type
, &access
, options
);
1057 if (ret
== STATUS_INVALID_HANDLE
)
1059 SERVER_START_REQ( get_handle_fd
)
1061 req
->handle
= wine_server_obj_handle( handle
);
1062 if (!(ret
= wine_server_call( req
)))
1064 if (type
) *type
= reply
->type
;
1065 if (options
) *options
= reply
->options
;
1066 access
= reply
->access
;
1067 if ((fd
= receive_fd( &fd_handle
)) != -1)
1069 assert( wine_server_ptr_handle(fd_handle
) == handle
);
1070 *needs_close
= (!reply
->cacheable
||
1071 !add_fd_to_cache( handle
, fd
, reply
->type
,
1072 reply
->access
, reply
->options
));
1074 else ret
= STATUS_TOO_MANY_OPENED_FILES
;
1076 else if (reply
->cacheable
)
1078 add_fd_to_cache( handle
, ret
, FD_TYPE_INVALID
, 0, 0 );
1083 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1086 if (!ret
&& ((access
& wanted_access
) != wanted_access
))
1088 ret
= STATUS_ACCESS_DENIED
;
1089 if (*needs_close
) close( fd
);
1091 if (!ret
) *unix_fd
= fd
;
1096 /***********************************************************************
1097 * wine_server_fd_to_handle
1099 NTSTATUS CDECL
wine_server_fd_to_handle( int fd
, unsigned int access
, unsigned int attributes
, HANDLE
*handle
)
1104 wine_server_send_fd( fd
);
1106 SERVER_START_REQ( alloc_file_handle
)
1108 req
->access
= access
;
1109 req
->attributes
= attributes
;
1111 if (!(ret
= wine_server_call( req
))) *handle
= wine_server_ptr_handle( reply
->handle
);
1118 /***********************************************************************
1119 * unixcall_wine_server_fd_to_handle
1121 NTSTATUS
unixcall_wine_server_fd_to_handle( void *args
)
1123 struct wine_server_fd_to_handle_params
*params
= args
;
1125 return wine_server_fd_to_handle( params
->fd
, params
->access
, params
->attributes
, params
->handle
);
1129 /***********************************************************************
1130 * wine_server_handle_to_fd
1132 * Retrieve the file descriptor corresponding to a file handle.
1134 NTSTATUS CDECL
wine_server_handle_to_fd( HANDLE handle
, unsigned int access
, int *unix_fd
,
1135 unsigned int *options
)
1138 NTSTATUS ret
= server_get_unix_fd( handle
, access
, unix_fd
, &needs_close
, NULL
, options
);
1140 if (!ret
&& !needs_close
)
1142 if ((*unix_fd
= dup(*unix_fd
)) == -1) ret
= STATUS_TOO_MANY_OPENED_FILES
;
1148 /***********************************************************************
1149 * unixcall_wine_server_handle_to_fd
1151 NTSTATUS
unixcall_wine_server_handle_to_fd( void *args
)
1153 struct wine_server_handle_to_fd_params
*params
= args
;
1155 return wine_server_handle_to_fd( params
->handle
, params
->access
, params
->unix_fd
, params
->options
);
1159 /***********************************************************************
1162 * Create a pipe for communicating with the server.
1164 int server_pipe( int fd
[2] )
1168 static BOOL have_pipe2
= TRUE
;
1172 if (!(ret
= pipe2( fd
, O_CLOEXEC
))) return ret
;
1173 if (errno
== ENOSYS
|| errno
== EINVAL
) have_pipe2
= FALSE
; /* don't try again */
1176 if (!(ret
= pipe( fd
)))
1178 fcntl( fd
[0], F_SETFD
, FD_CLOEXEC
);
1179 fcntl( fd
[1], F_SETFD
, FD_CLOEXEC
);
1185 /***********************************************************************
1188 static const char *init_server_dir( dev_t dev
, ino_t ino
)
1191 size_t len
= sizeof("/server-") + 2 * sizeof(dev
) + 2 * sizeof(ino
) + 2;
1193 #ifdef __ANDROID__ /* there's no /tmp dir on Android */
1194 len
+= strlen( config_dir
) + sizeof("/.wineserver");
1195 dir
= malloc( len
);
1196 strcpy( dir
, config_dir
);
1197 strcat( dir
, "/.wineserver/server-" );
1199 len
+= sizeof("/tmp/.wine-") + 12;
1200 dir
= malloc( len
);
1201 sprintf( dir
, "/tmp/.wine-%u/server-", getuid() );
1203 p
= dir
+ strlen( dir
);
1204 if (dev
!= (unsigned long)dev
)
1205 p
+= sprintf( p
, "%lx%08lx-", (unsigned long)((unsigned long long)dev
>> 32), (unsigned long)dev
);
1207 p
+= sprintf( p
, "%lx-", (unsigned long)dev
);
1209 if (ino
!= (unsigned long)ino
)
1210 sprintf( p
, "%lx%08lx", (unsigned long)((unsigned long long)ino
>> 32), (unsigned long)ino
);
1212 sprintf( p
, "%lx", (unsigned long)ino
);
1217 /***********************************************************************
1220 * Setup the wine configuration dir.
1222 static int setup_config_dir(void)
1226 int fd_cwd
= open( ".", O_RDONLY
);
1228 if (chdir( config_dir
) == -1)
1230 if (errno
!= ENOENT
) fatal_perror( "cannot use directory %s", config_dir
);
1231 if ((p
= strrchr( config_dir
, '/' )) && p
!= config_dir
)
1233 while (p
> config_dir
+ 1 && p
[-1] == '/') p
--;
1235 if (!stat( config_dir
, &st
) && st
.st_uid
!= getuid())
1236 fatal_error( "'%s' is not owned by you, refusing to create a configuration directory there\n",
1240 mkdir( config_dir
, 0777 );
1241 if (chdir( config_dir
) == -1) fatal_perror( "chdir to %s", config_dir
);
1242 MESSAGE( "wine: created the configuration directory '%s'\n", config_dir
);
1245 if (stat( ".", &st
) == -1) fatal_perror( "stat %s", config_dir
);
1246 if (st
.st_uid
!= getuid()) fatal_error( "'%s' is not owned by you\n", config_dir
);
1248 server_dir
= init_server_dir( st
.st_dev
, st
.st_ino
);
1250 if (!mkdir( "dosdevices", 0777 ))
1252 mkdir( "drive_c", 0777 );
1253 symlink( "../drive_c", "dosdevices/c:" );
1254 symlink( "/", "dosdevices/z:" );
1256 else if (errno
!= EEXIST
) fatal_perror( "cannot create %s/dosdevices", config_dir
);
1258 if (fd_cwd
== -1) fd_cwd
= open( "dosdevices/c:", O_RDONLY
);
1259 fcntl( fd_cwd
, F_SETFD
, FD_CLOEXEC
);
1264 /***********************************************************************
1265 * server_connect_error
1267 * Try to display a meaningful explanation of why we couldn't connect
1270 static void server_connect_error( const char *serverdir
)
1275 if ((fd
= open( LOCKNAME
, O_WRONLY
)) == -1)
1276 fatal_error( "for some mysterious reason, the wine server never started.\n" );
1278 fl
.l_type
= F_WRLCK
;
1279 fl
.l_whence
= SEEK_SET
;
1282 if (fcntl( fd
, F_GETLK
, &fl
) != -1)
1284 if (fl
.l_type
== F_WRLCK
) /* the file is locked */
1285 fatal_error( "a wine server seems to be running, but I cannot connect to it.\n"
1286 " You probably need to kill that process (it might be pid %d).\n",
1288 fatal_error( "for some mysterious reason, the wine server failed to run.\n" );
1290 fatal_error( "the file system of '%s' doesn't support locks,\n"
1291 " and there is a 'socket' file in that directory that prevents wine from starting.\n"
1292 " You should make sure no wine server is running, remove that file and try again.\n",
1297 /***********************************************************************
1300 * Attempt to connect to an existing server socket.
1302 static int server_connect(void)
1304 struct sockaddr_un addr
;
1308 initial_cwd
= setup_config_dir();
1310 /* chdir to the server directory */
1311 if (chdir( server_dir
) == -1)
1313 if (errno
!= ENOENT
) fatal_perror( "chdir to %s", server_dir
);
1314 start_server( TRACE_ON(server
) );
1315 if (chdir( server_dir
) == -1) fatal_perror( "chdir to %s", server_dir
);
1318 /* make sure we are at the right place */
1319 if (stat( ".", &st
) == -1) fatal_perror( "stat %s", server_dir
);
1320 if (st
.st_uid
!= getuid()) fatal_error( "'%s' is not owned by you\n", server_dir
);
1321 if (st
.st_mode
& 077) fatal_error( "'%s' must not be accessible by other users\n", server_dir
);
1323 for (retry
= 0; retry
< 6; retry
++)
1325 /* if not the first try, wait a bit to leave the previous server time to exit */
1328 usleep( 100000 * retry
* retry
);
1329 start_server( TRACE_ON(server
) );
1330 if (lstat( SOCKETNAME
, &st
) == -1) continue; /* still no socket, wait a bit more */
1332 else if (lstat( SOCKETNAME
, &st
) == -1) /* check for an already existing socket */
1334 if (errno
!= ENOENT
) fatal_perror( "lstat %s/%s", server_dir
, SOCKETNAME
);
1335 start_server( TRACE_ON(server
) );
1336 if (lstat( SOCKETNAME
, &st
) == -1) continue; /* still no socket, wait a bit more */
1339 /* make sure the socket is sane (ISFIFO needed for Solaris) */
1340 if (!S_ISSOCK(st
.st_mode
) && !S_ISFIFO(st
.st_mode
))
1341 fatal_error( "'%s/%s' is not a socket\n", server_dir
, SOCKETNAME
);
1342 if (st
.st_uid
!= getuid())
1343 fatal_error( "'%s/%s' is not owned by you\n", server_dir
, SOCKETNAME
);
1345 /* try to connect to it */
1346 addr
.sun_family
= AF_UNIX
;
1347 strcpy( addr
.sun_path
, SOCKETNAME
);
1348 slen
= sizeof(addr
) - sizeof(addr
.sun_path
) + strlen(addr
.sun_path
) + 1;
1349 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
1350 addr
.sun_len
= slen
;
1352 if ((s
= socket( AF_UNIX
, SOCK_STREAM
, 0 )) == -1) fatal_perror( "socket" );
1357 setsockopt( s
, SOL_SOCKET
, SO_PASSCRED
, &enable
, sizeof(enable
) );
1360 if (connect( s
, (struct sockaddr
*)&addr
, slen
) != -1)
1362 fchdir( initial_cwd
); /* switch back to the starting directory */
1363 fcntl( s
, F_SETFD
, FD_CLOEXEC
);
1368 server_connect_error( server_dir
);
1373 #include <mach/mach.h>
1374 #include <mach/mach_error.h>
1375 #include <servers/bootstrap.h>
1377 /* send our task port to the server */
1378 static void send_server_task_port(void)
1380 mach_port_t bootstrap_port
, wineserver_port
;
1384 mach_msg_header_t header
;
1385 mach_msg_body_t body
;
1386 mach_msg_port_descriptor_t task_port
;
1389 if (task_get_bootstrap_port(mach_task_self(), &bootstrap_port
) != KERN_SUCCESS
) return;
1394 stat( config_dir
, &st
);
1395 server_dir
= init_server_dir( st
.st_dev
, st
.st_ino
);
1397 kret
= bootstrap_look_up(bootstrap_port
, server_dir
, &wineserver_port
);
1398 if (kret
!= KERN_SUCCESS
)
1399 fatal_error( "cannot find the server port: 0x%08x\n", kret
);
1401 mach_port_deallocate(mach_task_self(), bootstrap_port
);
1403 msg
.header
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, 0) | MACH_MSGH_BITS_COMPLEX
;
1404 msg
.header
.msgh_size
= sizeof(msg
);
1405 msg
.header
.msgh_remote_port
= wineserver_port
;
1406 msg
.header
.msgh_local_port
= MACH_PORT_NULL
;
1408 msg
.body
.msgh_descriptor_count
= 1;
1409 msg
.task_port
.name
= mach_task_self();
1410 msg
.task_port
.disposition
= MACH_MSG_TYPE_COPY_SEND
;
1411 msg
.task_port
.type
= MACH_MSG_PORT_DESCRIPTOR
;
1413 kret
= mach_msg_send(&msg
.header
);
1414 if (kret
!= KERN_SUCCESS
)
1415 server_protocol_error( "mach_msg_send failed: 0x%08x\n", kret
);
1417 mach_port_deallocate(mach_task_self(), wineserver_port
);
1419 #endif /* __APPLE__ */
1422 /***********************************************************************
1425 * Retrieve the Unix tid to use on the server side for the current thread.
1427 static int get_unix_tid(void)
1430 #ifdef HAVE_PTHREAD_GETTHREADID_NP
1431 ret
= pthread_getthreadid_np();
1432 #elif defined(linux)
1433 ret
= syscall( __NR_gettid
);
1434 #elif defined(__sun)
1435 ret
= pthread_self();
1436 #elif defined(__APPLE__)
1437 ret
= mach_thread_self();
1438 mach_port_deallocate(mach_task_self(), ret
);
1439 #elif defined(__NetBSD__)
1441 #elif defined(__FreeBSD__)
1445 #elif defined(__DragonFly__)
1452 /***********************************************************************
1455 * Create the server->client communication pipe.
1457 static int init_thread_pipe(void)
1462 ss
.ss_sp
= get_signal_stack();
1463 ss
.ss_size
= signal_stack_size
;
1465 sigaltstack( &ss
, NULL
);
1467 if (server_pipe( reply_pipe
) == -1) server_protocol_perror( "pipe" );
1468 if (server_pipe( ntdll_get_thread_data()->wait_fd
) == -1) server_protocol_perror( "pipe" );
1469 wine_server_send_fd( reply_pipe
[1] );
1470 wine_server_send_fd( ntdll_get_thread_data()->wait_fd
[1] );
1471 ntdll_get_thread_data()->reply_fd
= reply_pipe
[0];
1472 return reply_pipe
[1];
1476 /***********************************************************************
1477 * process_exit_wrapper
1479 * Close server socket and exit process normally.
1481 void process_exit_wrapper( int status
)
1488 /***********************************************************************
1489 * server_init_process
1491 * Start the server and create the initial socket pair.
1493 size_t server_init_process(void)
1495 const char *arch
= getenv( "WINEARCH" );
1496 const char *env_socket
= getenv( "WINESERVERSOCKET" );
1497 obj_handle_t version
;
1499 int ret
, reply_pipe
;
1500 struct sigaction sig_act
;
1507 fd_socket
= atoi( env_socket
);
1508 if (fcntl( fd_socket
, F_SETFD
, FD_CLOEXEC
) == -1)
1509 fatal_perror( "Bad server socket %d", fd_socket
);
1510 unsetenv( "WINESERVERSOCKET" );
1514 const char *arch
= getenv( "WINEARCH" );
1516 if (arch
&& strcmp( arch
, "win32" ) && strcmp( arch
, "win64" ))
1517 fatal_error( "WINEARCH set to invalid value '%s', it must be either win32 or win64.\n", arch
);
1519 fd_socket
= server_connect();
1522 /* setup the signal mask */
1523 sigemptyset( &server_block_set
);
1524 sigaddset( &server_block_set
, SIGALRM
);
1525 sigaddset( &server_block_set
, SIGIO
);
1526 sigaddset( &server_block_set
, SIGINT
);
1527 sigaddset( &server_block_set
, SIGHUP
);
1528 sigaddset( &server_block_set
, SIGUSR1
);
1529 sigaddset( &server_block_set
, SIGUSR2
);
1530 sigaddset( &server_block_set
, SIGCHLD
);
1531 pthread_sigmask( SIG_BLOCK
, &server_block_set
, NULL
);
1533 /* receive the first thread request fd on the main socket */
1534 ntdll_get_thread_data()->request_fd
= receive_fd( &version
);
1537 /* now that we hopefully received the server_pid, disable SO_PASSCRED */
1540 setsockopt( fd_socket
, SOL_SOCKET
, SO_PASSCRED
, &enable
, sizeof(enable
) );
1544 if (version
!= SERVER_PROTOCOL_VERSION
)
1545 server_protocol_error( "version mismatch %d/%d.\n"
1546 "Your %s binary was not upgraded correctly,\n"
1547 "or you have an older one somewhere in your PATH.\n"
1548 "Or maybe the wrong wineserver is still running?\n",
1549 version
, SERVER_PROTOCOL_VERSION
,
1550 (version
> SERVER_PROTOCOL_VERSION
) ? "wine" : "wineserver" );
1551 #if defined(__linux__) && defined(HAVE_PRCTL)
1552 /* work around Ubuntu's ptrace breakage */
1553 if (server_pid
!= -1) prctl( 0x59616d61 /* PR_SET_PTRACER */, server_pid
);
1556 /* ignore SIGPIPE so that we get an EPIPE error instead */
1557 sig_act
.sa_handler
= SIG_IGN
;
1558 sig_act
.sa_flags
= 0;
1559 sigemptyset( &sig_act
.sa_mask
);
1560 sigaction( SIGPIPE
, &sig_act
, NULL
);
1562 reply_pipe
= init_thread_pipe();
1564 SERVER_START_REQ( init_first_thread
)
1566 req
->unix_pid
= getpid();
1567 req
->unix_tid
= get_unix_tid();
1568 req
->reply_fd
= reply_pipe
;
1569 req
->wait_fd
= ntdll_get_thread_data()->wait_fd
[1];
1570 req
->debug_level
= (TRACE_ON(server
) != 0);
1571 wine_server_set_reply( req
, supported_machines
, sizeof(supported_machines
) );
1572 ret
= wine_server_call( req
);
1575 peb
->SessionId
= reply
->session_id
;
1576 info_size
= reply
->info_size
;
1577 server_start_time
= reply
->server_start
;
1578 supported_machines_count
= wine_server_reply_size( reply
) / sizeof(*supported_machines
);
1581 close( reply_pipe
);
1583 if (ret
) server_protocol_error( "init_first_thread failed with status %x\n", ret
);
1585 if (!supported_machines_count
)
1586 fatal_error( "'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.\n",
1589 native_machine
= supported_machines
[0];
1590 if (is_machine_64bit( native_machine
))
1592 if (arch
&& !strcmp( arch
, "win32" ))
1593 fatal_error( "WINEARCH set to win32 but '%s' is a 64-bit installation.\n", config_dir
);
1595 NtCurrentTeb()->GdiBatchCount
= PtrToUlong( (char *)NtCurrentTeb() - teb_offset
);
1596 NtCurrentTeb()->WowTebOffset
= -teb_offset
;
1597 wow_peb
= (PEB64
*)((char *)peb
- page_size
);
1603 fatal_error( "'%s' is a 32-bit installation, it cannot support 64-bit applications.\n", config_dir
);
1604 if (arch
&& !strcmp( arch
, "win64" ))
1605 fatal_error( "WINEARCH set to win64 but '%s' is a 32-bit installation.\n", config_dir
);
1608 set_thread_id( NtCurrentTeb(), pid
, tid
);
1610 for (i
= 0; i
< supported_machines_count
; i
++)
1611 if (supported_machines
[i
] == current_machine
) return info_size
;
1613 fatal_error( "wineserver doesn't support the %04x architecture\n", current_machine
);
1617 /***********************************************************************
1618 * server_init_process_done
1620 void server_init_process_done(void)
1623 unsigned int status
;
1625 FILE_FS_DEVICE_INFORMATION info
;
1627 if (!get_device_info( initial_cwd
, &info
) && (info
.Characteristics
& FILE_REMOVABLE_MEDIA
))
1629 close( initial_cwd
);
1632 send_server_task_port();
1634 if (main_image_info
.ImageCharacteristics
& IMAGE_FILE_LARGE_ADDRESS_AWARE
)
1635 virtual_set_large_address_space();
1637 /* Install signal handlers; this cannot be done earlier, since we cannot
1638 * send exceptions to the debugger before the create process event that
1639 * is sent by init_process_done */
1640 signal_init_process();
1642 /* always send the native TEB */
1643 if (!(teb
= NtCurrentTeb64())) teb
= NtCurrentTeb();
1645 /* Signal the parent process to continue */
1646 SERVER_START_REQ( init_process_done
)
1648 req
->teb
= wine_server_client_ptr( teb
);
1649 req
->peb
= NtCurrentTeb64() ? NtCurrentTeb64()->Peb
: wine_server_client_ptr( peb
);
1651 req
->ldt_copy
= wine_server_client_ptr( &__wine_ldt_copy
);
1653 status
= wine_server_call( req
);
1654 suspend
= reply
->suspend
;
1655 entry
= wine_server_get_ptr( reply
->entry
);
1660 signal_start_thread( entry
, peb
, suspend
, NtCurrentTeb() );
1664 /***********************************************************************
1665 * server_init_thread
1667 * Send an init thread request.
1669 void server_init_thread( void *entry_point
, BOOL
*suspend
)
1672 int reply_pipe
= init_thread_pipe();
1674 /* always send the native TEB */
1675 if (!(teb
= NtCurrentTeb64())) teb
= NtCurrentTeb();
1677 SERVER_START_REQ( init_thread
)
1679 req
->unix_tid
= get_unix_tid();
1680 req
->teb
= wine_server_client_ptr( teb
);
1681 req
->entry
= wine_server_client_ptr( entry_point
);
1682 req
->reply_fd
= reply_pipe
;
1683 req
->wait_fd
= ntdll_get_thread_data()->wait_fd
[1];
1684 wine_server_call( req
);
1685 *suspend
= reply
->suspend
;
1688 close( reply_pipe
);
1692 /******************************************************************************
1695 NTSTATUS WINAPI
NtDuplicateObject( HANDLE source_process
, HANDLE source
, HANDLE dest_process
, HANDLE
*dest
,
1696 ACCESS_MASK access
, ULONG attributes
, ULONG options
)
1702 if (dest
) *dest
= 0;
1704 if ((options
& DUPLICATE_CLOSE_SOURCE
) && source_process
!= NtCurrentProcess())
1707 apc_result_t result
;
1709 memset( &call
, 0, sizeof(call
) );
1711 call
.dup_handle
.type
= APC_DUP_HANDLE
;
1712 call
.dup_handle
.src_handle
= wine_server_obj_handle( source
);
1713 call
.dup_handle
.dst_process
= wine_server_obj_handle( dest_process
);
1714 call
.dup_handle
.access
= access
;
1715 call
.dup_handle
.attributes
= attributes
;
1716 call
.dup_handle
.options
= options
;
1717 ret
= server_queue_process_apc( source_process
, &call
, &result
);
1718 if (ret
!= STATUS_SUCCESS
) return ret
;
1720 if (!result
.dup_handle
.status
)
1721 *dest
= wine_server_ptr_handle( result
.dup_handle
.handle
);
1722 return result
.dup_handle
.status
;
1725 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1727 /* always remove the cached fd; if the server request fails we'll just
1728 * retrieve it again */
1729 if (options
& DUPLICATE_CLOSE_SOURCE
)
1730 fd
= remove_fd_from_cache( source
);
1732 SERVER_START_REQ( dup_handle
)
1734 req
->src_process
= wine_server_obj_handle( source_process
);
1735 req
->src_handle
= wine_server_obj_handle( source
);
1736 req
->dst_process
= wine_server_obj_handle( dest_process
);
1737 req
->access
= access
;
1738 req
->attributes
= attributes
;
1739 req
->options
= options
;
1740 if (!(ret
= wine_server_call( req
)))
1742 if (dest
) *dest
= wine_server_ptr_handle( reply
->handle
);
1747 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1749 if (fd
!= -1) close( fd
);
1754 /**************************************************************************
1755 * NtCompareObjects (NTDLL.@)
1757 NTSTATUS WINAPI
NtCompareObjects( HANDLE first
, HANDLE second
)
1759 unsigned int status
;
1761 SERVER_START_REQ( compare_objects
)
1763 req
->first
= wine_server_obj_handle( first
);
1764 req
->second
= wine_server_obj_handle( second
);
1765 status
= wine_server_call( req
);
1773 /**************************************************************************
1776 NTSTATUS WINAPI
NtClose( HANDLE handle
)
1783 if (HandleToLong( handle
) >= ~5 && HandleToLong( handle
) <= ~0)
1784 return STATUS_SUCCESS
;
1786 server_enter_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1788 /* always remove the cached fd; if the server request fails we'll just
1789 * retrieve it again */
1790 fd
= remove_fd_from_cache( handle
);
1792 SERVER_START_REQ( close_handle
)
1794 req
->handle
= wine_server_obj_handle( handle
);
1795 ret
= wine_server_call( req
);
1799 server_leave_uninterrupted_section( &fd_cache_mutex
, &sigset
);
1801 if (fd
!= -1) close( fd
);
1803 if (ret
!= STATUS_INVALID_HANDLE
|| !handle
) return ret
;
1804 if (!peb
->BeingDebugged
) return ret
;
1805 if (!NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort
, &port
, sizeof(port
), NULL
) && port
)
1807 NtCurrentTeb()->ExceptionCode
= ret
;
1808 call_raise_user_exception_dispatcher();
1815 struct __server_request_info32
1819 union generic_request req
;
1820 union generic_reply reply
;
1822 unsigned int data_count
;
1824 struct { ULONG ptr
; data_size_t size
; } data
[__SERVER_MAX_DATA
];
1827 /**********************************************************************
1828 * wow64_wine_server_call
1830 NTSTATUS
wow64_wine_server_call( void *args
)
1832 struct __server_request_info32
*req32
= args
;
1835 struct __server_request_info req
;
1837 req
.u
.req
= req32
->u
.req
;
1838 req
.data_count
= req32
->data_count
;
1839 for (i
= 0; i
< req
.data_count
; i
++)
1841 req
.data
[i
].ptr
= ULongToPtr( req32
->data
[i
].ptr
);
1842 req
.data
[i
].size
= req32
->data
[i
].size
;
1844 req
.reply_data
= ULongToPtr( req32
->reply_data
);
1845 status
= wine_server_call( &req
);
1846 req32
->u
.reply
= req
.u
.reply
;
1850 /***********************************************************************
1851 * wow64_wine_server_fd_to_handle
1853 NTSTATUS
wow64_wine_server_fd_to_handle( void *args
)
1858 unsigned int access
;
1859 unsigned int attributes
;
1861 } const *params32
= args
;
1863 ULONG
*handle32
= ULongToPtr( params32
->handle
);
1867 ret
= wine_server_fd_to_handle( params32
->fd
, params32
->access
, params32
->attributes
, &handle
);
1868 *handle32
= HandleToULong( handle
);
1872 /**********************************************************************
1873 * wow64_wine_server_handle_to_fd
1875 NTSTATUS
wow64_wine_server_handle_to_fd( void *args
)
1880 unsigned int access
;
1883 } const *params32
= args
;
1885 return wine_server_handle_to_fd( ULongToHandle( params32
->handle
), params32
->access
,
1886 ULongToPtr( params32
->unix_fd
), ULongToPtr( params32
->options
));