[Solved] AudioIODeviceType::createAudioIODeviceType_WASAPI returns nullptr in Wine under Linux

AudioIODeviceType::createAudioIODeviceType_WASAPI(false) returns nullptr if running in Wine under Linux.
This is because the getWindowsVersion() function in juce_win32_SystemStats.cpp returns the wrong Windows version number.
Regardless of which version of the Windows environment I am using for Wine simulation (even if it is Windows 10), the version number of kernel32.dll used by wine will be 5.1.2600.2180.
image
If you match the version number of kernel32.dll to the Windows version number, it will become Windows XP.
Then I see the implementation of the AudioIODeviceType::createAudioIODeviceType_WASAPI method in juce_win32_WASAPI.cpp, using “SystemStats::getOperatingSystemType() >= SystemStats::WinVista” to determine if the Windows version is larger than Vista, obviously it will be false, so This method will return nullptr.

I think this way of judging the Windows version number is unreliable, at least in Wine, it cannot be judged in this way.
Our temporary solution is to change the juce_win32_WASAPI.cpp and change “SystemStats::getOperatingSystemType() >= SystemStats::WinVista” to use the “IsWindowsVistaOrGreater()” method in VersionHelpers.h (of course, juce_audio_devices.cpp Also added “#include <VersionHelpers.h>”).
But I don’t think this is a perfect solution. After all, it doesn’t solve the problem of how to get the Windows version number correctly. Executing “SystemStats::getOperatingSystemName()” in Wine will still return “Windows XP” forever.

So can you fix this problem with a solution that you think is better? After all, there are still many people using Wine to execute Windows applications, so we sincerely hope that this problem can be completely solved.

Many thanks!

I think Wine will report itself as Windows XP by default. This stackoverflow post seems to indicate that you can change the version of Windows that is reported via winecfg though. Does changing this to Windows 10 work?

I have changed to Windows 10 via winecfg, but “SystemStats::getOperatingSystemName()” still returns “Windows XP”.

Hmm ok. I wonder if there is a more reliable way of getting the Windows version from Wine other than checking kernel32.dll. Can you try replacing SystemStats::getOperatingSystemType() in juce_core/native/juce_win32_SystemStats.cpp with the following:

SystemStats::OperatingSystemType SystemStats::getOperatingSystemType()
{
	auto windowsVersionInfo = []
	{
		RTL_OSVERSIONINFOW versionInfo = { 0 };
​
		if (auto* mod = ::GetModuleHandleW (L"ntdll.dll"))
		{
			using RtlGetVersion = LONG (WINAPI*) (PRTL_OSVERSIONINFOW);
​
			if (auto* rtlGetVersion = (RtlGetVersion) ::GetProcAddress (mod, "RtlGetVersion"))
			{
				versionInfo.dwOSVersionInfoSize = sizeof (versionInfo);
				LONG STATUS_SUCCESS = 0;
​
				if (rtlGetVersion (&versionInfo) != STATUS_SUCCESS)
					versionInfo = { 0 };
			}
		}
​
		return versionInfo;
	}();
​
	auto major = windowsVersionInfo.dwMajorVersion;
​
	jassert (major <= 10); // need to add support for new version!
​
	if (major == 10)
	{
		return Windows10;
	}
	else if (major == 6)
	{
		auto minor = windowsVersionInfo.dwMinorVersion;
​
		if (minor == 3)
			return Windows8_1;
		if (minor == 2)
			return Windows8_0;
		if (minor == 1)
			return Windows7;
		if (minor == 0)
			return WinVista;
	}
	else if (major == 5)
	{
		auto minor = windowsVersionInfo.dwMinorVersion;
​
		if (minor == 1)
			return WinXP;
		if (minor == 0)
			return Win2000;
	}
​
    jassertfalse;
    return UnknownOS;
}

This will use RtlGetVersion to get the version instead and hopefully will pick up the version that Wine sets.

Yes! By using RtlGetVersion, wine can return the correct Windows version.
So I think this is a much better solution than the existing one!

Will this change be pushed to the develop brunch?

Yep:

Great, thanks!

Has this been tested in relation to this topic?

This commit resulted from it:

Yep, RtlGetVersion will work for Windows 10. See this StackOverflow thread.