dinput: Extract the DirectInput instance creation and initialization in DirectInputCreateEx to separate functions.
This commit is contained in:
parent
e5f73425dd
commit
c126b21a34
|
@ -115,14 +115,42 @@ static BOOL check_hook_thread(void);
|
|||
static CRITICAL_SECTION dinput_hook_crit;
|
||||
static struct list direct_input_list = LIST_INIT( direct_input_list );
|
||||
|
||||
static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwVersion);
|
||||
static void uninitialize_directinput_instance(IDirectInputImpl *This);
|
||||
|
||||
static HRESULT create_directinput_instance(REFIID riid, LPVOID *ppDI, IDirectInputImpl **out)
|
||||
{
|
||||
IDirectInputImpl *This = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectInputImpl) );
|
||||
HRESULT hr;
|
||||
|
||||
if (!This)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->IDirectInput7A_iface.lpVtbl = &ddi7avt;
|
||||
This->IDirectInput7W_iface.lpVtbl = &ddi7wvt;
|
||||
This->IDirectInput8A_iface.lpVtbl = &ddi8avt;
|
||||
This->IDirectInput8W_iface.lpVtbl = &ddi8wvt;
|
||||
|
||||
hr = IDirectInput_QueryInterface( &This->IDirectInput7A_iface, riid, ppDI );
|
||||
if (FAILED(hr))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, This );
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (out) *out = This;
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DirectInputCreateEx (DINPUT.@)
|
||||
*/
|
||||
HRESULT WINAPI DirectInputCreateEx(
|
||||
HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI,
|
||||
LPUNKNOWN punkOuter)
|
||||
LPUNKNOWN punkOuter)
|
||||
{
|
||||
IDirectInputImpl* This;
|
||||
IDirectInputImpl *This;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%04x,%s,%p,%p)\n", hinst, dwVersion, debugstr_guid(riid), ppDI, punkOuter);
|
||||
|
||||
|
@ -136,37 +164,21 @@ HRESULT WINAPI DirectInputCreateEx(
|
|||
IsEqualGUID( &IID_IDirectInput8A, riid ) ||
|
||||
IsEqualGUID( &IID_IDirectInput8W, riid ))
|
||||
{
|
||||
if (!(This = HeapAlloc( GetProcessHeap(), 0, sizeof(IDirectInputImpl) )))
|
||||
return DIERR_OUTOFMEMORY;
|
||||
hr = create_directinput_instance(riid, ppDI, &This);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
return DIERR_OLDDIRECTINPUTVERSION;
|
||||
|
||||
This->IDirectInput7A_iface.lpVtbl = &ddi7avt;
|
||||
This->IDirectInput7W_iface.lpVtbl = &ddi7wvt;
|
||||
This->IDirectInput8A_iface.lpVtbl = &ddi8avt;
|
||||
This->IDirectInput8W_iface.lpVtbl = &ddi8wvt;
|
||||
This->ref = 0;
|
||||
This->dwVersion = dwVersion;
|
||||
This->evsequence = 1;
|
||||
|
||||
InitializeCriticalSection(&This->crit);
|
||||
This->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectInputImpl*->crit");
|
||||
|
||||
list_init( &This->devices_list );
|
||||
|
||||
/* Add self to the list of the IDirectInputs */
|
||||
EnterCriticalSection( &dinput_hook_crit );
|
||||
list_add_head( &direct_input_list, &This->entry );
|
||||
LeaveCriticalSection( &dinput_hook_crit );
|
||||
|
||||
if (!check_hook_thread())
|
||||
hr = IDirectInput_Initialize( &This->IDirectInput7A_iface, hinst, dwVersion );
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IUnknown_Release( &This->IDirectInput7A_iface );
|
||||
return DIERR_GENERIC;
|
||||
IDirectInput_Release( &This->IDirectInput7A_iface );
|
||||
*ppDI = NULL;
|
||||
return hr;
|
||||
}
|
||||
|
||||
IDirectInput_QueryInterface( &This->IDirectInput7A_iface, riid, ppDI );
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
|
@ -328,6 +340,9 @@ static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
|
|||
if (!lpCallback)
|
||||
return DIERR_INVALIDPARAM;
|
||||
|
||||
if (!This->initialized)
|
||||
return DIERR_NOTINITIALIZED;
|
||||
|
||||
for (i = 0; i < NB_DINPUT_DEVICES; i++) {
|
||||
if (!dinput_devices[i]->enum_deviceA) continue;
|
||||
for (j = 0, r = -1; r != 0; j++) {
|
||||
|
@ -362,6 +377,9 @@ static HRESULT WINAPI IDirectInputWImpl_EnumDevices(
|
|||
if (!lpCallback)
|
||||
return DIERR_INVALIDPARAM;
|
||||
|
||||
if (!This->initialized)
|
||||
return DIERR_NOTINITIALIZED;
|
||||
|
||||
for (i = 0; i < NB_DINPUT_DEVICES; i++) {
|
||||
if (!dinput_devices[i]->enum_deviceW) continue;
|
||||
for (j = 0, r = -1; r != 0; j++) {
|
||||
|
@ -399,20 +417,13 @@ static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUT7A iface)
|
|||
|
||||
TRACE( "(%p) releasing from %d\n", This, ref + 1 );
|
||||
|
||||
if (ref) return ref;
|
||||
if (ref == 0)
|
||||
{
|
||||
uninitialize_directinput_instance( This );
|
||||
HeapFree( GetProcessHeap(), 0, This );
|
||||
}
|
||||
|
||||
/* Remove self from the list of the IDirectInputs */
|
||||
EnterCriticalSection( &dinput_hook_crit );
|
||||
list_remove( &This->entry );
|
||||
LeaveCriticalSection( &dinput_hook_crit );
|
||||
|
||||
check_hook_thread();
|
||||
|
||||
This->crit.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection( &This->crit );
|
||||
HeapFree( GetProcessHeap(), 0, This );
|
||||
|
||||
return 0;
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirectInputWImpl_Release(LPDIRECTINPUT7W iface)
|
||||
|
@ -478,6 +489,53 @@ static HRESULT WINAPI IDirectInputWImpl_QueryInterface(LPDIRECTINPUT7W iface, RE
|
|||
return IDirectInputAImpl_QueryInterface( &This->IDirectInput7A_iface, riid, ppobj );
|
||||
}
|
||||
|
||||
static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwVersion)
|
||||
{
|
||||
if (!This->initialized)
|
||||
{
|
||||
This->dwVersion = dwVersion;
|
||||
This->evsequence = 1;
|
||||
|
||||
InitializeCriticalSection( &This->crit );
|
||||
This->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectInputImpl*->crit");
|
||||
|
||||
list_init( &This->devices_list );
|
||||
|
||||
/* Add self to the list of the IDirectInputs */
|
||||
EnterCriticalSection( &dinput_hook_crit );
|
||||
list_add_head( &direct_input_list, &This->entry );
|
||||
LeaveCriticalSection( &dinput_hook_crit );
|
||||
|
||||
This->initialized = TRUE;
|
||||
|
||||
if (!check_hook_thread())
|
||||
{
|
||||
uninitialize_directinput_instance( This );
|
||||
return DIERR_GENERIC;
|
||||
}
|
||||
}
|
||||
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
static void uninitialize_directinput_instance(IDirectInputImpl *This)
|
||||
{
|
||||
if (This->initialized)
|
||||
{
|
||||
/* Remove self from the list of the IDirectInputs */
|
||||
EnterCriticalSection( &dinput_hook_crit );
|
||||
list_remove( &This->entry );
|
||||
LeaveCriticalSection( &dinput_hook_crit );
|
||||
|
||||
check_hook_thread();
|
||||
|
||||
This->crit.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection( &This->crit );
|
||||
|
||||
This->initialized = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
enum directinput_versions
|
||||
{
|
||||
DIRECTINPUT_VERSION_300 = 0x0300,
|
||||
|
@ -491,6 +549,8 @@ enum directinput_versions
|
|||
|
||||
static HRESULT WINAPI IDirectInputAImpl_Initialize(LPDIRECTINPUT7A iface, HINSTANCE hinst, DWORD version)
|
||||
{
|
||||
IDirectInputImpl *This = impl_from_IDirectInput7A( iface );
|
||||
|
||||
TRACE("(%p)->(%p, 0x%04x)\n", iface, hinst, version);
|
||||
|
||||
if (!hinst)
|
||||
|
@ -506,7 +566,7 @@ static HRESULT WINAPI IDirectInputAImpl_Initialize(LPDIRECTINPUT7A iface, HINSTA
|
|||
version != DIRECTINPUT_VERSION_700 && version != DIRECTINPUT_VERSION)
|
||||
return DIERR_BETADIRECTINPUTVERSION;
|
||||
|
||||
return DI_OK;
|
||||
return initialize_directinput_instance(This, version);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirectInputWImpl_Initialize(LPDIRECTINPUT7W iface, HINSTANCE hinst, DWORD x)
|
||||
|
@ -523,6 +583,9 @@ static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUT7A iface, R
|
|||
|
||||
TRACE( "(%p)->(%s)\n", This, debugstr_guid(rguid) );
|
||||
|
||||
if (!This->initialized)
|
||||
return DIERR_NOTINITIALIZED;
|
||||
|
||||
hr = IDirectInput_CreateDevice( iface, rguid, &device, NULL );
|
||||
if (hr != DI_OK) return DI_NOTATTACHED;
|
||||
|
||||
|
@ -555,6 +618,9 @@ static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUT7A iface,
|
|||
if (dwFlags)
|
||||
return DIERR_INVALIDPARAM;
|
||||
|
||||
if (!This->initialized)
|
||||
return DIERR_NOTINITIALIZED;
|
||||
|
||||
if (!CreateProcessW(NULL, control_exeW, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
|
@ -597,6 +663,9 @@ static HRESULT create_device(IDirectInputImpl *This, REFGUID rguid, REFIID riid,
|
|||
if (!rguid || !pvOut)
|
||||
return E_POINTER;
|
||||
|
||||
if (!This->initialized)
|
||||
return DIERR_NOTINITIALIZED;
|
||||
|
||||
/* Loop on all the devices to see if anyone matches the given GUID */
|
||||
for (i = 0; i < NB_DINPUT_DEVICES; i++)
|
||||
{
|
||||
|
@ -985,8 +1054,7 @@ static HRESULT WINAPI DICF_CreateInstance(
|
|||
IsEqualGUID( &IID_IDirectInput7W, riid ) ||
|
||||
IsEqualGUID( &IID_IDirectInput8A, riid ) ||
|
||||
IsEqualGUID( &IID_IDirectInput8W, riid ) ) {
|
||||
/* FIXME: reuse already created dinput if present? */
|
||||
return DirectInputCreateEx(0,0,riid,ppobj,pOuter);
|
||||
return create_directinput_instance(riid, ppobj, NULL);
|
||||
}
|
||||
|
||||
FIXME("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);
|
||||
|
|
|
@ -37,6 +37,7 @@ struct IDirectInputImpl
|
|||
|
||||
LONG ref;
|
||||
|
||||
BOOL initialized;
|
||||
CRITICAL_SECTION crit;
|
||||
struct list entry; /* entry into list of all IDirectInputs */
|
||||
|
||||
|
|
|
@ -49,6 +49,111 @@ static const DWORD directinput_version_list[] =
|
|||
DIRECTINPUT_VERSION_700,
|
||||
};
|
||||
|
||||
static BOOL CALLBACK dummy_callback(const DIDEVICEINSTANCEA *instance, void *context)
|
||||
{
|
||||
ok(0, "Callback was invoked with parameters (%p, %p)\n", instance, context);
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
|
||||
static void test_preinitialization(void)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
REFGUID rguid;
|
||||
BOOL pdev;
|
||||
HRESULT expected_hr;
|
||||
} create_device_tests[] =
|
||||
{
|
||||
{NULL, FALSE, E_POINTER},
|
||||
{NULL, TRUE, E_POINTER},
|
||||
{&GUID_Unknown, FALSE, E_POINTER},
|
||||
{&GUID_Unknown, TRUE, DIERR_NOTINITIALIZED},
|
||||
{&GUID_SysMouse, FALSE, E_POINTER},
|
||||
{&GUID_SysMouse, TRUE, DIERR_NOTINITIALIZED},
|
||||
};
|
||||
|
||||
static const struct
|
||||
{
|
||||
DWORD dwDevType;
|
||||
LPDIENUMDEVICESCALLBACKA lpCallback;
|
||||
DWORD dwFlags;
|
||||
HRESULT expected_hr;
|
||||
int todo;
|
||||
} enum_devices_tests[] =
|
||||
{
|
||||
{0, NULL, 0, DIERR_INVALIDPARAM},
|
||||
{0, NULL, ~0u, DIERR_INVALIDPARAM},
|
||||
{0, dummy_callback, 0, DIERR_NOTINITIALIZED},
|
||||
{0, dummy_callback, ~0u, DIERR_INVALIDPARAM, 1},
|
||||
{0xdeadbeef, NULL, 0, DIERR_INVALIDPARAM},
|
||||
{0xdeadbeef, NULL, ~0u, DIERR_INVALIDPARAM},
|
||||
{0xdeadbeef, dummy_callback, 0, DIERR_INVALIDPARAM, 1},
|
||||
{0xdeadbeef, dummy_callback, ~0u, DIERR_INVALIDPARAM, 1},
|
||||
};
|
||||
|
||||
IDirectInputA *pDI;
|
||||
HRESULT hr;
|
||||
int i;
|
||||
IDirectInputDeviceA *pDID;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInputA, (void **)&pDI);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(create_device_tests)/sizeof(create_device_tests[0]); i++)
|
||||
{
|
||||
if (create_device_tests[i].pdev) pDID = (void *)0xdeadbeef;
|
||||
hr = IDirectInput_CreateDevice(pDI, create_device_tests[i].rguid,
|
||||
create_device_tests[i].pdev ? &pDID : NULL,
|
||||
NULL);
|
||||
ok(hr == create_device_tests[i].expected_hr, "[%d] IDirectInput_CreateDevice returned 0x%08x\n", i, hr);
|
||||
if (create_device_tests[i].pdev)
|
||||
ok(pDID == NULL, "[%d] Output interface pointer is %p\n", i, pDID);
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(enum_devices_tests)/sizeof(enum_devices_tests[0]); i++)
|
||||
{
|
||||
hr = IDirectInput_EnumDevices(pDI, enum_devices_tests[i].dwDevType,
|
||||
enum_devices_tests[i].lpCallback,
|
||||
NULL,
|
||||
enum_devices_tests[i].dwFlags);
|
||||
if (enum_devices_tests[i].todo)
|
||||
{
|
||||
todo_wine
|
||||
ok(hr == enum_devices_tests[i].expected_hr, "[%d] IDirectInput_EnumDevice returned 0x%08x\n", i, hr);
|
||||
}
|
||||
else
|
||||
ok(hr == enum_devices_tests[i].expected_hr, "[%d] IDirectInput_EnumDevice returned 0x%08x\n", i, hr);
|
||||
}
|
||||
|
||||
hr = IDirectInput_GetDeviceStatus(pDI, NULL);
|
||||
todo_wine
|
||||
ok(hr == E_POINTER, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr);
|
||||
|
||||
hr = IDirectInput_GetDeviceStatus(pDI, &GUID_Unknown);
|
||||
ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr);
|
||||
|
||||
hr = IDirectInput_GetDeviceStatus(pDI, &GUID_SysMouse);
|
||||
ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr);
|
||||
|
||||
hr = IDirectInput_RunControlPanel(pDI, NULL, 0);
|
||||
ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
|
||||
|
||||
hr = IDirectInput_RunControlPanel(pDI, NULL, ~0u);
|
||||
ok(hr == DIERR_INVALIDPARAM, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
|
||||
|
||||
hr = IDirectInput_RunControlPanel(pDI, (HWND)0xdeadbeef, 0);
|
||||
ok(hr == E_HANDLE, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
|
||||
|
||||
hr = IDirectInput_RunControlPanel(pDI, (HWND)0xdeadbeef, ~0u);
|
||||
ok(hr == E_HANDLE, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
|
||||
|
||||
IDirectInput_Release(pDI);
|
||||
}
|
||||
|
||||
static void test_QueryInterface(void)
|
||||
{
|
||||
static const REFIID iid_list[] = {&IID_IUnknown, &IID_IDirectInputA, &IID_IDirectInputW,
|
||||
|
@ -352,6 +457,7 @@ START_TEST(dinput)
|
|||
hInstance = GetModuleHandleA(NULL);
|
||||
|
||||
CoInitialize(NULL);
|
||||
test_preinitialization();
|
||||
test_QueryInterface();
|
||||
test_CreateDevice();
|
||||
test_EnumDevices();
|
||||
|
|
|
@ -127,7 +127,17 @@ static HRESULT WINAPI DI8CF_CreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter
|
|||
|
||||
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);
|
||||
IDirectInputA *ppDI;
|
||||
HRESULT hr;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInputA, (void **)&ppDI);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
hr = IDirectInput_QueryInterface(ppDI, riid, ppobj);
|
||||
IDirectInput_Release(ppDI);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
ERR("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);
|
||||
|
|
Loading…
Reference in New Issue