[OLE32] Sync with Wine Staging 2.9. CORE-13362

9cc976a ole32: Fix compilation with recent versions of gcc.
2e36326 ole32: Synthesize dibs or bitmaps as appropriate.
e27708f ole32: Create CF_DIB and CF_BITMAP entries when either is cached.
20a8f1a ole32: Implement IOleCache_EnumCache().
f9b0f60 ole32: Check the cache entry's stgmedium for the unloaded state.
8fc1a4c ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject.
1d2860e ole32: Fix up the dib's resolution on loading.
e7bb4ba ole32: Don't cache the BITMAPFILEHEADER.
fc49d98 ole32: Set the advise flags in CreateEntry().
77d1eba ole32: Use the helper function to copy the clipboard's FORMATETC.
9ee30d7 ole32: Use the helper function to copy the datacache's FORMATETC.
11db491 ole32: Add a helper to copy FORMATETC structures.
b399baf ole32: Add CoRegisterSurrogate/Ex stubs.
87dba2b ole32: Zero STGMEDIUM before calling IDataObject::GetData.
c7e6fe6 ole32: Added GlobalOptions object stub implementation.
fd09c37 ole32: Use generic class factory for StdComponentCategoriesMgr object.
076c782 ole32: Use generic class factory for pointer moniker.
961c3dc ole32: Use generic class factory for class moniker.
947c9ba ole32: Use generic class factory for composite moniker.
b05fd46 ole32: Use generic class factory for anti moniker.
dee6463 ole32: Use generic class factory for item moniker.
cf7883f ole32: Added generic class factory implementation and use it for file moniker.

svn path=/trunk/; revision=74829
This commit is contained in:
Amine Khaldi 2017-06-03 22:33:33 +00:00
parent 3152f3df52
commit e1f8933518
17 changed files with 633 additions and 488 deletions

View file

@ -616,30 +616,8 @@ HRESULT WINAPI CreateAntiMoniker(IMoniker **ppmk)
(void**)ppmk);
}
static HRESULT WINAPI AntiMonikerCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IClassFactory_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI AntiMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI AntiMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI AntiMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
HRESULT WINAPI AntiMoniker_CreateInstance(IClassFactory *iface,
IUnknown *pUnk, REFIID riid, void **ppv)
{
IMoniker *pMoniker;
HRESULT hr;
@ -662,24 +640,3 @@ static HRESULT WINAPI AntiMonikerCF_CreateInstance(LPCLASSFACTORY iface,
return hr;
}
static HRESULT WINAPI AntiMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl AntiMonikerCFVtbl =
{
AntiMonikerCF_QueryInterface,
AntiMonikerCF_AddRef,
AntiMonikerCF_Release,
AntiMonikerCF_CreateInstance,
AntiMonikerCF_LockServer
};
static const IClassFactoryVtbl *AntiMonikerCF = &AntiMonikerCFVtbl;
HRESULT AntiMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&AntiMonikerCF, riid, ppv);
}

View file

@ -791,30 +791,8 @@ HRESULT ClassMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName, LP
return hr;
}
static HRESULT WINAPI ClassMonikerCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IClassFactory_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI ClassMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI ClassMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI ClassMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
HRESULT WINAPI ClassMoniker_CreateInstance(IClassFactory *iface,
IUnknown *pUnk, REFIID riid, void **ppv)
{
HRESULT hr;
IMoniker *pmk;
@ -834,25 +812,3 @@ static HRESULT WINAPI ClassMonikerCF_CreateInstance(LPCLASSFACTORY iface,
return hr;
}
static HRESULT WINAPI ClassMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl ClassMonikerCFVtbl =
{
ClassMonikerCF_QueryInterface,
ClassMonikerCF_AddRef,
ClassMonikerCF_Release,
ClassMonikerCF_CreateInstance,
ClassMonikerCF_LockServer
};
static IClassFactory ClassMonikerCF = { &ClassMonikerCFVtbl };
HRESULT ClassMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface(&ClassMonikerCF, riid, ppv);
}

View file

