mirror of
https://github.com/osukey/osukey.git
synced 2025-07-02 00:40:09 +09:00
Move hard link availability check to helper class
This commit is contained in:
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using osu.Framework;
|
using osu.Framework;
|
||||||
@ -57,22 +56,15 @@ namespace osu.Game.Database
|
|||||||
|
|
||||||
public bool CheckHardLinkAvailability()
|
public bool CheckHardLinkAvailability()
|
||||||
{
|
{
|
||||||
if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var stableStorage = GetCurrentStableStorage();
|
var stableStorage = GetCurrentStableStorage();
|
||||||
|
|
||||||
if (stableStorage == null || gameHost is not DesktopGameHost desktopGameHost)
|
if (stableStorage == null || gameHost is not DesktopGameHost desktopGameHost)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const string test_filename = "_hard_link_test";
|
string testExistingPath = stableStorage.GetFullPath(string.Empty);
|
||||||
|
string testDestinationPath = desktopGameHost.Storage.GetFullPath(string.Empty);
|
||||||
|
|
||||||
desktopGameHost.Storage.Delete(test_filename);
|
return HardLinkHelper.CheckAvailability(testDestinationPath, testExistingPath);
|
||||||
|
|
||||||
string testExistingPath = stableStorage.GetFullPath(stableStorage.GetFiles(string.Empty).First());
|
|
||||||
string testDestinationPath = desktopGameHost.Storage.GetFullPath(test_filename);
|
|
||||||
|
|
||||||
return HardLinkHelper.CreateHardLink(testDestinationPath, testExistingPath, IntPtr.Zero);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<int> GetImportCount(StableContent content, CancellationToken cancellationToken)
|
public virtual async Task<int> GetImportCount(StableContent content, CancellationToken cancellationToken)
|
||||||
|
@ -6,11 +6,55 @@ using System.IO;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.InteropServices.ComTypes;
|
using System.Runtime.InteropServices.ComTypes;
|
||||||
using Microsoft.Win32.SafeHandles;
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
using osu.Framework;
|
||||||
|
|
||||||
namespace osu.Game.IO
|
namespace osu.Game.IO
|
||||||
{
|
{
|
||||||
internal static class HardLinkHelper
|
internal static class HardLinkHelper
|
||||||
{
|
{
|
||||||
|
public static bool CheckAvailability(string testDestinationPath, string testSourcePath)
|
||||||
|
{
|
||||||
|
// We can support other operating systems quite easily in the future.
|
||||||
|
// Let's handle the most common one for now, though.
|
||||||
|
if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const string test_filename = "_hard_link_test";
|
||||||
|
|
||||||
|
testDestinationPath = Path.Combine(testDestinationPath, test_filename);
|
||||||
|
testSourcePath = Path.Combine(testSourcePath, test_filename);
|
||||||
|
|
||||||
|
cleanupFiles();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllText(testSourcePath, string.Empty);
|
||||||
|
|
||||||
|
// Test availability by creating an arbitrary hard link between the source and destination paths.
|
||||||
|
return CreateHardLink(testDestinationPath, testSourcePath, IntPtr.Zero);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
cleanupFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanupFiles()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(testDestinationPath);
|
||||||
|
File.Delete(testSourcePath);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For future use (to detect if a file is a hard link with other references existing on disk).
|
// For future use (to detect if a file is a hard link with other references existing on disk).
|
||||||
public static int GetFileLinkCount(string filePath)
|
public static int GetFileLinkCount(string filePath)
|
||||||
{
|
{
|
||||||
@ -27,26 +71,7 @@ namespace osu.Game.IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("Kernel32.dll", CharSet = CharSet.Unicode)]
|
[DllImport("Kernel32.dll", CharSet = CharSet.Unicode)]
|
||||||
public static extern bool CreateHardLink(
|
public static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes);
|
||||||
string lpFileName,
|
|
||||||
string lpExistingFileName,
|
|
||||||
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)]
|
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
private static extern SafeFileHandle CreateFile(
|
private static extern SafeFileHandle CreateFile(
|
||||||
@ -64,5 +89,20 @@ namespace osu.Game.IO
|
|||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
private static extern bool CloseHandle(SafeHandle hObject);
|
private static extern bool CloseHandle(SafeHandle hObject);
|
||||||
|
|
||||||
|
[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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user