Index: /trunk/include/iprt/nt/nt.h
===================================================================
--- /trunk/include/iprt/nt/nt.h	(revision 60479)
+++ /trunk/include/iprt/nt/nt.h	(revision 60480)
@@ -249,4 +249,15 @@
 
 /**
+ * Converts a windows-style path to NT format and encoding.
+ *
+ * @returns IPRT status code.
+ * @param   pNtName             Where to return the NT name.  Free using
+ *                              RTNtPathFree.
+ * @param   phRootDir           Where to return the root handle, if applicable.
+ * @param   pszPath             The UTF-8 path.
+ */
+RTDECL(int) RTNtPathFromWinUtf8(struct _UNICODE_STRING *pNtName, PHANDLE phRootDir, const char *pszPath);
+
+/**
  * Converts a UTF-16 windows-style path to NT format.
  *
@@ -263,12 +274,57 @@
 
 /**
+ * Ensures that the NT string has sufficient storage to hold @a cwcMin RTUTF16
+ * chars plus a terminator.
+ *
+ * The NT string must have been returned by RTNtPathFromWinUtf8 or
+ * RTNtPathFromWinUtf16Ex.
+ *
+ * @returns IPRT status code.
+ * @param   pNtName             The NT path string.
+ * @param   cwcMin              The minimum number of RTUTF16 chars. Max 32767.
+ * @sa      RTNtPathFree
+ */
+RTDECL(int) RTNtPathEnsureSpace(struct _UNICODE_STRING *pNtName, size_t cwcMin);
+
+/**
  * Frees the native path and root handle.
  *
- * @param   pNtName             The NT path after a successful
- *                              RTNtPathFromWinUtf16Ex call.
- * @param   phRootDir           The root handle variable after a successfull
- *                              RTNtPathFromWinUtf16Ex call.
+ * @param   pNtName             The NT path from a successful call to
+ *                              RTNtPathFromWinUtf8 or RTNtPathFromWinUtf16Ex.
+ * @param   phRootDir           The root handle variable from the same call.
  */
 RTDECL(void) RTNtPathFree(struct _UNICODE_STRING *pNtName, HANDLE *phRootDir);
+
+
+/**
+ * Checks whether the path could be containing alternative 8.3 names generated
+ * by NTFS, FAT, or other similar file systems.
+ *
+ * @returns Pointer to the first component that might be an 8.3 name, NULL if
+ *          not 8.3 path.
+ * @param   pwszPath        The path to check.
+ *
+ * @remarks This is making bad ASSUMPTION wrt to the naming scheme of 8.3 names,
+ *          however, non-tilde 8.3 aliases are probably rare enough to not be
+ *          worth all the extra code necessary to open each path component and
+ *          check if we've got the short name or not.
+ */
+RTDECL(PRTUTF16) RTNtPathFindPossible8dot3Name(PCRTUTF16 pwszPath);
+
+/**
+ * Fixes up a path possibly containing one or more alternative 8-dot-3 style
+ * components.
+ *
+ * The path is fixed up in place.  Errors are ignored.
+ *
+ * @returns VINF_SUCCESS if it all went smoothly, informational status codes
+ *          indicating the nature of last problem we ran into.
+ *
+ * @param   pUniStr     The path to fix up. MaximumLength is the max buffer
+ *                      length.
+ * @param   fPathOnly   Whether to only process the path and leave the filename
+ *                      as passed in.
+ */
+RTDECL(int) RTNtPathExpand8dot3Path(struct _UNICODE_STRING *pUniStr, bool fPathOnly);
 
 
Index: /trunk/src/VBox/HostDrivers/Support/Makefile.kmk
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/Makefile.kmk	(revision 60479)
+++ /trunk/src/VBox/HostDrivers/Support/Makefile.kmk	(revision 60480)
@@ -308,5 +308,4 @@
 	$(VBOX_PATH_RUNTIME_SRC)/common/path/RTPathChangeToUnixSlashes.cpp \
 	$(VBOX_PATH_RUNTIME_SRC)/common/path/RTPathExt.cpp \
