Пример #1
0
        public List <IsoTableEntryInfo> GetEntriesInfo(IList <IsoTableEntry> entries)
        {
            ProgressTotalChanged.NullSafeInvoke(entries.Count);
            List <IsoTableEntryInfo> result = new List <IsoTableEntryInfo>(entries.Count);

            int counter = 0;

            for (int i = 0; i < entries.Count - 1; i++)
            {
                IsoTableEntry entry          = entries[i];
                long          compressedSize = (entries[i + 1].Sector - entry.Sector) * _isoInfo.SectorSize - entry.Left;
                if (compressedSize < 1)
                {
                    ProgressIncrement.NullSafeInvoke(1);
                    continue;
                }

                long offset            = entry.Sector * _isoInfo.SectorSize;
                IsoTableEntryInfo info = new IsoTableEntryInfo(i, counter++, offset, compressedSize, entry.Flags);

                result.Add(info);
                ProgressIncrement.NullSafeInvoke(1);
            }

            return(result);
        }
Пример #2
0
        private void SafeReadAdditionalEntryInfo(IsoTableEntryInfo info)
        {
            try
            {
                if (info.CompressedSize < 4)
                {
                    return;
                }

                byte[] signature;
                using (Stream input = OpenStream(info.Offset, info.CompressedSize))
                    using (MemoryStream output = new MemoryStream(4))
                    {
                        if (!info.IsCompressed)
                        {
                            info.IsCompressed = (input.ReadByte() == 0x01);
                            input.Seek(-1, SeekOrigin.Current);
                        }

                        if (info.IsCompressed)
                        {
                            input.Seek(1, SeekOrigin.Current);
                            int uncompressedSize = input.ReadStruct <int>();
                            if (uncompressedSize < 4)
                            {
                                return;
                            }

                            LZSStream decompressStream = new LZSStream(input, output);
                            decompressStream.Decompress(4);
                            output.Flush();
                            signature = output.ToArray();
                            if (signature.Length == 0)
                            {
                                return;
                            }
                        }
                        else
                        {
                            signature = new byte[4];
                            input.EnsureRead(signature, 0, 4);
                        }
                    }
                info.Signature = (FFXFileSignatures)BitConverter.ToInt32(signature, 0);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Failed to read additional info of entry '{0}'", info.GetFileName());
            }
            finally
            {
                ProgressIncrement.NullSafeInvoke(1);
            }
        }
Пример #3
0
        public List <IsoTableEntry> GetEntries()
        {
            ProgressTotalChanged.NullSafeInvoke(_isoInfo.MaxEntriesCount);
            List <IsoTableEntry> entries = new List <IsoTableEntry>(_isoInfo.MaxEntriesCount);

            using (MemoryMappedViewStream input = _memory.CreateViewStream(_isoInfo.EntryTableOffset, _isoInfo.MaxEntriesCount * 4, MemoryMappedFileAccess.Read))
            {
                for (int i = 0; i < _isoInfo.MaxEntriesCount; i++)
                {
                    ProgressIncrement.NullSafeInvoke(1);

                    IsoTableEntry entry = input.ReadStruct <IsoTableEntry>();
                    if (entry.Sector == 0)
                    {
                        ProgressTotalChanged.NullSafeInvoke(i);
                        break;
                    }

                    entries.Add(entry);
                }
            }

            return(entries);
        }
