internal ConcurrentDictionary <string, CachedMedia> GetMediasFromMachine(ulong id) { _machineMediasCache.TryGetValue(id, out ConcurrentDictionary <string, CachedMedia> cachedMachineMedias); if (cachedMachineMedias != null) { return(cachedMachineMedias); } using var ctx = Context.Create(Settings.Settings.Current.DatabasePath); cachedMachineMedias = new ConcurrentDictionary <string, CachedMedia>(); foreach (MediaByMachine machineMedia in ctx.MediasByMachines.Where(mbm => mbm.Machine.Id == id && mbm.Media.IsInRepo && mbm.Media.Size != null)) { var cachedDisk = new CachedMedia { Id = machineMedia.Media.Id, Md5 = machineMedia.Media.Md5, Sha1 = machineMedia.Media.Sha1, Sha256 = machineMedia.Media.Sha256, SpamSum = machineMedia.Media.SpamSum, Size = machineMedia.Media.Size ?? 0, CreatedOn = machineMedia.Media.CreatedOn, UpdatedOn = machineMedia.Media.UpdatedOn }; cachedMachineMedias[machineMedia.Name] = cachedDisk; } _machineMediasCache[id] = cachedMachineMedias; return(cachedMachineMedias); }
protected override Errno OnGetPathStatus(string path, out Stat stat) { stat = new Stat(); string[] pieces = _vfs.SplitPath(path); if (pieces.Length == 0) { stat.st_mode = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0555"); stat.st_nlink = 2; return(0); } long romSetId = _vfs.GetRomSetId(pieces[0]); if (romSetId <= 0) { if (pieces[0] != ".fuse_umount" || _umountToken == null) { return(Errno.ENOENT); } stat = new Stat { st_mode = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"), st_nlink = 1, st_ctime = NativeConvert.ToTimeT(DateTime.UtcNow), st_mtime = NativeConvert.ToTimeT(DateTime.UtcNow), st_blksize = 0, st_blocks = 0, st_ino = 0, st_size = 0 }; return(0); } RomSet romSet = _vfs.GetRomSet(romSetId); if (romSet == null) { return(Errno.ENOENT); } if (pieces.Length == 1) { stat.st_mode = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0555"); stat.st_nlink = 2; stat.st_ctime = NativeConvert.ToTimeT(romSet.CreatedOn.ToUniversalTime()); stat.st_mtime = NativeConvert.ToTimeT(romSet.UpdatedOn.ToUniversalTime()); return(0); } CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]); if (machine == null) { return(Errno.ENOENT); } if (pieces.Length == 2) { stat = new Stat { st_mode = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0555"), st_nlink = 2, st_ctime = NativeConvert.ToTimeT(machine.CreationDate.ToUniversalTime()), st_mtime = NativeConvert.ToTimeT(machine.ModificationDate.ToUniversalTime()) }; return(0); } CachedFile file = _vfs.GetFile(machine.Id, pieces[2]); if (file != null) { 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(file.CreatedOn.ToUniversalTime()), st_mtime = NativeConvert.ToTimeT(file.FileLastModification?.ToUniversalTime() ?? file.UpdatedOn.ToUniversalTime()), st_blksize = 512, st_blocks = (long)(file.Size / 512), st_ino = file.Id, st_size = (long)file.Size }; return(0); } CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]); if (disk != null) { 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); } CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]); if (media == 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(media.CreatedOn.ToUniversalTime()), st_mtime = NativeConvert.ToTimeT(media.UpdatedOn.ToUniversalTime()), st_blksize = 512, st_blocks = (long)(media.Size / 512), st_ino = media.Id, st_size = (long)media.Size }; return(0); }
protected override Errno OnListPathExtendedAttributes(string path, out string[] names) { names = null; string[] pieces = _vfs.SplitPath(path); if (pieces.Length == 0) { return(0); } long romSetId = _vfs.GetRomSetId(pieces[0]); if (romSetId <= 0) { return(Errno.ENOENT); } RomSet romSet = _vfs.GetRomSet(romSetId); if (romSet == null) { return(Errno.ENOENT); } if (pieces.Length == 1) { return(0); } CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]); if (machine == null) { return(Errno.ENOENT); } if (pieces.Length == 2) { return(0); } List <string> xattrs = new List <string>(); CachedFile file = _vfs.GetFile(machine.Id, pieces[2]); 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) { if (pieces.Length > 3) { return(Errno.ENOSYS); } if (disk.Md5 != null) { xattrs.Add("user.md5"); } if (disk.Sha1 != null) { xattrs.Add("user.sha1"); } names = xattrs.ToArray(); return(0); } CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]); if (media == null) { return(Errno.ENOENT); } if (pieces.Length > 3) { return(Errno.ENOSYS); } if (media.Md5 != null) { xattrs.Add("user.md5"); } if (media.Sha1 != null) { xattrs.Add("user.sha1"); } if (media.Sha256 != null) { xattrs.Add("user.sha256"); } if (media.SpamSum != null) { xattrs.Add("user.spamsum"); } names = xattrs.ToArray(); return(0); }
protected override Errno OnGetPathExtendedAttribute(string path, string name, byte[] value, out int bytesWritten) { bytesWritten = 0; string[] pieces = _vfs.SplitPath(path); if (pieces.Length == 0) { return(Errno.ENODATA); } long romSetId = _vfs.GetRomSetId(pieces[0]); if (romSetId <= 0) { return(Errno.ENOENT); } RomSet romSet = _vfs.GetRomSet(romSetId); if (romSet == null) { return(Errno.ENOENT); } if (pieces.Length == 1) { return(Errno.ENODATA); } CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]); if (machine == null) { return(Errno.ENOENT); } if (pieces.Length == 2) { return(Errno.ENODATA); } CachedFile file = _vfs.GetFile(machine.Id, pieces[2]); string hash = null; if (file != null) { if (pieces.Length > 3) { return(Errno.ENOSYS); } switch (name) { case "user.crc32": hash = file.Crc32; break; case "user.md5": hash = file.Md5; break; case "user.sha1": hash = file.Sha1; break; case "user.sha256": hash = file.Sha256; break; case "user.sha384": hash = file.Sha384; break; case "user.sha512": hash = file.Sha512; break; } } else { CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]); if (disk != null) { switch (name) { case "user.md5": hash = disk.Md5; break; case "user.sha1": hash = disk.Sha1; break; } } else { CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]); if (media == null) { return(Errno.ENOENT); } switch (name) { case "user.md5": hash = media.Md5; break; case "user.sha1": hash = media.Sha1; break; case "user.sha256": hash = media.Sha256; break; case "user.spamsum": hash = media.SpamSum; break; } } } if (hash == null) { return(Errno.ENODATA); } byte[] xattr = null; if (name == "user.spamsum") { xattr = Encoding.ASCII.GetBytes(hash); } else { xattr = new byte[hash.Length / 2]; for (int i = 0; i < xattr.Length; i++) { if (hash[i * 2] >= 0x30 && hash[i * 2] <= 0x39) { xattr[i] = (byte)((hash[i * 2] - 0x30) * 0x10); } else if (hash[i * 2] >= 0x41 && hash[i * 2] <= 0x46) { xattr[i] = (byte)((hash[i * 2] - 0x37) * 0x10); } else if (hash[i * 2] >= 0x61 && hash[i * 2] <= 0x66) { xattr[i] = (byte)((hash[i * 2] - 0x57) * 0x10); } if (hash[(i * 2) + 1] >= 0x30 && hash[(i * 2) + 1] <= 0x39) { xattr[i] += (byte)(hash[(i * 2) + 1] - 0x30); } else if (hash[(i * 2) + 1] >= 0x41 && hash[(i * 2) + 1] <= 0x46) { xattr[i] += (byte)(hash[(i * 2) + 1] - 0x37); } else if (hash[(i * 2) + 1] >= 0x61 && hash[(i * 2) + 1] <= 0x66) { xattr[i] += (byte)(hash[(i * 2) + 1] - 0x57); } } } if (value == null) { bytesWritten = xattr.Length; return(0); } int maxSize = value.Length > xattr.Length ? xattr.Length : value.Length; Array.Copy(xattr, 0, value, 0, maxSize); bytesWritten = maxSize; return(0); }
protected override Errno OnOpenHandle(string path, OpenedPathInfo info) { string[] pieces = _vfs.SplitPath(path); if (pieces.Length == 0) { return(Errno.EISDIR); } long romSetId = _vfs.GetRomSetId(pieces[0]); if (romSetId <= 0) { return(Errno.ENOENT); } RomSet romSet = _vfs.GetRomSet(romSetId); if (romSet == null) { return(Errno.ENOENT); } if (pieces.Length == 1) { return(Errno.EISDIR); } CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]); if (machine == null) { return(Errno.ENOENT); } if (pieces.Length == 2) { return(Errno.EISDIR); } long handle = 0; Stat stat; CachedFile file = _vfs.GetFile(machine.Id, pieces[2]); if (file != null) { if (pieces.Length > 3) { return(Errno.ENOSYS); } 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); } 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.FileLastModification?.ToUniversalTime() ?? 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) { 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 }; } else { CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]); if (media == null) { return(Errno.ENOENT); } if (pieces.Length > 3) { return(Errno.ENOSYS); } if (media.Sha256 == null && media.Sha1 == null && media.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.OpenMedia(media.Sha256, media.Sha1, media.Md5); stat = new Stat { st_mode = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"), st_nlink = 1, st_ctime = NativeConvert.ToTimeT(media.CreatedOn.ToUniversalTime()), st_mtime = NativeConvert.ToTimeT(media.UpdatedOn.ToUniversalTime()), st_blksize = 512, st_blocks = (long)(media.Size / 512), st_ino = media.Id, st_size = (long)media.Size }; } } if (handle <= 0) { return(Errno.ENOENT); } info.Handle = new IntPtr(handle); _fileStatHandleCache[handle] = stat; return(0); }
protected override Errno OnAccessPath(string path, AccessModes mode) { string[] pieces = _vfs.SplitPath(path); if (pieces.Length == 0) { return(mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0); } long romSetId = _vfs.GetRomSetId(pieces[0]); if (romSetId <= 0) { return(Errno.ENOENT); } RomSet romSet = _vfs.GetRomSet(romSetId); if (romSet == null) { return(Errno.ENOENT); } if (pieces.Length == 1) { return(mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0); } CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]); if (machine == null) { return(Errno.ENOENT); } if (pieces.Length == 2) { return(mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0); } CachedFile file = _vfs.GetFile(machine.Id, pieces[2]); 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) { if (pieces.Length > 3) { return(Errno.ENOSYS); } return(mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0); } CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]); if (media == null) { return(Errno.ENOENT); } if (pieces.Length > 3) { return(Errno.ENOSYS); } return(mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0); }