Exemplo n.º 1
0
        private bool applyPartitionTableFixes(NStream inStream, List <string> requiredFiles, Settings settings, RecoveryData rec)
        {
            bool updateAdded = false;

            try
            {
                if (!_hdr.Partitions.Any(a => a.Type == PartitionType.Update))                                                   //missing update partitions
                {
                    _hdr.AddPartitionPlaceHolder(new WiiPartitionPlaceHolder(inStream, null, PartitionType.Update, 0x50000, 0)); //ensure update is first
                    _log?.LogDetail("Added missing update partition entry placeholder");
                    updateAdded = true;
                }

                //assumes that no partitions have the same type (vc is always different types). Channels are before data, vc is after data in table 1
                int  prtCount  = _hdr.Partitions.Count(a => a.Type != PartitionType.Update && a.Type != PartitionType.Data);
                bool truncated = _hdr.Partitions.Any(a => inStream.RealPosition(a.DiscOffset) >= inStream.SourceSize); //partitions after file ends

                if (prtCount == 0 || truncated)
                {
                    if (truncated)
                    {
                        _hdr.RemovePartitionChannels();
                        _log?.LogDetail("Removed all channels/VC as some partitions were after the file ends");
                    }
                    bool after = _hdr.Partitions.FirstOrDefault(a => a.Type == PartitionType.Data)?.DiscOffset == 0xF800000;
                    Tuple <string, string, string, uint>[] channels = rec.WiiChanData.Union(rec.WiiOtherChanData).Where(a => a.Item2 == inStream.Id8).OrderBy(a => a.Item1).ToArray();
                    Tuple <string, int> known = settings.RedumpChannels.FirstOrDefault(a => a.Item1 == inStream.Id8);

                    if (channels.Length == 1)
                    {
                        _log?.LogDetail("Added missing channel partition entry");
                        _hdr.AddPartitionPlaceHolder(new WiiPartitionPlaceHolder(inStream, Path.Combine(settings.RecoveryFilesPath, channels[0].Item1), PartitionType.Channel, after ? 0 : 0xf800000, 0)); //ensure update is first
                        requiredFiles.Add(Path.Combine(settings.RecoveryFilesPath, channels[0].Item1));
                    }
                    else
                    {
                        foreach (Tuple <string, string, string, uint> part in channels)
                        {
                            PartitionType type = (PartitionType)((uint)part.Item3[0] << 24 | (uint)part.Item3[1] << 16 | (uint)part.Item3[2] << 8 | (uint)part.Item3[3] << 0);

                            _log?.LogDetail(string.Format("Added missing VC partition entry - {0}: {1}", part.Item3, part.Item1));
                            if (!_hdr.Partitions.Any(a => a.Type == type))
                            {
                                _hdr.AddPartitionPlaceHolder(new WiiPartitionPlaceHolder(inStream, Path.Combine(settings.RecoveryFilesPath, part.Item1), type, 0, 1)); //0 offset until we get the data partition
                                requiredFiles.Add(Path.Combine(settings.RecoveryFilesPath, part.Item1));
                            }
                        }
                    }

                    if (known != null && known.Item2 != channels.Length)
                    {
                        _log?.LogDetail(string.Format("!! Known partitions mismatch: {0} known, {1} found - Add all {2}_* to Recovery Partitions folder and retry", known.Item2.ToString(), channels.Length.ToString(), inStream.Id8));
                    }
                }
                return(updateAdded);
            }
            catch (Exception ex)
            {
                throw new HandledException(ex, "RestoreReaderWii.applyPartitionTableFixes");
            }
        }