Putting it back in the queue, as it's been a while now with no commit (for reasons discussed offline) ChangeLog: Implement a classfactory for the Global Interface Table
Index: dlls/ole32/compobj.c =================================================================== RCS file: /home/wine/wine/dlls/ole32/compobj.c,v retrieving revision 1.75 diff -u -r1.75 compobj.c --- dlls/ole32/compobj.c 13 May 2003 22:14:30 -0000 1.75 +++ dlls/ole32/compobj.c 20 May 2003 21:51:17 -0000 @@ -60,7 +60,7 @@ const CLSID CLSID_StdGlobalInterfaceTable = { 0x00000323, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46} }; -static void* StdGlobalInterfaceTableInstance; + /***************************************************************************** * Apartment management stuff Index: dlls/ole32/compobj_private.h =================================================================== RCS file: /home/wine/wine/dlls/ole32/compobj_private.h,v retrieving revision 1.7 diff -u -r1.7 compobj_private.h --- dlls/ole32/compobj_private.h 13 May 2003 00:41:58 -0000 1.7 +++ dlls/ole32/compobj_private.h 20 May 2003 21:51:17 -0000 @@ -29,9 +29,12 @@ extern void* StdGlobalInterfaceTable_Construct(); extern void StdGlobalInterfaceTable_Destroy(void* self); +extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv); extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr); extern HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv); + +extern void* StdGlobalInterfaceTableInstance; inline static HRESULT get_facbuf_for_iid(REFIID riid,IPSFactoryBuffer **facbuf) { Index: dlls/ole32/git.c =================================================================== RCS file: /home/wine/wine/dlls/ole32/git.c,v retrieving revision 1.3 diff -u -r1.3 git.c --- dlls/ole32/git.c 10 Apr 2003 18:17:35 -0000 1.3 +++ dlls/ole32/git.c 20 May 2003 21:51:18 -0000 @@ -74,6 +74,8 @@ } StdGlobalInterfaceTableImpl; +void* StdGlobalInterfaceTableInstance; + /* IUnknown */ static HRESULT WINAPI StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface, REFIID riid, void** ppvObject); @@ -105,6 +107,8 @@ void* StdGlobalInterfaceTable_Construct() { StdGlobalInterfaceTableImpl* newGIT; + TRACE("constructing\n"); + newGIT = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGlobalInterfaceTableImpl)); if (newGIT == 0) return newGIT; @@ -141,6 +145,7 @@ if (e->cookie == cookie) return e; e = e->next; } + TRACE("Entry not found\n"); return NULL; } @@ -198,7 +203,7 @@ HRESULT hres; StdGITEntry* entry; - TRACE("iface=%p, pUnk=%p, riid=%s, pdwCookie=%p\n", iface, pUnk, debugstr_guid(riid), pdwCookie); + TRACE("iface=%p, pUnk=%p, riid=%s, pdwCookie=0x%p\n", iface, pUnk, debugstr_guid(riid), pdwCookie); if (pUnk == NULL) return E_INVALIDARG; @@ -222,6 +227,7 @@ /* and return the cookie */ *pdwCookie = entry->cookie; + TRACE("Cookie is 0x%ld\n", entry->cookie); return S_OK; } @@ -249,6 +255,8 @@ HRESULT WINAPI StdGlobalInterfaceTable_GetInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie, REFIID riid, void **ppv) { StdGITEntry* entry; HRESULT hres; + + TRACE("dwCookie=0x%lx, riid=%s\n", dwCookie, debugstr_guid(riid)); entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie); if (entry == NULL) return E_INVALIDARG; @@ -258,5 +266,50 @@ hres = CoGetInterfaceAndReleaseStream(entry->stream, riid, *ppv); if (hres) return hres; + return S_OK; +} + +/* Classfactory definition - despite what MSDN says, some programs need this */ + +static HRESULT WINAPI GITCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv) { + *ppv = NULL; + if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IGlobalInterfaceTable)) { + *ppv = (LPVOID)iface; + return S_OK; + } + return E_NOINTERFACE; +} +static ULONG WINAPI GITCF_AddRef(LPCLASSFACTORY iface) { return 2; } +static ULONG WINAPI GITCF_Release(LPCLASSFACTORY iface) { return 1; } + +static HRESULT WINAPI GITCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv) { + if (IsEqualIID(riid,&IID_IGlobalInterfaceTable)) { + if (StdGlobalInterfaceTableInstance == NULL) + StdGlobalInterfaceTableInstance = StdGlobalInterfaceTable_Construct(); + return IGlobalInterfaceTable_QueryInterface( (IGlobalInterfaceTable*) StdGlobalInterfaceTableInstance, riid, ppv); + } + + FIXME("(%s), not supported.\n",debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static HRESULT WINAPI GITCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) { + FIXME("(%d), stub!\n",fLock); + return S_OK; +} + +static ICOM_VTABLE(IClassFactory) GITClassFactoryVtbl = { + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + GITCF_QueryInterface, + GITCF_AddRef, + GITCF_Release, + GITCF_CreateInstance, + GITCF_LockServer +}; +static ICOM_VTABLE(IClassFactory) *PGITClassFactoryVtbl = &GITClassFactoryVtbl; + +HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv) { + *ppv = &PGITClassFactoryVtbl; + TRACE("Returning GIT classfactory\n"); return S_OK; } Index: dlls/ole32/oleproxy.c =================================================================== RCS file: /home/wine/wine/dlls/ole32/oleproxy.c,v retrieving revision 1.7 diff -u -r1.7 oleproxy.c --- dlls/ole32/oleproxy.c 13 May 2003 00:41:58 -0000 1.7 +++ dlls/ole32/oleproxy.c 20 May 2003 21:51:21 -0000 @@ -515,6 +515,9 @@ ) ) return MARSHAL_GetStandardMarshalCF(ppv); + if (IsEqualIID(rclsid,&CLSID_StdGlobalInterfaceTable) && (IsEqualIID(iid,&IID_IClassFactory) || IsEqualIID(iid,&IID_IUnknown))) + return StdGlobalInterfaceTable_GetFactory(ppv); + FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid)); return CLASS_E_CLASSNOTAVAILABLE; }