Add code to check whether a file is a hard link

This commit is contained in:
Dean Herbert 2022-10-13 18:18:29 +09:00
parent f27603dd6d
commit 3b1920c060
1 changed files with 48 additions and 0 deletions

View File

@ -5,6 +5,8 @@
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.Win32.SafeHandles;
using osu.Framework;
using osu.Framework.Extensions;
using osu.Framework.IO.Stores;
@ -77,6 +79,20 @@ private void copyToStore(RealmFile file, Stream data)
data.Seek(0, SeekOrigin.Begin);
}
public static int GetFileLinkCount(string filePath)
{
int result = 0;
SafeFileHandle handle = CreateFile(filePath, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Archive, IntPtr.Zero);
ByHandleFileInformation fileInfo;
if (GetFileInformationByHandle(handle, out fileInfo))
result = (int)fileInfo.NumberOfLinks;
CloseHandle(handle);
return result;
}
[DllImport("Kernel32.dll", CharSet = CharSet.Unicode)]
private static extern bool CreateHardLink(
string lpFileName,
@ -84,6 +100,38 @@ private static extern bool CreateHardLink(
IntPtr lpSecurityAttributes
);
[StructLayout(LayoutKind.Sequential)]
private struct ByHandleFileInformation
{
public readonly uint FileAttributes;
public readonly FILETIME CreationTime;
public readonly FILETIME LastAccessTime;
public readonly FILETIME LastWriteTime;
public readonly uint VolumeSerialNumber;
public readonly uint FileSizeHigh;
public readonly uint FileSizeLow;
public readonly uint NumberOfLinks;
public readonly uint FileIndexHigh;
public readonly uint FileIndexLow;
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern SafeFileHandle CreateFile(
string lpFileName,
[MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
[MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
IntPtr lpSecurityAttributes,
[MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition,
[MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetFileInformationByHandle(SafeFileHandle handle, out ByHandleFileInformation lpFileInformation);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(SafeHandle hObject);
private bool checkFileExistsAndMatchesHash(RealmFile file)
{
string path = file.GetStoragePath();