Intention is to use `CreateToolhelp32Snapshot` in `dbghelp.dll: EnumerateLoadedModulesW64`. Right now we can't because `CreateToolhelp32Snapshot` can't capture 32bit modules in wow64 processes, which is needed to support `SYMOPT_INCLUDE_32BIT_MODULES`.
The advantage of using `CreateToolhelp32Snapshot` in mainly performance. Right now `EnumerateLoadedModulesW64` is `O(n^2)`, because of each module it calls `GetModuleInformation` which is itself `O(n)` w.r.t. number of modules. Whereas with `CreateToolhelp32Snapshot` there is no need for `GetModuleInformation`, thus reduce the complexity to just `O(n)`.
* * *
P.S. I am also uncomfortable with the amount of similar code between `CreateToolhelp32Snapshot` and `EnumProcessModulesEx`. Can something be done here?
--
v7: kernel32: Implement TH32CS_SNAPMODULE32 support for CreateToolhelp32Snapshot.
kernel32: Use GetCurrentProcess() handle in CreateToolhelp32Snapshot if possible.
kernel32/tests: Test CreateToolhelp32Snapshot with TH32CS_SNAPMODULE32.
https://gitlab.winehq.org/wine/wine/-/merge_requests/9371
Intention is to use `CreateToolhelp32Snapshot` in `dbghelp.dll: EnumerateLoadedModulesW64`. Right now we can't because `CreateToolhelp32Snapshot` can't capture 32bit modules in wow64 processes, which is needed to support `SYMOPT_INCLUDE_32BIT_MODULES`.
The advantage of using `CreateToolhelp32Snapshot` in mainly performance. Right now `EnumerateLoadedModulesW64` is `O(n^2)`, because of each module it calls `GetModuleInformation` which is itself `O(n)` w.r.t. number of modules. Whereas with `CreateToolhelp32Snapshot` there is no need for `GetModuleInformation`, thus reduce the complexity to just `O(n)`.
* * *
P.S. I am also uncomfortable with the amount of similar code between `CreateToolhelp32Snapshot` and `EnumProcessModulesEx`. Can something be done here?
--
v6: kernel32: Implement TH32CS_SNAPMODULE32 support for CreateToolhelp32Snapshot.
kernel32: Use GetCurrentProcess() handle in CreateToolhelp32Snapshot if possible.
kernel32/tests: Test CreateToolhelp32Snapshot with TH32CS_SNAPMODULE32.
kernel32: Fix CreateToolhelp32Snapshot on old WoW64.
include: Add TH32CS_SNAPMODULE32.
kernel32/tests: Handle ERROR_BAD_LENGTH from CreateToolhelp32Snapshot.
kernel32/tests: Fix CreateToolhelp32Snapshot failure check.
https://gitlab.winehq.org/wine/wine/-/merge_requests/9371
On Tue Dec 2 05:58:21 2025 +0000, Yeshun Ye wrote:
> It's been a long time. I think it was "云视讯ViLin", but I'm not 100% sure.
> Also, it's possible that the application has been updated since then,
> which might be why the issue can no longer be reproduced. The app is
> from "China Mobile", and you can download it from here: https://download.125339.com.cn/
Alright, thank you.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/2565#note_124368
On Tue Dec 2 05:57:33 2025 +0000, Davide Beatrici wrote:
> @yeyeshun Could you perhaps tell us the name of the affected application
> so that we can test it and eventually complete your work?
It's been a long time. I think it was "云视讯ViLin", but I'm not 100% sure. Also, it's possible that the application has been updated since then, which might be why the issue can no longer be reproduced. The app is from "China Mobile", and you can download it from here: https://download.125339.com.cn/
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/2565#note_124367
The `redirect_data->clrdata_len` [is unset in /dlls/ntdll/actctx.c#L4411-4412](https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/ntdll/actctx.c?ref_type=heads#L4411-4412) when using registration-free COM in C# NET code.
Program.cs
```C#
//...
Guid guid = Guid.Parse("COM clsid");
Type type = Type.GetTypeFromCLSID(guid, true);
var instance = Activator.CreateInstance(type));
//...
```
App.manifest
```xml
<assembly>
<file name="ExampleCOM.dll">
<comClass description="ExampleCOM" progid="ExampleCOM" clsid="{COM clsid}" threadingModel="Free"/>
</file>
</assembly>
```
The above C# code gets this error on its second line.
```Shell
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
```
This is because `len_name` is uninitialized when calling `memcpy(ret_strings, ptr_name, len_name);` in `SxsLookupClrGuid`, which is fixed in this MR.
--
v7: change xml format
https://gitlab.winehq.org/wine/wine/-/merge_requests/9632
The `redirect_data->clrdata_len` [is unset in /dlls/ntdll/actctx.c#L4411-4412](https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/ntdll/actctx.c?ref_type=heads#L4411-4412) when using registration-free COM in C# NET code.
Program.cs
```C#
//...
Guid guid = Guid.Parse("COM clsid");
Type type = Type.GetTypeFromCLSID(guid, true);
var instance = Activator.CreateInstance(type));
//...
```
App.manifest
```xml
<assembly>
<file name="ExampleCOM.dll">
<comClass description="ExampleCOM" progid="ExampleCOM" clsid="{COM clsid}" threadingModel="Free"/>
</file>
</assembly>
```
The above C# code gets this error on its second line.
```Shell
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
```
This is because `len_name` is uninitialized when calling `memcpy(ret_strings, ptr_name, len_name);` in `SxsLookupClrGuid`, which is fixed in this MR.
--
v6: sxs: check len_name is set
https://gitlab.winehq.org/wine/wine/-/merge_requests/9632
The `redirect_data->clrdata_len` [is unset in /dlls/ntdll/actctx.c#L4411-4412](https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/ntdll/actctx.c?ref_type=heads#L4411-4412) when using registration-free COM in C# NET code.
Program.cs
```C#
//...
Guid guid = Guid.Parse("COM clsid");
Type type = Type.GetTypeFromCLSID(guid, true);
var instance = Activator.CreateInstance(type));
//...
```
App.manifest
```xml
<assembly>
<file name="ExampleCOM.dll">
<comClass description="ExampleCOM" progid="ExampleCOM" clsid="{COM clsid}" threadingModel="Free"/>
</file>
</assembly>
```
The above C# code gets this error on its second line.
```Shell
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
```
This is because `len_name` is uninitialized when calling `memcpy(ret_strings, ptr_name, len_name);` in `SxsLookupClrGuid`, which is fixed in this MR.
--
v5: change for triggering the pipeline to run
https://gitlab.winehq.org/wine/wine/-/merge_requests/9632