diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index cdaa76cd504..2b2c4646e31 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1186,6 +1186,24 @@ HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects( IDirectInputDevice8W *iface return DI_OK; } +static HRESULT enum_object_filter_init( IDirectInputDeviceImpl *impl, DIPROPHEADER *filter ) +{ + DIDATAFORMAT *format = impl->data_format.wine_df; + int i, *offsets = impl->data_format.offsets; + + if (filter->dwHow > DIPH_BYUSAGE) return DIERR_INVALIDPARAM; + if (filter->dwHow == DIPH_BYUSAGE && !(impl->instance.dwDevType & DIDEVTYPE_HID)) return DIERR_UNSUPPORTED; + if (filter->dwHow != DIPH_BYOFFSET) return DI_OK; + + if (!offsets) return DIERR_NOTFOUND; + + for (i = 0; i < format->dwNumObjs; ++i) if (offsets[i] == filter->dwObj) break; + if (i == format->dwNumObjs) return DIERR_NOTFOUND; + + filter->dwObj = format->rgodf[i].dwOfs; + return DI_OK; +} + static BOOL CALLBACK find_object( const DIDEVICEOBJECTINSTANCEW *instance, void *context ) { *(DIDEVICEOBJECTINSTANCEW *)context = *instance; @@ -1198,6 +1216,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty( IDirectInputDevice8W *iface IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface ); DWORD object_mask = DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV; DIDEVICEOBJECTINSTANCEW instance; + DIPROPHEADER filter; HRESULT hr; TRACE( "iface %p, guid %s, header %p\n", iface, debugstr_guid( guid ), header ); @@ -1206,6 +1225,9 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty( IDirectInputDevice8W *iface if (header->dwHeaderSize != sizeof(DIPROPHEADER)) return DIERR_INVALIDPARAM; if (!IS_DIPROP( guid )) return DI_OK; + filter = *header; + if (FAILED(hr = enum_object_filter_init( impl, &filter ))) return hr; + switch (LOWORD( guid )) { case (DWORD_PTR)DIPROP_PRODUCTNAME: @@ -1228,7 +1250,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty( IDirectInputDevice8W *iface case (DWORD_PTR)DIPROP_RANGE: if (header->dwSize != sizeof(DIPROPRANGE)) return DIERR_INVALIDPARAM; if (header->dwHow == DIPH_DEVICE) return DIERR_UNSUPPORTED; - hr = impl->vtbl->enum_objects( iface, header, object_mask, find_object, &instance ); + hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance ); if (FAILED(hr)) return hr; if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND; if (!(instance.dwType & DIDFT_AXIS)) return DIERR_UNSUPPORTED; @@ -1239,7 +1261,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty( IDirectInputDevice8W *iface case (DWORD_PTR)DIPROP_GRANULARITY: if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; if (header->dwHow == DIPH_DEVICE) return DIERR_UNSUPPORTED; - hr = impl->vtbl->enum_objects( iface, header, object_mask, find_object, &instance ); + hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance ); if (FAILED(hr)) return hr; if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND; if (!(instance.dwType & DIDFT_AXIS)) return DIERR_UNSUPPORTED; @@ -1247,7 +1269,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty( IDirectInputDevice8W *iface case (DWORD_PTR)DIPROP_KEYNAME: if (header->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM; - hr = impl->vtbl->enum_objects( iface, header, object_mask, find_object, &instance ); + hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance ); if (FAILED(hr)) return hr; if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND; if (!(instance.dwType & DIDFT_BUTTON)) return DIERR_UNSUPPORTED; @@ -1317,6 +1339,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty( IDirectInputDevice8W *iface { struct set_object_property_params params = {.iface = iface, .header = header, .property = LOWORD( guid )}; IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface ); + DIPROPHEADER filter; HRESULT hr; TRACE( "iface %p, guid %s, header %p\n", iface, debugstr_guid( guid ), header ); @@ -1325,6 +1348,9 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty( IDirectInputDevice8W *iface if (header->dwHeaderSize != sizeof(DIPROPHEADER)) return DIERR_INVALIDPARAM; if (!IS_DIPROP( guid )) return DI_OK; + filter = *header; + if (FAILED(hr = enum_object_filter_init( impl, &filter ))) return hr; + switch (LOWORD( guid )) { case (DWORD_PTR)DIPROP_RANGE: @@ -1332,7 +1358,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty( IDirectInputDevice8W *iface const DIPROPRANGE *value = (const DIPROPRANGE *)header; if (header->dwSize != sizeof(DIPROPRANGE)) return DIERR_INVALIDPARAM; if (value->lMin > value->lMax) return DIERR_INVALIDPARAM; - hr = impl->vtbl->enum_objects( iface, header, DIDFT_AXIS, set_object_property, ¶ms ); + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, set_object_property, ¶ms ); if (FAILED(hr)) return hr; return DI_OK; } @@ -1342,7 +1368,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty( IDirectInputDevice8W *iface const DIPROPDWORD *value = (const DIPROPDWORD *)header; if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; if (value->dwData > 10000) return DIERR_INVALIDPARAM; - hr = impl->vtbl->enum_objects( iface, header, DIDFT_AXIS, set_object_property, ¶ms ); + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, set_object_property, ¶ms ); if (FAILED(hr)) return hr; return DI_OK; } @@ -1473,7 +1499,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo( IDirectInputDevice8W *ifa DWORD obj, DWORD how ) { IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface ); - const DIPROPHEADER filter = + DIPROPHEADER filter = { .dwSize = sizeof(filter), .dwHeaderSize = sizeof(filter), @@ -1488,6 +1514,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo( IDirectInputDevice8W *ifa if (instance->dwSize != sizeof(DIDEVICEOBJECTINSTANCE_DX3W) && instance->dwSize != sizeof(DIDEVICEOBJECTINSTANCEW)) return DIERR_INVALIDPARAM; if (how == DIPH_DEVICE) return DIERR_INVALIDPARAM; + if (FAILED(hr = enum_object_filter_init( impl, &filter ))) return hr; hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_ALL, get_object_info, instance ); if (FAILED(hr)) return hr; diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 24d00bf2c11..5718f02bf47 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -392,28 +392,16 @@ static void set_axis_type( DIDEVICEOBJECTINSTANCEW *instance, BOOL *seen, DWORD seen[i] = TRUE; } -static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header, DWORD flags, +static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *filter, DWORD flags, enum_object_callback callback, void *data ) { - DWORD collection = 0, object = 0, axis = 0, button = 0, pov = 0, value_ofs = 0, button_ofs = 0, i, j; + DWORD collection = 0, object = 0, axis = 0, button = 0, pov = 0, value_ofs = 0, button_ofs = 0, j; struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)impl->preparsed; DIDEVICEOBJECTINSTANCEW instance = {.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW)}; struct hid_value_caps *caps, *caps_end, *nary, *nary_end, *effect_caps; - DIDATAFORMAT *format = impl->base.data_format.wine_df; - int *offsets = impl->base.data_format.offsets; struct hid_collection_node *node, *node_end; - DIPROPHEADER filter = *header; BOOL ret, seen_axis[6] = {0}; - if (filter.dwHow == DIPH_BYOFFSET) - { - if (!offsets) return DIENUM_CONTINUE; - for (i = 0; i < format->dwNumObjs; ++i) - if (offsets[i] == filter.dwObj) break; - if (i == format->dwNumObjs) return DIENUM_CONTINUE; - filter.dwObj = format->rgodf[i].dwOfs; - } - button_ofs += impl->caps.NumberInputValueCaps * sizeof(LONG); button_ofs += impl->caps.NumberOutputValueCaps * sizeof(LONG); button_ofs += impl->caps.NumberFeatureValueCaps * sizeof(LONG); @@ -489,7 +477,7 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header, instance.dwDimension = caps->units; instance.wExponent = caps->units_exp; check_pid_effect_axis_caps( impl, &instance ); - ret = enum_object( impl, &filter, flags, callback, caps, &instance, data ); + ret = enum_object( impl, filter, flags, callback, caps, &instance, data ); if (ret != DIENUM_CONTINUE) return ret; value_ofs += sizeof(LONG); object++; @@ -532,7 +520,7 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header, instance.wCollectionNumber = caps->link_collection; instance.dwDimension = caps->units; instance.wExponent = caps->units_exp; - ret = enum_object( impl, &filter, flags, callback, caps, &instance, data ); + ret = enum_object( impl, filter, flags, callback, caps, &instance, data ); if (ret != DIENUM_CONTINUE) return ret; button_ofs++; object++; @@ -567,7 +555,7 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header, instance.wCollectionNumber = nary->link_collection; instance.dwDimension = caps->units; instance.wExponent = caps->units_exp; - ret = enum_object( impl, &filter, flags, callback, nary, &instance, data ); + ret = enum_object( impl, filter, flags, callback, nary, &instance, data ); if (ret != DIENUM_CONTINUE) return ret; button_ofs++; } @@ -586,7 +574,7 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header, instance.wCollectionNumber = caps->link_collection; instance.dwDimension = caps->units; instance.wExponent = caps->units_exp; - ret = enum_object( impl, &filter, flags, callback, caps, &instance, data ); + ret = enum_object( impl, filter, flags, callback, caps, &instance, data ); if (ret != DIENUM_CONTINUE) return ret; if (caps->flags & HID_VALUE_CAPS_IS_BUTTON) button_ofs++; @@ -612,7 +600,7 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header, instance.wCollectionNumber = node->parent; instance.dwDimension = 0; instance.wExponent = 0; - ret = enum_object( impl, &filter, flags, callback, NULL, &instance, data ); + ret = enum_object( impl, filter, flags, callback, NULL, &instance, data ); if (ret != DIENUM_CONTINUE) return ret; } } diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index 0c2a1b839ff..ad91c948fbc 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -302,7 +302,7 @@ static BOOL try_enum_object( const DIPROPHEADER *filter, DWORD flags, LPDIENUMDE return DIENUM_CONTINUE; } -static HRESULT keyboard_internal_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEADER *header, DWORD flags, +static HRESULT keyboard_internal_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEADER *filter, DWORD flags, LPDIENUMDEVICEOBJECTSCALLBACKW callback, void *context ) { SysKeyboardImpl *impl = impl_from_IDirectInputDevice8W( iface ); @@ -314,31 +314,16 @@ static HRESULT keyboard_internal_enum_objects( IDirectInputDevice8W *iface, cons .dwOfs = DIK_ESCAPE, .dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( DIK_ESCAPE ), }; - DIDATAFORMAT *format = impl->base.data_format.wine_df; - int *offsets = impl->base.data_format.offsets; - DIPROPHEADER filter = *header; DWORD i, dik; BOOL ret; - if (header->dwHow != DIPH_DEVICE && header->dwHow != DIPH_BYOFFSET && header->dwHow != DIPH_BYID) - return DIERR_UNSUPPORTED; - - if (filter.dwHow == DIPH_BYOFFSET) - { - if (!offsets) return DIENUM_CONTINUE; - for (i = 0; i < format->dwNumObjs; ++i) - if (offsets[i] == filter.dwObj) break; - if (i == format->dwNumObjs) return DIENUM_CONTINUE; - filter.dwObj = format->rgodf[i].dwOfs; - } - for (i = 0; i < 512; ++i) { if (!GetKeyNameTextW( i << 16, instance.tszName, ARRAY_SIZE(instance.tszName) )) continue; if (!(dik = map_dik_code( i, 0, subtype, impl->base.dinput->dwVersion ))) continue; instance.dwOfs = dik; instance.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( dik ); - ret = try_enum_object( &filter, flags, callback, &instance, context ); + ret = try_enum_object( filter, flags, callback, &instance, context ); if (ret != DIENUM_CONTINUE) return DIENUM_STOP; } diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 3553a5af94d..5b3ec2d1f20 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -575,7 +575,7 @@ static BOOL try_enum_object( const DIPROPHEADER *filter, DWORD flags, LPDIENUMDE return DIENUM_CONTINUE; } -static HRESULT mouse_internal_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEADER *header, DWORD flags, +static HRESULT mouse_internal_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEADER *filter, DWORD flags, LPDIENUMDEVICEOBJECTSCALLBACKW callback, void *context ) { DIDEVICEOBJECTINSTANCEW instances[] = @@ -640,28 +640,12 @@ static HRESULT mouse_internal_enum_objects( IDirectInputDevice8W *iface, const D .tszName = L"Button 4", }, }; - SysMouseImpl *impl = impl_from_IDirectInputDevice8W( iface ); - DIDATAFORMAT *format = impl->base.data_format.wine_df; - int *offsets = impl->base.data_format.offsets; - DIPROPHEADER filter = *header; BOOL ret; DWORD i; - if (header->dwHow != DIPH_DEVICE && header->dwHow != DIPH_BYOFFSET && header->dwHow != DIPH_BYID) - return DIERR_UNSUPPORTED; - - if (filter.dwHow == DIPH_BYOFFSET) - { - if (!offsets) return DIENUM_CONTINUE; - for (i = 0; i < format->dwNumObjs; ++i) - if (offsets[i] == filter.dwObj) break; - if (i == format->dwNumObjs) return DIENUM_CONTINUE; - filter.dwObj = format->rgodf[i].dwOfs; - } - for (i = 0; i < ARRAY_SIZE(instances); ++i) { - ret = try_enum_object( &filter, flags, callback, instances + i, context ); + ret = try_enum_object( filter, flags, callback, instances + i, context ); if (ret != DIENUM_CONTINUE) return DIENUM_STOP; }