[PATCH 1/3] dx8vb: Add COM classfactory.

Fabian Maurer <[email protected]>
Newsgroups gmane.comp.emulators.wine.patches
Message-ID <[email protected]>
Signed-off-by: Fabian Maurer <[email protected]>
---
 dlls/dx8vb/Makefile.in |   1 +
 dlls/dx8vb/dx8vb.spec  |   8 +--
 dlls/dx8vb/main.c      | 153 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 158 insertions(+), 4 deletions(-)

diff --git a/dlls/dx8vb/Makefile.in b/dlls/dx8vb/Makefile.in
index ce3237c9a5..d9f93f96f1 100644
--- a/dlls/dx8vb/Makefile.in
+++ b/dlls/dx8vb/Makefile.in
@@ -1,4 +1,5 @@
 MODULE    = dx8vb.dll
+IMPORTS   = uuid ole32
 
 C_SRCS = \
 	main.c
diff --git a/dlls/dx8vb/dx8vb.spec b/dlls/dx8vb/dx8vb.spec
index 973d4b3f20..bb7c08300b 100644
--- a/dlls/dx8vb/dx8vb.spec
+++ b/dlls/dx8vb/dx8vb.spec
@@ -133,7 +133,7 @@
 @ stub D3DXMeshIndexBuffer8SetData
 @ stub D3DXMeshIndexBuffer8GetData
 @ stub DXCopyMemory
-@ stub DllCanUnloadNow
-@ stub DllGetClassObject
-@ stub DllRegisterServer
-@ stub DllUnregisterServer
+@ stdcall -private DllCanUnloadNow()
+@ stdcall -private DllGetClassObject(ptr ptr ptr)
+@ stdcall -private DllRegisterServer()
+@ stdcall -private DllUnregisterServer()
diff --git a/dlls/dx8vb/main.c b/dlls/dx8vb/main.c
index 0b60e345ca..1e23d40893 100644
--- a/dlls/dx8vb/main.c
+++ b/dlls/dx8vb/main.c
@@ -16,6 +16,10 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#define COBJMACROS
+
+#include "config.h"
+
 #include <stdarg.h>
 #include <string.h>
 
@@ -24,10 +28,17 @@
 #include "winuser.h"
 #include "winreg.h"
 
+#include "ole2.h"
+#include "rpcproxy.h"
+
+#include "unknwn.h"
+
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(dx8vb);
 
+static HINSTANCE instance_dx8vb;
+
 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
 {
     TRACE("(0x%p, %d, %p)\n", instance, reason, reserved);
@@ -38,8 +49,150 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
             return FALSE;    /* prefer native version */
         case DLL_PROCESS_ATTACH:
             DisableThreadLibraryCalls(instance);
+            instance_dx8vb = instance;
             break;
     }
 
     return TRUE;
 }
+
+typedef struct {
+    IClassFactory IClassFactory_iface;
+
+    LONG ref;
+    HRESULT (*pfnCreateInstance)(IUnknown *unk_outer, void **ppobj);
+} IClassFactoryImpl;
+
+static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
+{
+    return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
+}
+
+struct object_creation_info
+{
+    const CLSID *clsid;
+    HRESULT (*pfnCreateInstance)(IUnknown *unk_outer, void **ppobj);
+};
+
+static const struct object_creation_info object_creation[] =
+{
+    { &GUID_NULL, 0 },
+};
+
+static HRESULT WINAPI classfactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj)
+{
+    IClassFactoryImpl *This = impl_from_IClassFactory(iface);
+
+    if (IsEqualGUID(riid, &IID_IUnknown)
+        || IsEqualGUID(riid, &IID_IClassFactory))
+    {
+        IClassFactory_AddRef(iface);
+        *ppobj = &This->IClassFactory_iface;
+        return S_OK;
+    }
+
+    WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI classfactory_AddRef(IClassFactory *iface)
+{
+    IClassFactoryImpl *This = impl_from_IClassFactory(iface);
+    return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI classfactory_Release(IClassFactory *iface)
+{
+    IClassFactoryImpl *This = impl_from_IClassFactory(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    if (ref == 0)
+        HeapFree(GetProcessHeap(), 0, This);
+
+    return ref;
+}
+
+static HRESULT WINAPI classfactory_CreateInstance(IClassFactory *iface, IUnknown *outer_unk, REFIID riid, void **ppobj)
+{
+    IClassFactoryImpl *This = impl_from_IClassFactory(iface);
+    HRESULT hres;
+    IUnknown *unk;
+
+    TRACE("(%p)->(%p,%s,%p)\n", This, outer_unk, debugstr_guid(riid), ppobj);
+
+    *ppobj = NULL;
+    hres = This->pfnCreateInstance(outer_unk, (void **) &unk);
+    if (SUCCEEDED(hres))
+    {
+        hres = IUnknown_QueryInterface(unk, riid, ppobj);
+        IUnknown_Release(unk);
+    }
+    return hres;
+}
+
+static HRESULT WINAPI classfactory_LockServer(IClassFactory *iface, BOOL dolock)
+{
+    IClassFactoryImpl *This = impl_from_IClassFactory(iface);
+    FIXME("(%p)->(%d), stub!\n", This, dolock);
+    return S_OK;
+}
+
+static const IClassFactoryVtbl classfactory_Vtbl =
+{
+    classfactory_QueryInterface,
+    classfactory_AddRef,
+    classfactory_Release,
+    classfactory_CreateInstance,
+    classfactory_LockServer
+};
+
+HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
+{
+    unsigned int i;
+    IClassFactoryImpl *factory;
+
+    TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+
+    if (!IsEqualGUID(&IID_IClassFactory, riid)
+         && !IsEqualGUID( &IID_IUnknown, riid))
+        return E_NOINTERFACE;
+
+    for (i = 0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
+    {
+        if (IsEqualGUID(object_creation[i].clsid, rclsid))
+            break;
+    }
+
+    if (i == sizeof(object_creation)/sizeof(object_creation[0]))
+    {
+        FIXME("%s: no class found.\n", debugstr_guid(rclsid));
+        return CLASS_E_CLASSNOTAVAILABLE;
+    }
+
+    factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory));
+    if (factory == NULL)
+        return E_OUTOFMEMORY;
+
+    factory->IClassFactory_iface.lpVtbl = &classfactory_Vtbl;
+    factory->ref = 1;
+
+    factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
+
+    *ppv = &(factory->IClassFactory_iface);
+    return S_OK;
+}
+
+HRESULT WINAPI DllCanUnloadNow(void)
+{
+    return S_FALSE;
+}
+
+HRESULT WINAPI DllRegisterServer(void)
+{
+    return __wine_register_resources(instance_dx8vb);
+}
+
+HRESULT WINAPI DllUnregisterServer(void)
+{
+    return __wine_unregister_resources(instance_dx8vb);
+}
-- 
2.14.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.