Пример #1
0
        static string GetWindowsRealPath(string path)
        {
            const FileAttributes FILE_FLAG_BACKUP_SEMANTICS = (FileAttributes)0x02000000;
            const FileAccess     GENERIC_READ = unchecked ((FileAccess)0x80000000);
            IntPtr handle = CreateFileW(lpFileName: path,
                                        dwDesiredAccess:        GENERIC_READ,
                                        dwShareMode:            FileShare.Read,
                                        lpSecurityAttributes:   IntPtr.Zero,
                                        dwCreationDisposition:  FileMode.Open,
                                        dwFlagsAndAttributes:   FILE_FLAG_BACKUP_SEMANTICS,
                                        hTemplateFile:          IntPtr.Zero);

            if (handle == INVALID_FILE_HANDLE)
            {
                return(null);
            }
            IntPtr finalPathBuf = IntPtr.Zero;

            try  {
                const FinalPathFlags flags = FinalPathFlags.FILE_NAME_OPENED;
                uint len = GetFinalPathNameByHandleW(handle, IntPtr.Zero, 0, flags);
                if (len == 0)
                {
                    return(null);
                }
                len          = checked (len + 1);
                finalPathBuf = Marshal.AllocHGlobal(checked ((int)(sizeof(char) * (len))));
                uint checkLen = GetFinalPathNameByHandleW(handle, finalPathBuf, len, flags);
                if (checkLen == 0 || checkLen > len)
                {
                    Console.Error.WriteLine($"GetFinalPathNameByHandleW: expected {len}, got {checkLen}. Last Error: {Marshal.GetLastWin32Error()}");
                    return(null);
                }
                const string LocalUncPathPrefix = @"\\?\";
                string       finalPath          = Marshal.PtrToStringUni(finalPathBuf);
                if (finalPath?.StartsWith(LocalUncPathPrefix, StringComparison.Ordinal) ?? false)
                {
                    finalPath = finalPath.Substring(LocalUncPathPrefix.Length);
                }
                return(finalPath);
            }
            finally {
                Marshal.FreeHGlobal(finalPathBuf);
                CloseHandle(handle);
            }
        }
Пример #2
0
            internal static string GetFinalPathName(string path, FinalPathFlags finalPathFlags, bool resolveLinks)
            {
                if (path == null)
                {
                    return(null);
                }
                string lookupPath = Paths.AddExtendedPrefix(path);

                // BackupSemantics is needed to get directory handles
                AllFileAttributeFlags createFileFlags = AllFileAttributeFlags.FILE_ATTRIBUTE_NORMAL | AllFileAttributeFlags.FILE_FLAG_BACKUP_SEMANTICS;

                if (!resolveLinks)
                {
                    createFileFlags |= AllFileAttributeFlags.FILE_FLAG_OPEN_REPARSE_POINT;
                }

                string finalPath = null;

                using (SafeFileHandle file = CreateFile(
                           lookupPath,
                           // To look at metadata we don't need read or write access
                           0,
                           FileShare.ReadWrite,
                           FileMode.Open,
                           createFileFlags))
                {
                    if (file.IsInvalid)
                    {
                        int error = Marshal.GetLastWin32Error();
                        throw GetIoExceptionForError(error, path);
                    }

                    finalPath = NativeMethods.BufferInvoke((buffer) => Private.GetFinalPathNameByHandleW(file, buffer, (uint)buffer.CharCapacity, finalPathFlags), path);
                }

                // GetFinalPathNameByHandle will use the legacy drive for the volume (e.g. \\?\C:\). We may have started with \\?\Volume({GUID}) or some
                // other volume name format (C:\, etc.) we want to put it back.
                return(Paths.ReplaceRoot(path, finalPath));
            }
Пример #3
0
 static extern uint GetFinalPathNameByHandleW(
     IntPtr hFile,
     IntPtr lpszFilePath,
     uint cchFilePath,
     FinalPathFlags dwFlags);
Пример #4
0
 internal static extern uint GetFinalPathNameByHandleW(
     SafeFileHandle hFile,
     SafeHandle lpszFilePath,
     uint cchFilePath,
     FinalPathFlags dwFlags);
