Nikolay Sivov : ole32: Implement CoGetInstanceFromFile().

Alexandre Julliard julliard at winehq.org
Thu Feb 6 13:25:30 CST 2014


Module: wine
Branch: master
Commit: 35f218c39eb6707f43eb4917539003c7df8250b1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=35f218c39eb6707f43eb4917539003c7df8250b1

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Feb  6 08:44:46 2014 +0400

ole32: Implement CoGetInstanceFromFile().

---

 dlls/ole32/compobj.c  |  116 +++++++++++++++++++++++++++++++++++++------------
 dlls/ole32/ole32.spec |    2 +-
 2 files changed, 89 insertions(+), 29 deletions(-)

diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 3c0c085..4149ecb 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -3196,6 +3196,36 @@ HRESULT WINAPI CoCreateInstance(
     return hres;
 }
 
+static void init_multi_qi(DWORD count, MULTI_QI *mqi)
+{
+  ULONG i;
+
+  for (i = 0; i < count; i++)
+  {
+      mqi[i].pItf = NULL;
+      mqi[i].hr = E_NOINTERFACE;
+  }
+}
+
+static HRESULT return_multi_qi(IUnknown *unk, DWORD count, MULTI_QI *mqi)
+{
+  ULONG index, fetched = 0;
+
+  for (index = 0; index < count; index++)
+  {
+    mqi[index].hr = IUnknown_QueryInterface(unk, mqi[index].pIID, (void**)&mqi[index].pItf);
+    if (mqi[index].hr == S_OK)
+      fetched++;
+  }
+
+  IUnknown_Release(unk);
+
+  if (fetched == 0)
+    return E_NOINTERFACE;
+
+  return fetched == count ? S_OK : CO_S_NOTALLINTERFACES;
+}
+
 /***********************************************************************
  *           CoCreateInstanceEx [OLE32.@]
  */
@@ -3209,8 +3239,6 @@ HRESULT WINAPI CoCreateInstanceEx(
 {
   IUnknown* pUnk = NULL;
   HRESULT   hr;
-  ULONG     index;
-  ULONG     successCount = 0;
 
   /*
    * Sanity check
@@ -3221,14 +3249,7 @@ HRESULT WINAPI CoCreateInstanceEx(
   if (pServerInfo!=NULL)
     FIXME("() non-NULL pServerInfo not supported!\n");
 
-  /*
-   * Initialize all the "out" parameters.
-   */
-  for (index = 0; index < cmq; index++)
-  {
-    pResults[index].pItf = NULL;
-    pResults[index].hr   = E_NOINTERFACE;
-  }
+  init_multi_qi(cmq, pResults);
 
   /*
    * Get the object and get its IUnknown pointer.
@@ -3242,31 +3263,70 @@ HRESULT WINAPI CoCreateInstanceEx(
   if (hr != S_OK)
     return hr;
 
-  /*
-   * Then, query for all the interfaces requested.
-   */
-  for (index = 0; index < cmq; index++)
+  return return_multi_qi(pUnk, cmq, pResults);
+}
+
+/***********************************************************************
+ *           CoGetInstanceFromFile [OLE32.@]
+ */
+HRESULT WINAPI 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);
+
+  /* optionaly get CLSID from a file */
+  if (!rclsid)
   {
-    pResults[index].hr = IUnknown_QueryInterface(pUnk,
-						 pResults[index].pIID,
-						 (VOID**)&(pResults[index].pItf));
+    hr = GetClassFile(filename, &clsid);
+    if (FAILED(hr))
+    {
+      ERR("failed to get CLSID from a file\n");
+      return hr;
+    }
 
-    if (pResults[index].hr == S_OK)
-      successCount++;
+    rclsid = &clsid;
   }
 
-  /*
-   * Release our temporary unknown pointer.
-   */
-  IUnknown_Release(pUnk);
+  hr = CoCreateInstance(rclsid,
+			outer,
+			cls_context,
+			&IID_IUnknown,
+			(void**)&unk);
 
-  if (successCount == 0)
-    return E_NOINTERFACE;
+  if (hr != S_OK)
+    return hr;
 
-  if (successCount!=cmq)
-    return CO_S_NOTALLINTERFACES;
+  /* init from file */
+  hr = IUnknown_QueryInterface(unk, &IID_IPersistFile, (void**)&pf);
+  if (FAILED(hr))
+      ERR("failed to get IPersistFile\n");
 
-  return S_OK;
+  if (pf)
+  {
+      IPersistFile_Load(pf, filename, grfmode);
+      IPersistFile_Release(pf);
+  }
+
+  return return_multi_qi(unk, count, results);
 }
 
 /***********************************************************************
diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec
index d71168e..28a84a1 100644
--- a/dlls/ole32/ole32.spec
+++ b/dlls/ole32/ole32.spec
@@ -29,7 +29,7 @@
 @ stdcall CoGetCurrentLogicalThreadId(ptr)
 @ stdcall CoGetCurrentProcess()
 @ stdcall CoGetDefaultContext(long ptr ptr)
-@ stub CoGetInstanceFromFile      #@ stdcall (ptr ptr ptr long wstr long ptr) return 0,ERR_NOTIMPLEMENTED
+@ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr)
 @ stub CoGetInstanceFromIStorage  #@ stdcall (ptr ptr ptr long ptr long ptr) return 0,ERR_NOTIMPLEMENTED
 @ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr)
 @ stdcall CoGetMalloc(long ptr)




More information about the wine-cvs mailing list