Esempio n. 1
0
        string BuildFile(IReadOnlyFilesystem fs, string path, long length)
        {
            byte[] buffer = new byte[length];
            fs.Read(path, 0, length, ref buffer);

            return(Md5Context.Data(buffer, out _));
        }
Esempio n. 2
0
        void TestFile(IReadOnlyFilesystem fs, string path, string md5, long length, string testFile)
        {
            byte[] buffer = new byte[length];
            Errno  ret    = fs.Read(path, 0, length, ref buffer);

            Assert.AreEqual(Errno.NoError, ret, $"Unexpected error {ret} when reading \"{path}\" in {testFile}");

            string data = Md5Context.Data(buffer, out _);

            Assert.AreEqual(md5, data, $"Got MD5 {data} for \"{path}\" in {testFile} but expected {md5}");
        }
Esempio n. 3
0
        public void Read()
        {
            byte[] buffer = new byte[0];
            Errno  error  = _fs.Read("Content/0000000000000000/FFFE07DF/00040000", 0, 0, ref buffer);

            Assert.AreEqual(Errno.IsDirectory, error);

            error = _fs.Read("Content/0000000000000000/FFFE07DF/00040000/ContentCache", 0, 0, ref buffer);
            Assert.AreEqual(Errno.NoSuchFile, error);

            error = _fs.Read("Content/0000000000000000/FFFE07DF/00040000/ContentCache.pkg", 0, 0, ref buffer);
            Assert.AreEqual(Errno.NoError, error);
            Assert.AreEqual(0, buffer.Length);

            Assert.AreEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
                            Sha256Context.Data(buffer, out _));

            error = _fs.Read("Content/0000000000000000/FFFE07DF/00040000/ContentCache.pkg", 1, 16, ref buffer);
            Assert.AreEqual(Errno.NoError, error);
            Assert.AreEqual(16, buffer.Length);

            Assert.AreEqual("f73a941675b8df16b0fc908f242c3c51382c5b159e709e0f9ffc1e5aac35f77d",
                            Sha256Context.Data(buffer, out _));

            error = _fs.Read("Content/0000000000000000/FFFE07DF/00040000/ContentCache.pkg", 248, 131072, ref buffer);
            Assert.AreEqual(Errno.NoError, error);
            Assert.AreEqual(85768, buffer.Length);

            Assert.AreEqual("19caf1365e1b7d5446ca0c2518d15e94c3ab0faaf2f8f3b31c9e1656dff57bd9",
                            Sha256Context.Data(buffer, out _));

            error = _fs.Read("Content/0000000000000000/FFFE07DF/00040000/ContentCache.pkg", 131072, 0, ref buffer);
            Assert.AreEqual(Errno.InvalidArgument, error);
        }
Esempio n. 4
0
        public void Read()
        {
            byte[] buffer = new byte[0];
            Errno  error  = _fs.Read("49470015", 0, 0, ref buffer);

            Assert.AreEqual(Errno.IsDirectory, error);

            error = _fs.Read("49470015/TitleImage", 0, 0, ref buffer);
            Assert.AreEqual(Errno.NoSuchFile, error);

            error = _fs.Read("49470015/7AC2FE88C908/savedata.dat", 0, 0, ref buffer);
            Assert.AreEqual(Errno.NoError, error);
            Assert.AreEqual(0, buffer.Length);

            Assert.AreEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
                            Sha256Context.Data(buffer, out _));

            error = _fs.Read("49470015/7AC2FE88C908/savedata.dat", 1, 16, ref buffer);
            Assert.AreEqual(Errno.NoError, error);
            Assert.AreEqual(16, buffer.Length);

            Assert.AreEqual("ff82559d2d0c610ac25b78dcb53a8312e32b56192044deb1f01540581bd54e80",
                            Sha256Context.Data(buffer, out _));

            error = _fs.Read("49470015/7AC2FE88C908/savedata.dat", 248, 131072, ref buffer);
            Assert.AreEqual(Errno.NoError, error);
            Assert.AreEqual(61996, buffer.Length);

            Assert.AreEqual("2eb0d62a96ad28473ce0dd67052efdfae31f371992e1d8309beeeff6f2b46a59",
                            Sha256Context.Data(buffer, out _));

            error = _fs.Read("49470015/7AC2FE88C908/savedata.dat", 131072, 0, ref buffer);
            Assert.AreEqual(Errno.InvalidArgument, error);
        }
