private static String GetFinalPathName(String path) { Int32 nAccess = ReparseResolver.FILE_READ_EA; Int32 nShare = ReparseResolver.FILE_SHARE_READ | ReparseResolver.FILE_SHARE_WRITE | ReparseResolver.FILE_SHARE_DELETE; Int32 nMode = ReparseResolver.OPEN_EXISTING; Int32 nFlags = ReparseResolver.FILE_FLAG_BACKUP_SEMANTICS; IntPtr handle = ReparseResolver.CreateFileW(path, nAccess, nShare, IntPtr.Zero, nMode, nFlags, IntPtr.Zero); if (handle == ReparseResolver.InvalidHandleValue) { throw new NativeException($"Could not resolve final path name for \"{path}\".", Marshal.GetHRForLastWin32Error()); } try { nFlags = ReparseResolver.FILE_NAME_NORMALIZED; // Obtain required result size. Int32 length = ReparseResolver.GetFinalPathNameByHandleW(handle, null, 0, nFlags); if (length < 1) { throw new NativeException($"Could not obtain required buffer size to resolve final path name for \"{path}\".", Marshal.GetHRForLastWin32Error()); } StringBuilder builder = new StringBuilder(length); Int32 result = ReparseResolver.GetFinalPathNameByHandleW(handle, builder, length, nFlags); if (result < 1) { throw new NativeException($"Resolving final path name for \"{path}\" has failed.", Marshal.GetHRForLastWin32Error()); } return(builder.ToString()); } finally { ReparseResolver.CloseHandle(handle); } }
/// <summary> /// Tries to resolve the physical file path. /// </summary> /// <remarks> /// This method tries to resolve the physical file path of /// provided <paramref name="filename"/>. The full name is /// returned if parameter is not <c>null</c> or <c>empty</c>, /// no matter if the file needs to be resolved or not. /// </remarks> /// <param name="filename"> /// The file name to resolve. /// </param> /// <param name="resolved"> /// True if file name could be resolved and false otherwise. /// </param> /// <returns> /// The full path of the resolved file name. /// </returns> /// <exception cref="NativeException"> /// This exception is thrown in any error case. For example /// the requested file name could not be opened for read access. /// </exception> public static String Resolve(String filename, out Boolean resolved) { resolved = false; if (String.IsNullOrWhiteSpace(filename)) { return(filename); } FileInfo info = new FileInfo(Path.GetFullPath(filename)); if ((info.Attributes & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint) { return(info.FullName); } filename = ReparseResolver.GetFinalPathName(info.FullName); resolved = true; return(filename); }