server.c 34.7 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1
/*
2
 * Wine server communication
Alexandre Julliard's avatar
Alexandre Julliard committed
3 4
 *
 * Copyright (C) 1998 Alexandre Julliard
5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * 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
Alexandre Julliard's avatar
Alexandre Julliard committed
19 20
 */

21
#include "config.h"
22
#include "wine/port.h"
23

Alexandre Julliard's avatar
Alexandre Julliard committed
24
#include <assert.h>
25
#include <ctype.h>
26 27 28
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#endif
Alexandre Julliard's avatar
Alexandre Julliard committed
29
#include <errno.h>
30
#include <fcntl.h>
31
#include <signal.h>
32
#include <stdarg.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
33 34
#include <stdio.h>
#include <string.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
35
#include <sys/types.h>
36 37 38
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
39 40 41
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
Steven Edwards's avatar
Steven Edwards committed
42
#ifdef HAVE_SYS_UN_H
43
#include <sys/un.h>
Steven Edwards's avatar
Steven Edwards committed
44
#endif
45
#ifdef HAVE_SYS_MMAN_H
46
#include <sys/mman.h>
47
#endif
48 49 50
#ifdef HAVE_SYS_PRCTL_H
# include <sys/prctl.h>
#endif
51 52 53
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
54 55 56
#ifdef HAVE_SYS_SYSCALL_H
# include <sys/syscall.h>
#endif
Steven Edwards's avatar
Steven Edwards committed
57
#ifdef HAVE_SYS_UIO_H
Alexandre Julliard's avatar
Alexandre Julliard committed
58
#include <sys/uio.h>
Steven Edwards's avatar
Steven Edwards committed
59
#endif
60 61 62 63
#ifdef HAVE_SYS_THR_H
#include <sys/ucontext.h>
#include <sys/thr.h>
#endif
64 65 66
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
Alexandre Julliard's avatar
Alexandre Julliard committed
67

68
#include "ntstatus.h"
69
#define WIN32_NO_STATUS
70
#include "wine/library.h"
71
#include "wine/server.h"
72
#include "wine/debug.h"
73
#include "ntdll_misc.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
74

75 76
WINE_DEFAULT_DEBUG_CHANNEL(server);

Alexandre Julliard's avatar
Alexandre Julliard committed
77 78 79 80
/* Some versions of glibc don't define this */
#ifndef SCM_RIGHTS
#define SCM_RIGHTS 1
#endif
Alexandre Julliard's avatar
Alexandre Julliard committed
81

82 83 84 85
#ifndef MSG_CMSG_CLOEXEC
#define MSG_CMSG_CLOEXEC 0
#endif

86
#define SOCKETNAME "socket"        /* name of the socket file */
87
#define LOCKNAME   "lock"          /* name of the lock file */
88

89 90 91 92 93 94 95 96
#ifdef __i386__
static const enum cpu_type client_cpu = CPU_x86;
#elif defined(__x86_64__)
static const enum cpu_type client_cpu = CPU_x86_64;
#elif defined(__powerpc__)
static const enum cpu_type client_cpu = CPU_POWERPC;
#elif defined(__sparc__)
static const enum cpu_type client_cpu = CPU_SPARC;
97 98
#elif defined(__arm__)
static const enum cpu_type client_cpu = CPU_ARM;
99 100 101 102
#else
#error Unsupported CPU
#endif

103
unsigned int server_cpus = 0;
104
int is_wow64 = FALSE;
105

106
timeout_t server_start_time = 0;  /* time of server startup */
107

108
sigset_t server_block_set;  /* signals to block during server calls */
109
static int fd_socket = -1;  /* socket to exchange file descriptors with the server */
110
static pid_t server_pid;
111

112 113 114 115 116 117 118 119 120 121
static RTL_CRITICAL_SECTION fd_cache_section;
static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &fd_cache_section,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": fd_cache_section") }
};
static RTL_CRITICAL_SECTION fd_cache_section = { &critsect_debug, -1, 0, 0, 0, 0 };


122 123 124 125 126 127
#ifdef __GNUC__
static void fatal_error( const char *err, ... ) __attribute__((noreturn, format(printf,1,2)));
static void fatal_perror( const char *err, ... ) __attribute__((noreturn, format(printf,1,2)));
static void server_connect_error( const char *serverdir ) __attribute__((noreturn));
#endif

128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
/* die on a fatal error; use only during initialization */
static void fatal_error( const char *err, ... )
{
    va_list args;

    va_start( args, err );
    fprintf( stderr, "wine: " );
    vfprintf( stderr, err, args );
    va_end( args );
    exit(1);
}

/* die on a fatal error; use only during initialization */
static void fatal_perror( const char *err, ... )
{
    va_list args;

    va_start( args, err );
    fprintf( stderr, "wine: " );
    vfprintf( stderr, err, args );
    perror( " " );
    va_end( args );
    exit(1);
}

153

Alexandre Julliard's avatar
Alexandre Julliard committed
154
/***********************************************************************
155
 *           server_protocol_error
Alexandre Julliard's avatar
Alexandre Julliard committed
156
 */
157
void server_protocol_error( const char *err, ... )
Alexandre Julliard's avatar
Alexandre Julliard committed
158 159 160 161
{
    va_list args;

    va_start( args, err );
162
    fprintf( stderr, "wine client error:%x: ", GetCurrentThreadId() );
Alexandre Julliard's avatar
Alexandre Julliard committed
163 164
    vfprintf( stderr, err, args );
    va_end( args );
165
    abort_thread(1);
Alexandre Julliard's avatar
Alexandre Julliard committed
166 167 168
}


