Using GnuTLS 3.6.15 indeed solves the problem: I have tested this with a LibVLC.UWP build based on VLC 3.0.12.1 which includes recent contrib. OneDrive videos can now play on both x86 and x64. It was this merge which solved the issue.
Using your .nupkg, I can only get it to work on x64. No luck on x86. Interestingly, calling LibVLC.Changeset using your .nupkg returns 3.0.12.1-28-ge67c575d2c, which indicates the vlc-3.0 source you were using is 28 commits ahead of tag 3.0.12.1. How is this possible? At the time of writing, there are only 16 commits after tag 3.0.12.1. My own build returns 3.0.12.1-0-g170157402b, which perfectly matches git describe --long in a vlc-3.0 source at tag 3.0.12.1. I cannot find a commit with hash e67c575d2c anywhere.
Did you build the .nupkg using a prebuild contrib package? I built my version using these steps, and then "installed" it by replacing the contents of an existing nuget package in %USERPROFILE%\.nuget\packages\videolan.libvlc.uwp\3.3.0\build\win-x64 and win-x86 with my own files. Obviously, not a clean method, but the issue in question is fixed, and I confirmed my own built binaries are loaded using Ctrl+Alt+U in VS during debugging.
I tried creating a nuget package, but I cannot get the mono nuget.exe pack command from libvlc-nuget to work on either WSL or Debian. Should I upload my files as well?
What's the error? You have mono installed? dotnet pack will do, too.
Somewhere on my end, I probably did something horribly wrong. package-nuget-winrt.sh would not accept any version and spit errors (with nuget.exe in my path). It might have something to do with line endings, but I have not tested nor verified this:
johannes@JohannesMD:/mnt/c/Users/Johannes/build-met-script$ ./package-nuget-winrt.sh "3.3.1"./package-nuget-winrt.sh: line 2: $'\r': command not found./package-nuget-winrt.sh: line 5: $'\r': command not foundCannot open assembly 'nuget.exe': No such file or directory.johannes@JohannesMD:/mnt/c/Users/Johannes/build-met-script$
Mono on WSL would error out with this:
Could not load file or assembly 'System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
I ended up manually invoking nuget.exe pack "VideoLAN.LibVLC.UWP.nuspec" from cmd, which spat out warnings:
C:\Users\Johannes\build-met-script>nuget.exe pack "VideoLAN.LibVLC.UWP.nuspec"WARNING: Kan bestand of assembly HolographicExtensions.dll of een van de afhankelijkheden hiervan niet laden. Er wordt verwacht dat de module een assembly-manifest zou bevatten.WARNING: Kan bestand of assembly HoloSHExtensions.dll of een van de afhankelijkheden hiervan niet laden. Er wordt verwacht dat de module een assembly-manifest zou bevatten.WARNING: Kan bestand of assembly PerceptionSimulationExtensions.dll of een van de afhankelijkheden hiervan niet laden. Er wordt verwacht dat de module een assembly-manifest zou bevatten.WARNING: Kan bestand of assembly Windows.Devices.Printers.Extensions.dll of een van de afhankelijkheden hiervan niet laden. Er wordt verwacht dat de module een assembly-manifest zou bevatten.Attempting to build package from 'VideoLAN.LibVLC.UWP.nuspec'.Successfully created package 'C:\Users\Johannes\build-met-script\VideoLAN.LibVLC.UWP.3.3.3.nupkg'.C:\Users\Johannes\build-met-script>
However, it did produce a .nupkg, so with that out of the way:
After applying the patches from vlc-winrt, building by invoking the build script from vlc-3.0 directly and creating a .nupkg, it still works fine on both x86 and x64.
However, this .nupkg was about 3x larger than yours, so I tried it again with the vlc-winrt script. This time, the size was comparable to your nuget, as were the results: x64 works but x86 does not.
A snippet from the x86 log with your nuget: cannot allocate credentials: Internal error in memory allocation.. My build produces the same error.
The difference in size of these nugets lies probably somewhere in the configure command used by the vlc-winrt build script, which disables a whole bunch of stuff. However, I have no clue as to why, even with the patches, the "fat" build works while the normal build does not.
Just tried and it's not working here.
On both architectures? I forgot this last time: OneDrive links expire after a while and have to be renewed. This is usually the first thing I would do if nothing's working.
I don't think the patches being absent was the problem: it implies it should work with the patches applied, and not without them. But neither is universally true. I think it has something to do with the build script used to build libvlc.
With or without the patches applied, builds with the Windows build script (options: -r -c -a i686 -z -u -w) still works fine on x86 while builds with the WinRT build script don't.
So the question now becomes, why does it work with the Windows build script, and what's different (outside of the patches) between these build scripts?
One obvious difference is of course the appcontainer.pl script, which gets called in the WinRT build script but not in the Windows build script. From what I understand, it shouldn't let previously working binaries fail. I did however try applying that script to the binaries generated with the Windows build script, and as expected, it didn't result in failure.
Other differences include the configure options and build variables, taken from the debug output at startup:
CPPFLAGS: WinRT script defines _WIN32_WINNT as 0xA00 instead of 0x0AA, Windows script additionally defines __MSVCRT_VERSION__ as 0xE00 while WinRT doesn't define it
LDFLAGS : WinRT script links with -lwinstorecompat instead of -lwindowsappcompat and additionally with -lnormaliz -lruntimeobject -lsynchronization
enable/disable passed to configure
I tried to replace -lwinstorecompat with -lwindowsappcompat (as per vlc@614f172e) in the WinRT script, but this also doesn't fix the issue.
I don't know the state of upstream now, but the correct way to go about this would be to build the latest version of upstream gnutls, see which custom patches are still needed (if any) and figure out which lines of the gnutls code are an issue for 32 bits builds only (since presumably it works fine on x64).
the correct way to go about this would be to build the latest version of upstream gnutls
I had no luck in getting that to work... The next minor version, 3.6.16, requires some files to be generated during the build by the native compiler instead of the the crosscompiler. I don't know autotools very well, but I certainly do not know guix, and when I saw how they fixed it, well.... See here and here.
But, the issue is fixed at last.
The reason it wasn't working was not because of an error with memory allocation, rather, the library is in an error state when OpenClient calls it. This is because during the library initialization (when it is loaded as a plugin), it tries to call LoadLibrary on crypt32.dll. Why? Because the check here only was intended for mingw32 (the old mingw, from mingw.org), but it also evaluates to true for mingw-w64 on i686 mode. The result is that the LoadLibrary code is not #ifdef-ed out on i686. On x86_64 the check evaluates to false and there's no LoadLibrary being called, rather, crypt32.dll is linked statically.
With the WinRT build script, this LoadLibrary call wraps to LoadPackagedLibrary via libwinstorecompat (libwindowsappcompat aswell?) and thus the call fails with error code 126, because crypt32.dll is not contained in the UWP appx folder. With the VLC main build script, with options mentioned above, the LoadLibrary call wraps to LoadLibraryEx (or another win32 variant which is not allowed on UWP, theoretically atleast). And of course then it succeeds. Why it wraps to the win32 variant, I don't know. Maybe @robUx4 knows?
The fix is to add checks for __MINGW64_VERSION_MAJOR and __MINGW64_VERSION_MINOR, and thus only call LoadLibrary if these are not defined and GnuTLS is being build for the old mingw. This way, crypt32.dll will be statically linked on i686-mode mingw-w64 and the call to LoadLibrary will never be made.
On UWP builds you can't use LoadLibrary or LoadLibraryEx, they are [desktop apps only] API's. Any system library needs to be used via direct calls and linking with the appropriate .lib/.a.
In this case, CertEnumCRLsInStore should be called directly. It is available in UWP: [desktop apps | UWP apps]. So, as you said, the other part of the ifdef should be used.
was intended for mingw32, but it also evaluates to true for mingw-w64 on i686 mode
According to this document, the __MINGW64__ macro is only defined for x86_64 mode mingw-w64, and not for i686-mode mingw-w64 (and old mingw for that matter). However, on i686-mode mingw-w64, the 64bit major and minor version macros are defined. I tested this out myself
On UWP builds you can't use LoadLibrary or LoadLibraryEx, they are [desktop apps only] API's. Any system library needs to be used via direct calls and linking with the appropriate .lib/.a.
Yes, but that's only in theory. With the WinRT build script, the LoadLibrary call is substituted for LoadLibraryW and ultimately calls LoadPackagedLibrary (which ofc. fails).
Screenshot of gnutls_system_global_init disassemly:
Screenshot of LoadLibraryW disassembly:
With the main VLC build script, with options -u -w -z (so building for windows store/UWP), the LoadLibrary call is substituted for LoadLibraryW, which calls directly into kernel32.dll and succeeds at loading crypt32.dll.
Screenshot of gnutls_system_global_init disassemly:
Screenshot of LoadLibraryW disassembly:
This explains why the x86 build with the main VLC build script had no issues, while x86 build with the WinRT build script was failing.
As to how or why, I thought you'd have a better understanding of both scripts. But I do think this should not be the case, right?
On my compiler __MINGW64__ is defined, but it doesn't seem to come from mingw64 (not defined anywhere in the repo, just checked in some places). We also don't use it anywhere in VLC. Maybe it's not that reliable.
I think just adding && !defined(__MINGW64_VERSION_MAJOR) should be enough. Technically there should also be this before the mingw version check, even though it's usually included by other headers: