Index: /trunk/include/iprt/thread.h
===================================================================
--- /trunk/include/iprt/thread.h	(revision 88687)
+++ /trunk/include/iprt/thread.h	(revision 88688)
@@ -255,6 +255,13 @@
     RTTHREADFLAGS_WAITABLE_BIT = 0,
 
+    /** Call CoInitializeEx w/ COINIT_MULTITHREADED, COINIT_DISABLE_OLE1DDE and
+     * COINIT_SPEED_OVER_MEMORY.  Ignored on non-windows platforms. */
+    RTTHREADFLAGS_COM_MTA = RT_BIT(1),
+    /** Call CoInitializeEx w/ COINIT_APARTMENTTHREADED and
+     *  COINIT_SPEED_OVER_MEMORY.   Ignored on non-windows platforms.  */
+    RTTHREADFLAGS_COM_STA = RT_BIT(2),
+
     /** Mask of valid flags, use for validation. */
-    RTTHREADFLAGS_MASK = RT_BIT(0)
+    RTTHREADFLAGS_MASK = UINT32_C(0x7)
 } RTTHREADFLAGS;
 
Index: /trunk/src/VBox/Runtime/r3/win/thread-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/thread-win.cpp	(revision 88687)
+++ /trunk/src/VBox/Runtime/r3/win/thread-win.cpp	(revision 88688)
@@ -42,4 +42,5 @@
 #include <iprt/cpuset.h>
 #include <iprt/err.h>
+#include <iprt/ldr.h>
 #include <iprt/log.h>
 #include <iprt/mem.h>
@@ -55,4 +56,12 @@
 typedef HRESULT (WINAPI *PFNSETTHREADDESCRIPTION)(HANDLE hThread, WCHAR *pwszName); /* Since W10 1607 */
 
+/** CoInitializeEx */
+typedef HRESULT (WINAPI *PFNCOINITIALIZEEX)(LPVOID, DWORD);
+/** CoUninitialize */
+typedef void (WINAPI *PFNCOUNINITIALIZE)(void);
+/** OleUninitialize */
+typedef void (WINAPI *PFNOLEUNINITIALIZE)(void);
+
+
 
 /*********************************************************************************************************************************
@@ -60,7 +69,14 @@
 *********************************************************************************************************************************/
 /** The TLS index allocated for storing the RTTHREADINT pointer. */
-static DWORD g_dwSelfTLS = TLS_OUT_OF_INDEXES;
+static DWORD                    g_dwSelfTLS = TLS_OUT_OF_INDEXES;
 /** Pointer to SetThreadDescription (KERNEL32.DLL) if available. */
-static PFNSETTHREADDESCRIPTION g_pfnSetThreadDescription = NULL;
+static PFNSETTHREADDESCRIPTION  g_pfnSetThreadDescription = NULL;
+
+/** Pointer to CoInitializeEx (OLE32.DLL / combase.dll) if available. */
+static PFNCOINITIALIZEEX volatile   g_pfnCoInitializeEx  = NULL;
+/** Pointer to CoUninitialize (OLE32.DLL / combase.dll) if available. */
+static PFNCOUNINITIALIZE volatile   g_pfnCoUninitialize  = NULL;
+/** Pointer to OleUninitialize (OLE32.DLL / combase.dll) if available. */
+static PFNOLEUNINITIALIZE volatile  g_pfnOleUninitialize = NULL;
 
 
@@ -251,14 +267,19 @@
                          cComInits, cComInits, cOleInits, cOleInits));
 