Esempio n. 5
0
        static void ExtractFilesInDir(string path, IReadOnlyFilesystem fs, string volumeName, string outputDir,
                                      bool doXattrs)
        {
            if (path.StartsWith('/'))
            {
                path = path.Substring(1);
            }

            Errno error = fs.ReadDir(path, out List <string> directory);

            if (error != Errno.NoError)
            {
                AaruConsole.ErrorWriteLine("Error {0} reading root directory {0}", error.ToString());

                return;
            }

            foreach (string entry in directory)
            {
                error = fs.Stat(path + "/" + entry, out FileEntryInfo stat);

                if (error == Errno.NoError)
                {
                    string outputPath;

                    if (stat.Attributes.HasFlag(FileAttributes.Directory))
                    {
                        outputPath = Path.Combine(outputDir, fs.XmlFsType.Type, volumeName, path, entry);

                        Directory.CreateDirectory(outputPath);

                        AaruConsole.WriteLine("Created subdirectory at {0}", outputPath);

                        ExtractFilesInDir(path + "/" + entry, fs, volumeName, outputDir, doXattrs);

                        var di = new DirectoryInfo(outputPath);

                        #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
                        try
                        {
                            if (stat.CreationTimeUtc.HasValue)
                            {
                                di.CreationTimeUtc = stat.CreationTimeUtc.Value;
                            }
                        }
                        catch
                        {
                            // ignored
                        }

                        try
                        {
                            if (stat.LastWriteTimeUtc.HasValue)
                            {
                                di.LastWriteTimeUtc = stat.LastWriteTimeUtc.Value;
                            }
                        }
                        catch
                        {
                            // ignored
                        }

                        try
                        {
                            if (stat.AccessTimeUtc.HasValue)
                            {
                                di.LastAccessTimeUtc = stat.AccessTimeUtc.Value;
                            }
                        }
                        catch
                        {
                            // ignored
                        }
                        #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body

                        continue;
                    }

                    FileStream outputFile;

                    if (doXattrs)
                    {
                        error = fs.ListXAttr(path + "/" + entry, out List <string> xattrs);

                        if (error == Errno.NoError)
                        {
                            foreach (string xattr in xattrs)
                            {
                                byte[] xattrBuf = new byte[0];
                                error = fs.GetXattr(path + "/" + entry, xattr, ref xattrBuf);

                                if (error != Errno.NoError)
                                {
                                    continue;
                                }

                                outputPath = Path.Combine(outputDir, fs.XmlFsType.Type, volumeName, path, ".xattrs", xattr);

                                Directory.CreateDirectory(outputPath);

                                outputPath = Path.Combine(outputPath, entry);

                                if (!File.Exists(outputPath))
                                {
                                    outputFile = new FileStream(outputPath, FileMode.CreateNew, FileAccess.ReadWrite,
                                                                FileShare.None);

                                    outputFile.Write(xattrBuf, 0, xattrBuf.Length);
                                    outputFile.Close();
                                    var fi = new FileInfo(outputPath);
                                    #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
                                    try
                                    {
                                        if (stat.CreationTimeUtc.HasValue)
                                        {
                                            fi.CreationTimeUtc = stat.CreationTimeUtc.Value;
                                        }
                                    }
                                    catch
                                    {
                                        // ignored
                                    }

                                    try
                                    {
                                        if (stat.LastWriteTimeUtc.HasValue)
                                        {
                                            fi.LastWriteTimeUtc = stat.LastWriteTimeUtc.Value;
                                        }
                                    }
                                    catch
                                    {
                                        // ignored
                                    }

                                    try
                                    {
                                        if (stat.AccessTimeUtc.HasValue)
                                        {
                                            fi.LastAccessTimeUtc = stat.AccessTimeUtc.Value;
                                        }
                                    }
                                    catch
                                    {
                                        // ignored
                                    }
                                    #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
                                    AaruConsole.WriteLine("Written {0} bytes of xattr {1} from file {2} to {3}",
                                                          xattrBuf.Length, xattr, entry, outputPath);
                                }
                                else
                                {
                                    AaruConsole.ErrorWriteLine("Cannot write xattr {0} for {1}, output exists", xattr,
                                                               entry);
                                }
                            }
                        }
                    }

                    outputPath = Path.Combine(outputDir, fs.XmlFsType.Type, volumeName, path);

                    Directory.CreateDirectory(outputPath);

                    outputPath = Path.Combine(outputPath, entry);

                    if (!File.Exists(outputPath))
                    {
                        byte[] outBuf = new byte[0];

                        error = fs.Read(path + "/" + entry, 0, stat.Length, ref outBuf);

                        if (error == Errno.NoError)
                        {
                            outputFile = new FileStream(outputPath, FileMode.CreateNew, FileAccess.ReadWrite,
                                                        FileShare.None);

                            outputFile.Write(outBuf, 0, outBuf.Length);
                            outputFile.Close();
                            var fi = new FileInfo(outputPath);
                            #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
                            try
                            {
                                if (stat.CreationTimeUtc.HasValue)
                                {
                                    fi.CreationTimeUtc = stat.CreationTimeUtc.Value;
                                }
                            }
                            catch
                            {
                                // ignored
                            }

                            try
                            {
                                if (stat.LastWriteTimeUtc.HasValue)
                                {
                                    fi.LastWriteTimeUtc = stat.LastWriteTimeUtc.Value;
                                }
                            }
                            catch
                            {
                                // ignored
                            }

                            try
                            {
                                if (stat.AccessTimeUtc.HasValue)
                                {
                                    fi.LastAccessTimeUtc = stat.AccessTimeUtc.Value;
                                }
                            }
                            catch
                            {
                                // ignored
                            }
                            #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
                            AaruConsole.WriteLine("Written {0} bytes of file {1} to {2}", outBuf.Length, entry,
                                                  outputPath);
                        }
                        else
                        {
                            AaruConsole.ErrorWriteLine("Error {0} reading file {1}", error, entry);
                        }
                    }
                    else
                    {
                        AaruConsole.ErrorWriteLine("Cannot write file {0}, output exists", entry);
                    }
                }
                else
                {
                    AaruConsole.ErrorWriteLine("Error reading file {0}", entry);
                }
            }
        }