@ -311,14 +311,8 @@ static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Next
for(i = 0; i < cfetch; i++)
{
rgelt[i] = This->data->entries[This->pos++].fmtetc;
if(rgelt[i].ptd)
{
DVTARGETDEVICE *target = rgelt[i].ptd;
rgelt[i].ptd = CoTaskMemAlloc(target->tdSize);
if(!rgelt[i].ptd) return E_OUTOFMEMORY;
memcpy(rgelt[i].ptd, target, target->tdSize);
}
hres = copy_formatetc(rgelt + i, &This->data->entries[This->pos++].fmtetc);
if(FAILED(hres)) return hres;
}
}
else
@ -722,7 +716,7 @@ static HRESULT get_data_from_storage(IDataObject *data, FORMATETC *fmt, HGLOBAL
hr = IDataObject_GetDataHere(data, &stg_fmt, &med);
if(FAILED(hr))
{
med.u.pstg = NULL;
memset(&med, 0, sizeof(med));
hr = IDataObject_GetData(data, &stg_fmt, &med);
if(FAILED(hr)) goto end;
@ -770,7 +764,7 @@ static HRESULT get_data_from_stream(IDataObject *data, FORMATETC *fmt, HGLOBAL *
LARGE_INTEGER offs;
ULARGE_INTEGER pos;
med.u.pstm = NULL;
memset(&med, 0, sizeof(med));
hr = IDataObject_GetData(data, &stm_fmt, &med);
if(FAILED(hr)) goto error;
@ -807,9 +801,7 @@ static HRESULT get_data_from_global(IDataObject *data, FORMATETC *fmt, HGLOBAL *
mem_fmt = *fmt;
mem_fmt.tymed = TYMED_HGLOBAL;
#ifdef __REACTOS__
med.pUnkForRelease = NULL;
#endif
memset(&med, 0, sizeof(med));
hr = IDataObject_GetData(data, &mem_fmt, &med);
if(FAILED(hr)) return hr;
@ -837,6 +829,7 @@ static HRESULT get_data_from_enhmetafile(IDataObject *data, FORMATETC *fmt, HGLO
mem_fmt = *fmt;
mem_fmt.tymed = TYMED_ENHMF;
memset(&med, 0, sizeof(med));
hr = IDataObject_GetData(data, &mem_fmt, &med);
if(FAILED(hr)) return hr;
@ -864,6 +857,7 @@ static HRESULT get_data_from_metafilepict(IDataObject *data, FORMATETC *fmt, HGL
mem_fmt = *fmt;
mem_fmt.tymed = TYMED_MFPICT;
memset(&med, 0, sizeof(med));
hr = IDataObject_GetData(data, &mem_fmt, &med);
if(FAILED(hr)) return hr;
@ -893,6 +887,7 @@ static HRESULT get_data_from_bitmap(IDataObject *data, FORMATETC *fmt, HBITMAP *
mem_fmt = *fmt;
mem_fmt.tymed = TYMED_GDI;
memset(&med, 0, sizeof(med));
hr = IDataObject_GetData(data, &mem_fmt, &med);
if(FAILED(hr)) return hr;
@ -1378,6 +1373,8 @@ static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt,
if ( !fmt || !med ) return E_INVALIDARG;
memset(med, 0, sizeof(*med));
if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN;
if(!This->data)
@ -1770,35 +1767,6 @@ void OLEClipbrd_Initialize(void)
}
}
/***********************************************************************
* OLEClipbrd_UnInitialize()
* Un-Initializes the OLE clipboard
*/
void OLEClipbrd_UnInitialize(void)
{
ole_clipbrd *clipbrd = theOleClipboard;
TRACE("()\n");
if ( clipbrd )
{
static const WCHAR ole32W[] = {'o','l','e','3','2',0};
HINSTANCE hinst = GetModuleHandleW(ole32W);
if ( clipbrd->window )
{
DestroyWindow(clipbrd->window);
UnregisterClassW( clipbrd_wndclass, hinst );
}
IStream_Release(clipbrd->marshal_data);
if (clipbrd->src_data) IDataObject_Release(clipbrd->src_data);
HeapFree(GetProcessHeap(), 0, clipbrd->cached_enum);
HeapFree(GetProcessHeap(), 0, clipbrd);
theOleClipboard = NULL;
}
}
/*********************************************************************
* set_clipboard_formats
*
@ -1998,6 +1966,41 @@ static HRESULT set_src_dataobject(ole_clipbrd *clipbrd, IDataObject *data)
return hr;
}
/***********************************************************************
* OLEClipbrd_UnInitialize()
* Un-Initializes the OLE clipboard
*/
void OLEClipbrd_UnInitialize(void)
{
ole_clipbrd *clipbrd = theOleClipboard;
TRACE("()\n");
if ( clipbrd )
{
static const WCHAR ole32W[] = {'o','l','e','3','2',0};
HINSTANCE hinst = GetModuleHandleW(ole32W);
/* OleUninitialize() does not release the reference to the dataobject, so
take an additional reference here. This reference is then leaked. */
if (clipbrd->src_data)
{
IDataObject_AddRef(clipbrd->src_data);
set_src_dataobject(clipbrd, NULL);
}
if ( clipbrd->window )
{
DestroyWindow(clipbrd->window);
UnregisterClassW( clipbrd_wndclass, hinst );
}
IStream_Release(clipbrd->marshal_data);
HeapFree(GetProcessHeap(), 0, clipbrd);
theOleClipboard = NULL;
}
}
/***********************************************************************
* clipbrd_wndproc
*/

View file

@ -684,53 +684,7 @@ static const ICatInformationVtbl COMCAT_ICatInformation_Vtbl =
COMCAT_ICatInformation_EnumReqCategoriesOfClass
};
/**********************************************************************
* COMCAT_IClassFactory_QueryInterface (also IUnknown)
*/
static HRESULT WINAPI COMCAT_IClassFactory_QueryInterface(
LPCLASSFACTORY iface,
REFIID riid,
LPVOID *ppvObj)
{
TRACE("%s\n",debugstr_guid(riid));
if (ppvObj == NULL) return E_POINTER;
if (IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IClassFactory))
{
*ppvObj = iface;
IClassFactory_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
/**********************************************************************
* COMCAT_IClassFactory_AddRef (also IUnknown)
*/
static ULONG WINAPI COMCAT_IClassFactory_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
/**********************************************************************
* COMCAT_IClassFactory_Release (also IUnknown)
*/
static ULONG WINAPI COMCAT_IClassFactory_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
/**********************************************************************
* COMCAT_IClassFactory_CreateInstance
*/
static HRESULT WINAPI COMCAT_IClassFactory_CreateInstance(
LPCLASSFACTORY iface,
LPUNKNOWN pUnkOuter,
REFIID riid,
LPVOID *ppvObj)
HRESULT WINAPI ComCat_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter, REFIID riid, void **ppvObj)
{
HRESULT res;
TRACE("%s\n",debugstr_guid(riid));
@ -748,36 +702,6 @@ static HRESULT WINAPI COMCAT_IClassFactory_CreateInstance(
return CLASS_E_CLASSNOTAVAILABLE;
}
/**********************************************************************
* COMCAT_IClassFactory_LockServer
*/
static HRESULT WINAPI COMCAT_IClassFactory_LockServer(
LPCLASSFACTORY iface,
BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
/**********************************************************************
* static ClassFactory instance
*/
static const IClassFactoryVtbl ComCatCFVtbl =
{
COMCAT_IClassFactory_QueryInterface,
COMCAT_IClassFactory_AddRef,
COMCAT_IClassFactory_Release,
COMCAT_IClassFactory_CreateInstance,
COMCAT_IClassFactory_LockServer
};
static const IClassFactoryVtbl *ComCatCF = &ComCatCFVtbl;
HRESULT ComCatCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&ComCatCF, riid, ppv);
}
/**********************************************************************
* IEnumCATEGORYINFO implementation
*

View file

@ -2974,6 +2974,8 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
if (release_apt) apartment_release(apt);
return FTMarshalCF_Create(iid, ppv);
}
if (IsEqualCLSID(rclsid, &CLSID_GlobalOptions))
return IClassFactory_QueryInterface(&GlobalOptionsCF, iid, ppv);
}
if (CLSCTX_INPROC & dwClsContext)
@ -5050,6 +5052,122 @@ HRESULT WINAPI CoGetApartmentType(APTTYPE *type, APTTYPEQUALIFIER *qualifier)
return info->apt ? S_OK : CO_E_NOTINITIALIZED;
}
/***********************************************************************
* CoRegisterSurrogate [OLE32.@]
*/
HRESULT WINAPI CoRegisterSurrogate(ISurrogate *surrogate)
{
FIXME("(%p): stub\n", surrogate);
return E_NOTIMPL;
}
/***********************************************************************
* CoRegisterSurrogateEx [OLE32.@]
*/
HRESULT WINAPI CoRegisterSurrogateEx(REFGUID guid, void *reserved)
{
FIXME("(%s %p): stub\n", debugstr_guid(guid), reserved);
return E_NOTIMPL;
}
typedef struct {
IGlobalOptions IGlobalOptions_iface;
LONG ref;
} GlobalOptions;
static inline GlobalOptions *impl_from_IGlobalOptions(IGlobalOptions *iface)
{
return CONTAINING_RECORD(iface, GlobalOptions, IGlobalOptions_iface);
}
static HRESULT WINAPI GlobalOptions_QueryInterface(IGlobalOptions *iface, REFIID riid, void **ppv)
{
GlobalOptions *This = impl_from_IGlobalOptions(iface);
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
if (IsEqualGUID(&IID_IGlobalOptions, riid) || IsEqualGUID(&IID_IUnknown, riid))
{
*ppv = iface;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI GlobalOptions_AddRef(IGlobalOptions *iface)
{
GlobalOptions *This = impl_from_IGlobalOptions(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI GlobalOptions_Release(IGlobalOptions *iface)
{
GlobalOptions *This = impl_from_IGlobalOptions(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if (!ref)
heap_free(This);
return ref;
}
static HRESULT WINAPI GlobalOptions_Set(IGlobalOptions *iface, GLOBALOPT_PROPERTIES property, ULONG_PTR value)
{
GlobalOptions *This = impl_from_IGlobalOptions(iface);
FIXME("(%p)->(%u %lx)\n", This, property, value);
return S_OK;
}
static HRESULT WINAPI GlobalOptions_Query(IGlobalOptions *iface, GLOBALOPT_PROPERTIES property, ULONG_PTR *value)
{
GlobalOptions *This = impl_from_IGlobalOptions(iface);
FIXME("(%p)->(%u %p)\n", This, property, value);
return E_NOTIMPL;
}
static const IGlobalOptionsVtbl GlobalOptionsVtbl = {
GlobalOptions_QueryInterface,
GlobalOptions_AddRef,
GlobalOptions_Release,
GlobalOptions_Set,
GlobalOptions_Query
};
HRESULT WINAPI GlobalOptions_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
{
GlobalOptions *global_options;
HRESULT hres;
TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);
if (outer)
return E_INVALIDARG;
global_options = heap_alloc(sizeof(*global_options));
if (!global_options)
return E_OUTOFMEMORY;
global_options->IGlobalOptions_iface.lpVtbl = &GlobalOptionsVtbl;
global_options->ref = 1;
hres = IGlobalOptions_QueryInterface(&global_options->IGlobalOptions_iface, riid, ppv);
IGlobalOptions_Release(&global_options->IGlobalOptions_iface);
return hres;
}
/***********************************************************************
* DllMain (OLE32.@)
*/

View file

@ -286,6 +286,10 @@ extern HRESULT WINAPI OLE32_DllUnregisterServer(void) DECLSPEC_HIDDEN;
extern HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
extern HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
extern HRESULT WINAPI GlobalOptions_CreateInstance(IClassFactory *iface, IUnknown *pUnk,
REFIID riid, void **ppv) DECLSPEC_HIDDEN;
extern IClassFactory GlobalOptionsCF DECLSPEC_HIDDEN;
/* Exported non-interface Data Advise Holder functions */
HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDelegate) DECLSPEC_HIDDEN;
void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface) DECLSPEC_HIDDEN;
@ -319,4 +323,19 @@ static inline BOOL heap_free(void *mem)
return HeapFree(GetProcessHeap(), 0, mem);
}
static inline HRESULT copy_formatetc(FORMATETC *dst, const FORMATETC *src)
{
*dst = *src;
if (src->ptd)
{
dst->ptd = CoTaskMemAlloc( src->ptd->tdSize );
if (!dst->ptd) return E_OUTOFMEMORY;
memcpy( dst->ptd, src->ptd, src->ptd->tdSize );
}
return S_OK;
}
extern HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data,
BOOL copy, IEnumSTATDATA **ppenum) DECLSPEC_HIDDEN;
#endif /* __WINE_OLE_COMPOBJ_H */

View file

@ -1976,30 +1976,8 @@ MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkComm
return E_NOTIMPL;
}
static HRESULT WINAPI CompositeMonikerCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IClassFactory_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI CompositeMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI CompositeMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI CompositeMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
HRESULT WINAPI CompositeMoniker_CreateInstance(IClassFactory *iface,
IUnknown *pUnk, REFIID riid, void **ppv)
{
IMoniker* pMoniker;
HRESULT hr;
@ -2021,24 +1999,3 @@ static HRESULT WINAPI CompositeMonikerCF_CreateInstance(LPCLASSFACTORY iface,
return hr;
}
static HRESULT WINAPI CompositeMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl CompositeMonikerCFVtbl =
{
CompositeMonikerCF_QueryInterface,
CompositeMonikerCF_AddRef,
CompositeMonikerCF_Release,
CompositeMonikerCF_CreateInstance,
CompositeMonikerCF_LockServer
};
static const IClassFactoryVtbl *CompositeMonikerCF = &CompositeMonikerCFVtbl;
HRESULT CompositeMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&CompositeMonikerCF, riid, ppv);
}

View file

@ -209,12 +209,41 @@ const char *debugstr_formatetc(const FORMATETC *formatetc)
formatetc->lindex, formatetc->tymed);
}
/***********************************************************************
* bitmap_info_size
*
* Return the size of the bitmap info structure including color table.
*/
int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
{
unsigned int colors, size, masks = 0;
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
return sizeof(BITMAPCOREHEADER) + colors *
((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
}
else /* assume BITMAPINFOHEADER */
{
colors = info->bmiHeader.biClrUsed;
if (colors > 256) /* buffer overflow otherwise */
colors = 256;
if (!colors && (info->bmiHeader.biBitCount <= 8))
colors = 1 << info->bmiHeader.biBitCount;
if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
}
}
static void DataCacheEntry_Destroy(DataCache *cache, DataCacheEntry *cache_entry)
{
list_remove(&cache_entry->entry);
if (cache_entry->stream)
IStream_Release(cache_entry->stream);
HeapFree(GetProcessHeap(), 0, cache_entry->fmtetc.ptd);
CoTaskMemFree(cache_entry->fmtetc.ptd);
ReleaseStgMedium(&cache_entry->stgmedium);
if(cache_entry->sink_id)
IDataObject_DUnadvise(cache->running_object, cache_entry->sink_id);
@ -253,13 +282,21 @@ static void DataCache_Destroy(
static DataCacheEntry *DataCache_GetEntryForFormatEtc(DataCache *This, const FORMATETC *formatetc)
{
DataCacheEntry *cache_entry;
FORMATETC fmt = *formatetc;
if (fmt.cfFormat == CF_BITMAP)
{
fmt.cfFormat = CF_DIB;
fmt.tymed = TYMED_HGLOBAL;
}
LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
{
/* FIXME: also compare DVTARGETDEVICEs */
if ((!cache_entry->fmtetc.cfFormat || !formatetc->cfFormat || (formatetc->cfFormat == cache_entry->fmtetc.cfFormat)) &&
(formatetc->dwAspect == cache_entry->fmtetc.dwAspect) &&
(formatetc->lindex == cache_entry->fmtetc.lindex) &&
(!cache_entry->fmtetc.tymed || !formatetc->tymed || (formatetc->tymed == cache_entry->fmtetc.tymed)))
if ((!cache_entry->fmtetc.cfFormat || !fmt.cfFormat || (fmt.cfFormat == cache_entry->fmtetc.cfFormat)) &&
(fmt.dwAspect == cache_entry->fmtetc.dwAspect) &&
(fmt.lindex == cache_entry->fmtetc.lindex) &&
(!cache_entry->fmtetc.tymed || !fmt.tymed || (fmt.tymed == cache_entry->fmtetc.tymed)))
return cache_entry;
}
return NULL;
@ -285,7 +322,30 @@ static HRESULT check_valid_clipformat_and_tymed(CLIPFORMAT cfFormat, DWORD tymed
}
}
static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc, DataCacheEntry **cache_entry, BOOL load)
static BOOL init_cache_entry(DataCacheEntry *entry, const FORMATETC *fmt, DWORD advf,
DWORD id)
{
HRESULT hr;
hr = copy_formatetc(&entry->fmtetc, fmt);
if (FAILED(hr)) return FALSE;
entry->data_cf = 0;
entry->stgmedium.tymed = TYMED_NULL;
entry->stgmedium.pUnkForRelease = NULL;
entry->stream = NULL;
entry->stream_type = no_stream;
entry->id = id;
entry->dirty = TRUE;
entry->stream_number = -1;
entry->sink_id = 0;
entry->advise_flags = advf;
return TRUE;
}
static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc, DWORD advf,
DataCacheEntry **cache_entry, BOOL load)
{
HRESULT hr;
@ -299,24 +359,17 @@ static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc
if (!*cache_entry)
return E_OUTOFMEMORY;
(*cache_entry)->fmtetc = *formatetc;
if (formatetc->ptd)
{
(*cache_entry)->fmtetc.ptd = HeapAlloc(GetProcessHeap(), 0, formatetc->ptd->tdSize);
memcpy((*cache_entry)->fmtetc.ptd, formatetc->ptd, formatetc->ptd->tdSize);
}
(*cache_entry)->data_cf = 0;
(*cache_entry)->stgmedium.tymed = TYMED_NULL;
(*cache_entry)->stgmedium.pUnkForRelease = NULL;
(*cache_entry)->stream = NULL;
(*cache_entry)->stream_type = no_stream;
(*cache_entry)->id = This->last_cache_id++;
(*cache_entry)->dirty = TRUE;
(*cache_entry)->stream_number = -1;
(*cache_entry)->sink_id = 0;
(*cache_entry)->advise_flags = 0;
if (!init_cache_entry(*cache_entry, formatetc, advf, This->last_cache_id))
goto fail;
list_add_tail(&This->cache_list, &(*cache_entry)->entry);
This->last_cache_id++;
return hr;
fail:
HeapFree(GetProcessHeap(), 0, *cache_entry);
return E_OUTOFMEMORY;
}
/************************************************************************
@ -573,7 +626,9 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm )
STATSTG stat;
void *dib;
HGLOBAL hglobal;
ULONG read;
ULONG read, info_size, bi_size;
BITMAPFILEHEADER file;
BITMAPINFOHEADER *info;
if (cache_entry->stream_type != contents_stream)
{
@ -584,24 +639,71 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm )
hr = IStream_Stat( stm, &stat, STATFLAG_NONAME );
if (FAILED( hr )) return hr;
if (stat.cbSize.QuadPart < sizeof(file) + sizeof(DWORD)) return E_FAIL;
hr = IStream_Read( stm, &file, sizeof(file), &read );
if (hr != S_OK || read != sizeof(file)) return E_FAIL;
stat.cbSize.QuadPart -= sizeof(file);
hglobal = GlobalAlloc( GMEM_MOVEABLE, stat.cbSize.u.LowPart );
if (!hglobal) return E_OUTOFMEMORY;
dib = GlobalLock( hglobal );
hr = IStream_Read( stm, dib, stat.cbSize.u.LowPart, &read );
GlobalUnlock( hglobal );
hr = IStream_Read( stm, dib, sizeof(DWORD), &read );
if (hr != S_OK || read != sizeof(DWORD)) goto fail;
bi_size = *(DWORD *)dib;
if (stat.cbSize.QuadPart < bi_size) goto fail;
if (hr != S_OK || read != stat.cbSize.u.LowPart)
hr = IStream_Read( stm, (char *)dib + sizeof(DWORD), bi_size - sizeof(DWORD), &read );
if (hr != S_OK || read != bi_size - sizeof(DWORD)) goto fail;
info_size = bitmap_info_size( dib, DIB_RGB_COLORS );
if (stat.cbSize.QuadPart < info_size) goto fail;
if (info_size > bi_size)
{
GlobalFree( hglobal );
return E_FAIL;
hr = IStream_Read( stm, (char *)dib + bi_size, info_size - bi_size, &read );
if (hr != S_OK || read != info_size - bi_size) goto fail;
}
stat.cbSize.QuadPart -= info_size;
if (file.bfOffBits)
{
LARGE_INTEGER skip;
skip.QuadPart = file.bfOffBits - sizeof(file) - info_size;
if (stat.cbSize.QuadPart < skip.QuadPart) goto fail;
hr = IStream_Seek( stm, skip, STREAM_SEEK_CUR, NULL );
if (hr != S_OK) goto fail;
stat.cbSize.QuadPart -= skip.QuadPart;
}
hr = IStream_Read( stm, (char *)dib + info_size, stat.cbSize.u.LowPart, &read );
if (hr != S_OK || read != stat.cbSize.QuadPart) goto fail;
if (bi_size >= sizeof(*info))
{
info = (BITMAPINFOHEADER *)dib;
if (info->biXPelsPerMeter == 0 || info->biYPelsPerMeter == 0)
{
HDC hdc = GetDC( 0 );
info->biXPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSX ), 10000, 254 );
info->biYPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSY ), 10000, 254 );
ReleaseDC( 0, hdc );
}
}
GlobalUnlock( hglobal );
cache_entry->data_cf = cache_entry->fmtetc.cfFormat;
cache_entry->stgmedium.tymed = TYMED_HGLOBAL;
cache_entry->stgmedium.u.hGlobal = hglobal;
return S_OK;
fail:
GlobalUnlock( hglobal );
GlobalFree( hglobal );
return E_FAIL;
}
/************************************************************************
@ -792,11 +894,56 @@ static HRESULT copy_stg_medium(CLIPFORMAT cf, STGMEDIUM *dest_stgm,
return S_OK;
}
static HGLOBAL synthesize_dib( HBITMAP bm )
{
HDC hdc = GetDC( 0 );
BITMAPINFOHEADER header;
BITMAPINFO *bmi;
HGLOBAL ret = 0;
DWORD header_size;
memset( &header, 0, sizeof(header) );
header.biSize = sizeof(header);
if (!GetDIBits( hdc, bm, 0, 0, NULL, (BITMAPINFO *)&header, DIB_RGB_COLORS )) goto done;
header_size = bitmap_info_size( (BITMAPINFO *)&header, DIB_RGB_COLORS );
if (!(ret = GlobalAlloc( GMEM_MOVEABLE, header_size + header.biSizeImage ))) goto done;
bmi = GlobalLock( ret );
memset( bmi, 0, header_size );
memcpy( bmi, &header, header.biSize );
GetDIBits( hdc, bm, 0, abs(header.biHeight), (char *)bmi + header_size, bmi, DIB_RGB_COLORS );
GlobalUnlock( ret );
done:
ReleaseDC( 0, hdc );
return ret;
}
static HBITMAP synthesize_bitmap( HGLOBAL dib )
{
HBITMAP ret = 0;
BITMAPINFO *bmi;
HDC hdc = GetDC( 0 );
if ((bmi = GlobalLock( dib )))
{
/* FIXME: validate data size */
ret = CreateDIBitmap( hdc, &bmi->bmiHeader, CBM_INIT,
(char *)bmi + bitmap_info_size( bmi, DIB_RGB_COLORS ),
bmi, DIB_RGB_COLORS );
GlobalUnlock( dib );
}
ReleaseDC( 0, hdc );
return ret;
}
static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
const FORMATETC *formatetc,
const STGMEDIUM *stgmedium,
STGMEDIUM *stgmedium,
BOOL fRelease)
{
STGMEDIUM dib_copy;
if ((!cache_entry->fmtetc.cfFormat && !formatetc->cfFormat) ||
(cache_entry->fmtetc.tymed == TYMED_NULL && formatetc->tymed == TYMED_NULL) ||
stgmedium->tymed == TYMED_NULL)
@ -808,6 +955,17 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
cache_entry->dirty = TRUE;
ReleaseStgMedium(&cache_entry->stgmedium);
cache_entry->data_cf = cache_entry->fmtetc.cfFormat ? cache_entry->fmtetc.cfFormat : formatetc->cfFormat;
if (formatetc->cfFormat == CF_BITMAP)
{
dib_copy.tymed = TYMED_HGLOBAL;
dib_copy.u.hGlobal = synthesize_dib( stgmedium->u.hBitmap );
dib_copy.pUnkForRelease = NULL;
if (fRelease) ReleaseStgMedium(stgmedium);
stgmedium = &dib_copy;
fRelease = TRUE;
}
if (fRelease)
{
cache_entry->stgmedium = *stgmedium;
@ -818,9 +976,9 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
&cache_entry->stgmedium, stgmedium);
}
static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, STGMEDIUM *stgmedium)
static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, FORMATETC *fmt, STGMEDIUM *stgmedium)
{
if (stgmedium->tymed == TYMED_NULL && cache_entry->stream)
if (cache_entry->stgmedium.tymed == TYMED_NULL && cache_entry->stream)
{
HRESULT hr = DataCacheEntry_LoadData(cache_entry);
if (FAILED(hr))
@ -828,6 +986,14 @@ static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, STGMEDIUM *st
}
if (cache_entry->stgmedium.tymed == TYMED_NULL)
return OLE_E_BLANK;
if (fmt->cfFormat == CF_BITMAP)
{
stgmedium->tymed = TYMED_GDI;
stgmedium->u.hBitmap = synthesize_bitmap( cache_entry->stgmedium.u.hGlobal );
stgmedium->pUnkForRelease = NULL;
return S_OK;
}
return copy_stg_medium(cache_entry->data_cf, stgmedium, &cache_entry->stgmedium);
}
@ -1000,7 +1166,7 @@ static HRESULT WINAPI DataCache_GetData(
if (!cache_entry)
return OLE_E_BLANK;
return DataCacheEntry_GetData(cache_entry, pmedium);
return DataCacheEntry_GetData(cache_entry, pformatetcIn, pmedium);
}
static HRESULT WINAPI DataCache_GetDataHere(
@ -1245,7 +1411,7 @@ static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, IStream *
cache_entry = DataCache_GetEntryForFormatEtc( This, fmt );
if (!cache_entry)
hr = DataCache_CreateEntry( This, fmt, &cache_entry, TRUE );
hr = DataCache_CreateEntry( This, fmt, 0, &cache_entry, TRUE );
if (SUCCEEDED( hr ))
{
DataCacheEntry_DiscardData( cache_entry );
@ -1641,16 +1807,14 @@ static HRESULT WINAPI DataCache_Draw(
}
case CF_DIB:
{
BITMAPFILEHEADER *file_head;
BITMAPINFO *info;
BYTE *bits;
if ((cache_entry->stgmedium.tymed != TYMED_HGLOBAL) ||
!((file_head = GlobalLock( cache_entry->stgmedium.u.hGlobal ))))
!((info = GlobalLock( cache_entry->stgmedium.u.hGlobal ))))
continue;
info = (BITMAPINFO *)(file_head + 1);
bits = (BYTE *) file_head + file_head->bfOffBits;
bits = (BYTE *) info + bitmap_info_size( info, DIB_RGB_COLORS );
StretchDIBits( hdcDraw, lprcBounds->left, lprcBounds->top,
lprcBounds->right - lprcBounds->left, lprcBounds->bottom - lprcBounds->top,
0, 0, info->bmiHeader.biWidth, info->bmiHeader.biHeight,
@ -1861,17 +2025,14 @@ static HRESULT WINAPI DataCache_GetExtent(
}
case CF_DIB:
{
BITMAPFILEHEADER *file_head;
BITMAPINFOHEADER *info;
LONG x_pels_m, y_pels_m;
if ((cache_entry->stgmedium.tymed != TYMED_HGLOBAL) ||
!((file_head = GlobalLock( cache_entry->stgmedium.u.hGlobal ))))
!((info = GlobalLock( cache_entry->stgmedium.u.hGlobal ))))
continue;
info = (BITMAPINFOHEADER *)(file_head + 1);
x_pels_m = info->biXPelsPerMeter;
y_pels_m = info->biYPelsPerMeter;
@ -1975,6 +2136,7 @@ static HRESULT WINAPI DataCache_Cache(
DataCache *This = impl_from_IOleCache2(iface);
DataCacheEntry *cache_entry;
HRESULT hr;
FORMATETC fmt_cpy;
TRACE("(%p, 0x%x, %p)\n", pformatetc, advf, pdwConnection);
@ -1983,9 +2145,16 @@ static HRESULT WINAPI DataCache_Cache(
TRACE("pformatetc = %s\n", debugstr_formatetc(pformatetc));
fmt_cpy = *pformatetc; /* No need for a deep copy */
if (fmt_cpy.cfFormat == CF_BITMAP && fmt_cpy.tymed == TYMED_GDI)
{
fmt_cpy.cfFormat = CF_DIB;
fmt_cpy.tymed = TYMED_HGLOBAL;
}
*pdwConnection = 0;
cache_entry = DataCache_GetEntryForFormatEtc(This, pformatetc);
cache_entry = DataCache_GetEntryForFormatEtc(This, &fmt_cpy);
if (cache_entry)
{
TRACE("found an existing cache entry\n");
@ -1993,12 +2162,11 @@ static HRESULT WINAPI DataCache_Cache(
return CACHE_S_SAMECACHE;
}
hr = DataCache_CreateEntry(This, pformatetc, &cache_entry, FALSE);
hr = DataCache_CreateEntry(This, &fmt_cpy, advf, &cache_entry, FALSE);
if (SUCCEEDED(hr))
{
*pdwConnection = cache_entry->id;
cache_entry->advise_flags = advf;
setup_sink(This, cache_entry);
}
@ -2026,12 +2194,58 @@ static HRESULT WINAPI DataCache_Uncache(
return OLE_E_NOCONNECTION;
}
static HRESULT WINAPI DataCache_EnumCache(
IOleCache2* iface,
IEnumSTATDATA** ppenumSTATDATA)
static HRESULT WINAPI DataCache_EnumCache(IOleCache2 *iface,
IEnumSTATDATA **enum_stat)
{
FIXME("stub\n");
return E_NOTIMPL;
DataCache *This = impl_from_IOleCache2( iface );
DataCacheEntry *cache_entry;
int i = 0, count = 0;
STATDATA *data;
HRESULT hr;
TRACE( "(%p, %p)\n", This, enum_stat );
LIST_FOR_EACH_ENTRY( cache_entry, &This->cache_list, DataCacheEntry, entry )
{
count++;
if (cache_entry->fmtetc.cfFormat == CF_DIB)
count++;
}
data = CoTaskMemAlloc( count * sizeof(*data) );
if (!data) return E_OUTOFMEMORY;
LIST_FOR_EACH_ENTRY( cache_entry, &This->cache_list, DataCacheEntry, entry )
{
if (i == count) goto fail;
hr = copy_formatetc( &data[i].formatetc, &cache_entry->fmtetc );
if (FAILED(hr)) goto fail;
data[i].advf = cache_entry->advise_flags;
data[i].pAdvSink = NULL;
data[i].dwConnection = cache_entry->id;
i++;
if (cache_entry->fmtetc.cfFormat == CF_DIB)
{
if (i == count) goto fail;
hr = copy_formatetc( &data[i].formatetc, &cache_entry->fmtetc );
if (FAILED(hr)) goto fail;
data[i].formatetc.cfFormat = CF_BITMAP;
data[i].formatetc.tymed = TYMED_GDI;
data[i].advf = cache_entry->advise_flags;
data[i].pAdvSink = NULL;
data[i].dwConnection = cache_entry->id;
i++;
}
}
hr = EnumSTATDATA_Construct( NULL, 0, i, data, FALSE, enum_stat );
if (SUCCEEDED(hr)) return hr;
fail:
while (i--) CoTaskMemFree( data[i].formatetc.ptd );
CoTaskMemFree( data );
return hr;
}
static HRESULT WINAPI DataCache_InitCache(

View file

@ -1525,31 +1525,7 @@ HRESULT FileMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
}
static HRESULT WINAPI FileMonikerCF_QueryInterface(LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IClassFactory_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI FileMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI FileMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI FileMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
HRESULT WINAPI FileMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv)
{
FileMonikerImpl* newFileMoniker;
HRESULT hr;
@ -1575,24 +1551,3 @@ static HRESULT WINAPI FileMonikerCF_CreateInstance(LPCLASSFACTORY iface,
return hr;
}
static HRESULT WINAPI FileMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl FileMonikerCFVtbl =
{
FileMonikerCF_QueryInterface,
FileMonikerCF_AddRef,
FileMonikerCF_Release,
FileMonikerCF_CreateInstance,
FileMonikerCF_LockServer
};
static const IClassFactoryVtbl *FileMonikerCF = &FileMonikerCFVtbl;
HRESULT FileMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&FileMonikerCF, riid, ppv);
}

View file

@ -933,39 +933,16 @@ HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim, LPCOLESTR lpszItem, IMoni
hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);
if (FAILED(hr)){
HeapFree(GetProcessHeap(),0,newItemMoniker);
return hr;
return hr;
}
return ItemMonikerImpl_QueryInterface(&newItemMoniker->IMoniker_iface,&IID_IMoniker,
(void**)ppmk);
}
static HRESULT WINAPI ItemMonikerCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IClassFactory_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI ItemMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI ItemMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI ItemMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
HRESULT WINAPI ItemMoniker_CreateInstance(IClassFactory *iface,
IUnknown *pUnk, REFIID riid, void **ppv)
{
ItemMonikerImpl* newItemMoniker;
HRESULT hr;
@ -991,24 +968,3 @@ static HRESULT WINAPI ItemMonikerCF_CreateInstance(LPCLASSFACTORY iface,
return hr;
}
static HRESULT WINAPI ItemMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl ItemMonikerCFVtbl =
{
ItemMonikerCF_QueryInterface,
ItemMonikerCF_AddRef,
ItemMonikerCF_Release,
ItemMonikerCF_CreateInstance,
ItemMonikerCF_LockServer
};
static const IClassFactoryVtbl *ItemMonikerCF = &ItemMonikerCFVtbl;
HRESULT ItemMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&ItemMonikerCF, riid, ppv);
}

View file

@ -30,13 +30,13 @@ DEFINE_OLEGUID( CLSID_CompositeMoniker, 0x309, 0, 0 );
DEFINE_OLEGUID( CLSID_ClassMoniker, 0x31a, 0, 0 );
DEFINE_OLEGUID( CLSID_PointerMoniker, 0x306, 0, 0 );
HRESULT FileMonikerCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
HRESULT ItemMonikerCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
HRESULT AntiMonikerCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
HRESULT CompositeMonikerCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
HRESULT ClassMonikerCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
HRESULT PointerMonikerCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
HRESULT ComCatCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
HRESULT WINAPI FileMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI ItemMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI AntiMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI CompositeMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI ClassMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI PointerMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
HRESULT WINAPI ComCat_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
/* This function decomposes a String path to a String Table containing all the elements ("\" or "subDirectory" or "Directory" or "FileName") of the path */
int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable) DECLSPEC_HIDDEN;

View file

@ -87,8 +87,8 @@
@ stdcall CoRegisterMallocSpy (ptr)
@ stdcall CoRegisterMessageFilter(ptr ptr)
@ stdcall CoRegisterPSClsid(ptr ptr)
@ stub CoRegisterSurrogate
@ stub CoRegisterSurrogateEx
@ stdcall CoRegisterSurrogate(ptr)
@ stdcall CoRegisterSurrogateEx(ptr ptr)
@ stdcall CoReleaseMarshalData(ptr)
@ stdcall CoReleaseServerProcess()
@ stdcall CoResumeClassObjects()

View file

@ -42,14 +42,14 @@ static void release_statdata(STATDATA *data)
static HRESULT copy_statdata(STATDATA *dst, const STATDATA *src)
{
*dst = *src;
if(src->formatetc.ptd)
{
dst->formatetc.ptd = CoTaskMemAlloc(src->formatetc.ptd->tdSize);
if(!dst->formatetc.ptd) return E_OUTOFMEMORY;
memcpy(dst->formatetc.ptd, src->formatetc.ptd, src->formatetc.ptd->tdSize);
}
if(dst->pAdvSink) IAdviseSink_AddRef(dst->pAdvSink);
HRESULT hr;
hr = copy_formatetc( &dst->formatetc, &src->formatetc );
if (FAILED(hr)) return hr;
dst->advf = src->advf;
dst->pAdvSink = src->pAdvSink;
if (dst->pAdvSink) IAdviseSink_AddRef( dst->pAdvSink );
dst->dwConnection = src->dwConnection;
return S_OK;
}
@ -57,8 +57,6 @@ static HRESULT copy_statdata(STATDATA *dst, const STATDATA *src)
* EnumSTATDATA Implementation
*/
static HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data, IEnumSTATDATA **ppenum);
typedef struct
{
IEnumSTATDATA IEnumSTATDATA_iface;
@ -106,7 +104,7 @@ static ULONG WINAPI EnumSTATDATA_Release(IEnumSTATDATA *iface)
for(i = 0; i < This->num_of_elems; i++)
release_statdata(This->statdata + i);
HeapFree(GetProcessHeap(), 0, This->statdata);
IUnknown_Release(This->holder);
if (This->holder) IUnknown_Release(This->holder);
HeapFree(GetProcessHeap(), 0, This);
}
return refs;
@ -170,7 +168,8 @@ static HRESULT WINAPI EnumSTATDATA_Clone(IEnumSTATDATA *iface, IEnumSTATDATA **p
{
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
return EnumSTATDATA_Construct(This->holder, This->index, This->num_of_elems, This->statdata, ppenum);
return EnumSTATDATA_Construct(This->holder, This->index, This->num_of_elems, This->statdata,
TRUE, ppenum);
}
static const IEnumSTATDATAVtbl EnumSTATDATA_VTable =
@ -184,8 +183,8 @@ static const IEnumSTATDATAVtbl EnumSTATDATA_VTable =
EnumSTATDATA_Clone
};
static HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data,
IEnumSTATDATA **ppenum)
HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data,
BOOL copy, IEnumSTATDATA **ppenum)
{
EnumSTATDATA *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
DWORD i, count;
@ -196,25 +195,33 @@ static HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array
This->ref = 1;
This->index = index;
This->statdata = HeapAlloc(GetProcessHeap(), 0, array_len * sizeof(*This->statdata));
if(!This->statdata)
if (copy)
{
HeapFree(GetProcessHeap(), 0, This);
return E_OUTOFMEMORY;
}
for(i = 0, count = 0; i < array_len; i++)
{
if(data[i].pAdvSink)
This->statdata = HeapAlloc(GetProcessHeap(), 0, array_len * sizeof(*This->statdata));
if(!This->statdata)
{
copy_statdata(This->statdata + count, data + i);
count++;
HeapFree(GetProcessHeap(), 0, This);
return E_OUTOFMEMORY;
}
for(i = 0, count = 0; i < array_len; i++)
{
if(data[i].pAdvSink)
{
copy_statdata(This->statdata + count, data + i);
count++;
}
}
}
else
{
This->statdata = data;
count = array_len;
}
This->num_of_elems = count;
This->holder = holder;
IUnknown_AddRef(holder);
if (holder) IUnknown_AddRef(holder);
*ppenum = &This->IEnumSTATDATA_iface;
return S_OK;
}
@ -389,7 +396,7 @@ static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise(IOleAdviseHolder *iface, IE
TRACE("(%p)->(%p)\n", This, enum_advise);
IOleAdviseHolder_QueryInterface(iface, &IID_IUnknown, (void**)&unk);
hr = EnumSTATDATA_Construct(unk, 0, This->max_cons, This->connections, enum_advise);
hr = EnumSTATDATA_Construct(unk, 0, This->max_cons, This->connections, TRUE, enum_advise);
IUnknown_Release(unk);
return hr;
}
@ -723,7 +730,7 @@ static HRESULT WINAPI DataAdviseHolder_EnumAdvise(IDataAdviseHolder *iface,
TRACE("(%p)->(%p)\n", This, enum_advise);
IDataAdviseHolder_QueryInterface(iface, &IID_IUnknown, (void**)&unk);
hr = EnumSTATDATA_Construct(unk, 0, This->maxCons, This->connections, enum_advise);
hr = EnumSTATDATA_Construct(unk, 0, This->maxCons, This->connections, TRUE, enum_advise);
IUnknown_Release(unk);
return hr;
}

