Superseded patch 150331. Thanks Zhiyi's advice.
For bug 42710: https://bugs.winehq.org/show_bug.cgi?id=42710 .
Signed-off-by: Jactry Zeng jzeng@codeweavers.com --- dlls/ole32/ole2impl.c | 51 ++++++++++++++++++++++++++++++++++-- dlls/ole32/tests/ole2.c | 57 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 2 deletions(-)
diff --git a/dlls/ole32/ole2impl.c b/dlls/ole32/ole2impl.c index fa5777beb0..8927267e90 100644 --- a/dlls/ole32/ole2impl.c +++ b/dlls/ole32/ole2impl.c @@ -232,9 +232,56 @@ HRESULT WINAPI OleCreateStaticFromData(IDataObject *data, REFIID iid, IOleClientSite *client_site, IStorage *stg, void **obj) { - FIXME("%p,%s,%08x,%p,%p,%p,%p: semi-stub\n", + HRESULT hr; + IOleCache2 *ole_cache = NULL; + IPersistStorage *persist = NULL; + DWORD connection; + STGMEDIUM stgmedium; + + TRACE("(%p, %s, 0x%08x, %p, %p, %p, %p)\n", data, debugstr_guid(iid), renderopt, fmt, client_site, stg, obj); - return OleCreateFromData(data, iid, renderopt, fmt, client_site, stg, obj); + + if (!obj || !stg) + return E_INVALIDARG; + + if (renderopt != OLERENDER_FORMAT) + { + FIXME("semi-stub\n"); + return OleCreateFromData(data, iid, renderopt, fmt, client_site, stg, obj); + } + + if (!fmt) + return E_INVALIDARG; + + hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&ole_cache); + if (FAILED(hr)) goto end; + + hr = IOleCache2_Cache(ole_cache, fmt, ADVF_PRIMEFIRST, &connection); + if (FAILED(hr)) goto end; + + hr = IDataObject_GetData(data, fmt, &stgmedium); + if (FAILED(hr)) goto end; + + hr = IOleCache2_SetData(ole_cache, fmt, &stgmedium, TRUE); + if (FAILED(hr)) goto end; + + hr = IOleCache2_QueryInterface(ole_cache, &IID_IPersistStorage, (LPVOID *)&persist); + if (FAILED(hr)) goto end; + + hr = IPersistStorage_Save(persist, stg, TRUE); + if (FAILED(hr)) goto end; + + hr = IPersistStorage_SaveCompleted(persist, NULL); + if (FAILED(hr)) goto end; + + hr = OleLoad(stg, iid, client_site, obj); + +end: + if (persist) + IPersistStorage_Release(persist); + if (ole_cache) + IOleCache2_Release(ole_cache); + return hr; }
/****************************************************************************** diff --git a/dlls/ole32/tests/ole2.c b/dlls/ole32/tests/ole2.c index 48c9e0cbab..ceec369dc3 100644 --- a/dlls/ole32/tests/ole2.c +++ b/dlls/ole32/tests/ole2.c @@ -4593,6 +4593,62 @@ todo_wine_if(!(test_data[i].in == &stg_def_0 || test_data[i].in == &stg_def_4 || } }
+static void test_OleCreateStaticFromData(void) +{ + HRESULT hr; + IOleObject *ole_obj = NULL; + IStorage *storage; + ILockBytes *ilb; + static FORMATETC bitmap_fmt[] = + { + { CF_BITMAP, NULL, DVASPECT_CONTENT, -1, TYMED_GDI }, + { 0 } + }; + static const struct expected_method methods_create_from_bitmap[] = + { + { "DataObject_EnumFormatEtc", TEST_TODO }, + { "DataObject_GetDataHere", 0 }, + { "DataObject_QueryGetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_ISTORAGE } }, + { NULL } + }; + static const struct expected_method methods_createstatic_from_bitmap[] = + { + { "DataObject_GetData", 0, { CF_BITMAP, NULL, DVASPECT_CONTENT, -1, TYMED_GDI } }, + { NULL } + }; + + hr = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb); + ok(hr == S_OK, "CreateILockBytesOnHGlobal failed: 0x%08x.\n", hr); + hr = StgCreateDocfileOnILockBytes(ilb, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, + 0, &storage); + ok(hr == S_OK, "StgCreateDocfileOnILockBytes failed: 0x%08x.\n", hr); + + hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT, + bitmap_fmt, NULL, NULL, (void **)&ole_obj); + ok(hr == E_INVALIDARG, "OleCreateStaticFromData should fail: 0x%08x.\n", hr); + + hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT, + bitmap_fmt, NULL, storage, NULL); + ok(hr == E_INVALIDARG, "OleCreateStaticFromData should fail: 0x%08x.\n", hr); + + g_dataobject_fmts = bitmap_fmt; + expected_method_list = methods_create_from_bitmap; + hr = OleCreateFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT, bitmap_fmt, NULL, + storage, (void **)&ole_obj); + todo_wine ok(hr == DV_E_FORMATETC, "OleCreateFromData should failed: 0x%08x.\n", hr); + + g_dataobject_fmts = bitmap_fmt; + expected_method_list = methods_createstatic_from_bitmap; + hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT, + bitmap_fmt, NULL, storage, (void **)&ole_obj); + ok(hr == S_OK, "OleCreateStaticFromData failed: 0x%08x.\n", hr); + if (ole_obj) + IOleObject_Release(ole_obj); + + IStorage_Release(storage); + ILockBytes_Release(ilb); +} + START_TEST(ole2) { DWORD dwRegister; @@ -4643,6 +4699,7 @@ START_TEST(ole2) test_data_cache_save(); test_data_cache_save_data(); test_data_cache_contents(); + test_OleCreateStaticFromData();
CoUninitialize(); }
On Tue, Aug 28, 2018 at 09:25:02PM +0800, Jactry Zeng wrote:
Superseded patch 150331. Thanks Zhiyi's advice.
For bug 42710: https://bugs.winehq.org/show_bug.cgi?id=42710 .
Signed-off-by: Jactry Zeng jzeng@codeweavers.com
dlls/ole32/ole2impl.c | 51 ++++++++++++++++++++++++++++++++++-- dlls/ole32/tests/ole2.c | 57 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 2 deletions(-)
diff --git a/dlls/ole32/ole2impl.c b/dlls/ole32/ole2impl.c index fa5777beb0..8927267e90 100644 --- a/dlls/ole32/ole2impl.c +++ b/dlls/ole32/ole2impl.c @@ -232,9 +232,56 @@ HRESULT WINAPI OleCreateStaticFromData(IDataObject *data, REFIID iid, IOleClientSite *client_site, IStorage *stg, void **obj) {
- FIXME("%p,%s,%08x,%p,%p,%p,%p: semi-stub\n",
- HRESULT hr;
- IOleCache2 *ole_cache = NULL;
- IPersistStorage *persist = NULL;
- DWORD connection;
- STGMEDIUM stgmedium;
- TRACE("(%p, %s, 0x%08x, %p, %p, %p, %p)\n", data, debugstr_guid(iid), renderopt, fmt, client_site, stg, obj);
- return OleCreateFromData(data, iid, renderopt, fmt, client_site, stg, obj);
- if (!obj || !stg)
return E_INVALIDARG;
- if (renderopt != OLERENDER_FORMAT)
- {
FIXME("semi-stub\n");
return OleCreateFromData(data, iid, renderopt, fmt, client_site, stg, obj);
- }
- if (!fmt)
return E_INVALIDARG;
- hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&ole_cache);
- if (FAILED(hr)) goto end;
This should most likely call OleCreateDefaultHandler() instead so that you don't need the OleLoad later on.
- hr = IOleCache2_Cache(ole_cache, fmt, ADVF_PRIMEFIRST, &connection);
- if (FAILED(hr)) goto end;
- hr = IDataObject_GetData(data, fmt, &stgmedium);
- if (FAILED(hr)) goto end;
- hr = IOleCache2_SetData(ole_cache, fmt, &stgmedium, TRUE);
- if (FAILED(hr)) goto end;
- hr = IOleCache2_QueryInterface(ole_cache, &IID_IPersistStorage, (LPVOID *)&persist);
- if (FAILED(hr)) goto end;
- hr = IPersistStorage_Save(persist, stg, TRUE);
- if (FAILED(hr)) goto end;
- hr = IPersistStorage_SaveCompleted(persist, NULL);
- if (FAILED(hr)) goto end;
- hr = OleLoad(stg, iid, client_site, obj);
Thanks Huw! I sent another try. Huw Davies huw@codeweavers.com 于2018年8月29日周三 下午3:29写道:
On Tue, Aug 28, 2018 at 09:25:02PM +0800, Jactry Zeng wrote:
Superseded patch 150331. Thanks Zhiyi's advice.
For bug 42710: https://bugs.winehq.org/show_bug.cgi?id=42710 .
Signed-off-by: Jactry Zeng jzeng@codeweavers.com
dlls/ole32/ole2impl.c | 51 ++++++++++++++++++++++++++++++++++-- dlls/ole32/tests/ole2.c | 57 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 2 deletions(-)
diff --git a/dlls/ole32/ole2impl.c b/dlls/ole32/ole2impl.c index fa5777beb0..8927267e90 100644 --- a/dlls/ole32/ole2impl.c +++ b/dlls/ole32/ole2impl.c @@ -232,9 +232,56 @@ HRESULT WINAPI OleCreateStaticFromData(IDataObject *data, REFIID iid, IOleClientSite *client_site, IStorage *stg, void **obj) {
- FIXME("%p,%s,%08x,%p,%p,%p,%p: semi-stub\n",
- HRESULT hr;
- IOleCache2 *ole_cache = NULL;
- IPersistStorage *persist = NULL;
- DWORD connection;
- STGMEDIUM stgmedium;
- TRACE("(%p, %s, 0x%08x, %p, %p, %p, %p)\n", data, debugstr_guid(iid), renderopt, fmt, client_site, stg, obj);
- return OleCreateFromData(data, iid, renderopt, fmt, client_site, stg, obj);
- if (!obj || !stg)
return E_INVALIDARG;
- if (renderopt != OLERENDER_FORMAT)
- {
FIXME("semi-stub\n");
return OleCreateFromData(data, iid, renderopt, fmt, client_site, stg, obj);
- }
- if (!fmt)
return E_INVALIDARG;
- hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&ole_cache);
- if (FAILED(hr)) goto end;
This should most likely call OleCreateDefaultHandler() instead so that you don't need the OleLoad later on.
- hr = IOleCache2_Cache(ole_cache, fmt, ADVF_PRIMEFIRST, &connection);
- if (FAILED(hr)) goto end;
- hr = IDataObject_GetData(data, fmt, &stgmedium);
- if (FAILED(hr)) goto end;
- hr = IOleCache2_SetData(ole_cache, fmt, &stgmedium, TRUE);
- if (FAILED(hr)) goto end;
- hr = IOleCache2_QueryInterface(ole_cache, &IID_IPersistStorage, (LPVOID *)&persist);
- if (FAILED(hr)) goto end;
- hr = IPersistStorage_Save(persist, stg, TRUE);
- if (FAILED(hr)) goto end;
- hr = IPersistStorage_SaveCompleted(persist, NULL);
- if (FAILED(hr)) goto end;
- hr = OleLoad(stg, iid, client_site, obj);