Index: trunk/src/VBox/Runtime/common/string/strformatrt.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/string/strformatrt.cpp	(revision 66415)
+++ trunk/src/VBox/Runtime/common/string/strformatrt.cpp	(revision 66731)
@@ -670,5 +670,5 @@
 
             /*
-             * Base name printing.
+             * Base name printing, big endian UTF-16.
              */
             case 'b':
@@ -699,4 +699,54 @@
                         return pfnOutput(pvArgOutput, pszLastSep, psz - pszLastSep);
                     }
+
+                    /* %lRbs */
+                    case 's':
+                        if (chArgSize == 'l')
+                        {
+                            /* utf-16BE -> utf-8 */
+                            int         cchStr;
+                            PCRTUTF16   pwszStr = va_arg(*pArgs, PRTUTF16);
+
+                            if (RT_VALID_PTR(pwszStr))
+                            {
+                                cchStr = 0;
+                                while (cchStr < cchPrecision && pwszStr[cchStr] != '\0')
+                                    cchStr++;
+                            }
+                            else
+                            {
+                                static RTUTF16  s_wszBigNull[] =
+                                {
+                                    RT_H2BE_U16_C((uint16_t)'<'), RT_H2BE_U16_C((uint16_t)'N'), RT_H2BE_U16_C((uint16_t)'U'),
+                                    RT_H2BE_U16_C((uint16_t)'L'), RT_H2BE_U16_C((uint16_t)'L'), RT_H2BE_U16_C((uint16_t)'>'), '\0'
+                                };
+                                pwszStr = s_wszBigNull;
+                                cchStr  = RT_ELEMENTS(s_wszBigNull) - 1;
+                            }
+
+                            cch = 0;
+                            if (!(fFlags & RTSTR_F_LEFT))
+                                while (--cchWidth >= cchStr)
+                                    cch += pfnOutput(pvArgOutput, " ", 1);
+                            cchWidth -= cchStr;
+                            while (cchStr-- > 0)
+                            {
+/** @todo \#ifndef IN_RC*/
+#ifdef IN_RING3
+                                RTUNICP Cp = 0;
+                                RTUtf16BigGetCpEx(&pwszStr, &Cp);
+                                char *pszEnd = RTStrPutCp(szBuf, Cp);
+                                *pszEnd = '\0';
+                                cch += pfnOutput(pvArgOutput, szBuf, pszEnd - szBuf);
+#else
+                                char ch = (char)(*pwszStr++ >> 8);
+                                cch += pfnOutput(pvArgOutput, &ch, 1);
+#endif
+                            }
+                            while (--cchWidth >= 0)
+                                cch += pfnOutput(pvArgOutput, " ", 1);
+                            return cch;
+                        }
+                    /* fall thru */
 
                     default:
Index: trunk/src/VBox/Runtime/common/string/utf-16-case.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/string/utf-16-case.cpp	(revision 66415)
+++ trunk/src/VBox/Runtime/common/string/utf-16-case.cpp	(revision 66731)
@@ -34,4 +34,5 @@
 #include <iprt/uni.h>
 #include <iprt/alloc.h>
+#include <iprt/asm.h>
 #include <iprt/assert.h>
 #include <iprt/err.h>
@@ -104,4 +105,75 @@
 }
 RT_EXPORT_SYMBOL(RTUtf16ICmp);
