How Proton helped improve Wine 4.2

27 March 2019 by Andrew EikumAndrew Eikum


On Tuesday (March 26, 2019), Valve released Proton 4.2, a new update to their Steam Play compatibility layer based on Wine 4.2. The previous major version of Proton was based on Wine 3.16.

As with CodeWeavers's own projects, the strong preference for work going into Proton is to also get the changes into upstream Wine. There are many benefits to this. First, all Wine users will benefit from these fixes, whether they are end users of Wine itself, CrossOver users, or users of any other Wine fork. There are also benefits for the maintainers of Proton. For example, upstreaming patches helps prevent regressions, thanks to Wine's extensive test suite; it lowers the maintenance burden, as there are fewer changes to move between Wine versions; it ensures code quality, since patches to Wine are reviewed by the Wine community; and it widens the pool of users to test, since Wine is used in many, many places other than Proton.

Proton 3.16-8 has 380 commits on top of Wine 3.16. After rebasing onto Wine 4.2, there are 214 commits. That means that 166 patches from the 3.16 branch have either been upstreamed, or are otherwise no longer needed going forward. In addition, a lot of work we have done for Wine 4.2 never got pulled back into Proton 3.16.

Let's take a look at how upstream Wine has improved thanks to Valve's sponsored work on Wine. Below is a list of changes to upstream Wine that were made in order to improve games running in Proton.

Support for importing user certificates in crypt32
fb53f6e7 crypt32/base64: Fix certificate request header and trailer in CryptBinaryToStringW() output.
d18d38bc crypt32: Fix NULL output buffer handling for CryptBinaryToString().
5652a191 crypt32: Fix output buffer handling for CRYPT_STRING_BINARY case.
09a785cb crypt32: Fix formatted output length for base64.
71f3a225 crypt32: Add CRYPT_STRING_BINARY mode for CryptBinaryToStringW().
226fd5cb crypt32: Initial implementation of PFXImportCertStore.
6dba4f78 crypt32: Add support for importing RSA private keys from PFX blobs.
5b465c50 crypt32: Support password protected PFX blobs.
962aed51 crypt32: Add support for PFX objects in CryptQueryObject.
cf9b492f crypt32/tests: Show that PFXImportCertStore doesn't set CERT_KEY_PROV_INFO_PROP_ID.

Support GL drawing from system memory buffers
b18a53a5 d3d9: Support drawing from D3DPOOL_SYSTEMMEM vertex buffers.
f34a19e6 d3d9: Support drawing from D3DPOOL_SYSTEMMEM index buffers.
75b7ff60 d3d8: Support drawing from D3DPOOL_SYSTEMMEM vertex buffers.
695dbca9 d3d8: Support drawing from D3DPOOL_SYSTEMMEM index buffers.
5a8e430b ddraw: Support drawing from D3DVBCAPS_SYSTEMMEMORY vertex buffers.
70a95cea d3d9: Fix Reset() with system memory buffers.
bdccebca d3d8: Fix Reset() with system memory buffers.
2058505c wined3d: Handle unmappable buffers in wined3d_device_process_vertices() gracefully.
ce8ef46a d3d8: Upload vertex buffer range relative to base vertex index.
1519977d d3d9: Upload vertex buffer range relative to base vertex index.
409463fb d3d9/tests: Add test for base vertex index with sysmem vertex buffers.
02222e40 d3d8/tests: Add test for base vertex index with sysmem vertex buffers.
9b1b5894 d3d9/tests: Add a test for ProcessVertices() on D3DPOOL_SYSTEMMEM buffers.
da50331b d3d8/tests: Add a test for ProcessVertices() on D3DPOOL_SYSTEMMEM buffers.
36180aa1 d3d9: Avoid calling wined3d_device_process_vertices() with unmappable source buffers.
dc3221a9 d3d8: Avoid calling wined3d_device_process_vertices() with unmappable source buffers.
445b97b2 ddraw: Pass correct box when mapping system memory vertex buffers.

