This fixes Trials Fusion often crashing when disconnecting a controller while there are more still connected.
--
v7: hidclass: Set Status for pending IRPs of removed devices to STATUS_DEVICE_NOT_CONNECTED.
ntdll/tests: Test IOSB values of the cancel operation.
ntdll/tests: Add more NtCancelIoFile[Ex]() tests.
ntdll: Wait for all asyncs to handle cancel in NtCancelIoFile[Ex]().
server: Introduce a separate server object for the async cancel operation.
server: Keep cancelled async in a separate list.
server: Introduce a find_async_from_user helper.
ntdll: Factor out a cancel_io() function.
https://gitlab.winehq.org/wine/wine/-/merge_requests/7797
On Thu Jul 31 18:58:30 2025 +0000, Tim Clem wrote:
> Ah, interesting. Thanks for looking in to that. I can't speak to any of
> that, really - I'm not very familiar with winegstreamer at all. I was
> more wondering if we needed to explicitly set `byte-stream`, and maybe
> we don't?: tclem/wine!8. Not sure if the tests cover the initial issue
> you were addressing though. And I guess if it fixates to AVC but doesn't
> have the required `codec_data` then maybe `byte-stream` is the only
> option. But like I said, that has broken h.264 on macOS.
Yeah, sorry. I took a look yesterday in the hope of finding answers, but instead came away with more questions.
But, as you probably already noticed, we do need that `stream-format=byte-stream` for `avdec_h264` to work. Otherwise we get a bunch of failed tests in `mf:transform`:
https://gitlab.winehq.org/tclem/wine/-/jobs/178373#L2122
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/8532#note_111763
These do not do anything currently, since we don't support FILE_OPEN_REPARSE_POINT on the Unix side yet. However, they are correct, as demonstrated by the recently committed tests, and it seems prudent to get these out of the way for now.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/8540
https://store.steampowered.com/app/638930/Dal_Segno/ occasionally calls IDirectSoundBuffer::Lock() with writecursor == buflen and writebytes == 0.
This is illegal, so Lock() returns DSERR_INVALIDPARAM - but the game doesn't notice, and does a memcpy to fill the returned buffer.
On native, the out params are zeroed on failure, so the memcpy ends up doing the right thing.
On Wine, the out params are left unchanged on failure, resulting in memcpy(STACK GARBAGE, src, STACK GARBAGE); after a few minutes of gameplay or idling (when the size isn't coincidentally zero), it crashes.
```
6518.932:0130:01b8:trace:dsound:IDirectSoundBufferImpl_GetCurrentPosition (01FF9BC0,090BEE94,00000000)
6518.932:0130:01b8:trace:dsound:IDirectSoundBufferImpl_GetCurrentPosition playpos = 20674080, writepos = -1, buflen=20709376 (01FF9BC0, time=6518932)
6518.932:0130:01b8:trace:dsound:IDirectSoundBufferImpl_Lock (01FF9BC0,20709376,0,090BEEA0,090BEE90,090BEE9C,090BEE98,0x00000000) at 6518932
6518.932:0130:01b8:warn:dsound:IDirectSoundBufferImpl_Lock Invalid parameter, writecursor: 20709376 >= buflen: 20709376
6518.932:0130:01b8:trace:seh:dispatch_exception code=c0000005 flags=0 addr=00444C5C ip=00444c5c
6518.932:0130:01b8:trace:seh:dispatch_exception info[0]=00000001
6518.932:0130:01b8:trace:seh:dispatch_exception info[1]=0042d0b5
6518.932:0130:01b8:warn:seh:dispatch_exception EXCEPTION_ACCESS_VIOLATION exception (code=c0000005) raised
6518.932:0130:01b8:trace:seh:dispatch_exception eax=0000008e ebx=7aa539c0 ecx=00000008 edx=00000000 esi=004dcf10 edi=0042d0b5
6518.932:0130:01b8:trace:seh:dispatch_exception ebp=090bee68 esp=090bee60 cs=0023 ss=002b ds=002b es=002b fs=0063 gs=006b flags=00010246
```
(The game is poorly written in several other ways - the segfault is caught in a SEH handler that also segfaults, repeat until stack overflow; it repeatedly unlocks critical section 004A4A28, which nothing ever locks; there's a homemade spinlock implementation at 0042CAB2; probably some more weirdness I didn't discover. But those have little or no user-visible impact, they just look ugly in the PROTON_LOG and/or game disassembly. Let's ignore them.)
...is there such a thing as too many tests? Nobody's gonna try most of what these tests do.
--
v2: dsound: Improve IDirectSoundBufferImpl_Lock handling of invalid arguments.
dsound/tests: Add tests for IDirectSoundBuffer_Lock.
https://gitlab.winehq.org/wine/wine/-/merge_requests/8632
I think this dates from a time where every window had its own window surface, and unless I'm missing something this isn't needed anymore. My intention is to refactor the client surfaces, so that they can be manipulated directly from win32u, and unify GL/VK client surfaces. This would make the code simpler, in preparation for that.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/8504
On Thu Jul 31 05:43:48 2025 +0000, Brendan McGrath wrote:
> I never did get to the bottom of why this was required for `avdec_h264`,
> after all, GStreamer plays the test file just fine without the need for
> a `capsfilter` between `h264parse` and `avdec_h264`. So I dug a bit
> deeper this morning.
> It seems it fails under wine as a result of the `GST_EVENT_SEGMENT_DONE`
> event sent within `complete_drain`. When `h264parse` receives this
> event, it fixates its caps to `AVC` and then forwards its data buffers
> to `avdec_h264` without ever providing `codec_data` (which is required
> for AVC).
> Simply removing all the events sent in `complete_drain` fixes this
> problem but unsurprisingly causes a couple of other test failures (along
> with one fix!). You can see an example of what I mean here:
> https://gitlab.winehq.org/redmcg/wine/-/merge_requests/7
> But I'm not sure yet if this is a bug in `h264parse` or in our draining logic.
Ah, interesting. Thanks for looking in to that. I can't speak to any of that, really - I'm not very familiar with winegstreamer at all. I was more wondering if we needed to explicitly set `byte-stream`, and maybe we don't?: tclem/wine!8. Not sure if the tests cover the initial issue you were addressing though. And I guess if it fixates to AVC but doesn't have the required `codec_data` then maybe `byte-stream` is the only option. But like I said, that has broken h.264 on macOS.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/8532#note_111746
FFB Autocenter introduced in https://gitlab.winehq.org/wine/wine/-/merge_requests/4911
had one major misunderstanding.
The USB PID standard doesn't actually define any explicit way to
autocenter a device. One could of course use the spring effect with a
deadzone of 0 and dead band of 0. This is what I'm actually working on
for the Linux PID driver (spring + friction/damper).
Some devices implement autocenter in firmware when they receive the
DC Disable Actuators command. Very few, if not just one, implement this
weird autocenter effect on slot 1. This is, from what I can gather, only
implemented on the MS SideWinder joystick(s) and the Windows' USB PID
driver is created around these devices.
Windows PID driver is a bit out of spec, is quite permissive when it
comes to fields missing in the descriptor (basically, only effect types
and their effect type blocks are optional). Another thing it does is
handling of this out-of-spec autocentering for their joysticks.
Funnliy enough, the creator of the Linux PID driver based the initial
code on testing with MS Sidewinder so it's autocentering is supported.
This is where the autocentering mentioned in the MR comes from. It's not
the directinput api that does it but the Windows PID driver. As such,
autocentering on reset should be left to the drivers, not handeled by
Wine.
SDL lacks full reset support and Linux is even more barebones, whre it's
not even possible to query the device state, effects etc (something I'm
working on slowly). As such, when games send out RESET to prepare the
device, the device starts autocentering for no good reason and the
effect is not removed once other effect are uploaded and played which
would be the case for MS sidewinder.
In any case, even Windows in inconsistent and I think the directinput
documentation has some errors. directinput ffb api is largely based on
USB PID but:


Testing with my Moza Racing R9 wheelbase, the DC Reset PID command is
sent, but there's no DC Disable Actuators in sight. The games still
call reset then enable actuators though.
tl;dr
Set autocentering to 0 instead of max value when DISFFC_RESET is
received to remove the unwanted autocenter behavior.
Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny(a)gmail.com>
--
v4: winebus: Do not touch autocenter on device init and device reset
https://gitlab.winehq.org/wine/wine/-/merge_requests/8605