Author: jimtabor Date: Wed Nov 16 17:01:04 2011 New Revision: 54398
URL: http://svn.reactos.org/svn/reactos?rev=54398&view=rev Log: [Ole2] - Fix Adobe Acrobat Reader 7.x from throwing exceptions at start up. Partial sync with wine, See bug 5560.
Modified: trunk/reactos/dll/win32/ole32/ole2.c trunk/reactos/dll/win32/ole32/ole32res.rc
Modified: trunk/reactos/dll/win32/ole32/ole2.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/ole2.c?rev=... ============================================================================== --- trunk/reactos/dll/win32/ole32/ole2.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/ole2.c [iso-8859-1] Wed Nov 16 17:01:04 2011 @@ -6,6 +6,7 @@ * Copyright 1999 Noel Borthwick * Copyright 1999, 2000 Marcus Meissner * Copyright 2005 Juan Lang + * Copyright 2011 Adam Martinson for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -377,6 +378,116 @@ return hr; }
+/* This is to work around apps which break COM rules by not implementing + * IDropTarget::QueryInterface(). Windows doesn't expose this because it + * doesn't call CoMarshallInterface() in RegisterDragDrop(). + * The wrapper is only used internally, and only exists for the life of + * the marshal. */ +typedef struct { + IDropTarget IDropTarget_iface; + IDropTarget* inner; + LONG refs; +} DropTargetWrapper; + +static inline DropTargetWrapper* impl_from_IDropTarget(IDropTarget* iface) +{ + return CONTAINING_RECORD(iface, DropTargetWrapper, IDropTarget_iface); +} + +static HRESULT WINAPI DropTargetWrapper_QueryInterface(IDropTarget* iface, + REFIID riid, + void** ppvObject) +{ + DropTargetWrapper* This = impl_from_IDropTarget(iface); + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IDropTarget)) + { + IDropTarget_AddRef(&This->IDropTarget_iface); + *ppvObject = &This->IDropTarget_iface; + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI DropTargetWrapper_AddRef(IDropTarget* iface) +{ + DropTargetWrapper* This = impl_from_IDropTarget(iface); + return InterlockedIncrement(&This->refs); +} + +static ULONG WINAPI DropTargetWrapper_Release(IDropTarget* iface) +{ + DropTargetWrapper* This = impl_from_IDropTarget(iface); + ULONG refs = InterlockedDecrement(&This->refs); + if (!refs) + { + IDropTarget_Release(This->inner); + HeapFree(GetProcessHeap(), 0, This); + } + return refs; +} + +static HRESULT WINAPI DropTargetWrapper_DragEnter(IDropTarget* iface, + IDataObject* pDataObj, + DWORD grfKeyState, + POINTL pt, + DWORD* pdwEffect) +{ + DropTargetWrapper* This = impl_from_IDropTarget(iface); + return IDropTarget_DragEnter(This->inner, pDataObj, grfKeyState, pt, pdwEffect); +} + +static HRESULT WINAPI DropTargetWrapper_DragOver(IDropTarget* iface, + DWORD grfKeyState, + POINTL pt, + DWORD* pdwEffect) +{ + DropTargetWrapper* This = impl_from_IDropTarget(iface); + return IDropTarget_DragOver(This->inner, grfKeyState, pt, pdwEffect); +} + +static HRESULT WINAPI DropTargetWrapper_DragLeave(IDropTarget* iface) +{ + DropTargetWrapper* This = impl_from_IDropTarget(iface); + return IDropTarget_DragLeave(This->inner); +} + +static HRESULT WINAPI DropTargetWrapper_Drop(IDropTarget* iface, + IDataObject* pDataObj, + DWORD grfKeyState, + POINTL pt, + DWORD* pdwEffect) +{ + DropTargetWrapper* This = impl_from_IDropTarget(iface); + return IDropTarget_Drop(This->inner, pDataObj, grfKeyState, pt, pdwEffect); +} + +static const IDropTargetVtbl DropTargetWrapperVTbl = +{ + DropTargetWrapper_QueryInterface, + DropTargetWrapper_AddRef, + DropTargetWrapper_Release, + DropTargetWrapper_DragEnter, + DropTargetWrapper_DragOver, + DropTargetWrapper_DragLeave, + DropTargetWrapper_Drop +}; + +static IDropTarget* WrapDropTarget(IDropTarget* inner) +{ + DropTargetWrapper* This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + + if (This) + { + IDropTarget_AddRef(inner); + This->IDropTarget_iface.lpVtbl = &DropTargetWrapperVTbl; + This->inner = inner; + This->refs = 1; + } + return &This->IDropTarget_iface; +} + /*********************************************************************** * get_droptarget_pointer * @@ -409,7 +520,7 @@ HRESULT hr; IStream *stream; HANDLE map; - IUnknown *unk; + IDropTarget *wrapper;
TRACE("(%p,%p)\n", hwnd, pDropTarget);
@@ -450,16 +561,15 @@ hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); if(FAILED(hr)) return hr;
- unk = NULL; - hr = IDropTarget_QueryInterface(pDropTarget, &IID_IUnknown, (void**)&unk); - if (SUCCEEDED(hr) && !unk) hr = E_NOINTERFACE; - if(FAILED(hr)) - { - IStream_Release(stream); - return hr; - } - hr = CoMarshalInterface(stream, &IID_IDropTarget, unk, MSHCTX_LOCAL, NULL, MSHLFLAGS_TABLESTRONG); - IUnknown_Release(unk); + /* IDropTarget::QueryInterface() shouldn't be called, some (broken) apps depend on this. */ + wrapper = WrapDropTarget(pDropTarget); + if(!wrapper) + { + IStream_Release(stream); + return E_OUTOFMEMORY; + } + hr = CoMarshalInterface(stream, &IID_IDropTarget, (IUnknown*)wrapper, MSHCTX_LOCAL, NULL, MSHLFLAGS_TABLESTRONG); + IDropTarget_Release(wrapper);
if(SUCCEEDED(hr)) { @@ -812,13 +922,18 @@
typedef struct { - const IEnumOLEVERBVtbl *lpvtbl; + IEnumOLEVERB IEnumOLEVERB_iface; LONG ref;
HKEY hkeyVerb; ULONG index; } EnumOLEVERB;
+static inline EnumOLEVERB *impl_from_IEnumOLEVERB(IEnumOLEVERB *iface) +{ + return CONTAINING_RECORD(iface, EnumOLEVERB, IEnumOLEVERB_iface); +} + static HRESULT WINAPI EnumOLEVERB_QueryInterface( IEnumOLEVERB *iface, REFIID riid, void **ppv) { @@ -836,7 +951,7 @@ static ULONG WINAPI EnumOLEVERB_AddRef( IEnumOLEVERB *iface) { - EnumOLEVERB *This = (EnumOLEVERB *)iface; + EnumOLEVERB *This = impl_from_IEnumOLEVERB(iface); TRACE("()\n"); return InterlockedIncrement(&This->ref); } @@ -844,7 +959,7 @@ static ULONG WINAPI EnumOLEVERB_Release( IEnumOLEVERB *iface) { - EnumOLEVERB *This = (EnumOLEVERB *)iface; + EnumOLEVERB *This = impl_from_IEnumOLEVERB(iface); LONG refs = InterlockedDecrement(&This->ref); TRACE("()\n"); if (!refs) @@ -859,7 +974,7 @@ IEnumOLEVERB *iface, ULONG celt, LPOLEVERB rgelt, ULONG *pceltFetched) { - EnumOLEVERB *This = (EnumOLEVERB *)iface; + EnumOLEVERB *This = impl_from_IEnumOLEVERB(iface); HRESULT hr = S_OK;
TRACE("(%d, %p, %p)\n", celt, rgelt, pceltFetched); @@ -946,7 +1061,7 @@ static HRESULT WINAPI EnumOLEVERB_Skip( IEnumOLEVERB *iface, ULONG celt) { - EnumOLEVERB *This = (EnumOLEVERB *)iface; + EnumOLEVERB *This = impl_from_IEnumOLEVERB(iface);
TRACE("(%d)\n", celt);
@@ -957,7 +1072,7 @@ static HRESULT WINAPI EnumOLEVERB_Reset( IEnumOLEVERB *iface) { - EnumOLEVERB *This = (EnumOLEVERB *)iface; + EnumOLEVERB *This = impl_from_IEnumOLEVERB(iface);
TRACE("()\n");
@@ -969,7 +1084,7 @@ IEnumOLEVERB *iface, IEnumOLEVERB **ppenum) { - EnumOLEVERB *This = (EnumOLEVERB *)iface; + EnumOLEVERB *This = impl_from_IEnumOLEVERB(iface); HKEY hkeyVerb; TRACE("(%p)\n", ppenum); if (!DuplicateHandle(GetCurrentProcess(), This->hkeyVerb, GetCurrentProcess(), (HANDLE *)&hkeyVerb, 0, FALSE, DUPLICATE_SAME_ACCESS)) @@ -996,12 +1111,12 @@ RegCloseKey(hkeyVerb); return E_OUTOFMEMORY; } - This->lpvtbl = &EnumOLEVERB_VTable; + This->IEnumOLEVERB_iface.lpVtbl = &EnumOLEVERB_VTable; This->ref = 1; This->index = index; This->hkeyVerb = hkeyVerb; - *ppenum = (IEnumOLEVERB *)&This->lpvtbl; - return S_OK; + *ppenum = &This->IEnumOLEVERB_iface; + return S_OK; }
/*********************************************************************** @@ -1181,13 +1296,12 @@ } }
- if (SUCCEEDED(hres)) - /* - * Initialize the object with it's IPersistStorage interface. - */ - hres = IOleObject_QueryInterface(pUnk, - &IID_IPersistStorage, - (void**)&persistStorage); + /* + * Initialize the object with its IPersistStorage interface. + */ + hres = IOleObject_QueryInterface(pUnk, + &IID_IPersistStorage, + (void**)&persistStorage);
if (SUCCEEDED(hres)) { @@ -2224,19 +2338,19 @@
if (*trackerInfo->pdwEffect & DROPEFFECT_MOVE) { + hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(2)); + } + else if (*trackerInfo->pdwEffect & DROPEFFECT_COPY) + { + hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(3)); + } + else if (*trackerInfo->pdwEffect & DROPEFFECT_LINK) + { + hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(4)); + } + else + { hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(1)); - } - else if (*trackerInfo->pdwEffect & DROPEFFECT_COPY) - { - hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(2)); - } - else if (*trackerInfo->pdwEffect & DROPEFFECT_LINK) - { - hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(3)); - } - else - { - hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(0)); }
SetCursor(hCur); @@ -2530,7 +2644,17 @@ if (SUCCEEDED(hres2)) { DWORD dwConnection; - hres = IOleCache_Cache(pOleCache, pFormatEtc, ADVF_PRIMEFIRST, &dwConnection); + if (renderopt == OLERENDER_DRAW && !pFormatEtc) { + FORMATETC pfe; + pfe.cfFormat = 0; + pfe.ptd = NULL; + pfe.dwAspect = DVASPECT_CONTENT; + pfe.lindex = -1; + pfe.tymed = TYMED_NULL; + hres = IOleCache_Cache(pOleCache, &pfe, ADVF_PRIMEFIRST, &dwConnection); + } + else + hres = IOleCache_Cache(pOleCache, pFormatEtc, ADVF_PRIMEFIRST, &dwConnection); IOleCache_Release(pOleCache); } } @@ -2614,15 +2738,17 @@ /****************************************************************************** * OleIsRunning [OLE32.@] */ -BOOL WINAPI OleIsRunning(LPOLEOBJECT pObject) +BOOL WINAPI OleIsRunning(LPOLEOBJECT object) { IRunnableObject *pRunnable; HRESULT hr; BOOL running;
- TRACE("(%p)\n", pObject); - - hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnable); + TRACE("(%p)\n", object); + + if (!object) return FALSE; + + hr = IOleObject_QueryInterface(object, &IID_IRunnableObject, (void **)&pRunnable); if (FAILED(hr)) return TRUE; running = IRunnableObject_IsRunning(pRunnable);
Modified: trunk/reactos/dll/win32/ole32/ole32res.rc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/ole32res.rc... ============================================================================== --- trunk/reactos/dll/win32/ole32/ole32res.rc [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/ole32res.rc [iso-8859-1] Wed Nov 16 17:01:04 2011 @@ -23,10 +23,10 @@ #include "winuser.h" #include "winnls.h"
-#define WINE_OLESELFREGISTER #define WINE_FILENAME_STR "ole32.dll" +#define WINE_EXTRAVALUES VALUE "OLESelfRegister",""
-#include <wine/wine_common_ver.rc> +#include "wine/wine_common_ver.rc"
/* * Everything that does not depend on language, @@ -37,13 +37,13 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
/* @makedep: nodrop.cur */ -0 CURSOR nodrop.cur +1 CURSOR nodrop.cur
/* @makedep: drag_move.cur */ -1 CURSOR drag_move.cur +2 CURSOR drag_move.cur
/* @makedep: drag_copy.cur */ -2 CURSOR drag_copy.cur +3 CURSOR drag_copy.cur
/* @makedep: drag_link.cur */ -3 CURSOR drag_link.cur +4 CURSOR drag_link.cur