Пример #1
0
static inline BOOL find_next_hook(DWORD event, HWND hwnd, LONG object_id,
                                  LONG child_id, struct hook_info *info)
{
    BOOL ret;

    SERVER_START_REQ( get_hook_info )
    {
        req->handle = wine_server_user_handle( info->handle );
        req->get_next = 1;
        req->event = event;
        req->window = wine_server_user_handle( hwnd );
        req->object_id = object_id;
        req->child_id = child_id;
        wine_server_set_reply( req, info->module, sizeof(info->module)-sizeof(WCHAR) );
        ret = !wine_server_call( req );
        if (ret)
        {
            info->module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
            info->handle    = wine_server_ptr_handle( reply->handle );
            info->proc      = wine_server_get_ptr( reply->proc );
            info->tid       = reply->tid;
        }
    }
    SERVER_END_REQ;
    return ret;
}
Пример #2
0
/******************************************************************************
 *              NtTerminateThread  (NTDLL.@)
 *              ZwTerminateThread  (NTDLL.@)
 */
NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code )
{
    NTSTATUS ret;
    BOOL self;

    SERVER_START_REQ( terminate_thread )
    {
        req->handle    = wine_server_obj_handle( handle );
        req->exit_code = exit_code;
        ret = wine_server_call( req );
        self = !ret && reply->self;
    }
    SERVER_END_REQ;

#ifdef CONFIG_UNIFIED_KERNEL
    if (self)
    {
        server_kill_thread( exit_code );
        abort_thread( exit_code );
    }
#else
    if (self) abort_thread( exit_code );
#endif
    return ret;
}
Пример #3
0
/***********************************************************************
 *           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... */
    if (!SIGNAL_Init()) exit(1);

    /* Signal the parent process to continue */
    SERVER_START_REQ( init_process_done )
    {
        req->module = peb->ImageBaseAddress;
        req->entry  = (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint;
        req->gui    = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI);
        status = wine_server_call( req );
    }
    SERVER_END_REQ;

    return status;
}
Пример #4
0
/*****************************************************************
 *               CARET_Callback
 */
static void CALLBACK CARET_Callback( HWND hwnd, UINT msg, UINT_PTR id, DWORD ctime)
{
    BOOL ret;
    RECT r;
    int old_state = 0;
    int hidden = 0;

    SERVER_START_REQ( set_caret_info )
    {
        req->flags  = SET_CARET_STATE;
        req->handle = hwnd;
        req->x      = 0;
        req->y      = 0;
        req->hide   = 0;
        req->state  = -1;  /* toggle current state */
        if ((ret = !wine_server_call( req )))
        {
            hwnd      = reply->full_handle;
            r.left    = reply->old_rect.left;
            r.top     = reply->old_rect.top;
            r.right   = reply->old_rect.right;
            r.bottom  = reply->old_rect.bottom;
            old_state = reply->old_state;
            hidden    = reply->old_hide;
        }
    }
    SERVER_END_REQ;

    if (ret && !hidden) CARET_DisplayCaret( hwnd, &r );
}
Пример #5
0
/******************************************************************************
 *  NtDuplicateToken		[NTDLL.@]
 *  ZwDuplicateToken		[NTDLL.@]
 */
NTSTATUS WINAPI NtDuplicateToken(
        IN HANDLE ExistingToken,
        IN ACCESS_MASK DesiredAccess,
        IN POBJECT_ATTRIBUTES ObjectAttributes,
        IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
        IN TOKEN_TYPE TokenType,
        OUT PHANDLE NewToken)
{
    NTSTATUS status;

    TRACE("(%p,0x%08lx,%p,0x%08x,0x%08x,%p)\n",
        ExistingToken, DesiredAccess, ObjectAttributes,
        ImpersonationLevel, TokenType, NewToken);
        dump_ObjectAttributes(ObjectAttributes);

    SERVER_START_REQ( duplicate_token )
    {
        req->handle              = ExistingToken;
        req->access              = DesiredAccess;
        req->attributes          = ObjectAttributes ? ObjectAttributes->Attributes : 0;
        req->primary             = (TokenType == TokenPrimary);
        req->impersonation_level = ImpersonationLevel;
        status = wine_server_call( req );
        if (!status) *NewToken = reply->new_handle;
    }
    SERVER_END_REQ;

    return status;
}
Пример #6
0
/***********************************************************************
 *              send_mouse_input
 *
 * Update the various window states on a mouse event.
 */