Fixes for alt-tabbing out of some d3d games
4e80641d ddraw/tests: Look for more messages when losing focus.
222d3075 wined3d: Deactivate the device before minimizing the window.
7a36efc3 wined3d: Avoid accessing the device after minimize in ddraw.
a4104c7c wined3d: Avoid accessing the device after deactivation some more.
d02b4581 ddraw/tests: Test when the device goes bad on focus loss.
9317303b d3d8/tests: Test when the device goes bad on focus loss.
c964f1f9 d3d9/tests: Test when the device gets occluded during d3d9ex focus loss.
1b9483dc d3d9/tests: Test when the device goes bad on focus loss.
6954e4e2 ddraw/tests: Test destroying ddraw in WM_KILLFOCUS.

Keyboard, mouse, and gamepad compatibility improvements
cbc657a2 winex11.drv: Force changing lock keys state if hooks blocked keyboard input processing.
5040b8d5 hidclass.sys: Prevent buffer overrun.
b16fb118 hid: Don't sign-extend 16-bit values.
bd9e130e winebus.sys: Translate SDL controller axes to unsigned 32-bit values.
5ff6a116 server: Improve handling of cursor position clipping for empty rectangle.

Support for more Vulkan versions and features
6e872355 winevulkan: Remove parsing of validextensionstructs.
94a4dadd winevulkan: Check if conversion is required for pNext chains.
b5a79ca5 winevulkan: Parse enum value aliases.
5d071ce0 winevulkan: Update vk.xml to 1.1.86.
648bd17b winevulkan: Update vk.xml to 1.1.88.
eb39d3db winevulkan: Update vk.xml to 1.1.94.
ee61493d vulkan-1/tests: Add tests for vkGetPhysicalDeviceProperties2.

Improve named pipe support
36c6a16c server: Use pipe_end_get_file_info for FilePipeLocalInformation implementation.
5f43a1b9 server: Use pipe_end_get_file_info for FilePipeInformation implementation.
68a32b8c server: Support NamedPipeState in FilePipeLocalInformation.

Support FileIoCompletionNotification
2f17e011 ntdll: Add setting FileIoCompletionNotificationInformation implementation.
c0996553 server: Support FILE_SKIP_COMPLETION_PORT_ON_SUCCESS on server-side asyncs.
18e074b0 server: Support FILE_SKIP_COMPLETION_PORT_ON_SUCCESS on client-side asyncs.
04094a66 server: Use server_get_file_info for all info classes not implemented on client side.
8b8eba7e server: Use default_fd_get_file_info for FileAccessInformation implementation.
6c2ac810 ntdll/tests: Add more NtQueryInformationFile tests.
66e20ce5 server: Add NtQueryInformationFile(FileIoCompletionNotificationInformation) implementation.
4be482bc ntdll/tests: Added more FILE_SKIP_COMPLETION_PORT_ON_SUCCESS tests.
2adfa93a server: Add FileModeInformation implementation.
f003ac5e server: Use requested options for device pseudo fd.
2600ecd4 server: Use a separated object for each opened named pipe device file.
b114bd07 kernel32: Wait on pipe handle in ConnectNamedPipe if needed.
4fc5aff5 kernel32: Wait on pipe handle in TransactNamedPipe if needed.
9050b58f ntdll: Correctly return result of blocking NtFlushBuffersFile.
36693cfb ntdll/tests: Add more I/O blocking and completion tests.
f7f9bf98 server: Introduce is_fd_overlapped()
43cdcc07 server: Use file mode flags in async_handoff to decide if request is blocking.
3dacf821 server: Add FILE_SKIP_SET_EVENT_ON_HANDLE support.