Alexandre Julliard's avatar
Alexandre Julliard committed
169
/***********************************************************************
170
 *           server_protocol_perror
171
 */
172
void server_protocol_perror( const char *err )
173
{
174
    fprintf( stderr, "wine client error:%x: ", GetCurrentThreadId() );
175
    perror( err );
176
    abort_thread(1);
177 178 179 180 181
}


/***********************************************************************
 *           send_request
Alexandre Julliard's avatar
Alexandre Julliard committed
182 183 184
 *
 * Send a request to the server.
 */
185
static unsigned int send_request( const struct __server_request_info *req )
186
{
187 188
    unsigned int i;
    int ret;
189 190 191

    if (!req->u.req.request_header.request_size)
    {
192
        if ((ret = write( ntdll_get_thread_data()->request_fd, &req->u.req,
193
                          sizeof(req->u.req) )) == sizeof(req->u.req)) return STATUS_SUCCESS;
194 195 196 197 198 199 200 201 202 203 204 205 206

    }
    else
    {
        struct iovec vec[__SERVER_MAX_DATA+1];

        vec[0].iov_base = (void *)&req->u.req;
        vec[0].iov_len = sizeof(req->u.req);
        for (i = 0; i < req->data_count; i++)
        {
            vec[i+1].iov_base = (void *)req->data[i].ptr;
            vec[i+1].iov_len = req->data[i].size;
        }
207
        if ((ret = writev( ntdll_get_thread_data()->request_fd, vec, i+1 )) ==
208
            req->u.req.request_header.request_size + sizeof(req->u.req)) return STATUS_SUCCESS;
209
    }
210 211

    if (ret >= 0) server_protocol_error( "partial write %d\n", ret );
212
    if (errno == EPIPE) abort_thread(0);
213
    if (errno == EFAULT) return STATUS_ACCESS_VIOLATION;
214
    server_protocol_perror( "write" );
215 216
}

217

Alexandre Julliard's avatar
Alexandre Julliard committed
218
/***********************************************************************
219
 *           read_reply_data
Alexandre Julliard's avatar
Alexandre Julliard committed
220
 *
221
 * Read data from the reply buffer; helper for wait_reply.
Alexandre Julliard's avatar
Alexandre Julliard committed
222
 */
223
static void read_reply_data( void *buffer, size_t size )
Alexandre Julliard's avatar
Alexandre Julliard committed
224
{
225
    int ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
226

227
    for (;;)
Alexandre Julliard's avatar
Alexandre Julliard committed
228
    {
229
        if ((ret = read( ntdll_get_thread_data()->reply_fd, buffer, size )) > 0)
230 231 232 233 234
        {
            if (!(size -= ret)) return;
            buffer = (char *)buffer + ret;
            continue;
        }
235
        if (!ret) break;
236 237
        if (errno == EINTR) continue;
        if (errno == EPIPE) break;
238
        server_protocol_perror("read");
Alexandre Julliard's avatar
Alexandre Julliard committed
239
    }
240
    /* the server closed the connection; time to die... */
241
    abort_thread(0);
Alexandre Julliard's avatar
Alexandre Julliard committed
242 243 244
}


245 246 247 248 249
/***********************************************************************
 *           wait_reply
 *
 * Wait for a reply from the server.
 */
250
static inline unsigned int wait_reply( struct __server_request_info *req )
251 252 253 254
{
    read_reply_data( &req->u.reply, sizeof(req->u.reply) );
    if (req->u.reply.reply_header.reply_size)
        read_reply_data( req->reply_data, req->u.reply.reply_header.reply_size );
255
    return req->u.reply.reply_header.error;
256 257 258
}


Alexandre Julliard's avatar
Alexandre Julliard committed
259
/***********************************************************************
260
 *           wine_server_call (NTDLL.@)
261 262
 *
 * Perform a server call.
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
 *
 * PARAMS
 *     req_ptr [I/O] Function dependent data
 *
 * RETURNS
 *     Depends on server function being called, but usually an NTSTATUS code.
 *
 * NOTES
 *     Use the SERVER_START_REQ and SERVER_END_REQ to help you fill out the
 *     server request structure for the particular call. E.g:
 *|     SERVER_START_REQ( event_op )
 *|     {
 *|         req->handle = handle;
 *|         req->op     = SET_EVENT;
 *|         ret = wine_server_call( req );
 *|     }
 *|     SERVER_END_REQ;
280
 */
281
unsigned int wine_server_call( void *req_ptr )
282
{
283
    struct __server_request_info * const req = req_ptr;
284
    sigset_t old_set;
285
    unsigned int ret;
286

287
    pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
288 289
    ret = send_request( req );
    if (!ret) ret = wait_reply( req );
290
    pthread_sigmask( SIG_SETMASK, &old_set, NULL );
291
    return ret;
292 293 294
}


295 296 297 298 299
/***********************************************************************
 *           server_enter_uninterrupted_section
 */
void server_enter_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset )
{
300
    pthread_sigmask( SIG_BLOCK, &server_block_set, sigset );
301 302 303 304 305 306 307 308 309 310
    RtlEnterCriticalSection( cs );
}


/***********************************************************************
 *           server_leave_uninterrupted_section
 */