static void send_mouse_input(HWND hwnd, UINT flags, int x, int y,
                             DWORD mouse_data, unsigned long time)
{
    INPUT input;
    HWND top_level_hwnd;

    top_level_hwnd = GetAncestor(hwnd, GA_ROOT);

    if ((flags & MOUSEEVENTF_MOVE) && (flags & MOUSEEVENTF_ABSOLUTE))
    {
        RECT rect;

        /* update the wine server Z-order */
        SetRect(&rect, x, y, x + 1, y + 1);
        MapWindowPoints(0, top_level_hwnd, (POINT *)&rect, 2);

        SERVER_START_REQ(update_window_zorder)
        {
            req->window      = wine_server_user_handle(top_level_hwnd);
            req->rect.left   = rect.left;
            req->rect.top    = rect.top;
            req->rect.right  = rect.right;
            req->rect.bottom = rect.bottom;
            wine_server_call(req);
        }
        SERVER_END_REQ;
    }
Пример #7
0
/******************************************************************************
 *              EnumWindowStationsW  (USER32.@)
 */
BOOL WINAPI EnumWindowStationsW( WINSTAENUMPROCW func, LPARAM lparam )
{
    unsigned int index = 0;
    WCHAR name[MAX_PATH];
    BOOL ret = TRUE;
    NTSTATUS status;

    while (ret)
    {
        SERVER_START_REQ( enum_winstation )
        {
            req->index = index;
            wine_server_set_reply( req, name, sizeof(name) - sizeof(WCHAR) );
            status = wine_server_call( req );
            name[wine_server_reply_size(reply)/sizeof(WCHAR)] = 0;
            index = reply->next;
        }
        SERVER_END_REQ;
        if (status == STATUS_NO_MORE_ENTRIES)
            break;
        if (status)
        {
            SetLastError( RtlNtStatusToDosError( status ) );
            return FALSE;
        }
        ret = func( name, lparam );
    }
    return ret;
}
Пример #8
0
/***********************************************************************
 *              CreateDesktopW   (USER32.@)
 */
HDESK WINAPI CreateDesktopW( LPCWSTR name, LPCWSTR device, LPDEVMODEW devmode,
                             DWORD flags, ACCESS_MASK access, LPSECURITY_ATTRIBUTES sa )
{
    HANDLE ret;
    DWORD len = name ? strlenW(name) : 0;

    if (device || devmode)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return 0;
    }
    if (len >= MAX_PATH)
    {
        SetLastError( ERROR_FILENAME_EXCED_RANGE );
        return 0;
    }
    SERVER_START_REQ( create_desktop )
    {
        req->flags      = flags;
        req->access     = access;
        req->attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF |
                          ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0);
        wine_server_add_data( req, name, len * sizeof(WCHAR) );
        /* it doesn't seem to set last error */
        wine_server_call( req );
        ret = wine_server_ptr_handle( reply->handle );
    }
    SERVER_END_REQ;
    return ret;
}
Пример #9
0
/******************************************************************************
 *  NtOpenThreadToken		[NTDLL.@]
 *  ZwOpenThreadToken		[NTDLL.@]
 */
