diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 7376525..5f7abc4 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -746,7 +746,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetDepthStencilSurface(LPDIRECT3DDE } } else { WARN("Call to IWineD3DDevice_GetDepthStencilSurface failed\n"); - *ppZStencilSurface = NULL; + // *ppZStencilSurface = NULL; } LeaveCriticalSection(&d3d9_cs); return hr; diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c index bc2ee97..59f56d8 100644 --- a/dlls/ntdll/om.c +++ b/dlls/ntdll/om.c @@ -108,7 +108,7 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle, } break; default: - FIXME("Unsupported information class %u\n", info_class); + FIXME("Unsupported information class %u compared to %u\n", info_class, ObjectAllInformation); status = STATUS_NOT_IMPLEMENTED; break; } diff --git a/dlls/ole32/ole2.c b/dlls/ole32/ole2.c index 5cee7a1..8294131 100644 --- a/dlls/ole32/ole2.c +++ b/dlls/ole32/ole2.c @@ -279,7 +279,7 @@ HRESULT WINAPI RegisterDragDrop( { DropTargetNode* dropTargetInfo; - TRACE("(%p,%p)\n", hwnd, pDropTarget); + FIXME("(%p,%p)\n", hwnd, pDropTarget); if (!COM_CurrentApt()) { @@ -323,6 +323,7 @@ HRESULT WINAPI RegisterDragDrop( list_add_tail(&targetListHead, &dropTargetInfo->entry); + FIXME("Okay\n"); return S_OK; } @@ -334,7 +335,7 @@ HRESULT WINAPI RevokeDragDrop( { DropTargetNode* dropTargetInfo; - TRACE("(%p)\n", hwnd); + FIXME("(%p)\n", hwnd); if (!IsWindow(hwnd)) { @@ -1940,6 +1941,14 @@ static DropTargetNode* OLEDD_FindDropTarget(HWND hwndOfTarget) return NULL; } +IDropTarget* wine_oledd_find_drop_target(HWND hwndOfTarget) +{ + DropTargetNode *node = OLEDD_FindDropTarget(hwndOfTarget); + if (node) + return node->dropTarget; + return NULL; +} + /*** * OLEDD_DragTrackerWindowProc() * diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 7561156..5c4761f 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -277,3 +277,5 @@ @ stdcall WriteFmtUserTypeStg(ptr long ptr) @ stub WriteOleStg @ stub WriteStringStream +@ cdecl wine_oledd_find_drop_target(long) + diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 49a72eb..e626912 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3382,7 +3382,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetScissorRect(IWineD3DDevice *iface, C static HRESULT WINAPI IWineD3DDeviceImpl_GetScissorRect(IWineD3DDevice *iface, RECT* pRect) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - *pRect = This->updateStateBlock->scissorRect; + // For some, as of yet unexplained, reason, this breaks Spore Creature Creator. + // *pRect = This->updateStateBlock->scissorRect; + // Go back to previous version for now + memcpy(pRect, &This->updateStateBlock->scissorRect, sizeof(pRect)); TRACE("(%p)Returning a Scissor Rect of %d:%d-%d:%d\n", This, pRect->left, pRect->top, pRect->right, pRect->bottom); return WINED3D_OK; } diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c index 1422578..240e494 100644 --- a/dlls/winex11.drv/xdnd.c +++ b/dlls/winex11.drv/xdnd.c @@ -19,6 +19,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS +#include + #include "config.h" #include "wine/port.h" @@ -36,6 +39,8 @@ #include "x11drv.h" #include "shlobj.h" /* DROPFILES */ +#include "oleidl.h" +#include "objidl.h" #include "wine/unicode.h" #include "wine/debug.h" @@ -57,6 +62,10 @@ typedef struct tagXDNDDATA static LPXDNDDATA XDNDData = NULL; static POINT XDNDxy = { 0, 0 }; +extern IDataObject xdndDataObject; +static BOOL XDNDEntered = FALSE; +static BOOL XDNDAccepted = FALSE; +static DWORD XDNDDropEffect = DROPEFFECT_NONE; static void X11DRV_XDND_InsertXDNDData(int property, int format, void* data, unsigned int len); static int X11DRV_XDND_DeconstructTextURIList(int property, void* data, int len); @@ -70,6 +79,10 @@ static void X11DRV_XDND_FreeDragDropOp(void); static unsigned int X11DRV_XDND_UnixToDos(char** lpdest, char* lpsrc, int len); static WCHAR* X11DRV_XDND_URIToDOS(char *encodedURI); +static void X11DRV_XDND_DescribeClipboardFormat(int cfFormat, char *buffer, int size); +static DWORD X11DRV_XDND_ActionToDROPEFFECT(long action); +static long X11DRV_XDND_DROPEFFECTToAction(DWORD effect); + static CRITICAL_SECTION xdnd_cs; static CRITICAL_SECTION_DEBUG critsect_debug = { @@ -150,15 +163,75 @@ void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event ) { XClientMessageEvent e; int accept = 0; /* Assume we're not accepting */ + HMODULE ole32; + IDropTarget *dropTarget = NULL; + DWORD effect; + POINTL pointl; XDNDxy.x = event->data.l[2] >> 16; XDNDxy.y = event->data.l[2] & 0xFFFF; + pointl.x = XDNDxy.x; + pointl.y = XDNDxy.y; + + effect = X11DRV_XDND_ActionToDROPEFFECT(event->data.l[4]); + + /* Notify OLE of DragEnter. Result determines if we accept */ + ole32 = GetModuleHandleA("OLE32.DLL"); + if (ole32) + { + IDropTarget *(CDECL *wine_oledd_find_drop_target)(HWND) = (void*) + GetProcAddress(ole32, "wine_oledd_find_drop_target"); + if (wine_oledd_find_drop_target) + { + dropTarget = wine_oledd_find_drop_target(hWnd); + if (dropTarget) + { + HRESULT hr; + if (XDNDEntered == FALSE) + { + XDNDEntered = TRUE; + hr = IDropTarget_DragEnter(dropTarget, &xdndDataObject, + MK_LBUTTON, pointl, &effect); + if (SUCCEEDED(hr)) + { + if (effect != DROPEFFECT_NONE) + { + XDNDAccepted = TRUE; + TRACE("the application accepted the drop\n"); + } + else + TRACE("the application refused the drop\n"); + } + else + WARN("IDropTarget_DragEnter failed, error 0x%X\n", hr); + } + } + else + TRACE("no drop target\n"); + } + else + WARN("wine_oledd_find_drop_target not found\n"); + } + else + WARN("loading ole32 failed\n"); - /* FIXME: Notify OLE of DragEnter. Result determines if we accept */ + if (XDNDAccepted) + accept = 1; if (GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES) accept = 1; + + /* If drag accepted notify OLE of DragOver */ + if (dropTarget && accept) + { + HRESULT hr = IDropTarget_DragOver(dropTarget, MK_LBUTTON, pointl, &effect); + if (SUCCEEDED(hr)) + XDNDDropEffect = effect; + else + WARN("IDropTarget_DragOver failed, error 0x%X\n", hr); + } + TRACE("action req: %ld accept(%d) at x(%d),y(%d)\n", event->data.l[4], accept, XDNDxy.x, XDNDxy.y); @@ -176,14 +249,12 @@ void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event ) e.data.l[2] = 0; /* Empty Rect */ e.data.l[3] = 0; /* Empty Rect */ if (accept) - e.data.l[4] = event->data.l[4]; + e.data.l[4] = X11DRV_XDND_DROPEFFECTToAction(effect); else e.data.l[4] = None; wine_tsx11_lock(); XSendEvent(event->display, event->data.l[0], False, NoEventMask, (XEvent*)&e); wine_tsx11_unlock(); - - /* FIXME: if drag accepted notify OLE of DragOver */ } /************************************************************************** @@ -194,6 +265,7 @@ void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event ) void X11DRV_XDND_DropEvent( HWND hWnd, XClientMessageEvent *event ) { XClientMessageEvent e; + HMODULE ole32; TRACE("\n"); @@ -201,7 +273,44 @@ void X11DRV_XDND_DropEvent( HWND hWnd, XClientMessageEvent *event ) if (GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES) X11DRV_XDND_SendDropFiles( hWnd ); - /* FIXME: Notify OLE of Drop */ + /* Notify OLE of Drop */ + ole32 = GetModuleHandleA("OLE32.DLL"); + if (ole32) + { + IDropTarget *(CDECL *wine_oledd_find_drop_target)(HWND) = (void*) + GetProcAddress(ole32, "wine_oledd_find_drop_target"); + if (wine_oledd_find_drop_target) + { + IDropTarget *dropTarget = wine_oledd_find_drop_target(hWnd); + if (dropTarget) + { + HRESULT hr; + POINTL pointl; + DWORD effect = XDNDDropEffect; + + pointl.x = XDNDxy.x; + pointl.y = XDNDxy.y; + hr = IDropTarget_Drop(dropTarget, &xdndDataObject, MK_LBUTTON, + pointl, &effect); + if (SUCCEEDED(hr)) + { + if (effect != DROPEFFECT_NONE) + TRACE("drop succeeded\n"); + else + TRACE("the application refused the drop\n"); + } + else + WARN("drop failed, error 0x%X\n", hr); + } + else + TRACE("no drop target\n"); + } + else + WARN("wine_oledd_find_drop_target failed\n"); + } + else + WARN("failed loading ole32\n"); + X11DRV_XDND_FreeDragDropOp(); /* Tell the target we are finished. */ @@ -215,6 +324,8 @@ void X11DRV_XDND_DropEvent( HWND hWnd, XClientMessageEvent *event ) wine_tsx11_lock(); XSendEvent(event->display, event->data.l[0], False, NoEventMask, (XEvent*)&e); wine_tsx11_unlock(); + + XDNDEntered = XDNDAccepted = FALSE; } /************************************************************************** @@ -224,11 +335,36 @@ void X11DRV_XDND_DropEvent( HWND hWnd, XClientMessageEvent *event ) */ void X11DRV_XDND_LeaveEvent( HWND hWnd, XClientMessageEvent *event ) { + HMODULE ole32; TRACE("DND Operation canceled\n"); X11DRV_XDND_FreeDragDropOp(); - /* FIXME: Notify OLE of DragLeave */ + /* Notify OLE of DragLeave */ + ole32 = GetModuleHandleA("OLE32.DLL"); + if (ole32) + { + IDropTarget *(CDECL *wine_oledd_find_drop_target)(HWND) = (void*) + GetProcAddress(ole32, "wine_oledd_find_drop_target"); + if (wine_oledd_find_drop_target) + { + IDropTarget *dropTarget = wine_oledd_find_drop_target(hWnd); + if (dropTarget) + { + HRESULT hr = IDropTarget_DragLeave(dropTarget); + if (FAILED(hr)) + WARN("IDropTarget_DragLeave failed, error 0x%X\n", hr); + } + else + TRACE("drop target not found\n"); + } + else + WARN("wine_oledd_find_drop_target not found\n"); + } + else + WARN("loading ole32 failed\n"); + + XDNDEntered = XDNDAccepted = FALSE; } @@ -248,6 +384,9 @@ static void X11DRV_XDND_ResolveProperty(Display *display, Window xwin, Time tm, unsigned long bytesret, icount; int entries = 0; unsigned char* data = NULL; + XDNDDATA *previous = NULL; + XDNDDATA *current, *next; + BOOL haveHDROP = FALSE; TRACE("count(%ld)\n", *count); @@ -292,6 +431,67 @@ static void X11DRV_XDND_ResolveProperty(Display *display, Window xwin, Time tm, wine_tsx11_unlock(); } + /* We get the list of formats in descending order of preference, yet the linked + * list is a stack so the order is inverted. Reverse the linked list here so + * that we get the right order. + */ + current = XDNDData; + while (current != NULL) + { + next = current->next; + current->next = previous; + previous = current; + current = next; + } + if (previous) + XDNDData = previous; + + /* On Windows when there is a CF_HDROP, there is no other CF_ formats. + * foobar2000 relies on this (spaces -> %20's without it). + */ + current = XDNDData; + while (current != NULL) + { + if (current->cf_win == CF_HDROP) + { + haveHDROP = TRUE; + break; + } + current = current->next; + } + if (haveHDROP) + { + current = XDNDData; + while (current != NULL + && current->cf_win != CF_HDROP + && current->cf_win < CF_MAX) + { + next = current->next; + HeapFree(GetProcessHeap(), 0, current->data); + HeapFree(GetProcessHeap(), 0, current); + current = next; + --entries; + } + XDNDData = previous = current; + while (current != NULL) + { + current = current->next; + while (current != NULL + && current->cf_win != CF_HDROP + && current->cf_win < CF_MAX) + { + next = current->next; + HeapFree(GetProcessHeap(), 0, current->data); + HeapFree(GetProcessHeap(), 0, current); + current = next; + --entries; + } + previous->next = current; + previous = current; + } + } + + *count = entries; } @@ -329,7 +529,7 @@ static int X11DRV_XDND_MapFormat(unsigned int property, unsigned char *data, int void* xdata; int count = 0; - TRACE("%d: %s\n", property, data); + TRACE("%d: len %i\n", property, strlen((char*) data)); /* Always include the raw type */ xdata = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); @@ -424,6 +624,7 @@ static int X11DRV_XDND_DeconstructTextURIList(int property, void* data, int len) dropFiles->fNC = 0; dropFiles->fWide = FALSE; out[size] = '\0'; + FIXME("Out: %s\n", out); memcpy(((char*)dropFiles) + dropFiles->pFiles, out, size + 1); X11DRV_XDND_InsertXDNDData(property, CF_HDROP, dropFiles, sizeof(DROPFILES) + size + 1); count = 1; @@ -652,6 +853,331 @@ static WCHAR* X11DRV_XDND_URIToDOS(char *encodedURI) ret = wine_get_dos_file_name(&uri[5]); } } + else if (strncmp(uri, "http://", 7) == 0) + { + FIXME("Hack ensues.\n"); + char tmp[1024]; + char *tn = tmpnam(tmp); + int len = strlen(tn) + strlen("wget ") + strlen(" -O ") + strlen(uri) + strlen(strrchr(uri, '/')+1); + char *cmd = (char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); + strcpy(cmd, "wget "); strcat(cmd, uri); strcat(cmd, " -O "); strcat(cmd, tn); strcat(cmd, strrchr(uri, '/')+1); + system(cmd); + ret = wine_get_dos_file_name(strstr(cmd, " -O ")+4); + HeapFree(GetProcessHeap(), 0, cmd); + } HeapFree(GetProcessHeap(), 0, uri); return ret; } + +/************************************************************************** + * X11DRV_XDND_DescribeClipboardFormat + */ +static void X11DRV_XDND_DescribeClipboardFormat(int cfFormat, char *buffer, int size) +{ +#define D(x) case x: lstrcpynA(buffer, #x, size); return; + switch (cfFormat) + { + D(CF_TEXT) + D(CF_BITMAP) + D(CF_METAFILEPICT) + D(CF_SYLK) + D(CF_DIF) + D(CF_TIFF) + D(CF_OEMTEXT) + D(CF_DIB) + D(CF_PALETTE) + D(CF_PENDATA) + D(CF_RIFF) + D(CF_WAVE) + D(CF_UNICODETEXT) + D(CF_ENHMETAFILE) + D(CF_HDROP) + D(CF_LOCALE) + D(CF_DIBV5) + } +#undef D + + if (CF_PRIVATEFIRST <= cfFormat && cfFormat <= CF_PRIVATELAST) + { + GetClipboardFormatNameA(cfFormat, buffer, size); + return; + } + + if (CF_GDIOBJFIRST <= cfFormat && cfFormat <= CF_GDIOBJLAST) + { + lstrcpynA(buffer, "some GDI object", size); + return; + } + + snprintf(buffer, size, "unknown format %d", cfFormat); +} + + +/************************************************************************** + * X11DRV_XDND_ActionToDROPEFFECT + */ +static DWORD X11DRV_XDND_ActionToDROPEFFECT(long action) +{ + /* In Windows, nothing but the given effects is allowed. + * In X the given action is just a hint, and you can always + * XdndActionCopy and XdndActionPrivate, so be more permissive. */ + if (action == x11drv_atom(XdndActionCopy)) + return DROPEFFECT_COPY; + else if (action == x11drv_atom(XdndActionMove)) + return DROPEFFECT_MOVE | DROPEFFECT_COPY; + else if (action == x11drv_atom(XdndActionLink)) + return DROPEFFECT_LINK | DROPEFFECT_COPY; + else if (action == x11drv_atom(XdndActionAsk)) + /* FIXME: should we somehow ask the user what to do here? */ + return DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_LINK; + FIXME("unknown action %ld, assuming DROPEFFECT_COPY\n", action); + return DROPEFFECT_COPY; +} + + +/************************************************************************** + * X11DRV_XDND_DROPEFFECTToAction + */ +static long X11DRV_XDND_DROPEFFECTToAction(DWORD effect) +{ + if (effect == DROPEFFECT_COPY) + return x11drv_atom(XdndActionCopy); + else if (effect == DROPEFFECT_MOVE) + return x11drv_atom(XdndActionMove); + else if (effect == DROPEFFECT_LINK) + return x11drv_atom(XdndActionLink); + FIXME("unknown drop effect %u, assuming XdndActionCopy\n", effect); + return x11drv_atom(XdndActionCopy); +} + + +/* The IDataObject singleton we feed to OLE follows */ + +static HRESULT WINAPI DATAOBJECT_QueryInterface(IDataObject *dataObject, + REFIID riid, void **ppvObject) +{ + TRACE("(%p, %s, %p)\n", dataObject, debugstr_guid(riid), ppvObject); + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDataObject)) + { + *ppvObject = dataObject; + IDataObject_AddRef(dataObject); + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI DATAOBJECT_AddRef(IDataObject *dataObject) +{ + TRACE("(%p)\n", dataObject); + return 2; +} + +static ULONG WINAPI DATAOBJECT_Release(IDataObject *dataObject) +{ + TRACE("(%p)\n", dataObject); + return 1; +} + +static HRESULT WINAPI DATAOBJECT_GetData(IDataObject *dataObject, + FORMATETC *formatEtc, + STGMEDIUM *pMedium) +{ + XDNDDATA *data = XDNDData; + HRESULT hr; + char buffer[1024]; + + TRACE("(%p, %p, %p)\n", dataObject, formatEtc, pMedium); + X11DRV_XDND_DescribeClipboardFormat(formatEtc->cfFormat, + buffer, sizeof(buffer)); + TRACE("application is looking for %s\n", buffer); + + hr = IDataObject_QueryGetData(dataObject, formatEtc); + if (SUCCEEDED(hr)) + { + while (data != NULL) + { + if (data->cf_win == formatEtc->cfFormat) + { + pMedium->tymed = TYMED_HGLOBAL; + pMedium->hGlobal = HeapAlloc(GetProcessHeap(), 0, data->size); + if (pMedium->hGlobal == NULL) + return E_OUTOFMEMORY; + memcpy(pMedium->hGlobal, data->data, data->size); + pMedium->pUnkForRelease = 0; + return S_OK; + } + data = data->next; + } + } + return hr; +} + +static HRESULT WINAPI DATAOBJECT_GetDataHere(IDataObject *dataObject, + FORMATETC *formatEtc, + STGMEDIUM *pMedium) +{ + FIXME("(%p, %p, %p): stub\n", dataObject, formatEtc, pMedium); + return DATA_E_FORMATETC; +} + +static HRESULT WINAPI DATAOBJECT_QueryGetData(IDataObject *dataObject, + FORMATETC *formatEtc) +{ + XDNDDATA *data = XDNDData; + char buffer[1024]; + + TRACE("(%p, %p)\n", dataObject, formatEtc); + X11DRV_XDND_DescribeClipboardFormat(formatEtc->cfFormat, buffer, + sizeof(buffer)); + + if (formatEtc->tymed != TYMED_HGLOBAL) + { + FIXME("only HGLOBAL medium types supported right now\n"); + return E_NOTIMPL; + } + if (formatEtc->dwAspect != DVASPECT_CONTENT) + { + FIXME("only the content aspect is supported right now\n"); + return E_NOTIMPL; + } + + while (data != NULL) + { + if (data->cf_win == formatEtc->cfFormat) + { + TRACE("application found %s\n", buffer); + TRACE("Data is: %i %.*s\n", data->size, data->size, (char*) data->data); + return S_OK; + } + data = data->next; + } + TRACE("application didn't find %s\n", buffer); + return DV_E_FORMATETC; +} + +static HRESULT WINAPI DATAOBJECT_GetCanonicalFormatEtc(IDataObject *dataObject, + FORMATETC *formatEtc, + FORMATETC *formatEtcOut) +{ + FIXME("(%p, %p, %p): stub\n", dataObject, formatEtc, formatEtcOut); + formatEtcOut->ptd = NULL; + return E_NOTIMPL; +} + +static HRESULT WINAPI DATAOBJECT_SetData(IDataObject *dataObject, + FORMATETC *formatEtc, + STGMEDIUM *pMedium, BOOL fRelease) +{ + FIXME("(%p, %p, %p, %s): stub\n", dataObject, formatEtc, + pMedium, fRelease?"TRUE":"FALSE"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DATAOBJECT_EnumFormatEtc(IDataObject *dataObject, + DWORD dwDirection, + IEnumFORMATETC **ppEnumFormatEtc) +{ + HMODULE shell32; + XDNDDATA *data = XDNDData; + int i; + DWORD count = 0; + FORMATETC *formats; + HRESULT hr; + + TRACE("(%u, %p)\n", dwDirection, ppEnumFormatEtc); + + if (dwDirection != DATADIR_GET) + { + FIXME("only the get direction is implemented\n"); + return E_NOTIMPL; + } + + while (data != NULL) + { + data = data->next; + ++count; + } + + formats = HeapAlloc(GetProcessHeap(), 0, count * sizeof(FORMATETC)); + if (formats) + { + data = XDNDData; + for (i = 0; i < count; ++i) + { + formats[i].cfFormat = data->cf_win; + formats[i].ptd = NULL; + formats[i].dwAspect = DVASPECT_CONTENT; + formats[i].lindex = -1; + formats[i].tymed = TYMED_HGLOBAL; + data = data->next; + } + /* For some strange reason, load-time linking SHELL32.DLL to WINEX11.DRV + * causes wine to segfault on startup. So rather use run-time linking. + */ + shell32 = LoadLibraryA("SHELL32.DLL"); + if (shell32) + { + HRESULT (WINAPI *SHCreateStdEnumFmtEtc)(DWORD, FORMATETC*, IEnumFORMATETC**) = (void*) + GetProcAddress(shell32, (char*) MAKELONG(74, 0)); + if (SHCreateStdEnumFmtEtc) + hr = SHCreateStdEnumFmtEtc(count, formats, ppEnumFormatEtc); + else + { + ERR("symbol lookup of SHCreateStdEnumFmtEtc failed\n"); + hr = E_FAIL; + } + } + else + { + WARN("loading SHELL32.DLL failed\n"); + hr = E_FAIL; + } + HeapFree(GetProcessHeap(), 0, formats); + return hr; + } + else + return E_OUTOFMEMORY; +} + +static HRESULT WINAPI DATAOBJECT_DAdvise(IDataObject *dataObject, + FORMATETC *formatEtc, DWORD advf, + IAdviseSink *adviseSink, + DWORD *pdwConnection) +{ + FIXME("(%p, %p, %u, %p, %p): stub\n", dataObject, formatEtc, advf, + adviseSink, pdwConnection); + return OLE_E_ADVISENOTSUPPORTED; +} + +static HRESULT WINAPI DATAOBJECT_DUnadvise(IDataObject *dataObject, + DWORD dwConnection) +{ + FIXME("(%p, %u): stub\n", dataObject, dwConnection); + return OLE_E_ADVISENOTSUPPORTED; +} + +static HRESULT WINAPI DATAOBJECT_EnumDAdvise(IDataObject *dataObject, + IEnumSTATDATA **pEnumAdvise) +{ + FIXME("(%p, %p): stub\n", dataObject, pEnumAdvise); + return OLE_E_ADVISENOTSUPPORTED; +} + +static IDataObjectVtbl xdndDataObjectVtbl = +{ + DATAOBJECT_QueryInterface, + DATAOBJECT_AddRef, + DATAOBJECT_Release, + DATAOBJECT_GetData, + DATAOBJECT_GetDataHere, + DATAOBJECT_QueryGetData, + DATAOBJECT_GetCanonicalFormatEtc, + DATAOBJECT_SetData, + DATAOBJECT_EnumFormatEtc, + DATAOBJECT_DAdvise, + DATAOBJECT_DUnadvise, + DATAOBJECT_EnumDAdvise +}; + +IDataObject xdndDataObject = { &xdndDataObjectVtbl };