/*********************************************************************** * DEFWND_SetTextA * * Set the window text. */ static void DEFWND_SetTextA( HWND hwnd, LPCSTR text ) { int count; WCHAR *textW; WND *wndPtr; if (!text) text = ""; count = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 ); if (!(wndPtr = WIN_GetPtr( hwnd ))) return; if ((textW = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR)))) { HeapFree(GetProcessHeap(), 0, wndPtr->text); wndPtr->text = textW; MultiByteToWideChar( CP_ACP, 0, text, -1, textW, count ); SERVER_START_REQ( set_window_text ) { req->handle = wine_server_user_handle( hwnd ); wine_server_add_data( req, textW, (count-1) * sizeof(WCHAR) ); wine_server_call( req ); } SERVER_END_REQ; }
/****************************************************************************** * NtPrivilegeCheck [NTDLL.@] * ZwPrivilegeCheck [NTDLL.@] */ NTSTATUS WINAPI NtPrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, PBOOLEAN Result) { NTSTATUS status; SERVER_START_REQ( check_token_privileges ) { req->handle = ClientToken; req->all_required = ((RequiredPrivileges->Control & PRIVILEGE_SET_ALL_NECESSARY) ? TRUE : FALSE); wine_server_add_data( req, &RequiredPrivileges->Privilege, RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) ); wine_server_set_reply( req, &RequiredPrivileges->Privilege, RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) ); status = wine_server_call( req ); if (status == STATUS_SUCCESS) *Result = (reply->has_privileges ? TRUE : FALSE); } SERVER_END_REQ; return status; }
/****************************************************************************** * NtAdjustPrivilegesToken [NTDLL.@] * ZwAdjustPrivilegesToken [NTDLL.@] * * FIXME: parameters unsafe */ NTSTATUS WINAPI NtAdjustPrivilegesToken( IN HANDLE TokenHandle, IN BOOLEAN DisableAllPrivileges, IN PTOKEN_PRIVILEGES NewState, IN DWORD BufferLength, OUT PTOKEN_PRIVILEGES PreviousState, OUT PDWORD ReturnLength) { NTSTATUS ret; TRACE("(%p,0x%08x,%p,0x%08lx,%p,%p)\n", TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength); SERVER_START_REQ( adjust_token_privileges ) { req->handle = TokenHandle; req->disable_all = DisableAllPrivileges; req->get_modified_state = (PreviousState != NULL); if (!DisableAllPrivileges) { wine_server_add_data( req, &NewState->Privileges, NewState->PrivilegeCount * sizeof(NewState->Privileges[0]) ); } if (PreviousState && BufferLength >= FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges )) wine_server_set_reply( req, &PreviousState->Privileges, BufferLength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) ); ret = wine_server_call( req ); if (PreviousState) { *ReturnLength = reply->len + FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ); PreviousState->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES); } } SERVER_END_REQ; return ret; }
/****************************************************************************** * WriteConsoleOutputCharacterW [KERNEL32.@] Copies character to consecutive * cells in the console screen buffer * * PARAMS * hConsoleOutput [I] Handle to screen buffer * str [I] Pointer to buffer with chars to write * length [I] Number of cells to write to * coord [I] Coords of first cell * lpNumCharsWritten [O] Pointer to number of cells written * * RETURNS * Success: TRUE * Failure: FALSE * */ BOOL WINAPI WriteConsoleOutputCharacterW( HANDLE hConsoleOutput, LPCWSTR str, DWORD length, COORD coord, LPDWORD lpNumCharsWritten ) { BOOL ret; TRACE("(%d,%s,%ld,%dx%d,%p)\n", hConsoleOutput, debugstr_wn(str, length), length, coord.X, coord.Y, lpNumCharsWritten); SERVER_START_REQ( write_console_output ) { req->handle = hConsoleOutput; req->x = coord.X; req->y = coord.Y; req->mode = CHAR_INFO_MODE_TEXT; req->wrap = TRUE; wine_server_add_data( req, str, length * sizeof(WCHAR) ); if ((ret = !wine_server_call_err( req ))) { if (lpNumCharsWritten) *lpNumCharsWritten = reply->written; } } SERVER_END_REQ; return ret; }
/*********************************************************************** * set_windows_hook * * Implementation of SetWindowsHookExA and SetWindowsHookExW. */ static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid, BOOL unicode ) { HHOOK handle = 0; WCHAR module[MAX_PATH]; DWORD len; if (!proc) { SetLastError( ERROR_INVALID_FILTER_PROC ); return 0; } if (tid) /* thread-local hook */ { if (id == WH_JOURNALRECORD || id == WH_JOURNALPLAYBACK || id == WH_KEYBOARD_LL || id == WH_MOUSE_LL || id == WH_SYSMSGFILTER) { /* these can only be global */ SetLastError( ERROR_INVALID_PARAMETER ); return 0; } } else /* system-global hook */ { if (id == WH_KEYBOARD_LL || id == WH_MOUSE_LL) inst = 0; else if (!inst) { SetLastError( ERROR_HOOK_NEEDS_HMOD ); return 0; } } if (inst && (!(len = GetModuleFileNameW( inst, module, MAX_PATH )) || len >= MAX_PATH)) { SetLastError( ERROR_INVALID_PARAMETER ); return 0; } SERVER_START_REQ( set_hook ) { req->id = id; req->pid = 0; req->tid = tid; req->event_min = EVENT_MIN; req->event_max = EVENT_MAX; req->flags = WINEVENT_INCONTEXT; req->unicode = unicode; 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( "%s %p %x -> %p\n", hook_names[id-WH_MINHOOK], proc, tid, handle ); return handle; }
/*********************************************************************** * NtSetContextThread (NTDLL.@) * ZwSetContextThread (NTDLL.@) */ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) { NTSTATUS ret; DWORD dummy, i; BOOL self = FALSE; #ifdef __i386__ /* on i386 debug registers always require a server call */ self = (handle == GetCurrentThread()); if (self && (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))) { self = (ntdll_get_thread_data()->dr0 == context->Dr0 && ntdll_get_thread_data()->dr1 == context->Dr1 && ntdll_get_thread_data()->dr2 == context->Dr2 && ntdll_get_thread_data()->dr3 == context->Dr3 && ntdll_get_thread_data()->dr6 == context->Dr6 && ntdll_get_thread_data()->dr7 == context->Dr7); } #endif if (!self) { context_t server_context; context_to_server( &server_context, context ); SERVER_START_REQ( set_thread_context ) { req->handle = wine_server_obj_handle( handle ); req->suspend = 1; wine_server_add_data( req, &server_context, sizeof(server_context) ); ret = wine_server_call( req ); self = reply->self; } SERVER_END_REQ; if (ret == STATUS_PENDING) { for (i = 0; i < 100; i++) { SERVER_START_REQ( set_thread_context ) { req->handle = wine_server_obj_handle( handle ); req->suspend = 0; wine_server_add_data( req, &server_context, sizeof(server_context) ); ret = wine_server_call( req ); } SERVER_END_REQ; if (ret == STATUS_PENDING) { LARGE_INTEGER timeout; timeout.QuadPart = -10000; NtDelayExecution( FALSE, &timeout ); } else break; } NtResumeThread( handle, &dummy ); if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED; } if (ret) return ret; }