NTSTATUS WINAPI NtOpenThreadToken(
	HANDLE ThreadHandle,
	DWORD DesiredAccess,
	BOOLEAN OpenAsSelf,
	HANDLE *TokenHandle)
{
    NTSTATUS ret;

    TRACE("(%p,0x%08lx,0x%08x,%p)\n",
          ThreadHandle,DesiredAccess, OpenAsSelf, TokenHandle);

    SERVER_START_REQ( open_token )
    {
        req->handle     = ThreadHandle;
        req->access     = DesiredAccess;
        req->attributes = 0;
        req->flags      = OPEN_TOKEN_THREAD;
        if (OpenAsSelf) req->flags |= OPEN_TOKEN_AS_SELF;
        ret = wine_server_call( req );
        if (!ret) *TokenHandle = reply->token;
    }
    SERVER_END_REQ;

    return ret;
}
Пример #10
0
/***********************************************************************
 *              CreateWindowStationW  (USER32.@)
 */
HWINSTA WINAPI CreateWindowStationW( LPCWSTR name, DWORD reserved, ACCESS_MASK access,
                                     LPSECURITY_ATTRIBUTES sa )
{
    HANDLE ret;
    DWORD len = name ? strlenW(name) : 0;

    if (len >= MAX_PATH)
    {
        SetLastError( ERROR_FILENAME_EXCED_RANGE );
        return 0;
    }
    SERVER_START_REQ( create_winstation )
    {
        req->flags      = 0;
        req->access     = access;
        req->attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF |
                          ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0);
        wine_server_add_data( req, name, len * sizeof(WCHAR) );
        /* it doesn't seem to set last error */
        wine_server_call( req );
        ret = wine_server_ptr_handle( reply->handle );
    }
    SERVER_END_REQ;
    return ret;
}
Пример #11
0
static inline BOOL find_first_hook(DWORD id, DWORD event, HWND hwnd, LONG object_id,
                                   LONG child_id, struct hook_info *info)
{
    struct user_thread_info *thread_info = get_user_thread_info();
    BOOL ret;

    if (!HOOK_IsHooked( id ))
    {
        TRACE( "skipping hook %s mask %x\n", hook_names[id-WH_MINHOOK], thread_info->active_hooks );
        return FALSE;
    }

    SERVER_START_REQ( start_hook_chain )
    {
        req->id = id;
        req->event = event;
        req->window = wine_server_user_handle( hwnd );
        req->object_id = object_id;
        req->child_id = child_id;
        wine_server_set_reply( req, info->module, sizeof(info->module)-sizeof(WCHAR) );
        ret = !wine_server_call( req );
        if (ret)
        {
            info->module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
            info->handle    = wine_server_ptr_handle( reply->handle );
            info->proc      = wine_server_get_ptr( reply->proc );
            info->tid       = reply->tid;
            thread_info->active_hooks = reply->active_hooks;
        }
    }
    SERVER_END_REQ;
    return ret && (info->tid || info->proc);
}
Пример #12
0
/***********************************************************************
 *		HOOK_CallHooks
 */
LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode )
{
    struct user_thread_info *thread_info = get_user_thread_info();
    struct hook_info info;
    DWORD_PTR ret = 0;

    USER_CheckNotLock();

    if (!HOOK_IsHooked( id ))
    {
        TRACE( "skipping hook %s mask %x\n", hook_names[id-WH_MINHOOK], thread_info->active_hooks );
        return 0;
    }

    ZeroMemory( &info, sizeof(info) - sizeof(info.module) );
    info.prev_unicode = unicode;
    info.id = id;

    SERVER_START_REQ( start_hook_chain )
    {
        req->id = info.id;
        req->event = EVENT_MIN;
        wine_server_set_reply( req, info.module, sizeof(info.module)-sizeof(WCHAR) );
        if (!wine_server_call( req ))
        {
            info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
            info.handle       = wine_server_ptr_handle( reply->handle );
            info.pid          = reply->pid;
            info.tid          = reply->tid;
            info.proc         = wine_server_get_ptr( reply->proc );
            info.next_unicode = reply->unicode;
            thread_info->active_hooks = reply->active_hooks;
        }
    }
    SERVER_END_REQ;

    if (!info.tid && !info.proc) return 0;
    ret = call_hook( &info, code, wparam, lparam );

    SERVER_START_REQ( finish_hook_chain )
    {
        req->id = id;
        wine_server_call( req );
    }
    SERVER_END_REQ;
    return ret;
}
Пример #13
0
/***********************************************************************
 *		send_mouse_input
 *
 * Update the various window states on a mouse event.
 */