Пример #4
0
        public async Task <IList <RegistryKey> > ParseAsync(string[][] a,
                                                            string[][] b,
                                                            IProgress <ProgressIncrement> progress)
        {
            var keys = new List <RegistryKey>();

            a = a.OrderBy(x => x[0]).ToArray();
            b = b.OrderBy(x => x[0]).ToArray();

            var checkedB  = new bool[b.Length];
            var inANotInB = new List <DiffingToken>();
            var inBNotInA = new List <DiffingToken>();
            var inBoth    = new List <DiffingToken>();
            var total     = a.Length + (int)Math.Round(b.Length * 1.25);
            var j         = 0;

            for (var i = 0; i < a.Length; i++)
            {
                var matchIndex = BinarySearch(b, a[i][0]);

                if (matchIndex < 0)
                {
                    inANotInB.Add(new DiffingToken
                    {
                        IsInA = true,
                        IsInB = false,
                        Token = a[i]
                    });
                }

                else
                {
                    checkedB[matchIndex] = true;
                    inBoth.Add(new DiffingToken
                    {
                        IsInA = true,
                        IsInB = true,
                        Token = a[i]
                    });
                }

                if (i % 4973 == 0)
                {
                    await Task.Run(() => progress.Report(new ProgressIncrement
                    {
                        Current = i,
                        Message = $"Diffing files... ({i} of {total})",
                        Total   = total
                    }));
                }

                j = i;
            }

            for (var i = 0; i < b.Length; i++)
            {
                if (checkedB[i])
                {
                    continue;
                }

                var matchIndex = BinarySearch(a, b[i][0]);

                if (matchIndex < 0)
                {
                    inBNotInA.Add(new DiffingToken
                    {
                        IsInA = false,
                        IsInB = true,
                        Token = b[i]
                    });
                }


                if ((j + i) % 4973 == 0)
                {
                    await Task.Run(() => progress.Report(new ProgressIncrement
                    {
                        Current = j + i,
                        Message = $"Diffing files... ({j + i} of {total})",
                        Total   = total
                    }));
                }
            }

            var combined = inBoth
                           .Concat(inANotInB)
                           .Concat(inBNotInA)
                           .OrderBy(x => x.Token[0])
                           .ToArray();

            for (var i = 0; i < combined.Length; i++)
            {
                var token = combined[i];

                if (token.Token.Length == 1)
                {
                    var key = new RegistryKey
                    {
                        IsInA = token.IsInA,
                        IsInB = token.IsInB
                    };
                    i = await ParseKeyAsync(token, combined, i + 1, key, progress);

                    if (i % 3726 == 0)
                    {
                        var progressIncrement = new ProgressIncrement
                        {
                            Current = i + 1,
                            Message = $"Building view... ({i + 1} of {combined.Length})",
                            Total   = combined.Length
                        };
                        await Task.Run(() => progress?.Report(progressIncrement));
                    }

                    keys.Add(key);
                }
            }

            await Task.Run(() => progress?.Report(new ProgressIncrement
            {
                Current = combined.Length,
                Message = "Finished diffing result.",
                Total   = combined.Length
            }));

            return(keys);
        }
Пример #5
0
        private static async Task <int> ParseKeyAsync(DiffingToken token,
                                                      DiffingToken[] tokens,
                                                      int startIndex,
                                                      RegistryKey key,
                                                      IProgress <ProgressIncrement> progress,
                                                      RegistryKey parent = null)
        {
            bool ShouldContinue(int index)
            {
                return(index < tokens.Length && tokens[index].Token[0].StartsWith(token.Token[0]));
            }

            key.Path          = token.Token[0];
            key.Name          = token.Token[0].Split('\\').Last();
            key.HasDifference = !key.IsInB || !key.IsInA;

            if (key.HasDifference && parent != null)
            {
                parent.HasDifference = true;
            }

            for (; ShouldContinue(startIndex); startIndex++)
            {
                var nextToken = tokens[startIndex];

                // Registry key.
                if (nextToken.Token.Length == 1)
                {
                    var nextKey = new RegistryKey
                    {
                        IsInA = nextToken.IsInA,
                        IsInB = nextToken.IsInB
                    };
                    startIndex = await ParseKeyAsync(nextToken, tokens, startIndex + 1, nextKey, progress, key);

                    if (key.HasDifference && parent != null)
                    {
                        parent.HasDifference = true;
                    }

                    key.Keys.Add(nextKey);
                }

                // Registry value.
                else if (nextToken.Token.Length == 3)
                {
                    key.Values.Add(ParseValue(nextToken, key));

                    if (key.HasDifference && parent != null)
                    {
                        parent.HasDifference = true;
                    }
                }

                if (startIndex + 1 % 3726 == 0)
                {
                    var progressIncrement = new ProgressIncrement
                    {
                        Current = startIndex + 1,
                        Message = $"Building view... ({startIndex + 1} of {tokens.Length})",
                        Total   = tokens.Length
                    };
                    await Task.Run(() => progress?.Report(progressIncrement));
                }
            }

            return(--startIndex);
        }