void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset )
{
    RtlLeaveCriticalSection( cs );
311
    pthread_sigmask( SIG_SETMASK, sigset, NULL );
312 313 314
}


315
/***********************************************************************
316
 *           wine_server_send_fd   (NTDLL.@)
Alexandre Julliard's avatar
Alexandre Julliard committed
317
 *
318
 * Send a file descriptor to the server.
319 320 321 322 323 324
 *
 * PARAMS
 *     fd [I] file descriptor to send
 *
 * RETURNS
 *     nothing
Alexandre Julliard's avatar
Alexandre Julliard committed
325
 */
326
void CDECL wine_server_send_fd( int fd )
327
{
328 329 330 331 332
    struct send_fd data;
    struct msghdr msghdr;
    struct iovec vec;
    int ret;

333
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
334 335
    msghdr.msg_accrights    = (void *)&fd;
    msghdr.msg_accrightslen = sizeof(fd);
336
#else  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
337 338 339 340
    char cmsg_buffer[256];
    struct cmsghdr *cmsg;
    msghdr.msg_control    = cmsg_buffer;
    msghdr.msg_controllen = sizeof(cmsg_buffer);
341
    msghdr.msg_flags      = 0;
342 343 344 345 346 347
    cmsg = CMSG_FIRSTHDR( &msghdr );
    cmsg->cmsg_len   = CMSG_LEN( sizeof(fd) );
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type  = SCM_RIGHTS;
    *(int *)CMSG_DATA(cmsg) = fd;
    msghdr.msg_controllen = cmsg->cmsg_len;
348
#endif  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
349

350 351 352 353 354 355 356 357
    msghdr.msg_name    = NULL;
    msghdr.msg_namelen = 0;
    msghdr.msg_iov     = &vec;
    msghdr.msg_iovlen  = 1;

    vec.iov_base = (void *)&data;
    vec.iov_len  = sizeof(data);

358
    data.tid = GetCurrentThreadId();
359 360 361 362 363 364 365
    data.fd  = fd;

    for (;;)
    {
        if ((ret = sendmsg( fd_socket, &msghdr, 0 )) == sizeof(data)) return;
        if (ret >= 0) server_protocol_error( "partial write %d\n", ret );
        if (errno == EINTR) continue;
366
        if (errno == EPIPE) abort_thread(0);
367 368
        server_protocol_perror( "sendmsg" );
    }
369 370 371 372
}


/***********************************************************************
373
 *           receive_fd
374 375 376
 *
 * Receive a file descriptor passed from the server.
 */
377
static int receive_fd( obj_handle_t *handle )
Alexandre Julliard's avatar
Alexandre Julliard committed
378
{
379
    struct iovec vec;
Patrik Stridvall's avatar
Patrik Stridvall committed
380
    struct msghdr msghdr;
381
    int ret, fd = -1;
Patrik Stridvall's avatar
Patrik Stridvall committed
382

383
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
384 385
    msghdr.msg_accrights    = (void *)&fd;
    msghdr.msg_accrightslen = sizeof(fd);
386
#else  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
387 388 389
    char cmsg_buffer[256];
    msghdr.msg_control    = cmsg_buffer;
    msghdr.msg_controllen = sizeof(cmsg_buffer);
Patrik Stridvall's avatar
Patrik Stridvall committed
390
    msghdr.msg_flags      = 0;
391
#endif  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
Patrik Stridvall's avatar
Patrik Stridvall committed
392 393 394

    msghdr.msg_name    = NULL;
    msghdr.msg_namelen = 0;
395 396
    msghdr.msg_iov     = &vec;
    msghdr.msg_iovlen  = 1;
397 398
    vec.iov_base = (void *)handle;
    vec.iov_len  = sizeof(*handle);
Patrik Stridvall's avatar
Patrik Stridvall committed
399

400
    for (;;)
Alexandre Julliard's avatar
Alexandre Julliard committed
401
    {
402
        if ((ret = recvmsg( fd_socket, &msghdr, MSG_CMSG_CLOEXEC )) > 0)
403
        {
404
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
405 406 407 408 409
            struct cmsghdr *cmsg;
            for (cmsg = CMSG_FIRSTHDR( &msghdr ); cmsg; cmsg = CMSG_NXTHDR( &msghdr, cmsg ))
            {
                if (cmsg->cmsg_level != SOL_SOCKET) continue;
                if (cmsg->cmsg_type == SCM_RIGHTS) fd = *(int *)CMSG_DATA(cmsg);
410 411 412 413 414 415 416
#ifdef SCM_CREDENTIALS
                else if (cmsg->cmsg_type == SCM_CREDENTIALS)
                {
                    struct ucred *ucred = (struct ucred *)CMSG_DATA(cmsg);
                    server_pid = ucred->pid;
                }
#endif
417 418
            }
#endif  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
419
            if (fd != -1) fcntl( fd, F_SETFD, FD_CLOEXEC ); /* in case MSG_CMSG_CLOEXEC is not supported */
420
            return fd;
421
        }
422
        if (!ret) break;
423 424
        if (errno == EINTR) continue;
        if (errno == EPIPE) break;
425
        server_protocol_perror("recvmsg");
Alexandre Julliard's avatar
Alexandre Julliard committed
426
    }
427
    /* the server closed the connection; time to die... */
428
    abort_thread(0);
429
}
Alexandre Julliard's avatar
Alexandre Julliard committed
430 431