-	$(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrPrintHexBytes.cpp \
 	$(VBOX_PATH_RUNTIME_SRC)/common/string/RTUtf16PrintHexBytes.cpp \
 	$(VBOX_PATH_RUNTIME_SRC)/common/string/RTUtf16ICmpAscii.cpp \
@@ -375,4 +374,6 @@
  	win/SUPR3HardenedNoCrt-win.cpp \
  	$(VBOX_PATH_RUNTIME_SRC)/nt/RTErrConvertFromNtStatus.cpp \
+ 	$(VBOX_PATH_RUNTIME_SRC)/nt/RTNtPathFindPossible8dot3Name.cpp \
+ 	$(VBOX_PATH_RUNTIME_SRC)/nt/RTNtPathExpand8dot3Path.cpp \
  	$(VBOX_PATH_RUNTIME_SRC)/r3/nt/pathint-nt.cpp \
  	$(VBOX_PATH_RUNTIME_SRC)/win/RTErrConvertFromWin32.cpp \
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h	(revision 60479)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h	(revision 60480)
@@ -76,6 +76,4 @@
 DECLHIDDEN(int)     supHardNtVpThread(HANDLE hProcess, HANDLE hThread, PRTERRINFO pErrInfo);
 DECLHIDDEN(int)     supHardNtVpDebugger(HANDLE hProcess, PRTERRINFO pErrInfo);
-DECLHIDDEN(PRTUTF16) supHardNtVpIsPossible8dot3Path(PCRTUTF16 pwszPath);
-DECLHIDDEN(void)    supHardNtVpFix8dot3Path(PUNICODE_STRING pUniStr, bool fPathOnly);
 
 DECLHIDDEN(bool)    supHardViUtf16PathIsEqualEx(PCRTUTF16 pawcLeft, size_t cwcLeft, const char *pszRight);
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp	(revision 60479)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp	(revision 60480)
@@ -1090,170 +1090,4 @@
 
 /**
- * Checks whether the path could be containing alternative 8.3 names generated
- * by NTFS, FAT, or other similar file systems.
- *
- * @returns Pointer to the first component that might be an 8.3 name, NULL if
- *          not 8.3 path.
- * @param   pwszPath        The path to check.
- *
- * @remarks This is making bad ASSUMPTION wrt to the naming scheme of 8.3 names,
- *          however, non-tilde 8.3 aliases are probably rare enough to not be
- *          worth all the extra code necessary to open each path component and
- *          check if we've got the short name or not.
- */
-DECLHIDDEN(PRTUTF16) supHardNtVpIsPossible8dot3Path(PCRTUTF16 pwszPath)
-{
-    PCRTUTF16 pwszName = pwszPath;
-    for (;;)
-    {
-        RTUTF16 wc = *pwszPath++;
-        if (wc == '~')
-        {
-            /* Could check more here before jumping to conclusions... */
-            if (pwszPath - pwszName <= 8+1+3)
-                return (PRTUTF16)pwszName;
-        }
-        else if (wc == '\\' || wc == '/' || wc == ':')
-            pwszName = pwszPath;
-        else if (wc == 0)
-            break;
-    }
-    return NULL;
-}
-
-
-/**
- * Fixes up a path possibly containing one or more alternative 8-dot-3 style
- * components.
- *
- * The path is fixed up in place.  Errors are ignored.
- *
- * @param   pUniStr     The path to fix up. MaximumLength is the max buffer
- *                      length.
- * @param   fPathOnly   Whether to only process the path and leave the filename
- *                      as passed in.
- */
-DECLHIDDEN(void) supHardNtVpFix8dot3Path(PUNICODE_STRING pUniStr, bool fPathOnly)
-{
-    /*
-     * We could use FileNormalizedNameInformation here and slap the volume device
-     * path in front of the result, but it's only supported since windows 8.0
-     * according to some docs... So we expand all supicious names.
-     */
-    union fix8dot3tmp
-    {
-        FILE_BOTH_DIR_INFORMATION Info;
-        uint8_t abBuffer[sizeof(FILE_BOTH_DIR_INFORMATION) + 2048 * sizeof(WCHAR)];
-    } *puBuf = NULL;
-
-
-    PRTUTF16 pwszFix = pUniStr->Buffer;
-    while (*pwszFix)
-    {
-        pwszFix = supHardNtVpIsPossible8dot3Path(pwszFix);
-        if (pwszFix == NULL)
-            break;
-
-        RTUTF16 wc;
-        PRTUTF16 pwszFixEnd = pwszFix;
-        while ((wc = *pwszFixEnd) != '\0' && wc != '\\' && wc != '/')
-            pwszFixEnd++;
-        if (wc == '\0' && fPathOnly)
-            break;
-
-        if (!puBuf)
-        {
-            puBuf = (union fix8dot3tmp *)RTMemAlloc(sizeof(*puBuf));
-            if (!puBuf)
-                break;
-        }
-
-        RTUTF16 const wcSaved = *pwszFix;
-        *pwszFix = '\0';                     /* paranoia. */
-
-        UNICODE_STRING      NtDir;
-        NtDir.Buffer = pUniStr->Buffer;
-        NtDir.Length = NtDir.MaximumLength = (USHORT)((pwszFix - pUniStr->Buffer) * sizeof(WCHAR));
-
-        HANDLE              hDir  = RTNT_INVALID_HANDLE_VALUE;
-        IO_STATUS_BLOCK     Ios   = RTNT_IO_STATUS_BLOCK_INITIALIZER;
-
-        OBJECT_ATTRIBUTES   ObjAttr;
-        InitializeObjectAttributes(&ObjAttr, &NtDir, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
-#ifdef IN_RING0
-        ObjAttr.Attributes |= OBJ_KERNEL_HANDLE;
-#endif
-
-        NTSTATUS rcNt = NtCreateFile(&hDir,
-                                     FILE_READ_DATA | SYNCHRONIZE,
-                                     &ObjAttr,
-                                     &Ios,
-                                     NULL /* Allocation Size*/,
-                                     FILE_ATTRIBUTE_NORMAL,
-                                     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-                                     FILE_OPEN,
-                                     FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
-                                     NULL /*EaBuffer*/,
-                                     0 /*EaLength*/);
-        *pwszFix = wcSaved;
-        if (NT_SUCCESS(rcNt))
-        {
-            RT_ZERO(*puBuf);
-
-            IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
-            UNICODE_STRING  NtFilterStr;
-            NtFilterStr.Buffer = pwszFix;
-            NtFilterStr.Length = (USHORT)((uintptr_t)pwszFixEnd - (uintptr_t)pwszFix);
-            NtFilterStr.MaximumLength = NtFilterStr.Length;
-            rcNt = NtQueryDirectoryFile(hDir,
-                                        NULL /* Event */,
-                                        NULL /* ApcRoutine */,
-                                        NULL /* ApcContext */,
-                                        &Ios,
-                                        puBuf,
-                                        sizeof(*puBuf) - sizeof(WCHAR),
-                                        FileBothDirectoryInformation,
-                                        FALSE /*ReturnSingleEntry*/,
-                                        &NtFilterStr,
-                                        FALSE /*RestartScan */);
-            if (NT_SUCCESS(rcNt) && puBuf->Info.NextEntryOffset == 0) /* There shall only be one entry matching... */
-            {
-                uint32_t offName = puBuf->Info.FileNameLength / sizeof(WCHAR);
-                while (offName > 0  && puBuf->Info.FileName[offName - 1] != '\\' && puBuf->Info.FileName[offName - 1] != '/')
-                    offName--;
-                uint32_t cwcNameNew = (puBuf->Info.FileNameLength / sizeof(WCHAR)) - offName;
-                uint32_t cwcNameOld = (uint32_t)(pwszFixEnd - pwszFix);
-
-                if (cwcNameOld == cwcNameNew)
-                    memcpy(pwszFix, &puBuf->Info.FileName[offName], cwcNameNew * sizeof(WCHAR));
-                else if (   pUniStr->Length + cwcNameNew * sizeof(WCHAR) - cwcNameOld * sizeof(WCHAR) + sizeof(WCHAR)
-                         <= pUniStr->MaximumLength)
-                {
-                    size_t cwcLeft = pUniStr->Length - (pwszFixEnd - pUniStr->Buffer) * sizeof(WCHAR) + sizeof(WCHAR);
-                    memmove(&pwszFix[cwcNameNew], pwszFixEnd, cwcLeft * sizeof(WCHAR));
-                    pUniStr->Length -= (USHORT)(cwcNameOld * sizeof(WCHAR));
-                    pUniStr->Length += (USHORT)(cwcNameNew * sizeof(WCHAR));
-                    pwszFixEnd      -= cwcNameOld;
-                    pwszFixEnd      -= cwcNameNew;
-                    memcpy(pwszFix, &puBuf->Info.FileName[offName], cwcNameNew * sizeof(WCHAR));
-                }
-                /* else: ignore overflow. */
-            }
-            /* else: ignore failure. */
-
-            NtClose(hDir);
-        }
-
-        /* Advance */
-        pwszFix = pwszFixEnd;
-    }
-
-    if (puBuf)
-        RTMemFree(puBuf);
-}
-
-
-
-/**
  * Matches two UNICODE_STRING structures in a case sensitive fashion.
  *
@@ -1316,5 +1150,5 @@
      */
     PUNICODE_STRING pLongName = &pImage->Name.UniStr;
-    if (supHardNtVpIsPossible8dot3Path(pLongName->Buffer))
+    if (RTNtPathFindPossible8dot3Name(pLongName->Buffer))
     {
         AssertCompile(sizeof(pThis->abMemory) > sizeof(pImage->Name));
@@ -1325,5 +1159,5 @@
         memcpy(pTmp->Buffer, pLongName->Buffer, pLongName->Length + sizeof(RTUTF16));
 
-        supHardNtVpFix8dot3Path(pTmp, false /*fPathOnly*/);
+        RTNtPathExpand8dot3Path(pTmp, false /*fPathOnly*/);
         Assert(pTmp->Buffer[pTmp->Length / sizeof(RTUTF16)] == '\0');
 
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 60479)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 60480)
@@ -1225,8 +1225,11 @@
     }
 
