mirror of
https://github.com/claunia/romrepomgr.git
synced 2025-12-16 19:24:51 +00:00
Implement open in winfsp.
This commit is contained in:
@@ -1,15 +1,24 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.IO;
|
||||||
using Fsp;
|
using Fsp;
|
||||||
using Fsp.Interop;
|
using Fsp.Interop;
|
||||||
|
using RomRepoMgr.Database.Models;
|
||||||
|
using FileInfo = Fsp.Interop.FileInfo;
|
||||||
|
|
||||||
namespace RomRepoMgr.Core.Filesystem
|
namespace RomRepoMgr.Core.Filesystem
|
||||||
{
|
{
|
||||||
public class Winfsp : FileSystemBase
|
public class Winfsp : FileSystemBase
|
||||||
{
|
{
|
||||||
readonly Vfs _vfs;
|
readonly ConcurrentDictionary<long, FileInfo> _fileStatHandleCache;
|
||||||
FileSystemHost _host;
|
readonly Vfs _vfs;
|
||||||
|
FileSystemHost _host;
|
||||||
|
|
||||||
public Winfsp(Vfs vfs) => _vfs = vfs;
|
public Winfsp(Vfs vfs)
|
||||||
|
{
|
||||||
|
_vfs = vfs;
|
||||||
|
_fileStatHandleCache = new ConcurrentDictionary<long, FileInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
public static bool IsAvailable
|
public static bool IsAvailable
|
||||||
{
|
{
|
||||||
@@ -117,5 +126,76 @@ namespace RomRepoMgr.Core.Filesystem
|
|||||||
|
|
||||||
return base.GetVolumeInfo(out volumeInfo);
|
return base.GetVolumeInfo(out volumeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override int Open(string fileName, uint createOptions, uint grantedAccess, out object fileNode,
|
||||||
|
out object fileDesc, out FileInfo fileInfo, out string normalizedName)
|
||||||
|
{
|
||||||
|
fileNode = default;
|
||||||
|
fileDesc = default;
|
||||||
|
fileInfo = default;
|
||||||
|
normalizedName = default;
|
||||||
|
|
||||||
|
string[] pieces = _vfs.SplitPath(fileName);
|
||||||
|
|
||||||
|
if(pieces.Length == 0)
|
||||||
|
return STATUS_FILE_IS_A_DIRECTORY;
|
||||||
|
|
||||||
|
long romSetId = _vfs.GetRomSetId(pieces[0]);
|
||||||
|
|
||||||
|
if(romSetId <= 0)
|
||||||
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
|
||||||
|
RomSet romSet = _vfs.GetRomSet(romSetId);
|
||||||
|
|
||||||
|
if(romSet == null)
|
||||||
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
|
||||||
|
if(pieces.Length == 1)
|
||||||
|
return STATUS_FILE_IS_A_DIRECTORY;
|
||||||
|
|
||||||
|
CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);
|
||||||
|
|
||||||
|
if(machine == null)
|
||||||
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
|
||||||
|
if(pieces.Length == 2)
|
||||||
|
return STATUS_FILE_IS_A_DIRECTORY;
|
||||||
|
|
||||||
|
CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);
|
||||||
|
|
||||||
|
if(file == null)
|
||||||
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
|
||||||
|
if(pieces.Length > 3)
|
||||||
|
return STATUS_FILE_IS_A_DIRECTORY;
|
||||||
|
|
||||||
|
if(file.Sha384 == null)
|
||||||
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
|
||||||
|
long handle = _vfs.Open(file.Sha384, (long)file.Size);
|
||||||
|
|
||||||
|
if(handle <= 0)
|
||||||
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
|
||||||
|
fileNode = handle;
|
||||||
|
normalizedName = Path.GetFileName(fileName);
|
||||||
|
|
||||||
|
// TODO: Real allocation size
|
||||||
|
fileInfo = new FileInfo
|
||||||
|
{
|
||||||
|
ChangeTime = (ulong)file.UpdatedOn.ToFileTimeUtc(),
|
||||||
|
AllocationSize = (file.Size + 511) / 512,
|
||||||
|
FileSize = file.Size,
|
||||||
|
CreationTime = (ulong)file.CreatedOn.ToFileTimeUtc(),
|
||||||
|
FileAttributes = (uint)(FileAttributes.Normal | FileAttributes.Compressed | FileAttributes.ReadOnly),
|
||||||
|
IndexNumber = file.Id,
|
||||||
|
LastAccessTime = (ulong)DateTime.UtcNow.ToFileTimeUtc(),
|
||||||
|
LastWriteTime = (ulong)file.UpdatedOn.ToFileTimeUtc()
|
||||||
|
};
|
||||||
|
|
||||||
|
_fileStatHandleCache[handle] = fileInfo;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user