432 433
/***********************************************************************/
/* fd cache support */
434

435 436 437
struct fd_cache_entry
{
    int fd;
438 439 440
    enum server_fd_type type : 6;
    unsigned int        access : 2;
    unsigned int        options : 24;
441 442
};

443 444 445 446 447 448
#define FD_CACHE_BLOCK_SIZE  (65536 / sizeof(struct fd_cache_entry))
#define FD_CACHE_ENTRIES     128

static struct fd_cache_entry *fd_cache[FD_CACHE_ENTRIES];
static struct fd_cache_entry fd_cache_initial_block[FD_CACHE_BLOCK_SIZE];

449
static inline unsigned int handle_to_index( HANDLE handle, unsigned int *entry )
450
{
451
    unsigned int idx = (wine_server_obj_handle(handle) >> 2) - 1;
452 453 454 455
    *entry = idx / FD_CACHE_BLOCK_SIZE;
    return idx % FD_CACHE_BLOCK_SIZE;
}

456 457 458 459 460 461

/***********************************************************************
 *           add_fd_to_cache
 *
 * Caller must hold fd_cache_section.
 */
462
static int add_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type,
463
                            unsigned int access, unsigned int options )
464
{
465 466
    unsigned int entry, idx = handle_to_index( handle, &entry );
    int prev_fd;
467

468
    if (entry >= FD_CACHE_ENTRIES)
469
    {
470 471 472
        FIXME( "too many allocated handles, not caching %p\n", handle );
        return 0;
    }
473

474 475 476
    if (!fd_cache[entry])  /* do we need to allocate a new block of entries? */
    {
        if (!entry) fd_cache[0] = fd_cache_initial_block;
477 478
        else
        {
479 480 481 482
            void *ptr = wine_anon_mmap( NULL, FD_CACHE_BLOCK_SIZE * sizeof(struct fd_cache_entry),
                                        PROT_READ | PROT_WRITE, 0 );
            if (ptr == MAP_FAILED) return 0;
            fd_cache[entry] = ptr;
483 484
        }
    }
485 486 487
    /* store fd+1 so that 0 can be used as the unset value */
    prev_fd = interlocked_xchg( &fd_cache[entry][idx].fd, fd + 1 ) - 1;
    fd_cache[entry][idx].type = type;
488 489
    fd_cache[entry][idx].access = access;
    fd_cache[entry][idx].options = options;
490 491
    if (prev_fd != -1) close( prev_fd );
    return 1;
492 493 494 495 496 497 498 499
}


/***********************************************************************
 *           get_cached_fd
 *
 * Caller must hold fd_cache_section.
 */
500
static inline int get_cached_fd( HANDLE handle, enum server_fd_type *type,
501
                                 unsigned int *access, unsigned int *options )
502
{
503
    unsigned int entry, idx = handle_to_index( handle, &entry );
504 505
    int fd = -1;

506
    if (entry < FD_CACHE_ENTRIES && fd_cache[entry])
507
    {
508 509
        fd = fd_cache[entry][idx].fd - 1;
        if (type) *type = fd_cache[entry][idx].type;
510 511
        if (access) *access = fd_cache[entry][idx].access;
        if (options) *options = fd_cache[entry][idx].options;
512
    }
513 514 515 516 517 518 519
    return fd;
}


/***********************************************************************
 *           server_remove_fd_from_cache
 */
520
int server_remove_fd_from_cache( HANDLE handle )
521
{
522
    unsigned int entry, idx = handle_to_index( handle, &entry );
523 524
    int fd = -1;

525 526
    if (entry < FD_CACHE_ENTRIES && fd_cache[entry])
        fd = interlocked_xchg( &fd_cache[entry][idx].fd, 0 ) - 1;
527 528 529 530 531

    return fd;
}


532 533 534 535 536
/***********************************************************************
 *           server_get_unix_fd
 *
 * The returned unix_fd should be closed iff needs_close is non-zero.
 */
537
int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
538
                        int *needs_close, enum server_fd_type *type, unsigned int *options )
539
{
540
    sigset_t sigset;
541
    obj_handle_t fd_handle;
542
    int ret = 0, fd;
543
    unsigned int access = 0;
544 545 546

    *unix_fd = -1;
    *needs_close = 0;
547
    wanted_access &= FILE_READ_DATA | FILE_WRITE_DATA;
548

549
    server_enter_uninterrupted_section( &fd_cache_section, &sigset );
550

551 552
    fd = get_cached_fd( handle, type, &access, options );
    if (fd != -1) goto done;
553 554 555

    SERVER_START_REQ( get_handle_fd )
    {
556
        req->handle = wine_server_obj_handle( handle );
557 558
        if (!(ret = wine_server_call( req )))
        {
559
            if (type) *type = reply->type;
560 561 562
            if (options) *options = reply->options;
            access = reply->access;
            if ((fd = receive_fd( &fd_handle )) != -1)
563
            {
564
                assert( wine_server_ptr_handle(fd_handle) == handle );
565
                *needs_close = (!reply->cacheable ||
566 567
                                !add_fd_to_cache( handle, fd, reply->type,
                                                  reply->access, reply->options ));
568
            }
569
            else ret = STATUS_TOO_MANY_OPENED_FILES;
570 571 572 573 574
        }
    }
    SERVER_END_REQ;

done:
575
    server_leave_uninterrupted_section( &fd_cache_section, &sigset );
576 577 578 579 580
    if (!ret && ((access & wanted_access) != wanted_access))
    {
        ret = STATUS_ACCESS_DENIED;
        if (*needs_close) close( fd );
    }
581 582 583 584 585
    if (!ret) *unix_fd = fd;
    return ret;
}