Esempio n. 6
0
File: Files.cs Progetto: paulyc/Aaru
        ContentsFileType SidecarFile(IReadOnlyFilesystem filesystem, string path, string filename, FileEntryInfo stat)
        {
            var file          = new ContentsFileType();
            var fileChkWorker = new Checksum();

            if (stat.AccessTimeUtc.HasValue)
            {
                file.accessTime          = stat.AccessTimeUtc.Value;
                file.accessTimeSpecified = true;
            }

            file.attributes = (ulong)stat.Attributes;

            if (stat.BackupTimeUtc.HasValue)
            {
                file.backupTime          = stat.BackupTimeUtc.Value;
                file.backupTimeSpecified = true;
            }

            if (stat.CreationTimeUtc.HasValue)
            {
                file.creationTime          = stat.CreationTimeUtc.Value;
                file.creationTimeSpecified = true;
            }

            if (stat.DeviceNo.HasValue)
            {
                file.deviceNumber          = stat.DeviceNo.Value;
                file.deviceNumberSpecified = true;
            }

            file.inode = stat.Inode;

            if (stat.LastWriteTimeUtc.HasValue)
            {
                file.lastWriteTime          = stat.LastWriteTimeUtc.Value;
                file.lastWriteTimeSpecified = true;
            }

            file.length = (ulong)stat.Length;
            file.links  = stat.Links;
            file.name   = filename;

            if (stat.GID.HasValue)
            {
                file.posixGroupId          = stat.GID.Value;
                file.posixGroupIdSpecified = true;
            }

            if (stat.Mode.HasValue)
            {
                file.posixMode          = stat.Mode.Value;
                file.posixModeSpecified = true;
            }

            if (stat.UID.HasValue)
            {
                file.posixUserId          = stat.UID.Value;
                file.posixUserIdSpecified = true;
            }

            if (stat.StatusChangeTimeUtc.HasValue)
            {
                file.statusChangeTime          = stat.StatusChangeTimeUtc.Value;
                file.statusChangeTimeSpecified = true;
            }

            byte[] data = new byte[0];

            if (stat.Length > 0)
            {
                long position = 0;
                UpdateStatus($"Hashing file {path}/{filename}...");
                InitProgress2();

                while (position < stat.Length - 1048576)
                {
                    if (_aborted)
                    {
                        return(file);
                    }

                    data = new byte[1048576];
                    filesystem.Read(path + "/" + filename, position, 1048576, ref data);

                    UpdateProgress2("Hashing file byte {0} of {1}", position, stat.Length);

                    fileChkWorker.Update(data);

                    position += 1048576;
                }

                data = new byte[stat.Length - position];
                filesystem.Read(path + "/" + filename, position, stat.Length - position, ref data);

                UpdateProgress2("Hashing file byte {0} of {1}", position, stat.Length);

                fileChkWorker.Update(data);

                EndProgress();

                file.Checksums = fileChkWorker.End().ToArray();
            }
            else
            {
                file.Checksums = _emptyChecksums;
            }

            Errno ret = filesystem.ListXAttr(path + "/" + filename, out List <string> xattrs);

            if (ret != Errno.NoError)
            {
                return(file);
            }

            List <ExtendedAttributeType> xattrTypes = new List <ExtendedAttributeType>();

            foreach (string xattr in xattrs)
            {
                ret = filesystem.GetXattr(path + "/" + filename, xattr, ref data);

                if (ret != Errno.NoError)
                {
                    continue;
                }

                var xattrChkWorker = new Checksum();
                xattrChkWorker.Update(data);

                xattrTypes.Add(new ExtendedAttributeType
                {
                    Checksums = xattrChkWorker.End().ToArray(),
                    length    = (ulong)data.Length,
                    name      = xattr
                });
            }

            if (xattrTypes.Count > 0)
            {
                file.ExtendedAttributes = xattrTypes.OrderBy(x => x.name).ToArray();
            }

            return(file);
        }
