ntdll/tests: Adjust test_virtual_unwind() for Win11 results.
[wine.git] / dlls / user32 / user_main.c
blobef2b94ba698e8910780a7a65e7b1068caffd15a7
1 /*
2 * USER initialization code
4 * Copyright 2000 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "user_private.h"
22 #include "controls.h"
23 #include "imm.h"
24 #include "immdev.h"
25 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(graphics);
29 WINE_DECLARE_DEBUG_CHANNEL(message);
31 HMODULE user32_module = 0;
33 extern void WDML_NotifyThreadDetach(void);
36 /***********************************************************************
37 * UserRealizePalette (USER32.@)
39 UINT WINAPI UserRealizePalette( HDC hdc )
41 return NtUserRealizePalette( hdc );
45 /***********************************************************************
46 * dpiaware_init
48 * Initialize the DPI awareness style.
50 static void dpiaware_init(void)
52 WCHAR buffer[256];
53 DWORD option;
55 if (!LdrQueryImageFileExecutionOptions( &NtCurrentTeb()->Peb->ProcessParameters->ImagePathName,
56 L"dpiAwareness", REG_DWORD, &option, sizeof(option), NULL ))
58 TRACE( "got option %lx\n", option );
59 if (option <= 2)
61 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~(ULONG_PTR)option );
62 return;
66 if (QueryActCtxSettingsW( 0, NULL, L"http://schemas.microsoft.com/SMI/2016/WindowsSettings",
67 L"dpiAwareness", buffer, ARRAY_SIZE(buffer), NULL ))
69 static const WCHAR * const types[] = { L"unaware", L"system", L"permonitor", L"permonitorv2" };
70 WCHAR *p, *start, *end;
71 ULONG_PTR i;
73 TRACE( "got dpiAwareness=%s\n", debugstr_w(buffer) );
74 for (start = buffer; *start; start = end)
76 start += wcsspn( start, L" \t\r\n" );
77 if (!(end = wcschr( start, ',' ))) end = start + lstrlenW(start);
78 else *end++ = 0;
79 if ((p = wcspbrk( start, L" \t\r\n" ))) *p = 0;
80 for (i = 0; i < ARRAY_SIZE(types); i++)
82 if (wcsicmp( start, types[i] )) continue;
83 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
84 return;
88 else if (QueryActCtxSettingsW( 0, NULL, L"http://schemas.microsoft.com/SMI/2005/WindowsSettings",
89 L"dpiAware", buffer, ARRAY_SIZE(buffer), NULL ))
91 TRACE( "got dpiAware=%s\n", debugstr_w(buffer) );
92 if (!wcsicmp( buffer, L"true" ))
93 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
94 else if (!wcsicmp( buffer, L"true/pm" ) || !wcsicmp( buffer, L"per monitor" ))
95 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
96 else
97 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
101 static NTSTATUS WINAPI User32CopyImage( const struct copy_image_params *params, ULONG size )
103 HANDLE ret = CopyImage( params->hwnd, params->type, params->dx, params->dy, params->flags );
104 return HandleToUlong( ret );
107 static NTSTATUS WINAPI User32DrawNonClientButton( const struct draw_non_client_button_params *params, ULONG size )
109 user_api->pNonClientButtonDraw( params->hwnd, params->hdc, params->type, params->rect,
110 params->down, params->grayed );
111 return 0;
114 static NTSTATUS WINAPI User32DrawScrollBar( const struct draw_scroll_bar_params *params, ULONG size )
116 RECT rect = params->rect;
117 user_api->pScrollBarDraw( params->hwnd, params->hdc, params->bar, params->hit_test,
118 &params->tracking_info, params->arrows, params->interior,
119 &rect, params->enable_flags, params->arrow_size, params->thumb_pos,
120 params->thumb_size, params->vertical );
121 return 0;
124 static NTSTATUS WINAPI User32DrawText( struct draw_text_params *params, ULONG size )
126 int ret;
128 size -= FIELD_OFFSET( struct draw_text_params, str );
129 ret = DrawTextW( params->hdc, params->str, size / sizeof(WCHAR), &params->rect, params->flags );
130 return NtCallbackReturn( &params->rect, sizeof(params->rect), ret );
133 static NTSTATUS WINAPI User32ImmProcessKey( const struct imm_process_key_params *params, ULONG size )
135 return ImmProcessKey( params->hwnd, params->hkl, params->vkey, params->key_data, 0 );
138 static NTSTATUS WINAPI User32ImmTranslateMessage( const struct imm_translate_message_params *params,
139 ULONG size )
141 return ImmTranslateMessage( params->hwnd, params->msg, params->wparam, params->key_data );
144 static NTSTATUS WINAPI User32LoadImage( const struct load_image_params *params, ULONG size )
146 HANDLE ret = LoadImageW( params->hinst, params->name, params->type,
147 params->dx, params->dy, params->flags );
148 return HandleToUlong( ret );
151 static NTSTATUS WINAPI User32LoadSysMenu( const struct load_sys_menu_params *params, ULONG size )
153 HMENU ret = LoadMenuW( user32_module, params->mdi ? L"SYSMENUMDI" : L"SYSMENU" );
154 return HandleToUlong( ret );
157 static NTSTATUS WINAPI User32FreeCachedClipboardData( const struct free_cached_data_params *params,
158 ULONG size )
160 free_cached_data( params->format, params->handle );
161 return 0;
164 static NTSTATUS WINAPI User32PostDDEMessage( const struct post_dde_message_params *params, ULONG size )
166 return post_dde_message( params->hwnd, params->msg, params->wparam, params->lparam,
167 params->dest_tid, params->type );
170 static NTSTATUS WINAPI User32RenderSsynthesizedFormat( const struct render_synthesized_format_params *params,
171 ULONG size )
173 render_synthesized_format( params->format, params->from );
174 return 0;
177 static BOOL WINAPI User32LoadDriver( const WCHAR *path, ULONG size )
179 return LoadLibraryW( path ) != NULL;
182 static NTSTATUS WINAPI User32UnpackDDEMessage( const struct unpack_dde_message_params *params, ULONG size )
184 struct unpack_dde_message_result result = { .wparam = params->wparam, .lparam = params->lparam };
186 size -= FIELD_OFFSET( struct unpack_dde_message_params, data );
187 if (!unpack_dde_message( params->hwnd, params->message, &result.wparam, &result.lparam,
188 params->data, size ))
189 return FALSE;
191 if (params->result) *params->result = result;
192 else NtCallbackReturn( &result, sizeof(result), TRUE );
193 return TRUE;
196 static const void *kernel_callback_table[NtUserCallCount] =
198 User32CallEnumDisplayMonitor,
199 User32CallSendAsyncCallback,
200 User32CallWinEventHook,
201 User32CallWindowProc,
202 User32CallWindowsHook,
203 User32CopyImage,
204 User32DrawNonClientButton,
205 User32DrawScrollBar,
206 User32DrawText,
207 User32FreeCachedClipboardData,
208 User32ImmProcessKey,
209 User32ImmTranslateMessage,
210 User32InitBuiltinClasses,
211 User32LoadDriver,
212 User32LoadImage,
213 User32LoadSysMenu,
214 User32PostDDEMessage,
215 User32RenderSsynthesizedFormat,
216 User32UnpackDDEMessage,
220 /***********************************************************************
221 * USER initialisation routine
223 static BOOL process_attach(void)
225 NtCurrentTeb()->Peb->KernelCallbackTable = kernel_callback_table;
227 winproc_init();
228 dpiaware_init();
229 SYSPARAMS_Init();
231 return TRUE;
235 /**********************************************************************
236 * thread_detach
238 static void thread_detach(void)
240 struct ntuser_thread_info *thread_info = NtUserGetThreadInfo();
242 NtUserCallNoParam( NtUserExitingThread );
244 WDML_NotifyThreadDetach();
246 NtUserCallNoParam( NtUserThreadDetach );
247 HeapFree( GetProcessHeap(), 0, (void *)(UINT_PTR)thread_info->wmchar_data );
251 /***********************************************************************
252 * UserClientDllInitialize (USER32.@)
254 * USER dll initialisation routine (exported as UserClientDllInitialize for compatibility).
256 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
258 static HMODULE imm32_module;
259 BOOL ret = TRUE;
261 switch(reason)
263 case DLL_PROCESS_ATTACH:
264 user32_module = inst;
265 ret = process_attach();
266 if(ret)
267 imm32_module = LoadLibraryW(L"imm32.dll");
268 break;
269 case DLL_THREAD_DETACH:
270 thread_detach();
271 break;
272 case DLL_PROCESS_DETACH:
273 FreeLibrary(imm32_module);
274 break;
276 return ret;
280 /***********************************************************************
281 * ExitWindowsEx (USER32.@)
283 BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reason )
285 WCHAR app[MAX_PATH];
286 WCHAR cmdline[MAX_PATH + 64];
287 PROCESS_INFORMATION pi;
288 STARTUPINFOW si;
289 void *redir;
291 GetSystemDirectoryW( app, MAX_PATH - ARRAY_SIZE( L"\\wineboot.exe" ));
292 lstrcatW( app, L"\\wineboot.exe" );
293 lstrcpyW( cmdline, app );
295 if (flags & EWX_FORCE) lstrcatW( cmdline, L" --kill" );
296 else
298 lstrcatW( cmdline, L" --end-session" );
299 if (flags & EWX_FORCEIFHUNG) lstrcatW( cmdline, L" --force" );
301 if (!(flags & EWX_REBOOT)) lstrcatW( cmdline, L" --shutdown" );
303 memset( &si, 0, sizeof si );
304 si.cb = sizeof si;
305 Wow64DisableWow64FsRedirection( &redir );
306 if (!CreateProcessW( app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi ))
308 Wow64RevertWow64FsRedirection( redir );
309 ERR( "Failed to run %s\n", debugstr_w(cmdline) );
310 return FALSE;
312 Wow64RevertWow64FsRedirection( redir );
313 CloseHandle( pi.hProcess );
314 CloseHandle( pi.hThread );
315 return TRUE;
318 /***********************************************************************
319 * LockWorkStation (USER32.@)
321 BOOL WINAPI LockWorkStation(void)
323 TRACE(": stub\n");
324 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
325 return FALSE;
328 /***********************************************************************
329 * RegisterServicesProcess (USER32.@)
331 int WINAPI RegisterServicesProcess(DWORD ServicesProcessId)
333 FIXME("(0x%lx): stub\n", ServicesProcessId);
334 return 0;
337 /***********************************************************************
338 * ShutdownBlockReasonCreate (USER32.@)
340 BOOL WINAPI ShutdownBlockReasonCreate(HWND hwnd, LPCWSTR reason)
342 FIXME("(%p, %s): stub\n", hwnd, debugstr_w(reason));
343 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
344 return FALSE;
347 /***********************************************************************
348 * ShutdownBlockReasonDestroy (USER32.@)
350 BOOL WINAPI ShutdownBlockReasonDestroy(HWND hwnd)
352 FIXME("(%p): stub\n", hwnd);
353 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
354 return FALSE;
357 const char *SPY_GetMsgName( UINT msg, HWND hwnd )
359 char buf[128];
360 NtUserMessageCall( hwnd, msg, ARRAYSIZE(buf), 0, buf, NtUserSpyGetMsgName, FALSE );
361 return wine_dbg_sprintf( "%s", buf );
364 void SPY_EnterMessage( INT flag, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
366 if (TRACE_ON(message)) NtUserMessageCall( hwnd, msg, wparam, lparam, 0, NtUserSpyEnter, flag );
369 void SPY_ExitMessage( INT flag, HWND hwnd, UINT msg, LRESULT lreturn, WPARAM wparam, LPARAM lparam )
371 if (TRACE_ON(message)) NtUserMessageCall( hwnd, msg, wparam, lparam, (void *)lreturn,
372 NtUserSpyExit, flag );