[DEVENUM] Sync with Wine Staging 4.18. CORE-16441
[reactos.git] / dll / directx / wine / devenum / devenum_main.c
index 21e7b47..3f60c29 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     exported dll functions for devenum.dll
+ * Device Enumeration
  *
  * Copyright (C) 2002 John K. Hohm
  * Copyright (C) 2002 Robert Shearman
  */
 
 #include "devenum_private.h"
+#include "rpcproxy.h"
+#include "wine/debug.h"
 
-#include <rpcproxy.h>
+WINE_DEFAULT_DEBUG_CHANNEL(devenum);
 
 DECLSPEC_HIDDEN LONG dll_refs;
-DECLSPEC_HIDDEN HINSTANCE DEVENUM_hInstance;
-
-typedef struct
-{
-    REFCLSID clsid;
-    LPCWSTR friendly_name;
-    BOOL instance;
-} register_info;
+static HINSTANCE devenum_instance;
 
 #ifdef __REACTOS__
 static void DEVENUM_RegisterQuartz(void);
 #endif
 
-/***********************************************************************
- *             Global string constant definitions
- */
-const WCHAR clsid_keyname[6] = { 'C', 'L', 'S', 'I', 'D', 0 };
-
 /***********************************************************************
  *             DllEntryPoint
  */
@@ -51,29 +41,101 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
 
     switch(fdwReason) {
     case DLL_PROCESS_ATTACH:
-        DEVENUM_hInstance = hinstDLL;
+        devenum_instance = hinstDLL;
         DisableThreadLibraryCalls(hinstDLL);
        break;
     }
     return TRUE;
 }
 
+struct class_factory
+{
+    IClassFactory IClassFactory_iface;
+    IUnknown *obj;
+};
+
+static inline struct class_factory *impl_from_IClassFactory( IClassFactory *iface )
+{
+    return CONTAINING_RECORD( iface, struct class_factory, IClassFactory_iface );
+}
+
+static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID iid, void **obj)
+{
+    TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), obj);
+
+    if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
+    {
+        IClassFactory_AddRef(iface);
+        *obj = iface;
+        return S_OK;
+    }
+
+    *obj = NULL;
+    WARN("no interface for %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
+{
+    DEVENUM_LockModule();
+    return 2;
+}
+
+static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
+{
+    DEVENUM_UnlockModule();
+    return 1;
+}
+
+static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface,
+    IUnknown *outer, REFIID iid, void **obj)
+{
+    struct class_factory *This = impl_from_IClassFactory( iface );
+
+    TRACE("(%p, %s, %p)\n", outer, debugstr_guid(iid), obj);
+
+    if (!obj) return E_POINTER;
+
+    if (outer) return CLASS_E_NOAGGREGATION;
+
+    return IUnknown_QueryInterface(This->obj, iid, obj);
+}
+
+static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL lock)
+{
+    if (lock)
+        DEVENUM_LockModule();
+    else
+        DEVENUM_UnlockModule();
+    return S_OK;
+}
+
+static const IClassFactoryVtbl ClassFactory_vtbl = {
+    ClassFactory_QueryInterface,
+    ClassFactory_AddRef,
+    ClassFactory_Release,
+    ClassFactory_CreateInstance,
+    ClassFactory_LockServer
+};
+
+static struct class_factory create_devenum_cf = { { &ClassFactory_vtbl }, (IUnknown *)&DEVENUM_CreateDevEnum };
+static struct class_factory device_moniker_cf = { { &ClassFactory_vtbl }, (IUnknown *)&DEVENUM_ParseDisplayName };
+
 /***********************************************************************
  *             DllGetClassObject (DEVENUM.@)
  */
-HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
+HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **obj)
 {
-    TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
+    TRACE("(%s, %s, %p)\n", debugstr_guid(clsid), debugstr_guid(iid), obj);
 
-    *ppv = NULL;
+    *obj = NULL;
 
-    /* FIXME: we should really have two class factories.
-     * Oh well - works just fine as it is */
-    if (IsEqualGUID(rclsid, &CLSID_SystemDeviceEnum) ||
-        IsEqualGUID(rclsid, &CLSID_CDeviceMoniker))
-        return IClassFactory_QueryInterface(&DEVENUM_ClassFactory.IClassFactory_iface, iid, ppv);
+    if (IsEqualGUID(clsid, &CLSID_SystemDeviceEnum))
+        return IClassFactory_QueryInterface(&create_devenum_cf.IClassFactory_iface, iid, obj);
+    else if (IsEqualGUID(clsid, &CLSID_CDeviceMoniker))
+        return IClassFactory_QueryInterface(&device_moniker_cf.IClassFactory_iface, iid, obj);
 
-    FIXME("CLSID: %s, IID: %s\n", debugstr_guid(rclsid), debugstr_guid(iid));
+    FIXME("class %s not available\n", debugstr_guid(clsid));
     return CLASS_E_CLASSNOTAVAILABLE;
 }
 
@@ -96,7 +158,9 @@ HRESULT WINAPI DllRegisterServer(void)
 
     TRACE("\n");
 
-    res = __wine_register_resources( DEVENUM_hInstance );
+    res = __wine_register_resources( devenum_instance );
+    if (FAILED(res))
+        return res;
 
 #ifdef __REACTOS__
     /* Quartz is needed for IFilterMapper2 */
@@ -147,7 +211,7 @@ HRESULT WINAPI DllRegisterServer(void)
 HRESULT WINAPI DllUnregisterServer(void)
 {
     FIXME("stub!\n");
-    return __wine_unregister_resources( DEVENUM_hInstance );
+    return __wine_unregister_resources( devenum_instance );
 }
 
 #ifdef __REACTOS__