static void send_mouse_input( HWND hwnd, UINT flags, Window window, int x, int y,
                              unsigned int state, DWORD mouse_data, Time time )
{
    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
    POINT pt;
    INPUT input;

    if (!data) return;

    if (window == data->whole_window)
    {
        x += data->whole_rect.left - data->client_rect.left;
        y += data->whole_rect.top - data->client_rect.top;
    }
    if (window == root_window)
    {
        x += virtual_screen_rect.left;
        y += virtual_screen_rect.top;
    }
    pt.x = x;
    pt.y = y;
    if (GetWindowLongW( data->hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL)
        pt.x = data->client_rect.right - data->client_rect.left - 1 - pt.x;
    MapWindowPoints( hwnd, 0, &pt, 1 );

    if (InterlockedExchangePointer( (void **)&cursor_window, hwnd ) != hwnd ||
        GetTickCount() - last_time_modified > 100)
    {
        cursor_window = hwnd;
        sync_window_cursor( data );
    }
    last_time_modified = GetTickCount();

    if (hwnd != GetDesktopWindow()) hwnd = GetAncestor( hwnd, GA_ROOT );

    /* update the wine server Z-order */

    if (window != x11drv_thread_data()->grab_window &&
        /* ignore event if a button is pressed, since the mouse is then grabbed too */
        !(state & (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask|Button6Mask|Button7Mask)))
    {
        RECT rect;
        SetRect( &rect, pt.x, pt.y, pt.x + 1, pt.y + 1 );
        MapWindowPoints( 0, hwnd, (POINT *)&rect, 2 );

        SERVER_START_REQ( update_window_zorder )
        {
            req->window      = wine_server_user_handle( hwnd );
            req->rect.left   = rect.left;
            req->rect.top    = rect.top;
            req->rect.right  = rect.right;
            req->rect.bottom = rect.bottom;
            wine_server_call( req );
        }
        SERVER_END_REQ;
    }
Пример #14
0
/***********************************************************************
 *           __wine_make_process_system   (NTDLL.@)
 *
 * Mark the current process as a system process.
 * Returns the event that is signaled when all non-system processes have exited.
 */
HANDLE CDECL __wine_make_process_system(void)
{
    HANDLE ret = 0;
    SERVER_START_REQ( make_process_system )
    {
        if (!wine_server_call( req )) ret = wine_server_ptr_handle( reply->event );
    }
    SERVER_END_REQ;
    return ret;
}
Пример #15
0
/***********************************************************************
 *           exit_thread
 */
void exit_thread( int status )
{
    static void *prev_teb;
    shmlocal_t *shmlocal;
    sigset_t sigset;
    TEB *teb;

    if (status)  /* send the exit code to the server (0 is already the default) */
    {
        SERVER_START_REQ( terminate_thread )
        {
            req->handle    = wine_server_obj_handle( GetCurrentThread() );
            req->exit_code = status;
            wine_server_call( req );
        }
        SERVER_END_REQ;
    }

    if (interlocked_xchg_add( &nb_threads, 0 ) <= 1)
    {
        LdrShutdownProcess();
        exit( status );
    }

    LdrShutdownThread();
    RtlFreeThreadActivationContextStack();

    shmlocal = interlocked_xchg_ptr( &NtCurrentTeb()->Reserved5[2], NULL );
    if (shmlocal) NtUnmapViewOfSection( NtCurrentProcess(), shmlocal );

    pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );

    if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() )))
    {
        struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;

        if (thread_data->pthread_id)
        {
            pthread_join( thread_data->pthread_id, NULL );
            signal_free_thread( teb );
        }
    }

    sigemptyset( &sigset );
    sigaddset( &sigset, SIGQUIT );
    pthread_sigmask( SIG_BLOCK, &sigset, NULL );
    if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) _exit( status );

    close( ntdll_get_thread_data()->wait_fd[0] );
    close( ntdll_get_thread_data()->wait_fd[1] );
    close( ntdll_get_thread_data()->reply_fd );
    close( ntdll_get_thread_data()->request_fd );
    pthread_exit( UIntToPtr(status) );
}
Пример #16
0
static DWORD DEVICE_GetClientID( HANDLE handle )
{
    DWORD       ret = 0;
    SERVER_START_REQ( get_file_info )
    {
        req->handle = handle;
        if (!wine_server_call( req ) && (reply->type == FILE_TYPE_UNKNOWN))
            ret = reply->attr;
    }
    SERVER_END_REQ;
    return ret;
}
Пример #17
0
/**************************************************************************
 *                 NtClose				[NTDLL.@]
 * FUNCTION: Closes a handle reference to an object
 * ARGUMENTS:
 *	Handle	handle to close
 */
