[OLE32] Sync with Wine Staging 2.16. CORE-13762
a56bc8f ole32: Store proxy/stub CLSIDs per process, not per apartment. 3b44927 ole32: New high resolution cursors generated from SVG. 5a3b87a ole32: Avoid null pointer dereferences in CoGetTreatAsClass. 13c6d37 ole32: Add stub for OleGetIconOfFile. 33a720b ole32: InitNew() should fail if there is a current storage. 966e8a2 ole32: Create initial cache entries for the CLSID_Picture_ classes. 111b72f ole32: Add the ability to create an entry without returning it. 705ccd7 ole32: Start allocating regular cache entries with id of 2. 0267564 ole32: Fix incorrectly assigned member in the presentation stream. 85a1309 ole32: Make bitmap_info_size() static. svn path=/trunk/; revision=75890
|
@ -146,6 +146,17 @@ struct registered_psclsid
|
||||||
CLSID clsid;
|
CLSID clsid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct list registered_psclsid_list = LIST_INIT(registered_psclsid_list);
|
||||||
|
|
||||||
|
static CRITICAL_SECTION cs_registered_psclsid_list;
|
||||||
|
static CRITICAL_SECTION_DEBUG psclsid_cs_debug =
|
||||||
|
{
|
||||||
|
0, 0, &cs_registered_psclsid_list,
|
||||||
|
{ &psclsid_cs_debug.ProcessLocksList, &psclsid_cs_debug.ProcessLocksList },
|
||||||
|
0, 0, { (DWORD_PTR)(__FILE__ ": cs_registered_psclsid_list") }
|
||||||
|
};
|
||||||
|
static CRITICAL_SECTION cs_registered_psclsid_list = { &psclsid_cs_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a marshallable object exposing registered local servers.
|
* This is a marshallable object exposing registered local servers.
|
||||||
* IServiceProvider is used only because it happens meet requirements
|
* IServiceProvider is used only because it happens meet requirements
|
||||||
|
@ -600,7 +611,6 @@ static APARTMENT *apartment_construct(DWORD model)
|
||||||
|
|
||||||
list_init(&apt->proxies);
|
list_init(&apt->proxies);
|
||||||
list_init(&apt->stubmgrs);
|
list_init(&apt->stubmgrs);
|
||||||
list_init(&apt->psclsids);
|
|
||||||
list_init(&apt->loaded_dlls);
|
list_init(&apt->loaded_dlls);
|
||||||
apt->ipidc = 0;
|
apt->ipidc = 0;
|
||||||
apt->refs = 1;
|
apt->refs = 1;
|
||||||
|
@ -711,6 +721,21 @@ static void COM_RevokeAllClasses(const struct apartment *apt)
|
||||||
LeaveCriticalSection( &csRegisteredClassList );
|
LeaveCriticalSection( &csRegisteredClassList );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void revoke_registered_psclsids(void)
|
||||||
|
{
|
||||||
|
struct registered_psclsid *psclsid, *psclsid2;
|
||||||
|
|
||||||
|
EnterCriticalSection( &cs_registered_psclsid_list );
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY_SAFE(psclsid, psclsid2, ®istered_psclsid_list, struct registered_psclsid, entry)
|
||||||
|
{
|
||||||
|
list_remove(&psclsid->entry);
|
||||||
|
HeapFree(GetProcessHeap(), 0, psclsid);
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &cs_registered_psclsid_list );
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Implementation of the manual reset event object. (CLSID_ManualResetEvent)
|
* Implementation of the manual reset event object. (CLSID_ManualResetEvent)
|
||||||
*/
|
*/
|
||||||
|
@ -1151,15 +1176,6 @@ DWORD apartment_release(struct apartment *apt)
|
||||||
stub_manager_int_release(stubmgr);
|
stub_manager_int_release(stubmgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
LIST_FOR_EACH_SAFE(cursor, cursor2, &apt->psclsids)
|
|
||||||
{
|
|
||||||
struct registered_psclsid *registered_psclsid =
|
|
||||||
LIST_ENTRY(cursor, struct registered_psclsid, entry);
|
|
||||||
|
|
||||||
list_remove(®istered_psclsid->entry);
|
|
||||||
HeapFree(GetProcessHeap(), 0, registered_psclsid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if this assert fires, then another thread took a reference to a
|
/* if this assert fires, then another thread took a reference to a
|
||||||
* stub manager without taking a reference to the containing
|
* stub manager without taking a reference to the containing
|
||||||
* apartment, which it must do. */
|
* apartment, which it must do. */
|
||||||
|
@ -1966,6 +1982,7 @@ void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
|
||||||
{
|
{
|
||||||
TRACE("() - Releasing the COM libraries\n");
|
TRACE("() - Releasing the COM libraries\n");
|
||||||
|
|
||||||
|
revoke_registered_psclsids();
|
||||||
RunningObjectTableImpl_UnInitialize();
|
RunningObjectTableImpl_UnInitialize();
|
||||||
}
|
}
|
||||||
else if (lCOMRefCnt<1) {
|
else if (lCOMRefCnt<1) {
|
||||||
|
@ -2558,17 +2575,17 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
|
||||||
if (!pclsid)
|
if (!pclsid)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
EnterCriticalSection(&apt->cs);
|
EnterCriticalSection(&cs_registered_psclsid_list);
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(registered_psclsid, &apt->psclsids, struct registered_psclsid, entry)
|
LIST_FOR_EACH_ENTRY(registered_psclsid, ®istered_psclsid_list, struct registered_psclsid, entry)
|
||||||
if (IsEqualIID(®istered_psclsid->iid, riid))
|
if (IsEqualIID(®istered_psclsid->iid, riid))
|
||||||
{
|
{
|
||||||
*pclsid = registered_psclsid->clsid;
|
*pclsid = registered_psclsid->clsid;
|
||||||
LeaveCriticalSection(&apt->cs);
|
LeaveCriticalSection(&cs_registered_psclsid_list);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection(&apt->cs);
|
LeaveCriticalSection(&cs_registered_psclsid_list);
|
||||||
|
|
||||||
data.cbSize = sizeof(data);
|
data.cbSize = sizeof(data);
|
||||||
if (FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
|
if (FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
|
||||||
|
@ -2613,6 +2630,9 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
|
* Unlike CoRegisterClassObject(), CLSIDs registered with CoRegisterPSClsid()
|
||||||
|
* will be returned from other apartments in the same process.
|
||||||
|
*
|
||||||
* This function does not add anything to the registry and the effects are
|
* This function does not add anything to the registry and the effects are
|
||||||
* limited to the lifetime of the current process.
|
* limited to the lifetime of the current process.
|
||||||
*
|
*
|
||||||
|
@ -2632,28 +2652,28 @@ HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid)
|
||||||
return CO_E_NOTINITIALIZED;
|
return CO_E_NOTINITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterCriticalSection(&apt->cs);
|
EnterCriticalSection(&cs_registered_psclsid_list);
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(registered_psclsid, &apt->psclsids, struct registered_psclsid, entry)
|
LIST_FOR_EACH_ENTRY(registered_psclsid, ®istered_psclsid_list, struct registered_psclsid, entry)
|
||||||
if (IsEqualIID(®istered_psclsid->iid, riid))
|
if (IsEqualIID(®istered_psclsid->iid, riid))
|
||||||
{
|
{
|
||||||
registered_psclsid->clsid = *rclsid;
|
registered_psclsid->clsid = *rclsid;
|
||||||
LeaveCriticalSection(&apt->cs);
|
LeaveCriticalSection(&cs_registered_psclsid_list);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
registered_psclsid = HeapAlloc(GetProcessHeap(), 0, sizeof(struct registered_psclsid));
|
registered_psclsid = HeapAlloc(GetProcessHeap(), 0, sizeof(struct registered_psclsid));
|
||||||
if (!registered_psclsid)
|
if (!registered_psclsid)
|
||||||
{
|
{
|
||||||
LeaveCriticalSection(&apt->cs);
|
LeaveCriticalSection(&cs_registered_psclsid_list);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
registered_psclsid->iid = *riid;
|
registered_psclsid->iid = *riid;
|
||||||
registered_psclsid->clsid = *rclsid;
|
registered_psclsid->clsid = *rclsid;
|
||||||
list_add_head(&apt->psclsids, ®istered_psclsid->entry);
|
list_add_head(®istered_psclsid_list, ®istered_psclsid->entry);
|
||||||
|
|
||||||
LeaveCriticalSection(&apt->cs);
|
LeaveCriticalSection(&cs_registered_psclsid_list);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -3803,6 +3823,10 @@ HRESULT WINAPI CoGetTreatAsClass(REFCLSID clsidOld, LPCLSID clsidNew)
|
||||||
LONG len = sizeof(szClsidNew);
|
LONG len = sizeof(szClsidNew);
|
||||||
|
|
||||||
TRACE("(%s,%p)\n", debugstr_guid(clsidOld), clsidNew);
|
TRACE("(%s,%p)\n", debugstr_guid(clsidOld), clsidNew);
|
||||||
|
|
||||||
|
if (!clsidOld || !clsidNew)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
*clsidNew = *clsidOld; /* copy over old value */
|
*clsidNew = *clsidOld; /* copy over old value */
|
||||||
|
|
||||||
res = COM_OpenKeyForCLSID(clsidOld, wszTreatAs, KEY_READ, &hkey);
|
res = COM_OpenKeyForCLSID(clsidOld, wszTreatAs, KEY_READ, &hkey);
|
||||||
|
|
|
@ -126,7 +126,6 @@ struct apartment
|
||||||
struct list stubmgrs; /* stub managers for exported objects (CS cs) */
|
struct list stubmgrs; /* stub managers for exported objects (CS cs) */
|
||||||
BOOL remunk_exported; /* has the IRemUnknown interface for this apartment been created yet? (CS cs) */
|
BOOL remunk_exported; /* has the IRemUnknown interface for this apartment been created yet? (CS cs) */
|
||||||
LONG remoting_started; /* has the RPC system been started for this apartment? (LOCK) */
|
LONG remoting_started; /* has the RPC system been started for this apartment? (LOCK) */
|
||||||
struct list psclsids; /* list of registered PS CLSIDs (CS cs) */
|
|
||||||
struct list loaded_dlls; /* list of dlls loaded by this apartment (CS cs) */
|
struct list loaded_dlls; /* list of dlls loaded by this apartment (CS cs) */
|
||||||
DWORD host_apt_tid; /* thread ID of apartment hosting objects of differing threading model (CS cs) */
|
DWORD host_apt_tid; /* thread ID of apartment hosting objects of differing threading model (CS cs) */
|
||||||
HWND host_apt_hwnd; /* handle to apartment window of host apartment (CS cs) */
|
HWND host_apt_hwnd; /* handle to apartment window of host apartment (CS cs) */
|
||||||
|
|
|
@ -67,7 +67,7 @@ typedef struct PresentationDataHeader
|
||||||
DWORD unknown3; /* 4, possibly TYMED_ISTREAM */
|
DWORD unknown3; /* 4, possibly TYMED_ISTREAM */
|
||||||
DVASPECT dvAspect;
|
DVASPECT dvAspect;
|
||||||
DWORD lindex;
|
DWORD lindex;
|
||||||
DWORD tymed;
|
DWORD advf;
|
||||||
DWORD unknown7; /* 0 */
|
DWORD unknown7; /* 0 */
|
||||||
DWORD dwObjectExtentX;
|
DWORD dwObjectExtentX;
|
||||||
DWORD dwObjectExtentY;
|
DWORD dwObjectExtentY;
|
||||||
|
@ -145,7 +145,9 @@ struct DataCache
|
||||||
*/
|
*/
|
||||||
DWORD sinkAspects;
|
DWORD sinkAspects;
|
||||||
DWORD sinkAdviseFlag;
|
DWORD sinkAdviseFlag;
|
||||||
IAdviseSink* sinkInterface;
|
IAdviseSink *sinkInterface;
|
||||||
|
|
||||||
|
CLSID clsid;
|
||||||
IStorage *presentationStorage;
|
IStorage *presentationStorage;
|
||||||
|
|
||||||
/* list of cache entries */
|
/* list of cache entries */
|
||||||
|
@ -214,7 +216,7 @@ const char *debugstr_formatetc(const FORMATETC *formatetc)
|
||||||
*
|
*
|
||||||
* Return the size of the bitmap info structure including color table.
|
* Return the size of the bitmap info structure including color table.
|
||||||
*/
|
*/
|
||||||
int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
|
static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
|
||||||
{
|
{
|
||||||
unsigned int colors, size, masks = 0;
|
unsigned int colors, size, masks = 0;
|
||||||
|
|
||||||
|
@ -305,10 +307,10 @@ static DataCacheEntry *DataCache_GetEntryForFormatEtc(DataCache *This, const FOR
|
||||||
/* checks that the clipformat and tymed are valid and returns an error if they
|
/* checks that the clipformat and tymed are valid and returns an error if they
|
||||||
* aren't and CACHE_S_NOTSUPPORTED if they are valid, but can't be rendered by
|
* aren't and CACHE_S_NOTSUPPORTED if they are valid, but can't be rendered by
|
||||||
* DataCache_Draw */
|
* DataCache_Draw */
|
||||||
static HRESULT check_valid_clipformat_and_tymed(CLIPFORMAT cfFormat, DWORD tymed, BOOL load)
|
static HRESULT check_valid_clipformat_and_tymed(CLIPFORMAT cfFormat, DWORD tymed)
|
||||||
{
|
{
|
||||||
if (!cfFormat || !tymed ||
|
if (!cfFormat || !tymed ||
|
||||||
(cfFormat == CF_METAFILEPICT && (tymed == TYMED_MFPICT || load)) ||
|
(cfFormat == CF_METAFILEPICT && tymed == TYMED_MFPICT) ||
|
||||||
(cfFormat == CF_BITMAP && tymed == TYMED_GDI) ||
|
(cfFormat == CF_BITMAP && tymed == TYMED_GDI) ||
|
||||||
(cfFormat == CF_DIB && tymed == TYMED_HGLOBAL) ||
|
(cfFormat == CF_DIB && tymed == TYMED_HGLOBAL) ||
|
||||||
(cfFormat == CF_ENHMETAFILE && tymed == TYMED_ENHMF))
|
(cfFormat == CF_ENHMETAFILE && tymed == TYMED_ENHMF))
|
||||||
|
@ -345,30 +347,38 @@ static BOOL init_cache_entry(DataCacheEntry *entry, const FORMATETC *fmt, DWORD
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc, DWORD advf,
|
static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc, DWORD advf,
|
||||||
DataCacheEntry **cache_entry, BOOL load)
|
BOOL automatic, DataCacheEntry **cache_entry)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
DWORD id = automatic ? 1 : This->last_cache_id;
|
||||||
|
DataCacheEntry *entry;
|
||||||
|
|
||||||
hr = check_valid_clipformat_and_tymed(formatetc->cfFormat, formatetc->tymed, load);
|
hr = check_valid_clipformat_and_tymed(formatetc->cfFormat, formatetc->tymed);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
if (hr == CACHE_S_FORMATETC_NOTSUPPORTED)
|
if (hr == CACHE_S_FORMATETC_NOTSUPPORTED)
|
||||||
TRACE("creating unsupported format %d\n", formatetc->cfFormat);
|
TRACE("creating unsupported format %d\n", formatetc->cfFormat);
|
||||||
|
|
||||||
*cache_entry = HeapAlloc(GetProcessHeap(), 0, sizeof(**cache_entry));
|
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
|
||||||
if (!*cache_entry)
|
if (!entry)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if (!init_cache_entry(*cache_entry, formatetc, advf, This->last_cache_id))
|
if (!init_cache_entry(entry, formatetc, advf, id))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
list_add_tail(&This->cache_list, &(*cache_entry)->entry);
|
if (automatic)
|
||||||
This->last_cache_id++;
|
list_add_head(&This->cache_list, &entry->entry);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list_add_tail(&This->cache_list, &entry->entry);
|
||||||
|
This->last_cache_id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache_entry) *cache_entry = entry;
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
HeapFree(GetProcessHeap(), 0, *cache_entry);
|
HeapFree(GetProcessHeap(), 0, entry);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,7 +793,7 @@ static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storag
|
||||||
header.unknown3 = 4;
|
header.unknown3 = 4;
|
||||||
header.dvAspect = cache_entry->fmtetc.dwAspect;
|
header.dvAspect = cache_entry->fmtetc.dwAspect;
|
||||||
header.lindex = cache_entry->fmtetc.lindex;
|
header.lindex = cache_entry->fmtetc.lindex;
|
||||||
header.tymed = cache_entry->stgmedium.tymed;
|
header.advf = cache_entry->advise_flags;
|
||||||
header.unknown7 = 0;
|
header.unknown7 = 0;
|
||||||
header.dwObjectExtentX = 0;
|
header.dwObjectExtentX = 0;
|
||||||
header.dwObjectExtentY = 0;
|
header.dwObjectExtentY = 0;
|
||||||
|
@ -1013,6 +1023,66 @@ static inline void DataCacheEntry_HandsOffStorage(DataCacheEntry *cache_entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline DWORD tymed_from_cf( DWORD cf )
|
||||||
|
{
|
||||||
|
switch( cf )
|
||||||
|
{
|
||||||
|
case CF_BITMAP: return TYMED_GDI;
|
||||||
|
case CF_METAFILEPICT: return TYMED_MFPICT;
|
||||||
|
case CF_ENHMETAFILE: return TYMED_ENHMF;
|
||||||
|
case CF_DIB:
|
||||||
|
default: return TYMED_HGLOBAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* create_automatic_entry
|
||||||
|
*
|
||||||
|
* Creates an appropriate cache entry for one of the CLSID_Picture_
|
||||||
|
* classes. The connection id of the entry is one. Any pre-existing
|
||||||
|
* automatic entry is re-assigned a new connection id, and moved to
|
||||||
|
* the end of the list.
|
||||||
|
*/
|
||||||
|
static HRESULT create_automatic_entry(DataCache *cache, const CLSID *clsid)
|
||||||
|
{
|
||||||
|
static const struct data
|
||||||
|
{
|
||||||
|
const CLSID *clsid;
|
||||||
|
FORMATETC fmt;
|
||||||
|
} data[] =
|
||||||
|
{
|
||||||
|
{ &CLSID_Picture_Dib, { CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
|
||||||
|
{ &CLSID_Picture_Metafile, { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
|
||||||
|
{ &CLSID_Picture_EnhMetafile, { CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF } },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
const struct data *ptr = data;
|
||||||
|
struct list *head;
|
||||||
|
DataCacheEntry *entry;
|
||||||
|
|
||||||
|
if (IsEqualCLSID( &cache->clsid, clsid )) return S_OK;
|
||||||
|
|
||||||
|
/* move and reassign any pre-existing automatic entry */
|
||||||
|
if ((head = list_head( &cache->cache_list )))
|
||||||
|
{
|
||||||
|
entry = LIST_ENTRY( head, DataCacheEntry, entry );
|
||||||
|
if (entry->id == 1)
|
||||||
|
{
|
||||||
|
list_remove( &entry->entry );
|
||||||
|
entry->id = cache->last_cache_id++;
|
||||||
|
list_add_tail( &cache->cache_list, &entry->entry );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ptr->clsid)
|
||||||
|
{
|
||||||
|
if (IsEqualCLSID( clsid, ptr->clsid ))
|
||||||
|
return DataCache_CreateEntry( cache, &ptr->fmt, 0, TRUE, NULL );
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************
|
/*********************************************************
|
||||||
* Method implementation for the non delegating IUnknown
|
* Method implementation for the non delegating IUnknown
|
||||||
* part of the DataCache class.
|
* part of the DataCache class.
|
||||||
|
@ -1334,22 +1404,9 @@ static ULONG WINAPI DataCache_IPersistStorage_Release(
|
||||||
static HRESULT WINAPI DataCache_GetClassID(IPersistStorage *iface, CLSID *clsid)
|
static HRESULT WINAPI DataCache_GetClassID(IPersistStorage *iface, CLSID *clsid)
|
||||||
{
|
{
|
||||||
DataCache *This = impl_from_IPersistStorage( iface );
|
DataCache *This = impl_from_IPersistStorage( iface );
|
||||||
HRESULT hr;
|
|
||||||
STATSTG statstg;
|
|
||||||
|
|
||||||
TRACE( "(%p, %p)\n", iface, clsid );
|
TRACE( "(%p, %p) returning %s\n", iface, clsid, debugstr_guid(&This->clsid) );
|
||||||
|
*clsid = This->clsid;
|
||||||
if (This->presentationStorage)
|
|
||||||
{
|
|
||||||
hr = IStorage_Stat( This->presentationStorage, &statstg, STATFLAG_NONAME );
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
*clsid = statstg.clsid;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*clsid = CLSID_NULL;
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -1386,22 +1443,33 @@ static HRESULT WINAPI DataCache_InitNew(
|
||||||
IStorage* pStg)
|
IStorage* pStg)
|
||||||
{
|
{
|
||||||
DataCache *This = impl_from_IPersistStorage(iface);
|
DataCache *This = impl_from_IPersistStorage(iface);
|
||||||
|
CLSID clsid;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("(%p, %p)\n", iface, pStg);
|
TRACE("(%p, %p)\n", iface, pStg);
|
||||||
|
|
||||||
if (This->presentationStorage != NULL)
|
if (This->presentationStorage != NULL)
|
||||||
IStorage_Release(This->presentationStorage);
|
return CO_E_ALREADYINITIALIZED;
|
||||||
|
|
||||||
This->presentationStorage = pStg;
|
This->presentationStorage = pStg;
|
||||||
|
|
||||||
IStorage_AddRef(This->presentationStorage);
|
IStorage_AddRef(This->presentationStorage);
|
||||||
This->dirty = TRUE;
|
This->dirty = TRUE;
|
||||||
|
ReadClassStg( pStg, &clsid );
|
||||||
|
hr = create_automatic_entry( This, &clsid );
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
IStorage_Release( pStg );
|
||||||
|
This->presentationStorage = NULL;
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
This->clsid = clsid;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, IStream *stm,
|
static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, DWORD advf, IStream *stm,
|
||||||
enum stream_type type )
|
enum stream_type type )
|
||||||
{
|
{
|
||||||
DataCacheEntry *cache_entry;
|
DataCacheEntry *cache_entry;
|
||||||
|
@ -1411,7 +1479,7 @@ static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, IStream *
|
||||||
|
|
||||||
cache_entry = DataCache_GetEntryForFormatEtc( This, fmt );
|
cache_entry = DataCache_GetEntryForFormatEtc( This, fmt );
|
||||||
if (!cache_entry)
|
if (!cache_entry)
|
||||||
hr = DataCache_CreateEntry( This, fmt, 0, &cache_entry, TRUE );
|
hr = DataCache_CreateEntry( This, fmt, advf, FALSE, &cache_entry );
|
||||||
if (SUCCEEDED( hr ))
|
if (SUCCEEDED( hr ))
|
||||||
{
|
{
|
||||||
DataCacheEntry_DiscardData( cache_entry );
|
DataCacheEntry_DiscardData( cache_entry );
|
||||||
|
@ -1457,9 +1525,9 @@ static HRESULT parse_pres_streams( DataCache *This, IStorage *stg )
|
||||||
fmtetc.ptd = NULL; /* FIXME */
|
fmtetc.ptd = NULL; /* FIXME */
|
||||||
fmtetc.dwAspect = header.dvAspect;
|
fmtetc.dwAspect = header.dvAspect;
|
||||||
fmtetc.lindex = header.lindex;
|
fmtetc.lindex = header.lindex;
|
||||||
fmtetc.tymed = header.tymed;
|
fmtetc.tymed = tymed_from_cf( clipformat );
|
||||||
|
|
||||||
add_cache_entry( This, &fmtetc, stm, pres_stream );
|
add_cache_entry( This, &fmtetc, header.advf, stm, pres_stream );
|
||||||
}
|
}
|
||||||
IStream_Release( stm );
|
IStream_Release( stm );
|
||||||
}
|
}
|
||||||
|
@ -1490,7 +1558,7 @@ static HRESULT parse_contents_stream( DataCache *This, IStorage *stg, IStream *s
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return add_cache_entry( This, fmt, stm, contents_stream );
|
return add_cache_entry( This, fmt, 0, stm, contents_stream );
|
||||||
}
|
}
|
||||||
|
|
||||||
static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
|
static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
|
||||||
|
@ -1508,11 +1576,22 @@ static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *pStg )
|
||||||
DataCache *This = impl_from_IPersistStorage(iface);
|
DataCache *This = impl_from_IPersistStorage(iface);
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
IStream *stm;
|
IStream *stm;
|
||||||
|
CLSID clsid;
|
||||||
|
DataCacheEntry *entry, *cursor2;
|
||||||
|
|
||||||
TRACE("(%p, %p)\n", iface, pStg);
|
TRACE("(%p, %p)\n", iface, pStg);
|
||||||
|
|
||||||
IPersistStorage_HandsOffStorage( iface );
|
IPersistStorage_HandsOffStorage( iface );
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY_SAFE( entry, cursor2, &This->cache_list, DataCacheEntry, entry )
|
||||||
|
DataCacheEntry_Destroy( This, entry );
|
||||||
|
|
||||||
|
ReadClassStg( pStg, &clsid );
|
||||||
|
hr = create_automatic_entry( This, &clsid );
|
||||||
|
if (FAILED( hr )) return hr;
|
||||||
|
|
||||||
|
This->clsid = clsid;
|
||||||
|
|
||||||
hr = IStorage_OpenStream( pStg, CONTENTS, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
|
hr = IStorage_OpenStream( pStg, CONTENTS, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
|
||||||
0, &stm );
|
0, &stm );
|
||||||
if (SUCCEEDED( hr ))
|
if (SUCCEEDED( hr ))
|
||||||
|
@ -2162,7 +2241,7 @@ static HRESULT WINAPI DataCache_Cache(
|
||||||
return CACHE_S_SAMECACHE;
|
return CACHE_S_SAMECACHE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = DataCache_CreateEntry(This, &fmt_cpy, advf, &cache_entry, FALSE);
|
hr = DataCache_CreateEntry(This, &fmt_cpy, advf, FALSE, &cache_entry);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
@ -2593,12 +2672,16 @@ static DataCache* DataCache_Construct(
|
||||||
newObject->sinkAspects = 0;
|
newObject->sinkAspects = 0;
|
||||||
newObject->sinkAdviseFlag = 0;
|
newObject->sinkAdviseFlag = 0;
|
||||||
newObject->sinkInterface = 0;
|
newObject->sinkInterface = 0;
|
||||||
|
newObject->clsid = CLSID_NULL;
|
||||||
newObject->presentationStorage = NULL;
|
newObject->presentationStorage = NULL;
|
||||||
list_init(&newObject->cache_list);
|
list_init(&newObject->cache_list);
|
||||||
newObject->last_cache_id = 1;
|
newObject->last_cache_id = 2;
|
||||||
newObject->dirty = FALSE;
|
newObject->dirty = FALSE;
|
||||||
newObject->running_object = NULL;
|
newObject->running_object = NULL;
|
||||||
|
|
||||||
|
create_automatic_entry( newObject, clsid );
|
||||||
|
newObject->clsid = *clsid;
|
||||||
|
|
||||||
return newObject;
|
return newObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 32 KiB |
|
@ -53,6 +53,15 @@ HGLOBAL WINAPI OleGetIconOfClass(REFCLSID rclsid, LPOLESTR lpszLabel, BOOL fUseT
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* OleGetIconOfFile [OLE32.@]
|
||||||
|
*/
|
||||||
|
HGLOBAL WINAPI OleGetIconOfFile(LPOLESTR path, BOOL use_file_as_label)
|
||||||
|
{
|
||||||
|
FIXME("(%s, %d), stub!\n", debugstr_w(path), use_file_as_label);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* OleRegEnumFormatEtc [OLE32.@]
|
* OleRegEnumFormatEtc [OLE32.@]
|
||||||
*/
|
*/
|
||||||
|
@ -74,12 +83,3 @@ HRESULT WINAPI CoGetCallerTID(LPDWORD lpdwTID)
|
||||||
FIXME("stub!\n");
|
FIXME("stub!\n");
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* OleGetIconOfFile [OLE32.@]
|
|
||||||
*/
|
|
||||||
HGLOBAL WINAPI OleGetIconOfFile(LPOLESTR path, BOOL use_file_as_label)
|
|
||||||
{
|
|
||||||
FIXME("(%p, %d), stub!\n", path, use_file_as_label);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
|
@ -236,7 +236,7 @@
|
||||||
@ stdcall OleGetAutoConvert(ptr ptr)
|
@ stdcall OleGetAutoConvert(ptr ptr)
|
||||||
@ stdcall OleGetClipboard(ptr)
|
@ stdcall OleGetClipboard(ptr)
|
||||||
@ stdcall OleGetIconOfClass(ptr ptr long)
|
@ stdcall OleGetIconOfClass(ptr ptr long)
|
||||||
@ stdcall OleGetIconOfFile(ptr long)
|
@ stdcall OleGetIconOfFile(wstr long)
|
||||||
@ stdcall OleInitialize(ptr)
|
@ stdcall OleInitialize(ptr)
|
||||||
@ stdcall OleInitializeWOW(long long)
|
@ stdcall OleInitializeWOW(long long)
|
||||||
@ stdcall OleIsCurrentClipboard(ptr)
|
@ stdcall OleIsCurrentClipboard(ptr)
|
||||||
|
|
|
@ -139,7 +139,7 @@ reactos/dll/win32/ntdsapi # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/objsel # Synced to WineStaging-2.9
|
reactos/dll/win32/objsel # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/odbc32 # Synced to WineStaging-2.9. Depends on port of Linux ODBC.
|
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/odbccp32 # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/ole32 # Synced to WineStaging-2.9
|
reactos/dll/win32/ole32 # Synced to WineStaging-2.16
|
||||||
reactos/dll/win32/oleacc # Synced to WineStaging-2.9
|
reactos/dll/win32/oleacc # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/oleaut32 # Synced to WineStaging-2.9
|
reactos/dll/win32/oleaut32 # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/olecli32 # Synced to WineStaging-2.9
|
reactos/dll/win32/olecli32 # Synced to WineStaging-2.9
|
||||||
|
|