Пример #5
0
            internal static string GetFinalPathName(string path, FinalPathFlags finalPathFlags, bool resolveLinks)
            {
                if (path == null) return null;
                string lookupPath = Paths.AddExtendedPrefix(path);

                // BackupSemantics is needed to get directory handles
                AllFileAttributeFlags createFileFlags = AllFileAttributeFlags.FILE_ATTRIBUTE_NORMAL | AllFileAttributeFlags.FILE_FLAG_BACKUP_SEMANTICS;
                if (!resolveLinks) createFileFlags |= AllFileAttributeFlags.FILE_FLAG_OPEN_REPARSE_POINT;

                string finalPath = null;

                using (SafeFileHandle file = CreateFile(
                    lookupPath,
                    // To look at metadata we don't need read or write access
                    0,
                    FileShare.ReadWrite,
                    FileMode.Open,
                    createFileFlags))
                {
                    if (file.IsInvalid)
                    {
                        int error = Marshal.GetLastWin32Error();
                        throw GetIoExceptionForError(error, path);
                    }

                    finalPath = NativeMethods.BufferInvoke((buffer) => Private.GetFinalPathNameByHandleW(file, buffer, (uint)buffer.CharCapacity, finalPathFlags), path);
                }

                // GetFinalPathNameByHandle will use the legacy drive for the volume (e.g. \\?\C:\). We may have started with \\?\Volume({GUID}) or some
                // other volume name format (C:\, etc.) we want to put it back.
                return Paths.ReplaceRoot(path, finalPath);
            }
Пример #6
0
 internal static string GetFinalPathName(SafeFileHandle fileHandle, FinalPathFlags finalPathFlags)
 {
     return NativeMethods.BufferInvoke((buffer) => Private.GetFinalPathNameByHandleW(fileHandle, buffer, (uint)buffer.CharCapacity, finalPathFlags));
 }
Пример #7
0
 internal static extern uint GetFinalPathNameByHandleW(
     SafeFileHandle hFile,
     SafeHandle lpszFilePath,
     uint cchFilePath,
     FinalPathFlags dwFlags);
Пример #8
0
 internal static string GetFinalPathName(SafeFileHandle fileHandle, FinalPathFlags finalPathFlags)
 {
     return(NativeMethods.BufferInvoke((buffer) => Private.GetFinalPathNameByHandleW(fileHandle, buffer, (uint)buffer.CharCapacity, finalPathFlags)));
 }
Пример #9
0
 public static extern uint GetFinalPathNameByHandle(IntPtr hFile,
                                                    [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszFilePath,
                                                    uint cchFilePath,
                                                    FinalPathFlags dwFlags);
Пример #10
0
 private static extern uint GetFinalPathNameByHandlePrivate(SafeFileHandle hFile, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszFilePath, uint cchFilePath, FinalPathFlags dwFlags);
Пример #11
0
            internal static string GetFinalPathName(string path, FinalPathFlags finalPathFlags)
            {
                if (path == null) return null;
                string lookupPath = Paths.AddExtendedPathPrefix(path);

                using (SafeFileHandle file = FileManagement.CreateFilePrivate(
                    lookupPath,
                    FileAccess.Read,
                    FileShare.ReadWrite,
                    IntPtr.Zero,
                    FileMode.Open,
                    // BackupSemantics is needed to get directory handles
                    AllFileAttributeFlags.FILE_ATTRIBUTE_NORMAL | AllFileAttributeFlags.FILE_FLAG_BACKUP_SEMANTICS,
                    IntPtr.Zero))
                {
                    if (file.IsInvalid)
                    {
                        int error = Marshal.GetLastWin32Error();
                        throw GetIoExceptionForError(error, path);
                    }

                    return NativeMethods.ConvertString(path, (value, sb) => FileManagement.GetFinalPathNameByHandlePrivate(file, sb, (uint)sb.Capacity, finalPathFlags));
                }
            }
Пример #12
0
 internal static string GetFinalPathName(SafeFileHandle fileHandle, FinalPathFlags finalPathFlags)
 {
     return NativeMethods.ConvertString("GetFinalPathNameByHandle", (value, sb) => FileManagement.GetFinalPathNameByHandlePrivate(fileHandle, sb, (uint)sb.Capacity, finalPathFlags));
 }