NTSTATUS WINAPI NtClose( HANDLE Handle )
{
    NTSTATUS ret;
    SERVER_START_REQ( close_handle )
    {
        req->handle = Handle;
        ret = wine_server_call( req );
        if (!ret && reply->fd != -1) close( reply->fd );
    }
    SERVER_END_REQ;
    return ret;
}
Пример #18
0
/******************************************************************************
 *              NtResumeThread   (NTDLL.@)
 *              ZwResumeThread   (NTDLL.@)
 */
NTSTATUS WINAPI NtResumeThread( HANDLE handle, PULONG count )
{
    NTSTATUS ret;

    SERVER_START_REQ( resume_thread )
    {
        req->handle = wine_server_obj_handle( handle );
        if (!(ret = wine_server_call( req ))) *count = reply->count;
    }
    SERVER_END_REQ;
    return ret;
}
Пример #19
0
/***********************************************************************
 *           server_init_thread
 *
 * Send an init thread request. Return 0 if OK.
 */
size_t server_init_thread( int unix_pid, int unix_tid, void *entry_point )
{
    int ret;
    int reply_pipe[2];
    struct sigaction sig_act;
    size_t info_size;

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

    /* ignore SIGPIPE so that we get an EPIPE error instead  */
    sigaction( SIGPIPE, &sig_act, NULL );
    /* automatic child reaping to avoid zombies */
#ifdef SA_NOCLDWAIT
    sig_act.sa_flags |= SA_NOCLDWAIT;
#endif
    sigaction( SIGCHLD, &sig_act, NULL );

    /* create the server->client communication pipes */
    if (pipe( reply_pipe ) == -1) server_protocol_perror( "pipe" );
    if (pipe( ntdll_get_thread_data()->wait_fd ) == -1) server_protocol_perror( "pipe" );
    wine_server_send_fd( reply_pipe[1] );
    wine_server_send_fd( ntdll_get_thread_data()->wait_fd[1] );
    ntdll_get_thread_data()->reply_fd = reply_pipe[0];
    close( reply_pipe[1] );

    /* set close on exec flag */
    fcntl( ntdll_get_thread_data()->reply_fd, F_SETFD, 1 );
    fcntl( ntdll_get_thread_data()->wait_fd[0], F_SETFD, 1 );
    fcntl( ntdll_get_thread_data()->wait_fd[1], F_SETFD, 1 );

    SERVER_START_REQ( init_thread )
    {
        req->unix_pid    = unix_pid;
        req->unix_tid    = unix_tid;
        req->teb         = wine_server_client_ptr( NtCurrentTeb() );
        req->peb         = wine_server_client_ptr( NtCurrentTeb()->Peb );
        req->entry       = wine_server_client_ptr( entry_point );
        req->reply_fd    = reply_pipe[1];
        req->wait_fd     = ntdll_get_thread_data()->wait_fd[1];
        req->debug_level = (TRACE_ON(server) != 0);
        ret = wine_server_call( req );
        NtCurrentTeb()->ClientId.UniqueProcess = ULongToHandle(reply->pid);
        NtCurrentTeb()->ClientId.UniqueThread  = ULongToHandle(reply->tid);
        info_size         = reply->info_size;
        server_start_time = reply->server_start;
    }
    SERVER_END_REQ;

    if (ret) server_protocol_error( "init_thread failed with status %x\n", ret );
    return info_size;
}
Пример #20
0
static NTSTATUS get_wait_mask(HANDLE hDevice, DWORD* mask)
{
    NTSTATUS    status;

    SERVER_START_REQ( get_serial_info )
    {
        req->handle = wine_server_obj_handle( hDevice );
        if (!(status = wine_server_call( req )))
            *mask = reply->eventmask;
    }
    SERVER_END_REQ;
    return status;
}
Пример #21
0
static void stop_waiting( HANDLE handle )
{
    NTSTATUS status;

    SERVER_START_REQ( set_serial_info )
    {
        req->handle = wine_server_obj_handle( handle );
        req->flags = SERIALINFO_PENDING_WAIT;
        if ((status = wine_server_call( req )))
            ERR("failed to clear waiting state: %#x\n", status);
    }
    SERVER_END_REQ;
}
Пример #22
0
static NTSTATUS set_wait_mask(HANDLE hDevice, DWORD mask)
{
    NTSTATUS status;

    SERVER_START_REQ( set_serial_info )
    {
        req->handle    = wine_server_obj_handle( hDevice );
        req->flags     = SERIALINFO_SET_MASK;
        req->eventmask = mask;
        status = wine_server_call( req );
    }
    SERVER_END_REQ;
    return status;
}
Пример #23
0
/**********************************************************************
 *		GetKeyState (USER32.@)
 *
 * An application calls the GetKeyState function in response to a
 * keyboard-input message.  This function retrieves the state of the key
 * at the time the input message was generated.
 */
