Beispiel #1
0
        public static string GetShortestAbsolutePath(string strPath)
        {
            if (strPath == null)
            {
                throw new ArgumentNullException("strPath");
            }
            if (strPath.Length == 0)
            {
                return(string.Empty);
            }

            // Path.GetFullPath is incompatible with UNC paths traversing over
            // different server shares (which are created by PathRelativePathTo);
            // we need to build the absolute path on our own...
            if (IsUncPath(strPath))
            {
                char   chSep = strPath[0];
                char[] vSep  = ((chSep == '/') ? (new char[] { '/' }) :
                                (new char[] { '\\', '/' }));

                List <string> l = new List <string>();
#if !KeePassLibSD
                string[] v = strPath.Split(vSep, StringSplitOptions.None);
#else
                string[] v = strPath.Split(vSep);
#endif
                Debug.Assert((v.Length >= 3) && (v[0].Length == 0) &&
                             (v[1].Length == 0));

                foreach (string strPart in v)
                {
                    if (strPart.Equals("."))
                    {
                        continue;
                    }
                    else if (strPart.Equals(".."))
                    {
                        if (l.Count > 0)
                        {
                            l.RemoveAt(l.Count - 1);
                        }
                        else
                        {
                            Debug.Assert(false);
                        }
                    }
                    else
                    {
                        l.Add(strPart);                      // Do not ignore zero length parts
                    }
                }

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < l.Count; ++i)
                {
                    // Don't test length of sb, might be 0 due to initial UNC seps
                    if (i > 0)
                    {
                        sb.Append(chSep);
                    }

                    sb.Append(l[i]);
                }

                return(sb.ToString());
            }

            string str;
            try { str = Path.GetFullPath(strPath); }
            catch (Exception) { Debug.Assert(false); return(strPath); }

            Debug.Assert((str.IndexOf("\\..\\") < 0) || NativeLib.IsUnix());
            foreach (char ch in UrlUtil.DirSepChars)
            {
                string strSep = new string(ch, 1);
                str = str.Replace(strSep + "." + strSep, strSep);
            }

            return(str);
        }
Beispiel #2
0
        public static string MakeRelativePath(string strBaseFile, string strTargetFile)
        {
            if (strBaseFile == null)
            {
                throw new ArgumentNullException("strBasePath");
            }
            if (strTargetFile == null)
            {
                throw new ArgumentNullException("strTargetPath");
            }
            if (strBaseFile.Length == 0)
            {
                return(strTargetFile);
            }
            if (strTargetFile.Length == 0)
            {
                return(string.Empty);
            }

            // Test whether on different Windows drives
            if ((strBaseFile.Length >= 3) && (strTargetFile.Length >= 3))
            {
                if ((strBaseFile[1] == ':') && (strTargetFile[1] == ':') &&
                    (strBaseFile[2] == '\\') && (strTargetFile[2] == '\\') &&
                    (strBaseFile[0] != strTargetFile[0]))
                {
                    return(strTargetFile);
                }
            }

#if (!KeePassLibSD && !KeePassUAP && !KPCLib)
            if (NativeLib.IsUnix())
            {
#endif
            bool bBaseUnc   = IsUncPath(strBaseFile);
            bool bTargetUnc = IsUncPath(strTargetFile);
            if ((!bBaseUnc && bTargetUnc) || (bBaseUnc && !bTargetUnc))
            {
                return(strTargetFile);
            }

            string strBase   = GetShortestAbsolutePath(strBaseFile);
            string strTarget = GetShortestAbsolutePath(strTargetFile);
            string[] vBase   = strBase.Split(UrlUtil.DirSepChars);
            string[] vTarget = strTarget.Split(UrlUtil.DirSepChars);

            int i = 0;
            while ((i < (vBase.Length - 1)) && (i < (vTarget.Length - 1)) &&
                   (vBase[i] == vTarget[i]))
            {
                ++i;
            }

            StringBuilder sbRel = new StringBuilder();
            for (int j = i; j < (vBase.Length - 1); ++j)
            {
                if (sbRel.Length > 0)
                {
                    sbRel.Append(UrlUtil.LocalDirSepChar);
                }
                sbRel.Append("..");
            }
            for (int k = i; k < vTarget.Length; ++k)
            {
                if (sbRel.Length > 0)
                {
                    sbRel.Append(UrlUtil.LocalDirSepChar);
                }
                sbRel.Append(vTarget[k]);
            }

            return(sbRel.ToString());

#if (!KeePassLibSD && !KeePassUAP && !KPCLib)
        }

        try                 // Windows
        {
            const int     nMaxPath = NativeMethods.MAX_PATH * 2;
            StringBuilder sb       = new StringBuilder(nMaxPath + 2);
            if (!NativeMethods.PathRelativePathTo(sb, strBaseFile, 0,
                                                  strTargetFile, 0))
            {
                return(strTargetFile);
            }

            string str = sb.ToString();
            while (str.StartsWith(".\\"))
            {
                str = str.Substring(2, str.Length - 2);
            }

            return(str);
        }
        catch (Exception) { Debug.Assert(false); }
        return(strTargetFile);
#endif
        }