Fix context handle return value handling in RPC
841a7574 widl: Fix HANDLE_PARAM_IS_RETURN flag handling.
28389a06 widl: Use public HANDLE_PARAM_IS_* flags.
0f6ab0e3 mshtml.idl: Add IDOMCustomEvent declaration.
69ca517e rpcrt4: Fix comment about HANDLE_PARAM_IS_RETURN.
d73a6bae rpcrt4/tests: Run RPC tests in both mixed and fully interpreted mode.
f634a84f rpcrt4/tests: Use --prefix-client to avoid duplicated function implementations.
895d0462 widl: Fix context handle as return value handling.
d2a8994d widl: Default to input param if [out] nor [in] attribut is specified in get_contexthandle_flags.
57cf4a38 mshtml: Add IDOMCustomEvent interface stub implementation.
b6c48de6 rpcrt4: Fix context handle return value marshaling.
464ba54b rpcrt4: Fix context handle return value unmarshaling.
83b94380 widl: Fix handling context handle return type in mixed mode.

ntoskrnl improvements
496447f0 ntoskrnl.exe: Add __C_specific_handler entry.
80c23190 ntoskrnl.exe: Add KeEnterGuardedRegion and KeLeaveGuardedRegion stubs.
5bfbcb73 ntoskrnl.exe: Implement KeExpandKernelStackAndCallout and KeExpandKernelStackAndCalloutEx.
2401d86f ntoskrnl.exe: Properly export *SList functions on win64.
7149ae11 ntoskrnl.exe: Add PsRevertToSelf stub.
7bacd853 ntoskrnl.exe: Implement ExDeleteNPagedLookasideList.
38c82559 ntoskrnl.exe: Set FileObject of IRP passed to driver callbacks.
4498648e ntoskrnl.exe: Add KeRevertToUserAffinityThread stub.
4505ef6c ntoskrnl.exe/tests: Introduce get_proc_address helper.
6b50fa31 ntoskrnl.exe: Add PsReferenceProcessFilePointer stub.

Improved CPU reporting
48554a26 wbemprox: Support cpuid on 64-bit.
d1f70b17 wbemprox: Strip trailing spaces from processor name.
dfb0c8c9 wbemprox: Include extended model and family fields in processor properties.
f2e1c514 wbemprox: Fix processor caption on AMD 64-bit.
cee89865 wbemprox: Create one processor object per package.
d929a1fa wineboot: More accurate reporting of AMD and Intel processors.

Support for RtlCreateUserProcess
aec7befb server: Avoid potential size overflow for empty object attributes.
be40b01c server: Align object attributes to a DWORD-boundary.
4a328e08 server: Allow specifying the security descriptor for a new thread.
af8f3ae3 server: Move initial thread creation out of the create_process() function.
0fd450af server: Specify the process in which to create a new thread.
39afcaac server: Create the initial thread as a separate request.
ac7ae92a server: Allow specifying the security descriptor for a new process.
d6683d63 server: Store the process exe file in the process structure.
2cab0ec3 server: Don't return the process exe file to the client.
622aeeba server: Return more specific error status for NE binaries.
57512807 kernel32: Reimplement GetBinaryTypeW to rely on the server for header parsing.
1060567c kernel32: Remove the DOS/Win16/OS2 binary distinction.
8b492467 kernel32: Move MODULE_get_binary_info implementation to process.c.
9d3a5a96 kernel32: Retrieve binary information from the server for PE files.
da40de3c kernel32: Determine 32/64-bitness from the PE architecture.
df637816 kernel32: Return the binary type from get_binary_info().
ec13f6ec kernel32: Get rid of the binary_info structure.
dc0ec550 kernel32: Create a fresh PE info structure when running winevdm.
2475cb76 kernel32: Make a copy of the process environment in CreateProcessW().
fd60a33e kernel32: Pass the full filename to winevdm.exe in CreateProcessW().
2418bb1d ntdll: Implement RtlCreateProcessParametersEx().
0964b3cd kernel32: Use the CPU type from the image information in CreateProcess().
79e2afaa kernel32: Build a standard process parameters structure in CreateProcess().
ed551282 kernel32: Pass the standard process parameters structure to create_process().
27ba57e8 kernel32: Pass the standard process parameters structure to fork_and_exec().
fce198cc ntdll: Store a copy of the environment in RtlCreateProcessParametersEx().
ae7ccbba ntdll: Fixup size of the current directory in RtlCreateProcessParametersEx().
179c0ee6 ntdll: Align string data in RtlCreateProcessParametersEx().
b5d4484c ntdll: Allocate process parameters on the heap in RtlCreateProcessParametersEx().
ec0c5a11 kernel32: Move environment Unicode conversion into create_process_params().
c4d85843 kernel32: Get the current directory from the process parameters in create_cmd_process().
a77ef5c4 server: Add a separate request to exec a new process.
bff32557 server: Pass a process as parent to create_process().
7e965140 kernel32: Separate the exec process functionality.
33c3cee8 kernel32: Get std handles from the process parameters.
1a561b64 kernel32: Use the Unicode string length to build the argv array.
7a8ff7fa kernel32: Avoid setting an empty current directory in the process params.
5cc8bcf0 ntdll: Implement RtlCreateUserProcess().
c998667b ntdll: Also return the SECTION_IMAGE_INFORMATION data from RtlCreateUserProcess().

