コード例 #1
0
ファイル: FileSystem.cs プロジェクト: skudi/NKit
        public static FileSystem Parse(Stream fstData, long fstOffset, long length, string id, bool isGc)
        {
            MemorySection ms = MemorySection.Read(fstData, length);
            FstFile       ff = new FstFile(null)
            {
                Name = "fst.bin", DataOffset = fstOffset, Offset = NStream.DataToOffset(fstOffset, !isGc), IsNonFstFile = true, Length = (int)fstData.Length
            };

            return(Parse(ms, ff, id, isGc));
        }
コード例 #2
0
        private static uint recurseFst(MemorySection ms, FstFolder folder, long names, uint i, string id, bool isGc)
        {
            uint   j;
            uint   hdr  = ms.ReadUInt32B((int)(12 * i));
            long   name = names + hdr & 0x00ffffffL;
            int    type = (int)(hdr >> 24);
            string nm   = ms.ReadStringToNull((int)name, Encoding.GetEncoding("shift-jis"));
            uint   size = ms.ReadUInt32B((int)(12 * i + 8));

            if (type == 1)
            {
                FstFolder f = i == 0 ? folder : new FstFolder(folder)
                {
                    Name = nm
                };
                if (i != 0)
                {
                    folder.Folders.Add(f);
                }

                for (j = i + 1; j < size;)
                {
                    j = recurseFst(ms, f, names, j, id, isGc);
                }

                return(size);
            }
            else
            {
                int  pos  = (int)(12 * i + 4);
                long doff = ms.ReadUInt32B(pos) * (isGc ? 1L : 4L); //offset in data
                size = ms.ReadUInt32B((int)(12 * i + 8));
                long off = NStream.DataToOffset(doff, !isGc);       //offset in raw partition
                folder.Files.Add(new FstFile(folder)
                {
                    DataOffset = doff, Offset = off, Length = size, Name = nm, PartitionId = id, OffsetInFstFile = pos
                });
                return(i + 1);
            }
        }
コード例 #3
0
        public bool Unscrub(List <JunkRedumpPatch> junkPatches)
        {
            bool changed = false;
            //bool performCheck = true; //start on the assumption last was valid as it would be hassle to work out
            List <FstFile> nulls = new List <FstFile>();

            bool good = _data.IsValid(false);                                                    //forces decrypt and hash cache build and test - does not test data in blocks matchs H0 table

            Parallel.For(0, _data.UsedBlocks, bi => _unscrubValid[bi] = _data.BlockIsValid(bi)); //test data matches H0 table

            for (int bi = 0; bi < _data.UsedBlocks; bi++)
            {
                if (!_unscrubValid[bi])
                {
                    if (_junk == null)
                    {
                        _junk = new JunkStream(_partHdr.Id, _partHdr.DiscNo, _partHdr.PartitionDataSize);
                    }

                    _junk.Position = NStream.OffsetToData(this.Offset + _data.BlockDataOffset(bi), true);
                    _junk.Read(_data.Decrypted, _data.BlockDataOffset(bi), 0x7c00);
                    _data.MarkBlockUnscrubbedAndDirty(bi);
                    changed = true;
                }
            }

            if (junkPatches != null && junkPatches.Count != 0)
            {
                foreach (JunkRedumpPatch jp in junkPatches)
                {
                    if (jp.Offset >= this.DiscOffset && jp.Offset < this.DiscOffset + this.Size)
                    {
                        Array.Copy(jp.Data, 0, _data.Decrypted, jp.Offset - this.DiscOffset, jp.Data.Length);
                        _data.MarkBlockDirty((int)((jp.Offset - this.DiscOffset) / 0x8000));  //560de532
                    }
                }
            }

            if (changed)
            {
                good = _data.IsValid(true); //true as changes were made
                if (!good)
                {
                    bool zerod = false;
                    List <Tuple <long, int, FstFile> > h3Nulls = new List <Tuple <long, int, FstFile> >(_partHdr.ScrubManager.H3Nulls);

                    if (h3Nulls.Count != 0)
                    {
                        int dataLen = (int)NStream.HashedLenToData(this.Decrypted.Length);
                        foreach (Tuple <long, int, FstFile> n in h3Nulls)
                        {
                            if (n.Item1 >= this.DataOffset && n.Item1 < this.DataOffset + dataLen)
                            {
                                int idx = (int)((n.Item1 - this.DataOffset) / 0x7c00);
                                _data.MarkBlockDirty(idx);
                                int pos = (int)NStream.DataToOffset(n.Item1 - this.DataOffset, true);
                                Array.Clear(_data.Decrypted, pos, n.Item2);
                                zerod = true;
                            }
                        }
                    }
                    if (zerod)
                    {
                        good = _data.IsValid(true);
                    }
                    if (!good)
                    {
                        this.H3Errors++;
                    }
                }
            }

            return(changed);
        }