From: Jacek Caban jacek@codeweavers.com
--- dlls/wow64win/user.c | 1238 +++++++++++++++++++++--------------------- 1 file changed, 619 insertions(+), 619 deletions(-)
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index ca84c4a7bab..2ed13ac424a 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -104,36 +104,83 @@ static MSG32 *msg_64to32( MSG *msg, MSG32 *msg32 ) return msg32; }
-NTSTATUS WINAPI wow64_NtUserInitializeClientPfnArrays( UINT *args ) +NTSTATUS WINAPI wow64_NtUserAddClipboardFormatListener( UINT *args ) { - FIXME( "\n" ); - return STATUS_NOT_SUPPORTED; + HWND hwnd = get_handle( &args ); + + return NtUserAddClipboardFormatListener( hwnd ); }
-NTSTATUS WINAPI wow64_NtUserCreateWindowStation( UINT *args ) +NTSTATUS WINAPI wow64_NtUserAttachThreadInput( UINT *args ) { - OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); - ACCESS_MASK access = get_ulong( &args ); - ULONG arg3 = get_ulong( &args ); - ULONG arg4 = get_ulong( &args ); - ULONG arg5 = get_ulong( &args ); - ULONG arg6 = get_ulong( &args ); - ULONG arg7 = get_ulong( &args ); + DWORD from = get_ulong( &args ); + DWORD to = get_ulong( &args ); + BOOL attach = get_ulong( &args );
- struct object_attr64 attr; + return NtUserAttachThreadInput( from, to, attach ); +}
- return HandleToUlong( NtUserCreateWindowStation( objattr_32to64( &attr, attr32 ), access, - arg3, arg4, arg5, arg6, arg7 )); +NTSTATUS WINAPI wow64_NtUserBuildHwndList( UINT *args ) +{ + HDESK desktop = get_handle( &args ); + ULONG unk2 = get_ulong( &args ); + ULONG unk3 = get_ulong( &args ); + ULONG unk4 = get_ulong( &args ); + ULONG thread_id = get_ulong( &args ); + ULONG count = get_ulong( &args ); + UINT32 *buffer32 = get_ptr( &args ); + ULONG *size = get_ptr( &args ); + + HWND *buffer; + ULONG i; + NTSTATUS status; + + if (!(buffer = Wow64AllocateTemp( count * sizeof(*buffer) ))) return STATUS_NO_MEMORY; + + if ((status = NtUserBuildHwndList( desktop, unk2, unk3, unk4, thread_id, count, buffer, size ))) + return status; + + for (i = 0; i < *size; i++) + buffer32[i] = HandleToUlong( buffer[i] ); + return status; }
-NTSTATUS WINAPI wow64_NtUserOpenWindowStation( UINT *args ) +NTSTATUS WINAPI wow64_NtUserCallMsgFilter( UINT *args ) { - OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); - ACCESS_MASK access = get_ulong( &args ); + MSG32 *msg32 = get_ptr( &args ); + INT code = get_ulong( &args ); + MSG msg; + BOOL ret;
- struct object_attr64 attr; + ret = NtUserCallMsgFilter( msg_32to64( &msg, msg32 ), code ); + msg_64to32( &msg, msg32 ); + return ret; +}
- return HandleToUlong( NtUserOpenWindowStation( objattr_32to64( &attr, attr32 ), access )); +NTSTATUS WINAPI wow64_NtUserCheckMenuItem( UINT *args ) +{ + HMENU handle = get_handle( &args ); + UINT id = get_ulong( &args ); + UINT flags = get_ulong( &args ); + + return NtUserCheckMenuItem( handle, id, flags ); +} + +NTSTATUS WINAPI wow64_NtUserChildWindowFromPointEx( UINT *args ) +{ + HWND parent = get_handle( &args ); + LONG x = get_ulong( &args ); + LONG y = get_ulong( &args ); + UINT flags = get_ulong( &args ); + + return HandleToUlong( NtUserChildWindowFromPointEx( parent, x, y, flags )); +} + +NTSTATUS WINAPI wow64_NtUserCloseDesktop( UINT *args ) +{ + HDESK handle = get_handle( &args ); + + return NtUserCloseDesktop( handle ); }
NTSTATUS WINAPI wow64_NtUserCloseWindowStation( UINT *args ) @@ -143,16 +190,21 @@ NTSTATUS WINAPI wow64_NtUserCloseWindowStation( UINT *args ) return NtUserCloseWindowStation( handle ); }
-NTSTATUS WINAPI wow64_NtUserGetProcessWindowStation( UINT *args ) +NTSTATUS WINAPI wow64_NtUserCopyAcceleratorTable( UINT *args ) { - return HandleToUlong( NtUserGetProcessWindowStation() ); + HACCEL src = get_handle( &args ); + ACCEL *dst = get_ptr( &args ); + INT count = get_ulong( &args ); + + return NtUserCopyAcceleratorTable( src, dst, count ); }
-NTSTATUS WINAPI wow64_NtUserSetProcessWindowStation( UINT *args ) +NTSTATUS WINAPI wow64_NtUserCreateAcceleratorTable( UINT *args ) { - HWINSTA handle = get_handle( &args ); + ACCEL *table = get_ptr( &args ); + INT count = get_ulong( &args );
- return NtUserSetProcessWindowStation( handle ); + return HandleToUlong( NtUserCreateAcceleratorTable( table, count )); }
NTSTATUS WINAPI wow64_NtUserCreateDesktopEx( UINT *args ) @@ -174,93 +226,80 @@ NTSTATUS WINAPI wow64_NtUserCreateDesktopEx( UINT *args ) return HandleToUlong( ret ); }
-NTSTATUS WINAPI wow64_NtUserOpenDesktop( UINT *args ) +NTSTATUS WINAPI wow64_NtUserCreateWindowStation( UINT *args ) { OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); - DWORD flags = get_ulong( &args ); ACCESS_MASK access = get_ulong( &args ); + ULONG arg3 = get_ulong( &args ); + ULONG arg4 = get_ulong( &args ); + ULONG arg5 = get_ulong( &args ); + ULONG arg6 = get_ulong( &args ); + ULONG arg7 = get_ulong( &args );
struct object_attr64 attr; - HANDLE ret; - - ret = NtUserOpenDesktop( objattr_32to64( &attr, attr32 ), flags, access ); - return HandleToUlong( ret ); -} - -NTSTATUS WINAPI wow64_NtUserCloseDesktop( UINT *args ) -{ - HDESK handle = get_handle( &args );
- return NtUserCloseDesktop( handle ); + return HandleToUlong( NtUserCreateWindowStation( objattr_32to64( &attr, attr32 ), access, + arg3, arg4, arg5, arg6, arg7 )); }
-NTSTATUS WINAPI wow64_NtUserGetThreadDesktop( UINT *args ) +NTSTATUS WINAPI wow64_NtUserDeleteMenu( UINT *args ) { - DWORD thread = get_ulong( &args ); + HMENU menu = get_handle( &args ); + UINT id = get_ulong( &args ); + UINT flags = get_ulong( &args );
- return HandleToUlong( NtUserGetThreadDesktop( thread )); + return NtUserDeleteMenu( menu, id, flags ); }
-NTSTATUS WINAPI wow64_NtUserSetThreadDesktop( UINT *args ) +NTSTATUS WINAPI wow64_NtUserDestroyAcceleratorTable( UINT *args ) { - HDESK handle = get_handle( &args ); + HACCEL handle = get_handle( &args );
- return NtUserSetThreadDesktop( handle ); + return NtUserDestroyAcceleratorTable( handle ); }
-NTSTATUS WINAPI wow64_NtUserOpenInputDesktop( UINT *args ) +NTSTATUS WINAPI wow64_NtUserEndMenu( UINT *args ) { - DWORD flags = get_ulong( &args ); - BOOL inherit = get_ulong( &args ); - ACCESS_MASK access = get_ulong( &args ); - - return HandleToUlong( NtUserOpenInputDesktop( flags, inherit, access )); + return NtUserEndMenu(); }
-NTSTATUS WINAPI wow64_NtUserGetObjectInformation( UINT *args ) +NTSTATUS WINAPI wow64_NtUserFindExistingCursorIcon( UINT *args ) { - HANDLE handle = get_handle( &args ); - INT index = get_ulong( &args ); - void *info = get_ptr( &args ); - DWORD len = get_ulong( &args ); - DWORD *needed = get_ptr( &args ); - - return NtUserGetObjectInformation( handle, index, info, len, needed ); -} + UNICODE_STRING32 *module32 = get_ptr( &args ); + UNICODE_STRING32 *res_name32 = get_ptr( &args ); + void *desc = get_ptr( &args );
-NTSTATUS WINAPI wow64_NtUserSetObjectInformation( UINT *args ) -{ - HANDLE handle = get_handle( &args ); - INT index = get_ulong( &args ); - void *info = get_ptr( &args ); - DWORD len = get_ulong( &args ); + UNICODE_STRING module; + UNICODE_STRING res_name; + HICON ret;
- return NtUserSetObjectInformation( handle, index, info, len ); + ret = NtUserFindExistingCursorIcon( unicode_str_32to64( &module, module32 ), + unicode_str_32to64( &res_name, res_name32 ), desc ); + return HandleToUlong( ret ); }
-NTSTATUS WINAPI wow64_NtUserGetProp( UINT *args ) +NTSTATUS WINAPI wow64_NtUserFindWindowEx( UINT *args ) { - HWND hwnd = get_handle( &args ); - const WCHAR *str = get_ptr( &args ); - - return HandleToUlong( NtUserGetProp( hwnd, str )); -} + HWND parent = get_handle( &args ); + HWND child = get_handle( &args ); + UNICODE_STRING32 *class32 = get_ptr( &args ); + UNICODE_STRING32 *title32 = get_ptr( &args ); + ULONG unk = get_ulong( &args );
-NTSTATUS WINAPI wow64_NtUserSetProp( UINT *args ) -{ - HWND hwnd = get_handle( &args ); - const WCHAR *str = get_ptr( &args ); - HANDLE handle = get_handle( &args ); + UNICODE_STRING class, title; + HWND ret;
- return NtUserSetProp( hwnd, str, handle ); + ret = NtUserFindWindowEx( parent, child, unicode_str_32to64( &class, class32 ), + unicode_str_32to64( &title, title32 ), unk ); + return HandleToUlong( ret ); }
-NTSTATUS WINAPI wow64_NtUserRemoveProp( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetAncestor( UINT *args ) { HWND hwnd = get_handle( &args ); - const WCHAR *str = get_ptr( &args ); + UINT type = get_ulong( &args );
- return HandleToUlong( NtUserRemoveProp( hwnd, str )); + return HandleToUlong( NtUserGetAncestor( hwnd, type )); }
NTSTATUS WINAPI wow64_NtUserGetAtomName( UINT *args ) @@ -273,6 +312,18 @@ NTSTATUS WINAPI wow64_NtUserGetAtomName( UINT *args ) return NtUserGetAtomName( atom, unicode_str_32to64( &str, str32 )); }
+NTSTATUS WINAPI wow64_NtUserGetCaretBlinkTime( UINT *args ) +{ + return NtUserGetCaretBlinkTime(); +} + +NTSTATUS WINAPI wow64_NtUserGetCaretPos( UINT *args ) +{ + POINT *pt = get_ptr( &args ); + + return NtUserGetCaretPos( pt ); +} + NTSTATUS WINAPI wow64_NtUserGetClassName( UINT *args ) { HWND hwnd = get_handle( &args ); @@ -284,151 +335,99 @@ NTSTATUS WINAPI wow64_NtUserGetClassName( UINT *args ) return NtUserGetClassName( hwnd, real, unicode_str_32to64( &str, str32 )); }
-NTSTATUS WINAPI wow64_NtUserGetAncestor( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetClipboardFormatName( UINT *args ) { - HWND hwnd = get_handle( &args ); - UINT type = get_ulong( &args ); + UINT format = get_ulong( &args ); + WCHAR *buffer = get_ptr( &args ); + INT maxlen = get_ulong( &args );
- return HandleToUlong( NtUserGetAncestor( hwnd, type )); + return NtUserGetClipboardFormatName( format, buffer, maxlen ); }
-NTSTATUS WINAPI wow64_NtUserGetWindowRgnEx( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetClipboardOwner( UINT *args ) { - HWND hwnd = get_handle( &args ); - HRGN hrgn = get_handle( &args ); - UINT unk = get_ulong( &args ); - - return NtUserGetWindowRgnEx( hwnd, hrgn, unk ); + return HandleToUlong( NtUserGetClipboardOwner() ); }
-NTSTATUS WINAPI wow64_NtUserWindowFromDC( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetClipboardSequenceNumber( UINT *args ) { - HDC hdc = get_handle( &args ); + return NtUserGetClipboardSequenceNumber(); +}
- return HandleToUlong( NtUserWindowFromDC( hdc )); +NTSTATUS WINAPI wow64_NtUserGetClipboardViewer( UINT *args ) +{ + return HandleToUlong( NtUserGetClipboardViewer() ); }
-NTSTATUS WINAPI wow64_NtUserBuildHwndList( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetCursor( UINT *args ) { - HDESK desktop = get_handle( &args ); - ULONG unk2 = get_ulong( &args ); - ULONG unk3 = get_ulong( &args ); - ULONG unk4 = get_ulong( &args ); - ULONG thread_id = get_ulong( &args ); - ULONG count = get_ulong( &args ); - UINT32 *buffer32 = get_ptr( &args ); - ULONG *size = get_ptr( &args ); + return HandleToUlong( NtUserGetCursor() ); +}
- HWND *buffer; - ULONG i; - NTSTATUS status; +NTSTATUS WINAPI wow64_NtUserGetCursorFrameInfo( UINT *args ) +{ + HCURSOR cursor = get_ptr( &args ); + DWORD istep = get_ulong( &args ); + DWORD *rate_jiffies = get_ptr( &args ); + DWORD *num_steps = get_ptr( &args );
- if (!(buffer = Wow64AllocateTemp( count * sizeof(*buffer) ))) return STATUS_NO_MEMORY; - - if ((status = NtUserBuildHwndList( desktop, unk2, unk3, unk4, thread_id, count, buffer, size ))) - return status; - - for (i = 0; i < *size; i++) - buffer32[i] = HandleToUlong( buffer[i] ); - return status; -} - -NTSTATUS WINAPI wow64_NtUserFindWindowEx( UINT *args ) -{ - HWND parent = get_handle( &args ); - HWND child = get_handle( &args ); - UNICODE_STRING32 *class32 = get_ptr( &args ); - UNICODE_STRING32 *title32 = get_ptr( &args ); - ULONG unk = get_ulong( &args ); - - UNICODE_STRING class, title; - HWND ret; - - ret = NtUserFindWindowEx( parent, child, unicode_str_32to64( &class, class32 ), - unicode_str_32to64( &title, title32 ), unk ); - return HandleToUlong( ret ); -} - -NTSTATUS WINAPI wow64_NtUserInternalGetWindowText( UINT *args ) -{ - HWND hwnd = get_handle( &args ); - WCHAR *text = get_ptr( &args ); - INT count = get_ulong( &args ); - - return NtUserInternalGetWindowText( hwnd, text, count ); -} - -NTSTATUS WINAPI wow64_NtUserGetLayeredWindowAttributes( UINT *args ) -{ - HWND hwnd = get_handle( &args ); - COLORREF *key = get_ptr( &args ); - BYTE *alpha = get_ptr( &args ); - DWORD *flags = get_ptr( &args ); - - return NtUserGetLayeredWindowAttributes( hwnd, key, alpha, flags ); -} - -NTSTATUS WINAPI wow64_NtUserGetClipboardFormatName( UINT *args ) -{ - UINT format = get_ulong( &args ); - WCHAR *buffer = get_ptr( &args ); - INT maxlen = get_ulong( &args ); - - return NtUserGetClipboardFormatName( format, buffer, maxlen ); -} - -NTSTATUS WINAPI wow64_NtUserGetClipboardOwner( UINT *args ) -{ - return HandleToUlong( NtUserGetClipboardOwner() ); -} - -NTSTATUS WINAPI wow64_NtUserGetOpenClipboardWindow( UINT *args ) -{ - return HandleToUlong( NtUserGetOpenClipboardWindow() ); -} - -NTSTATUS WINAPI wow64_NtUserGetClipboardSequenceNumber( UINT *args ) -{ - return NtUserGetClipboardSequenceNumber(); -} - -NTSTATUS WINAPI wow64_NtUserGetClipboardViewer( UINT *args ) -{ - return HandleToUlong( NtUserGetClipboardViewer() ); + return HandleToUlong( NtUserGetCursorFrameInfo( cursor, istep, rate_jiffies, num_steps )); }
-NTSTATUS WINAPI wow64_NtUserAddClipboardFormatListener( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetDoubleClickTime( UINT *args ) { - HWND hwnd = get_handle( &args ); - - return NtUserAddClipboardFormatListener( hwnd ); + return NtUserGetDoubleClickTime(); }
-NTSTATUS WINAPI wow64_NtUserRemoveClipboardFormatListener( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetDpiForMonitor( UINT *args ) { - HWND hwnd = get_handle( &args ); + HMONITOR monitor = get_handle( &args ); + UINT type = get_ulong( &args ); + UINT *x = get_ptr( &args ); + UINT *y = get_ptr( &args );
- return NtUserRemoveClipboardFormatListener( hwnd ); + return NtUserGetDpiForMonitor( monitor, type, x, y ); }
-NTSTATUS WINAPI wow64_NtUserGetCursor( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetForegroundWindow( UINT *args ) { - return HandleToUlong( NtUserGetCursor() ); + return HandleToUlong( NtUserGetForegroundWindow() ); }
-NTSTATUS WINAPI wow64_NtUserFindExistingCursorIcon( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetGUIThreadInfo( UINT *args ) { - UNICODE_STRING32 *module32 = get_ptr( &args ); - UNICODE_STRING32 *res_name32 = get_ptr( &args ); - void *desc = get_ptr( &args ); + DWORD id = get_ulong( &args ); + struct + { + DWORD cbSize; + DWORD flags; + ULONG hwndActive; + ULONG hwndFocus; + ULONG hwndCapture; + ULONG hwndMenuOwner; + ULONG hwndMoveSize; + ULONG hwndCaret; + RECT rcCaret; + } *info32 = get_ptr( &args ); + GUITHREADINFO info;
- UNICODE_STRING module; - UNICODE_STRING res_name; - HICON ret; + if (info32->cbSize != sizeof(*info32)) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + }
- ret = NtUserFindExistingCursorIcon( unicode_str_32to64( &module, module32 ), - unicode_str_32to64( &res_name, res_name32 ), desc ); - return HandleToUlong( ret ); + info.cbSize = sizeof(info); + if (!NtUserGetGUIThreadInfo( id, &info )) return FALSE; + info32->flags = info.flags; + info32->hwndActive = HandleToUlong( info.hwndActive ); + info32->hwndFocus = HandleToUlong( info.hwndFocus ); + info32->hwndCapture = HandleToUlong( info.hwndCapture ); + info32->hwndMenuOwner = HandleToUlong( info.hwndMenuOwner ); + info32->hwndMoveSize = HandleToUlong( info.hwndMoveSize ); + info32->hwndCaret = HandleToUlong( info.hwndCaret ); + info32->rcCaret = info.rcCaret; + return TRUE; }
NTSTATUS WINAPI wow64_NtUserGetIconSize( UINT *args ) @@ -441,25 +440,6 @@ NTSTATUS WINAPI wow64_NtUserGetIconSize( UINT *args ) return NtUserGetIconSize( handle, step, width, height ); }
-NTSTATUS WINAPI wow64_NtUserGetCursorFrameInfo( UINT *args ) -{ - HCURSOR cursor = get_ptr( &args ); - DWORD istep = get_ulong( &args ); - DWORD *rate_jiffies = get_ptr( &args ); - DWORD *num_steps = get_ptr( &args ); - - return HandleToUlong( NtUserGetCursorFrameInfo( cursor, istep, rate_jiffies, num_steps )); -} - -NTSTATUS WINAPI wow64_NtUserAttachThreadInput( UINT *args ) -{ - DWORD from = get_ulong( &args ); - DWORD to = get_ulong( &args ); - BOOL attach = get_ulong( &args ); - - return NtUserAttachThreadInput( from, to, attach ); -} - NTSTATUS WINAPI wow64_NtUserGetKeyState( UINT *args ) { INT vkey = get_ulong( &args ); @@ -488,11 +468,24 @@ NTSTATUS WINAPI wow64_NtUserGetKeyboardState( UINT *args ) return NtUserGetKeyboardState( state ); }
-NTSTATUS WINAPI wow64_NtUserSetKeyboardState( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetLayeredWindowAttributes( UINT *args ) { - BYTE *state = get_ptr( &args ); + HWND hwnd = get_handle( &args ); + COLORREF *key = get_ptr( &args ); + BYTE *alpha = get_ptr( &args ); + DWORD *flags = get_ptr( &args );
- return NtUserSetKeyboardState( state ); + return NtUserGetLayeredWindowAttributes( hwnd, key, alpha, flags ); +} + +NTSTATUS WINAPI wow64_NtUserGetMenuItemRect( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HMENU handle = get_handle( &args ); + UINT item = get_ulong( &args ); + RECT *rect = get_ptr( &args ); + + return NtUserGetMenuItemRect( hwnd, handle, item, rect ); }
NTSTATUS WINAPI wow64_NtUserGetMouseMovePointsEx( UINT *args ) @@ -506,22 +499,20 @@ NTSTATUS WINAPI wow64_NtUserGetMouseMovePointsEx( UINT *args ) return NtUserGetMouseMovePointsEx( size, ptin, ptout, count, resolution ); }
-NTSTATUS WINAPI wow64_NtUserChildWindowFromPointEx( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetObjectInformation( UINT *args ) { - HWND parent = get_handle( &args ); - LONG x = get_ulong( &args ); - LONG y = get_ulong( &args ); - UINT flags = get_ulong( &args ); + HANDLE handle = get_handle( &args ); + INT index = get_ulong( &args ); + void *info = get_ptr( &args ); + DWORD len = get_ulong( &args ); + DWORD *needed = get_ptr( &args );
- return HandleToUlong( NtUserChildWindowFromPointEx( parent, x, y, flags )); + return NtUserGetObjectInformation( handle, index, info, len, needed ); }
-NTSTATUS WINAPI wow64_NtUserSetProcessDpiAwarenessContext( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetOpenClipboardWindow( UINT *args ) { - ULONG awareness = get_ulong( &args ); - ULONG unknown = get_ulong( &args ); - - return NtUserSetProcessDpiAwarenessContext( awareness, unknown ); + return HandleToUlong( NtUserGetOpenClipboardWindow() ); }
NTSTATUS WINAPI wow64_NtUserGetProcessDpiAwarenessContext( UINT *args ) @@ -531,159 +522,262 @@ NTSTATUS WINAPI wow64_NtUserGetProcessDpiAwarenessContext( UINT *args ) return NtUserGetProcessDpiAwarenessContext( process ); }
-NTSTATUS WINAPI wow64_NtUserGetSystemDpiForProcess( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetProcessWindowStation( UINT *args ) { - HANDLE process = get_handle( &args ); - - return NtUserGetSystemDpiForProcess( process ); + return HandleToUlong( NtUserGetProcessWindowStation() ); }
-NTSTATUS WINAPI wow64_NtUserGetDpiForMonitor( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetProp( UINT *args ) { - HMONITOR monitor = get_handle( &args ); - UINT type = get_ulong( &args ); - UINT *x = get_ptr( &args ); - UINT *y = get_ptr( &args ); + HWND hwnd = get_handle( &args ); + const WCHAR *str = get_ptr( &args );
- return NtUserGetDpiForMonitor( monitor, type, x, y ); + return HandleToUlong( NtUserGetProp( hwnd, str )); }
-NTSTATUS WINAPI wow64_NtUserGetDoubleClickTime( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetRawInputBuffer( UINT *args ) { - return NtUserGetDoubleClickTime(); -} + RAWINPUT *data = get_ptr( &args ); + UINT *data_size = get_ptr( &args ); + UINT header_size = get_ulong( &args );
-NTSTATUS WINAPI wow64_NtUserNotifyWinEvent( UINT *args ) -{ - DWORD event = get_ulong( &args ); - HWND hwnd = get_handle( &args ); - LONG object_id = get_ulong( &args ); - LONG child_id = get_ulong( &args ); + if (header_size != sizeof(RAWINPUTHEADER32)) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return ~0u; + }
- NtUserNotifyWinEvent( event, hwnd, object_id, child_id ); - return 0; + /* RAWINPUT has different sizes on 32-bit and 64-bit, but no translation is + * done. The function actually returns different structures depending on + * whether it's operating under WoW64 or not. */ + return NtUserGetRawInputBuffer( data, data_size, sizeof(RAWINPUTHEADER) ); }
-NTSTATUS WINAPI wow64_NtUserSetWinEventHook( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetRawInputData( UINT *args ) { - DWORD event_min = get_ulong( &args ); - DWORD event_max = get_ulong( &args ); - HMODULE inst = get_handle( &args ); - UNICODE_STRING32 *module32 = get_ptr( &args ); - WINEVENTPROC proc = get_ptr(&args ); - DWORD pid = get_ulong( &args ); - DWORD tid = get_ulong( &args ); - DWORD flags = get_ulong( &args ); - UNICODE_STRING module; - HWINEVENTHOOK ret; - - ret = NtUserSetWinEventHook( event_min, event_max, inst, - unicode_str_32to64( &module, module32 ), - proc, pid, tid, flags ); - return HandleToUlong( ret ); -} + HRAWINPUT handle = get_handle( &args ); + UINT command = get_ulong( &args ); + void *data = get_ptr( &args ); + UINT *data_size = get_ptr( &args ); + UINT header_size = get_ulong( &args );
-NTSTATUS WINAPI wow64_NtUserUnhookWinEvent( UINT *args ) -{ - HWINEVENTHOOK handle = get_handle( &args ); + if (header_size != sizeof(RAWINPUTHEADER32)) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return ~0u; + }
- return NtUserUnhookWinEvent( handle ); + switch (command) + { + case RID_INPUT: + if (data) + { + UINT data_size64, body_size, ret; + RAWINPUTHEADER32 *data32 = data; + RAWINPUTHEADER *data64 = NULL; + + data_size64 = *data_size + sizeof(RAWINPUTHEADER); + if (!(data64 = Wow64AllocateTemp( data_size64 ))) + { + SetLastError( STATUS_NO_MEMORY ); + return ~0u; + } + + ret = NtUserGetRawInputData( handle, command, data64, &data_size64, sizeof(RAWINPUTHEADER) ); + if (ret == ~0u) return ret; + + body_size = ret - sizeof(RAWINPUTHEADER); + if (*data_size < sizeof(RAWINPUTHEADER32) + body_size) + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + return ~0u; + } + + data32->dwType = data64->dwType; + data32->dwSize = sizeof(RAWINPUTHEADER32) + body_size; + data32->hDevice = (UINT_PTR)data64->hDevice; + data32->wParam = data64->wParam; + memcpy( data32 + 1, data64 + 1, body_size ); + return sizeof(RAWINPUTHEADER32) + body_size; + } + else + { + UINT data_size64, ret; + + ret = NtUserGetRawInputData( handle, command, NULL, &data_size64, sizeof(RAWINPUTHEADER) ); + if (ret == ~0u) return ret; + *data_size = data_size64 - sizeof(RAWINPUTHEADER) + sizeof(RAWINPUTHEADER32); + return 0; + } + + case RID_HEADER: + { + UINT data_size64 = sizeof(RAWINPUTHEADER); + RAWINPUTHEADER32 *data32 = data; + RAWINPUTHEADER data64; + UINT ret; + + if (!data) + { + *data_size = sizeof(RAWINPUTHEADER32); + return 0; + } + + if (*data_size < sizeof(RAWINPUTHEADER32)) + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + return ~0u; + } + + ret = NtUserGetRawInputData( handle, command, &data64, &data_size64, sizeof(RAWINPUTHEADER) ); + if (ret == ~0u) return ret; + data32->dwType = data64.dwType; + data32->dwSize = data64.dwSize - sizeof(RAWINPUTHEADER) + sizeof(RAWINPUTHEADER32); + data32->hDevice = (UINT_PTR)data64.hDevice; + data32->wParam = data64.wParam; + return sizeof(RAWINPUTHEADER32); + } + + default: + SetLastError( ERROR_INVALID_PARAMETER ); + return ~0u; + } }
-NTSTATUS WINAPI wow64_NtUserSetWindowsHookEx( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetRawInputDeviceInfo( UINT *args ) { - HINSTANCE inst = get_handle( &args ); - UNICODE_STRING32 *module32 = get_ptr( &args ); - DWORD tid = get_ulong( &args ); - INT id = get_ulong( &args ); - HOOKPROC proc = get_ptr( &args ); - BOOL ansi = get_ulong( &args ); - UNICODE_STRING module; - HHOOK ret; + HANDLE handle = get_handle( &args ); + UINT command = get_ulong( &args ); + void *data = get_ptr( &args ); + UINT *data_size = get_ptr( &args );
- ret = NtUserSetWindowsHookEx( inst, unicode_str_32to64( &module, module32 ), - tid, id, proc, ansi ); - return HandleToUlong( ret ); + return NtUserGetRawInputDeviceInfo( handle, command, data, data_size ); }
-NTSTATUS WINAPI wow64_NtUserUnhookWindowsHookEx( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetRawInputDeviceList( UINT *args ) { - HHOOK handle = get_handle( &args ); + RAWINPUTDEVICELIST32 *devices32 = get_ptr( &args ); + UINT *count = get_ptr( &args ); + UINT size = get_ulong( &args );
- return NtUserUnhookWindowsHookEx( handle ); + if (size != sizeof(RAWINPUTDEVICELIST32)) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return ~0u; + } + + if (devices32) + { + RAWINPUTDEVICELIST *devices64; + unsigned int ret, i; + + if (!(devices64 = Wow64AllocateTemp( (*count) * sizeof(*devices64) ))) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return ~0u; + } + + ret = NtUserGetRawInputDeviceList( devices64, count, sizeof(RAWINPUTDEVICELIST) ); + if (ret == ~0u) return ret; + + for (i = 0; i < *count; ++i) + { + devices32[i].hDevice = (UINT_PTR)devices64[i].hDevice; + devices32[i].dwType = devices64[i].dwType; + } + return ret; + } + else + { + return NtUserGetRawInputDeviceList( NULL, count, sizeof(RAWINPUTDEVICELIST) ); + } }
-NTSTATUS WINAPI wow64_NtUserCallMsgFilter( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetRegisteredRawInputDevices( UINT *args ) { - MSG32 *msg32 = get_ptr( &args ); - INT code = get_ulong( &args ); - MSG msg; - BOOL ret; + RAWINPUTDEVICE32 *devices32 = get_ptr( &args ); + UINT *count = get_ptr( &args ); + UINT size = get_ulong( &args );
- ret = NtUserCallMsgFilter( msg_32to64( &msg, msg32 ), code ); - msg_64to32( &msg, msg32 ); - return ret; + if (size != sizeof(RAWINPUTDEVICE32)) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return ~0u; + } + + if (devices32) + { + RAWINPUTDEVICE *devices64; + unsigned int ret, i; + + if (!(devices64 = Wow64AllocateTemp( (*count) * sizeof(*devices64) ))) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return ~0u; + } + + ret = NtUserGetRegisteredRawInputDevices( devices64, count, sizeof(RAWINPUTDEVICE) ); + if (ret == ~0u) return ret; + + for (i = 0; i < *count; ++i) + { + devices32[i].usUsagePage = devices64[i].usUsagePage; + devices32[i].usUsage = devices64[i].usUsage; + devices32[i].dwFlags = devices64[i].dwFlags; + devices32[i].hwndTarget = (ULONG_PTR)devices64[i].hwndTarget; + } + return ret; + } + else + { + return NtUserGetRegisteredRawInputDevices( NULL, count, sizeof(RAWINPUTDEVICE) ); + } }
-NTSTATUS WINAPI wow64_NtUserGetForegroundWindow( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetSystemDpiForProcess( UINT *args ) { - return HandleToUlong( NtUserGetForegroundWindow() ); + HANDLE process = get_handle( &args ); + + return NtUserGetSystemDpiForProcess( process ); }
-NTSTATUS WINAPI wow64_NtUserGetGUIThreadInfo( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetThreadDesktop( UINT *args ) { - DWORD id = get_ulong( &args ); - struct - { - DWORD cbSize; - DWORD flags; - ULONG hwndActive; - ULONG hwndFocus; - ULONG hwndCapture; - ULONG hwndMenuOwner; - ULONG hwndMoveSize; - ULONG hwndCaret; - RECT rcCaret; - } *info32 = get_ptr( &args ); - GUITHREADINFO info; + DWORD thread = get_ulong( &args );
- if (info32->cbSize != sizeof(*info32)) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return FALSE; - } + return HandleToUlong( NtUserGetThreadDesktop( thread )); +}
- info.cbSize = sizeof(info); - if (!NtUserGetGUIThreadInfo( id, &info )) return FALSE; - info32->flags = info.flags; - info32->hwndActive = HandleToUlong( info.hwndActive ); - info32->hwndFocus = HandleToUlong( info.hwndFocus ); - info32->hwndCapture = HandleToUlong( info.hwndCapture ); - info32->hwndMenuOwner = HandleToUlong( info.hwndMenuOwner ); - info32->hwndMoveSize = HandleToUlong( info.hwndMoveSize ); - info32->hwndCaret = HandleToUlong( info.hwndCaret ); - info32->rcCaret = info.rcCaret; - return TRUE; +NTSTATUS WINAPI wow64_NtUserGetTitleBarInfo( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + TITLEBARINFO *info = get_ptr( &args ); + + return NtUserGetTitleBarInfo( hwnd, info ); }
-NTSTATUS WINAPI wow64_NtUserSetSystemTimer( UINT *args ) +NTSTATUS WINAPI wow64_NtUserGetWindowRgnEx( UINT *args ) { HWND hwnd = get_handle( &args ); - UINT_PTR id = get_ulong( &args ); - UINT timeout = get_ulong( &args ); + HRGN hrgn = get_handle( &args ); + UINT unk = get_ulong( &args );
- return NtUserSetSystemTimer( hwnd, id, timeout ); + return NtUserGetWindowRgnEx( hwnd, hrgn, unk ); }
-NTSTATUS WINAPI wow64_NtUserSetTimer( UINT *args ) +NTSTATUS WINAPI wow64_NtUserInitializeClientPfnArrays( UINT *args ) +{ + FIXME( "\n" ); + return STATUS_NOT_SUPPORTED; +} + +NTSTATUS WINAPI wow64_NtUserInternalGetWindowText( UINT *args ) { HWND hwnd = get_handle( &args ); - UINT_PTR id = get_ulong( &args ); - UINT timeout = get_ulong( &args ); - TIMERPROC proc = get_ptr( &args ); - ULONG tolerance = get_ulong( &args ); + WCHAR *text = get_ptr( &args ); + INT count = get_ulong( &args );
- return NtUserSetTimer( hwnd, id, timeout, proc, tolerance ); + return NtUserInternalGetWindowText( hwnd, text, count ); }
NTSTATUS WINAPI wow64_NtUserKillTimer( UINT *args ) @@ -694,83 +788,127 @@ NTSTATUS WINAPI wow64_NtUserKillTimer( UINT *args ) return NtUserKillTimer( hwnd, id ); }
-NTSTATUS WINAPI wow64_NtUserGetCaretBlinkTime( UINT *args ) +NTSTATUS WINAPI wow64_NtUserLockWindowUpdate( UINT *args ) { - return NtUserGetCaretBlinkTime(); + HWND hwnd = get_handle( &args ); + + return NtUserLockWindowUpdate( hwnd ); }
-NTSTATUS WINAPI wow64_NtUserGetCaretPos( UINT *args ) +NTSTATUS WINAPI wow64_NtUserMenuItemFromPoint( UINT *args ) { - POINT *pt = get_ptr( &args ); + HWND hwnd = get_handle( &args ); + HMENU handle = get_handle( &args ); + int x = get_ulong( &args ); + int y = get_ulong( &args );
- return NtUserGetCaretPos( pt ); + return NtUserMenuItemFromPoint( hwnd, handle, x, y ); }
-NTSTATUS WINAPI wow64_NtUserCopyAcceleratorTable( UINT *args ) +NTSTATUS WINAPI wow64_NtUserNotifyWinEvent( UINT *args ) { - HACCEL src = get_handle( &args ); - ACCEL *dst = get_ptr( &args ); - INT count = get_ulong( &args ); + DWORD event = get_ulong( &args ); + HWND hwnd = get_handle( &args ); + LONG object_id = get_ulong( &args ); + LONG child_id = get_ulong( &args );
- return NtUserCopyAcceleratorTable( src, dst, count ); + NtUserNotifyWinEvent( event, hwnd, object_id, child_id ); + return 0; }
-NTSTATUS WINAPI wow64_NtUserCreateAcceleratorTable( UINT *args ) +NTSTATUS WINAPI wow64_NtUserOpenDesktop( UINT *args ) { - ACCEL *table = get_ptr( &args ); - INT count = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + DWORD flags = get_ulong( &args ); + ACCESS_MASK access = get_ulong( &args );
- return HandleToUlong( NtUserCreateAcceleratorTable( table, count )); + struct object_attr64 attr; + HANDLE ret; + + ret = NtUserOpenDesktop( objattr_32to64( &attr, attr32 ), flags, access ); + return HandleToUlong( ret ); }
-NTSTATUS WINAPI wow64_NtUserDestroyAcceleratorTable( UINT *args ) +NTSTATUS WINAPI wow64_NtUserOpenInputDesktop( UINT *args ) { - HACCEL handle = get_handle( &args ); + DWORD flags = get_ulong( &args ); + BOOL inherit = get_ulong( &args ); + ACCESS_MASK access = get_ulong( &args );
- return NtUserDestroyAcceleratorTable( handle ); + return HandleToUlong( NtUserOpenInputDesktop( flags, inherit, access )); }
-NTSTATUS WINAPI wow64_NtUserCheckMenuItem( UINT *args ) +NTSTATUS WINAPI wow64_NtUserOpenWindowStation( UINT *args ) { - HMENU handle = get_handle( &args ); - UINT id = get_ulong( &args ); - UINT flags = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args );
- return NtUserCheckMenuItem( handle, id, flags ); + struct object_attr64 attr; + + return HandleToUlong( NtUserOpenWindowStation( objattr_32to64( &attr, attr32 ), access )); }
-NTSTATUS WINAPI wow64_NtUserDeleteMenu( UINT *args ) +NTSTATUS WINAPI wow64_NtUserRegisterRawInputDevices( UINT *args ) { - HMENU menu = get_handle( &args ); - UINT id = get_ulong( &args ); - UINT flags = get_ulong( &args ); + const RAWINPUTDEVICE32 *devices32 = get_ptr( &args ); + UINT count = get_ulong( &args ); + UINT size = get_ulong( &args );
- return NtUserDeleteMenu( menu, id, flags ); + RAWINPUTDEVICE *devices64; + unsigned int i; + + if (size != sizeof(RAWINPUTDEVICE32)) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + if (!(devices64 = Wow64AllocateTemp( count * sizeof(*devices64) ))) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + + for (i = 0; i < count; ++i) + { + devices64[i].usUsagePage = devices32[i].usUsagePage; + devices64[i].usUsage = devices32[i].usUsage; + devices64[i].dwFlags = devices32[i].dwFlags; + devices64[i].hwndTarget = UlongToPtr( devices32[i].hwndTarget ); + } + + return NtUserRegisterRawInputDevices( devices64, count, sizeof(*devices64) ); }
-NTSTATUS WINAPI wow64_NtUserEndMenu( UINT *args ) +NTSTATUS WINAPI wow64_NtUserRemoveClipboardFormatListener( UINT *args ) { - return NtUserEndMenu(); + HWND hwnd = get_handle( &args ); + + return NtUserRemoveClipboardFormatListener( hwnd ); }
-NTSTATUS WINAPI wow64_NtUserGetMenuItemRect( UINT *args ) +NTSTATUS WINAPI wow64_NtUserRemoveMenu( UINT *args ) { - HWND hwnd = get_handle( &args ); HMENU handle = get_handle( &args ); - UINT item = get_ulong( &args ); - RECT *rect = get_ptr( &args ); + UINT id = get_ulong( &args ); + UINT flags = get_ulong( &args );
- return NtUserGetMenuItemRect( hwnd, handle, item, rect ); + return NtUserRemoveMenu( handle, id, flags ); }
-NTSTATUS WINAPI wow64_NtUserMenuItemFromPoint( UINT *args ) +NTSTATUS WINAPI wow64_NtUserRemoveProp( UINT *args ) { HWND hwnd = get_handle( &args ); - HMENU handle = get_handle( &args ); - int x = get_ulong( &args ); - int y = get_ulong( &args ); + const WCHAR *str = get_ptr( &args );
- return NtUserMenuItemFromPoint( hwnd, handle, x, y ); + return HandleToUlong( NtUserRemoveProp( hwnd, str )); +} + +NTSTATUS WINAPI wow64_NtUserSetKeyboardState( UINT *args ) +{ + BYTE *state = get_ptr( &args ); + + return NtUserSetKeyboardState( state ); }
NTSTATUS WINAPI wow64_NtUserSetMenuContextHelpId( UINT *args ) @@ -787,7 +925,103 @@ NTSTATUS WINAPI wow64_NtUserSetMenuDefaultItem( UINT *args ) UINT item = get_ulong( &args ); UINT bypos = get_ulong( &args );
- return NtUserSetMenuDefaultItem( handle, item, bypos ); + return NtUserSetMenuDefaultItem( handle, item, bypos ); +} + +NTSTATUS WINAPI wow64_NtUserSetObjectInformation( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + INT index = get_ulong( &args ); + void *info = get_ptr( &args ); + DWORD len = get_ulong( &args ); + + return NtUserSetObjectInformation( handle, index, info, len ); +} + +NTSTATUS WINAPI wow64_NtUserSetProcessDpiAwarenessContext( UINT *args ) +{ + ULONG awareness = get_ulong( &args ); + ULONG unknown = get_ulong( &args ); + + return NtUserSetProcessDpiAwarenessContext( awareness, unknown ); +} + +NTSTATUS WINAPI wow64_NtUserSetProcessWindowStation( UINT *args ) +{ + HWINSTA handle = get_handle( &args ); + + return NtUserSetProcessWindowStation( handle ); +} + +NTSTATUS WINAPI wow64_NtUserSetProp( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + const WCHAR *str = get_ptr( &args ); + HANDLE handle = get_handle( &args ); + + return NtUserSetProp( hwnd, str, handle ); +} + +NTSTATUS WINAPI wow64_NtUserSetSystemTimer( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + UINT_PTR id = get_ulong( &args ); + UINT timeout = get_ulong( &args ); + + return NtUserSetSystemTimer( hwnd, id, timeout ); +} + +NTSTATUS WINAPI wow64_NtUserSetThreadDesktop( UINT *args ) +{ + HDESK handle = get_handle( &args ); + + return NtUserSetThreadDesktop( handle ); +} + +NTSTATUS WINAPI wow64_NtUserSetTimer( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + UINT_PTR id = get_ulong( &args ); + UINT timeout = get_ulong( &args ); + TIMERPROC proc = get_ptr( &args ); + ULONG tolerance = get_ulong( &args ); + + return NtUserSetTimer( hwnd, id, timeout, proc, tolerance ); +} + +NTSTATUS WINAPI wow64_NtUserSetWinEventHook( UINT *args ) +{ + DWORD event_min = get_ulong( &args ); + DWORD event_max = get_ulong( &args ); + HMODULE inst = get_handle( &args ); + UNICODE_STRING32 *module32 = get_ptr( &args ); + WINEVENTPROC proc = get_ptr(&args ); + DWORD pid = get_ulong( &args ); + DWORD tid = get_ulong( &args ); + DWORD flags = get_ulong( &args ); + UNICODE_STRING module; + HWINEVENTHOOK ret; + + ret = NtUserSetWinEventHook( event_min, event_max, inst, + unicode_str_32to64( &module, module32 ), + proc, pid, tid, flags ); + return HandleToUlong( ret ); +} + +NTSTATUS WINAPI wow64_NtUserSetWindowsHookEx( UINT *args ) +{ + HINSTANCE inst = get_handle( &args ); + UNICODE_STRING32 *module32 = get_ptr( &args ); + DWORD tid = get_ulong( &args ); + INT id = get_ulong( &args ); + HOOKPROC proc = get_ptr( &args ); + BOOL ansi = get_ulong( &args ); + UNICODE_STRING module; + HHOOK ret; + + ret = NtUserSetWindowsHookEx( inst, unicode_str_32to64( &module, module32 ), + tid, id, proc, ansi ); + return HandleToUlong( ret ); }
NTSTATUS WINAPI wow64_NtUserThunkedMenuInfo( UINT *args ) @@ -857,257 +1091,23 @@ NTSTATUS WINAPI wow64_NtUserThunkedMenuItemInfo( UINT *args ) unicode_str_32to64( &str, str32 )); }
-NTSTATUS WINAPI wow64_NtUserRemoveMenu( UINT *args ) -{ - HMENU handle = get_handle( &args ); - UINT id = get_ulong( &args ); - UINT flags = get_ulong( &args ); - - return NtUserRemoveMenu( handle, id, flags ); -} - -NTSTATUS WINAPI wow64_NtUserLockWindowUpdate( UINT *args ) -{ - HWND hwnd = get_handle( &args ); - - return NtUserLockWindowUpdate( hwnd ); -} - -NTSTATUS WINAPI wow64_NtUserGetTitleBarInfo( UINT *args ) -{ - HWND hwnd = get_handle( &args ); - TITLEBARINFO *info = get_ptr( &args ); - - return NtUserGetTitleBarInfo( hwnd, info ); -} - -NTSTATUS WINAPI wow64_NtUserGetRawInputData( UINT *args ) -{ - HRAWINPUT handle = get_handle( &args ); - UINT command = get_ulong( &args ); - void *data = get_ptr( &args ); - UINT *data_size = get_ptr( &args ); - UINT header_size = get_ulong( &args ); - - if (header_size != sizeof(RAWINPUTHEADER32)) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return ~0u; - } - - switch (command) - { - case RID_INPUT: - if (data) - { - UINT data_size64, body_size, ret; - RAWINPUTHEADER32 *data32 = data; - RAWINPUTHEADER *data64 = NULL; - - data_size64 = *data_size + sizeof(RAWINPUTHEADER); - if (!(data64 = Wow64AllocateTemp( data_size64 ))) - { - SetLastError( STATUS_NO_MEMORY ); - return ~0u; - } - - ret = NtUserGetRawInputData( handle, command, data64, &data_size64, sizeof(RAWINPUTHEADER) ); - if (ret == ~0u) return ret; - - body_size = ret - sizeof(RAWINPUTHEADER); - if (*data_size < sizeof(RAWINPUTHEADER32) + body_size) - { - SetLastError( ERROR_INSUFFICIENT_BUFFER ); - return ~0u; - } - - data32->dwType = data64->dwType; - data32->dwSize = sizeof(RAWINPUTHEADER32) + body_size; - data32->hDevice = (UINT_PTR)data64->hDevice; - data32->wParam = data64->wParam; - memcpy( data32 + 1, data64 + 1, body_size ); - return sizeof(RAWINPUTHEADER32) + body_size; - } - else - { - UINT data_size64, ret; - - ret = NtUserGetRawInputData( handle, command, NULL, &data_size64, sizeof(RAWINPUTHEADER) ); - if (ret == ~0u) return ret; - *data_size = data_size64 - sizeof(RAWINPUTHEADER) + sizeof(RAWINPUTHEADER32); - return 0; - } - - case RID_HEADER: - { - UINT data_size64 = sizeof(RAWINPUTHEADER); - RAWINPUTHEADER32 *data32 = data; - RAWINPUTHEADER data64; - UINT ret; - - if (!data) - { - *data_size = sizeof(RAWINPUTHEADER32); - return 0; - } - - if (*data_size < sizeof(RAWINPUTHEADER32)) - { - SetLastError( ERROR_INSUFFICIENT_BUFFER ); - return ~0u; - } - - ret = NtUserGetRawInputData( handle, command, &data64, &data_size64, sizeof(RAWINPUTHEADER) ); - if (ret == ~0u) return ret; - data32->dwType = data64.dwType; - data32->dwSize = data64.dwSize - sizeof(RAWINPUTHEADER) + sizeof(RAWINPUTHEADER32); - data32->hDevice = (UINT_PTR)data64.hDevice; - data32->wParam = data64.wParam; - return sizeof(RAWINPUTHEADER32); - } - - default: - SetLastError( ERROR_INVALID_PARAMETER ); - return ~0u; - } -} - -NTSTATUS WINAPI wow64_NtUserGetRawInputBuffer( UINT *args ) -{ - RAWINPUT *data = get_ptr( &args ); - UINT *data_size = get_ptr( &args ); - UINT header_size = get_ulong( &args ); - - if (header_size != sizeof(RAWINPUTHEADER32)) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return ~0u; - } - - /* RAWINPUT has different sizes on 32-bit and 64-bit, but no translation is - * done. The function actually returns different structures depending on - * whether it's operating under WoW64 or not. */ - return NtUserGetRawInputBuffer( data, data_size, sizeof(RAWINPUTHEADER) ); -} - -NTSTATUS WINAPI wow64_NtUserRegisterRawInputDevices( UINT *args ) -{ - const RAWINPUTDEVICE32 *devices32 = get_ptr( &args ); - UINT count = get_ulong( &args ); - UINT size = get_ulong( &args ); - - RAWINPUTDEVICE *devices64; - unsigned int i; - - if (size != sizeof(RAWINPUTDEVICE32)) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return FALSE; - } - - if (!(devices64 = Wow64AllocateTemp( count * sizeof(*devices64) ))) - { - SetLastError( ERROR_NOT_ENOUGH_MEMORY ); - return FALSE; - } - - for (i = 0; i < count; ++i) - { - devices64[i].usUsagePage = devices32[i].usUsagePage; - devices64[i].usUsage = devices32[i].usUsage; - devices64[i].dwFlags = devices32[i].dwFlags; - devices64[i].hwndTarget = UlongToPtr( devices32[i].hwndTarget ); - } - - return NtUserRegisterRawInputDevices( devices64, count, sizeof(*devices64) ); -} - -NTSTATUS WINAPI wow64_NtUserGetRegisteredRawInputDevices( UINT *args ) +NTSTATUS WINAPI wow64_NtUserUnhookWinEvent( UINT *args ) { - RAWINPUTDEVICE32 *devices32 = get_ptr( &args ); - UINT *count = get_ptr( &args ); - UINT size = get_ulong( &args ); - - if (size != sizeof(RAWINPUTDEVICE32)) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return ~0u; - } - - if (devices32) - { - RAWINPUTDEVICE *devices64; - unsigned int ret, i; - - if (!(devices64 = Wow64AllocateTemp( (*count) * sizeof(*devices64) ))) - { - SetLastError( ERROR_NOT_ENOUGH_MEMORY ); - return ~0u; - } - - ret = NtUserGetRegisteredRawInputDevices( devices64, count, sizeof(RAWINPUTDEVICE) ); - if (ret == ~0u) return ret; + HWINEVENTHOOK handle = get_handle( &args );
- for (i = 0; i < *count; ++i) - { - devices32[i].usUsagePage = devices64[i].usUsagePage; - devices32[i].usUsage = devices64[i].usUsage; - devices32[i].dwFlags = devices64[i].dwFlags; - devices32[i].hwndTarget = (ULONG_PTR)devices64[i].hwndTarget; - } - return ret; - } - else - { - return NtUserGetRegisteredRawInputDevices( NULL, count, sizeof(RAWINPUTDEVICE) ); - } + return NtUserUnhookWinEvent( handle ); }
-NTSTATUS WINAPI wow64_NtUserGetRawInputDeviceInfo( UINT *args ) +NTSTATUS WINAPI wow64_NtUserUnhookWindowsHookEx( UINT *args ) { - HANDLE handle = get_handle( &args ); - UINT command = get_ulong( &args ); - void *data = get_ptr( &args ); - UINT *data_size = get_ptr( &args ); + HHOOK handle = get_handle( &args );
- return NtUserGetRawInputDeviceInfo( handle, command, data, data_size ); + return NtUserUnhookWindowsHookEx( handle ); }
-NTSTATUS WINAPI wow64_NtUserGetRawInputDeviceList( UINT *args ) +NTSTATUS WINAPI wow64_NtUserWindowFromDC( UINT *args ) { - RAWINPUTDEVICELIST32 *devices32 = get_ptr( &args ); - UINT *count = get_ptr( &args ); - UINT size = get_ulong( &args ); - - if (size != sizeof(RAWINPUTDEVICELIST32)) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return ~0u; - } - - if (devices32) - { - RAWINPUTDEVICELIST *devices64; - unsigned int ret, i; - - if (!(devices64 = Wow64AllocateTemp( (*count) * sizeof(*devices64) ))) - { - SetLastError( ERROR_NOT_ENOUGH_MEMORY ); - return ~0u; - } - - ret = NtUserGetRawInputDeviceList( devices64, count, sizeof(RAWINPUTDEVICELIST) ); - if (ret == ~0u) return ret; + HDC hdc = get_handle( &args );
- for (i = 0; i < *count; ++i) - { - devices32[i].hDevice = (UINT_PTR)devices64[i].hDevice; - devices32[i].dwType = devices64[i].dwType; - } - return ret; - } - else - { - return NtUserGetRawInputDeviceList( NULL, count, sizeof(RAWINPUTDEVICELIST) ); - } + return HandleToUlong( NtUserWindowFromDC( hdc )); }
From: Jacek Caban jacek@codeweavers.com
--- dlls/win32u/Makefile.in | 1 + dlls/win32u/imm.c | 148 ++++++++++++++++++++++++++++++++++++++++ dlls/win32u/syscall.c | 4 ++ dlls/win32u/win32u.spec | 8 +-- dlls/wow64win/syscall.h | 4 ++ dlls/wow64win/user.c | 31 +++++++++ include/ntuser.h | 13 ++++ 7 files changed, 205 insertions(+), 4 deletions(-) create mode 100644 dlls/win32u/imm.c
diff --git a/dlls/win32u/Makefile.in b/dlls/win32u/Makefile.in index 153f5f45d9f..692b2d5c9f2 100644 --- a/dlls/win32u/Makefile.in +++ b/dlls/win32u/Makefile.in @@ -32,6 +32,7 @@ C_SRCS = \ freetype.c \ gdiobj.c \ hook.c \ + imm.c \ input.c \ main.c \ mapping.c \ diff --git a/dlls/win32u/imm.c b/dlls/win32u/imm.c new file mode 100644 index 00000000000..8778ea4f514 --- /dev/null +++ b/dlls/win32u/imm.c @@ -0,0 +1,148 @@ +/* + * Input Context implementation + * + * Copyright 2022 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "win32u_private.h" +#include "ntuser_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(imm); + + +struct imc +{ + struct user_object obj; + DWORD thread_id; + UINT_PTR client_ptr; +}; + + +static struct imc *get_imc_ptr( HIMC handle ) +{ + struct imc *imc = get_user_handle_ptr( handle, NTUSER_OBJ_IMC ); + if (imc && imc != OBJ_OTHER_PROCESS) return imc; + WARN( "invalid handle %p\n", handle ); + SetLastError( ERROR_INVALID_HANDLE ); + return NULL; +} + +static void release_imc_ptr( struct imc *imc ) +{ + release_user_handle_ptr( imc ); +} + +/****************************************************************************** + * NtUserCreateInputContext (win32u.@) + */ +HIMC WINAPI NtUserCreateInputContext( UINT_PTR client_ptr ) +{ + struct imc *imc; + HIMC handle; + + if (!(imc = malloc( sizeof(*imc) ))) return 0; + imc->client_ptr = client_ptr; + imc->thread_id = GetCurrentThreadId(); + if (!(handle = alloc_user_handle( &imc->obj, NTUSER_OBJ_IMC ))) + { + free( imc ); + return 0; + } + + TRACE( "%lx returning %p\n", client_ptr, handle ); + return handle; +} + +/****************************************************************************** + * NtUserDestroyInputContext (win32u.@) + */ +BOOL WINAPI NtUserDestroyInputContext( HIMC handle ) +{ + struct imc *imc; + + TRACE( "%p\n", handle ); + + if (!(imc = free_user_handle( handle, NTUSER_OBJ_IMC ))) return FALSE; + if (imc == OBJ_OTHER_PROCESS) + { + FIXME( "other process handle %p\n", handle ); + return FALSE; + } + free( imc ); + return TRUE; +} + +/****************************************************************************** + * NtUserUpdateInputContext (win32u.@) + */ +BOOL WINAPI NtUserUpdateInputContext( HIMC handle, UINT attr, UINT_PTR value ) +{ + struct imc *imc; + BOOL ret = TRUE; + + TRACE( "%p %u %lx\n", handle, attr, value ); + + if (!(imc = get_imc_ptr( handle ))) return FALSE; + + switch (attr) + { + case NtUserInputContextClientPtr: + imc->client_ptr = value; + break; + + default: + FIXME( "unknown attr %u\n", attr ); + ret = FALSE; + }; + + release_imc_ptr( imc ); + return ret; +} + +/****************************************************************************** + * NtUserQueryInputContext (win32u.@) + */ +UINT_PTR WINAPI NtUserQueryInputContext( HIMC handle, UINT attr ) +{ + struct imc *imc; + UINT_PTR ret; + + if (!(imc = get_imc_ptr( handle ))) return FALSE; + + switch (attr) + { + case NtUserInputContextClientPtr: + ret = imc->client_ptr; + break; + + case NtUserInputContextThreadId: + ret = imc->thread_id; + break; + + default: + FIXME( "unknown attr %u\n", attr ); + ret = 0; + }; + + release_imc_ptr( imc ); + return ret; +} diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index e68519f15e5..5ba65e08de0 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -111,9 +111,11 @@ static void * const syscalls[] = NtUserCopyAcceleratorTable, NtUserCreateAcceleratorTable, NtUserCreateDesktopEx, + NtUserCreateInputContext, NtUserCreateWindowStation, NtUserDeleteMenu, NtUserDestroyAcceleratorTable, + NtUserDestroyInputContext, NtUserEndMenu, NtUserFindExistingCursorIcon, NtUserFindWindowEx, @@ -163,6 +165,7 @@ static void * const syscalls[] = NtUserOpenDesktop, NtUserOpenInputDesktop, NtUserOpenWindowStation, + NtUserQueryInputContext, NtUserRegisterRawInputDevices, NtUserRemoveClipboardFormatListener, NtUserRemoveMenu, @@ -183,6 +186,7 @@ static void * const syscalls[] = NtUserThunkedMenuItemInfo, NtUserUnhookWinEvent, NtUserUnhookWindowsHookEx, + NtUserUpdateInputContext, NtUserWindowFromDC, };
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index a2369364877..87447e59a28 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -811,7 +811,7 @@ @ stub NtUserCreateDCompositionHwndTarget @ stdcall -syscall NtUserCreateDesktopEx(ptr ptr ptr long long long) @ stub NtUserCreateEmptyCursorObject -@ stub NtUserCreateInputContext +@ stdcall -syscall NtUserCreateInputContext(ptr) @ stub NtUserCreateLocalMemHandle @ stub NtUserCreatePalmRejectionDelayZone @ stdcall NtUserCreateWindowEx(long ptr ptr ptr long long long long long long long long ptr long long long long) @@ -831,7 +831,7 @@ @ stub NtUserDestroyActivationObject @ stdcall NtUserDestroyCursor(long long) @ stub NtUserDestroyDCompositionHwndTarget -@ stub NtUserDestroyInputContext +@ stdcall -syscall NtUserDestroyInputContext(long) @ stdcall NtUserDestroyMenu(long) @ stub NtUserDestroyPalmRejectionDelayZone @ stdcall NtUserDestroyWindow(long) @@ -1114,7 +1114,7 @@ @ stub NtUserQueryBSDRWindow @ stub NtUserQueryDisplayConfig @ stub NtUserQueryInformationThread -@ stub NtUserQueryInputContext +@ stdcall -syscall NtUserQueryInputContext(long long) @ stub NtUserQuerySendMessage @ stub NtUserQueryWindow @ stub NtUserRealChildWindowFromPoint @@ -1293,7 +1293,7 @@ @ stub NtUserUnregisterSessionPort @ stub NtUserUnregisterUserApiHook @ stub NtUserUpdateDefaultDesktopThumbnail -@ stub NtUserUpdateInputContext +@ stdcall -syscall NtUserUpdateInputContext(long long ptr) @ stub NtUserUpdateInstance @ stdcall NtUserUpdateLayeredWindow(long long ptr ptr long ptr long ptr long ptr) @ stub NtUserUpdatePerUserSystemParameters diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 30b6795f8e8..43e2bc8c838 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -98,9 +98,11 @@ SYSCALL_ENTRY( NtUserCopyAcceleratorTable ) \ SYSCALL_ENTRY( NtUserCreateAcceleratorTable ) \ SYSCALL_ENTRY( NtUserCreateDesktopEx ) \ + SYSCALL_ENTRY( NtUserCreateInputContext ) \ SYSCALL_ENTRY( NtUserCreateWindowStation ) \ SYSCALL_ENTRY( NtUserDeleteMenu ) \ SYSCALL_ENTRY( NtUserDestroyAcceleratorTable ) \ + SYSCALL_ENTRY( NtUserDestroyInputContext ) \ SYSCALL_ENTRY( NtUserEndMenu ) \ SYSCALL_ENTRY( NtUserFindExistingCursorIcon ) \ SYSCALL_ENTRY( NtUserFindWindowEx ) \ @@ -150,6 +152,7 @@ SYSCALL_ENTRY( NtUserOpenDesktop ) \ SYSCALL_ENTRY( NtUserOpenInputDesktop ) \ SYSCALL_ENTRY( NtUserOpenWindowStation ) \ + SYSCALL_ENTRY( NtUserQueryInputContext ) \ SYSCALL_ENTRY( NtUserRegisterRawInputDevices ) \ SYSCALL_ENTRY( NtUserRemoveClipboardFormatListener ) \ SYSCALL_ENTRY( NtUserRemoveMenu ) \ @@ -170,6 +173,7 @@ SYSCALL_ENTRY( NtUserThunkedMenuItemInfo ) \ SYSCALL_ENTRY( NtUserUnhookWinEvent ) \ SYSCALL_ENTRY( NtUserUnhookWindowsHookEx ) \ + SYSCALL_ENTRY( NtUserUpdateInputContext ) \ SYSCALL_ENTRY( NtUserWindowFromDC )
#endif /* __WOW64WIN_SYSCALL_H */ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 2ed13ac424a..cd5a805bea7 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -226,6 +226,13 @@ NTSTATUS WINAPI wow64_NtUserCreateDesktopEx( UINT *args ) return HandleToUlong( ret ); }
+NTSTATUS WINAPI wow64_NtUserCreateInputContext( UINT *args ) +{ + UINT_PTR client_ptr = get_ulong( &args ); + + return HandleToUlong( NtUserCreateInputContext( client_ptr )); +} + NTSTATUS WINAPI wow64_NtUserCreateWindowStation( UINT *args ) { OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); @@ -258,6 +265,13 @@ NTSTATUS WINAPI wow64_NtUserDestroyAcceleratorTable( UINT *args ) return NtUserDestroyAcceleratorTable( handle ); }
+NTSTATUS WINAPI wow64_NtUserDestroyInputContext( UINT *args ) +{ + HIMC handle = get_handle( &args ); + + return NtUserDestroyInputContext( handle ); +} + NTSTATUS WINAPI wow64_NtUserEndMenu( UINT *args ) { return NtUserEndMenu(); @@ -848,6 +862,14 @@ NTSTATUS WINAPI wow64_NtUserOpenWindowStation( UINT *args ) return HandleToUlong( NtUserOpenWindowStation( objattr_32to64( &attr, attr32 ), access )); }
+NTSTATUS WINAPI wow64_NtUserQueryInputContext( UINT *args ) +{ + HIMC handle = get_handle( &args ); + UINT attr = get_ulong( &args ); + + return NtUserQueryInputContext( handle, attr ); +} + NTSTATUS WINAPI wow64_NtUserRegisterRawInputDevices( UINT *args ) { const RAWINPUTDEVICE32 *devices32 = get_ptr( &args ); @@ -1105,6 +1127,15 @@ NTSTATUS WINAPI wow64_NtUserUnhookWindowsHookEx( UINT *args ) return NtUserUnhookWindowsHookEx( handle ); }
+NTSTATUS WINAPI wow64_NtUserUpdateInputContext( UINT *args ) +{ + HIMC handle = get_handle( &args ); + UINT attr = get_ulong( &args ); + UINT_PTR value = get_ulong( &args ); + + return NtUserUpdateInputContext( handle, attr, value ); +} + NTSTATUS WINAPI wow64_NtUserWindowFromDC( UINT *args ) { HDC hdc = get_handle( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index 34701d21533..41ed5a779e5 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -21,6 +21,7 @@
#include <winuser.h> #include <wingdi.h> +#include <imm.h> #include <winternl.h>
/* KernelCallbackTable codes, not compatible with Windows */ @@ -265,6 +266,7 @@ struct send_message_callback_params #define NTUSER_OBJ_WINPOS 0x04 #define NTUSER_OBJ_ACCEL 0x08 #define NTUSER_OBJ_HOOK 0x0f +#define NTUSER_OBJ_IMC 0x11
/* NtUserScrollWindowEx flag */ #define SW_NODCCACHE 0x8000 @@ -358,6 +360,13 @@ struct draw_scroll_bar_params BOOL vertical; };
+/* NtUserUpdateInputContext param, not compatible with Window */ +enum input_context_attr +{ + NtUserInputContextClientPtr, + NtUserInputContextThreadId, +}; + /* internal messages codes */ enum wine_internal_message { @@ -558,6 +567,7 @@ BOOL WINAPI NtUserCreateCaret( HWND hwnd, HBITMAP bitmap, int width, int heig HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *device, DEVMODEW *devmode, DWORD flags, ACCESS_MASK access, ULONG heap_size ); +HIMC WINAPI NtUserCreateInputContext( UINT_PTR client_ptr ); HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, UNICODE_STRING *version, UNICODE_STRING *window_name, DWORD style, INT x, INT y, INT cx, INT cy, @@ -570,6 +580,7 @@ HDWP WINAPI NtUserDeferWindowPosAndBand( HDWP hdwp, HWND hwnd, HWND after, IN BOOL WINAPI NtUserDeleteMenu( HMENU menu, UINT id, UINT flags ); BOOL WINAPI NtUserDestroyAcceleratorTable( HACCEL handle ); BOOL WINAPI NtUserDestroyCursor( HCURSOR cursor, ULONG arg ); +BOOL WINAPI NtUserDestroyInputContext( HIMC handle ); BOOL WINAPI NtUserDestroyMenu( HMENU menu ); BOOL WINAPI NtUserDestroyWindow( HWND hwnd ); LRESULT WINAPI NtUserDispatchMessage( const MSG *msg ); @@ -686,6 +697,7 @@ HDESK WINAPI NtUserOpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK ac BOOL WINAPI NtUserPeekMessage( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT flags ); BOOL WINAPI NtUserPostMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ); BOOL WINAPI NtUserPostThreadMessage( DWORD thread, UINT msg, WPARAM wparam, LPARAM lparam ); +UINT_PTR WINAPI NtUserQueryInputContext( HIMC handle, UINT attr ); BOOL WINAPI NtUserRedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags ); ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *name, UNICODE_STRING *version, struct client_menu_name *client_menu_name, DWORD fnid, DWORD flags, @@ -763,6 +775,7 @@ BOOL WINAPI NtUserUnhookWindowsHookEx( HHOOK handle ); BOOL WINAPI NtUserUnregisterClass( UNICODE_STRING *name, HINSTANCE instance, struct client_menu_name *client_menu_name ); BOOL WINAPI NtUserUnregisterHotKey( HWND hwnd, INT id ); +BOOL WINAPI NtUserUpdateInputContext( HIMC handle, UINT attr, UINT_PTR value ); BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_dst, const SIZE *size, HDC hdc_src, const POINT *pts_src, COLORREF key, const BLENDFUNCTION *blend, DWORD flags, const RECT *dirty );
From: Jacek Caban jacek@codeweavers.com
--- dlls/imm32/Makefile.in | 2 +- dlls/imm32/imm.c | 55 ++++++++++++++++++++---------------------- 2 files changed, 27 insertions(+), 30 deletions(-)
diff --git a/dlls/imm32/Makefile.in b/dlls/imm32/Makefile.in index 214b2b753d4..29de6063792 100644 --- a/dlls/imm32/Makefile.in +++ b/dlls/imm32/Makefile.in @@ -1,6 +1,6 @@ MODULE = imm32.dll IMPORTLIB = imm32 -IMPORTS = user32 gdi32 advapi32 +IMPORTS = user32 gdi32 advapi32 win32u DELAYIMPORTS = ole32
C_SRCS = \ diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index bcb02b82c83..e27c658b930 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -29,7 +29,7 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" -#include "winuser.h" +#include "ntuser.h" #include "winerror.h" #include "wine/debug.h" #include "imm.h" @@ -73,6 +73,7 @@ typedef struct _tagImmHkl{
typedef struct tagInputContextData { + HIMC handle; DWORD dwLock; INPUTCONTEXT IMC; DWORD threadID; @@ -80,7 +81,6 @@ typedef struct tagInputContextData ImmHkl *immKbd; UINT lastVK; BOOL threadDefault; - DWORD magic; } InputContextData;
#define WINE_IMC_VALID_MAGIC 0x56434D49 @@ -628,19 +628,13 @@ static HIMCC ImmCreateBlankCompStr(void) return rc; }
-static InputContextData* get_imc_data(HIMC hIMC) +static InputContextData *get_imc_data(HIMC handle) { - InputContextData *data = hIMC; + InputContextData *ret;
- if (hIMC == NULL) - return NULL; - - if(IsBadReadPtr(data, sizeof(InputContextData)) || data->magic != WINE_IMC_VALID_MAGIC) - { - SetLastError(ERROR_INVALID_HANDLE); - return NULL; - } - return data; + if (!handle) return NULL; + ret = (void *)NtUserQueryInputContext( handle, NtUserInputContextClientPtr ); + return ret && ret->handle == handle ? ret : NULL; }
static HIMC get_default_context( HWND hwnd ) @@ -668,7 +662,7 @@ static HIMC get_default_context( HWND hwnd )
ret = ImmCreateContext(); if (!ret) return 0; - ((InputContextData*)ret)->threadDefault = TRUE; + get_imc_data(ret)->threadDefault = TRUE;
/* thread_data is in the current thread so we can assume it's still valid */ EnterCriticalSection(&threaddata_cs); @@ -903,16 +897,24 @@ HIMC WINAPI ImmCreateContext(void) InputContextData *new_context; LPGUIDELINE gl; LPCANDIDATEINFO ci; + HIMC handle; int i;
new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
+ if (!(handle = NtUserCreateInputContext((UINT_PTR)new_context))) + { + HeapFree(GetProcessHeap(),0,new_context); + return 0; + } + /* Load the IME */ new_context->immKbd = IMM_GetImmHkl(GetKeyboardLayout(0));
if (!new_context->immKbd->hIME) { TRACE("IME dll could not be loaded\n"); + NtUserDestroyInputContext(handle); HeapFree(GetProcessHeap(),0,new_context); return 0; } @@ -940,9 +942,10 @@ HIMC WINAPI ImmCreateContext(void) new_context->IMC.fdwConversion = new_context->immKbd->imeInfo.fdwConversionCaps; new_context->IMC.fdwSentence = new_context->immKbd->imeInfo.fdwSentenceCaps;
- if (!new_context->immKbd->pImeSelect(new_context, TRUE)) + if (!new_context->immKbd->pImeSelect(handle, TRUE)) { TRACE("Selection of IME failed\n"); + NtUserDestroyInputContext(handle); IMM_DestroyContext(new_context); return 0; } @@ -952,8 +955,7 @@ HIMC WINAPI ImmCreateContext(void) new_context->immKbd->uSelected++; TRACE("Created context %p\n",new_context);
- new_context->magic = WINE_IMC_VALID_MAGIC; - return new_context; + return new_context->handle = handle; }
static BOOL IMM_DestroyContext(HIMC hIMC) @@ -975,7 +977,7 @@ static BOOL IMM_DestroyContext(HIMC hIMC) ImmDestroyIMCC(data->IMC.hPrivate); ImmDestroyIMCC(data->IMC.hMsgBuf);
- data->magic = 0; + NtUserDestroyInputContext(data->handle); HeapFree(GetProcessHeap(),0,data);
return TRUE; @@ -1730,8 +1732,9 @@ HIMC WINAPI ImmGetContext(HWND hWnd)
if (rc) { - InputContextData *data = rc; - data->IMC.hWnd = hWnd; + InputContextData *data = get_imc_data(rc); + if (data) data->IMC.hWnd = hWnd; + else rc = 0; }
TRACE("returning %p\n", rc); @@ -2218,7 +2221,7 @@ BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos) UINT WINAPI ImmGetVirtualKey(HWND hWnd) { OSVERSIONINFOA version; - InputContextData *data = ImmGetContext( hWnd ); + InputContextData *data = get_imc_data( ImmGetContext( hWnd )); TRACE("%p\n", hWnd);
if ( data ) @@ -3233,10 +3236,7 @@ BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyD
TRACE("%p %x %x %x\n",hwnd, msg, (UINT)wParam, (UINT)lKeyData);
- if (imc) - data = imc; - else - return FALSE; + if (!(data = get_imc_data( imc ))) return FALSE;
if (!data->immKbd->hIME || !data->immKbd->pImeToAsciiEx || data->lastVK == VK_PROCESSKEY) return FALSE; @@ -3292,10 +3292,7 @@ BOOL WINAPI ImmProcessKey(HWND hwnd, HKL hKL, UINT vKey, LPARAM lKeyData, DWORD
TRACE("%p %p %x %x %lx\n",hwnd, hKL, vKey, (UINT)lKeyData, unknown);
- if (imc) - data = imc; - else - return FALSE; + if (!(data = get_imc_data( imc ))) return FALSE;
/* Make sure we are inputting to the correct keyboard */ if (data->immKbd->hkl != hKL)
From: Jacek Caban jacek@codeweavers.com
--- dlls/imm32/imm.c | 117 +++++++++++++++++++++++++++++++++-- dlls/imm32/imm32.spec | 2 +- dlls/user32/misc.c | 112 +++------------------------------ dlls/win32u/ntuser_private.h | 4 -- include/ntuser.h | 5 ++ 5 files changed, 126 insertions(+), 114 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index e27c658b930..be4ff25a3f9 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -43,6 +43,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm); #define IMM_INIT_MAGIC 0x19650412 BOOL WINAPI User32InitializeImmEntryTable(DWORD);
+/* MSIME messages */ +static UINT WM_MSIME_SERVICE; +static UINT WM_MSIME_RECONVERTOPTIONS; +static UINT WM_MSIME_MOUSE; +static UINT WM_MSIME_RECONVERTREQUEST; +static UINT WM_MSIME_RECONVERT; +static UINT WM_MSIME_QUERYPOSITION; +static UINT WM_MSIME_DOCUMENTFEED; + typedef struct _tagImmHkl{ struct list entry; HKL hkl; @@ -534,11 +543,6 @@ static ImmHkl *IMM_GetImmHkl(HKL hkl) } #undef LOAD_FUNCPTR
-HWND WINAPI __wine_get_ui_window(HKL hkl) -{ - ImmHkl *immHkl = IMM_GetImmHkl(hkl); - return immHkl->UIWnd; -}
static void IMM_FreeAllImmHkl(void) { @@ -3361,3 +3365,106 @@ BOOL WINAPI ImmDisableLegacyIME(void) FIXME("stub\n"); return TRUE; } + +static HWND get_ui_window(HKL hkl) +{ + ImmHkl *immHkl = IMM_GetImmHkl(hkl); + return immHkl->UIWnd; +} + +static BOOL is_ime_ui_msg(UINT msg) +{ + switch (msg) + { + case WM_IME_STARTCOMPOSITION: + case WM_IME_ENDCOMPOSITION: + case WM_IME_COMPOSITION: + case WM_IME_SETCONTEXT: + case WM_IME_NOTIFY: + case WM_IME_CONTROL: + case WM_IME_COMPOSITIONFULL: + case WM_IME_SELECT: + case WM_IME_CHAR: + case WM_IME_REQUEST: + case WM_IME_KEYDOWN: + case WM_IME_KEYUP: + return TRUE; + default: + return msg == WM_MSIME_RECONVERTOPTIONS || + msg == WM_MSIME_SERVICE || + msg == WM_MSIME_MOUSE || + msg == WM_MSIME_RECONVERTREQUEST || + msg == WM_MSIME_RECONVERT || + msg == WM_MSIME_QUERYPOSITION || + msg == WM_MSIME_DOCUMENTFEED; + } +} + +static LRESULT ime_internal_msg( WPARAM wparam, LPARAM lparam) +{ + HWND hwnd = (HWND)lparam; + HIMC himc; + + switch (wparam) + { + case IME_INTERNAL_ACTIVATE: + case IME_INTERNAL_DEACTIVATE: + himc = ImmGetContext(hwnd); + ImmSetActiveContext(hwnd, himc, wparam == IME_INTERNAL_ACTIVATE); + ImmReleaseContext(hwnd, himc); + break; + default: + FIXME("wparam = %Ix\n", wparam); + break; + } + + return 0; +} + +static void init_messages(void) +{ + static BOOL initialized; + + if (initialized) return; + + WM_MSIME_SERVICE = RegisterWindowMessageW(L"MSIMEService"); + WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageW(L"MSIMEReconvertOptions"); + WM_MSIME_MOUSE = RegisterWindowMessageW(L"MSIMEMouseOperation"); + WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageW(L"MSIMEReconvertRequest"); + WM_MSIME_RECONVERT = RegisterWindowMessageW(L"MSIMEReconvert"); + WM_MSIME_QUERYPOSITION = RegisterWindowMessageW(L"MSIMEQueryPosition"); + WM_MSIME_DOCUMENTFEED = RegisterWindowMessageW(L"MSIMEDocumentFeed"); + initialized = TRUE; +} + +LRESULT WINAPI __wine_ime_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi) +{ + HWND uiwnd; + + switch (msg) + { + case WM_CREATE: + init_messages(); + return TRUE; + + case WM_IME_INTERNAL: + return ime_internal_msg(wparam, lparam); + } + + if (is_ime_ui_msg(msg)) + { + if ((uiwnd = get_ui_window(NtUserGetKeyboardLayout(0)))) + { + if (ansi) + return SendMessageA(uiwnd, msg, wparam, lparam); + else + return SendMessageW(uiwnd, msg, wparam, lparam); + } + return FALSE; + } + + if (ansi) + return DefWindowProcA(hwnd, msg, wparam, lparam); + else + return DefWindowProcW(hwnd, msg, wparam, lparam); +} diff --git a/dlls/imm32/imm32.spec b/dlls/imm32/imm32.spec index 25876de873d..e95731183ea 100644 --- a/dlls/imm32/imm32.spec +++ b/dlls/imm32/imm32.spec @@ -114,6 +114,6 @@
################################################################ # Wine internal extensions -@ stdcall __wine_get_ui_window(ptr) +@ stdcall __wine_ime_wnd_proc(long long long long long) @ stdcall __wine_register_window(long) @ stdcall __wine_unregister_window(long) diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c index 35518578c6c..31ec85c36eb 100644 --- a/dlls/user32/misc.c +++ b/dlls/user32/misc.c @@ -38,19 +38,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(win); BOOL WINAPI ImmSetActiveContext(HWND, HIMC, BOOL);
#define IMM_INIT_MAGIC 0x19650412 -static HWND (WINAPI *imm_get_ui_window)(HKL); +static LRESULT (WINAPI *imm_ime_wnd_proc)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi); BOOL (WINAPI *imm_register_window)(HWND) = NULL; void (WINAPI *imm_unregister_window)(HWND) = NULL;
-/* MSIME messages */ -static UINT WM_MSIME_SERVICE; -static UINT WM_MSIME_RECONVERTOPTIONS; -static UINT WM_MSIME_MOUSE; -static UINT WM_MSIME_RECONVERTREQUEST; -static UINT WM_MSIME_RECONVERT; -static UINT WM_MSIME_QUERYPOSITION; -static UINT WM_MSIME_DOCUMENTFEED; - /* USER signal proc flags and codes */ /* See UserSignalProc for comments */ #define USIG_FLAGS_WIN32 0x0001 @@ -332,22 +323,14 @@ BOOL WINAPI User32InitializeImmEntryTable(DWORD magic) if (!imm32 || magic != IMM_INIT_MAGIC) return FALSE;
- if (imm_get_ui_window) + if (imm_ime_wnd_proc) return TRUE;
- WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService"); - WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions"); - WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation"); - WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest"); - WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert"); - WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition"); - WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed"); - /* this part is not compatible with native imm32.dll */ - imm_get_ui_window = (void*)GetProcAddress(imm32, "__wine_get_ui_window"); + imm_ime_wnd_proc = (void*)GetProcAddress(imm32, "__wine_ime_wnd_proc"); imm_register_window = (void*)GetProcAddress(imm32, "__wine_register_window"); imm_unregister_window = (void*)GetProcAddress(imm32, "__wine_unregister_window"); - if (!imm_get_ui_window) + if (!imm_ime_wnd_proc) FIXME("native imm32.dll not supported\n"); return TRUE; } @@ -561,93 +544,14 @@ const struct builtin_class_descr IME_builtin_class = 0 /* brush */ };
-static BOOL is_ime_ui_msg( UINT msg ) -{ - switch(msg) { - case WM_IME_STARTCOMPOSITION: - case WM_IME_ENDCOMPOSITION: - case WM_IME_COMPOSITION: - case WM_IME_SETCONTEXT: - case WM_IME_NOTIFY: - case WM_IME_CONTROL: - case WM_IME_COMPOSITIONFULL: - case WM_IME_SELECT: - case WM_IME_CHAR: - case WM_IME_REQUEST: - case WM_IME_KEYDOWN: - case WM_IME_KEYUP: - return TRUE; - default: - if ((msg == WM_MSIME_RECONVERTOPTIONS) || - (msg == WM_MSIME_SERVICE) || - (msg == WM_MSIME_MOUSE) || - (msg == WM_MSIME_RECONVERTREQUEST) || - (msg == WM_MSIME_RECONVERT) || - (msg == WM_MSIME_QUERYPOSITION) || - (msg == WM_MSIME_DOCUMENTFEED)) - return TRUE; - - return FALSE; - } -} - -static LRESULT ime_internal_msg( WPARAM wParam, LPARAM lParam) -{ - HWND hwnd = (HWND)lParam; - HIMC himc; - - switch(wParam) - { - case IME_INTERNAL_ACTIVATE: - case IME_INTERNAL_DEACTIVATE: - himc = ImmGetContext(hwnd); - ImmSetActiveContext(hwnd, himc, wParam == IME_INTERNAL_ACTIVATE); - ImmReleaseContext(hwnd, himc); - break; - default: - FIXME("wParam = %Ix\n", wParam); - break; - } - - return 0; -} - LRESULT WINAPI ImeWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { - HWND uiwnd; - - if (msg==WM_CREATE) - return TRUE; - - if (msg==WM_IME_INTERNAL) - return ime_internal_msg(wParam, lParam); - - if (imm_get_ui_window && is_ime_ui_msg(msg)) - { - if ((uiwnd = imm_get_ui_window( NtUserGetKeyboardLayout(0) ))) - return SendMessageA(uiwnd, msg, wParam, lParam); - return FALSE; - } - - return DefWindowProcA(hwnd, msg, wParam, lParam); + if (!imm_ime_wnd_proc) return DefWindowProcA(hwnd, msg, wParam, lParam); + return imm_ime_wnd_proc( hwnd, msg, wParam, lParam, TRUE ); }
LRESULT WINAPI ImeWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { - HWND uiwnd; - - if (msg==WM_CREATE) - return TRUE; - - if (msg==WM_IME_INTERNAL) - return ime_internal_msg(wParam, lParam); - - if (imm_get_ui_window && is_ime_ui_msg(msg)) - { - if ((uiwnd = imm_get_ui_window( NtUserGetKeyboardLayout(0) ))) - return SendMessageW(uiwnd, msg, wParam, lParam); - return FALSE; - } - - return DefWindowProcW(hwnd, msg, wParam, lParam); + if (!imm_ime_wnd_proc) return DefWindowProcW(hwnd, msg, wParam, lParam); + return imm_ime_wnd_proc( hwnd, msg, wParam, lParam, FALSE ); } diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index fb6e5a5200b..490d59afb47 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -134,10 +134,6 @@ static inline BOOL is_broadcast( HWND hwnd ) return hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST; }
-#define WM_IME_INTERNAL 0x287 -#define IME_INTERNAL_ACTIVATE 0x17 -#define IME_INTERNAL_DEACTIVATE 0x18 - /* this is the structure stored in TEB->Win32ClientInfo */ /* no attempt is made to keep the layout compatible with the Windows one */ struct user_thread_info diff --git a/include/ntuser.h b/include/ntuser.h index 41ed5a779e5..713c7d071fc 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -385,6 +385,11 @@ enum wine_internal_message WM_WINE_LAST_DRIVER_MSG = 0x80001fff };
+/* internal IME message */ +#define WM_IME_INTERNAL 0x287 +#define IME_INTERNAL_ACTIVATE 0x17 +#define IME_INTERNAL_DEACTIVATE 0x18 + /* the various structures that can be sent in messages, in platform-independent layout */ struct packed_CREATESTRUCTW {
From: Jacek Caban jacek@codeweavers.com
--- dlls/imm32/imm.c | 149 +++++++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 63 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index be4ff25a3f9..d290e580a23 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -107,8 +107,13 @@ typedef struct _tagIMMThreadData { HWND hwndDefault; BOOL disableIME; DWORD windowRefs; +} IMMThreadData; + +struct coinit_spy +{ IInitializeSpy IInitializeSpy_iface; - ULARGE_INTEGER spy_cookie; + LONG ref; + ULARGE_INTEGER cookie; enum { IMM_APT_INIT = 0x1, @@ -116,7 +121,9 @@ typedef struct _tagIMMThreadData { IMM_APT_CAN_FREE = 0x4, IMM_APT_BROKEN = 0x8 } apt_flags; -} IMMThreadData; +}; + +static LONG spy_tls = TLS_OUT_OF_INDEXES;
static struct list ImmHklList = LIST_INIT(ImmHklList); static struct list ImmThreadDataList = LIST_INIT(ImmThreadDataList); @@ -249,62 +256,38 @@ static DWORD convert_candidatelist_AtoW( return ret; }
-static void imm_coinit_thread(IMMThreadData *thread_data) +static void imm_couninit_thread(BOOL cleanup) { - HRESULT hr; - - TRACE("implicit COM initialization\n"); - - if (thread_data->threadID != GetCurrentThreadId()) - return; - - if (thread_data->apt_flags & (IMM_APT_INIT | IMM_APT_BROKEN)) - return; - thread_data->apt_flags |= IMM_APT_INIT; + struct coinit_spy *spy;
- if(!thread_data->spy_cookie.QuadPart) - { - hr = CoRegisterInitializeSpy(&thread_data->IInitializeSpy_iface, - &thread_data->spy_cookie); - if (FAILED(hr)) - return; - } - - hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - if (SUCCEEDED(hr)) - thread_data->apt_flags |= IMM_APT_CREATED; -} - -static void imm_couninit_thread(IMMThreadData *thread_data, BOOL cleanup) -{ TRACE("implicit COM deinitialization\n");
- if (thread_data->apt_flags & IMM_APT_BROKEN) + if (!(spy = TlsGetValue(spy_tls)) || (spy->apt_flags & IMM_APT_BROKEN)) return;
- if (cleanup && thread_data->spy_cookie.QuadPart) + if (cleanup && spy->cookie.QuadPart) { - CoRevokeInitializeSpy(thread_data->spy_cookie); - thread_data->spy_cookie.QuadPart = 0; + CoRevokeInitializeSpy(spy->cookie); + spy->cookie.QuadPart = 0; }
- if (!(thread_data->apt_flags & IMM_APT_INIT)) + if (!(spy->apt_flags & IMM_APT_INIT)) return; - thread_data->apt_flags &= ~IMM_APT_INIT; + spy->apt_flags &= ~IMM_APT_INIT;
- if (thread_data->apt_flags & IMM_APT_CREATED) + if (spy->apt_flags & IMM_APT_CREATED) { - thread_data->apt_flags &= ~IMM_APT_CREATED; - if (thread_data->apt_flags & IMM_APT_CAN_FREE) + spy->apt_flags &= ~IMM_APT_CREATED; + if (spy->apt_flags & IMM_APT_CAN_FREE) CoUninitialize(); } if (cleanup) - thread_data->apt_flags = 0; + spy->apt_flags = 0; }
-static inline IMMThreadData *impl_from_IInitializeSpy(IInitializeSpy *iface) +static inline struct coinit_spy *impl_from_IInitializeSpy(IInitializeSpy *iface) { - return CONTAINING_RECORD(iface, IMMThreadData, IInitializeSpy_iface); + return CONTAINING_RECORD(iface, struct coinit_spy, IInitializeSpy_iface); }
static HRESULT WINAPI InitializeSpy_QueryInterface(IInitializeSpy *iface, REFIID riid, void **obj) @@ -323,24 +306,28 @@ static HRESULT WINAPI InitializeSpy_QueryInterface(IInitializeSpy *iface, REFIID
static ULONG WINAPI InitializeSpy_AddRef(IInitializeSpy *iface) { - return 2; + struct coinit_spy *spy = impl_from_IInitializeSpy(iface); + return InterlockedIncrement(&spy->ref); }
static ULONG WINAPI InitializeSpy_Release(IInitializeSpy *iface) { - return 1; + struct coinit_spy *spy = impl_from_IInitializeSpy(iface); + LONG ref = InterlockedDecrement(&spy->ref); + if (!ref) HeapFree(GetProcessHeap(), 0, spy); + return ref; }
static HRESULT WINAPI InitializeSpy_PreInitialize(IInitializeSpy *iface, DWORD coinit, DWORD refs) { - IMMThreadData *thread_data = impl_from_IInitializeSpy(iface); + struct coinit_spy *spy = impl_from_IInitializeSpy(iface);
- if ((thread_data->apt_flags & IMM_APT_CREATED) && + if ((spy->apt_flags & IMM_APT_CREATED) && !(coinit & COINIT_APARTMENTTHREADED) && refs == 1) { - imm_couninit_thread(thread_data, TRUE); - thread_data->apt_flags |= IMM_APT_BROKEN; + imm_couninit_thread(TRUE); + spy->apt_flags |= IMM_APT_BROKEN; } return S_OK; } @@ -348,12 +335,12 @@ static HRESULT WINAPI InitializeSpy_PreInitialize(IInitializeSpy *iface, static HRESULT WINAPI InitializeSpy_PostInitialize(IInitializeSpy *iface, HRESULT hr, DWORD coinit, DWORD refs) { - IMMThreadData *thread_data = impl_from_IInitializeSpy(iface); + struct coinit_spy *spy = impl_from_IInitializeSpy(iface);
- if ((thread_data->apt_flags & IMM_APT_CREATED) && hr == S_FALSE && refs == 2) + if ((spy->apt_flags & IMM_APT_CREATED) && hr == S_FALSE && refs == 2) hr = S_OK; if (SUCCEEDED(hr)) - thread_data->apt_flags |= IMM_APT_CAN_FREE; + spy->apt_flags |= IMM_APT_CAN_FREE; return hr; }
@@ -364,12 +351,14 @@ static HRESULT WINAPI InitializeSpy_PreUninitialize(IInitializeSpy *iface, DWORD
static HRESULT WINAPI InitializeSpy_PostUninitialize(IInitializeSpy *iface, DWORD refs) { - IMMThreadData *thread_data = impl_from_IInitializeSpy(iface); + struct coinit_spy *spy = impl_from_IInitializeSpy(iface); + + TRACE("%lu %p\n", refs, ImmGetDefaultIMEWnd(0));
- if (refs == 1 && !thread_data->windowRefs) - imm_couninit_thread(thread_data, FALSE); + if (refs == 1 && !ImmGetDefaultIMEWnd(0)) + imm_couninit_thread(FALSE); else if (!refs) - thread_data->apt_flags &= ~IMM_APT_CAN_FREE; + spy->apt_flags &= ~IMM_APT_CAN_FREE; return S_OK; }
@@ -384,6 +373,45 @@ static const IInitializeSpyVtbl InitializeSpyVtbl = InitializeSpy_PostUninitialize, };
+static void imm_coinit_thread(void) +{ + struct coinit_spy *spy; + HRESULT hr; + + TRACE("implicit COM initialization\n"); + + if (spy_tls == TLS_OUT_OF_INDEXES) + { + DWORD tls = TlsAlloc(); + if (tls == TLS_OUT_OF_INDEXES) return; + if (InterlockedCompareExchange(&spy_tls, tls, TLS_OUT_OF_INDEXES)) TlsFree(tls); + } + if (!(spy = TlsGetValue(spy_tls))) + { + if (!(spy = HeapAlloc(GetProcessHeap(), 0, sizeof(*spy)))) return; + spy->IInitializeSpy_iface.lpVtbl = &InitializeSpyVtbl; + spy->ref = 1; + spy->cookie.QuadPart = 0; + spy->apt_flags = 0; + TlsSetValue(spy_tls, spy); + } + + if (spy->apt_flags & (IMM_APT_INIT | IMM_APT_BROKEN)) + return; + spy->apt_flags |= IMM_APT_INIT; + + if(!spy->cookie.QuadPart) + { + hr = CoRegisterInitializeSpy(&spy->IInitializeSpy_iface, &spy->cookie); + if (FAILED(hr)) + return; + } + + hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if (SUCCEEDED(hr)) + spy->apt_flags |= IMM_APT_CREATED; +} + static IMMThreadData *IMM_GetThreadData(HWND hwnd, DWORD thread) { IMMThreadData *data; @@ -410,7 +438,6 @@ static IMMThreadData *IMM_GetThreadData(HWND hwnd, DWORD thread) if (data->threadID == thread) return data;
data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data)); - data->IInitializeSpy_iface.lpVtbl = &InitializeSpyVtbl; data->threadID = thread; list_add_head(&ImmThreadDataList,&data->entry); TRACE("Thread Data Created (%lx)\n",thread); @@ -429,6 +456,7 @@ static BOOL IMM_IsDefaultContext(HIMC imc)
static void IMM_FreeThreadData(void) { + struct coinit_spy *spy; IMMThreadData *data;
EnterCriticalSection(&threaddata_cs); @@ -439,13 +467,14 @@ static void IMM_FreeThreadData(void) list_remove(&data->entry); LeaveCriticalSection(&threaddata_cs); IMM_DestroyContext(data->defaultContext); - imm_couninit_thread(data, TRUE); HeapFree(GetProcessHeap(),0,data); TRACE("Thread Data Destroyed\n"); return; } } LeaveCriticalSection(&threaddata_cs); + + if ((spy = TlsGetValue(spy_tls))) IInitializeSpy_Release(&spy->IInitializeSpy_iface); }
static HMODULE load_graphics_driver(void) @@ -704,19 +733,13 @@ static BOOL IMM_IsCrossThreadAccess(HWND hWnd, HIMC hIMC) BOOL WINAPI ImmSetActiveContext(HWND hwnd, HIMC himc, BOOL activate) { InputContextData *data = get_imc_data(himc); - IMMThreadData *thread_data;
TRACE("(%p, %p, %x)\n", hwnd, himc, activate);
if (himc && !data && activate) return FALSE;
- thread_data = IMM_GetThreadData(hwnd, 0); - if (thread_data) - { - imm_coinit_thread(thread_data); - LeaveCriticalSection(&threaddata_cs); - } + imm_coinit_thread();
if (data) { @@ -1002,10 +1025,10 @@ static HWND imm_detach_default_window(IMMThreadData *thread_data) { HWND to_destroy;
- imm_couninit_thread(thread_data, TRUE); to_destroy = thread_data->hwndDefault; thread_data->hwndDefault = NULL; thread_data->windowRefs = 0; + imm_couninit_thread(TRUE); return to_destroy; }
From: Jacek Caban jacek@codeweavers.com
--- dlls/imm32/imm.c | 9 ++++++++- dlls/user32/tests/win.c | 1 - 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index d290e580a23..42cf6a712f9 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -1028,7 +1028,6 @@ static HWND imm_detach_default_window(IMMThreadData *thread_data) to_destroy = thread_data->hwndDefault; thread_data->hwndDefault = NULL; thread_data->windowRefs = 0; - imm_couninit_thread(TRUE); return to_destroy; }
@@ -3470,6 +3469,14 @@ LRESULT WINAPI __wine_ime_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp init_messages(); return TRUE;
+ case WM_DESTROY: + { + HWND default_hwnd = ImmGetDefaultIMEWnd(0); + if (!default_hwnd || hwnd == default_hwnd) + imm_couninit_thread(TRUE); + } + return TRUE; + case WM_IME_INTERNAL: return ime_internal_msg(wparam, lparam); } diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 3727efb1b41..4c2af09d0c6 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -3760,7 +3760,6 @@ static void test_SetActiveWindow_0_proc( char **argv ) else /* < Win10 */ { ok( tmp == hwnd, "SetActiveWindow returned %p\n", tmp ); - todo_wine ok( GetLastError() == 0, "got error %lu\n", GetLastError() );
tmp = GetForegroundWindow();
This merge request was approved by Huw Davies.