From ffcf4490be7fbb1e5583173a3c9ac2a074252f2f Mon Sep 17 00:00:00 2001 From: Kamil Hornicek Date: Sun, 8 Feb 2009 14:34:49 +0000 Subject: [PATCH] - sync dinput and dinput8 with wine svn path=/trunk/; revision=39484 --- reactos/dll/directx/dinput/dinput_main.c | 4 +- .../dll/directx/dinput/effect_linuxinput.c | 26 +- .../dll/directx/dinput/joystick_linuxinput.c | 37 ++- reactos/dll/directx/dinput/regsvr.c | 8 +- reactos/dll/directx/dinput8/dinput8.rbuild | 2 + reactos/dll/directx/dinput8/dinput8_main.c | 149 +++++++-- reactos/dll/directx/dinput8/regsvr.c | 294 ++++++++++++++++++ reactos/dll/directx/dinput8/version.rc | 3 +- reactos/media/doc/README.WINE | 2 +- 9 files changed, 469 insertions(+), 56 deletions(-) create mode 100644 reactos/dll/directx/dinput8/regsvr.c diff --git a/reactos/dll/directx/dinput/dinput_main.c b/reactos/dll/directx/dinput/dinput_main.c index 46e4e281e73..bdcf557eca0 100644 --- a/reactos/dll/directx/dinput/dinput_main.c +++ b/reactos/dll/directx/dinput/dinput_main.c @@ -885,6 +885,7 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam ) { IDirectInputImpl *dinput; + int skip = 0; if (code != HC_ACTION) return CallNextHookEx( 0, code, wparam, lparam ); @@ -899,12 +900,13 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam ) { TRACE("calling %p->%p (%lx %lx)\n", dev, dev->event_proc, wparam, lparam); dev->event_proc( (LPDIRECTINPUTDEVICE8A)dev, wparam, lparam ); + skip |= dev->dwCoopLevel & DISCL_EXCLUSIVE; } LeaveCriticalSection( &dinput->crit ); } LeaveCriticalSection( &dinput_hook_crit ); - return CallNextHookEx( 0, code, wparam, lparam ); + return skip ? 1 : CallNextHookEx( 0, code, wparam, lparam ); } static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam ) diff --git a/reactos/dll/directx/dinput/effect_linuxinput.c b/reactos/dll/directx/dinput/effect_linuxinput.c index 155d800d97a..3c86a34489d 100644 --- a/reactos/dll/directx/dinput/effect_linuxinput.c +++ b/reactos/dll/directx/dinput/effect_linuxinput.c @@ -55,6 +55,7 @@ struct LinuxInputEffectImpl struct ff_effect effect; /* Effect data */ int gain; /* Effect gain */ + int first_axis_is_x; int* fd; /* Parent device */ struct list *entry; /* Entry into the parent's list of effects */ }; @@ -512,12 +513,6 @@ static HRESULT WINAPI LinuxInputEffectImpl_Start( } event.type = EV_FF; - - event.code = FF_GAIN; - event.value = This->gain; - if (write(*(This->fd), &event, sizeof(event)) == -1) - FIXME("Failed setting gain. Error: %d \"%s\".\n", errno, strerror(errno)); - event.code = This->effect.id; event.value = dwIterations; if (write(*(This->fd), &event, sizeof(event)) == -1) { @@ -554,6 +549,7 @@ static HRESULT WINAPI LinuxInputEffectImpl_SetParameters( return DIERR_INVALIDPARAM; else if (peff->cAxes < 1) return DIERR_INCOMPLETEEFFECT; + This->first_axis_is_x = peff->rgdwAxes[0] == DIJOFS_X; } /* some of this may look funky, but it's 'cause the linux driver and directx have @@ -578,15 +574,15 @@ static HRESULT WINAPI LinuxInputEffectImpl_SetParameters( } } else { /* two axes */ if (peff->dwFlags & DIEFF_CARTESIAN) { - /* avoid divide-by-zero */ - if (peff->rglDirection[1] == 0) { - if (peff->rglDirection[0] >= 0) - This->effect.direction = 0x4000; - else if (peff->rglDirection[0] < 0) - This->effect.direction = 0xC000; + LONG x, y; + if (This->first_axis_is_x) { + x = peff->rglDirection[0]; + y = peff->rglDirection[1]; } else { - This->effect.direction = (int)(atan(peff->rglDirection[0] / peff->rglDirection[1]) * 0x7FFF / (3 * M_PI)); + x = peff->rglDirection[1]; + y = peff->rglDirection[0]; } + This->effect.direction = (int)((3 * M_PI / 2 - atan2(y, x)) * -0x7FFF / M_PI); } else { /* Polar and spherical are the same for 2 axes */ /* Precision is important here, so we do double math with exact constants */ @@ -627,8 +623,10 @@ static HRESULT WINAPI LinuxInputEffectImpl_SetParameters( /* Gain and Sample Period settings are not supported by the linux * event system */ - if (dwFlags & DIEP_GAIN) + if (dwFlags & DIEP_GAIN) { This->gain = 0xFFFF * peff->dwGain / 10000; + TRACE("Effect gain requested but no effect gain functionality present.\n"); + } if (dwFlags & DIEP_SAMPLEPERIOD) TRACE("Sample period requested but no sample period functionality present.\n"); diff --git a/reactos/dll/directx/dinput/joystick_linuxinput.c b/reactos/dll/directx/dinput/joystick_linuxinput.c index e1b92f7313c..c24ade98ad9 100644 --- a/reactos/dll/directx/dinput/joystick_linuxinput.c +++ b/reactos/dll/directx/dinput/joystick_linuxinput.c @@ -194,6 +194,7 @@ struct JoystickImpl struct list ff_effects; int ff_state; int ff_autocenter; + int ff_gain; }; static void fake_current_js_state(JoystickImpl *ji); @@ -461,6 +462,7 @@ static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputIm Instead, track it with ff_autocenter, and assume it's initialy enabled. */ newDevice->ff_autocenter = 1; + newDevice->ff_gain = 0xFFFF; InitializeCriticalSection(&newDevice->base.crit); newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->base.crit"); @@ -670,12 +672,16 @@ static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface) } else { + struct input_event event; + + event.type = EV_FF; + event.code = FF_GAIN; + event.value = This->ff_gain; + if (write(This->joyfd, &event, sizeof(event)) == -1) + ERR("Failed to set gain (%i): %d %s\n", This->ff_gain, errno, strerror(errno)); if (!This->ff_autocenter) { - struct input_event event; - /* Disable autocenter. */ - event.type = EV_FF; event.code = FF_AUTOCENTER; event.value = 0; if (write(This->joyfd, &event, sizeof(event)) == -1) @@ -974,6 +980,23 @@ static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface, fake_current_js_state(This); break; } + case (DWORD_PTR)DIPROP_FFGAIN: { + LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; + + TRACE("DIPROP_FFGAIN(%d)\n", pd->dwData); + This->ff_gain = MulDiv(pd->dwData, 0xFFFF, 10000); + if (This->base.acquired) { + /* Update immediately. */ + struct input_event event; + + event.type = EV_FF; + event.code = FF_GAIN; + event.value = This->ff_gain; + if (write(This->joyfd, &event, sizeof(event)) == -1) + ERR("Failed to set gain (%i): %d %s\n", This->ff_gain, errno, strerror(errno)); + } + break; + } default: return IDirectInputDevice2AImpl_SetProperty(iface, rguid, ph); } @@ -1085,6 +1108,14 @@ static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, TRACE("autocenter(%d)\n", pd->dwData); break; } + case (DWORD_PTR) DIPROP_FFGAIN: + { + LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph; + + pd->dwData = MulDiv(This->ff_gain, 10000, 0xFFFF); + TRACE("DIPROP_FFGAIN(%d)\n", pd->dwData); + break; + } default: return IDirectInputDevice2AImpl_GetProperty(iface, rguid, pdiph); diff --git a/reactos/dll/directx/dinput/regsvr.c b/reactos/dll/directx/dinput/regsvr.c index 77e2fc7350d..54f5be5b160 100644 --- a/reactos/dll/directx/dinput/regsvr.c +++ b/reactos/dll/directx/dinput/regsvr.c @@ -204,7 +204,7 @@ static HRESULT unregister_interfaces(struct regsvr_interface const *list) WCHAR buf[39]; StringFromGUID2(list->iid, buf, 39); - //res = RegDeleteTreeW(interface_key, buf); + res = RegDeleteTreeW(interface_key, buf); if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; } @@ -312,18 +312,18 @@ static HRESULT unregister_coclasses(struct regsvr_coclass const *list) WCHAR buf[39]; StringFromGUID2(list->clsid, buf, 39); - //res = RegDeleteTreeW(coclass_key, buf); + res = RegDeleteTreeW(coclass_key, buf); if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; if (res != ERROR_SUCCESS) goto error_close_coclass_key; if (list->progid) { - // res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid); + res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid); if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; if (res != ERROR_SUCCESS) goto error_close_coclass_key; } if (list->viprogid) { - //res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid); + res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid); if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; if (res != ERROR_SUCCESS) goto error_close_coclass_key; } diff --git a/reactos/dll/directx/dinput8/dinput8.rbuild b/reactos/dll/directx/dinput8/dinput8.rbuild index 88339de3181..687473cfb79 100644 --- a/reactos/dll/directx/dinput8/dinput8.rbuild +++ b/reactos/dll/directx/dinput8/dinput8.rbuild @@ -3,6 +3,7 @@ + 0x600 . include/reactos/wine wine @@ -17,4 +18,5 @@ dinput version.rc dinput8_main.c + regsvr.c diff --git a/reactos/dll/directx/dinput8/dinput8_main.c b/reactos/dll/directx/dinput8/dinput8_main.c index 432d3f184a2..c855caf62ec 100644 --- a/reactos/dll/directx/dinput8/dinput8_main.c +++ b/reactos/dll/directx/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 @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" @@ -22,6 +23,8 @@ #include #include +#define COBJMACROS + #include "wine/debug.h" #include "windef.h" #include "winbase.h" @@ -29,25 +32,124 @@ #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) { + HRESULT hr; + + TRACE("hInst (%p), dwVersion: %d, riid (%s), punkOuter (%p))\n", hinst, dwVersion, debugstr_guid(riid), punkOuter); + + /* The specified version needs to be dinput8 (0x800) or higher */ + if(dwVersion < 0x800) + return DIERR_OLDDIRECTINPUTVERSION; + + if( !(IsEqualGUID(&IID_IDirectInput8A, riid) || IsEqualGUID(&IID_IDirectInput8W, riid) || IsEqualGUID(&IID_IUnknown, riid)) ) + return DIERR_INVALIDPARAM; + + CoInitialize(NULL); + + hr = CoCreateInstance( &CLSID_DirectInput8, punkOuter, CLSCTX_INPROC_SERVER, riid, ppDI); + if(FAILED(hr)) { + ERR("CoCreateInstance failed with hr = %d; Try running wineprefixcreate to fix it.\n", hr); + return DIERR_INVALIDPARAM; + } + + CoUninitialize(); + + /* When aggregation is used (punkOuter!=NULL) the application needs to manually call Initialize. */ + if(punkOuter == NULL && IsEqualGUID(&IID_IDirectInput8A, riid)) { + LPDIRECTINPUTA DI = *ppDI; + IDirectInput8_Initialize(DI, hinst, dwVersion); + } + + if(punkOuter == NULL && IsEqualGUID(&IID_IDirectInput8W, riid)) { + LPDIRECTINPUTW DI = *ppDI; + IDirectInput8_Initialize(DI, hinst, dwVersion); + } + + return S_OK; } +/******************************************************************************* + * 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 ) || IsEqualGUID( &IID_IUnknown, riid )) { + return DirectInputCreateEx(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,28 +157,13 @@ 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 = &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; } - -/*********************************************************************** - * DllRegisterServer (DINPUT8.@) - */ -HRESULT WINAPI DllRegisterServer(void) -{ - FIXME("(void): stub\n"); - - return S_OK; -} - -/*********************************************************************** - * DllUnregisterServer (DINPUT8.@) - */ -HRESULT WINAPI DllUnregisterServer(void) -{ - FIXME("(void): stub\n"); - - return S_OK; -} diff --git a/reactos/dll/directx/dinput8/regsvr.c b/reactos/dll/directx/dinput8/regsvr.c new file mode 100644 index 00000000000..3d8cdc9458a --- /dev/null +++ b/reactos/dll/directx/dinput8/regsvr.c @@ -0,0 +1,294 @@ +/* + * self-registerable dll functions for dinput8.dll + * + * Copyright (C) 2003 John K. Hohm + * Copyright (C) 2007 Francois Gouget for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "wingdi.h" +#include "winuser.h" +#include "winerror.h" + +#include "dinput.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dinput); + +/* + * Near the bottom of this file are the exported DllRegisterServer and + * DllUnregisterServer, which make all this worthwhile. + */ + +/*********************************************************************** + * interface for self-registering + */ + +struct regsvr_coclass +{ + CLSID const *clsid; /* NULL for end of list */ + LPCSTR name; /* can be NULL to omit */ + LPCSTR ips; /* can be NULL to omit */ + LPCSTR ips32; /* can be NULL to omit */ + LPCSTR ips32_tmodel; /* can be NULL to omit */ + LPCSTR clsid_str; /* can be NULL to omit */ + LPCSTR progid; /* can be NULL to omit */ +}; + +static HRESULT register_coclasses(struct regsvr_coclass const *list); +static HRESULT unregister_coclasses(struct regsvr_coclass const *list); + +/*********************************************************************** + * static string constants + */ +static WCHAR const interface_keyname[10] = { + 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 }; +static WCHAR const base_ifa_keyname[14] = { + 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', + 'e', 0 }; +static WCHAR const num_methods_keyname[11] = { + 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 }; +static WCHAR const ps_clsid_keyname[15] = { + 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', + 'i', 'd', 0 }; +static WCHAR const ps_clsid32_keyname[17] = { + 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', + 'i', 'd', '3', '2', 0 }; +static WCHAR const clsid_keyname[6] = { + 'C', 'L', 'S', 'I', 'D', 0 }; +static WCHAR const ips_keyname[13] = { + 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', + 0 }; +static WCHAR const ips32_keyname[15] = { + 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', + '3', '2', 0 }; +static WCHAR const progid_keyname[7] = { + 'P', 'r', 'o', 'g', 'I', 'D', 0 }; +static char const tmodel_valuename[] = "ThreadingModel"; + +/*********************************************************************** + * static helper functions + */ +static LONG register_key_defvalueW(HKEY base, WCHAR const *name, + WCHAR const *value); +static LONG register_key_defvalueA(HKEY base, WCHAR const *name, + char const *value); + +/*********************************************************************** + * register_coclasses + */ +static HRESULT register_coclasses(struct regsvr_coclass const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + + res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + WCHAR buf[39]; + HKEY clsid_key; + + StringFromGUID2(list->clsid, buf, 39); + res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + if (list->name) { + res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ, + (CONST BYTE*)(list->name), + strlen(list->name) + 1); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->ips) { + res = register_key_defvalueA(clsid_key, ips_keyname, list->ips); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->ips32) { + HKEY ips32_key; + + res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, + &ips32_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ, + (CONST BYTE*)list->ips32, + lstrlenA(list->ips32) + 1); + if (res == ERROR_SUCCESS && list->ips32_tmodel) + res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ, + (CONST BYTE*)list->ips32_tmodel, + strlen(list->ips32_tmodel) + 1); + RegCloseKey(ips32_key); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->clsid_str) { + res = register_key_defvalueA(clsid_key, clsid_keyname, + list->clsid_str); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->progid) { + HKEY progid_key; + + res = register_key_defvalueA(clsid_key, progid_keyname, + list->progid); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = RegCreateKeyExA(HKEY_CLASSES_ROOT, list->progid, 0, + NULL, 0, KEY_READ | KEY_WRITE, NULL, + &progid_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = register_key_defvalueW(progid_key, clsid_keyname, buf); + RegCloseKey(progid_key); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + error_close_clsid_key: + RegCloseKey(clsid_key); + } + +error_close_coclass_key: + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * unregister_coclasses + */ +static HRESULT unregister_coclasses(struct regsvr_coclass const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, + KEY_READ | KEY_WRITE, &coclass_key); + if (res == ERROR_FILE_NOT_FOUND) return S_OK; + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + WCHAR buf[39]; + + StringFromGUID2(list->clsid, buf, 39); + res = RegDeleteTreeW(coclass_key, buf); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + if (list->progid) { + res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + } + } + +error_close_coclass_key: + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * regsvr_key_defvalueW + */ +static LONG register_key_defvalueW( + HKEY base, + WCHAR const *name, + WCHAR const *value) +{ + LONG res; + HKEY key; + + res = RegCreateKeyExW(base, name, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &key, NULL); + if (res != ERROR_SUCCESS) return res; + res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value, + (lstrlenW(value) + 1) * sizeof(WCHAR)); + RegCloseKey(key); + return res; +} + +/*********************************************************************** + * regsvr_key_defvalueA + */ +static LONG register_key_defvalueA( + HKEY base, + WCHAR const *name, + char const *value) +{ + LONG res; + HKEY key; + + res = RegCreateKeyExW(base, name, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &key, NULL); + if (res != ERROR_SUCCESS) return res; + res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value, + lstrlenA(value) + 1); + RegCloseKey(key); + return res; +} + +/*********************************************************************** + * coclass list + */ + +static struct regsvr_coclass const coclass_list[] = { + { &CLSID_DirectInput8, + "DirectInput8 Object", + NULL, + "dinput8.dll", + "Both" + }, + { NULL } /* list terminator */ +}; + +/*********************************************************************** + * DllRegisterServer (DINPUT8.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + HRESULT hr; + + TRACE("\n"); + + hr = register_coclasses(coclass_list); + return hr; +} + +/*********************************************************************** + * DllUnregisterServer (DINPUT8.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + HRESULT hr; + + TRACE("\n"); + + hr = unregister_coclasses(coclass_list); + return hr; +} diff --git a/reactos/dll/directx/dinput8/version.rc b/reactos/dll/directx/dinput8/version.rc index e69fa99701d..ef512965db5 100644 --- a/reactos/dll/directx/dinput8/version.rc +++ b/reactos/dll/directx/dinput8/version.rc @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define WINE_FILEDESCRIPTION_STR "Wine DirectInput 8" @@ -22,6 +22,5 @@ #define WINE_FILEVERSION_STR "5.1.2600.881" #define WINE_PRODUCTVERSION 5,1,2600,881 #define WINE_PRODUCTVERSION_STR "5.1" -#define WINE_PRODUCTNAME_STR "DirectX" #include "wine/wine_common_ver.rc" diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index bf2cb31993e..1dab9338171 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -124,7 +124,7 @@ reactos/dll/win32/wldap32 # Autosync reactos/dll/win32/wmi # Autosync reactos/dll/win32/wtsapi32 # Autosync reactos/dll/directx/dinput # Synced to Wine-1_1_4 -reactos/dll/directx/dinput8 # Synced to Wine-0_9_5 +reactos/dll/directx/dinput8 # Synced to Wine-1_1_4 reactos/dll/directx/dplay # Synced to Wine-0_9_5 reactos/dll/directx/dplayx # Synced to Wine-0_9_5 reactos/dll/directx/dxdiagn # Synced to Wine-0_9_5