View file

@ -21,6 +21,126 @@
#include "precomp.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
{
return 2;
}
static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
{
return 1;
}
static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
{
TRACE("(%x)\n", fLock);
return S_OK;
}
static const IClassFactoryVtbl FileMonikerCFVtbl =
{
ClassFactory_QueryInterface,
ClassFactory_AddRef,
ClassFactory_Release,
FileMoniker_CreateInstance,
ClassFactory_LockServer
};
static IClassFactory FileMonikerCF = { &FileMonikerCFVtbl };
static const IClassFactoryVtbl ItemMonikerCFVtbl =
{
ClassFactory_QueryInterface,
ClassFactory_AddRef,
ClassFactory_Release,
ItemMoniker_CreateInstance,
ClassFactory_LockServer
};
static IClassFactory ItemMonikerCF = { &ItemMonikerCFVtbl };
static const IClassFactoryVtbl AntiMonikerCFVtbl =
{
ClassFactory_QueryInterface,
ClassFactory_AddRef,
ClassFactory_Release,
AntiMoniker_CreateInstance,
ClassFactory_LockServer
};
static IClassFactory AntiMonikerCF = { &AntiMonikerCFVtbl };
static const IClassFactoryVtbl CompositeMonikerCFVtbl =
{
ClassFactory_QueryInterface,
ClassFactory_AddRef,
ClassFactory_Release,
CompositeMoniker_CreateInstance,
ClassFactory_LockServer
};
static IClassFactory CompositeMonikerCF = { &CompositeMonikerCFVtbl };
static const IClassFactoryVtbl ClassMonikerCFVtbl =
{
ClassFactory_QueryInterface,
ClassFactory_AddRef,
ClassFactory_Release,
ClassMoniker_CreateInstance,
ClassFactory_LockServer
};
static IClassFactory ClassMonikerCF = { &ClassMonikerCFVtbl };
static const IClassFactoryVtbl PointerMonikerCFVtbl =
{
ClassFactory_QueryInterface,
ClassFactory_AddRef,
ClassFactory_Release,
PointerMoniker_CreateInstance,
ClassFactory_LockServer
};
static IClassFactory PointerMonikerCF = { &PointerMonikerCFVtbl };
static const IClassFactoryVtbl ComCatCFVtbl =
{
ClassFactory_QueryInterface,
ClassFactory_AddRef,
ClassFactory_Release,
ComCat_CreateInstance,
ClassFactory_LockServer
};
static IClassFactory ComCatCF = { &ComCatCFVtbl };
static const IClassFactoryVtbl GlobalOptionsCFVtbl =
{
ClassFactory_QueryInterface,
ClassFactory_AddRef,
ClassFactory_Release,
GlobalOptions_CreateInstance,
ClassFactory_LockServer
};
IClassFactory GlobalOptionsCF = { &GlobalOptionsCFVtbl };
/***********************************************************************
* DllGetClassObject [OLE32.@]
*/
@ -38,19 +158,19 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
if (IsEqualIID(rclsid,&CLSID_StdGlobalInterfaceTable) && (IsEqualIID(iid,&IID_IClassFactory) || IsEqualIID(iid,&IID_IUnknown)))
return StdGlobalInterfaceTable_GetFactory(ppv);
if (IsEqualCLSID(rclsid, &CLSID_FileMoniker))
return FileMonikerCF_Create(iid, ppv);
return IClassFactory_QueryInterface(&FileMonikerCF, iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_ItemMoniker))
return ItemMonikerCF_Create(iid, ppv);
return IClassFactory_QueryInterface(&ItemMonikerCF, iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_AntiMoniker))
return AntiMonikerCF_Create(iid, ppv);
return IClassFactory_QueryInterface(&AntiMonikerCF, iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_CompositeMoniker))
return CompositeMonikerCF_Create(iid, ppv);
return IClassFactory_QueryInterface(&CompositeMonikerCF, iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_ClassMoniker))
return ClassMonikerCF_Create(iid, ppv);
return IClassFactory_QueryInterface(&ClassMonikerCF, iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_PointerMoniker))
return PointerMonikerCF_Create(iid, ppv);
return IClassFactory_QueryInterface(&PointerMonikerCF, iid, ppv);
if (IsEqualGUID(rclsid, &CLSID_StdComponentCategoriesMgr))
return ComCatCF_Create(iid, ppv);
return IClassFactory_QueryInterface(&ComCatCF, iid, ppv);
hr = OLE32_DllGetClassObject(rclsid, iid, ppv);
if (SUCCEEDED(hr))

