Index: trunk/src/emx/src/lib/sys/b_fs.h
===================================================================
--- trunk/src/emx/src/lib/sys/b_fs.h	(revision 1946)
+++ trunk/src/emx/src/lib/sys/b_fs.h	(revision 1947)
@@ -119,17 +119,21 @@
  * @{ */
 /** Resolves the path up to but not including the last component. */
-#define BACKFS_FLAGS_RESOLVE_PARENT         0
+#define BACKFS_FLAGS_RESOLVE_PARENT             0x00
 /** Resolves and verfies the entire path. */
-#define BACKFS_FLAGS_RESOLVE_FULL           1
+#define BACKFS_FLAGS_RESOLVE_FULL               0x01
+/** Resolves and verfies the entire path, but don't resolve any symlink in the last component. */
+#define BACKFS_FLAGS_RESOLVE_FULL_SYMLINK       0x02
+/** Internal, use BACKFS_FLAGS_RESOLVE_FULL_MAYBE. */
+#define BACKFS_FLAGS_RESOLVE_FULL_MAYBE_        0x08
 /** Resolves and verfies the entire path but it's ok if the last component doesn't exist. */
-#define BACKFS_FLAGS_RESOLVE_FULL_MAYBE     (BACKFS_FLAGS_RESOLVE_FULL | BACKFS_FLAGS_RESOLVE_FULL_MAYBE_)
-/** Internal, use BACKFS_FLAGS_RESOLVE_FULL_MAYBE. */
-#define BACKFS_FLAGS_RESOLVE_FULL_MAYBE_    2
+#define BACKFS_FLAGS_RESOLVE_FULL_MAYBE         (BACKFS_FLAGS_RESOLVE_FULL_MAYBE_ | BACKFS_FLAGS_RESOLVE_FULL)
+/** Resolves and verfies the entire path but it's ok if the last component doesn't exist. */
+#define BACKFS_FLAGS_RESOLVE_FULL_SYMLINK_MAYBE (BACKFS_FLAGS_RESOLVE_FULL_MAYBE_ | BACKFS_FLAGS_RESOLVE_FULL_SYMLINK)
 /** The specified path is a directory. */
-#define BACKFS_FLAGS_RESOLVE_DIR            4
+#define BACKFS_FLAGS_RESOLVE_DIR                0x10
+/** Internal, use BACKFS_FLAGS_RESOLVE_DIR_MAYBE. */
+#define BACKFS_FLAGS_RESOLVE_DIR_MAYBE_         0x80
 /** The specified path maybe a directory. */
-#define BACKFS_FLAGS_RESOLVE_DIR_MAYBE      (BACKFS_FLAGS_RESOLVE_DIR | BACKFS_FLAGS_RESOLVE_DIR_MAYBE_)
-/** Internal, use BACKFS_FLAGS_RESOLVE_DIR_MAYBE. */
-#define BACKFS_FLAGS_RESOLVE_DIR_MAYBE_     8
+#define BACKFS_FLAGS_RESOLVE_DIR_MAYBE          (BACKFS_FLAGS_RESOLVE_DIR_MAYBE_ | BACKFS_FLAGS_RESOLVE_DIR)
 /** @} */
 
Index: trunk/src/emx/src/lib/sys/b_fsDirRemove.c
===================================================================
--- trunk/src/emx/src/lib/sys/b_fsDirRemove.c	(revision 1946)
+++ trunk/src/emx/src/lib/sys/b_fsDirRemove.c	(revision 1947)
@@ -58,5 +58,5 @@
      */
     char szNativePath[PATH_MAX];
-    int rc = __libc_back_fsResolve(pszPath, BACKFS_FLAGS_RESOLVE_PARENT | BACKFS_FLAGS_RESOLVE_DIR, &szNativePath[0], NULL);
+    int rc = __libc_back_fsResolve(pszPath, BACKFS_FLAGS_RESOLVE_FULL_SYMLINK | BACKFS_FLAGS_RESOLVE_DIR, &szNativePath[0], NULL);
     if (rc)
         LIBCLOG_RETURN_INT(rc);
Index: trunk/src/emx/src/lib/sys/b_fsRename.c
===================================================================
--- trunk/src/emx/src/lib/sys/b_fsRename.c	(revision 1946)
+++ trunk/src/emx/src/lib/sys/b_fsRename.c	(revision 1947)
@@ -66,5 +66,5 @@
      */
     char szNativePathOld[PATH_MAX];
-    int rc = __libc_back_fsResolve(pszPathOld, BACKFS_FLAGS_RESOLVE_PARENT | BACKFS_FLAGS_RESOLVE_DIR_MAYBE, &szNativePathOld[0], NULL);
+    int rc = __libc_back_fsResolve(pszPathOld, BACKFS_FLAGS_RESOLVE_FULL_SYMLINK | BACKFS_FLAGS_RESOLVE_DIR_MAYBE, &szNativePathOld[0], NULL);
     if (rc)
         LIBCLOG_RETURN_INT(rc);
Index: trunk/src/emx/src/lib/sys/b_fsSymlinkModeSet.c
===================================================================
--- trunk/src/emx/src/lib/sys/b_fsSymlinkModeSet.c	(revision 1946)
+++ trunk/src/emx/src/lib/sys/b_fsSymlinkModeSet.c	(revision 1947)
@@ -51,5 +51,5 @@
      */
     char szNativePath[PATH_MAX];
-    int rc = __libc_back_fsResolve(pszPath, BACKFS_FLAGS_RESOLVE_PARENT | BACKFS_FLAGS_RESOLVE_DIR_MAYBE, szNativePath, NULL);
+    int rc = __libc_back_fsResolve(pszPath, BACKFS_FLAGS_RESOLVE_FULL_SYMLINK | BACKFS_FLAGS_RESOLVE_DIR_MAYBE, szNativePath, NULL);
     if (!rc)
         rc = __libc_back_fsNativeFileModeSet(szNativePath, Mode);
Index: trunk/src/emx/src/lib/sys/b_fsSymlinkRead.c
===================================================================
--- trunk/src/emx/src/lib/sys/b_fsSymlinkRead.c	(revision 1946)
+++ trunk/src/emx/src/lib/sys/b_fsSymlinkRead.c	(revision 1947)
@@ -59,5 +59,5 @@
      */
     char szNativePath[PATH_MAX];
-    int rc = __libc_back_fsResolve(pszPath, BACKFS_FLAGS_RESOLVE_PARENT, &szNativePath[0], NULL);
+    int rc = __libc_back_fsResolve(pszPath, BACKFS_FLAGS_RESOLVE_FULL_SYMLINK, &szNativePath[0], NULL);
     if (!rc)
         rc = __libc_back_fsNativeSymlinkRead(szNativePath, pachBuf, cchBuf);
Index: trunk/src/emx/src/lib/sys/b_fsSymlinkStat.c
===================================================================
--- trunk/src/emx/src/lib/sys/b_fsSymlinkStat.c	(revision 1946)
+++ trunk/src/emx/src/lib/sys/b_fsSymlinkStat.c	(revision 1947)
@@ -53,5 +53,5 @@
      */
     char szNativePath[PATH_MAX];
-    int rc = __libc_back_fsResolve(pszPath, BACKFS_FLAGS_RESOLVE_PARENT | BACKFS_FLAGS_RESOLVE_DIR_MAYBE, szNativePath, NULL);
+    int rc = __libc_back_fsResolve(pszPath, BACKFS_FLAGS_RESOLVE_FULL_SYMLINK | BACKFS_FLAGS_RESOLVE_DIR_MAYBE, szNativePath, NULL);
     if (!rc)
         rc = __libc_back_fsNativeFileStat(szNativePath, pStat);
Index: trunk/src/emx/src/lib/sys/b_fsUnlink.c
===================================================================
--- trunk/src/emx/src/lib/sys/b_fsUnlink.c	(revision 1946)
+++ trunk/src/emx/src/lib/sys/b_fsUnlink.c	(revision 1947)
@@ -65,5 +65,5 @@
      */
     char szNativePath[PATH_MAX];
-    int rc = __libc_back_fsResolve(pszPath, BACKFS_FLAGS_RESOLVE_PARENT | BACKFS_FLAGS_RESOLVE_DIR_MAYBE, &szNativePath[0], NULL);
+    int rc = __libc_back_fsResolve(pszPath, BACKFS_FLAGS_RESOLVE_FULL_SYMLINK | BACKFS_FLAGS_RESOLVE_DIR_MAYBE, &szNativePath[0], NULL);
     if (rc)
         LIBCLOG_RETURN_INT(rc);
Index: trunk/src/emx/src/lib/sys/fs.c
===================================================================
--- trunk/src/emx/src/lib/sys/fs.c	(revision 1946)
+++ trunk/src/emx/src/lib/sys/fs.c	(revision 1947)
@@ -187,4 +187,5 @@
 *******************************************************************************/
 static int fsResolveUnix(const char *pszUserPath, unsigned fFlags, char *pszNativePath, int *pfInUnixTree);
+static int fsResolveOS2(const char *pszUserPath, unsigned fFlags, char *pszNativePath, int *pfInUnixTree);
 static uint32_t crc32str(const char *psz);
 static uint32_t djb2(const char *str);
@@ -192,5 +193,5 @@
 
 
-
+#ifndef STANDALONE_TEST
 /**
  * Init the file system stuff.
@@ -365,4 +366,5 @@
 }
 
+#endif /*!STANDALONE_TEST*/
 
 /**
@@ -668,40 +670,6 @@
     if (!__libc_gfNoUnix)
         return fsResolveUnix(pszUserPath, fFlags, pszNativePath, pfInUnixTree);
-
-    /* __libc_back_fsResolveOS2(): */
-
-    LIBCLOG_ENTER("pszUserPath=%p:{%s} fFlags=%x pszNativePath=%p pfInUnixTree=%p\n",
-                  (void *)pszUserPath, pszUserPath, fFlags, (void *)pszNativePath, (void *)pfInUnixTree);
-
-    /*
-     * Apply rewrite rule.
-     */
-    int cch = __libc_PathRewrite(pszUserPath, pszNativePath, sizeof(pszNativePath));
-    if (cch < 0)
-        LIBCLOG_RETURN_INT(-EINVAL);
-    if (cch == 0)
-    {
-        cch = strlen(pszUserPath);
-        if (cch >= PATH_MAX)
-            LIBCLOG_RETURN_INT(-ENAMETOOLONG);
-        memcpy(pszNativePath, pszUserPath, cch + 1);
-    }
-
-    /*
-     * Convert slashes.
-     */
-    char *psz = strchr(pszNativePath, '/');
-    while (psz)
-    {
-        *psz++ = '\\';
-        psz = strchr(psz, '/');
-    }
-
-    /** @todo Validate the path? hopefully not necessary. */
-
-    if (pfInUnixTree)
-        *pfInUnixTree = 0;
-
-    LIBCLOG_RETURN_INT(0);
+    else
+        return fsResolveOS2(pszUserPath, fFlags, pszNativePath, pfInUnixTree);
 }
 
