Running the Windows Airflow media streaming app under Wine on Fedora Linux. Airflow streams video/audio to AirPlay and Chromecast devices.
Debugged with Claude Code Opus 4.6. By Martin Alderson - check out my blog if you found this useful: martinalderson.com
- Fedora 43, AMD Ryzen 9 7900, AMD Radeon RX 9070 XT
- Wine 11.0 Staging
- MinGW cross-compiler:
x86_64-w64-mingw32-gcc15.2.1
WINEPREFIX=/home/martin/.wine-airflow \
WINEDLLOVERRIDES="powrprof=n;vcruntime140_1=n;vcruntime140=n;msvcp140=n;concrt140=n" \
WINEDEBUG=-all \
wine /home/martin/source/airflow/Airflow.exe- App launches and displays UI via DXVK (Vulkan translation of Direct3D)
- AirPlay device discovery (via built-in mDNS in airflow_server.dll)
- Chromecast streaming (play button, casting video)
- AirPlay devices visible
Wine doesn't implement PowerRegisterSuspendResumeNotification. Built a stub DLL that exports the required functions and returns success.
File: powrprof_override.c + powrprof.def
Build:
x86_64-w64-mingw32-gcc -shared -o powrprof.dll powrprof_override.c powrprof.def -lkernel32 -e DllMainDeploy: Copy powrprof.dll into the Airflow directory. The WINEDLLOVERRIDES="powrprof=n" flag tells Wine to use our native DLL instead of its builtin.
The built-in mDNS responder in airflow_server.dll calls setsockopt with Windows socket option level 0xFFFB for IP_PKTINFO. Wine's Winsock translation doesn't handle this level, causing "unable to create recv socket" errors and automatic crashes on startup.
Fix: Binary patch at file offset 0x33BFD — changed BA FB FF 00 00 (mov edx, 0xFFFB) to BA 00 00 00 00 (mov edx, 0 = IPPROTO_IP).
Backup: airflow_server.dll.bak
Wine's builtin vcruntime140_1.dll implements __CxxFrameHandler4 (the MSVC C++ exception handler) with bugs that corrupt exception objects and catch block state. This caused a chain of crashes:
- DEP violation in foundation.dll vtable entry pointing to .rdata
- Access violation during exception object destruction (corrupt tree structure)
- Garbage vtable pointers (0x21F) in catch block handlers
Fix: Force Wine to load the native Microsoft MSVC runtime DLLs that ship with Airflow instead of Wine's builtin implementations:
WINEDLLOVERRIDES="vcruntime140_1=n;vcruntime140=n;msvcp140=n;concrt140=n"
The native DLLs are already present in the Airflow directory — Wine just needs to be told to prefer them (=n means native).
When pressing play on a Chromecast device, the app calls QGuiApplication::screenAt(QPoint) to get the screen geometry. Under Wine, this returns null (Wine's display management doesn't map screen coordinates the same way as Windows), and the code calls QScreen::availableGeometry() on the null pointer.
Fix: Binary patch with a code cave. Added a null check after screenAt() — if null, skip the availableGeometry() call and take the fallback path.
- Patch site (RVA
0x4B584, 13 bytes):test rax,rax; jz +0x5C; jmp cave - Code cave (RVA
0x15E392, 20 bytes in CC padding): originallea rdx; mov rcx; call [availableGeometry]; jmp back
Backup: modules/airflow_ui.dll.bak
A separate crash in a catch block at airflow_ui+0x9B90 where [this+0x38] pointed to an object with a corrupted sub-object. The function null-checks [this+0x38] but always found it non-null; the corruption was deeper.
Fix: Changed conditional jump at RVA 0x9BB8 from JE (74 12) to JMP (EB 12), making the code always take the null/fallback path and skip the problematic virtual call chain.
For 4K monitors, Wine defaults to 96 DPI making the UI tiny. Set higher DPI with:
WINEPREFIX=/home/martin/.wine-airflow wine reg add 'HKCU\Control Panel\Desktop' /v LogPixels /t REG_DWORD /d 192 /f192 = 200% scaling. Use 144 for 150%.
- Bonjour service (port 5354):
dnssd.dlltries to connect to Apple's Bonjour daemon at 127.0.0.1:5354 which doesn't exist on Linux. Device discovery works anyway via the built-in mDNS in airflow_server.dll, but Bonjour-specific features may not work. - AirPlay Receiver permissions: Target devices (Apple TV, Mac) need AirPlay Receiver set to "Everyone" or "Anyone on the Same Network" in their settings.
| File | Description |
|---|---|
Airflow.exe |
Main application |
powrprof_override.c |
Source for power API stub DLL |
powrprof.def |
Exports definition for stub DLL |
powrprof.dll |
Compiled stub (deployed to app directory) |
kernel32_hook.c |
Named pipe path fix (from WSL2 era, may not be needed) |
modules/airflow_server.dll |
Patched for setsockopt level |
modules/airflow_ui.dll |
Patched for screenAt null + catch handler skip |
foundation.dll |
Unmodified (native MSVC runtime fixes the exception issues) |
*.bak / *.bak2 |
Backups of original DLLs before patching |