SHORT WINAPI DECLSPEC_HOTPATCH GetKeyState(INT vkey)
{
    SHORT retval = 0;

    SERVER_START_REQ( get_key_state )
    {
        req->tid = GetCurrentThreadId();
        req->key = vkey;
        if (!wine_server_call( req )) retval = (signed char)reply->state;
    }
    SERVER_END_REQ;
    TRACE("key (0x%x) -> %x\n", vkey, retval);
    return retval;
}
Пример #24
0
/**************************************************************************
 *		CLIPBOARD_OpenClipboard
 */
static BOOL CLIPBOARD_OpenClipboard(HWND hWnd)
{
    BOOL bRet;

    SERVER_START_REQ( set_clipboard_info )
    {
        req->flags = SET_CB_OPEN;
        req->clipboard = wine_server_user_handle( hWnd );
        bRet = !wine_server_call( req );
    }
    SERVER_END_REQ;

    return bRet;
}
Пример #25
0
/***********************************************************************
 *              sync_window_cursor
 */
void sync_window_cursor( struct x11drv_win_data *data )
{
    HCURSOR cursor;

    SERVER_START_REQ( set_cursor )
    {
        req->flags = 0;
        wine_server_call( req );
        cursor = reply->prev_count >= 0 ? wine_server_ptr_handle( reply->prev_handle ) : 0;
    }
    SERVER_END_REQ;

    if (data->cursor != cursor) set_window_cursor( data, cursor );
}
Пример #26
0
/***********************************************************************
 *           exit_thread
 */