+
+
+RTDECL(int) RTUtf16BigICmp(register PCRTUTF16 pwsz1, register PCRTUTF16 pwsz2)
+{
+    if (pwsz1 == pwsz2)
+        return 0;
+    if (!pwsz1)
+        return -1;
+    if (!pwsz2)
+        return 1;
+
+    PCRTUTF16 pwsz1Start = pwsz1; /* keep it around in case we have to backtrack on a surrogate pair */
+    for (;;)
+    {
+        register RTUTF16  wc1 = *pwsz1;
+        register RTUTF16  wc2 = *pwsz2;
+        register int     iDiff = wc1 - wc2;
+        if (iDiff)
+        {
+            /* unless they are *both* surrogate pairs, there is no chance they'll be identical. */
+            wc1 = RT_BE2H_U16(wc1);
+            wc2 = RT_BE2H_U16(wc2);
+            if (    wc1 < 0xd800
+                ||  wc2 < 0xd800
+                ||  wc1 > 0xdfff
+                ||  wc2 > 0xdfff)
+            {
+                /* simple UCS-2 char */
+                iDiff = RTUniCpToUpper(wc1) - RTUniCpToUpper(wc2);
+                if (iDiff)
+                    iDiff = RTUniCpToLower(wc1) - RTUniCpToLower(wc2);
+            }
+            else
+            {
+                /* a damned pair */
+                RTUNICP uc1;
+                RTUNICP uc2;
+                if (wc1 >= 0xdc00)
+                {
+                    if (pwsz1Start == pwsz1)
+                        return iDiff;
+                    uc1 = RT_BE2H_U16(pwsz1[-1]);
+                    if (uc1 < 0xd800 || uc1 >= 0xdc00)
+                        return iDiff;
+                    uc1 = 0x10000 + (((uc1                    & 0x3ff) << 10) | (wc1 & 0x3ff));
+                    uc2 = 0x10000 + (((RT_BE2H_U16(pwsz2[-1]) & 0x3ff) << 10) | (wc2 & 0x3ff));
+                }
+                else
+                {
+                    RTUTF16 wcTmp = *++pwsz1;
+                    uc1 = RT_BE2H_U16(wcTmp);
+                    if (uc1 < 0xdc00 || uc1 >= 0xe000)
+                        return iDiff;
+                    uc1 = 0x10000 + (((wc1 & 0x3ff) << 10) | (uc1                & 0x3ff));
+                    wcTmp = *++pwsz2;
+                    uc2 = 0x10000 + (((wc2 & 0x3ff) << 10) | (RT_BE2H_U16(wcTmp) & 0x3ff));
+                }
+                iDiff = RTUniCpToUpper(uc1) - RTUniCpToUpper(uc2);
+                if (iDiff)
+                    iDiff = RTUniCpToLower(uc1) - RTUniCpToLower(uc2); /* serious paranoia! */
+            }
+            if (iDiff)
+                return iDiff;
+        }
+        if (!wc1)
+            return 0;
+        pwsz1++;
+        pwsz2++;
+    }
+}
+RT_EXPORT_SYMBOL(RTUtf16BigICmp);
 
 
@@ -145,4 +217,154 @@
 
 
+RTDECL(int) RTUtf16NICmp(register PCRTUTF16 pwsz1, register PCRTUTF16 pwsz2, size_t cwcMax)
+{
+    if (pwsz1 == pwsz2)
+        return 0;
+    if (!pwsz1)
+        return -1;
+    if (!pwsz2)
+        return 1;
+
+    PCRTUTF16 pwsz1Start = pwsz1; /* keep it around in case we have to backtrack on a surrogate pair */
+    while (cwcMax-- > 0)
+    {
+        register RTUTF16  wc1 = *pwsz1;
+        register RTUTF16  wc2 = *pwsz2;
+        register int     iDiff = wc1 - wc2;
+        if (iDiff)
+        {
+            /* unless they are *both* surrogate pairs, there is no chance they'll be identical. */
+            if (    wc1 < 0xd800
+                ||  wc2 < 0xd800
+                ||  wc1 > 0xdfff
+                ||  wc2 > 0xdfff)
+            {
+                /* simple UCS-2 char */
+                iDiff = RTUniCpToUpper(wc1) - RTUniCpToUpper(wc2);
+                if (iDiff)
+                    iDiff = RTUniCpToLower(wc1) - RTUniCpToLower(wc2);
+            }
+            else
+            {
+                /* a damned pair */
+                RTUNICP uc1;
+                RTUNICP uc2;
+                if (wc1 >= 0xdc00)
+                {
+                    if (pwsz1Start == pwsz1)
+                        return iDiff;
+                    uc1 = pwsz1[-1];
+                    if (uc1 < 0xd800 || uc1 >= 0xdc00)
+                        return iDiff;
+                    uc1 = 0x10000 + (((uc1       & 0x3ff) << 10) | (wc1 & 0x3ff));
+                    uc2 = 0x10000 + (((pwsz2[-1] & 0x3ff) << 10) | (wc2 & 0x3ff));
+                }
+                else if (cwcMax-- > 0)
+                {
+                    uc1 = *++pwsz1;
+                    if (uc1 < 0xdc00 || uc1 >= 0xe000)
+                        return iDiff;
+                    uc1 = 0x10000 + (((wc1 & 0x3ff) << 10) | (uc1      & 0x3ff));
+                    uc2 = 0x10000 + (((wc2 & 0x3ff) << 10) | (*++pwsz2 & 0x3ff));
+                }
+                else
+                {
+                    iDiff = wc1 - wc2;
+                    return iDiff;
+                }
+                iDiff = RTUniCpToUpper(uc1) - RTUniCpToUpper(uc2);
+                if (iDiff)
+                    iDiff = RTUniCpToLower(uc1) - RTUniCpToLower(uc2); /* serious paranoia! */
+            }
+            if (iDiff)
+                return iDiff;
+        }
+        if (!wc1)
+            return 0;
+        pwsz1++;
+        pwsz2++;
+    }
+    return 0;
+}
+RT_EXPORT_SYMBOL(RTUtf16NICmp);
+
+
+RTDECL(int) RTUtf16BigNICmp(register PCRTUTF16 pwsz1, register PCRTUTF16 pwsz2, size_t cwcMax)
+{
+    if (pwsz1 == pwsz2)
+        return 0;
+    if (!pwsz1)
+        return -1;
+    if (!pwsz2)
+        return 1;
+
+    PCRTUTF16 pwsz1Start = pwsz1; /* keep it around in case we have to backtrack on a surrogate pair */
+    while (cwcMax-- > 0)
+    {
+        register RTUTF16  wc1 = *pwsz1;
+        register RTUTF16  wc2 = *pwsz2;
+        register int     iDiff = wc1 - wc2;
+        if (iDiff)
+        {
+            /* unless they are *both* surrogate pairs, there is no chance they'll be identical. */
+            wc1 = RT_BE2H_U16(wc1);
+            wc2 = RT_BE2H_U16(wc2);
+            if (    wc1 < 0xd800
+                ||  wc2 < 0xd800
+                ||  wc1 > 0xdfff
+                ||  wc2 > 0xdfff)
+            {
+                /* simple UCS-2 char */
+                iDiff = RTUniCpToUpper(wc1) - RTUniCpToUpper(wc2);
+                if (iDiff)
+                    iDiff = RTUniCpToLower(wc1) - RTUniCpToLower(wc2);
+            }
+            else
+            {
+                /* a damned pair */
+                RTUNICP uc1;
+                RTUNICP uc2;
+                if (wc1 >= 0xdc00)
+                {
+                    if (pwsz1Start == pwsz1)
+                        return iDiff;
+                    uc1 = RT_BE2H_U16(pwsz1[-1]);
+                    if (uc1 < 0xd800 || uc1 >= 0xdc00)
+                        return iDiff;
+                    uc1 = 0x10000 + (((uc1                    & 0x3ff) << 10) | (wc1 & 0x3ff));
+                    uc2 = 0x10000 + (((RT_BE2H_U16(pwsz2[-1]) & 0x3ff) << 10) | (wc2 & 0x3ff));
+                }
+                else if (cwcMax > 0)
+                {
+                    RTUTF16 wcTmp = *++pwsz1;
+                    uc1 = RT_BE2H_U16(wcTmp);
+                    if (uc1 < 0xdc00 || uc1 >= 0xe000)
+                        return iDiff;
+                    uc1 = 0x10000 + (((wc1 & 0x3ff) << 10) | (uc1                & 0x3ff));
+                    wcTmp = *++pwsz2;
+                    uc2 = 0x10000 + (((wc2 & 0x3ff) << 10) | (RT_BE2H_U16(wcTmp) & 0x3ff));
+                }
+                else
+                {
+                    iDiff = wc1 - wc2;
+                    return iDiff;
+                }
+                iDiff = RTUniCpToUpper(uc1) - RTUniCpToUpper(uc2);
+                if (iDiff)
+                    iDiff = RTUniCpToLower(uc1) - RTUniCpToLower(uc2); /* serious paranoia! */
+            }
+            if (iDiff)
+                return iDiff;
+        }
+        if (!wc1)
+            return 0;
+        pwsz1++;
+        pwsz2++;
+    }
+    return 0;
+}
+RT_EXPORT_SYMBOL(RTUtf16BigNICmp);
+
+
 RTDECL(PRTUTF16) RTUtf16ToLower(PRTUTF16 pwsz)
 {
Index: trunk/src/VBox/Runtime/common/string/utf-16.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/string/utf-16.cpp	(revision 66415)
+++ trunk/src/VBox/Runtime/common/string/utf-16.cpp	(revision 66731)
@@ -33,5 +33,6 @@
 
 #include <iprt/uni.h>
-#include <iprt/alloc.h>
+#include <iprt/asm.h>
+#include <iprt/mem.h>
 #include <iprt/assert.h>
 #include <iprt/err.h>
@@ -735,4 +736,49 @@
 
 
+RTDECL(int) RTUtf16BigGetCpExInternal(PCRTUTF16 *ppwsz, PRTUNICP pCp)
+{
+    const RTUTF16 wc = RT_BE2H_U16(**ppwsz);
+
+    /* simple */
+    if (wc < 0xd800 || (wc > 0xdfff && wc < 0xfffe))
+    {
+        (*ppwsz)++;
+        *pCp = wc;
+        return VINF_SUCCESS;
+    }
+
+    int rc;
+    if (wc < 0xfffe)
+    {
+        /* surrogate pair */
+        if (wc < 0xdc00)
+        {
+            const RTUTF16 wc2 = RT_BE2H_U16((*ppwsz)[1]);
+            if (wc2 >= 0xdc00 && wc2 <= 0xdfff)
+            {
+                RTUNICP uc = 0x10000 + (((wc & 0x3ff) << 10) | (wc2 & 0x3ff));
+                *pCp = uc;
+                (*ppwsz) += 2;
+                return VINF_SUCCESS;
+            }
+
+            RTStrAssertMsgFailed(("wc=%#08x wc2=%#08x - invalid 2nd char in surrogate pair\n", wc, wc2));
+        }
+        else
+            RTStrAssertMsgFailed(("wc=%#08x - invalid surrogate pair order\n", wc));
+        rc = VERR_INVALID_UTF16_ENCODING;
+    }
+    else
+    {
+        RTStrAssertMsgFailed(("wc=%#08x - endian indicator\n", wc));
+        rc = VERR_CODE_POINT_ENDIAN_INDICATOR;
+    }
+    *pCp = RTUNICP_INVALID;
+    (*ppwsz)++;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTUtf16GetCpExInternal);
+
+
 RTDECL(PRTUTF16) RTUtf16PutCpInternal(PRTUTF16 pwsz, RTUNICP CodePoint)
 {
