Fix native TWAIN transfer mode for 64-Bit wine: pData points to a HGLOBAL, which is a 64-Bit value in WIN64, not an UINT32
--
v2: Release 10.17.
winemac: Remove the no-longer-needed macdrv_dll.h.
msvcrt: Support anonymous namespace in __unDName().
bcp47langs/tests: Fix a crash when running on Wine.
winex11: Remove unnecessary extra window hiding condition.
winex11: Simplify the logic to reset cursor clipping.
winex11: Update WM_HINTS and NET_WM_STATE when WM_STATE isn't.
win32u: Import Vulkan fence from the D3DKMT object fd.
win32u: Keep exported fence fd with the D3DKMT global object.
win32u: Import Vulkan semaphore from the D3DKMT object fd.
win32u: Keep exported semaphore fd with the global D3DKMT object.
user32: Fix uiLengthDrawn calculation in DrawTextExW().
user32/tests: Add some tests for uiLengthDrawn calculation in DrawTextExW().
win32u: Correct a comment.
winex11.drv: Ignore fullscreen window config changes.
winex11: Avoid freeing default colormap.
winevulkan: Use generated PE thunks for vkGetPhysicalDeviceProperties2[KHR].
win32u: Move LUID handling from winevulkan.
win32u: Wrap vkGetPhysicalDeviceProperties2[KHR].
mmdevapi/tests: Test extensible wave formats when capturing.
mmdevapi/tests: Test flag AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM when capturing.
mmdevapi/tests: Test flag AUDCLNT_STREAMFLAGS_RATEADJUST when capturing.
mmdevapi/tests: Check that Initialize() matches IsFormatSupported() when capturing.
mmdevapi/tests: Simplify checking IsFormatSupported() result when capturing.
mmdevapi/tests: Tweak the lists of audio format to test when capturing.
mmdevapi/tests: Iterate independently on sampling rates, channel counts and sample formats when capturing.
oleaut32/tests: Enable more tests for VarAnd().
oleaut32/tests: Enable more tests for VarXor().
oleaut32/tests: Enable more tests for VarEqv().
oleaut32/tests: Enable more tests for VarMul().
ntdll: Use ReadPointerAcquire to get pointer value in RtlRunOnceComplete.
makedep: Don't use LDFLAGS for special programs like the preloader.
configure: Remove a couple of unnecessary checks.
cmd: Remove transition helpers for pipe commands.
cmd: Rewrite explicit blocks for pipe.
cmd: Rewrite FOR commands for pipe.
cmd: Add support for IF commands in rewrite.
cmd: Rewrite binary operations for pipes.
wintypes: Increase string reference count when property_value_GetStringArray() succeeds.
wintypes: Create a copy for string arrays for property_value_statics_CreateStringArray().
wintypes: Increase string reference count when property_value_GetString() succeeds.
wintypes: Restore a pointer check in property_value_statics_CreateString().
wintypes: Fix a memory leak.
msxml3/element: Implement removeAttributeNode function.
server: Target the default or foreground window for internal hardware messages.
winex11: Use EGL by default for OpenGL rendering.
user32/tests: Remove some broken() for older systems in test_comctl32_class().
comctl32: Add a helper to handle CCM_SETVERSION messages.
comctl32/tests: Move toolbar Unicode format tests.
mscoree: Update Wine Mono to 10.3.0.
shell32: Move ShellMessageBox implementation to shlwapi.
include: Bump COMCTL32_VERSION to 6.
comctl32/toolbar: Fix CCM_{GET,SET}VERSION handling.
comctl32/rebar: Fix CCM_{GET,SET}VERSION handling.
comctl32/listview: Fix CCM_{GET,SET}VERSION handling.
comctl32/toolbar: Don't change Unicode format when handling CCM_SETVERSION.
comctl32/tests: Add CCM_SETVERSION tests.
activeds: Remove misleading comments.
uxtheme: Add stub for GetThemeBitmap.
bcp47langs: Add stub for GetUserLanguages.
ntdll: Clear nested exception flag at correct frame on x64.
ntdll: Make nested_exception_handler() arch specific.
ntdll/tests: Add more tests for nested exceptions on x64.
d3dx10: Pass D3DX10_IMAGE_LOAD_INFO texture creation arguments through in load_texture_data().
d3dx10: Handle FirstMipLevel argument in load_texture_data().
d3dx10: Add support for generating mipmaps to load_texture_data().
d3dx10: Handle filter value passed in via D3DX10_IMAGE_LOAD_INFO.
win32u: Fix incorrect D3DKMT exported name length.
win32u: Use local handles in D3DKMT_ESCAPE_UPDATE_RESOURCE_WINE.
win32u/tests: Avoid closing invalid handle after OpenSharedHandleByName.
win32u: Import vulkan memory from the D3DKMT object fd.
win32u: Send D3DKMT object fd to wineserver on creation.
win32u: Export host memory unix file descriptor.
ntdll: Export wine_server_send_fd to other unix libs.
winevulkan: Handle WOW64 conversion of SECURITY_ATTRIBUTES.
winevulkan: Require VK_EXT_map_memory_placed for WOW64 memory export.
winevulkan: Move physical device extension checks around.
ntdll: Use ReadPointerAcquire to get pointer value in RtlRunOnceBeginInitialize.
include: Add atomic read/write of pointers.
dmscript: Get rid of the IDirectMusicScriptImpl typedef.
dmscript: Reimplement the loading of a script.
dmscript: Move the loading of the container to a helper.
server: Don't set QS_RAWINPUT for internal hardware messages.
win32u: Process internal hardware messages while waiting.
server: Clear QS_RAWINPUT | QS_HARDWARE in get_rawinput_buffer.
win32u: Keep waiting on the queue until it gets signaled.
win32u: Use an absolute wait timeout in wait_message.
ole32: Move CoIsOle1Class() stub to combase.
combase: Remove unreachable failure path in CoTreatAsClass().
combase: Check for null arguments in CoTreatAsClass().
ole32: Move CoTreatAsClass() to combase.
This merge request has too many patches to be relayed via email.
Please visit the URL below to see the contents of the merge request.
https://gitlab.winehq.org/wine/wine/-/merge_requests/9187
# Fault secnario
If an application loads twain_32.dll for every scan and unloads it when done with scanning, it very likely crashes when the user chooses to scan a second time within the same process. Unloading twain_32.dll is not uncommon behaviour.
# Internal error cause
When sane.ds gets loaded the first time, it retrieves the address of the DSM_Entry function from twain_32.dll and stores it in a variable SANE_dsmentry in the sane.ds global data. When the DS gets closed, the sane.ds does not get unloaded due to an old workaround in dlls/twain_32/dsm_ctrl.c:275:
```
twRC = currentDS->dsEntry (pOrigin, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, pData);
/* This causes crashes due to still open Windows, so leave out for now.
* FreeLibrary (currentDS->hmod);
*/
```
When the application program closes the DSM (twain_32.dll) and reloads it, there is a hight probability that it will be loaded in a different memory location. So the exported DSM_Entry function is located at a different address. But the code in dlls/sane.ds/sane_main.c:60 does not update the pointer if SANE_dsmentry is not NULL:
```
if (SANE_dsmentry == NULL)
{
HMODULE moddsm = GetModuleHandleW(L"twain_32");
if (moddsm)
SANE_dsmentry = (void*)GetProcAddress(moddsm, "DSM_Entry");
```
So SANE_dsmentry still points to where the twain_32.dll was loaded the first time it loaded the sane.ds. Which is now an invalid address.
When later the DS wants to notify the application of an event (DS Closed, Image transfered..) it calls SANE_Notify in sane_main.c:357:
```
void SANE_Notify (TW_UINT16 message)
{ SANE_dsmentry (&activeDS.identity, &activeDS.appIdentity, DG_CONTROL, DAT_NULL, message, NULL);
}
```
And here the crash occurs due to the invalid pointer in variable SANE_dsmentry.
# Suggested Solution
There are many ways how this problem could be solved. The solution suggested here is based on an extension of the TWAIN protocol in Version 2: The DSM transfers the entry points to it's callback functions in a message:
DG_CONTROL / DAT_ENTRYPOINT / MSG_SET
That message was already implemented in sane.ds and gphoto2.gs. And both also set the flag DF_DS2 in the identitiy information SupportedGroups, so the DSM knows it is allowed to send that message. So this approach is not a workaround, but an additional feature that solves the problem in the way intended according to the TWAIN specification. This also means that the patch should solve the problem in closed source TWAIN drivers a user might install.
However [sane.d](http://sane.de)s and gphoto2.ds do not fill the TW_IDENTITY information in the response to the DAT_IDENTITIY / MSG_OPENDS message. This is different from the behaviour observed on windows. For that reason the DF_DS2 flag in SupportedGroups is also not set, and thus a change in sane.ds is neccessary to make the DAT_ENTRYPOINT solution work.
This is also not just a workaround but a change of the behaviour so it becomes closer to what is observed on windows.
# Test scenario software
I've written a small 163 lines C application program to reproduce the erroneous behaviour. It is called unloaddsm.c and I'll attach it to this merge request. It is meant to be cross-compiled with mingw-w64. It loads the DSM, opens the DS (withour showing the UI), closes the DS, unloads DSM, re-loads DSM, re-opens the DS and then displays the UI (User Interface) when the user then clicks "cancel" or presses escape, this causes the call of SANE_Notify that leads to the crash.
It also shows the TW_IDENTITY fields that sane.ds did not fill. I ran the same program with a 32-Bit windows TWAIN driver on Windows 10 and there the idendity fields were filled.
With the patch applied, the error does not occur any more in sane.ds.
```
Archive: /tmp/unloaddsm.zip
Length Date Time Name
5283 2025-10-18 23:31 unloaddsm.c
77104 2025-10-16 14:02 twain.h
161 2025-10-18 15:57 Makefile
```
--
v2: Avoid the syntax of an obsolete GNU extension for struct initialization
https://gitlab.winehq.org/wine/wine/-/merge_requests/9217
# Fault secnario
If an application loads twain_32.dll for every scan and unloads it when done with scanning, it very likely crashes when the user chooses to scan a second time within the same process. Unloading twain_32.dll is not uncommon behaviour.
# Internal error cause
When sane.ds gets loaded the first time, it retrieves the address of the DSM_Entry function from twain_32.dll and stores it in a variable SANE_dsmentry in the sane.ds global data. When the DS gets closed, the sane.ds does not get unloaded due to an old workaround in dlls/twain_32/dsm_ctrl.c:275:
```
twRC = currentDS->dsEntry (pOrigin, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, pData);
/* This causes crashes due to still open Windows, so leave out for now.
* FreeLibrary (currentDS->hmod);
*/
```
When the application program closes the DSM (twain_32.dll) and reloads it, there is a hight probability that it will be loaded in a different memory location. So the exported DSM_Entry function is located at a different address. But the code in dlls/sane.ds/sane_main.c:60 does not update the pointer if SANE_dsmentry is not NULL:
```
if (SANE_dsmentry == NULL)
{
HMODULE moddsm = GetModuleHandleW(L"twain_32");
if (moddsm)
SANE_dsmentry = (void*)GetProcAddress(moddsm, "DSM_Entry");
```
So SANE_dsmentry still points to where the twain_32.dll was loaded the first time it loaded the sane.ds. Which is now an invalid address.
When later the DS wants to notify the application of an event (DS Closed, Image transfered..) it calls SANE_Notify in sane_main.c:357:
```
void SANE_Notify (TW_UINT16 message)
{ SANE_dsmentry (&activeDS.identity, &activeDS.appIdentity, DG_CONTROL, DAT_NULL, message, NULL);
}
```
And here the crash occurs due to the invalid pointer in variable SANE_dsmentry.
# Suggested Solution
There are many ways how this problem could be solved. The solution suggested here is based on an extension of the TWAIN protocol in Version 2: The DSM transfers the entry points to it's callback functions in a message:
DG_CONTROL / DAT_ENTRYPOINT / MSG_SET
That message was already implemented in sane.ds and gphoto2.gs. And both also set the flag DF_DS2 in the identitiy information SupportedGroups, so the DSM knows it is allowed to send that message. So this approach is not a workaround, but an additional feature that solves the problem in the way intended according to the TWAIN specification. This also means that the patch should solve the problem in closed source TWAIN drivers a user might install.
However [sane.d](http://sane.de)s and gphoto2.ds do not fill the TW_IDENTITY information in the response to the DAT_IDENTITIY / MSG_OPENDS message. This is different from the behaviour observed on windows. For that reason the DF_DS2 flag in SupportedGroups is also not set, and thus a change in sane.ds is neccessary to make the DAT_ENTRYPOINT solution work.
This is also not just a workaround but a change of the behaviour so it becomes closer to what is observed on windows.
# Test scenario software
I've written a small 163 lines C application program to reproduce the erroneous behaviour. It is called unloaddsm.c and I'll attach it to this merge request. It is meant to be cross-compiled with mingw-w64. It loads the DSM, opens the DS (withour showing the UI), closes the DS, unloads DSM, re-loads DSM, re-opens the DS and then displays the UI (User Interface) when the user then clicks "cancel" or presses escape, this causes the call of SANE_Notify that leads to the crash.
It also shows the TW_IDENTITY fields that sane.ds did not fill. I ran the same program with a 32-Bit windows TWAIN driver on Windows 10 and there the idendity fields were filled.
With the patch applied, the error does not occur any more in sane.ds.
```
Archive: /tmp/unloaddsm.zip
Length Date Time Name
5283 2025-10-18 23:31 unloaddsm.c
77104 2025-10-16 14:02 twain.h
161 2025-10-18 15:57 Makefile
```
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/9217
This adds LZX compression support to FCI.
Most of the work for this was done here: https://github.com/elasota/liblzx
The LZX compression code is based on the LZX compression code from wimlib with modifications to support the cabinet variant and streaming compression. Eric Biggers (the author of wimlib) has given permission to redistribute the modified LZX code under LGPLv2 terms: https://wimlib.net/forums/viewtopic.php?t=854
I've been testing this against some large data sets (dumped game assets, Visual Studio installation) with a test program and decompressing with 7-zip and diffs have been coming back OK.
--
v12: cabinet: lzx compression support
https://gitlab.winehq.org/wine/wine/-/merge_requests/9061
This adds LZX compression support to FCI.
Most of the work for this was done here: https://github.com/elasota/liblzx
The LZX compression code is based on the LZX compression code from wimlib with modifications to support the cabinet variant and streaming compression. Eric Biggers (the author of wimlib) has given permission to redistribute the modified LZX code under LGPLv2 terms: https://wimlib.net/forums/viewtopic.php?t=854
I've been testing this against some large data sets (dumped game assets, Visual Studio installation) with a test program and decompressing with 7-zip and diffs have been coming back OK.
--
v11: cabinet: lzx compression support
https://gitlab.winehq.org/wine/wine/-/merge_requests/9061
uiLengthDrawn should represent the number of characters that have been processed.
However, the original implementation uses len (the count of displayed characters
in the current line), which is not accurate.
When text requires line breaks or special processing (such as adding an ellipsis),
the actual number of processed characters may differ from the number of displayed
characters.
When the DT_CALCRECT flag is absent, len gets decremented to 0 during the drawing loop.
Consequently, uiLengthDrawn becomes inaccurate since it relies on len's value for statistics.
--
v8: user32: Fix uiLengthDrawn calculation in DrawTextExW().
user32/tests: Add some tests for uiLengthDrawn calculation in DrawTextExW().
https://gitlab.winehq.org/wine/wine/-/merge_requests/8178