View file

@ -575,31 +575,8 @@ HRESULT WINAPI CreatePointerMoniker(LPUNKNOWN punk, LPMONIKER *ppmk)
return S_OK;
}
static HRESULT WINAPI PointerMonikerCF_QueryInterface(LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IClassFactory_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI PointerMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI PointerMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI PointerMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
HRESULT WINAPI PointerMoniker_CreateInstance(IClassFactory *iface,
IUnknown *pUnk, REFIID riid, void **ppv)
{
IMoniker *pMoniker;
HRESULT hr;
@ -622,24 +599,3 @@ static HRESULT WINAPI PointerMonikerCF_CreateInstance(LPCLASSFACTORY iface,
return hr;
}
static HRESULT WINAPI PointerMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl PointerMonikerCFVtbl =
{
PointerMonikerCF_QueryInterface,
PointerMonikerCF_AddRef,
PointerMonikerCF_Release,
PointerMonikerCF_CreateInstance,
PointerMonikerCF_LockServer
};
static const IClassFactoryVtbl *PointerMonikerCF = &PointerMonikerCFVtbl;
HRESULT PointerMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&PointerMonikerCF, riid, ppv);
}

View file

@ -517,6 +517,9 @@ StgStreamImpl* StgStreamImpl_Construct(
/******************************************************************************
* Endian conversion macros
*/
#undef htole32
#undef htole16
#ifdef WORDS_BIGENDIAN
#define htole32(x) RtlUlongByteSwap(x)

View file

@ -139,7 +139,7 @@ reactos/dll/win32/ntdsapi # Synced to WineStaging-1.9.11
reactos/dll/win32/objsel # Synced to WineStaging-1.9.11
reactos/dll/win32/odbc32 # Synced to WineStaging-2.9. Depends on port of Linux ODBC.
reactos/dll/win32/odbccp32 # Synced to WineStaging-2.9
reactos/dll/win32/ole32 # Synced to WineStaging-2.2
reactos/dll/win32/ole32 # Synced to WineStaging-2.9
reactos/dll/win32/oleacc # Synced to WineStaging-1.9.11
reactos/dll/win32/oleaut32 # Synced to WineStaging-2.2
reactos/dll/win32/olecli32 # Synced to WineStaging-1.9.11