From 969ae13ebb2c177508b2c052c3f352c73ec5b3c6 Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander Date: Sat, 6 May 2006 20:45:11 +0200 Subject: [PATCH] dinput8: DllGetClassObject support. --- dlls/dinput8/Makefile.in | 2 +- dlls/dinput8/dinput8_main.c | 96 +++++++++++++++++++++++++++++++++---- 2 files changed, 87 insertions(+), 11 deletions(-) diff --git a/dlls/dinput8/Makefile.in b/dlls/dinput8/Makefile.in index cd23d04a04b..34135c124bb 100644 --- a/dlls/dinput8/Makefile.in +++ b/dlls/dinput8/Makefile.in @@ -5,7 +5,7 @@ VPATH = @srcdir@ MODULE = dinput8.dll IMPORTLIB = libdinput8.$(IMPLIBEXT) IMPORTS = dinput kernel32 -EXTRALIBS = -luuid +EXTRALIBS = -luuid -ldxguid C_SRCS = \ dinput8_main.c diff --git a/dlls/dinput8/dinput8_main.c b/dlls/dinput8/dinput8_main.c index 432d3f184a2..ad9b2ebac17 100644 --- a/dlls/dinput8/dinput8_main.c +++ b/dlls/dinput8/dinput8_main.c @@ -1,6 +1,7 @@ /* DirectInput 8 * * Copyright 2002 TransGaming Technologies Inc. + * Copyright 2006 Roderick Colenbrander * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,6 +23,8 @@ #include #include +#define COBJMACROS + #include "wine/debug.h" #include "windef.h" #include "winbase.h" @@ -29,25 +32,93 @@ #include "dinput.h" WINE_DEFAULT_DEBUG_CHANNEL(dinput); +static LONG dll_count; + +/* + * Dll lifetime tracking declaration + */ +static void LockModule(void) +{ + InterlockedIncrement(&dll_count); +} + +static void UnlockModule(void) +{ + InterlockedDecrement(&dll_count); +} /****************************************************************************** * DirectInput8Create (DINPUT8.@) */ -HRESULT WINAPI DirectInput8Create( - HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI, - LPUNKNOWN punkOuter -) { - return DirectInputCreateEx(hinst, dwVersion, riid, ppDI, punkOuter); +HRESULT WINAPI DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI, LPUNKNOWN punkOuter) { + /* TODO: Create the interface using CoCreateInstance as that's what windows does too and check if the version number >= 0x800 */ + return DirectInputCreateEx(hinst, dwVersion, riid, ppDI, punkOuter); } +/******************************************************************************* + * DirectInput8 ClassFactory + */ +typedef struct +{ + /* IUnknown fields */ + const IClassFactoryVtbl *lpVtbl; +} IClassFactoryImpl; + +static HRESULT WINAPI DI8CF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj); + return E_NOINTERFACE; +} + +static ULONG WINAPI DI8CF_AddRef(LPCLASSFACTORY iface) { + LockModule(); + return 2; +} + +static ULONG WINAPI DI8CF_Release(LPCLASSFACTORY iface) { + UnlockModule(); + return 1; +} + +static HRESULT WINAPI DI8CF_CreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj) { + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + + TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); + if( IsEqualGUID( &IID_IDirectInput8A, riid ) || IsEqualGUID( &IID_IDirectInput8W, riid ) ) { + return DirectInput8Create(0, DIRECTINPUT_VERSION, riid, ppobj, pOuter); + } + + ERR("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj); + return E_NOINTERFACE; +} + +static HRESULT WINAPI DI8CF_LockServer(LPCLASSFACTORY iface,BOOL dolock) { + TRACE("(%p)->(%d)\n", iface, dolock); + + if(dolock) + LockModule(); + else + UnlockModule(); + + return S_OK; +} + +static const IClassFactoryVtbl DI8CF_Vtbl = { + DI8CF_QueryInterface, + DI8CF_AddRef, + DI8CF_Release, + DI8CF_CreateInstance, + DI8CF_LockServer +}; +static IClassFactoryImpl DINPUT8_CF = { &DI8CF_Vtbl }; + + /*********************************************************************** * DllCanUnloadNow (DINPUT8.@) */ HRESULT WINAPI DllCanUnloadNow(void) { - FIXME("(void): stub\n"); - - return S_FALSE; + return dll_count == 0 ? S_OK : S_FALSE; } /*********************************************************************** @@ -55,9 +126,14 @@ HRESULT WINAPI DllCanUnloadNow(void) */ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { - FIXME("(%p, %p, %p): stub\n", debugstr_guid(rclsid), - debugstr_guid(riid), ppv); + TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); + if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) { + *ppv = (LPVOID)&DINPUT8_CF; + IClassFactory_AddRef((IClassFactory*)*ppv); + return S_OK; + } + FIXME("(%s,%s,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); return CLASS_E_CLASSNOTAVAILABLE; }