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
22 #define WIN32_NO_STATUS
23 #include "user_private.h"
27 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(graphics
);
31 WINE_DECLARE_DEBUG_CHANNEL(message
);
33 HMODULE user32_module
= 0;
35 extern void WDML_NotifyThreadDetach(void);
38 /***********************************************************************
39 * UserRealizePalette (USER32.@)
41 UINT WINAPI
UserRealizePalette( HDC hdc
)
43 return NtUserRealizePalette( hdc
);
47 /***********************************************************************
50 * Initialize the DPI awareness style.
52 static void dpiaware_init(void)
57 if (!LdrQueryImageFileExecutionOptions( &NtCurrentTeb()->Peb
->ProcessParameters
->ImagePathName
,
58 L
"dpiAwareness", REG_DWORD
, &option
, sizeof(option
), NULL
))
60 TRACE( "got option %lx\n", option
);
63 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT
)~(ULONG_PTR
)option
);
68 if (QueryActCtxSettingsW( 0, NULL
, L
"http://schemas.microsoft.com/SMI/2016/WindowsSettings",
69 L
"dpiAwareness", buffer
, ARRAY_SIZE(buffer
), NULL
))
71 static const WCHAR
* const types
[] = { L
"unaware", L
"system", L
"permonitor", L
"permonitorv2" };
72 WCHAR
*p
, *start
, *end
;
75 TRACE( "got dpiAwareness=%s\n", debugstr_w(buffer
) );
76 for (start
= buffer
; *start
; start
= end
)
78 start
+= wcsspn( start
, L
" \t\r\n" );
79 if (!(end
= wcschr( start
, ',' ))) end
= start
+ lstrlenW(start
);
81 if ((p
= wcspbrk( start
, L
" \t\r\n" ))) *p
= 0;
82 for (i
= 0; i
< ARRAY_SIZE(types
); i
++)
84 if (wcsicmp( start
, types
[i
] )) continue;
85 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT
)~i
);
90 else if (QueryActCtxSettingsW( 0, NULL
, L
"http://schemas.microsoft.com/SMI/2005/WindowsSettings",
91 L
"dpiAware", buffer
, ARRAY_SIZE(buffer
), NULL
))
93 TRACE( "got dpiAware=%s\n", debugstr_w(buffer
) );
94 if (!wcsicmp( buffer
, L
"true" ))
95 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE
);
96 else if (!wcsicmp( buffer
, L
"true/pm" ) || !wcsicmp( buffer
, L
"per monitor" ))
97 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE
);
99 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE
);
103 static NTSTATUS WINAPI
User32CopyImage( void *args
, ULONG size
)
105 const struct copy_image_params
*params
= args
;
106 HANDLE ret
= CopyImage( params
->hwnd
, params
->type
, params
->dx
, params
->dy
, params
->flags
);
107 if (!ret
) return STATUS_NO_MEMORY
;
108 return NtCallbackReturn( &ret
, sizeof(ret
), STATUS_SUCCESS
);
111 static NTSTATUS WINAPI
User32DrawNonClientButton( void *args
, ULONG size
)
113 const struct draw_non_client_button_params
*params
= args
;
114 user_api
->pNonClientButtonDraw( params
->hwnd
, params
->hdc
, params
->type
, params
->rect
,
115 params
->down
, params
->grayed
);
116 return STATUS_SUCCESS
;
119 static NTSTATUS WINAPI
User32DrawScrollBar( void *args
, ULONG size
)
121 const struct draw_scroll_bar_params
*params
= args
;
122 RECT rect
= params
->rect
;
123 user_api
->pScrollBarDraw( params
->hwnd
, params
->hdc
, params
->bar
, params
->hit_test
,
124 ¶ms
->tracking_info
, params
->arrows
, params
->interior
,
125 &rect
, params
->enable_flags
, params
->arrow_size
, params
->thumb_pos
,
126 params
->thumb_size
, params
->vertical
);
127 return STATUS_SUCCESS
;
130 static NTSTATUS WINAPI
User32DrawText( void *args
, ULONG size
)
132 const struct draw_text_params
*params
= args
;
133 struct draw_text_result result
;
135 size
-= FIELD_OFFSET( struct draw_text_params
, str
);
136 result
.rect
= params
->rect
;
137 result
.height
= DrawTextW( params
->hdc
, params
->str
, size
/ sizeof(WCHAR
), &result
.rect
, params
->flags
);
138 return NtCallbackReturn( &result
, sizeof(result
), STATUS_SUCCESS
);
141 static NTSTATUS WINAPI
User32ImmProcessKey( void *args
, ULONG size
)
143 const struct imm_process_key_params
*params
= args
;
144 if (ImmProcessKey( params
->hwnd
, params
->hkl
, params
->vkey
, params
->key_data
, 0 ))
145 return STATUS_SUCCESS
;
146 return STATUS_INVALID_PARAMETER
;
149 static NTSTATUS WINAPI
User32ImmTranslateMessage( void *args
, ULONG size
)
151 const struct imm_translate_message_params
*params
= args
;
152 if (ImmTranslateMessage( params
->hwnd
, params
->msg
, params
->wparam
, params
->key_data
))
153 return STATUS_SUCCESS
;
154 return STATUS_INVALID_PARAMETER
;
157 static NTSTATUS WINAPI
User32LoadImage( void *args
, ULONG size
)
159 const struct load_image_params
*params
= args
;
160 HANDLE ret
= LoadImageW( params
->hinst
, params
->name
, params
->type
,
161 params
->dx
, params
->dy
, params
->flags
);
162 if (!ret
) return STATUS_NO_MEMORY
;
163 return NtCallbackReturn( &ret
, sizeof(ret
), STATUS_SUCCESS
);
166 static NTSTATUS WINAPI
User32LoadSysMenu( void *args
, ULONG size
)
168 const struct load_sys_menu_params
*params
= args
;
169 HMENU ret
= LoadMenuW( user32_module
, params
->mdi
? L
"SYSMENUMDI" : L
"SYSMENU" );
170 if (!ret
) return STATUS_NO_MEMORY
;
171 return NtCallbackReturn( &ret
, sizeof(ret
), STATUS_SUCCESS
);
174 static NTSTATUS WINAPI
User32FreeCachedClipboardData( void *args
, ULONG size
)
176 const struct free_cached_data_params
*params
= args
;
177 free_cached_data( params
->format
, params
->handle
);
178 return STATUS_SUCCESS
;
181 static NTSTATUS WINAPI
User32PostDDEMessage( void *args
, ULONG size
)
183 const struct post_dde_message_params
*params
= args
;
184 return post_dde_message( params
->hwnd
, params
->msg
, params
->wparam
, params
->lparam
,
185 params
->dest_tid
, params
->type
);
188 static NTSTATUS WINAPI
User32RenderSsynthesizedFormat( void *args
, ULONG size
)
190 const struct render_synthesized_format_params
*params
= args
;
191 render_synthesized_format( params
->format
, params
->from
);
192 return STATUS_SUCCESS
;
195 static NTSTATUS WINAPI
User32LoadDriver( void *args
, ULONG size
)
197 const WCHAR
*path
= args
;
201 RtlInitUnicodeString( &str
, path
);
202 return LdrLoadDll( L
"c:\\windows\\system32", 0, &str
, &module
);
205 static NTSTATUS WINAPI
User32UnpackDDEMessage( void *args
, ULONG size
)
207 const struct unpack_dde_message_params
*params
= args
;
208 struct unpack_dde_message_result result
= { .wparam
= params
->wparam
, .lparam
= params
->lparam
};
210 size
-= FIELD_OFFSET( struct unpack_dde_message_params
, data
);
211 if (!unpack_dde_message( params
->hwnd
, params
->message
, &result
.wparam
, &result
.lparam
,
212 params
->data
, size
))
213 return STATUS_NO_MEMORY
;
215 return NtCallbackReturn( &result
, sizeof(result
), STATUS_SUCCESS
);
218 static KERNEL_CALLBACK_PROC kernel_callback_table
[NtUserCallCount
] =
220 User32CallEnumDisplayMonitor
,
221 User32CallSendAsyncCallback
,
222 User32CallWinEventHook
,
223 User32CallWindowProc
,
224 User32CallWindowsHook
,
226 User32DrawNonClientButton
,
229 User32FreeCachedClipboardData
,
231 User32ImmTranslateMessage
,
232 User32InitBuiltinClasses
,
236 User32PostDDEMessage
,
237 User32RenderSsynthesizedFormat
,
238 User32UnpackDDEMessage
,
242 /***********************************************************************
243 * USER initialisation routine
245 static BOOL
process_attach(void)
247 NtCurrentTeb()->Peb
->KernelCallbackTable
= kernel_callback_table
;
257 /**********************************************************************
260 static void thread_detach(void)
262 struct ntuser_thread_info
*thread_info
= NtUserGetThreadInfo();
264 NtUserCallNoParam( NtUserExitingThread
);
266 WDML_NotifyThreadDetach();
268 NtUserCallNoParam( NtUserThreadDetach
);
269 HeapFree( GetProcessHeap(), 0, (void *)(UINT_PTR
)thread_info
->wmchar_data
);
273 /***********************************************************************
274 * UserClientDllInitialize (USER32.@)
276 * USER dll initialisation routine (exported as UserClientDllInitialize for compatibility).
278 BOOL WINAPI
DllMain( HINSTANCE inst
, DWORD reason
, LPVOID reserved
)
280 static HMODULE imm32_module
;
285 case DLL_PROCESS_ATTACH
:
286 user32_module
= inst
;
287 ret
= process_attach();
289 imm32_module
= LoadLibraryW(L
"imm32.dll");
291 case DLL_THREAD_DETACH
:
294 case DLL_PROCESS_DETACH
:
295 FreeLibrary(imm32_module
);
302 /***********************************************************************
303 * ExitWindowsEx (USER32.@)
305 BOOL WINAPI
ExitWindowsEx( UINT flags
, DWORD reason
)
308 WCHAR cmdline
[MAX_PATH
+ 64];
309 PROCESS_INFORMATION pi
;
313 GetSystemDirectoryW( app
, MAX_PATH
- ARRAY_SIZE( L
"\\wineboot.exe" ));
314 lstrcatW( app
, L
"\\wineboot.exe" );
315 lstrcpyW( cmdline
, app
);
317 if (flags
& EWX_FORCE
) lstrcatW( cmdline
, L
" --kill" );
320 lstrcatW( cmdline
, L
" --end-session" );
321 if (flags
& EWX_FORCEIFHUNG
) lstrcatW( cmdline
, L
" --force" );
323 if (!(flags
& EWX_REBOOT
)) lstrcatW( cmdline
, L
" --shutdown" );
325 memset( &si
, 0, sizeof si
);
327 Wow64DisableWow64FsRedirection( &redir
);
328 if (!CreateProcessW( app
, cmdline
, NULL
, NULL
, FALSE
, DETACHED_PROCESS
, NULL
, NULL
, &si
, &pi
))
330 Wow64RevertWow64FsRedirection( redir
);
331 ERR( "Failed to run %s\n", debugstr_w(cmdline
) );
334 Wow64RevertWow64FsRedirection( redir
);
335 CloseHandle( pi
.hProcess
);
336 CloseHandle( pi
.hThread
);
340 /***********************************************************************
341 * LockWorkStation (USER32.@)
343 BOOL WINAPI
LockWorkStation(void)
346 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
350 /***********************************************************************
351 * RegisterServicesProcess (USER32.@)
353 int WINAPI
RegisterServicesProcess(DWORD ServicesProcessId
)
355 FIXME("(0x%lx): stub\n", ServicesProcessId
);
359 /***********************************************************************
360 * ShutdownBlockReasonCreate (USER32.@)
362 BOOL WINAPI
ShutdownBlockReasonCreate(HWND hwnd
, LPCWSTR reason
)
364 FIXME("(%p, %s): stub\n", hwnd
, debugstr_w(reason
));
365 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
369 /***********************************************************************
370 * ShutdownBlockReasonDestroy (USER32.@)
372 BOOL WINAPI
ShutdownBlockReasonDestroy(HWND hwnd
)
374 FIXME("(%p): stub\n", hwnd
);
375 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
379 const char *SPY_GetMsgName( UINT msg
, HWND hwnd
)
382 NtUserMessageCall( hwnd
, msg
, ARRAYSIZE(buf
), 0, buf
, NtUserSpyGetMsgName
, FALSE
);
383 return wine_dbg_sprintf( "%s", buf
);
386 void SPY_EnterMessage( INT flag
, HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
388 if (TRACE_ON(message
)) NtUserMessageCall( hwnd
, msg
, wparam
, lparam
, 0, NtUserSpyEnter
, flag
);
391 void SPY_ExitMessage( INT flag
, HWND hwnd
, UINT msg
, LRESULT lreturn
, WPARAM wparam
, LPARAM lparam
)
393 if (TRACE_ON(message
)) NtUserMessageCall( hwnd
, msg
, wparam
, lparam
, (void *)lreturn
,
394 NtUserSpyExit
, flag
);