示例#1
0
        protected override Errno OnOpenDirectory(string directory, OpenedPathInfo info)
        {
            try
            {
                if (directory == "/")
                {
                    List <DirectoryEntry> entries = new List <DirectoryEntry>
                    {
                        new DirectoryEntry("."),
                        new DirectoryEntry("..")
                    };

                    entries.AddRange(_vfs.GetRootEntries().Select(e => new DirectoryEntry(e)));

                    _lastHandle++;
                    info.Handle = new IntPtr(_lastHandle);

                    _directoryCache[_lastHandle] = entries;

                    return(0);
                }

                string[] pieces = directory.Split("/", StringSplitOptions.RemoveEmptyEntries);

                if (pieces.Length == 0)
                {
                    return(Errno.ENOENT);
                }

                long romSetId = _vfs.GetRomSetId(pieces[0]);

                if (romSetId <= 0)
                {
                    return(Errno.ENOENT);
                }

                RomSet romSet = _vfs.GetRomSet(romSetId);

                if (romSet == null)
                {
                    return(Errno.ENOENT);
                }

                ConcurrentDictionary <string, CachedMachine> machines = _vfs.GetMachinesFromRomSet(romSetId);

                if (pieces.Length == 1)
                {
                    List <DirectoryEntry> entries = new List <DirectoryEntry>
                    {
                        new DirectoryEntry("."),
                        new DirectoryEntry("..")
                    };

                    entries.AddRange(machines.Select(mach => new DirectoryEntry(mach.Key)));

                    _lastHandle++;
                    info.Handle = new IntPtr(_lastHandle);

                    _directoryCache[_lastHandle] = entries;

                    return(0);
                }

                CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);

                if (machine == null)
                {
                    return(Errno.ENOENT);
                }

                ConcurrentDictionary <string, CachedFile>  cachedMachineFiles  = _vfs.GetFilesFromMachine(machine.Id);
                ConcurrentDictionary <string, CachedDisk>  cachedMachineDisks  = _vfs.GetDisksFromMachine(machine.Id);
                ConcurrentDictionary <string, CachedMedia> cachedMachineMedias = _vfs.GetMediasFromMachine(machine.Id);

                if (pieces.Length == 2)
                {
                    List <DirectoryEntry> entries = new List <DirectoryEntry>
                    {
                        new DirectoryEntry("."),
                        new DirectoryEntry("..")
                    };

                    entries.AddRange(cachedMachineFiles.Select(file => new DirectoryEntry(file.Key)));
                    entries.AddRange(cachedMachineDisks.Select(disk => new DirectoryEntry(disk.Key + ".chd")));
                    entries.AddRange(cachedMachineMedias.Select(media => new DirectoryEntry(media.Key + ".aif")));

                    _lastHandle++;
                    info.Handle = new IntPtr(_lastHandle);

                    _directoryCache[_lastHandle] = entries;

                    return(0);
                }

                // TODO: DATs with subfolders as game name
                if (pieces.Length >= 3)
                {
                    return(Errno.EISDIR);
                }

                return(Errno.ENOENT);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);

                throw;
            }
        }
示例#2
0
        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);
        }
示例#3
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);
        }
示例#4
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);
        }
示例#5
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);
        }
示例#6
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);
        }