Support for finding dlls of the correct 32/64 bitness
c827e3f6 kernel32: Fix handling of NULL argument in SetDllDirectoryA().
6fb00db5 ntdll: Don't use current directory for libraries unless explicitly specified in the search path.
a6e4c814 ntdll: Use an NT filename to search for loaded modules.
3099b04a ntdll: Return an NT filename in find_dll_file().
e24b1624 ntdll: Pass an NT filename to get_load_order().
dc40bc85 ntdll: Use NT filenames when loading dlls.
f7b31209 ntdll: Remove no longer used parameter from find_fileid_module().
4880a5a0 ntdll: Pass a flag instead of a file handle to load_builtin_dll().
c946922a ntdll: Directly try to open the dll file instead of checking for existence first.
f1bb3580 ntdll: Create the memory mapping for a dll directly at open time.
f244c3b5 server: Add custom flag for fake dlls in PE image information.
2062df7e ntdll: Use the image info to check for fake dlls.
9839bb76 ntdll: Skip dlls of the wrong machine type when searching through the load path.
6abf99b4 ntdll: Use the current platform as processorArchitecture instead of a wildcard.

Misc improvements
60c06980 msvcrt: Implement __strncnt().
8908bdbb winedbg: Ignore ^C events in the parent 32-bit process.
1c936548 start: Try cycling through extensions if original path failed to execute.
bbdf6d5e msacm32: Reference count local drivers.
bd730a5f user32: Check for null handle in GetRawInputData().

About Andrew Eikum
Andrew has been a Wine developer at CodeWeavers since 2009. He works on all parts of Wine, but specifically supports Wine's audio. He's also a developer on many of CodeWeavers's software ports.

About CodeWeavers
Founded in 1996 as a general software consultancy, CodeWeavers focuses on the development of Wine – the core technology found in all of its CrossOver products. The company's goal is to bring expanded market opportunities for Windows software developers by making it easier, faster and more painless to port Windows software to Mac and Linux. CodeWeavers is recognized as a leader in open-source Windows porting technology, and maintains development offices in Minnesota, the United Kingdom and elsewhere around the world. The company is privately held.

The following comments are owned by whoever posted them. We are not responsible for them in any way.


New Comment

Dashton Peccia
Posted 2019-05-02 14:45
Very interesting read as always!  I am wondering, since Proton is exclusively for Linux now, do as many of these changes benefit the macOS version of Wine as well?  
Ian Sliwinski
Ian Sliwinski
Posted 2019-05-17 14:03
Will this mean that finally the WoT Mac Wrapper will be 64-bit versus the current 32-bit standalone app that, IIRC, is based on Wine 1.5.2?

Please Wait...
eyJjYXJ0IjowLCJ0enMiOi01LCJjZG4iOiJodHRwczpcL1wvbWVkaWEuY29kZXdlYXZlcnMuY29tXC9wdWJcL2Nyb3Nzb3Zlclwvd2Vic2l0ZSIsImNkbnRzIjoxNTU4MDM0NTA0fQ==