none
Is there any way to determine if two paths reference the same file when symlinks are involved? RRS feed

  • Question

  • Hello

    I need a way to determine if two different file paths reference the same file in the system. I was doing this comparing the absolutes file paths, but this is not working when symlinks are involved, for obvious reasons.

    I've been trying yo find a way to solve this but haven't find a solution. I'm sure this is something some people would have faced before me, so if anyone can point me to the right direction it would be highly appreciated.

    EDIT: Maybe it would be enough to have a way to get te FileID of a given file using path, and comparing the two of them could bring some light. But again no clues how to solve this

    Thanks!


    Manel Ibáñez


    • Edited by Ziggy_bcn Thursday, February 7, 2013 7:15 PM More info regarding the issue
    Thursday, February 7, 2013 2:40 PM

Answers

  • Here is an example how to get the uniqie file identifier.

    http://stackoverflow.com/questions/1866454/unique-file-identifier-in-windows

    • Marked as answer by Ziggy_bcn Thursday, February 7, 2013 9:28 PM
    Thursday, February 7, 2013 8:28 PM
    Moderator
  • That's been very helpful!

    This is a vb version of it (a bit simplified): (just in case anyone is using VB as I do)

    Imports System.Runtime.InteropServices Imports System.IO Public Class WinAPI <DllImport("ntdll.dll", SetLastError:=True)> _ Public Shared Function NtQueryInformationFile(fileHandle As IntPtr, ByRef IoStatusBlock As IO_STATUS_BLOCK, pInfoBlock As IntPtr, length As UInteger, fileInformation As FILE_INFORMATION_CLASS) As IntPtr End Function Public Structure IO_STATUS_BLOCK Private status As UInteger Private information As ULong End Structure Public Structure _FILE_INTERNAL_INFORMATION Public IndexNumber As ULong End Structure ' Abbreviated, there are more values than shown Public Enum FILE_INFORMATION_CLASS FileDirectoryInformation = 1 ' 1 FileFullDirectoryInformation ' 2 FileBothDirectoryInformation ' 3 FileBasicInformation ' 4 FileStandardInformation ' 5 FileInternalInformation ' 6 End Enum <DllImport("kernel32.dll", SetLastError:=True)> _ Public Shared Function GetFileInformationByHandle(hFile As IntPtr, ByRef lpFileInformation As BY_HANDLE_FILE_INFORMATION) As Boolean End Function Public Structure BY_HANDLE_FILE_INFORMATION Public FileAttributes As UInteger Public CreationTime As FILETIME Public LastAccessTime As FILETIME Public LastWriteTime As FILETIME Public VolumeSerialNumber As UInteger Public FileSizeHigh As UInteger Public FileSizeLow As UInteger Public NumberOfLinks As UInteger Public FileIndexHigh As UInteger Public FileIndexLow As UInteger End Structure Public Shared Function GetFileID(file As String) As ULong Dim objectFileInfo As New WinAPI.BY_HANDLE_FILE_INFORMATION() Dim fi As New FileInfo(file) Dim fs As FileStream = fi.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite) WinAPI.GetFileInformationByHandle(fs.Handle, objectFileInfo) fs.Close() Dim fileIndex As ULong = (CULng(objectFileInfo.FileIndexHigh) << 32) + CULng(objectFileInfo.FileIndexLow) Return fileIndex End Function End Class


    Manel Ibáñez

    Thursday, February 7, 2013 9:40 PM

All replies

  • Here is an example how to get the uniqie file identifier.

    http://stackoverflow.com/questions/1866454/unique-file-identifier-in-windows

    • Marked as answer by Ziggy_bcn Thursday, February 7, 2013 9:28 PM
    Thursday, February 7, 2013 8:28 PM
    Moderator
  • That's been very helpful!

    This is a vb version of it (a bit simplified): (just in case anyone is using VB as I do)

    Imports System.Runtime.InteropServices Imports System.IO Public Class WinAPI <DllImport("ntdll.dll", SetLastError:=True)> _ Public Shared Function NtQueryInformationFile(fileHandle As IntPtr, ByRef IoStatusBlock As IO_STATUS_BLOCK, pInfoBlock As IntPtr, length As UInteger, fileInformation As FILE_INFORMATION_CLASS) As IntPtr End Function Public Structure IO_STATUS_BLOCK Private status As UInteger Private information As ULong End Structure Public Structure _FILE_INTERNAL_INFORMATION Public IndexNumber As ULong End Structure ' Abbreviated, there are more values than shown Public Enum FILE_INFORMATION_CLASS FileDirectoryInformation = 1 ' 1 FileFullDirectoryInformation ' 2 FileBothDirectoryInformation ' 3 FileBasicInformation ' 4 FileStandardInformation ' 5 FileInternalInformation ' 6 End Enum <DllImport("kernel32.dll", SetLastError:=True)> _ Public Shared Function GetFileInformationByHandle(hFile As IntPtr, ByRef lpFileInformation As BY_HANDLE_FILE_INFORMATION) As Boolean End Function Public Structure BY_HANDLE_FILE_INFORMATION Public FileAttributes As UInteger Public CreationTime As FILETIME Public LastAccessTime As FILETIME Public LastWriteTime As FILETIME Public VolumeSerialNumber As UInteger Public FileSizeHigh As UInteger Public FileSizeLow As UInteger Public NumberOfLinks As UInteger Public FileIndexHigh As UInteger Public FileIndexLow As UInteger End Structure Public Shared Function GetFileID(file As String) As ULong Dim objectFileInfo As New WinAPI.BY_HANDLE_FILE_INFORMATION() Dim fi As New FileInfo(file) Dim fs As FileStream = fi.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite) WinAPI.GetFileInformationByHandle(fs.Handle, objectFileInfo) fs.Close() Dim fileIndex As ULong = (CULng(objectFileInfo.FileIndexHigh) << 32) + CULng(objectFileInfo.FileIndexLow) Return fileIndex End Function End Class


    Manel Ibáñez

    Thursday, February 7, 2013 9:40 PM