Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/combase/combase.c | 98 +++++++++++++++++++++++++++++++++++++++ dlls/combase/combase.spec | 2 +- dlls/ole32/compobj.c | 73 ----------------------------- dlls/ole32/ole32.spec | 2 +- 4 files changed, 100 insertions(+), 75 deletions(-)
diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c index 1370aa82718..06fc97e17d4 100644 --- a/dlls/combase/combase.c +++ b/dlls/combase/combase.c @@ -627,3 +627,101 @@ HRESULT WINAPI CoGetActivationState(GUID guid, DWORD arg2, DWORD *arg3)
return E_NOTIMPL; } + +static void init_multi_qi(DWORD count, MULTI_QI *mqi, HRESULT hr) +{ + ULONG i; + + for (i = 0; i < count; i++) + { + mqi[i].pItf = NULL; + mqi[i].hr = hr; + } +} + +static HRESULT return_multi_qi(IUnknown *unk, DWORD count, MULTI_QI *mqi, BOOL include_unk) +{ + ULONG index = 0, fetched = 0; + + if (include_unk) + { + mqi[0].hr = S_OK; + mqi[0].pItf = unk; + index = fetched = 1; + } + + for (; index < count; index++) + { + mqi[index].hr = IUnknown_QueryInterface(unk, mqi[index].pIID, (void **)&mqi[index].pItf); + if (mqi[index].hr == S_OK) + fetched++; + } + + if (!include_unk) + IUnknown_Release(unk); + + if (fetched == 0) + return E_NOINTERFACE; + + return fetched == count ? S_OK : CO_S_NOTALLINTERFACES; +} + +/*********************************************************************** + * CoGetInstanceFromFile (combase.@) + */ +HRESULT WINAPI DECLSPEC_HOTPATCH CoGetInstanceFromFile(COSERVERINFO *server_info, CLSID *rclsid, + IUnknown *outer, DWORD cls_context, DWORD grfmode, OLECHAR *filename, DWORD count, + MULTI_QI *results) +{ + IPersistFile *pf = NULL; + IUnknown *obj = NULL; + CLSID clsid; + HRESULT hr; + + if (!count || !results) + return E_INVALIDARG; + + if (server_info) + FIXME("() non-NULL server_info not supported\n"); + + init_multi_qi(count, results, E_NOINTERFACE); + + if (!rclsid) + { + hr = GetClassFile(filename, &clsid); + if (FAILED(hr)) + { + ERR("Failed to get CLSID from a file.\n"); + return hr; + } + + rclsid = &clsid; + } + + hr = CoCreateInstance(rclsid, outer, cls_context, &IID_IUnknown, (void **)&obj); + if (hr != S_OK) + { + init_multi_qi(count, results, hr); + return hr; + } + + /* Init from file */ + hr = IUnknown_QueryInterface(obj, &IID_IPersistFile, (void **)&pf); + if (FAILED(hr)) + { + init_multi_qi(count, results, hr); + IUnknown_Release(obj); + return hr; + } + + hr = IPersistFile_Load(pf, filename, grfmode); + IPersistFile_Release(pf); + if (SUCCEEDED(hr)) + return return_multi_qi(obj, count, results, FALSE); + else + { + init_multi_qi(count, results, hr); + IUnknown_Release(obj); + return hr; + } +} diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index 4f737aeb53a..e90df05446e 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -107,7 +107,7 @@ @ stdcall CoGetCurrentProcess() ole32.CoGetCurrentProcess @ stdcall CoGetDefaultContext(long ptr ptr) ole32.CoGetDefaultContext @ stub CoGetErrorInfo -@ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr) ole32.CoGetInstanceFromFile +@ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr) @ stdcall CoGetInstanceFromIStorage(ptr ptr ptr long ptr long ptr) ole32.CoGetInstanceFromIStorage @ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr) ole32.CoGetInterfaceAndReleaseStream @ stdcall CoGetMalloc(long ptr) diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index 6a0c518081e..1ad8a4b1d1d 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -3434,79 +3434,6 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstanceEx( return return_multi_qi(unk, cmq, pResults, TRUE); }
-/*********************************************************************** - * CoGetInstanceFromFile [OLE32.@] - */ -HRESULT WINAPI DECLSPEC_HOTPATCH CoGetInstanceFromFile( - COSERVERINFO *server_info, - CLSID *rclsid, - IUnknown *outer, - DWORD cls_context, - DWORD grfmode, - OLECHAR *filename, - DWORD count, - MULTI_QI *results -) -{ - IPersistFile *pf = NULL; - IUnknown* unk = NULL; - CLSID clsid; - HRESULT hr; - - if (count == 0 || !results) - return E_INVALIDARG; - - if (server_info) - FIXME("() non-NULL server_info not supported\n"); - - init_multi_qi(count, results, E_NOINTERFACE); - - /* optionally get CLSID from a file */ - if (!rclsid) - { - hr = GetClassFile(filename, &clsid); - if (FAILED(hr)) - { - ERR("failed to get CLSID from a file\n"); - return hr; - } - - rclsid = &clsid; - } - - hr = CoCreateInstance(rclsid, - outer, - cls_context, - &IID_IUnknown, - (void**)&unk); - - if (hr != S_OK) - { - init_multi_qi(count, results, hr); - return hr; - } - - /* init from file */ - hr = IUnknown_QueryInterface(unk, &IID_IPersistFile, (void**)&pf); - if (FAILED(hr)) - { - init_multi_qi(count, results, hr); - IUnknown_Release(unk); - return hr; - } - - hr = IPersistFile_Load(pf, filename, grfmode); - IPersistFile_Release(pf); - if (SUCCEEDED(hr)) - return return_multi_qi(unk, count, results, FALSE); - else - { - init_multi_qi(count, results, hr); - IUnknown_Release(unk); - return hr; - } -} - /*********************************************************************** * CoGetInstanceFromIStorage [OLE32.@] */ diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index ef074bbc26e..b1949eec8ec 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -35,7 +35,7 @@ @ stdcall CoGetCurrentLogicalThreadId(ptr) @ stdcall CoGetCurrentProcess() @ stdcall CoGetDefaultContext(long ptr ptr) -@ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr) +@ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr) combase.CoGetInstanceFromFile @ stdcall CoGetInstanceFromIStorage(ptr ptr ptr long ptr long ptr) @ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr) @ stdcall CoGetMalloc(long ptr) combase.CoGetMalloc