From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/winemac.drv/clipboard.c | 29 ++++++++++++++--------------- dlls/winemac.drv/dragdrop.c | 24 ++++++++++++++++++++++-- dlls/winemac.drv/macdrv.h | 2 +- dlls/winemac.drv/macdrv_main.c | 1 + dlls/winemac.drv/unixlib.h | 10 ++++++++++ 5 files changed, 48 insertions(+), 18 deletions(-)
diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index f46bb389cc9..8a795e61724 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -1128,24 +1128,26 @@ static CFDataRef export_unicodetext_to_utf16(void *data, size_t size)
/************************************************************************** - * macdrv_get_pasteboard_data + * macdrv_dnd_get_data */ -HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) +NTSTATUS macdrv_dnd_get_data(void *arg) { + struct dnd_get_data_params *params = arg; + CFTypeRef pasteboard = pasteboard_from_handle(params->handle); CFArrayRef types; CFIndex count; CFIndex i; CFStringRef type, best_type; WINE_CLIPFORMAT* best_format = NULL; - HANDLE data = NULL; + NTSTATUS status = STATUS_SUCCESS;
- TRACE("pasteboard %p, desired_format %s\n", pasteboard, debugstr_format(desired_format)); + TRACE("pasteboard %p, desired_format %s\n", pasteboard, debugstr_format(params->format));
types = macdrv_copy_pasteboard_types(pasteboard); if (!types) { WARN("Failed to copy pasteboard types\n"); - return NULL; + return STATUS_NO_MEMORY; }
count = CFArrayGetCount(types); @@ -1161,7 +1163,7 @@ HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) { TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id));
- if (format->format_id == desired_format) + if (format->format_id == params->format) { /* The best format is the matching one which is not synthesized. Failing that, the best format is the first matching synthesized format. */ @@ -1183,15 +1185,12 @@ HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) if (pasteboard_data) { size_t size; - void *import = best_format->import_func(pasteboard_data, &size), *ptr; + void *import = best_format->import_func(pasteboard_data, &size); if (import) { - data = GlobalAlloc(GMEM_FIXED, size); - if (data && (ptr = GlobalLock(data))) - { - memcpy(ptr, import, size); - GlobalUnlock(data); - } + if (size > params->size) status = STATUS_BUFFER_OVERFLOW; + else memcpy(params->data, import, size); + params->size = size; free(import); } CFRelease(pasteboard_data); @@ -1199,8 +1198,8 @@ HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) }
CFRelease(types); - TRACE(" -> %p\n", data); - return data; + TRACE(" -> %#x\n", status); + return status; }
diff --git a/dlls/winemac.drv/dragdrop.c b/dlls/winemac.drv/dragdrop.c index 962a9d8c24b..aec8b1f4790 100644 --- a/dlls/winemac.drv/dragdrop.c +++ b/dlls/winemac.drv/dragdrop.c @@ -24,6 +24,8 @@
#define NONAMELESSUNION
+#include "ntstatus.h" +#define WIN32_NO_STATUS #include "macdrv.h"
#define COBJMACROS @@ -92,6 +94,24 @@ static inline DragDropDataObject *impl_from_IDataObject(IDataObject *iface) }
+static HANDLE get_pasteboard_data(UINT64 pasteboard, UINT desired_format) +{ + struct dnd_get_data_params params = { .handle = pasteboard, .format = desired_format, .size = 2048 }; + HANDLE handle; + NTSTATUS status; + + for (;;) + { + if (!(handle = GlobalAlloc(GMEM_FIXED, params.size))) return 0; + params.data = GlobalLock(handle); + status = MACDRV_CALL(dnd_get_data, ¶ms); + GlobalUnlock(handle); + if (!status) return GlobalReAlloc(handle, params.size, 0); + GlobalFree(handle); + if (status != STATUS_BUFFER_OVERFLOW) return 0; + } +} + static HRESULT WINAPI dddo_QueryInterface(IDataObject* iface, REFIID riid, LPVOID *ppvObj) { DragDropDataObject *This = impl_from_IDataObject(iface); @@ -148,7 +168,7 @@ static HRESULT WINAPI dddo_GetData(IDataObject* iface, FORMATETC* formatEtc, STG if (SUCCEEDED(hr)) { medium->tymed = TYMED_HGLOBAL; - medium->u.hGlobal = macdrv_get_pasteboard_data((void *)(UINT_PTR)This->pasteboard, formatEtc->cfFormat); + medium->u.hGlobal = get_pasteboard_data(This->pasteboard, formatEtc->cfFormat); medium->pUnkForRelease = NULL; hr = medium->u.hGlobal ? S_OK : E_OUTOFMEMORY; } @@ -454,7 +474,7 @@ NTSTATUS WINAPI macdrv_dnd_query_drop(void *arg, ULONG size) hwnd = GetParent(hwnd); if (hwnd) { - HDROP hdrop = macdrv_get_pasteboard_data((void *)(UINT_PTR)params->handle, CF_HDROP); + HDROP hdrop = get_pasteboard_data(params->handle, CF_HDROP); DROPFILES *dropfiles = GlobalLock(hdrop); if (dropfiles) { diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 4c1a21a3fe8..a841465486e 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -255,7 +255,6 @@ extern void macdrv_displays_changed(const macdrv_event *event) DECLSPEC_HIDDEN; extern void macdrv_UpdateClipboard(void) DECLSPEC_HIDDEN; extern BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) DECLSPEC_HIDDEN; extern void macdrv_lost_pasteboard_ownership(HWND hwnd) DECLSPEC_HIDDEN; -extern HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) DECLSPEC_HIDDEN;
extern struct opengl_funcs *macdrv_wine_get_wgl_driver(UINT version) DECLSPEC_HIDDEN; extern const struct vulkan_funcs *macdrv_wine_get_vulkan_driver(UINT version) DECLSPEC_HIDDEN; @@ -285,6 +284,7 @@ extern NTSTATUS WINAPI macdrv_ime_query_char_rect(void *params, ULONG size) DECL
/* unixlib interface */
+extern NTSTATUS macdrv_dnd_get_data(void *arg) DECLSPEC_HIDDEN; extern NTSTATUS macdrv_dnd_get_formats(void *arg) DECLSPEC_HIDDEN; extern NTSTATUS macdrv_dnd_have_format(void *arg) DECLSPEC_HIDDEN; extern NTSTATUS macdrv_dnd_release(void *arg) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c index a0b29604e62..61195d408c8 100644 --- a/dlls/winemac.drv/macdrv_main.c +++ b/dlls/winemac.drv/macdrv_main.c @@ -630,6 +630,7 @@ static NTSTATUS macdrv_ime_using_input_method(void *arg)
const unixlib_entry_t __wine_unix_call_funcs[] = { + macdrv_dnd_get_data, macdrv_dnd_get_formats, macdrv_dnd_have_format, macdrv_dnd_release, diff --git a/dlls/winemac.drv/unixlib.h b/dlls/winemac.drv/unixlib.h index b29bf99e7f4..0bfc61321d0 100644 --- a/dlls/winemac.drv/unixlib.h +++ b/dlls/winemac.drv/unixlib.h @@ -21,6 +21,7 @@
enum macdrv_funcs { + unix_dnd_get_data, unix_dnd_get_formats, unix_dnd_have_format, unix_dnd_release, @@ -37,6 +38,15 @@ enum macdrv_funcs extern NTSTATUS unix_call(enum macdrv_funcs code, void *params) DECLSPEC_HIDDEN; #define MACDRV_CALL(func, params) unix_call( unix_ ## func, params )
+/* macdrv_dnd_get_data params */ +struct dnd_get_data_params +{ + UINT64 handle; + UINT format; + size_t size; + void *data; +}; + /* macdrv_dnd_get_formats params */ struct dnd_get_formats_params {