[v2 2/5] compobj.dll16: Implement CoGetClassObject16().

Zebediah Figura z.figura12 at gmail.com
Thu Feb 9 00:17:12 CST 2017


Fixes https://bugs.winehq.org/show_bug.cgi?id=41209

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/compobj.dll16/compobj.c | 89 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 76 insertions(+), 13 deletions(-)

diff --git a/dlls/compobj.dll16/compobj.c b/dlls/compobj.dll16/compobj.c
index 1673532..aa87227 100644
--- a/dlls/compobj.dll16/compobj.c
+++ b/dlls/compobj.dll16/compobj.c
@@ -42,6 +42,7 @@
 #include "wtypes.h"
 #include "wine/unicode.h"
 #include "wine/winbase16.h"
+#include "wine/list.h"
 
 #include "wine/debug.h"
 
@@ -256,11 +257,11 @@ static HRESULT dll_list_add(LPCSTR library_name, struct open_dll **ret)
 {
     struct open_dll *dll;
     HMODULE16 library;
-    FARPROC16 DllCanUnloadNow, DllGetClassObject;
+    FARPROC16 DllCanUnloadNow;
 
     LIST_FOR_EACH_ENTRY(dll, &open_dll_list, struct open_dll, entry)
     {
-        if(!strcasecmp(library_name, ptr->library_name))
+        if(!strcasecmp(library_name, dll->library_name))
         {
             TRACE("found %s already loaded\n", debugstr_a(library_name));
             dll->refs++;
@@ -294,10 +295,10 @@ static HRESULT dll_list_add(LPCSTR library_name, struct open_dll **ret)
 
 static void dll_list_free(struct open_dll *entry)
 {
-    TRACE("freeing %s\n", debugstr_a(library_name));
+    TRACE("freeing %s\n", debugstr_a(entry->library_name));
 
     list_remove(&entry->entry);
-    FreeLibrary(entry->library);
+    FreeLibrary16(entry->library);
     HeapFree(GetProcessHeap(), 0, entry->library_name);
     HeapFree(GetProcessHeap(), 0, entry);
 }
@@ -307,14 +308,14 @@ static void dll_list_free(struct open_dll *entry)
  *
  * Called internally by CoGetClassObject().
  */
-HINSTANCE WINAPI CoLoadLibrary16(
-    LPOLESTR lpszLibName,
+HINSTANCE16 WINAPI CoLoadLibrary16(
+    LPOLESTR16 lpszLibName,
     BOOL bAutoFree)
 {
-    struct open_dll dll;
+    struct open_dll *dll;
 
     if(dll_list_add(lpszLibName, &dll) != S_OK)
-        return NULL;
+        return ERROR_INVALID_HANDLE;
 
     return dll->library;
 }
@@ -325,7 +326,7 @@ HINSTANCE WINAPI CoLoadLibrary16(
  * Called internally by CoGetClassObject().
  */
 void WINAPI CoFreeLibrary16(
-    HINSTANCE hInst)
+    HINSTANCE16 hInst)
 {
     struct open_dll *dll;
 
@@ -813,14 +814,76 @@ HRESULT WINAPI CoFileTimeNow16( FILETIME *lpFileTime )
  */
 HRESULT WINAPI CoGetClassObject16(
     REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo,
-    REFIID iid, LPVOID *ppv)
+    REFIID riid, LPVOID *ppv)
 {
-    FIXME(", stub!\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
+    HRESULT hres = E_UNEXPECTED;
+
+    TRACE("CLSID: %s,IID: %s\n", debugstr_guid(rclsid), debugstr_guid(riid));
 
+    *ppv = NULL;
+ 
     if (pServerInfo) {
-	FIXME("\tpServerInfo: name=%s\n",debugstr_w(pServerInfo->pwszName));
-	FIXME("\t\tpAuthInfo=%p\n",pServerInfo->pAuthInfo);
+        FIXME("pServerInfo->name=%s pAuthInfo=%p\n",
+              debugstr_w(pServerInfo->pwszName), pServerInfo->pAuthInfo);
+    }
+
+    if (CLSCTX_INPROC_SERVER & dwClsContext)
+    {
+        char idstr[CHARS_IN_GUID];
+        char buf_key[CHARS_IN_GUID+19], dllpath[MAX_PATH+1];
+        LONG dllpath_len = sizeof(dllpath);
+        
+        struct open_dll *dll;
+        FARPROC16 DllGetClassObject;
+        
+        SEGPTR seg_rclsid = MapLS(rclsid);
+        SEGPTR seg_riid   = MapLS(riid);
+        SEGPTR seg_ppv    = MapLS(ppv);
+        WORD args[6];
+        DWORD dwRet;
+
+        hres = StringFromGUID216(rclsid, idstr, CHARS_IN_GUID);
+        sprintf(buf_key, "CLSID\\%s\\InprocServer", idstr);
+        if (RegQueryValueA(HKEY_CLASSES_ROOT, buf_key, dllpath, &dllpath_len))
+        {
+            ERR("class %s not registered\n", debugstr_guid(rclsid));
+            return REGDB_E_CLASSNOTREG;
+        }
+
+        hres = dll_list_add(dllpath, &dll);
+        if (FAILED(hres))
+            return hres;
+
+        DllGetClassObject = GetProcAddress16(dll->library, "DllGetClassObject");
+        if (!DllGetClassObject)
+        {
+            ERR("couldn't find function DllGetClassObject in %s\n", debugstr_a(dll->library_name));
+            dll_list_free(dll);
+            return CO_E_DLLNOTFOUND;
+        }
+
+        TRACE("calling DllGetClassObject %p\n", DllGetClassObject);
+        args[5] = SELECTOROF(seg_rclsid);
+        args[4] = OFFSETOF(seg_rclsid);
+        args[3] = SELECTOROF(seg_riid);
+        args[2] = OFFSETOF(seg_riid);
+        args[1] = SELECTOROF(seg_ppv);
+        args[0] = OFFSETOF(seg_ppv);
+        WOWCallback16Ex((DWORD) DllGetClassObject, WCB16_PASCAL, sizeof(args), args, &dwRet);
+        if (dwRet != S_OK)
+        {
+            ERR("DllGetClassObject returned error 0x%08x\n", dwRet);
+            return dwRet;
+        }
+
+        UnMapLS(seg_rclsid);
+        UnMapLS(seg_riid);
+        UnMapLS(seg_ppv);
+
+        return S_OK;
     }
+
+    FIXME("semi-stub\n");
     return E_NOTIMPL;
 }
 
-- 
2.7.4




More information about the wine-patches mailing list