-    if (supHardNtVpIsPossible8dot3Path(uBuf.UniStr.Buffer))
+    if (!RTNtPathFindPossible8dot3Name(uBuf.UniStr.Buffer))
+        cbNameBuf += sizeof(WCHAR);
+    else
     {
         uBuf.UniStr.MaximumLength = sizeof(uBuf) - 128;
-        supHardNtVpFix8dot3Path(&uBuf.UniStr, true /*fPathOnly*/);
+        RTNtPathExpand8dot3Path(&uBuf.UniStr, true /*fPathOnly*/);
+        cbNameBuf = (uintptr_t)uBuf.UniStr.Buffer + uBuf.UniStr.Length + sizeof(WCHAR) - (uintptr_t)&uBuf.abBuffer[0];
     }
 
Index: /trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/Makefile.kmk	(revision 60479)
+++ /trunk/src/VBox/Runtime/Makefile.kmk	(revision 60480)
@@ -784,4 +784,6 @@
 	generic/RTThreadGetNativeState-generic.cpp \
 	nt/RTErrConvertFromNtStatus.cpp \
+ 	nt/RTNtPathExpand8dot3Path.cpp \
+ 	nt/RTNtPathFindPossible8dot3Name.cpp \
  	r3/nt/fs-nt.cpp \
  	r3/nt/pathint-nt.cpp \
