Wine
Introduction
Wine is an open source implementation of a Windows application environment, which allows running Windows programs on other operating systems.
It is a complex piece of software, that relies on various parts of the underlying operating system. This page is meant to collect various bits of information about Wine on FreeBSD to assist in porting.
Contents
Status
On FreeBSD/i386 8.1 and later Wine should work for most user applications including Microsoft Office 2007. Games tend to be more problematic, but many work without issue. See the AppDB at WineHQ for the status of application support.
The FreeBSD/amd64 emulators/wine[-devel?] packages include Wine/i386 now. Previously, support for Wine/i386 on FreeBSD/amd64 was available in the emulators/i386-wine-devel port, with unofficial packages provided by DavidNaylor.
If you are running anything older than the most recent wine-devel, please refer to Issues with historical Wine versions.
If you run into bugs, feel free to file a bug report in the Wine bugzilla and mention the version of FreeBSD you are using.
Video capture
Like for video capture generally, you'll need the cuse kernel module and the multimedia/webcamd port. See the webcamd documentation for setup.
To get any 32 bit apps (whether on Wine or not) to access video capture on 64 bit FreeBSD, you need at least FreeBSD 11.3 or 12.1, and webcamd 5.3.7.0 or later built with the COMPAT32 option (which is on by default).
Binary Image Activation
The FreeBSD kernel can be configured to detect a Microsoft Windows binary and to automatically launch Wine to run the Windows binary. This allows one to treat Windows binaries like normal binaries (i.e. no need to call wine foo.exe).
As root do:
# binmiscctl add wine --interpreter /usr/local/bin/wine \ --magic "\x4d\x5a\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xff\xff\x00\x00\xb8\x00\x00\x00" \ --mask "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ --size 20 --set-enabled
As CVE-2017-11421 a.k.a "Bad Taste" vulnerability has shown, it is possible to unintentionally execute malicious Windows applications in the presence of Wine, therefore automatic execution of what the kernel would find a "Windows binary", without explicitly invoking wine, can only facilitate such (unintentional) threat vectors.
32bit Wine on FreeBSD/amd64
For details please see the i386-Wine wiki page.
Open Tasks
- file change notifications don't work, development of a patch to use libinotify-kqueue is in progress (or add kqueue support to server/change.c?)
- port missing bits in dlls/ntdll/cdrom.c
- copy protection support (securom, safedisc, etc.)
- improve CPU feature detection (MMX,SSE,...) in dlls/ntdll/nt.c:fill_cpu_info()
ASPI, a SCSI API from the 1990s, under Wine's dlls/wnaspi32, needs porting to FreeBSD.
fixme:ntdll:fill_battery_state SystemBatteryState not implemented on this platform
Unprivileged ICMP sockets
Some Windows applications need to be able to send pings. Raw network sockets are a security risk and only allowed by root, but Linux (https://lwn.net/Articles/420800/) and MacOSX (http://www.manpagez.com/man/4/icmp/) allow unprivileged applications to create special network sockets which can be used to do some ICMP operations. See also https://bugs.winehq.org/show_bug.cgi?id=8332
More Wine Bug Reports
Known Problems
Address space organisation
The address space of a wine process under FreeBSD/i386 looks roughly like this:
0x00000000-0x00110000 |
DOS area |
0x00110000-0x60000000 |
available for Windows exe, DLLs, thread stacks, heaps,... |
0x60000000-0x6000???? |
wine executable |
0x6000????-0x6200???? |
about 32MiB libc malloc(3) heap (since FreeBSD 7.0 malloc(3) can use mmap(2) as well) |
0x6200????-0x7ffe0000 |
unreserved, available to load libs (libc.so, libm.so, libX11.so,...), Wine DLLs (ntdll.dll.so, kernel32.dll.so,...) and other mmap(2) calls in code outside Wine (e.g. graphics drivers) |
0x7ffe0000-0x82000000 |
reserved by wine |
0x82000000-0xbe?????? |
unreserved, available to load more libs, Wine DLLs and other mmap(2) calls in code outside Wine (e.g. graphics drivers) |
0xbe??????-0xc0000000 |
main wine process stack |
0xc0000000-0xffffffff |
FreeBSD kernel address space |
This seems to mostly work, but the problem is that it's possible for Wine DLLs to be loaded beyond 0x80000000, which (by default) isn't user address space anymore on Windows and this could confuse some programs. On Linux this problem doesn't exist because Wine reserves everything beyond 0x80000000 and mmap allocations go downwards in memory. On Linux mmap can allocate space below 0x60000000 when needed. On FreeBSD addresses above 0x80000000 are not reserved, because mmap allocations go upwards starting after the malloc heap and there would only be about 480MiB available otherwise which is not always sufficient.
Copy protection schemes
At this point the main reason copy protection schemes like Securom and Safedisc don't work is that ntdll.dll.so and kernel32.dll.so aren't loaded at the right address. On Linux these libs have a specific base address (0x7bc00000 and 0x7b800000 respectively), but the FreeBSD ELF loader doesn't support base addresses for libs (only for programs).
This needs re-testing; as of Wine 5.10 (Wine commits 55ba3648379d90642f174e74809b84130d6d1ddc and e0138c4a6a7a87f1d25badd43e05490e706bc666) we do mmap() DLLs at the requested address whenever possible.
Issues with historical Wine versions
/proc needs to be mounted on Wine < 6.22
Wine used a number of entries in /proc, eg. /proc/curproc/file, refusing to start if /proc wasn't mounted.
As we switched to using sysctl and libprocstat instead, /proc gradually became less required in Wine > 6.20, and as of 6.22 it is completely unused.
i386_set_ldt() breaks Win16 and Win9x on Wine < 5.6
For what seems like a few years, Wine couldn't run Win16 apps, or even start running any 32 bit apps when the Windows version was set to Windows 2 or 3.1 or 9x, due to some kind of bug/regression in i386_set_ldt() on amd64 FreeBSD:
i386_set_ldt: Invalid argument Did you reconfigure the kernel with "options USER_LDT"?
USER_LDT was set, to no avail, and it worked on Linux.
Then as of this Wine commit, which was first released in Wine 5.6:
Commit a02d2773be0c330d68194e94a8a8e64f5cef2da5 Author: Alexandre Julliard <julliard@winehq.org> Date: Wed Apr 1 22:55:24 2020 +0200 krnl386: Reimplement LDT support using NtSetLdtEntries().
it started working on FreeBSD too, but only because Wine used i386_set_ldt() differently somehow. So there could still be that bug in amd64 FreeBSD's i386_set_ldt() lurking around.
Mailing Lists
You can use one of the following mailing lists:
freebsd-emulation@freebsd.org: Wine topics specifically related to FreeBSD.
wine-devel@winehq.org: General Wine developers mailing list.
wine-users@winehq.org: General Wine users mailing list.