Fixes a crash in Microsoft Flight Simulator (which passes some currently invalid values to ucrtbase._gmtime64() and doesn't expect NULL result).
It looks like any msvcrt version on modern Windows accepts wider range of values. Meanwhile, the exact range is different for ucrtbase vs older CRT versions (the exact values for ucrtbase also vary before Win10 1909). Also, older msvcrt.dll matches what we have in Wine now. So the patch keeps old msvcrt behavior, adds universally correct limits for msvcrt 70-120 and the latest (Win10 1909+) for ucrtbase.
--
v2: msvcrt: Adjust _gmtime64_s() accepted time limits.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5024
There are still some issues I need to fix, mainly around timing conversion between MIDI and dmusic. Right now MIDI files seem to be cut off before the end is reached.
Please have a look at the general approach in the meantime, I need to know if this is the right way to do this or not.
--
v11: dmime: Create a band track for MIDI segments.
https://gitlab.winehq.org/wine/wine/-/merge_requests/4982
The game I was trying to run (Ravendawn) was polluting the stdout with hundreds of CreateFile2 FIXMEs.
The game worked fine, probably because the params pointer was NULL, so any non-implemented extra parameters weren't even used and we just forwarded to CreateFileW.
So, a simple if was added to check whether the pointer is null, and if it is, we just call TRACE instead of FIXME since in this case it isn't really necessary.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5037
Theoretically, this allows debuggers to tell them apart. https://devblogs.microsoft.com/oldnewthing/20110429-00/?p=10803
But in practice, this is more about cleanliness than anything else; I'm not aware of anyone running SetLastError-aware debuggers in Wine. Feel free to reject if this is a waste of time.
The changeable SetLastError calls were found by this script:
```python
#!/usr/bin/env python3
import os
import re
for (dirpath, dirnames, filenames) in os.walk("."):
for fn in filenames:
if not fn.endswith(".c"):
continue
text = open(dirpath+"/"+fn,"rt").read()
text = text.replace("RtlSetLastWin32Error","SetLastError")
text = text.replace("RtlGetLastWin32Error","GetLastError")
if "SetLastError" not in text:
continue
varname = None
for line in text.split("\n"):
if "GetLastError" in line:
if m := re.search(r"([A-Za-z0-9_]+) *= *GetLastError", line):
prevline = line
varname = m[1]
if line == "}":
varname = None
if varname is not None and "SetLastError" in line:
if m := re.search(r"SetLastError\( *([A-Za-z0-9_]+) *\)", line):
if m[1] == varname:
print(dirpath+"/"+fn, prevline, line)
```
The script also flags https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/mpr/wnet.c#L2811, which is half set and half restore; I chose to left it unchanged.
Idea from https://gitlab.winehq.org/wine/wine/-/merge_requests/5020/diffs#6c845445f68…
--
v2: win32u: Use RtlRestoreLastWin32Error instead of RtlSetLastWin32Error if appropriate
everywhere: Change SetLastError to RestoreLastError if appropriate
ntdll: Duplicate RtlSetLastWin32Error to RtlRestoreLastWin32Error
https://gitlab.winehq.org/wine/wine/-/merge_requests/5035
Most paths that hold both the display_lock and the display_devices_init mutex acquire them in the order just mentioned. However, there are two cases where these are acquired in the opposite order, which with unfortunate thread interactions and timings can lead to a deadlock. Fix these cases to use the same order as the rest of the code.
---
The instance of this deadlock I am seeing happens when enabling the virtual desktop mode with the Wayland driver (with pristine master) with any program. It's a deadlock between two threads calling:
1. `get_display_depth` =\> first acquires `display_lock` (in `lock_display_devices`) then `display_devices_init` (in `adapter_get_current_settings)`
2. `desktop_update_display_devices` =\> `add_gpu` =\> first acquires `display_devices_init` then `display_lock`
The deadlock is not very easy to hit normally, but a sleep like in the attached patch below makes it 100% reproducible for me:
[add_gpu_sleep.patch](/uploads/c08632d7a9dec751840199bdb16fb9a8/add_gpu_sleep.patch)
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5036
There are still some issues I need to fix, mainly around timing conversion between MIDI and dmusic. Right now MIDI files seem to be cut off before the end is reached.
Please have a look at the general approach in the meantime, I need to know if this is the right way to do this or not.
--
v9: dmusic: Don't stop instrument downloading early on failure.
dmime: Create a band track for MIDI segments.
dmband: Move band.c to dmusic
dmband: Implement getting/setting GUID_BandParam on band tracks.
dmime/test: Add test for getting band track from midi file.
dmime: Implement IDirectMusicTrack_Play for MIDI tracks.
dmime: Implement getting/setting TempoParam for MIDI tracks.
dmime: Parse MIDI files.
https://gitlab.winehq.org/wine/wine/-/merge_requests/4982
Theoretically, this allows debuggers to tell them apart. https://devblogs.microsoft.com/oldnewthing/20110429-00/?p=10803
But in practice, this is more about cleanliness than anything else; I'm not aware of anyone running SetLastError-aware debuggers in Wine. Feel free to reject if this is a waste of time.
The changeable SetLastError calls were found by this script:
```python
#!/usr/bin/env python3
import os
import re
for (dirpath, dirnames, filenames) in os.walk("."):
for fn in filenames:
if not fn.endswith(".c"):
continue
text = open(dirpath+"/"+fn,"rt").read()
text = text.replace("RtlSetLastWin32Error","SetLastError")
text = text.replace("RtlGetLastWin32Error","GetLastError")
if "SetLastError" not in text:
continue
varname = None
for line in text.split("\n"):
if "GetLastError" in line:
if m := re.search(r"([A-Za-z0-9_]+) *= *GetLastError", line):
prevline = line
varname = m[1]
if line == "}":
varname = None
if varname is not None and "SetLastError" in line:
if m := re.search(r"SetLastError\( *([A-Za-z0-9_]+) *\)", line):
if m[1] == varname:
print(dirpath+"/"+fn, prevline, line)
```
The script also flags https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/mpr/wnet.c#L2811, which is half set and half restore; I chose to left it unchanged.
Idea from https://gitlab.winehq.org/wine/wine/-/merge_requests/5020/diffs#6c845445f68…
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5035