-        HMODULE hOle32 = GetModuleHandle("ole32.dll");
-        AssertReturnVoid(hOle32 != NULL);
-
-        typedef void (WINAPI *PFNOLEUNINITIALIZE)(void);
-        PFNOLEUNINITIALIZE  pfnOleUninitialize = (PFNOLEUNINITIALIZE)GetProcAddress(hOle32, "OleUninitialize");
-        AssertReturnVoid(pfnOleUninitialize);
-
-        typedef void (WINAPI *PFNCOUNINITIALIZE)(void);
-        PFNCOUNINITIALIZE   pfnCoUninitialize  = (PFNCOUNINITIALIZE)GetProcAddress(hOle32, "CoUninitialize");
-        AssertReturnVoid(pfnCoUninitialize);
+        PFNOLEUNINITIALIZE  pfnOleUninitialize = g_pfnOleUninitialize;
+        PFNCOUNINITIALIZE   pfnCoUninitialize  = g_pfnCoUninitialize;
+        if (pfnCoUninitialize && pfnOleUninitialize)
+        { /* likely */ }
+        else
+        {
+            HMODULE hOle32 = GetModuleHandle("ole32.dll");
+            AssertReturnVoid(hOle32 != NULL);
+
+            pfnOleUninitialize = (PFNOLEUNINITIALIZE)GetProcAddress(hOle32, "OleUninitialize");
+            AssertReturnVoid(pfnOleUninitialize);
+
+            pfnCoUninitialize  = (PFNCOUNINITIALIZE)GetProcAddress(hOle32, "CoUninitialize");
+            AssertReturnVoid(pfnCoUninitialize);
+        }
 
         while (cOleInits-- > 0)
@@ -276,4 +297,53 @@
 
 /**
+ * Implements the RTTHREADFLAGS_COM_MTA and RTTHREADFLAGS_COM_STA flags.
+ *
+ * @returns true if COM uninitialization should be done, false if not.
+ * @param   fFlags      The thread flags.
+ */
+static bool rtThreadNativeWinCoInitialize(unsigned fFlags)
+{
+    /*
+     * Resolve the ole32 init and uninit functions dynamically.
+     */
+    PFNCOINITIALIZEEX pfnCoInitializeEx = g_pfnCoInitializeEx;
+    PFNCOUNINITIALIZE pfnCoUninitialize = g_pfnCoUninitialize;
+    if (pfnCoInitializeEx && pfnCoUninitialize)
+    { /* likely */ }
+    else
+    {
+        RTLDRMOD hModOle32 = NIL_RTLDRMOD;
+        int rc = RTLdrLoadSystem("ole32.dll", true /*fNoUnload*/, &hModOle32);
+        AssertRCReturn(rc, false);
+
+        PFNOLEUNINITIALIZE pfnOleUninitialize;
+        pfnOleUninitialize = (PFNOLEUNINITIALIZE)RTLdrGetFunction(hModOle32, "OleUninitialize");
+        pfnCoUninitialize  = (PFNCOUNINITIALIZE )RTLdrGetFunction(hModOle32, "CoUninitialize");
+        pfnCoInitializeEx  = (PFNCOINITIALIZEEX )RTLdrGetFunction(hModOle32, "CoInitializeEx");
+
+        RTLdrClose(hModOle32);
+        AssertReturn(pfnCoInitializeEx && pfnCoUninitialize, false);
+
+        if (pfnOleUninitialize && !g_pfnOleUninitialize)
+            g_pfnOleUninitialize = pfnOleUninitialize;
+        g_pfnCoInitializeEx = pfnCoInitializeEx;
+        g_pfnCoUninitialize = pfnCoUninitialize;
+    }
+
+    /*
+     * Do the initializating.
+     */
+    DWORD fComInit;
+    if (fFlags & RTTHREADFLAGS_COM_MTA)
+        fComInit = COINIT_MULTITHREADED     | COINIT_SPEED_OVER_MEMORY | COINIT_DISABLE_OLE1DDE;
+    else
+        fComInit = COINIT_APARTMENTTHREADED | COINIT_SPEED_OVER_MEMORY;
+    HRESULT hrc = pfnCoInitializeEx(NULL, fComInit);
+    AssertMsg(SUCCEEDED(hrc), ("%Rhrc fComInit=%#x\n", hrc, fComInit));
+    return SUCCEEDED(hrc);
+}
+
+
+/**
  * Wrapper which unpacks the param stuff and calls thread function.
  */
@@ -287,5 +357,12 @@
     rtThreadWinSetThreadName(pThread, dwThreadId);
 
+    bool fUninitCom = (pThread->fFlags & (RTTHREADFLAGS_COM_MTA | RTTHREADFLAGS_COM_STA)) != 0;
+    if (fUninitCom)
+        fUninitCom = rtThreadNativeWinCoInitialize(pThread->fFlags);
+
     int rc = rtThreadMain(pThread, dwThreadId, &pThread->szName[0]);
+
+    if (fUninitCom && g_pfnCoUninitialize)
+        g_pfnCoUninitialize();
 
     TlsSetValue(g_dwSelfTLS, NULL);