void exit_thread( int status )
{
    static void *prev_teb;
    TEB *teb;

    if (status)  /* send the exit code to the server (0 is already the default) */
    {
        SERVER_START_REQ( terminate_thread )
        {
            req->handle    = wine_server_obj_handle( GetCurrentThread() );
            req->exit_code = status;
            wine_server_call( req );
        }
        SERVER_END_REQ;
    }

    if (interlocked_xchg_add( &nb_threads, -1 ) <= 1)
    {
        LdrShutdownProcess();
#ifdef CONFIG_UNIFIED_KERNEL
        server_kill_thread( status );
#endif
        exit( status );
    }

    LdrShutdownThread();

    pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );

    if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() )))
    {
        struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;

        if (thread_data->pthread_id)
        {
            pthread_join( thread_data->pthread_id, NULL );
            signal_free_thread( teb );
        }
    }

    close( ntdll_get_thread_data()->wait_fd[0] );
    close( ntdll_get_thread_data()->wait_fd[1] );
    close( ntdll_get_thread_data()->reply_fd );
    close( ntdll_get_thread_data()->request_fd );
#ifdef CONFIG_UNIFIED_KERNEL
    server_kill_thread( status );
#endif
    pthread_exit( UIntToPtr(status) );
}
Пример #27
0
/******************************************************************************
 *  NtTerminateProcess			[NTDLL.@]
 *
 *  Native applications must kill themselves when done
 */
NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code )
{
    NTSTATUS ret;
    BOOL self;
    SERVER_START_REQ( terminate_process )
    {
        req->handle    = wine_server_obj_handle( handle );
        req->exit_code = exit_code;
        ret = wine_server_call( req );
        self = !ret && reply->self;
    }
    SERVER_END_REQ;
    if (self && handle) _exit( exit_code );
    return ret;
}
Пример #28
0
/***********************************************************************
 *           exit_thread
 */
void exit_thread( int status )
{
    static void *prev_teb;
    TEB *teb;

    if (status)  /* send the exit code to the server (0 is already the default) */
    {
        SERVER_START_REQ( terminate_thread )
        {
            req->handle    = wine_server_obj_handle( GetCurrentThread() );
            req->exit_code = status;
            wine_server_call( req );
        }
        SERVER_END_REQ;
    }

    if (interlocked_xchg_add( &nb_threads, -1 ) <= 1)
    {
        LdrShutdownProcess();
        exit( status );
    }

    LdrShutdownThread();
    RtlAcquirePebLock();
    RemoveEntryList( &NtCurrentTeb()->TlsLinks );
    RtlReleasePebLock();
    RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->FlsSlots );
    RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->TlsExpansionSlots );

    pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );

    if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() )))
    {
        struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;

        if (thread_data->pthread_id)
        {
            pthread_join( thread_data->pthread_id, NULL );
            signal_free_thread( teb );
        }
    }

    close( ntdll_get_thread_data()->wait_fd[0] );
    close( ntdll_get_thread_data()->wait_fd[1] );
    close( ntdll_get_thread_data()->reply_fd );
    close( ntdll_get_thread_data()->request_fd );
    pthread_exit( UIntToPtr(status) );
}
Пример #29
0
/***********************************************************************
 *		GetInputState   (USER32.@)
 */
BOOL WINAPI GetInputState(void)
{
    DWORD ret = 0;

    /* check for pending X events */
    USER_Driver->pMsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_INPUT, 0 );

    SERVER_START_REQ( get_queue_status )
    {
        req->clear = 0;
        wine_server_call( req );
        ret = reply->wake_bits & (QS_KEY | QS_MOUSEBUTTON);
    }
    SERVER_END_REQ;
    return ret;
}
Пример #30
0
/***********************************************************************
 *              NtOpenThread   (NTDLL.@)
 *              ZwOpenThread   (NTDLL.@)
 */
NTSTATUS WINAPI NtOpenThread( HANDLE *handle, ACCESS_MASK access,
                              const OBJECT_ATTRIBUTES *attr, const CLIENT_ID *id )
{
    NTSTATUS ret;

    SERVER_START_REQ( open_thread )
    {
        req->tid        = HandleToULong(id->UniqueThread);
        req->access     = access;
        req->attributes = attr ? attr->Attributes : 0;
        ret = wine_server_call( req );
        *handle = wine_server_ptr_handle( reply->handle );
    }
    SERVER_END_REQ;
    return ret;
}