Bluetooth Filter Driver for DS3-compatibility - research notes



  • Since test feedback has been very pleasing so far I'll cut back on recruitment today and implement the missing bits and pieces in the drivers and then throw them into the WHQL test bench. Will keep you updated.



  • Jo, it's WHQL-o-clock 😅

    586b0df3-e046-49ff-8470-fe347dae078d-image.png

    This time the filter is my primary test subject. Fingers crossed! ☠



  • Oh yes, give me more green! All the green tick marks! 😎

    vmware_8NifFZYSXJ.png



  • @tulio150 @ryantburke done, welcome!



  • @Poosaurus you too 😛



  • Dammit, almost... 👀

    vmware_ZKTaK1RimB.png

    What's going on here....

    STACK_TEXT:  
    nt!DbgBreakPoint
    Wdf01000!imp_WdfCollectionRemove+0x2d1 [d:\win8_ldr\minkernel\wdf\framework\kmdf\src\support\fxcollectionapi.cpp @ 270] 
    wdftester!wdftester_WdfCollectionRemove+0xfe
    BthPS3PSM!BthPS3PSM_EvtDeviceContextCleanup+0x103 [d:\development\git.vigem.org\bthps3\bthps3psm\device.c @ 372] 
    Wdf01000!FxObject::DisposeChildrenWorker+0x2fa [d:\win8_ldr\minkernel\wdf\framework\shared\object\fxobjectstatemachine.cpp @ 1188] 
    Wdf01000!FxObject::PerformDisposingDisposeChildrenLocked+0xbc [d:\win8_ldr\minkernel\wdf\framework\shared\object\fxobjectstatemachine.cpp @ 814] 
    Wdf01000!FxObject::PerformEarlyDisposeWorkerAndUnlock+0xfb [d:\win8_ldr\minkernel\wdf\framework\shared\object\fxobjectstatemachine.cpp @ 894] 
    Wdf01000!FxObject::EarlyDispose+0x117 [d:\win8_ldr\minkernel\wdf\framework\shared\object\fxobjectstatemachine.cpp @ 460] 
    Wdf01000!FxPkgPnp::PnpEventRemovedCommonCode+0x1e2 [d:\win8_ldr\minkernel\wdf\framework\shared\irphandlers\pnp\pnpstatemachine.cpp @ 2047] 
    Wdf01000!FxPkgFdo::PnpEventFdoRemovedOverload+0x9 [d:\win8_ldr\minkernel\wdf\framework\shared\irphandlers\pnp\fxpkgfdo.cpp @ 1244] 
    Wdf01000!FxPkgPnp::PnpEnterNewState+0x1a1 [d:\win8_ldr\minkernel\wdf\framework\shared\irphandlers\pnp\pnpstatemachine.cpp @ 1231] 
    Wdf01000!FxPkgPnp::PnpProcessEventInner+0x122 [d:\win8_ldr\minkernel\wdf\framework\shared\irphandlers\pnp\pnpstatemachine.cpp @ 1147] 
    Wdf01000!FxPkgPnp::PnpProcessEvent+0x18d [d:\win8_ldr\minkernel\wdf\framework\shared\irphandlers\pnp\pnpstatemachine.cpp @ 933] 
    Wdf01000!FxDevice::DeleteDeviceFromFailedCreateNoDelete+0x13e [d:\win8_ldr\minkernel\wdf\framework\kmdf\src\core\fxdevice.cpp @ 530] 
    Wdf01000!FxDriver::AddDevice+0x158 [d:\win8_ldr\minkernel\wdf\framework\kmdf\src\core\fxdriver.cpp @ 550] 
    nt!PpvUtilCallAddDevice+0x45
    nt!PnpCallAddDevice+0xd5
    nt!PipCallDriverAddDevice+0x661
    nt!PipProcessDevNodeTree+0x2b2
    nt!PiRestartDevice+0xc7
    nt!PnpDeviceActionWorker+0x313
    nt!ExpWorkerThread+0x111
    nt!PspSystemThreadStartup+0x194
    nt!KiStartSystemThread+0x16
    

    Alright, what went wrong there on device disposal...

    --- start of log ---
    1: FxIFRStart - FxIFR logging started
    2: LockVerifierSection - Increment Lock counter (2) for Verifier Paged Memory from  \REGISTRY\MACHINE\SYSTEM\ControlSet001\services\BthPS3PSM from driver globals FFFFFA8009A2B970
    3: FxVerifierLock::InitializeLockOrder - Object Type 0x1036 does not have a lock order defined in fx\inc\FxVerifierLock.hpp
    4: FxVerifierLock::InitializeLockOrder - Object Type 0x1036 does not have a lock order defined in fx\inc\FxVerifierLock.hpp
    5: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x0000057FF58B94E8 !devobj 0xFFFFFA800AD37C20 entering PnP State WdfDevStatePnpInit from WdfDevStatePnpObjectCreated
    6: FxDevice::DeleteDeviceFromFailedCreateNoDelete - WDFDEVICE 0000057FF58B94E8 !devobj FFFFFA800AD37C20 created, but EvtDriverDeviceAdd returned status 0xc0000001(STATUS_UNSUCCESSFUL) or failure in creation
    7: FxDevice::DeleteDeviceFromFailedCreateNoDelete - WDFDEVICE 0000057FF58B94E8, !devobj FFFFFA800AD37C20 is a filter, converting 0xc0000001(STATUS_UNSUCCESSFUL) to STATUS_SUCCESS
    8: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x0000057FF58B94E8 !devobj 0xFFFFFA800AD37C20 entering PnP State WdfDevStatePnpRemoved from WdfDevStatePnpInit
    9: FxChildList::NotifyDeviceRemove - WDFCHILDLIST 0000057FF597F388:  removing children
    10: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x0000057FF58B94E8 !devobj 0xFFFFFA800AD37C20 entering PnP State WdfDevStatePnpRemovedChildrenRemoved from WdfDevStatePnpRemoved
    11: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x0000057FF58B94E8 !devobj 0xFFFFFA800AD37C20 entering PnP State WdfDevStatePnpFdoRemoved from WdfDevStatePnpRemovedChildrenRemoved
    12: FxPkgIo::StopProcessingForPower - Perform FxIoStopProcessingForPowerPurgeNonManaged for all queues of WDFDEVICE 0x0000057FF58B94E8
    13: FxIoTarget::WaitForDisposeEvent - WDFIOTARGET 0000057FF59F0368, Waiting on Dispose event FFFFF880031B0AD0
    14: imp_WdfCollectionRemove - WDFOBJECT 0000057FF58B94E8 not in WDFCOLLECTION 0000057FF57BAF78, 0xc0000225(STATUS_NOT_FOUND)
    ---- end of log ----
    

    Oh 😐 How did I manage to provoke that. Well, back to fixing stuff 😅



  • Very impressive work, would be interested in beta testing with an original Sixaxis DS3 and Bluetooth 4.0 adapter.



  • In my previous test run the filter crashed at the test Wdf - Kmdf Fault Injection Test

    This test is actually amazing! 😲 Summary:

    For each DDI that has been configured for fault injection, the WdfFiTester tool returns an NTSTATUS code of STATUS_UNSUCCESSFUL. The driver is expected to handle the failure.

    That is really cool! It means, that it uncovers continued code execution where a faulty return code of a WDF function call isn't caught properly, which may lead to a crash (as demonstrated in my last run). I think I've nailed down the issue in my code and just started another run. Fingers crossed 🤞



  • Beyond impressed with this. I've been wanting to use the PS3 Navi remote for my HTPC for years, but I didn't have the willpower to dig into it like you have. Also, thanks so much for the PS4 remote drivers. They worked flawlessly. Now able to use the Nvidia shield without having to pair/unpair its remote (next step is to run Steam Link on the Pi and then use it directly on that in a different room).

    Also happy to beta test, although it looks like you have plenty - I have a plethora of Windows machines, Pi's and Android TVs and tablets (also, as an aside, I'm also happy to give advice on career paths into coding if it will help - I manage teams of coders, previously at Atlassian, now about to join a startup. Was surprised to read it's been difficult).

    Looking forward to the final commit! 🎮



  • Man i've been reading your notes for a while now, it has been one interesting adventure even when i know very little about software coding. i'll be looking forward to send you a tip or buying the final version once its done! (idk if im mistaken or not but i remember you have a patreon going by nefarious soft solutions... right?).

    On a side note im using a genuine Sixaxis DS3 so i don't know if thats useful for beta testing (considering how many already got enroled) also im using a Wifi-Bth combo card (Qualcomm atheros) with scp.
    Cheers!



  • Why WHQL though...

    Why am I wasting so much time and resources on WHQL testing? Well, quick real-life demonstration on why cross-signing (misleadingly referred to as self-signing) kernel-mode code with an EV certificate alone in Windows 10 (UEFI, SecureBoot) doesn't work 🙂

    Installation attempt of filter driver

    Environment details

    61ca88c2-51ac-4e61-a910-4716fbb63e61-image.png

    539f07d9-9060-4878-82ed-cb46447f9d85-image.png

    INF (CAT) signed and happily offered

    ac968c22-7fad-43c4-8d29-595932771751-image.png

    So far so good...

    1db1ca3e-5e94-4215-bcdb-34203570dffa-image.png

    Uh oh, restart required, not promising...

    7eb497fc-f875-4666-a086-05ce95eef758-image.png

    And there we have it ☹

    2f25da8e-fd86-4a7a-a295-89f54f98414b-image.png

    Now with "Secure"Boot off

    SecureBoot directly influences Code Integrity settings applying to the kernel with a rather drastic impact:

    065ccc7e-ecc7-4f12-b904-b3fe66168e2b-image.png

    d1bed74e-eeb4-43cf-a8e3-a373ad6ef6c5-image.png

    So this would be production-ready. Except the cross-signed binary will not load when the rather common SecureBoot is enabled in UEFI. The Server Edition should be even more restrictive and not load cross-signed drivers anymore even without SecureBoot starting from Server 2016 IIRC. Yay...



  • @keefey hi! Well, currently it appears to be working fine, the whole self-employed coder thingy 😅 just need to clone myself hehe. Yeah my "mainstream" coding career never took off so here I am being my own boss 😛

    @ChileanHugDealer heya! Thanks for the encouragement, I do have a Patreon and currently got enough testers and so far I'm pleased with the overall results and now need to focus on getting this stack production-ready.

    Cheers



  • Status update

    We're almost feature-complete on both profile/bus and filter driver.

    A very good suggestion I still have to fully implement. The downside of the filter being active is interference with other common devices like the DS4 in "PC mode" and apparently also some branches of Xbox One compatible controllers? I currently only own an Xbox One Elite pad and that requires its own 5 GHz wireless adapter which isn't Bluetooth anyway 🤔

    So since the filter sits too low (USB/URB level) to know anything about the HCI/L2CAP state machine, it relies on some outside factors to decide if it should patch or not. So we thought about this flow:

    • Filter is active, PS3 peripherals can connect to profile driver
    • DS4 in "PC mode" connects, gets redirected to profile driver because PSM got patched
    • Profile driver denies connection with CONNECT_RSP_RESULT_PSM_NEG and instructs filter to disable itself for like 10 seconds
    • User presses PS button on DS4 to retry connection
    • Connection now successful due to filter being temporarily disabled
    • Timer enables filter again on its own to minimize required user interaction

    I haven't found a way to reject a connection attempt without the DS4 giving up so the only remaining inconvenience would be the user having to connect the controller twice if the filter is active. Other than that I think we thought off every possibility to minimize the negative impact on user experience.

    What do you think?



  • @nefarius i think that you are breathtaking. 😏

    Anyway it's a good solution if there aren't other methods.



  • @nefarius said in Bluetooth Filter Driver for DS3-compatibility - research notes:

    • Profile driver denies connection with CONNECT_RSP_RESULT_PSM_NEG and instructs filter to disable itself for like 10 seconds
    • User presses PS button on DS4 to retry connection
    • Connection now successful due to filter being temporarily disabled
    • Timer enables filter again on its own to minimize required user interaction

    I haven't found a way to reject a connection attempt without the DS4 giving up so the only remaining inconvenience would be the user having to connect the controller twice if the filter is active. Other than that I think we thought off every possibility to minimize the negative impact on user experience.

    What do you think?

    Great job! Thank you for the efforts you put in this along with the team.

    I'm not so into technical stuff, but I'll try my best here.

    The whole "reconnect" concept reminds of InputMapper 1.6. On the other hand, DS4Windows 1.7.5+ reestablishes the connection without the user initiating it manually. Just a reminder, both of these programs use ViGEm drivers.

    How does one (DS4W) achieves it while the other doesn't?



  • @AnyHoLiC said in Bluetooth Filter Driver for DS3-compatibility - research notes:

    How does one (DS4W) achieves it while the other doesn't?

    They don't. They don't/can't interfere with the Bluetooth connection process as that's completely abstracted away from them. They can send regular disconnect requests which works fine as long as the connection sequence isn't manipulated and the DS4 remains in "PC mode". The DS4 is a bit of a bastard child in this regards; even when once successfully paired to a Windows machine, once it has been turned off and turned on again it sneakily tries to connect in "PS4 mode" (a.k.a. directly establish HID Control and HID Interrupt L2CAP channels) which usually gets immediately rejected by the Windows Bluetooth stack and it tries again in "PC mode". Now with my filter patch active, the connection is - unexpectedly - routed through and the side effect I described happens. So this listing is my proposed solution/workaround until a better solution surfaces.

    Cheers



  • @nefarius Thanks for the explanation.

    So far the only issues I have while connecting DS4 to Windows (Windows 10, specifically) are the most common ones, while using IM and DS4W, which are:

    1. It takes longer to establish a connection compared to connecting to a PS4.
    2. Latency.
    3. Using it with Uplay (Ubisoft's) is basically unusable, which continuously switches back and forth between X360 and DS4 modes.

    I have yet to install ViGEm directly using PowerShell without using any extra programs.

    You don't have to reply to this.

    Thanks again for your insight.



  • @AnyHoLiC said in Bluetooth Filter Driver for DS3-compatibility - research notes:

    I have yet to install ViGEm directly using PowerShell without using any extra programs.

    PowerShell ain't no more mate 😛 see the news



  • @nefarius Funny, i have to connect my ds4 to scptoolkit twice too, to get it recognized! I can't wait to try it, i need autofire for bloodstained and joytokey auto repeat doesn't work...However twice or not, your work is amazing!!!



  • Survey: Desired Windows OS compatibility

    Ladies and gents, it's getting serious! 😅 I need community feedback on where to go from here with the singing fun for the production release. I've crafted a poll with the first answer being the most convenient and fast but most exclusive route and the last one being the most annoying but also most inclusive. Hop on, your voice matters! 🎉

    👉 BthPS3 - Desired Windows OS compatibility 👈

    Cheers


Log in to reply