Instead of linking with dinput8.dll and creating the class at load time, which causes some native hooks to fail loading.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52222 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winmm/Makefile.in | 2 +- dlls/winmm/joystick.c | 33 +++++++++++++++++++++++++++++---- dlls/winmm/winemm.h | 1 - dlls/winmm/winmm.c | 2 -- 4 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/dlls/winmm/Makefile.in b/dlls/winmm/Makefile.in index 5439ae21678..3036526c14e 100644 --- a/dlls/winmm/Makefile.in +++ b/dlls/winmm/Makefile.in @@ -1,7 +1,7 @@ EXTRADEFS = -D_WINMM_ MODULE = winmm.dll IMPORTLIB = winmm -IMPORTS = uuid user32 advapi32 ole32 msacm32 dinput8 +IMPORTS = uuid user32 advapi32 ole32 msacm32
C_SRCS = \ driver.c \ diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 5f5683e3e35..74bf53eac08 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -152,11 +152,31 @@ static BOOL CALLBACK enum_instances( const DIDEVICEINSTANCEW *instance, void *co return DIENUM_CONTINUE; }
-void joystick_load( HINSTANCE instance ) +static BOOL WINAPI joystick_load( INIT_ONCE *once, void *param, void **context ) { - HRESULT hr = DirectInput8Create( instance, DIRECTINPUT_VERSION, &IID_IDirectInput8W, - (void **)&dinput, NULL ); - if (FAILED(hr)) WARN( "could not create dinput instance, hr %#x\n", hr ); + HRESULT hr; + + CoInitialize( NULL ); + + hr = CoCreateInstance( &CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput8W, + (void **)&dinput ); + if (FAILED(hr)) + { + WARN( "Could not create dinput instance, hr %#x\n", hr ); + CoUninitialize(); + return FALSE; + } + + hr = IDirectInput8_Initialize( dinput, hWinMM32Instance, DIRECTINPUT_VERSION ); + if (FAILED(hr)) + { + WARN( "Could not initialize dinput instance, hr %#x\n", hr ); + IDirectInput8_Release( dinput ); + CoUninitialize(); + return FALSE; + } + + return TRUE; }
void joystick_unload() @@ -173,15 +193,20 @@ void joystick_unload() }
IDirectInput8_Release( dinput ); + CoUninitialize(); }
static void find_joysticks(void) { + static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; + IDirectInputDevice8W *device; HANDLE event; DWORD index; HRESULT hr;
+ InitOnceExecuteOnce( &init_once, joystick_load, NULL, NULL ); + if (!dinput) return;
index = 0; diff --git a/dlls/winmm/winemm.h b/dlls/winmm/winemm.h index 3459c2a85ef..52cab64b1c5 100644 --- a/dlls/winmm/winemm.h +++ b/dlls/winmm/winemm.h @@ -153,7 +153,6 @@ MMRESULT WINMM_CheckCallback(DWORD_PTR dwCallback, DWORD fdwOpen, BOOL mixer) DE
void WINMM_DeleteWaveform(void) DECLSPEC_HIDDEN;
-void joystick_load( HMODULE instance ) DECLSPEC_HIDDEN; void joystick_unload( void ) DECLSPEC_HIDDEN;
/* Global variables */ diff --git a/dlls/winmm/winmm.c b/dlls/winmm/winmm.c index aab8bfb51a9..aa2dd50c4c1 100644 --- a/dlls/winmm/winmm.c +++ b/dlls/winmm/winmm.c @@ -144,8 +144,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
if (!WINMM_CreateIData(hInstDLL)) return FALSE; - - joystick_load( hInstDLL ); break; case DLL_PROCESS_DETACH: if(fImpLoad)
On 12/17/21 17:20, Rémi Bernon wrote:
Instead of linking with dinput8.dll and creating the class at load time, which causes some native hooks to fail loading.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52222 Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/winmm/Makefile.in | 2 +- dlls/winmm/joystick.c | 33 +++++++++++++++++++++++++++++---- dlls/winmm/winemm.h | 1 - dlls/winmm/winmm.c | 2 -- 4 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/dlls/winmm/Makefile.in b/dlls/winmm/Makefile.in index 5439ae21678..3036526c14e 100644 --- a/dlls/winmm/Makefile.in +++ b/dlls/winmm/Makefile.in @@ -1,7 +1,7 @@ EXTRADEFS = -D_WINMM_ MODULE = winmm.dll IMPORTLIB = winmm -IMPORTS = uuid user32 advapi32 ole32 msacm32 dinput8 +IMPORTS = uuid user32 advapi32 ole32 msacm32
C_SRCS = \ driver.c \ diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 5f5683e3e35..74bf53eac08 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -152,11 +152,31 @@ static BOOL CALLBACK enum_instances( const DIDEVICEINSTANCEW *instance, void *co return DIENUM_CONTINUE; }
-void joystick_load( HINSTANCE instance ) +static BOOL WINAPI joystick_load( INIT_ONCE *once, void *param, void **context ) {
- HRESULT hr = DirectInput8Create( instance, DIRECTINPUT_VERSION, &IID_IDirectInput8W,
(void **)&dinput, NULL );
- if (FAILED(hr)) WARN( "could not create dinput instance, hr %#x\n", hr );
- HRESULT hr;
- CoInitialize( NULL );
- hr = CoCreateInstance( &CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput8W,
(void **)&dinput );
- if (FAILED(hr))
- {
WARN( "Could not create dinput instance, hr %#x\n", hr );
CoUninitialize();
return FALSE;
- }
- hr = IDirectInput8_Initialize( dinput, hWinMM32Instance, DIRECTINPUT_VERSION );
- if (FAILED(hr))
- {
WARN( "Could not initialize dinput instance, hr %#x\n", hr );
IDirectInput8_Release( dinput );
CoUninitialize();
return FALSE;
- }
- return TRUE; }
This is probably not in a winmm own created thread, right? In that case CoInitialize will fail if COM is already initialized as MT apartment. Which is probably not an issue by itself, but then CoUnitialize() may leave app's thread with uninit the app's thread initialization, so CoInitialize() return status should be considered. And propaply CoUninitialize() is missing on success return?
Apart from that, is there any reason not to just LoadLibrary()/ GetProcAddress("DirectInput8Create")?
On 12/17/21 15:43, Paul Gofman wrote:
On 12/17/21 17:20, Rémi Bernon wrote:
Instead of linking with dinput8.dll and creating the class at load time, which causes some native hooks to fail loading.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52222 Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/winmm/Makefile.in | 2 +- dlls/winmm/joystick.c | 33 +++++++++++++++++++++++++++++---- dlls/winmm/winemm.h | 1 - dlls/winmm/winmm.c | 2 -- 4 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/dlls/winmm/Makefile.in b/dlls/winmm/Makefile.in index 5439ae21678..3036526c14e 100644 --- a/dlls/winmm/Makefile.in +++ b/dlls/winmm/Makefile.in @@ -1,7 +1,7 @@ EXTRADEFS = -D_WINMM_ MODULE = winmm.dll IMPORTLIB = winmm -IMPORTS = uuid user32 advapi32 ole32 msacm32 dinput8 +IMPORTS = uuid user32 advapi32 ole32 msacm32 C_SRCS = \ driver.c \ diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 5f5683e3e35..74bf53eac08 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -152,11 +152,31 @@ static BOOL CALLBACK enum_instances( const DIDEVICEINSTANCEW *instance, void *co return DIENUM_CONTINUE; } -void joystick_load( HINSTANCE instance ) +static BOOL WINAPI joystick_load( INIT_ONCE *once, void *param, void **context ) { - HRESULT hr = DirectInput8Create( instance, DIRECTINPUT_VERSION, &IID_IDirectInput8W, - (void **)&dinput, NULL ); - if (FAILED(hr)) WARN( "could not create dinput instance, hr %#x\n", hr ); + HRESULT hr;
+ CoInitialize( NULL );
+ hr = CoCreateInstance( &CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput8W, + (void **)&dinput ); + if (FAILED(hr)) + { + WARN( "Could not create dinput instance, hr %#x\n", hr ); + CoUninitialize(); + return FALSE; + }
+ hr = IDirectInput8_Initialize( dinput, hWinMM32Instance, DIRECTINPUT_VERSION ); + if (FAILED(hr)) + { + WARN( "Could not initialize dinput instance, hr %#x\n", hr ); + IDirectInput8_Release( dinput ); + CoUninitialize(); + return FALSE; + }
+ return TRUE; }
This is probably not in a winmm own created thread, right? In that case CoInitialize will fail if COM is already initialized as MT apartment. Which is probably not an issue by itself, but then CoUnitialize() may leave app's thread with uninit the app's thread initialization, so CoInitialize() return status should be considered. And propaply CoUninitialize() is missing on success return?
Right, thanks.
Apart from that, is there any reason not to just LoadLibrary()/ GetProcAddress("DirectInput8Create")?
No specific reason except that CoCreateInstance seems to be somewhat a canonical way to create DInput class instances.
On 12/17/21 17:50, Rémi Bernon wrote:
On 12/17/21 15:43, Paul Gofman wrote:
On 12/17/21 17:20, Rémi Bernon wrote:
Instead of linking with dinput8.dll and creating the class at load time, which causes some native hooks to fail loading.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52222 Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/winmm/Makefile.in | 2 +- dlls/winmm/joystick.c | 33 +++++++++++++++++++++++++++++---- dlls/winmm/winemm.h | 1 - dlls/winmm/winmm.c | 2 -- 4 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/dlls/winmm/Makefile.in b/dlls/winmm/Makefile.in index 5439ae21678..3036526c14e 100644 --- a/dlls/winmm/Makefile.in +++ b/dlls/winmm/Makefile.in @@ -1,7 +1,7 @@ EXTRADEFS = -D_WINMM_ MODULE = winmm.dll IMPORTLIB = winmm -IMPORTS = uuid user32 advapi32 ole32 msacm32 dinput8 +IMPORTS = uuid user32 advapi32 ole32 msacm32 C_SRCS = \ driver.c \ diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 5f5683e3e35..74bf53eac08 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -152,11 +152,31 @@ static BOOL CALLBACK enum_instances( const DIDEVICEINSTANCEW *instance, void *co return DIENUM_CONTINUE; } -void joystick_load( HINSTANCE instance ) +static BOOL WINAPI joystick_load( INIT_ONCE *once, void *param, void **context ) { - HRESULT hr = DirectInput8Create( instance, DIRECTINPUT_VERSION, &IID_IDirectInput8W, - (void **)&dinput, NULL ); - if (FAILED(hr)) WARN( "could not create dinput instance, hr %#x\n", hr ); + HRESULT hr;
+ CoInitialize( NULL );
+ hr = CoCreateInstance( &CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput8W, + (void **)&dinput ); + if (FAILED(hr)) + { + WARN( "Could not create dinput instance, hr %#x\n", hr ); + CoUninitialize(); + return FALSE; + }
+ hr = IDirectInput8_Initialize( dinput, hWinMM32Instance, DIRECTINPUT_VERSION ); + if (FAILED(hr)) + { + WARN( "Could not initialize dinput instance, hr %#x\n", hr ); + IDirectInput8_Release( dinput ); + CoUninitialize(); + return FALSE; + }
+ return TRUE; }
No specific reason except that CoCreateInstance seems to be somewhat a canonical way to create DInput class instances.
But don't you get a chance of getting marshalled interface in theory if COM object and thread apartment models do not match? Maybe not in practice with dinput8 but isn't just using DirectInput8Create() simpler (no COM involved) and is also a valid way?