mirror of
https://github.com/claunia/romrepomgr.git
synced 2025-12-16 19:24:51 +00:00
Show disks in virtual filesystem.
This commit is contained in:
@@ -6,7 +6,6 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Mono.Fuse.NETStandard;
|
||||
using Mono.Unix.Native;
|
||||
using RomRepoMgr.Database;
|
||||
using RomRepoMgr.Database.Models;
|
||||
|
||||
namespace RomRepoMgr.Core.Filesystem
|
||||
@@ -141,11 +140,11 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
|
||||
CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);
|
||||
|
||||
if(file == null)
|
||||
return Errno.ENOENT;
|
||||
|
||||
if(pieces.Length == 3)
|
||||
if(file != null)
|
||||
{
|
||||
if(pieces.Length != 3)
|
||||
return Errno.ENOSYS;
|
||||
|
||||
stat = new Stat
|
||||
{
|
||||
st_mode = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"),
|
||||
@@ -161,7 +160,27 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Errno.ENOSYS;
|
||||
CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);
|
||||
|
||||
if(disk == null)
|
||||
return Errno.ENOENT;
|
||||
|
||||
if(pieces.Length != 3)
|
||||
return Errno.ENOSYS;
|
||||
|
||||
stat = new Stat
|
||||
{
|
||||
st_mode = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"),
|
||||
st_nlink = 1,
|
||||
st_ctime = NativeConvert.ToTimeT(disk.CreatedOn.ToUniversalTime()),
|
||||
st_mtime = NativeConvert.ToTimeT(disk.UpdatedOn.ToUniversalTime()),
|
||||
st_blksize = 512,
|
||||
st_blocks = (long)(disk.Size / 512),
|
||||
st_ino = disk.Id,
|
||||
st_size = (long)disk.Size
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected override Errno OnReadSymbolicLink(string link, out string target)
|
||||
@@ -221,41 +240,80 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
if(pieces.Length == 2)
|
||||
return Errno.EISDIR;
|
||||
|
||||
long handle = 0;
|
||||
Stat stat;
|
||||
|
||||
CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);
|
||||
|
||||
if(file == null)
|
||||
return Errno.ENOENT;
|
||||
if(file != null)
|
||||
{
|
||||
if(pieces.Length > 3)
|
||||
return Errno.ENOSYS;
|
||||
|
||||
if(pieces.Length > 3)
|
||||
return Errno.ENOSYS;
|
||||
if(file.Sha384 == null)
|
||||
return Errno.ENOENT;
|
||||
|
||||
if(file.Sha384 == null)
|
||||
return Errno.ENOENT;
|
||||
if(info.OpenAccess.HasFlag(OpenFlags.O_APPEND) ||
|
||||
info.OpenAccess.HasFlag(OpenFlags.O_CREAT) ||
|
||||
info.OpenAccess.HasFlag(OpenFlags.O_EXCL) ||
|
||||
info.OpenAccess.HasFlag(OpenFlags.O_TRUNC))
|
||||
return Errno.EROFS;
|
||||
|
||||
if(info.OpenAccess.HasFlag(OpenFlags.O_APPEND) ||
|
||||
info.OpenAccess.HasFlag(OpenFlags.O_CREAT) ||
|
||||
info.OpenAccess.HasFlag(OpenFlags.O_EXCL) ||
|
||||
info.OpenAccess.HasFlag(OpenFlags.O_TRUNC))
|
||||
return Errno.EROFS;
|
||||
handle = _vfs.Open(file.Sha384, (long)file.Size);
|
||||
|
||||
long handle = _vfs.Open(file.Sha384, (long)file.Size);
|
||||
stat = new Stat
|
||||
{
|
||||
st_mode = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"),
|
||||
st_nlink = 1,
|
||||
st_ctime = NativeConvert.ToTimeT(file.CreatedOn.ToUniversalTime()),
|
||||
st_mtime = NativeConvert.ToTimeT(file.UpdatedOn.ToUniversalTime()),
|
||||
st_blksize = 512,
|
||||
st_blocks = (long)(file.Size / 512),
|
||||
st_ino = file.Id,
|
||||
st_size = (long)file.Size
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);
|
||||
|
||||
if(disk == null)
|
||||
return Errno.ENOENT;
|
||||
|
||||
if(pieces.Length > 3)
|
||||
return Errno.ENOSYS;
|
||||
|
||||
if(disk.Sha1 == null &&
|
||||
disk.Md5 == null)
|
||||
return Errno.ENOENT;
|
||||
|
||||
if(info.OpenAccess.HasFlag(OpenFlags.O_APPEND) ||
|
||||
info.OpenAccess.HasFlag(OpenFlags.O_CREAT) ||
|
||||
info.OpenAccess.HasFlag(OpenFlags.O_EXCL) ||
|
||||
info.OpenAccess.HasFlag(OpenFlags.O_TRUNC))
|
||||
return Errno.EROFS;
|
||||
|
||||
handle = _vfs.OpenDisk(disk.Sha1, disk.Md5);
|
||||
|
||||
stat = new Stat
|
||||
{
|
||||
st_mode = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"),
|
||||
st_nlink = 1,
|
||||
st_ctime = NativeConvert.ToTimeT(disk.CreatedOn.ToUniversalTime()),
|
||||
st_mtime = NativeConvert.ToTimeT(disk.UpdatedOn.ToUniversalTime()),
|
||||
st_blksize = 512,
|
||||
st_blocks = (long)(disk.Size / 512),
|
||||
st_ino = disk.Id,
|
||||
st_size = (long)disk.Size
|
||||
};
|
||||
}
|
||||
|
||||
if(handle <= 0)
|
||||
return Errno.ENOENT;
|
||||
|
||||
info.Handle = new IntPtr(handle);
|
||||
|
||||
_fileStatHandleCache[handle] = new Stat
|
||||
{
|
||||
st_mode = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"),
|
||||
st_nlink = 1,
|
||||
st_ctime = NativeConvert.ToTimeT(file.CreatedOn.ToUniversalTime()),
|
||||
st_mtime = NativeConvert.ToTimeT(file.UpdatedOn.ToUniversalTime()),
|
||||
st_blksize = 512,
|
||||
st_blocks = (long)(file.Size / 512),
|
||||
st_ino = file.Id,
|
||||
st_size = (long)file.Size
|
||||
};
|
||||
_fileStatHandleCache[handle] = stat;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -370,40 +428,59 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
|
||||
CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);
|
||||
|
||||
if(file == null)
|
||||
return Errno.ENOENT;
|
||||
|
||||
if(pieces.Length > 3)
|
||||
return Errno.ENOSYS;
|
||||
|
||||
string hash = null;
|
||||
|
||||
switch(name)
|
||||
if(file != null)
|
||||
{
|
||||
case "user.crc32":
|
||||
hash = file.Crc32;
|
||||
if(pieces.Length > 3)
|
||||
return Errno.ENOSYS;
|
||||
|
||||
break;
|
||||
case "user.md5":
|
||||
hash = file.Md5;
|
||||
switch(name)
|
||||
{
|
||||
case "user.crc32":
|
||||
hash = file.Crc32;
|
||||
|
||||
break;
|
||||
case "user.sha1":
|
||||
hash = file.Sha1;
|
||||
break;
|
||||
case "user.md5":
|
||||
hash = file.Md5;
|
||||
|
||||
break;
|
||||
case "user.sha256":
|
||||
hash = file.Sha256;
|
||||
break;
|
||||
case "user.sha1":
|
||||
hash = file.Sha1;
|
||||
|
||||
break;
|
||||
case "user.sha384":
|
||||
hash = file.Sha384;
|
||||
break;
|
||||
case "user.sha256":
|
||||
hash = file.Sha256;
|
||||
|
||||
break;
|
||||
case "user.sha512":
|
||||
hash = file.Sha512;
|
||||
break;
|
||||
case "user.sha384":
|
||||
hash = file.Sha384;
|
||||
|
||||
break;
|
||||
break;
|
||||
case "user.sha512":
|
||||
hash = file.Sha512;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);
|
||||
|
||||
if(disk == null)
|
||||
return Errno.ENOENT;
|
||||
|
||||
switch(name)
|
||||
{
|
||||
case "user.md5":
|
||||
hash = disk.Md5;
|
||||
|
||||
break;
|
||||
case "user.sha1":
|
||||
hash = disk.Sha1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(hash == null)
|
||||
@@ -479,34 +556,52 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
if(pieces.Length == 2)
|
||||
return 0;
|
||||
|
||||
List<string> xattrs = new List<string>();
|
||||
|
||||
CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);
|
||||
|
||||
if(file == null)
|
||||
if(file != null)
|
||||
{
|
||||
if(pieces.Length > 3)
|
||||
return Errno.ENOSYS;
|
||||
|
||||
if(file.Crc32 != null)
|
||||
xattrs.Add("user.crc32");
|
||||
|
||||
if(file.Md5 != null)
|
||||
xattrs.Add("user.md5");
|
||||
|
||||
if(file.Sha1 != null)
|
||||
xattrs.Add("user.sha1");
|
||||
|
||||
if(file.Sha256 != null)
|
||||
xattrs.Add("user.sha256");
|
||||
|
||||
if(file.Sha384 != null)
|
||||
xattrs.Add("user.sha384");
|
||||
|
||||
if(file.Sha512 != null)
|
||||
xattrs.Add("user.sha512");
|
||||
|
||||
names = xattrs.ToArray();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);
|
||||
|
||||
if(disk == null)
|
||||
return Errno.ENOENT;
|
||||
|
||||
if(pieces.Length > 3)
|
||||
return Errno.ENOSYS;
|
||||
|
||||
List<string> xattrs = new List<string>();
|
||||
|
||||
if(file.Crc32 != null)
|
||||
xattrs.Add("user.crc32");
|
||||
|
||||
if(file.Md5 != null)
|
||||
if(disk.Md5 != null)
|
||||
xattrs.Add("user.md5");
|
||||
|
||||
if(file.Sha1 != null)
|
||||
if(disk.Sha1 != null)
|
||||
xattrs.Add("user.sha1");
|
||||
|
||||
if(file.Sha256 != null)
|
||||
xattrs.Add("user.sha256");
|
||||
|
||||
if(file.Sha384 != null)
|
||||
xattrs.Add("user.sha384");
|
||||
|
||||
if(file.Sha512 != null)
|
||||
xattrs.Add("user.sha512");
|
||||
|
||||
names = xattrs.ToArray();
|
||||
|
||||
return 0;
|
||||
@@ -577,6 +672,7 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
return Errno.ENOENT;
|
||||
|
||||
ConcurrentDictionary<string, CachedFile> cachedMachineFiles = _vfs.GetFilesFromMachine(machine.Id);
|
||||
ConcurrentDictionary<string, CachedDisk> cachedMachineDisks = _vfs.GetDisksFromMachine(machine.Id);
|
||||
|
||||
if(pieces.Length == 2)
|
||||
{
|
||||
@@ -587,6 +683,7 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
};
|
||||
|
||||
entries.AddRange(cachedMachineFiles.Select(file => new DirectoryEntry(file.Key)));
|
||||
entries.AddRange(cachedMachineDisks.Select(disk => new DirectoryEntry(disk.Key + ".chd")));
|
||||
|
||||
_lastHandle++;
|
||||
info.Handle = new IntPtr(_lastHandle);
|
||||
@@ -666,7 +763,17 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
|
||||
CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);
|
||||
|
||||
if(file == null)
|
||||
if(file != null)
|
||||
{
|
||||
if(pieces.Length > 3)
|
||||
return Errno.ENOSYS;
|
||||
|
||||
return mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0;
|
||||
}
|
||||
|
||||
CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);
|
||||
|
||||
if(disk == null)
|
||||
return Errno.ENOENT;
|
||||
|
||||
if(pieces.Length > 3)
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
// TODO: Do not show machines or romsets with no ROMs in repo
|
||||
public class Vfs : IDisposable
|
||||
{
|
||||
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedDisk>> _machineDisksCache;
|
||||
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedFile>> _machineFilesCache;
|
||||
readonly ConcurrentDictionary<long, ConcurrentDictionary<string, CachedMachine>> _machinesStatCache;
|
||||
readonly ConcurrentDictionary<long, RomSet> _romSetsCache;
|
||||
@@ -33,6 +34,7 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
_romSetsCache = new ConcurrentDictionary<long, RomSet>();
|
||||
_machinesStatCache = new ConcurrentDictionary<long, ConcurrentDictionary<string, CachedMachine>>();
|
||||
_machineFilesCache = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedFile>>();
|
||||
_machineDisksCache = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedDisk>>();
|
||||
_streamsCache = new ConcurrentDictionary<long, Stream>();
|
||||
_lastHandle = 0;
|
||||
}
|
||||
@@ -251,6 +253,39 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
return cachedMachineFiles;
|
||||
}
|
||||
|
||||
internal ConcurrentDictionary<string, CachedDisk> GetDisksFromMachine(ulong id)
|
||||
{
|
||||
_machineDisksCache.TryGetValue(id, out ConcurrentDictionary<string, CachedDisk> cachedMachineDisks);
|
||||
|
||||
if(cachedMachineDisks != null)
|
||||
return cachedMachineDisks;
|
||||
|
||||
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
|
||||
|
||||
cachedMachineDisks = new ConcurrentDictionary<string, CachedDisk>();
|
||||
|
||||
foreach(DiskByMachine machineDisk in ctx.DisksByMachines.Where(dbm => dbm.Machine.Id == id &&
|
||||
dbm.Disk.IsInRepo &&
|
||||
dbm.Disk.Size != null))
|
||||
{
|
||||
var cachedDisk = new CachedDisk
|
||||
{
|
||||
Id = machineDisk.Disk.Id,
|
||||
Md5 = machineDisk.Disk.Md5,
|
||||
Sha1 = machineDisk.Disk.Sha1,
|
||||
Size = machineDisk.Disk.Size ?? 0,
|
||||
CreatedOn = machineDisk.Disk.CreatedOn,
|
||||
UpdatedOn = machineDisk.Disk.UpdatedOn
|
||||
};
|
||||
|
||||
cachedMachineDisks[machineDisk.Name] = cachedDisk;
|
||||
}
|
||||
|
||||
_machineDisksCache[id] = cachedMachineDisks;
|
||||
|
||||
return cachedMachineDisks;
|
||||
}
|
||||
|
||||
internal CachedFile GetFile(ulong machineId, string name)
|
||||
{
|
||||
ConcurrentDictionary<string, CachedFile> cachedFiles = GetFilesFromMachine(machineId);
|
||||
@@ -262,6 +297,20 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
return file;
|
||||
}
|
||||
|
||||
internal CachedDisk GetDisk(ulong machineId, string name)
|
||||
{
|
||||
if(name.EndsWith(".chd", StringComparison.OrdinalIgnoreCase))
|
||||
name = name.Substring(0, name.Length - 4);
|
||||
|
||||
ConcurrentDictionary<string, CachedDisk> cachedDisks = GetDisksFromMachine(machineId);
|
||||
|
||||
if(cachedDisks == null ||
|
||||
!cachedDisks.TryGetValue(name, out CachedDisk disk))
|
||||
return null;
|
||||
|
||||
return disk;
|
||||
}
|
||||
|
||||
internal long Open(string sha384, long fileSize)
|
||||
{
|
||||
byte[] sha384Bytes = new byte[48];
|
||||
@@ -338,6 +387,100 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
|
||||
return _rootDirectoryCache.Keys.ToArray();
|
||||
}
|
||||
|
||||
public long OpenDisk(string sha1, string md5)
|
||||
{
|
||||
if(sha1 == null &&
|
||||
md5 == null)
|
||||
return -1;
|
||||
|
||||
string repoPath = null;
|
||||
string md5Path = null;
|
||||
string sha1Path = null;
|
||||
|
||||
if(sha1 != null)
|
||||
{
|
||||
byte[] sha1Bytes = new byte[20];
|
||||
|
||||
for(int i = 0; i < 20; i++)
|
||||
{
|
||||
if(sha1[i * 2] >= 0x30 &&
|
||||
sha1[i * 2] <= 0x39)
|
||||
sha1Bytes[i] = (byte)((sha1[i * 2] - 0x30) * 0x10);
|
||||
else if(sha1[i * 2] >= 0x41 &&
|
||||
sha1[i * 2] <= 0x46)
|
||||
sha1Bytes[i] = (byte)((sha1[i * 2] - 0x37) * 0x10);
|
||||
else if(sha1[i * 2] >= 0x61 &&
|
||||
sha1[i * 2] <= 0x66)
|
||||
sha1Bytes[i] = (byte)((sha1[i * 2] - 0x57) * 0x10);
|
||||
|
||||
if(sha1[(i * 2) + 1] >= 0x30 &&
|
||||
sha1[(i * 2) + 1] <= 0x39)
|
||||
sha1Bytes[i] += (byte)(sha1[(i * 2) + 1] - 0x30);
|
||||
else if(sha1[(i * 2) + 1] >= 0x41 &&
|
||||
sha1[(i * 2) + 1] <= 0x46)
|
||||
sha1Bytes[i] += (byte)(sha1[(i * 2) + 1] - 0x37);
|
||||
else if(sha1[(i * 2) + 1] >= 0x61 &&
|
||||
sha1[(i * 2) + 1] <= 0x66)
|
||||
sha1Bytes[i] += (byte)(sha1[(i * 2) + 1] - 0x57);
|
||||
}
|
||||
|
||||
string sha1B32 = Base32.ToBase32String(sha1Bytes);
|
||||
|
||||
sha1Path = Path.Combine(Settings.Settings.Current.RepositoryPath, "chd", "sha1", sha1B32[0].ToString(),
|
||||
sha1B32[1].ToString(), sha1B32[2].ToString(), sha1B32[3].ToString(),
|
||||
sha1B32[4].ToString(), sha1B32 + ".chd");
|
||||
}
|
||||
|
||||
if(md5 != null)
|
||||
{
|
||||
byte[] md5Bytes = new byte[16];
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
if(md5[i * 2] >= 0x30 &&
|
||||
md5[i * 2] <= 0x39)
|
||||
md5Bytes[i] = (byte)((md5[i * 2] - 0x30) * 0x10);
|
||||
else if(md5[i * 2] >= 0x41 &&
|
||||
md5[i * 2] <= 0x46)
|
||||
md5Bytes[i] = (byte)((md5[i * 2] - 0x37) * 0x10);
|
||||
else if(md5[i * 2] >= 0x61 &&
|
||||
md5[i * 2] <= 0x66)
|
||||
md5Bytes[i] = (byte)((md5[i * 2] - 0x57) * 0x10);
|
||||
|
||||
if(md5[(i * 2) + 1] >= 0x30 &&
|
||||
md5[(i * 2) + 1] <= 0x39)
|
||||
md5Bytes[i] += (byte)(md5[(i * 2) + 1] - 0x30);
|
||||
else if(md5[(i * 2) + 1] >= 0x41 &&
|
||||
md5[(i * 2) + 1] <= 0x46)
|
||||
md5Bytes[i] += (byte)(md5[(i * 2) + 1] - 0x37);
|
||||
else if(md5[(i * 2) + 1] >= 0x61 &&
|
||||
md5[(i * 2) + 1] <= 0x66)
|
||||
md5Bytes[i] += (byte)(md5[(i * 2) + 1] - 0x57);
|
||||
}
|
||||
|
||||
string md5B32 = Base32.ToBase32String(md5Bytes);
|
||||
|
||||
md5Path = Path.Combine(Settings.Settings.Current.RepositoryPath, "chd", "md5", md5B32[0].ToString(),
|
||||
md5B32[1].ToString(), md5B32[2].ToString(), md5B32[3].ToString(),
|
||||
md5B32[4].ToString(), md5B32 + ".chd");
|
||||
}
|
||||
|
||||
if(File.Exists(sha1Path))
|
||||
repoPath = sha1Path;
|
||||
else if(File.Exists(md5Path))
|
||||
repoPath = md5Path;
|
||||
|
||||
if(repoPath == null)
|
||||
return -1;
|
||||
|
||||
_lastHandle++;
|
||||
long handle = _lastHandle;
|
||||
|
||||
_streamsCache[handle] = Stream.Synchronized(new FileStream(repoPath, FileMode.Open, FileAccess.Read));
|
||||
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class CachedMachine
|
||||
@@ -360,4 +503,14 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public DateTime UpdatedOn { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class CachedDisk
|
||||
{
|
||||
public ulong Id { get; set; }
|
||||
public ulong Size { get; set; }
|
||||
public string Md5 { get; set; }
|
||||
public string Sha1 { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public DateTime UpdatedOn { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -247,18 +247,62 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);
|
||||
long handle = 0;
|
||||
CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);
|
||||
|
||||
if(file == null)
|
||||
if(file != null)
|
||||
{
|
||||
if(pieces.Length > 3)
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
if(file.Sha384 == null)
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
handle = _vfs.Open(file.Sha384, (long)file.Size);
|
||||
|
||||
if(handle <= 0)
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
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()
|
||||
};
|
||||
|
||||
fileNode = new FileNode
|
||||
{
|
||||
FileName = normalizedName,
|
||||
Info = fileInfo,
|
||||
Path = fileName,
|
||||
Handle = handle
|
||||
};
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);
|
||||
|
||||
if(disk == null)
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
if(pieces.Length > 3)
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
if(file.Sha384 == null)
|
||||
if(disk.Sha1 == null &&
|
||||
disk.Md5 == null)
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
long handle = _vfs.Open(file.Sha384, (long)file.Size);
|
||||
handle = _vfs.OpenDisk(disk.Sha1, disk.Md5);
|
||||
|
||||
if(handle <= 0)
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
@@ -268,14 +312,14 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
// 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(),
|
||||
ChangeTime = (ulong)disk.UpdatedOn.ToFileTimeUtc(),
|
||||
AllocationSize = (disk.Size + 511) / 512,
|
||||
FileSize = disk.Size,
|
||||
CreationTime = (ulong)disk.CreatedOn.ToFileTimeUtc(),
|
||||
FileAttributes = (uint)(FileAttributes.Normal | FileAttributes.Compressed | FileAttributes.ReadOnly),
|
||||
IndexNumber = file.Id,
|
||||
IndexNumber = disk.Id,
|
||||
LastAccessTime = (ulong)DateTime.UtcNow.ToFileTimeUtc(),
|
||||
LastWriteTime = (ulong)file.UpdatedOn.ToFileTimeUtc()
|
||||
LastWriteTime = (ulong)disk.UpdatedOn.ToFileTimeUtc()
|
||||
};
|
||||
|
||||
fileNode = new FileNode
|
||||
@@ -352,6 +396,9 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
ConcurrentDictionary<string, CachedFile> cachedMachineFiles =
|
||||
_vfs.GetFilesFromMachine(node.MachineId);
|
||||
|
||||
ConcurrentDictionary<string, CachedDisk> cachedMachineDisks =
|
||||
_vfs.GetDisksFromMachine(node.MachineId);
|
||||
|
||||
node.Children = new List<FileEntry>
|
||||
{
|
||||
new FileEntry
|
||||
@@ -382,6 +429,23 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
LastWriteTime = (ulong)file.Value.UpdatedOn.ToFileTimeUtc()
|
||||
}
|
||||
}));
|
||||
|
||||
node.Children.AddRange(cachedMachineDisks.Select(disk => new FileEntry
|
||||
{
|
||||
FileName = disk.Key + ".chd",
|
||||
Info = new FileInfo
|
||||
{
|
||||
ChangeTime = (ulong)disk.Value.UpdatedOn.ToFileTimeUtc(),
|
||||
AllocationSize = (disk.Value.Size + 511) / 512,
|
||||
FileSize = disk.Value.Size,
|
||||
CreationTime = (ulong)disk.Value.CreatedOn.ToFileTimeUtc(),
|
||||
FileAttributes =
|
||||
(uint)(FileAttributes.Normal | FileAttributes.Compressed | FileAttributes.ReadOnly),
|
||||
IndexNumber = disk.Value.Id,
|
||||
LastAccessTime = (ulong)DateTime.UtcNow.ToFileTimeUtc(),
|
||||
LastWriteTime = (ulong)disk.Value.UpdatedOn.ToFileTimeUtc()
|
||||
}
|
||||
}));
|
||||
}
|
||||
else if(node.RomSetId > 0)
|
||||
{
|
||||
@@ -525,18 +589,40 @@ namespace RomRepoMgr.Core.Filesystem
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);
|
||||
long handle = 0;
|
||||
CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);
|
||||
|
||||
if(file == null)
|
||||
if(file != null)
|
||||
{
|
||||
if(pieces.Length > 3)
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
if(file.Sha384 == null)
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
handle = _vfs.Open(file.Sha384, (long)file.Size);
|
||||
|
||||
if(handle <= 0)
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
fileAttributes = (uint)(FileAttributes.Normal | FileAttributes.Compressed | FileAttributes.ReadOnly);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);
|
||||
|
||||
if(disk == null)
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
if(pieces.Length > 3)
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
if(file.Sha384 == null)
|
||||
if(disk.Sha1 == null &&
|
||||
disk.Md5 == null)
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
long handle = _vfs.Open(file.Sha384, (long)file.Size);
|
||||
handle = _vfs.OpenDisk(disk.Sha1, disk.Md5);
|
||||
|
||||
if(handle <= 0)
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
Reference in New Issue
Block a user