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"
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 /***********************************************************************
48 * Initialize the DPI awareness style.
50 static void dpiaware_init(void)
55 if (!LdrQueryImageFileExecutionOptions( &NtCurrentTeb()->Peb
->ProcessParameters
->ImagePathName
,
56 L
"dpiAwareness", REG_DWORD
, &option
, sizeof(option
), NULL
))
58 TRACE( "got option %lx\n", option
);
61 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT
)~(ULONG_PTR
)option
);
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
;
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
);
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
);
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
);
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
);
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 ¶ms
->tracking_info
, params
->arrows
, params
->interior
,
119 &rect
, params
->enable_flags
, params
->arrow_size
, params
->thumb_pos
,
120 params
->thumb_size
, params
->vertical
);
124 static NTSTATUS WINAPI
User32DrawText( struct draw_text_params
*params
, ULONG size
)
128 size
-= FIELD_OFFSET( struct draw_text_params
, str
);
129 ret
= DrawTextW( params
->hdc
, params
->str
, size
/ sizeof(WCHAR
), ¶ms
->rect
, params
->flags
);
130 return NtCallbackReturn( ¶ms
->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
,
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
,
160 free_cached_data( params
->format
, params
->handle
);
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
,
173 render_synthesized_format( params
->format
, params
->from
);
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
))
191 if (params
->result
) *params
->result
= result
;
192 else NtCallbackReturn( &result
, sizeof(result
), TRUE
);
196 static const void *kernel_callback_table
[NtUserCallCount
] =
198 User32CallEnumDisplayMonitor
,
199 User32CallSendAsyncCallback
,
200 User32CallWinEventHook
,
201 User32CallWindowProc
,
202 User32CallWindowsHook
,
204 User32DrawNonClientButton
,
207 User32FreeCachedClipboardData
,
209 User32ImmTranslateMessage
,
210 User32InitBuiltinClasses
,
214 User32PostDDEMessage
,
215 User32RenderSsynthesizedFormat
,
216 User32UnpackDDEMessage
,
220 /***********************************************************************
221 * USER initialisation routine
223 static BOOL
process_attach(void)
225 NtCurrentTeb()->Peb
->KernelCallbackTable
= kernel_callback_table
;
235 /**********************************************************************
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
;
263 case DLL_PROCESS_ATTACH
:
264 user32_module
= inst
;
265 ret
= process_attach();
267 imm32_module
= LoadLibraryW(L
"imm32.dll");
269 case DLL_THREAD_DETACH
:
272 case DLL_PROCESS_DETACH
:
273 FreeLibrary(imm32_module
);
280 /***********************************************************************
281 * ExitWindowsEx (USER32.@)
283 BOOL WINAPI
ExitWindowsEx( UINT flags
, DWORD reason
)
286 WCHAR cmdline
[MAX_PATH
+ 64];
287 PROCESS_INFORMATION pi
;
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" );
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
);
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
) );
312 Wow64RevertWow64FsRedirection( redir
);
313 CloseHandle( pi
.hProcess
);
314 CloseHandle( pi
.hThread
);
318 /***********************************************************************
319 * LockWorkStation (USER32.@)
321 BOOL WINAPI
LockWorkStation(void)
324 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
328 /***********************************************************************
329 * RegisterServicesProcess (USER32.@)
331 int WINAPI
RegisterServicesProcess(DWORD ServicesProcessId
)
333 FIXME("(0x%lx): stub\n", ServicesProcessId
);
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
);
347 /***********************************************************************
348 * ShutdownBlockReasonDestroy (USER32.@)
350 BOOL WINAPI
ShutdownBlockReasonDestroy(HWND hwnd
)
352 FIXME("(%p): stub\n", hwnd
);
353 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
357 const char *SPY_GetMsgName( UINT msg
, HWND hwnd
)
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
);