From: Rémi Bernon rbernon@codeweavers.com
And use it to post WM_DROPFILES message. --- dlls/user32/clipboard.c | 13 +++++++++++++ dlls/user32/user_main.c | 8 ++++++++ dlls/user32/user_private.h | 2 ++ dlls/win32u/clipboard.c | 35 ++++++++++++++++++++++++++++++++++ dlls/win32u/message.c | 3 +++ dlls/win32u/ntuser_private.h | 4 ++++ dlls/winex11.drv/dllmain.c | 1 - dlls/winex11.drv/event.c | 17 +++++------------ dlls/winex11.drv/unixlib.h | 11 ----------- dlls/winex11.drv/x11drv.h | 1 - dlls/winex11.drv/x11drv_dll.h | 1 - dlls/winex11.drv/x11drv_main.c | 2 -- dlls/winex11.drv/xdnd.c | 21 -------------------- dlls/wow64win/user.c | 25 ++++++++++++++++++++++++ include/ntuser.h | 29 ++++++++++++++++++++++++++++ 15 files changed, 124 insertions(+), 49 deletions(-)
diff --git a/dlls/user32/clipboard.c b/dlls/user32/clipboard.c index 72c7720dc17..0ec42543b34 100644 --- a/dlls/user32/clipboard.c +++ b/dlls/user32/clipboard.c @@ -629,3 +629,16 @@ HANDLE WINAPI GetClipboardData( UINT format ) LeaveCriticalSection( &clipboard_cs ); return ret; } + +void drag_drop_post( HWND hwnd, UINT drop_size, const DROPFILES *drop ) +{ + HDROP handle; + + if ((handle = GlobalAlloc( GMEM_SHARE, drop_size ))) + { + DROPFILES *ptr = GlobalLock( handle ); + memcpy( ptr, drop, drop_size ); + GlobalUnlock( handle ); + PostMessageW( hwnd, WM_DROPFILES, (WPARAM)handle, 0 ); + } +} diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 20b3fa8b1f6..ec307a840f1 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -166,6 +166,13 @@ static NTSTATUS WINAPI User32CallDispatchCallback( void *args, ULONG size ) return callback( params, size ); }
+static NTSTATUS WINAPI User32DragDropPost( void *args, ULONG size ) +{ + const struct drag_drop_post_params *params = args; + drag_drop_post( params->hwnd, params->drop_size, (DROPFILES *)¶ms->drop ); + return STATUS_SUCCESS; +} + static KERNEL_CALLBACK_PROC kernel_callback_table[NtUserCallCount] = { User32CallDispatchCallback, @@ -188,6 +195,7 @@ static KERNEL_CALLBACK_PROC kernel_callback_table[NtUserCallCount] = User32PostDDEMessage, User32RenderSsynthesizedFormat, User32UnpackDDEMessage, + User32DragDropPost, };
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index a9d6a20ddf1..90e76fa16af 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -26,6 +26,7 @@ #include "winbase.h" #include "wingdi.h" #include "ntuser.h" +#include "shlobj.h" #include "winreg.h" #include "winnls.h" #include "wine/heap.h" @@ -51,6 +52,7 @@ extern BOOL unpack_dde_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM const void *buffer, size_t size ); extern void free_cached_data( UINT format, HANDLE handle ); extern HANDLE render_synthesized_format( UINT format, UINT from ); +extern void drag_drop_post( HWND hwnd, UINT drop_size, const DROPFILES *drop ); extern void unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, void *buffer, BOOL ansi );
diff --git a/dlls/win32u/clipboard.c b/dlls/win32u/clipboard.c index 6cf484a56ca..f9fbbcd9030 100644 --- a/dlls/win32u/clipboard.c +++ b/dlls/win32u/clipboard.c @@ -754,3 +754,38 @@ HANDLE WINAPI NtUserGetClipboardData( UINT format, struct get_clipboard_params * return 0; } } + +LRESULT drag_drop_call( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, void *data ) +{ + void *ret_ptr; + ULONG ret_len; + + TRACE( "hwnd %p, msg %#x, wparam %#zx, lparam %#lx, data %p\n", hwnd, msg, wparam, lparam, data ); + + switch (msg) + { + case WINE_DRAG_DROP_POST: + { + struct drag_drop_post_params *params; + const DROPFILES *drop = (DROPFILES *)lparam; + UINT drop_size = wparam, size; + NTSTATUS status; + + size = offsetof(struct drag_drop_post_params, drop) + drop_size; + if (!(params = malloc( size ))) return STATUS_NO_MEMORY; + params->hwnd = hwnd; + params->drop_size = drop_size; + memcpy( ¶ms->drop, drop, drop_size ); + + status = KeUserModeCallback( NtUserDragDropPost, params, size, &ret_ptr, &ret_len ); + free( params ); + return status; + } + + default: + FIXME( "Unknown NtUserDragDropCall msg %#x\n", msg ); + break; + } + + return -1; +} diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index c5913054f48..fd41bd670ce 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -4426,6 +4426,9 @@ LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa case NtUserSystemTrayCall: return system_tray_call( hwnd, msg, wparam, lparam, result_info );
+ case NtUserDragDropCall: + return drag_drop_call( hwnd, msg, wparam, lparam, result_info ); + default: FIXME( "%p %x %lx %lx %p %x %x\n", hwnd, msg, (long)wparam, lparam, result_info, (int)type, ansi ); } diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index f7d84e12cd1..dbf792bc3d2 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -24,6 +24,7 @@
#include "ntuser.h" #include "shellapi.h" +#include "shlobj.h" #include "wine/list.h" #include "wine/vulkan.h"
@@ -216,6 +217,9 @@ extern void register_desktop_class(void); extern LRESULT ime_driver_call( HWND hwnd, enum wine_ime_call call, WPARAM wparam, LPARAM lparam, struct ime_driver_call_params *params );
+/* clipboard.c */ +extern LRESULT drag_drop_call( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, void *data ); + /* cursoricon.c */ HICON alloc_cursoricon_handle( BOOL is_icon );
diff --git a/dlls/winex11.drv/dllmain.c b/dlls/winex11.drv/dllmain.c index 14336adf583..08ef36bdcde 100644 --- a/dlls/winex11.drv/dllmain.c +++ b/dlls/winex11.drv/dllmain.c @@ -31,7 +31,6 @@ BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) { .dnd_enter_event_callback = (UINT_PTR)x11drv_dnd_enter_event, .dnd_position_event_callback = (UINT_PTR)x11drv_dnd_position_event, - .dnd_post_drop_callback = (UINT_PTR)x11drv_dnd_post_drop, .dnd_drop_event_callback = (UINT_PTR)x11drv_dnd_drop_event, .dnd_leave_event_callback = (UINT_PTR)x11drv_dnd_leave_event, .foreign_window_proc = (UINT_PTR)foreign_window_proc, diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 34a364e11e3..3280dce0f10 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1436,17 +1436,10 @@ static HWND find_drop_window( HWND hQueryWnd, LPPOINT lpPt ) return hQueryWnd; }
-static void post_drop( HWND hwnd, DROPFILES *drop, ULONG size ) +static void drag_drop_post( HWND hwnd, DROPFILES *drop, ULONG size ) { - struct dnd_post_drop_params *params; - void *ret_ptr; - ULONG ret_len; - if (!(params = malloc( sizeof(*params) + size - sizeof(*drop) ))) return; - memcpy( ¶ms->drop, drop, size ); - params->drop.fWide = HandleToUlong( hwnd ); /* abuse fWide to pass window handle */ - params->dispatch.callback = dnd_post_drop_callback; - KeUserDispatchCallback( ¶ms->dispatch, size, &ret_ptr, &ret_len ); - free( params ); + NtUserMessageCall( hwnd, WINE_DRAG_DROP_POST, size, (LPARAM)drop, NULL, + NtUserDragDropCall, FALSE ); }
/********************************************************************** @@ -1498,7 +1491,7 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event )
if ((drop = file_list_to_drop_files( p_data, get_property_size( format, data_length ), &drop_size ))) { - post_drop( hWnd, drop, drop_size ); + drag_drop_post( hWnd, drop, drop_size ); free( drop ); } } @@ -1560,7 +1553,7 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) release_win_data( win_data ); }
- post_drop( hWnd, drop, drop_size ); + drag_drop_post( hWnd, drop, drop_size ); free( drop ); }
diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h index 522411f8e55..170cd4f80fc 100644 --- a/dlls/winex11.drv/unixlib.h +++ b/dlls/winex11.drv/unixlib.h @@ -89,14 +89,3 @@ struct dnd_drop_event_params struct dispatch_callback_params dispatch; ULONG hwnd; }; - -/* x11drv_dnd_post_drop params */ -struct dnd_post_drop_params -{ - struct dispatch_callback_params dispatch; - UINT32 __pad; - DROPFILES drop; - char data[]; -}; - -C_ASSERT(sizeof(struct dnd_post_drop_params) == offsetof(struct dnd_post_drop_params, data[0])); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 2ecf3cb54cd..7fb1d601690 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -436,7 +436,6 @@ extern Display *clipboard_display; extern UINT64 client_foreign_window_proc; extern UINT64 dnd_enter_event_callback; extern UINT64 dnd_position_event_callback; -extern UINT64 dnd_post_drop_callback; extern UINT64 dnd_drop_event_callback; extern UINT64 dnd_leave_event_callback;
diff --git a/dlls/winex11.drv/x11drv_dll.h b/dlls/winex11.drv/x11drv_dll.h index bc68c3996c3..3ed9fea6a5a 100644 --- a/dlls/winex11.drv/x11drv_dll.h +++ b/dlls/winex11.drv/x11drv_dll.h @@ -29,7 +29,6 @@
extern NTSTATUS WINAPI x11drv_dnd_enter_event( void *params, ULONG size ); extern NTSTATUS WINAPI x11drv_dnd_position_event( void *params, ULONG size ); -extern NTSTATUS WINAPI x11drv_dnd_post_drop( void *data, ULONG size ); extern NTSTATUS WINAPI x11drv_dnd_drop_event( void *params, ULONG size ); extern NTSTATUS WINAPI x11drv_dnd_leave_event( void *params, ULONG size );
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 3f8e48a7a8d..77169bf287f 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -88,7 +88,6 @@ char *process_name = NULL; UINT64 client_foreign_window_proc = 0; UINT64 dnd_enter_event_callback = 0; UINT64 dnd_position_event_callback = 0; -UINT64 dnd_post_drop_callback = 0; UINT64 dnd_drop_event_callback = 0; UINT64 dnd_leave_event_callback = 0;
@@ -650,7 +649,6 @@ static NTSTATUS x11drv_init( void *arg )
dnd_enter_event_callback = params->dnd_enter_event_callback; dnd_position_event_callback = params->dnd_position_event_callback; - dnd_post_drop_callback = params->dnd_post_drop_callback; dnd_drop_event_callback = params->dnd_drop_event_callback; dnd_leave_event_callback = params->dnd_leave_event_callback; client_foreign_window_proc = params->foreign_window_proc; diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c index 174b764aa63..d9f8380b95e 100644 --- a/dlls/winex11.drv/xdnd.c +++ b/dlls/winex11.drv/xdnd.c @@ -744,24 +744,3 @@ NTSTATUS WINAPI x11drv_dnd_enter_event( void *args, ULONG size ) if (previous) IDataObject_Release( previous ); return STATUS_SUCCESS; } - - -NTSTATUS WINAPI x11drv_dnd_post_drop( void *args, ULONG size ) -{ - UINT drop_size = size - offsetof(struct dnd_post_drop_params, drop); - struct dnd_post_drop_params *params = args; - HDROP handle; - - if ((handle = GlobalAlloc( GMEM_SHARE, drop_size ))) - { - DROPFILES *ptr = GlobalLock( handle ); - HWND hwnd; - memcpy( ptr, ¶ms->drop, drop_size ); - hwnd = UlongToHandle( ptr->fWide ); - ptr->fWide = TRUE; - GlobalUnlock( handle ); - PostMessageW( hwnd, WM_DROPFILES, (WPARAM)handle, 0 ); - } - - return STATUS_SUCCESS; -} diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 33bd65c5fea..f7e311990bc 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -26,6 +26,7 @@ #include "winbase.h" #include "ntuser.h" #include "shellapi.h" +#include "shlobj.h" #include "wow64win_private.h" #include "wine/debug.h"
@@ -1450,6 +1451,26 @@ static NTSTATUS WINAPI wow64_NtUserCallDispatchCallback( void *arg, ULONG size ) return dispatch_callback( NtUserCallDispatchCallback, arg, size ); }
+static NTSTATUS WINAPI wow64_NtUserDragDropPost( void *arg, ULONG size ) +{ + struct drag_drop_post_params32 + { + ULONG hwnd; + UINT drop_size; + struct drop_files drop; + BYTE files[]; + }; + const struct drag_drop_post_params *params = arg; + struct drag_drop_post_params32 *params32; + + size = offsetof(struct drag_drop_post_params32, drop) + params->drop_size; + if (!(params32 = Wow64AllocateTemp( size ))) return STATUS_NO_MEMORY; + params32->hwnd = HandleToUlong( params->hwnd ); + params32->drop_size = params->drop_size; + memcpy( ¶ms32->drop, ¶ms->drop, params->drop_size ); + return dispatch_callback( NtUserDragDropPost, params32, size ); +} + ntuser_callback user_callbacks[] = { /* user32 callbacks */ @@ -1473,6 +1494,7 @@ ntuser_callback user_callbacks[] = wow64_NtUserPostDDEMessage, wow64_NtUserRenderSynthesizedFormat, wow64_NtUserUnpackDDEMessage, + wow64_NtUserDragDropPost, };
C_ASSERT( ARRAYSIZE(user_callbacks) == NtUserCallCount ); @@ -3619,6 +3641,9 @@ NTSTATUS WINAPI wow64_NtUserMessageCall( UINT *args ) default: return NtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); } + + case NtUserDragDropCall: + return NtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); }
return message_call_32to64( hwnd, msg, wparam, lparam, result_info, type, ansi ); diff --git a/include/ntuser.h b/include/ntuser.h index 69dd1e2f434..6282f995ead 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -73,6 +73,7 @@ enum NtUserPostDDEMessage, NtUserRenderSynthesizedFormat, NtUserUnpackDDEMessage, + NtUserDragDropPost, NtUserCallCount };
@@ -299,6 +300,27 @@ struct unpack_dde_message_result LPARAM lparam; };
+/* NtUserDragDropPost params */ + +/* avoid including shlobj.h */ +struct drop_files +{ + DWORD pFiles; + POINT pt; + BOOL fNC; + BOOL fWide; +}; + +struct drag_drop_post_params +{ + HWND hwnd; + UINT drop_size; + struct drop_files drop; + BYTE files[]; +}; + +C_ASSERT( sizeof(struct drag_drop_post_params) == offsetof(struct drag_drop_post_params, files[0]) ); + /* DPI awareness contexts */ #define MAKE_NTUSER_DPI_CONTEXT( awareness, version, dpi, flags ) ((awareness) | ((version) << 4) | ((dpi) << 8) | (flags)) #define NTUSER_DPI_CONTEXT_GET_AWARENESS( ctx ) ((ctx) & 0x0f) @@ -349,6 +371,7 @@ enum NtUserSpyExit = 0x0304, NtUserImeDriverCall = 0x0305, NtUserSystemTrayCall = 0x0306, + NtUserDragDropCall = 0x0307, };
/* NtUserThunkedMenuItemInfo codes */ @@ -568,6 +591,12 @@ enum wine_systray_call WINE_SYSTRAY_DOCK_REMOVE, };
+/* NtUserDragDropCall calls */ +enum wine_drag_drop_call +{ + WINE_DRAG_DROP_POST, +}; + #define WM_SYSTIMER 0x0118