Merge pull request #901 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / corlib / System.IO / Path.cs
index 0585986e83d623a64cfac6c625a2fa050c8486e7..217f5af3992db30931b28c8ca4d709857bfc226c 100644 (file)
@@ -289,6 +289,29 @@ namespace System.IO {
                        return fullpath;
                }
 
+               // http://msdn.microsoft.com/en-us/library/windows/desktop/aa364963%28v=vs.85%29.aspx
+               [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+               private static extern int GetFullPathName(string path, int numBufferChars, StringBuilder buffer, ref IntPtr lpFilePartOrNull); 
+
+               internal static string GetFullPathName(string path)
+               {
+                       const int MAX_PATH = 260;
+                       StringBuilder buffer = new StringBuilder(MAX_PATH);
+                       IntPtr ptr = IntPtr.Zero;
+                       int length = GetFullPathName(path, MAX_PATH, buffer, ref ptr);
+                       if (length == 0)
+                       {
+                               int error = Marshal.GetLastWin32Error();
+                               throw new IOException("Windows API call to GetFullPathName failed, Windows error code: " + error);
+                       }
+                       else if (length > MAX_PATH)
+                       {
+                               buffer = new StringBuilder(length);
+                               GetFullPathName(path, length, buffer, ref ptr);
+                       }
+                       return buffer.ToString();
+               }
+
                internal static string WindowsDriveAdjustment (string path)
                {
                        // two special cases to consider when a drive is specified
@@ -304,7 +327,7 @@ namespace System.IO {
                                if (current [0] == path [0])
                                        path = current; // we return it
                                else
-                                       path += '\\';
+                                       path = GetFullPathName(path); // we have to use the GetFullPathName Windows API
                        } else if ((path [2] != Path.DirectorySeparatorChar) && (path [2] != Path.AltDirectorySeparatorChar)) {
                                // second, the drive + a directory is specified *without* a separator between them (e.g. C:dir).
                                // If the current directory is on the specified drive...
@@ -312,8 +335,8 @@ namespace System.IO {
                                        // then specified directory is appended to the current drive directory
                                        path = Path.Combine (current, path.Substring (2, path.Length - 2));
                                } else {
-                                       // if not, then just pretend there was a separator (Path.Combine won't work in this case)
-                                       path = String.Concat (path.Substring (0, 2), DirectorySeparatorStr, path.Substring (2, path.Length - 2));
+                                       // we have to use the GetFullPathName Windows API
+                                       path = GetFullPathName(path);
                                }
                        }
                        return path;
@@ -718,6 +741,9 @@ namespace System.IO {
                                                else
                                                        return current + ret;
                                        }
+                               } else {
+                                       if (root != "" && ret.Length > 0 && ret [0] != '/')
+                                               ret = root + ret;
                                }
                                return ret;
                        }
@@ -761,13 +787,21 @@ namespace System.IO {
                        var ret = new StringBuilder ();
                        int pathsLen = paths.Length;
                        int slen;
+                       need_sep = false;
+
                        foreach (var s in paths) {
-                               need_sep = false;
                                if (s == null)
                                        throw new ArgumentNullException ("One of the paths contains a null value", "paths");
+                               if (s.Length == 0)
+                                       continue;
                                if (s.IndexOfAny (InvalidPathChars) != -1)
                                        throw new ArgumentException ("Illegal characters in path.");
-                               
+
+                               if (need_sep) {
+                                       need_sep = false;
+                                       ret.Append (DirectorySeparatorStr);
+                               }
+
                                pathsLen--;
                                if (IsPathRooted (s))
                                        ret.Length = 0;
@@ -779,9 +813,6 @@ namespace System.IO {
                                        if (p1end != DirectorySeparatorChar && p1end != AltDirectorySeparatorChar && p1end != VolumeSeparatorChar)
                                                need_sep = true;
                                }
-                               
-                               if (need_sep)
-                                       ret.Append (DirectorySeparatorStr);
                        }
 
                        return ret.ToString ();