@@ -719,5 +687,5 @@
  * @param   pfInUnixTree    Where to store the result-in-unix-tree indicator. Optional.
  */
-int fsResolveUnix(const char *pszUserPath, unsigned fFlags, char *pszNativePath, int *pfInUnixTree)
+static int fsResolveUnix(const char *pszUserPath, unsigned fFlags, char *pszNativePath, int *pfInUnixTree)
 {
     LIBCLOG_ENTER("pszUserPath=%p:{%s} pszNativePath=%p *pfInUnixTree=%p\n",
@@ -744,5 +712,5 @@
             fInUnixTree = __libc_gfInUnixTree;
         }
-        else if (pszUserPath[0] && pszUserPath[1] == ':'
+        else if (   pszUserPath[0] && pszUserPath[1] == ':'
                  && (pszUserPath[2] == '/' || pszUserPath[2] == '\\'))
         {
@@ -898,16 +866,34 @@
 
         /*
-         * Expand unix root.
+         * Expand unix root or add missing drive letter.
          */
-        if (szTmp[0] == '/' && szTmp[1] != '/' && __libc_gcchUnixRoot)
-        {
-            iRoot = __libc_gcchUnixRoot;
-            if (cchTmp + iRoot >= PATH_MAX)
-            {
-                rcRet = -ENAMETOOLONG;
-                break;
-            }
+        if (szTmp[0] == '/' && szTmp[1] != '/')
+        {
             memcpy(pachBuffer, szTmp, cchTmp + 1);
-            memcpy(szTmp, __libc_gszUnixRoot, iRoot);
+            if (__libc_gcchUnixRoot)
+            {
+                iRoot = __libc_gcchUnixRoot;
+                if (cchTmp + iRoot >= PATH_MAX)
+                {
+                    rcRet = -ENAMETOOLONG;
+                    break;
+                }
+                memcpy(szTmp, __libc_gszUnixRoot, iRoot);
+                fInUnixTree = 1;
+            }
+            else
+            {
+                iRoot = 2;
+                ULONG   ulDisk = 0;
+                ULONG   ul;
+                DosQueryCurrentDisk(&ulDisk, &ul);
+                if (cchTmp + iRoot >= PATH_MAX)
+                {
+                    rcRet = -ENAMETOOLONG;
+                    break;
+                }
+                szTmp[0] = ulDisk + 'A' - 1;
+                szTmp[1] = ':';
+            }
             if (cchTmp != 1 || iRoot <= 2)
                 memcpy(&szTmp[iRoot], pachBuffer, cchTmp + 1);
@@ -915,6 +901,4 @@
                 szTmp[iRoot] = '\0';
             cchTmp += iRoot;
-
-            fInUnixTree = 1;
         }
 
@@ -962,4 +946,8 @@
         else
         {
+            /* drive letters are always uppercase! (inode dev number req) */
+            LIBC_ASSERT(szTmp[1] == ':');
+            if (szTmp[0] >= 'a' && szTmp[0] <= 'z')
+                szTmp[0] -= 'a' - 'A';
             pszPrev = &szTmp[iRoot + 1];
             psz = strchr(pszPrev, '/');
@@ -968,5 +956,5 @@
         /* If only one component, we'll check if the fVerifyLast was requested. */
         if (    !psz
-            &&  (fFlags & BACKFS_FLAGS_RESOLVE_FULL)
+            &&  (fFlags & (BACKFS_FLAGS_RESOLVE_FULL | BACKFS_FLAGS_RESOLVE_FULL_SYMLINK))
             &&  *pszPrev)
             psz = strchr(szTmp, '\0');
@@ -1014,5 +1002,5 @@
                     else
                     {
-                        if (!(fFlags & BACKFS_FLAGS_RESOLVE_FULL))
+                        if (!(fFlags & (BACKFS_FLAGS_RESOLVE_FULL | BACKFS_FLAGS_RESOLVE_FULL_SYMLINK)))
                         {
                             rcRet = 0;
@@ -1038,17 +1026,34 @@
              * Find the correct name and to check if it is a directory or not.
              * This'll of course also provide proper verification of the path too. :-)
+             *
+             * (This is a little bit messed up since we'll have to use wildcard for
+             * getting the caseing resolved.)
              */
+            LIBC_ASSERT(psz - szTmp == cchTmp);
             PFILEFINDBUF4 pFindBuf = (PFILEFINDBUF4)pachBuffer;
             ULONG cFiles = 1;
+            char chNext = psz[1];
+            psz[0] = '?';
+            psz[1] = '\0';
             int rc = DosFindFirst((PCSZ)&szTmp[0], &hDir, FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED,
                                   pFindBuf, SIZEOF_ACHBUFFER, &cFiles, FIL_QUERYEASIZE);
+            psz[0] = '\0';
+            psz[1] = chNext;
             if (rc || cFiles == 0)
             {
-                LIBCLOG_MSG("DosFindFirst('%s',,,,,) -> %d resolving '%s'\n", szTmp, rc, pszUserPathIn);
+                hDir = HDIR_CREATE;
+            }
+            while (!rc && cFiles == 1 && pFindBuf->cchName != psz - pszPrev)
+                rc = DosFindNext(hDir, pFindBuf, SIZEOF_ACHBUFFER, &cFiles);
+            if (rc || cFiles == 0)
+            {
+                LIBCLOG_MSG("DosFindFirst/Next('%s',,,,,) -> %d resolving '%s'\n", szTmp, rc, pszUserPathIn);
                 if ((fFlags & BACKFS_FLAGS_RESOLVE_FULL_MAYBE_) && !chSlash)
+                {
+                    *psz = chSlash;
                     rcRet = 0;
+                }
                 else
                     rcRet = rc == ERROR_FILE_NOT_FOUND && chSlash ? -ENOENT : -__libc_native2errno(rc);
-                hDir = HDIR_CREATE;
                 break;
             }
@@ -1057,5 +1062,5 @@
 
             /*
-             * Try querying the symlink EA value.
+             * Try querying the symlink EA value
              * (This operation will reuse the achBuffer overwriting the pFindBuf data!)
              *
@@ -1065,5 +1070,7 @@
              * is rather clumsily laid out. So, I decided not to try my luck on it.
              */
-            if (pFindBuf->cbList > sizeof(USHORT) * 2 + 1)
+            if (    pFindBuf->cbList > sizeof(USHORT) * 2 + 1
+                &&  (   (fFlags & BACKFS_FLAGS_RESOLVE_FULL)
+                     || chSlash))
             {
                 EAOP2   EaOp;
@@ -1163,5 +1170,5 @@
                             else
                             {
-                                if (!(fFlags & BACKFS_FLAGS_RESOLVE_FULL))
+                                if (!(fFlags & (BACKFS_FLAGS_RESOLVE_FULL | BACKFS_FLAGS_RESOLVE_FULL_SYMLINK)))
                                 {
                                     rcRet = 0;
@@ -1201,5 +1208,5 @@
                 if (!*psz)
                 {
-                    if (!(fFlags & BACKFS_FLAGS_RESOLVE_FULL))
+                    if (!(fFlags & (BACKFS_FLAGS_RESOLVE_FULL | BACKFS_FLAGS_RESOLVE_FULL_SYMLINK)))
                     {
                         rcRet = 0;
@@ -1244,4 +1251,56 @@
     pszUserPathIn = pszUserPathIn;
 }
+
+
+/**
+ * Resolves and verifies the user path to a native path.
+ *
+ * @returns 0 on success.
+ * @returns -1 and errno on failure.
+ * @param   pszUserPath     The user path.
+ * @parm    fFlags          Flags controlling the operation of the function.
+ *                          See the BACKFS_FLAGS_* defines.
+ * @param   pszNativePath   Where to store the native path. This buffer is at
+ *                          least PATH_MAX bytes big.
+ * @param   pfInUnixTree    Where to store the result-in-unix-tree indicator. Optional.
+ */
+static int fsResolveOS2(const char *pszUserPath, unsigned fFlags, char *pszNativePath, int *pfInUnixTree)
+{
+    LIBCLOG_ENTER("pszUserPath=%p:{%s} fFlags=%x pszNativePath=%p pfInUnixTree=%p\n",
+                  (void *)pszUserPath, pszUserPath, fFlags, (void *)pszNativePath, (void *)pfInUnixTree);
+
+    /*
+     * Apply rewrite rule.
+     */
+    int cch = __libc_PathRewrite(pszUserPath, pszNativePath, sizeof(pszNativePath));
+    if (cch < 0)
+        LIBCLOG_RETURN_INT(-EINVAL);
+    if (cch == 0)
+    {
+        cch = strlen(pszUserPath);
+        if (cch >= PATH_MAX)
+            LIBCLOG_RETURN_INT(-ENAMETOOLONG);
+        memcpy(pszNativePath, pszUserPath, cch + 1);
+    }
+
+    /*
+     * Convert slashes.
+     */
+    char *psz = strchr(pszNativePath, '/');
+    while (psz)
+    {
+        *psz++ = '\\';
+        psz = strchr(psz, '/');
+    }
+
+    /** @todo Validate the path? hopefully not necessary. */
+
+    if (pfInUnixTree)
+        *pfInUnixTree = 0;
+
+    LIBCLOG_RETURN_INT(0);
+}
+
+
 
 