586 587 588
/***********************************************************************
 *           wine_server_fd_to_handle   (NTDLL.@)
 *
589 590 591 592 593
 * Allocate a file handle for a Unix file descriptor.
 *
 * PARAMS
 *     fd      [I] Unix file descriptor.
 *     access  [I] Win32 access flags.
594
 *     attributes [I] Object attributes.
595 596 597 598
 *     handle  [O] Address where Wine file handle will be stored.
 *
 * RETURNS
 *     NTSTATUS code
599
 */
600
int CDECL wine_server_fd_to_handle( int fd, unsigned int access, unsigned int attributes, HANDLE *handle )
601 602 603 604 605 606 607 608
{
    int ret;

    *handle = 0;
    wine_server_send_fd( fd );

    SERVER_START_REQ( alloc_file_handle )
    {
609
        req->access     = access;
610
        req->attributes = attributes;
611
        req->fd         = fd;
612
        if (!(ret = wine_server_call( req ))) *handle = wine_server_ptr_handle( reply->handle );
613 614 615 616 617 618
    }
    SERVER_END_REQ;
    return ret;
}


619 620 621
/***********************************************************************
 *           wine_server_handle_to_fd   (NTDLL.@)
 *
622 623 624 625 626 627
 * Retrieve the file descriptor corresponding to a file handle.
 *
 * PARAMS
 *     handle  [I] Wine file handle.
 *     access  [I] Win32 file access rights requested.
 *     unix_fd [O] Address where Unix file descriptor will be stored.
628
 *     options [O] Address where the file open options will be stored. Optional.
629 630 631
 *
 * RETURNS
 *     NTSTATUS code
632
 */
633
int CDECL wine_server_handle_to_fd( HANDLE handle, unsigned int access, int *unix_fd,
634
                              unsigned int *options )
635
{
636
    int needs_close, ret = server_get_unix_fd( handle, access, unix_fd, &needs_close, NULL, options );
637

638
    if (!ret && !needs_close)
639
    {
640
        if ((*unix_fd = dup(*unix_fd)) == -1) ret = FILE_GetNtStatus();
641
    }
642
    return ret;
643 644 645
}


646 647 648
/***********************************************************************
 *           wine_server_release_fd   (NTDLL.@)
 *
649 650 651 652 653 654 655 656
 * Release the Unix file descriptor returned by wine_server_handle_to_fd.
 *
 * PARAMS
 *     handle  [I] Wine file handle.
 *     unix_fd [I] Unix file descriptor to release.
 *
 * RETURNS
 *     nothing
657
 */
658
void CDECL wine_server_release_fd( HANDLE handle, int unix_fd )
659 660 661 662 663
{
    close( unix_fd );
}


664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
/***********************************************************************
 *           server_pipe
 *
 * Create a pipe for communicating with the server.
 */
int server_pipe( int fd[2] )
{
    int ret;
#ifdef HAVE_PIPE2
    static int have_pipe2 = 1;

    if (have_pipe2)
    {
        if (!(ret = pipe2( fd, O_CLOEXEC ))) return ret;
        if (errno == ENOSYS || errno == EINVAL) have_pipe2 = 0;  /* don't try again */
    }
#endif
    if (!(ret = pipe( fd )))
    {
        fcntl( fd[0], F_SETFD, FD_CLOEXEC );
        fcntl( fd[1], F_SETFD, FD_CLOEXEC );
    }
    return ret;
}


690 691 692 693 694
/***********************************************************************
 *           start_server
 *
 * Start a new wine server.
 */
695
static void start_server(void)
696 697
{
    static int started;  /* we only try once */
698
    char *argv[3];
699 700
    static char wineserver[] = "server/wineserver";
    static char debug[] = "-d";
701

702 703
    if (!started)
    {
704
        int status;
705 706 707 708
        int pid = fork();
        if (pid == -1) fatal_perror( "fork" );
        if (!pid)
        {
709 710
            argv[0] = wineserver;
            argv[1] = TRACE_ON(server) ? debug : NULL;
711
            argv[2] = NULL;
712
            wine_exec_wine_binary( argv[0], argv, getenv("WINESERVER") );
713 714
            fatal_error( "could not exec wineserver\n" );
        }
715 716
        waitpid( pid, &status, 0 );
        status = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
717
        if (status == 2) return;  /* server lock held by someone else, will retry later */
718
        if (status) exit(status);  /* server failed */
719 720 721 722 723
        started = 1;
    }
}


724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752
/***********************************************************************
 *           setup_config_dir
 *
 * Setup the wine configuration dir.
 */
