Index: /trunk/src/VBox/Runtime/r3/nt/dirrel-r3-nt.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/nt/dirrel-r3-nt.cpp	(revision 71843)
+++ /trunk/src/VBox/Runtime/r3/nt/dirrel-r3-nt.cpp	(revision 71844)
@@ -187,4 +187,46 @@
 
 
+/**
+ * Helper for cooking up a path string for rtDirOpenRelativeOrHandle.
+ *
+ * @returns IPRT status code.
+ * @param   pszDst              The destination buffer.
+ * @param   cbDst               The size of the destination buffer.
+ * @param   pThis               The directory this is relative to.
+ * @param   pNtPath             The NT path with a possibly relative path.
+ * @param   fRelative           Whether @a pNtPath is relative or not.
+ * @param   pszPath             The input path.
+ */
+static int rtDirRelJoinPathForDirOpen(char *pszDst, size_t cbDst, PRTDIRINTERNAL pThis,
+                                      PUNICODE_STRING pNtPath, bool fRelative, const char *pszPath)
+{
+    int rc;
+    if (fRelative)
+    {
+        size_t cchRel = 0;
+        rc = RTUtf16CalcUtf8LenEx(pNtPath->Buffer, pNtPath->Length / sizeof(RTUTF16), &cchRel);
+        AssertRC(rc);
+        if (RT_SUCCESS(rc))
+        {
+            if (pThis->cchPath + cchRel < cbDst)
+            {
+                size_t cchBase = pThis->cchPath;
+                memcpy(pszDst, pThis->pszPath, cchBase);
+                pszDst += cchBase;
+                cbDst  -= cchBase;
+                rc = RTUtf16ToUtf8Ex(pNtPath->Buffer, pNtPath->Length / sizeof(RTUTF16), &pszDst, cbDst, NULL);
+            }
+            else
+                rc = VERR_FILENAME_TOO_LONG;
+        }
+    }
+    else
+    {
+        /** @todo would be better to convert pNtName to DOS/WIN path here,
+         *        as it is absolute and doesn't need stuff resolved. */
+        rc = RTPathJoin(pszDst, cbDst, pThis->pszPath, pszPath);
+    }
+    return rc;
+}
 
 RTDECL(int) RTDirRelDirOpen(RTDIR hDir, const char *pszDir, RTDIR *phDir)
@@ -210,5 +252,9 @@
     if (RT_SUCCESS(rc))
     {
-        rc = rtDirOpenRelativeOrHandle(phDir, pszDirAndFilter, enmFilter, fFlags, (uintptr_t)hRoot, &NtName);
+        char szAbsDirAndFilter[RTPATH_MAX];
+        rc = rtDirRelJoinPathForDirOpen(szAbsDirAndFilter, sizeof(szAbsDirAndFilter), pThis,
+                                        &NtName, hRoot != NULL, pszDirAndFilter);
+        if (RT_SUCCESS(rc))
+            rc = rtDirOpenRelativeOrHandle(phDir, szAbsDirAndFilter, enmFilter, fFlags, (uintptr_t)hRoot, &NtName);
         RTNtPathFree(&NtName, NULL);
     }
@@ -294,6 +340,10 @@
             else
             {
-                rc = rtDirOpenRelativeOrHandle(phSubDir, pszRelPath, RTDIRFILTER_NONE, 0 /*fFlags*/,
-                                               (uintptr_t)hNewDir, NULL /*pvNativeRelative*/);
+                char szAbsDirAndFilter[RTPATH_MAX];
+                rc = rtDirRelJoinPathForDirOpen(szAbsDirAndFilter, sizeof(szAbsDirAndFilter), pThis,
+                                                &NtName, hRoot != NULL, pszRelPath);
+                if (RT_SUCCESS(rc))
+                    rc = rtDirOpenRelativeOrHandle(phSubDir, pszRelPath, RTDIRFILTER_NONE, 0 /*fFlags*/,
+                                                   (uintptr_t)hNewDir, NULL /*pvNativeRelative*/);
                 if (RT_FAILURE(rc))
                     NtClose(hNewDir);