@@ -2171,4 +2173,6 @@
 	generic/RTMpGetCoreCount-generic.cpp \
 	nt/RTErrConvertFromNtStatus.cpp \
+	nt/RTNtPathExpand8dot3Path.cpp \
+	nt/RTNtPathFindPossible8dot3Name.cpp \
 	r0drv/generic/threadctxhooks-r0drv-generic.cpp \
 	r0drv/alloc-ef-r0drv.cpp \
Index: /trunk/src/VBox/Runtime/nt/RTNtPathExpand8dot3Path.cpp
===================================================================
--- /trunk/src/VBox/Runtime/nt/RTNtPathExpand8dot3Path.cpp	(revision 60480)
+++ /trunk/src/VBox/Runtime/nt/RTNtPathExpand8dot3Path.cpp	(revision 60480)
@@ -0,0 +1,190 @@
+/* $Id$ */
+/** @file
+ * IPRT - Native NT, RTNtPathExpand8dot3Path.
+ */
+
+/*
+ * Copyright (C) 2006-2016 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_FS
+#ifdef IN_SUP_HARDENED_R3
+# include <iprt/nt/nt-and-windows.h>
+#else
+# include <iprt/nt/nt.h>
+#endif
+
+#include <iprt/mem.h>
+#include <iprt/string.h>
+
+
+
+/**
+ * Fixes up a path possibly containing one or more alternative 8-dot-3 style
+ * components.
+ *
+ * The path is fixed up in place.  Errors are ignored.
+ *
+ * @returns VINF_SUCCESS if it all went smoothly, informational status codes
+ *          indicating the nature of last problem we ran into.
+ *
+ * @param   pUniStr     The path to fix up. MaximumLength is the max buffer
+ *                      length.
+ * @param   fPathOnly   Whether to only process the path and leave the filename
+ *                      as passed in.
+ */
+RTDECL(int) RTNtPathExpand8dot3Path(PUNICODE_STRING pUniStr, bool fPathOnly)
+{
+    int rc = VINF_SUCCESS;
+
+    /*
+     * We could use FileNormalizedNameInformation here and slap the volume device
+     * path in front of the result, but it's only supported since windows 8.0
+     * according to some docs... So we expand all supicious names.
+     */
+    union fix8dot3tmp
+    {
+        FILE_BOTH_DIR_INFORMATION Info;
+        uint8_t abBuffer[sizeof(FILE_BOTH_DIR_INFORMATION) + 2048 * sizeof(WCHAR)];
+    } *puBuf = NULL;
+
+
+    PRTUTF16 pwszFix = pUniStr->Buffer;
+    while (*pwszFix)
+    {
+        pwszFix = RTNtPathFindPossible8dot3Name(pwszFix);
+        if (pwszFix == NULL)
+            break;
+
+        RTUTF16 wc;
+        PRTUTF16 pwszFixEnd = pwszFix;
+        while ((wc = *pwszFixEnd) != '\0' && wc != '\\' && wc != '/')
+            pwszFixEnd++;
+        if (wc == '\0' && fPathOnly)
+            break;
+
+        if (!puBuf)
+        {
+            puBuf = (union fix8dot3tmp *)RTMemAlloc(sizeof(*puBuf));
+            if (!puBuf)
+                break;
+        }
+
+        RTUTF16 const wcSaved = *pwszFix;
+        *pwszFix = '\0';                     /* paranoia. */
+
+        UNICODE_STRING      NtDir;
+        NtDir.Buffer = pUniStr->Buffer;
+        NtDir.Length = NtDir.MaximumLength = (USHORT)((pwszFix - pUniStr->Buffer) * sizeof(WCHAR));
+
+        HANDLE              hDir  = RTNT_INVALID_HANDLE_VALUE;
+        IO_STATUS_BLOCK     Ios   = RTNT_IO_STATUS_BLOCK_INITIALIZER;
+
+        OBJECT_ATTRIBUTES   ObjAttr;
+        InitializeObjectAttributes(&ObjAttr, &NtDir, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
+#ifdef IN_RING0
+        ObjAttr.Attributes |= OBJ_KERNEL_HANDLE;
+#endif
+
+        NTSTATUS rcNt = NtCreateFile(&hDir,
+                                     FILE_READ_DATA | SYNCHRONIZE,
+                                     &ObjAttr,
+                                     &Ios,
+                                     NULL /* Allocation Size*/,
+                                     FILE_ATTRIBUTE_NORMAL,
+                                     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                                     FILE_OPEN,
+                                     FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
+                                     NULL /*EaBuffer*/,
+                                     0 /*EaLength*/);
+        *pwszFix = wcSaved;
+        if (NT_SUCCESS(rcNt))
+        {
+            RT_ZERO(*puBuf);
+
+            IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
+            UNICODE_STRING  NtFilterStr;
+            NtFilterStr.Buffer = pwszFix;
+            NtFilterStr.Length = (USHORT)((uintptr_t)pwszFixEnd - (uintptr_t)pwszFix);
+            NtFilterStr.MaximumLength = NtFilterStr.Length;
+            rcNt = NtQueryDirectoryFile(hDir,
+                                        NULL /* Event */,
+                                        NULL /* ApcRoutine */,
+                                        NULL /* ApcContext */,
+                                        &Ios,
+                                        puBuf,
+                                        sizeof(*puBuf) - sizeof(WCHAR),
+                                        FileBothDirectoryInformation,
+                                        FALSE /*ReturnSingleEntry*/,
+                                        &NtFilterStr,
+                                        FALSE /*RestartScan */);
+            if (NT_SUCCESS(rcNt) && puBuf->Info.NextEntryOffset == 0) /* There shall only be one entry matching... */
+            {
+                uint32_t offName = puBuf->Info.FileNameLength / sizeof(WCHAR);
+                while (offName > 0  && puBuf->Info.FileName[offName - 1] != '\\' && puBuf->Info.FileName[offName - 1] != '/')
+                    offName--;
+                uint32_t cwcNameNew = (puBuf->Info.FileNameLength / sizeof(WCHAR)) - offName;
+                uint32_t cwcNameOld = (uint32_t)(pwszFixEnd - pwszFix);
+
+                if (cwcNameOld == cwcNameNew)
+                    memcpy(pwszFix, &puBuf->Info.FileName[offName], cwcNameNew * sizeof(WCHAR));
+                else if (   pUniStr->Length + cwcNameNew * sizeof(WCHAR) - cwcNameOld * sizeof(WCHAR) + sizeof(WCHAR)
+                         <= pUniStr->MaximumLength)
+                {
+                    size_t cwcLeft = pUniStr->Length - (pwszFixEnd - pUniStr->Buffer) * sizeof(WCHAR) + sizeof(WCHAR);
+                    memmove(&pwszFix[cwcNameNew], pwszFixEnd, cwcLeft * sizeof(WCHAR));
+                    pUniStr->Length -= (USHORT)(cwcNameOld * sizeof(WCHAR));
+                    pUniStr->Length += (USHORT)(cwcNameNew * sizeof(WCHAR));
+                    pwszFixEnd      -= cwcNameOld;
+                    pwszFixEnd      -= cwcNameNew;
+                    memcpy(pwszFix, &puBuf->Info.FileName[offName], cwcNameNew * sizeof(WCHAR));
+                }
+                else
+                    rc = VINF_BUFFER_OVERFLOW;
+            }
+            else if (NT_SUCCESS(rcNt))
+                rc = -VERR_DUPLICATE;
+            else
+            {
+                rc = -RTErrConvertFromNtStatus(rcNt);
+                if (rc < 0)
+                    rc = -rc;
+            }
+
+            NtClose(hDir);
+        }
+
+        /* Advance */
+        pwszFix = pwszFixEnd;
+    }
+
+    if (puBuf)
+        RTMemFree(puBuf);
+
+    if (pUniStr->Length < pUniStr->MaximumLength)
+        pUniStr->Buffer[pUniStr->Length / sizeof(WCHAR)] = '\0';
+
+    return rc;
+}
+