static void setup_config_dir(void)
{
    const char *p, *config_dir = wine_get_config_dir();

    if (chdir( config_dir ) == -1)
    {
        if (errno != ENOENT) fatal_perror( "chdir to %s\n", config_dir );

        if ((p = strrchr( config_dir, '/' )) && p != config_dir)
        {
            struct stat st;
            char *tmp_dir;

            if (!(tmp_dir = malloc( p + 1 - config_dir ))) fatal_error( "out of memory\n" );
            memcpy( tmp_dir, config_dir, p - config_dir );
            tmp_dir[p - config_dir] = 0;
            if (!stat( tmp_dir, &st ) && st.st_uid != getuid())
                fatal_error( "'%s' is not owned by you, refusing to create a configuration directory there\n",
                             tmp_dir );
            free( tmp_dir );
        }

        mkdir( config_dir, 0777 );
        if (chdir( config_dir ) == -1) fatal_perror( "chdir to %s\n", config_dir );
753 754 755 756 757 758 759 760 761 762 763 764

        if ((p = getenv( "WINEARCH" )) && !strcmp( p, "win32" ))
        {
            /* force creation of a 32-bit prefix */
            int fd = open( "system.reg", O_WRONLY | O_CREAT | O_EXCL, 0666 );
            if (fd != -1)
            {
                static const char regfile[] = "WINE REGISTRY Version 2\n\n#arch=win32\n";
                write( fd, regfile, sizeof(regfile) - 1 );
                close( fd );
            }
        }
765
        MESSAGE( "wine: created the configuration directory '%s'\n", config_dir );
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781
    }

    if (mkdir( "dosdevices", 0777 ) == -1)
    {
        if (errno == EEXIST) return;
        fatal_perror( "cannot create %s/dosdevices\n", config_dir );
    }

    /* create the drive symlinks */

    mkdir( "drive_c", 0777 );
    symlink( "../drive_c", "dosdevices/c:" );
    symlink( "/", "dosdevices/z:" );
}


782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806
/***********************************************************************
 *           server_connect_error
 *
 * Try to display a meaningful explanation of why we couldn't connect
 * to the server.
 */
static void server_connect_error( const char *serverdir )
{
    int fd;
    struct flock fl;

    if ((fd = open( LOCKNAME, O_WRONLY )) == -1)
        fatal_error( "for some mysterious reason, the wine server never started.\n" );

    fl.l_type   = F_WRLCK;
    fl.l_whence = SEEK_SET;
    fl.l_start  = 0;
    fl.l_len    = 1;
    if (fcntl( fd, F_GETLK, &fl ) != -1)
    {
        if (fl.l_type == F_WRLCK)  /* the file is locked */
            fatal_error( "a wine server seems to be running, but I cannot connect to it.\n"
                         "   You probably need to kill that process (it might be pid %d).\n",
                         (int)fl.l_pid );
        fatal_error( "for some mysterious reason, the wine server failed to run.\n" );
807
    }
808 809 810 811
    fatal_error( "the file system of '%s' doesn't support locks,\n"
          "   and there is a 'socket' file in that directory that prevents wine from starting.\n"
          "   You should make sure no wine server is running, remove that file and try again.\n",
                 serverdir );
812 813
}

814

815 816 817 818 819 820
/***********************************************************************
 *           server_connect
 *
 * Attempt to connect to an existing server socket.
 * We need to be in the server directory already.
 */