Esempio n. 7
0
        void TestDirectory(IReadOnlyFilesystem fs, string path, Dictionary <string, FileData> children, string testFile)
        {
            Errno ret = fs.ReadDir(path, out List <string> contents);

            Assert.AreEqual(Errno.NoError, ret,
                            $"Unexpected error {ret} when reading directory \"{path}\" of {testFile}.");

            if (children.Count == 0 &&
                contents.Count == 0)
            {
                return;
            }

            if (path == "/")
            {
                path = "";
            }

            List <string> expectedNotFound = new List <string>();

            foreach (KeyValuePair <string, FileData> child in children)
            {
                string childPath = $"{path}/{child.Key}";
                ret = fs.Stat(childPath, out FileEntryInfo stat);

                if (ret == Errno.NoSuchFile ||
                    !contents.Contains(child.Key))
                {
                    expectedNotFound.Add(child.Key);

                    continue;
                }

                contents.Remove(child.Key);

                Assert.AreEqual(Errno.NoError, ret,
                                $"Unexpected error {ret} retrieving stats for \"{childPath}\" in {testFile}");

                stat.Should().BeEquivalentTo(child.Value.Info, $"Wrong info for \"{childPath}\" in {testFile}");

                byte[] buffer = new byte[0];

                if (child.Value.Info.Attributes.HasFlag(FileAttributes.Directory))
                {
                    ret = fs.Read(childPath, 0, 1, ref buffer);

                    Assert.AreEqual(Errno.IsDirectory, ret,
                                    $"Got wrong data for directory \"{childPath}\" in {testFile}");

                    Assert.IsNotNull(child.Value.Children,
                                     $"Contents for \"{childPath}\" in {testFile} must be defined in unit test declaration!");

                    if (child.Value.Children != null)
                    {
                        TestDirectory(fs, childPath, child.Value.Children, testFile);
                    }
                }
                else if (child.Value.Info.Attributes.HasFlag(FileAttributes.Symlink))
                {
                    ret = fs.ReadLink(childPath, out string link);

                    Assert.AreEqual(Errno.NoError, ret,
                                    $"Got wrong data for symbolic link \"{childPath}\" in {testFile}");

                    Assert.AreEqual(child.Value.LinkTarget, link,
                                    $"Invalid target for symbolic link \"{childPath}\" in {testFile}");
                }
                else
                {
                    // This ensure the buffer does not hang for collection
                    TestFile(fs, childPath, child.Value.MD5, child.Value.Info.Length, testFile);
                }

                ret = fs.ListXAttr(childPath, out List <string> xattrs);

                if (ret == Errno.NotSupported)
                {
                    Assert.IsNull(child.Value.XattrsWithMd5,
                                  $"Defined extended attributes for \"{childPath}\" in {testFile} are not supported by filesystem.");

                    continue;
                }

                Assert.AreEqual(Errno.NoError, ret,
                                $"Unexpected error {ret} when listing extended attributes for \"{childPath}\" in {testFile}");

                if (xattrs.Count > 0)
                {
                    Assert.IsNotNull(child.Value.XattrsWithMd5,
                                     $"Extended attributes for \"{childPath}\" in {testFile} must be defined in unit test declaration!");
                }

                if (xattrs.Count > 0 ||
                    child.Value.XattrsWithMd5?.Count > 0)
                {
                    TestFileXattrs(fs, childPath, child.Value.XattrsWithMd5, testFile);
                }
            }

            Assert.IsEmpty(expectedNotFound,
                           $"Could not find the children of \"{path}\" in {testFile}: {string.Join(" ", expectedNotFound)}");

            Assert.IsEmpty(contents,
                           $"Found the following unexpected children of \"{path}\" in {testFile}: {string.Join(" ", contents)}");
        }