/********************************************************************** * set_capture_window */ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) { HWND previous = 0; UINT flags = 0; BOOL ret; if (gui_flags & GUI_INMENUMODE) flags |= CAPTURE_MENU; if (gui_flags & GUI_INMOVESIZE) flags |= CAPTURE_MOVESIZE; SERVER_START_REQ( set_capture_window ) { req->handle = wine_server_user_handle( hwnd ); req->flags = flags; if ((ret = !wine_server_call_err( req ))) { previous = wine_server_ptr_handle( reply->previous ); hwnd = wine_server_ptr_handle( reply->full_handle ); } } SERVER_END_REQ; if (ret) { USER_Driver->pSetCapture( hwnd, gui_flags ); if (previous && previous != hwnd) SendMessageW( previous, WM_CAPTURECHANGED, 0, (LPARAM)hwnd ); if (prev_ret) *prev_ret = previous; } return ret; }
/***************************************************************** * GetFocus (USER32.@) */ HWND WINAPI GetFocus(void) { shmlocal_t *shm = wine_get_shmlocal(); HWND ret = 0; if (shm) return wine_server_ptr_handle( shm->input_focus ); SERVER_START_REQ( get_thread_input ) { req->tid = GetCurrentThreadId(); if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->focus ); } SERVER_END_REQ; return ret; }
/***************************************************************** * HideCaret (USER32.@) */ BOOL WINAPI HideCaret( HWND hwnd ) { BOOL ret; RECT r; int old_state = 0; int hidden = 0; SERVER_START_REQ( set_caret_info ) { req->flags = SET_CARET_HIDE|SET_CARET_STATE; req->handle = wine_server_user_handle( hwnd ); req->x = 0; req->y = 0; req->hide = 1; req->state = 0; if ((ret = !wine_server_call_err( req ))) { hwnd = wine_server_ptr_handle( 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) { if (old_state) CARET_DisplayCaret( hwnd, &r ); KillSystemTimer( hwnd, TIMERID ); } return ret; }
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; }
/***************************************************************** * set_focus_window * * Change the focus window, sending the WM_SETFOCUS and WM_KILLFOCUS messages */ static HWND set_focus_window( HWND hwnd ) { HWND previous = 0; BOOL ret; SERVER_START_REQ( set_focus_window ) { req->handle = wine_server_user_handle( hwnd ); if ((ret = !wine_server_call_err( req ))) previous = wine_server_ptr_handle( reply->previous ); } SERVER_END_REQ; if (!ret) return 0; if (previous == hwnd) return previous; if (previous) { SendMessageW( previous, WM_KILLFOCUS, (WPARAM)hwnd, 0 ); if (hwnd != GetFocus()) return previous; /* changed by the message */ } if (IsWindow(hwnd)) { USER_Driver->pSetFocus(hwnd); SendMessageW( hwnd, WM_SETFOCUS, (WPARAM)previous, 0 ); } return previous; }
/*********************************************************************** * CreateWindowStationW (USER32.@) */ HWINSTA WINAPI CreateWindowStationW( LPCWSTR name, DWORD flags, 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 | ((flags & CWF_CREATE_ONLY) ? 0 : OBJ_OPENIF) | ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0); req->rootdir = wine_server_obj_handle( get_winstations_dir_handle() ); wine_server_add_data( req, name, len * sizeof(WCHAR) ); wine_server_call_err( req ); ret = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return ret; }
/******************************************************************* * GetForegroundWindow (USER32.@) */ HWND WINAPI GetForegroundWindow(void) { struct user_thread_info *thread_info = get_user_thread_info(); shmglobal_t *shm = wine_get_shmglobal(); HWND ret = 0; DWORD epoch; if (shm) { epoch = shm->foreground_wnd_epoch; if (epoch == thread_info->foreground_wnd_epoch) return thread_info->foreground_wnd; } SERVER_START_REQ( get_thread_input ) { req->tid = 0; if (!wine_server_call_err( req )) { ret = wine_server_ptr_handle( reply->foreground ); if (shm) { thread_info->foreground_wnd = ret; thread_info->foreground_wnd_epoch = epoch; } } } SERVER_END_REQ; return ret; }
/******************************************************************* * set_foreground_window */ static BOOL set_foreground_window( HWND hwnd, BOOL mouse ) { BOOL ret, send_msg_old = FALSE, send_msg_new = FALSE; HWND previous = 0; SERVER_START_REQ( set_foreground_window ) { req->handle = wine_server_user_handle( hwnd ); if ((ret = !wine_server_call_err( req ))) { previous = wine_server_ptr_handle( reply->previous ); send_msg_old = reply->send_msg_old; send_msg_new = reply->send_msg_new; } } SERVER_END_REQ; if (ret && previous != hwnd) { if (send_msg_old) /* old window belongs to other thread */ SendNotifyMessageW( previous, WM_WINE_SETACTIVEWINDOW, 0, 0 ); else if (send_msg_new) /* old window belongs to us but new one to other thread */ ret = set_active_window( 0, NULL, mouse, TRUE ); if (send_msg_new) /* new window belongs to other thread */ SendNotifyMessageW( hwnd, WM_WINE_SETACTIVEWINDOW, (WPARAM)hwnd, 0 ); else /* new window belongs to us */ ret = set_active_window( hwnd, NULL, mouse, TRUE ); } return ret; }
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); }
LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) { struct hook_info info; ZeroMemory( &info, sizeof(info) - sizeof(info.module) ); SERVER_START_REQ( get_hook_info ) { req->handle = wine_server_user_handle( hhook ); req->get_next = 0; req->event = EVENT_MIN; wine_server_set_reply( req, info.module, sizeof(info.module)-sizeof(WCHAR) ); if (!wine_server_call_err( req )) { info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0; info.handle = wine_server_ptr_handle( reply->handle ); info.id = reply->id; info.pid = reply->pid; info.tid = reply->tid; info.proc = wine_server_get_ptr( reply->proc ); info.next_unicode = reply->unicode; } } SERVER_END_REQ; info.prev_unicode = TRUE; /* assume Unicode for this function */ return call_hook( &info, code, wparam, lparam ); }
/*********************************************************************** * 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; }
/***************************************************************** * ShowCaret (USER32.@) */ BOOL WINAPI ShowCaret( HWND hwnd ) { BOOL ret; RECT r; int hidden = 0; SERVER_START_REQ( set_caret_info ) { req->flags = SET_CARET_HIDE|SET_CARET_STATE; req->handle = wine_server_user_handle( hwnd ); req->x = 0; req->y = 0; req->hide = -1; req->state = 1; if ((ret = !wine_server_call_err( req ))) { hwnd = wine_server_ptr_handle( 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; hidden = reply->old_hide; } } SERVER_END_REQ; if (ret && (hidden == 1)) /* hidden was 1 so it's now 0 */ { CARET_DisplayCaret( hwnd, &r ); SetSystemTimer( hwnd, TIMERID, Caret.timeout, CARET_Callback ); } return ret; }
/*********************************************************************** * 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; }
/*********************************************************************** * SetWinEventHook [USER32.@] * * Set up an event hook for a set of events. * * PARAMS * event_min [I] Lowest event handled by pfnProc * event_max [I] Highest event handled by pfnProc * inst [I] DLL containing pfnProc * proc [I] Callback event hook function * pid [I] Process to get events from, or 0 for all processes * tid [I] Thread to get events from, or 0 for all threads * flags [I] Flags indicating the status of pfnProc * * RETURNS * Success: A handle representing the hook. * Failure: A NULL handle. */ HWINEVENTHOOK WINAPI SetWinEventHook(DWORD event_min, DWORD event_max, HMODULE inst, WINEVENTPROC proc, DWORD pid, DWORD tid, DWORD flags) { HWINEVENTHOOK handle = 0; WCHAR module[MAX_PATH]; DWORD len; TRACE("%d,%d,%p,%p,%08x,%04x,%08x\n", event_min, event_max, inst, proc, pid, tid, flags); if (inst) { if (!(len = GetModuleFileNameW(inst, module, MAX_PATH)) || len >= MAX_PATH) inst = 0; } if ((flags & WINEVENT_INCONTEXT) && !inst) { SetLastError(ERROR_HOOK_NEEDS_HMOD); return 0; } if (event_min > event_max) { SetLastError(ERROR_INVALID_HOOK_FILTER); return 0; } /* FIXME: what if the tid or pid belongs to another process? */ if (tid) /* thread-local hook */ inst = 0; SERVER_START_REQ( set_hook ) { req->id = WH_WINEVENT; req->pid = pid; req->tid = tid; req->event_min = event_min; req->event_max = event_max; req->flags = flags; req->unicode = 1; if (inst) /* make proc relative to the module base */ { req->proc = wine_server_client_ptr( (void *)((char *)proc - (char *)inst) ); wine_server_add_data( req, module, strlenW(module) * sizeof(WCHAR) ); } else req->proc = wine_server_client_ptr( proc ); if (!wine_server_call_err( req )) { handle = wine_server_ptr_handle( reply->handle ); get_user_thread_info()->active_hooks = reply->active_hooks; } } SERVER_END_REQ; TRACE("-> %p\n", handle); return handle; }
/*********************************************************************** * CallNextHookEx (USER32.@) */ LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) { struct user_thread_info *thread_info = get_user_thread_info(); struct hook_info info; ZeroMemory( &info, sizeof(info) - sizeof(info.module) ); SERVER_START_REQ( get_hook_info ) { req->handle = wine_server_user_handle( thread_info->hook ); req->get_next = 1; req->event = EVENT_MIN; wine_server_set_reply( req, info.module, sizeof(info.module)-sizeof(WCHAR) ); if (!wine_server_call_err( req )) { info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0; info.handle = wine_server_ptr_handle( reply->handle ); info.id = reply->id; info.pid = reply->pid; info.tid = reply->tid; info.proc = wine_server_get_ptr( reply->proc ); info.next_unicode = reply->unicode; } } SERVER_END_REQ; info.prev_unicode = thread_info->hook_unicode; return call_hook( &info, code, wparam, lparam ); }
/***************************************************************** * CARET_Callback */ static void CALLBACK CARET_Callback( HWND hwnd, UINT msg, UINT_PTR id, DWORD ctime) { BOOL ret; RECT r; int hidden = 0; SERVER_START_REQ( set_caret_info ) { req->flags = SET_CARET_STATE; req->handle = wine_server_user_handle( hwnd ); req->x = 0; req->y = 0; req->hide = 0; req->state = -1; /* toggle current state */ if ((ret = !wine_server_call( req ))) { hwnd = wine_server_ptr_handle( 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; hidden = reply->old_hide; } } SERVER_END_REQ; if (ret && !hidden) CARET_DisplayCaret( hwnd, &r ); }
/*********************************************************************** * __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; }
/******************************************************************* * GetForegroundWindow (USER32.@) */ HWND WINAPI GetForegroundWindow(void) { HWND ret = 0; SERVER_START_REQ( get_thread_input ) { req->tid = 0; if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->foreground ); } SERVER_END_REQ; return ret; }
/****************************************************************************** * GetThreadDesktop (USER32.@) */ HDESK WINAPI GetThreadDesktop( DWORD thread ) { HDESK ret = 0; SERVER_START_REQ( get_thread_desktop ) { req->tid = thread; if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return ret; }
/****************************************************************************** * GetProcessWindowStation (USER32.@) */ HWINSTA WINAPI GetProcessWindowStation(void) { HWINSTA ret = 0; SERVER_START_REQ( get_process_winstation ) { if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return ret; }
/********************************************************************** * GetCapture (USER32.@) */ HWND WINAPI GetCapture(void) { HWND ret = 0; SERVER_START_REQ( get_thread_input ) { req->tid = GetCurrentThreadId(); if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->capture ); } SERVER_END_REQ; return ret; }
/************************************************************************** * CLIPBOARD_GetClipboardInfo */ static BOOL CLIPBOARD_GetClipboardInfo(LPCLIPBOARDINFO cbInfo) { BOOL bRet; SERVER_START_REQ( set_clipboard_info ) { req->flags = 0; if (((bRet = !wine_server_call_err( req )))) { cbInfo->hWndOpen = wine_server_ptr_handle( reply->old_clipboard ); cbInfo->hWndOwner = wine_server_ptr_handle( reply->old_owner ); cbInfo->hWndViewer = wine_server_ptr_handle( reply->old_viewer ); cbInfo->seqno = reply->seqno; cbInfo->flags = reply->flags; } } SERVER_END_REQ; return bRet; }
/******************************************************************* * GetShellWindow (USER32.@) */ HWND WINAPI GetShellWindow(void) { HWND hwndShell = 0; SERVER_START_REQ(set_global_windows) { req->flags = 0; if (!wine_server_call_err(req)) hwndShell = wine_server_ptr_handle( reply->old_shell_window ); } SERVER_END_REQ; return hwndShell; }
/*********************************************************************** * 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 ); }
/************************************************************************** * GetOpenClipboardWindow (USER32.@) */ HWND WINAPI GetOpenClipboardWindow(void) { HWND hWndOpen = 0; SERVER_START_REQ( set_clipboard_info ) { req->flags = 0; if (!wine_server_call_err( req )) hWndOpen = wine_server_ptr_handle( reply->old_clipboard ); } SERVER_END_REQ; TRACE(" hWndClipWindow(%p)\n", hWndOpen); return hWndOpen; }
/************************************************************************** * GetClipboardViewer (USER32.@) */ HWND WINAPI GetClipboardViewer(void) { HWND hWndViewer = 0; SERVER_START_REQ( set_clipboard_info ) { req->flags = 0; if (!wine_server_call_err( req )) hWndViewer = wine_server_ptr_handle( reply->old_viewer ); } SERVER_END_REQ; TRACE(" hWndViewer=%p\n", hWndViewer); return hWndViewer; }
/*********************************************************************** * 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; }
/*********************************************************************** * server_get_unix_fd * * The returned unix_fd should be closed iff needs_close is non-zero. */ int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd, int *needs_close, enum server_fd_type *type, unsigned int *options ) { sigset_t sigset; obj_handle_t fd_handle; int ret = 0, fd; unsigned int access = 0; *unix_fd = -1; *needs_close = 0; wanted_access &= FILE_READ_DATA | FILE_WRITE_DATA; server_enter_uninterrupted_section( &fd_cache_section, &sigset ); fd = get_cached_fd( handle, type, &access, options ); if (fd != -1) goto done; SERVER_START_REQ( get_handle_fd ) { req->handle = wine_server_obj_handle( handle ); if (!(ret = wine_server_call( req ))) { if (type) *type = reply->type; if (options) *options = reply->options; access = reply->access; if ((fd = receive_fd( &fd_handle )) != -1) { assert( wine_server_ptr_handle(fd_handle) == handle ); *needs_close = (reply->removable || !add_fd_to_cache( handle, fd, reply->type, reply->access, reply->options )); } else ret = STATUS_TOO_MANY_OPENED_FILES; } } SERVER_END_REQ; done: server_leave_uninterrupted_section( &fd_cache_section, &sigset ); if (!ret && ((access & wanted_access) != wanted_access)) { ret = STATUS_ACCESS_DENIED; if (*needs_close) close( fd ); } if (!ret) *unix_fd = fd; return ret; }
/*********************************************************************** * 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; }
/*********************************************************************** * wine_server_fd_to_handle (NTDLL.@) * * Allocate a file handle for a Unix file descriptor. * * PARAMS * fd [I] Unix file descriptor. * access [I] Win32 access flags. * attributes [I] Object attributes. * handle [O] Address where Wine file handle will be stored. * * RETURNS * NTSTATUS code */ int CDECL wine_server_fd_to_handle( int fd, unsigned int access, unsigned int attributes, HANDLE *handle ) { int ret; *handle = 0; wine_server_send_fd( fd ); SERVER_START_REQ( alloc_file_handle ) { req->access = access; req->attributes = attributes; req->fd = fd; if (!(ret = wine_server_call( req ))) *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return ret; }