821
static int server_connect(void)
822
{
823
    const char *serverdir;
824 825
    struct sockaddr_un addr;
    struct stat st;
826 827 828 829 830
    int s, slen, retry, fd_cwd;

    /* retrieve the current directory */
    fd_cwd = open( ".", O_RDONLY );
    if (fd_cwd != -1) fcntl( fd_cwd, F_SETFD, 1 ); /* set close on exec flag */
831

832 833 834
    setup_config_dir();
    serverdir = wine_get_server_dir();

835
    /* chdir to the server directory */
836 837 838
    if (chdir( serverdir ) == -1)
    {
        if (errno != ENOENT) fatal_perror( "chdir to %s", serverdir );
839
        start_server();
840
        if (chdir( serverdir ) == -1) fatal_perror( "chdir to %s", serverdir );
841
    }
842 843

    /* make sure we are at the right place */
844 845 846 847
    if (stat( ".", &st ) == -1) fatal_perror( "stat %s", serverdir );
    if (st.st_uid != getuid()) fatal_error( "'%s' is not owned by you\n", serverdir );
    if (st.st_mode & 077) fatal_error( "'%s' must not be accessible by other users\n", serverdir );

848
    for (retry = 0; retry < 6; retry++)
849
    {
850 851 852 853
        /* if not the first try, wait a bit to leave the previous server time to exit */
        if (retry)
        {
            usleep( 100000 * retry * retry );
854
            start_server();
855 856 857
            if (lstat( SOCKETNAME, &st ) == -1) continue;  /* still no socket, wait a bit more */
        }
        else if (lstat( SOCKETNAME, &st ) == -1) /* check for an already existing socket */
858 859
        {
            if (errno != ENOENT) fatal_perror( "lstat %s/%s", serverdir, SOCKETNAME );
860
            start_server();
861
            if (lstat( SOCKETNAME, &st ) == -1) continue;  /* still no socket, wait a bit more */
862
        }
863

864 865
        /* make sure the socket is sane (ISFIFO needed for Solaris) */
        if (!S_ISSOCK(st.st_mode) && !S_ISFIFO(st.st_mode))
866 867 868
            fatal_error( "'%s/%s' is not a socket\n", serverdir, SOCKETNAME );
        if (st.st_uid != getuid())
            fatal_error( "'%s/%s' is not owned by you\n", serverdir, SOCKETNAME );
869

870 871 872 873
        /* try to connect to it */
        addr.sun_family = AF_UNIX;
        strcpy( addr.sun_path, SOCKETNAME );
        slen = sizeof(addr) - sizeof(addr.sun_path) + strlen(addr.sun_path) + 1;
874
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
875
        addr.sun_len = slen;
876
#endif
877
        if ((s = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
878 879
        if (connect( s, (struct sockaddr *)&addr, slen ) != -1)
        {
880 881 882 883 884 885
            /* switch back to the starting directory */
            if (fd_cwd != -1)
            {
                fchdir( fd_cwd );
                close( fd_cwd );
            }
886 887 888 889
            fcntl( s, F_SETFD, 1 ); /* set close on exec flag */
            return s;
        }
        close( s );
890
    }
891
    server_connect_error( serverdir );
892 893 894
}


895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937
#ifdef __APPLE__
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <servers/bootstrap.h>

/* send our task port to the server */
static void send_server_task_port(void)
{
    mach_port_t bootstrap_port, wineserver_port;
    kern_return_t kret;

    struct {
        mach_msg_header_t           header;
        mach_msg_body_t             body;
        mach_msg_port_descriptor_t  task_port;
    } msg;

    if (task_get_bootstrap_port(mach_task_self(), &bootstrap_port) != KERN_SUCCESS) return;

    kret = bootstrap_look_up(bootstrap_port, (char*)wine_get_server_dir(), &wineserver_port);
    if (kret != KERN_SUCCESS)
        fatal_error( "cannot find the server port: 0x%08x\n", kret );

    mach_port_deallocate(mach_task_self(), bootstrap_port);

    msg.header.msgh_bits        = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX;
    msg.header.msgh_size        = sizeof(msg);
    msg.header.msgh_remote_port = wineserver_port;
    msg.header.msgh_local_port  = MACH_PORT_NULL;

    msg.body.msgh_descriptor_count  = 1;
    msg.task_port.name              = mach_task_self();
    msg.task_port.disposition       = MACH_MSG_TYPE_COPY_SEND;
    msg.task_port.type              = MACH_MSG_PORT_DESCRIPTOR;

    kret = mach_msg_send(&msg.header);
    if (kret != KERN_SUCCESS)
        server_protocol_error( "mach_msg_send failed: 0x%08x\n", kret );

    mach_port_deallocate(mach_task_self(), wineserver_port);
}
#endif  /* __APPLE__ */

938 939 940 941 942 943 944 945 946

/***********************************************************************
 *           get_unix_tid
 *
 * Retrieve the Unix tid to use on the server side for the current thread.
 */
static int get_unix_tid(void)
{
    int ret = -1;
947 948
#ifdef linux
    ret = syscall( SYS_gettid );
949 950 951 952
#elif defined(__sun)
    ret = pthread_self();
#elif defined(__APPLE__)
    ret = mach_thread_self();
953
    mach_port_deallocate(mach_task_self(), ret);
954 955 956 957 958 959 960 961 962
#elif defined(__FreeBSD__)
    long lwpid;
    thr_self( &lwpid );
    ret = lwpid;
#endif
    return ret;
}


Alexandre Julliard's avatar
Alexandre Julliard committed
963
/***********************************************************************
964
 *           server_init_process
Alexandre Julliard's avatar
Alexandre Julliard committed
965
 *
966
 * Start the server and create the initial socket pair.
Alexandre Julliard's avatar
Alexandre Julliard committed
967
 */
968
void server_init_process(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
969
{
970
    obj_handle_t version;
971
    const char *env_socket = getenv( "WINESERVERSOCKET" );
972

973
    server_pid = -1;
974
    if (env_socket)
975
    {
976 977 978
        fd_socket = atoi( env_socket );
        if (fcntl( fd_socket, F_SETFD, 1 ) == -1)
            fatal_perror( "Bad server socket %d", fd_socket );
979
        unsetenv( "WINESERVERSOCKET" );
980
    }
981
    else fd_socket = server_connect();
982 983

    /* setup the signal mask */
984 985 986 987 988 989 990 991
    sigemptyset( &server_block_set );
    sigaddset( &server_block_set, SIGALRM );
    sigaddset( &server_block_set, SIGIO );
    sigaddset( &server_block_set, SIGINT );
    sigaddset( &server_block_set, SIGHUP );
    sigaddset( &server_block_set, SIGUSR1 );
    sigaddset( &server_block_set, SIGUSR2 );
    sigaddset( &server_block_set, SIGCHLD );
992
    pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
993

994
    /* receive the first thread request fd on the main socket */
995 996 997 998 999 1000 1001 1002 1003 1004 1005
#ifdef SO_PASSCRED
    if (server_pid == -1)
    {
        int enable = 1;
        setsockopt( fd_socket, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable) );
        ntdll_get_thread_data()->request_fd = receive_fd( &version );
        enable = 0;
        setsockopt( fd_socket, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable) );
    }
    else
#endif
1006
    ntdll_get_thread_data()->request_fd = receive_fd( &version );
1007

1008 1009 1010 1011 1012 1013 1014
    if (version != SERVER_PROTOCOL_VERSION)
        server_protocol_error( "version mismatch %d/%d.\n"
                               "Your %s binary was not upgraded correctly,\n"
                               "or you have an older one somewhere in your PATH.\n"
                               "Or maybe the wrong wineserver is still running?\n",
                               version, SERVER_PROTOCOL_VERSION,
                               (version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" );
1015 1016 1017
#ifdef __APPLE__
    send_server_task_port();
#endif
1018 1019 1020 1021
#if defined(__linux__) && defined(HAVE_PRCTL)
    /* work around Ubuntu's ptrace breakage */
    if (server_pid != -1) prctl( 0x59616d61 /* PR_SET_PTRACER */, server_pid );
#endif
Alexandre Julliard's avatar
Alexandre Julliard committed
1022 1023 1024
}


1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
/***********************************************************************
 *           server_init_process_done
 */
NTSTATUS server_init_process_done(void)
{
    PEB *peb = NtCurrentTeb()->Peb;
    IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
    NTSTATUS status;

    /* Install signal handlers; this cannot be done earlier, since we cannot
     * send exceptions to the debugger before the create process event that
     * is sent by REQ_INIT_PROCESS_DONE.
     * We do need the handlers in place by the time the request is over, so
     * we set them up here. If we segfault between here and the server call
     * something is very wrong... */
1040
    signal_init_process();
1041 1042 1043 1044

    /* Signal the parent process to continue */
    SERVER_START_REQ( init_process_done )
    {
1045 1046 1047 1048
        req->module   = wine_server_client_ptr( peb->ImageBaseAddress );
#ifdef __i386__
        req->ldt_copy = wine_server_client_ptr( &wine_ldt_copy );
#endif
1049
        req->entry    = wine_server_client_ptr( (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint );
1050
        req->gui      = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI);
1051 1052 1053 1054 1055 1056 1057 1058
        status = wine_server_call( req );
    }
    SERVER_END_REQ;

    return status;
}


1059
/***********************************************************************
1060
 *           server_init_thread
1061 1062 1063
 *
 * Send an init thread request. Return 0 if OK.
 */
1064
size_t server_init_thread( void *entry_point )
1065
{
1066
    static const int is_win64 = (sizeof(void *) > sizeof(int));
1067
    const char *arch = getenv( "WINEARCH" );
1068
    int ret;
1069
    int reply_pipe[2];
1070
    struct sigaction sig_act;
1071
    size_t info_size;
1072 1073 1074 1075

    sig_act.sa_handler = SIG_IGN;
    sig_act.sa_flags   = 0;
    sigemptyset( &sig_act.sa_mask );
1076

1077
    /* ignore SIGPIPE so that we get an EPIPE error instead  */
1078
    sigaction( SIGPIPE, &sig_act, NULL );
1079
    /* automatic child reaping to avoid zombies */
1080 1081 1082 1083
#ifdef SA_NOCLDWAIT
    sig_act.sa_flags |= SA_NOCLDWAIT;
#endif
    sigaction( SIGCHLD, &sig_act, NULL );
1084 1085

    /* create the server->client communication pipes */
1086 1087
    if (server_pipe( reply_pipe ) == -1) server_protocol_perror( "pipe" );
    if (server_pipe( ntdll_get_thread_data()->wait_fd ) == -1) server_protocol_perror( "pipe" );
1088
    wine_server_send_fd( reply_pipe[1] );
1089 1090
    wine_server_send_fd( ntdll_get_thread_data()->wait_fd[1] );
    ntdll_get_thread_data()->reply_fd = reply_pipe[0];
1091
    close( reply_pipe[1] );
1092

1093
    SERVER_START_REQ( init_thread )
1094
    {
1095 1096
        req->unix_pid    = getpid();
        req->unix_tid    = get_unix_tid();
1097
        req->teb         = wine_server_client_ptr( NtCurrentTeb() );
1098
        req->entry       = wine_server_client_ptr( entry_point );
1099
        req->reply_fd    = reply_pipe[1];
1100
        req->wait_fd     = ntdll_get_thread_data()->wait_fd[1];
1101
        req->debug_level = (TRACE_ON(server) != 0);
1102
        req->cpu         = client_cpu;
1103
        ret = wine_server_call( req );
1104 1105
        NtCurrentTeb()->ClientId.UniqueProcess = ULongToHandle(reply->pid);
        NtCurrentTeb()->ClientId.UniqueThread  = ULongToHandle(reply->tid);
1106 1107
        info_size         = reply->info_size;
        server_start_time = reply->server_start;
1108
        server_cpus       = reply->all_cpus;
1109 1110
    }
    SERVER_END_REQ;
1111

1112
    is_wow64 = !is_win64 && (server_cpus & (1 << CPU_x86_64)) != 0;
1113 1114
    ntdll_get_thread_data()->wow64_redir = is_wow64;

1115
    switch (ret)
1116
    {
1117
    case STATUS_SUCCESS:
1118 1119 1120 1121 1122
        if (arch)
        {
            if (!strcmp( arch, "win32" ) && (is_win64 || is_wow64))
                fatal_error( "WINEARCH set to win32 but '%s' is a 64-bit installation.\n",
                             wine_get_config_dir() );
1123
            if (!strcmp( arch, "win64" ) && !is_win64 && !is_wow64)
1124 1125 1126
                fatal_error( "WINEARCH set to win64 but '%s' is a 32-bit installation.\n",
                             wine_get_config_dir() );
        }
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138
        return info_size;
    case STATUS_NOT_REGISTRY_FILE:
        fatal_error( "'%s' is a 32-bit installation, it cannot support 64-bit applications.\n",
                     wine_get_config_dir() );
    case STATUS_NOT_SUPPORTED:
        if (is_win64)
            fatal_error( "wineserver is 32-bit, it cannot support 64-bit applications.\n" );
        else
            fatal_error( "'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.\n",
                         wine_get_config_dir() );
    default:
        server_protocol_error( "init_thread failed with status %x\n", ret );
1139
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
1140
}