calling GlobalizationPreferences::Languages() crashes after re-initializing with 'OleUninitialize(); OleInitialize(NULL);'

Andreas Buhr 21 Reputation points
2022-06-14T08:43:35.457+00:00

Calling winrt::Windows::System::UserProfile::GlobalizationPreferences::Languages(); crashes after re-initializing Ole by calling OleUninitialize(); and then OleInitialize(NULL);.

We found that during debugging of https://bugreports.qt.io/browse/QTBUG-103611.

#include <Ole2.h>  
#include <iostream>  

#   include <winrt/base.h>  
// Workaround for Windows SDK bug.  
// See https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/issues/47  
namespace winrt::impl  
{  
    template <typename Async>  
    auto wait_for(Async const& async, Windows::Foundation::TimeSpan const& timeout);  
}  
#include <winrt/Windows.Foundation.h>  
#include <winrt/Windows.Foundation.Collections.h>  
#include <winrt/Windows.System.UserProfile.h>  

int main()  
{  
    OleInitialize(NULL);  
    {  
        auto lang = winrt::Windows::System::UserProfile::GlobalizationPreferences::Languages();  
        std::cout << "First call succeeded!\n";  
    }  
    OleUninitialize();  

    OleInitialize(NULL);  
    {  
        // the next line crashes  
        auto lang = winrt::Windows::System::UserProfile::GlobalizationPreferences::Languages();  
        std::cout << "Second call succeeded!\n";  
    }  
    OleUninitialize();  
}  

callstack of crash:

OleInitializeCrashReproducer.exe!winrt::impl::consume_Windows_System_UserProfile_IGlobalizationPreferencesStatics<winrt::Windows::System::UserProfile::IGlobalizationPreferencesStatics>::Languages() Line 167 C++
OleInitializeCrashReproducer.exe!winrt::Windows::System::UserProfile::GlobalizationPreferences::Languages'::2'::<lambda_1>::operator() < winrt::Windows::System::UserProfile::IGlobalizationPreferencesStatics const& > (const winrt::Windows::System::UserProfile::IGlobalizationPreferencesStatics & f) Line 896 C++
OleInitializeCrashReproducer.exe!winrt::impl::factory_cache_entry<winrt::Windows::System::UserProfile::GlobalizationPreferences, winrt::Windows::System::UserProfile::IGlobalizationPreferencesStatics>::call<winrt: : Windows::System::UserProfile::GlobalizationPreferences::Languages'::2'::<lambda_1> &>(winrt::Windows::System::UserProfile::GlobalizationPreferences::Languages::__l2::<lambda_1> &callback) Line 5372 C++
OleInitializeCrashReproducer.exe!winrt::impl::call_factory<winrt::Windows::System::UserProfile::GlobalizationPreferences, winrt::Windows::System::UserProfile::IGlobalizationPreferencesStatics, winrt: : Windows::System::UserProfile::GlobalizationPreferences::Languages'::2'::<lambda_1>>(winrt::Windows::System::UserProfile::GlobalizationPreferences::Languages::__l2::<lambda_1> && callback) Line 5450 C++
OleInitializeCrashReproducer.exe!winrt::Windows::System::UserProfile::GlobalizationPreferences::Languages() Line 896 C++

OleInitializeCrashReproducer.exe!main() Line 31 C++

[External Code]

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,737 questions
{count} votes

Accepted answer
  1. RLWA32 47,231 Reputation points
    2022-06-26T01:45:17.383+00:00

    Try this --

        OleInitialize(NULL);  
        {  
            auto lang = winrt::Windows::System::UserProfile::GlobalizationPreferences::Languages();  
            std::cout << "First call succeeded!\n";  
        }  
        winrt::clear_factory_cache();  
        OleUninitialize();  
      
        OleInitialize(NULL);  
        {  
            // the next line crashes  
            auto lang = winrt::Windows::System::UserProfile::GlobalizationPreferences::Languages();  
            std::cout << "Second call succeeded!\n";  
        }  
        winrt::clear_factory_cache();  
        OleUninitialize();  
      
    
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Andreas Buhr 21 Reputation points
    2022-06-24T07:25:14.167+00:00

    Hi,

    the Problem I am describing is that the call GlobalizationPreferences::Languages() crashes after uninitializing and then re-initializing OLE. If I remove the first OleUninitialize() it does not crash any more. But then it's also no longer a reproducer of my problem.

    0 comments No comments

  2. Andreas Buhr 21 Reputation points
    2022-06-26T17:41:08.937+00:00

    Hi @RLWA32 yes this indeed fixes the problem.
    For us, the situation is a bit more complex, as we have multiple DLLs (in Qt) and each DLL has its own factory cache. So we have to call winrt::clear_factory_cache() once for each DLL. To achieve this, we created a registry in QtCore where each DLL registers its factory cache, so we can clear them all.
    I implemented this in https://codereview.qt-project.org/c/qt/qtbase/+/416500

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.