Exemple #1
0
        private void ReallocateBlockCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (_cache.Engine < EngineType.SecondGeneration || (_cache.Engine == EngineType.ThirdGeneration && _cache.HeaderSize == 0x800))
            {
                MetroMessageBox.Show("Tag Block Reallocator", "Only second and third generation cache files are currently supported by the block reallocator.");
                return;
            }

            var field = GetWrappedField(e.OriginalSource) as TagBlockData;

            if (field == null)
            {
                return;
            }
            var oldCount = field.Length;
            var newCount = MetroTagBlockReallocator.Show(_cache, field);

            if (newCount == null || newCount == oldCount)
            {
                return;                 // Canceled
            }
            var  oldAddress = field.FirstElementAddress;
            var  oldSize    = field.Length * field.ElementSize;
            var  newSize    = (int)newCount * field.ElementSize;
            long newAddress;

            using (var stream = _fileManager.OpenReadWrite())
            {
                // Reallocate the block
                newAddress = _cache.Allocator.Reallocate(oldAddress, (int)oldSize, (int)newSize, (uint)field.Align, stream);
                _cache.SaveChanges(stream);

                // If the block was made larger, zero extra data and null tagrefs
                if (newAddress != 0 && newSize > oldSize)
                {
                    stream.SeekTo(_cache.MetaArea.PointerToOffset(newAddress) + oldSize);
                    StreamUtil.Fill(stream, 0, (int)(newSize - oldSize));

                    var tagRefLayout = _buildInfo.Layouts.GetLayout("tag reference");
                    var groupOffset  = tagRefLayout.GetFieldOffset("tag group magic");
                    var datumOffset  = tagRefLayout.GetFieldOffset("datum index");

                    //go through each new page and write null for any tagrefs
                    for (int i = oldCount; i < newCount; i++)
                    {
                        var entryStart = _cache.MetaArea.PointerToOffset(newAddress) + (field.ElementSize * i);
                        foreach (MetaField mf in field.Template)
                        {
                            if (mf.GetType() != typeof(TagRefData))
                            {
                                continue;
                            }
                            var tagref = (TagRefData)mf;
                            if (tagref.WithGroup)
                            {
                                stream.SeekTo(entryStart + tagref.Offset + groupOffset);
                                stream.WriteInt32(-1);
                                stream.SeekTo(entryStart + tagref.Offset + datumOffset);
                                stream.WriteInt32(-1);
                            }
                            else
                            {
                                //no group, write to field offset without adding anything
                                stream.SeekTo(entryStart + tagref.Offset);
                                stream.WriteInt32(-1);
                            }
                        }
                    }
                }
            }

            // Changing these causes a read from the file, so the stream has to be closed first
            field.Length = (int)newCount;
            field.FirstElementAddress = newAddress;

            using (var stream = _fileManager.OpenReadWrite())
            {
                // Force a save back to the file
                var changes = new FieldChangeSet();
                changes.MarkChanged(field);
                var metaUpdate = new MetaWriter(stream, (uint)_tag.RawTag.MetaLocation.AsOffset(), _cache, _buildInfo,
                                                MetaWriter.SaveType.File, changes, _stringIdTrie);
                metaUpdate.WriteFields(_pluginVisitor.Values);
                _fileChanges.MarkUnchanged(field);
            }
            if (newAddress == oldAddress)
            {
                MetroMessageBox.Show("Tag Block Reallocator - Assembly",
                                     "The tag block was resized successfully. Its address did not change.");
            }
            else if (oldAddress == 0)
            {
                MetroMessageBox.Show("Tag Block Reallocator - Assembly",
                                     "The tag block was allocated successfully. Its address is 0x" + newAddress.ToString("X8") + ".");
            }
            else if (newAddress != 0)
            {
                MetroMessageBox.Show("Tag Block Reallocator - Assembly",
                                     "The tag block was reallocated successfully. Its new address is 0x" + newAddress.ToString("X8") + ".");
            }
            else
            {
                MetroMessageBox.Show("Tag Block Reallocator - Assembly",
                                     "The tag block was freed successfully.");
            }
        }
        private void ReallocateCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var field = GetWrappedField(e.OriginalSource) as ReflexiveData;

            if (field == null)
            {
                return;
            }
            var newCount = MetroTagBlockReallocator.Show(_cache, field);

            if (newCount == null || (int)newCount == field.Length)
            {
                return;                 // Canceled
            }
            var  oldAddress = field.FirstEntryAddress;
            var  oldSize    = field.Length * field.EntrySize;
            var  newSize    = (int)newCount * field.EntrySize;
            uint newAddress;

            using (var stream = _fileManager.OpenReadWrite())
            {
                // Reallocate the block
                newAddress = _cache.Allocator.Reallocate(oldAddress, (int)oldSize, (int)newSize, (uint)field.Align, stream);
                _cache.SaveChanges(stream);

                // If the block was made larger, zero extra data
                if (newAddress != 0 && newSize > oldSize)
                {
                    stream.SeekTo(_cache.MetaArea.PointerToOffset(newAddress) + oldSize);
                    StreamUtil.Fill(stream, 0, (int)(newSize - oldSize));
                }
            }

            // Changing these causes a read from the file, so the stream has to be closed first
            field.Length            = (int)newCount;
            field.FirstEntryAddress = newAddress;

            using (var stream = _fileManager.OpenReadWrite())
            {
                // Force a save back to the file
                var changes = new FieldChangeSet();
                changes.MarkChanged(field);
                var metaUpdate = new MetaWriter(stream, (uint)_tag.RawTag.MetaLocation.AsOffset(), _cache, _buildInfo,
                                                MetaWriter.SaveType.File, changes, _stringIdTrie);
                metaUpdate.WriteFields(_pluginVisitor.Values);
                _fileChanges.MarkUnchanged(field);
            }
            if (newAddress == oldAddress)
            {
                MetroMessageBox.Show("Tag Block Reallocator - Assembly",
                                     "The tag block was resized successfully. Its address did not change.");
            }
            else if (oldAddress == 0)
            {
                MetroMessageBox.Show("Tag Block Reallocator - Assembly",
                                     "The tag block was allocated successfully. Its address is 0x" + newAddress.ToString("X8") + ".");
            }
            else if (newAddress != 0)
            {
                MetroMessageBox.Show("Tag Block Reallocator - Assembly",
                                     "The tag block was reallocated successfully. Its new address is 0x" + newAddress.ToString("X8") + ".");
            }
            else
            {
                MetroMessageBox.Show("Tag Block Reallocator - Assembly",
                                     "The tag block was freed successfully.");
            }
        }