示例#1
0
        private bool repairBlocks(WiiPartitionGroupSection wp, int scrubbed, int blocks, bool forceBlockChanged, bool fstBlocks)
        {
            bool isValid = true;

            if (scrubbed == 0)
            {
                isValid = wp.IsValid(true);
            }
            else if (scrubbed == blocks) //copy the first data sector hash sector for each block (to pretend we still had the scrubbed hashes)
            {
                Parallel.For(0, blocks, i => Array.Copy(wp.Decrypted, (i * 0x8000) + 0x400, wp.Decrypted, i * 0x8000, 0x400));
            }
            return(isValid);
        }
示例#2
0
        internal WiiPartitionSection(NStream stream, WiiDiscHeaderSection header, NStream readPartitionStream, long discOffset)
        {
            _stream     = readPartitionStream;
            _discHdr    = header;
            _partialFst = 0;
            _seek       = -1;

            //calc the header
            byte[] partHdrTmp = new byte[0x400];             //read enough to get all the details we need
            _stream.Read(partHdrTmp, 0, partHdrTmp.Length);  //need to read this to get header length
            byte[] partHdrLen = new byte[4];
            Array.Copy(partHdrTmp, 0x2b8, partHdrLen, 0, 4); //location of partion header length
            long hdrLen = bigEndian(BitConverter.ToUInt32(partHdrLen, 0)) * 4;

            byte[] partHdr = new byte[hdrLen];
            Array.Copy(partHdrTmp, partHdr, partHdrTmp.Length);
            _stream.Read(partHdr, partHdrTmp.Length, partHdr.Length - partHdrTmp.Length);

            Header = new WiiPartitionHeaderSection(_discHdr, readPartitionStream, discOffset, partHdr, partHdr.Length);
            if (Header.IsRvtH)
            {
                throw new Exception("RVT-H image detected - this image type is not currently supported.");
            }

            byte[] data = new byte[GroupSize];

            //this is an awful work around that blocks are scrubbed but the wiistream can't unscrub them because the partition ID is unknown
            Dictionary <int, int> IsoDecUnscub = new Dictionary <int, int>(); //must cache this because of a dependency

            int dataLen = (int)Math.Min(data.Length, Header.PartitionSize);

            _stream.Read(data, 0, dataLen, (a, b) => IsoDecUnscub.Add(a, b)); //defer the decryption because we don't have the partition id etc

            WiiPartitionGroupSection ps = new WiiPartitionGroupSection(stream, _discHdr, Header, data, Header.DiscOffset + Header.Data.Length, dataLen, true);

            Header.Initialise(ps);

            //defered unscrubbing
            foreach (KeyValuePair <int, int> x in IsoDecUnscub)
            {
                _stream.JunkStream.Position = _stream.OffsetToData(x.Key);
                _stream.JunkStream.Read(ps.Decrypted, x.Key, x.Value);
            }
            _firstSection = ps;
        }
示例#3
0
        private void hashPatchGroup(NkitPartitionPatchInfo pi, WiiPartitionGroupSection wp)
        {
            int blockCount = (int)(wp.Size / 0x8000);

            for (int i = 0; i < blockCount; i++)
            {
                Array.Copy(pi.HashGroups[wp.DiscOffset].Data, i * 0x400, wp.Decrypted, i * 0x8000, 0x400);
            }

            byte[] e = wp.Encrypted;

            for (int bi = 0; bi < blockCount; bi++)
            {
                if (pi.ScrubManager.IsBlockScrubbed(wp.Offset + (bi * 0x8000), out byte byt))
                {
                    wp.MarkBlockDirty(bi); //will be reset by ApplyHashes
                    wp.SetScrubbed(bi, byt);
                }
            }
        }
示例#4
0
        private void patchGroups(NkitPartitionPatchInfo patchInfo, WiiDiscHeaderSection discHeader, long crcPatchOffset, byte[] crcPatchData)
        {
            long partDataOffset = patchInfo.DiscOffset + patchInfo.PartitionHeader.Size;
            int  groupIdx       = (int)((crcPatchOffset - partDataOffset) / WiiPartitionSection.GroupSize);

            byte[] data = new byte[WiiPartitionSection.GroupSize];

            WiiPartitionHeaderSection wh = new WiiPartitionHeaderSection(discHeader, null, partDataOffset, patchInfo.PartitionHeader.Data, patchInfo.PartitionHeader.Size)
            {
                ScrubManager = patchInfo.ScrubManager
            };

            wh.Initialise(true, patchInfo.PartitionDataHeader.ReadString(0, 4));
#if DECRYPT
            WiiPartitionGroupSection wp = new WiiPartitionGroupSection(discHeader, wh, ph.Data, , ph.Data.Length, false);
#else
            WiiPartitionGroupSection wp = new WiiPartitionGroupSection(discHeader, wh, data, partDataOffset, Math.Min(WiiPartitionSection.GroupSize, crcPatchData.Length), true);
#endif

            if (patchInfo.Fst != null)
            {
                using (MemoryStream fstStream = new MemoryStream(patchInfo.Fst.Data))
                {
                    fstPatch(patchInfo, wp, crcPatchOffset, crcPatchData, fstStream);
                }
            }

            MemorySection d = new MemorySection(crcPatchData);

            for (long i = 0; i < crcPatchData.Length; i += WiiPartitionSection.GroupSize)
            {
                Array.Copy(d.Data, (int)i, data, 0, Math.Min(WiiPartitionSection.GroupSize, d.Size - i));
                wp.Populate(groupIdx++, data, crcPatchOffset + i, Math.Min(WiiPartitionSection.GroupSize, d.Size - i));
                wp.ForceHashes(null);
                if (patchInfo.HashGroups.ContainsKey(wp.DiscOffset))
                {
                    hashPatchGroup(patchInfo, wp);
                    d.Write((int)i, wp.Encrypted, (int)wp.Size);
                }
            }
        }
示例#5
0
 private void parseFst(WiiPartitionGroupSection grp)
 {
     if (_partialFst != 0 || (grp.DataOffset <= this.Header.FstOffset && this.Header.FstOffset <= grp.DataOffset + (0x7c00 * 64)))
     {
         //hack to test with. doesn't support reading over groups
         if (_fst == null)
         {
             _fst = new byte[this.Header.FstSize];
         }
         int read = grp.DataCopy(_partialFst == 0 ? (int)(this.Header.FstOffset - grp.DataOffset) : 0, (int)this.Header.FstSize - _partialFst, false, _fst, _partialFst);
         if (read + _partialFst == _fst.Length)
         {
             this.Header.ParseFst(_fst);
             _fst        = null;
             _partialFst = 0;
         }
         else
         {
             _partialFst += read;
         }
     }
 }
示例#6
0
        internal void Initialise(WiiPartitionGroupSection firstSection)
        {
            _firstSection = firstSection;
            IsEncrypted   = firstSection.IsEncrypted;

            MemorySection ms = new MemorySection(firstSection.Decrypted);

            this.Id     = ms.ReadString(0x400, 4);
            this.DiscNo = (int)ms.Read8(0x406);

            if (this.Stream != null)
            {
                this.Stream.ChangeJunk(this.DiscOffset + _dataOffset, this.Id, this.DiscNo, PartitionDataSize);
            }

            if (this.Id != "\0\0\0\0")
            {
                _dolOffset = ms.ReadUInt32B(0x820) * 4L; //+400 to skip hashes
                FstOffset  = ms.ReadUInt32B(0x824) * 4L;
                FstSize    = ms.ReadUInt32B(0x828) * 4L;
            }
        }
示例#7
0
        private void fstPatch(NkitPartitionPatchInfo pi, WiiPartitionGroupSection wp, long patchOffset, byte[] crcPatchData, Stream fst)
        {
            long fstOffset = pi.PartitionDataHeader.ReadUInt32B(0x424) * 4L;
            long length    = pi.Fst.Data.Length;
            //seek to fst group
            int baseGroupIdx = (int)((patchOffset - (pi.DiscOffset + wp.Header.Size)) / WiiPartitionSection.GroupSize);

            int gs = (int)(fstOffset / (0x7c00L * 64));
            int ge = (int)((fstOffset + length) / (0x7c00L * 64));

            if ((int)((fstOffset + length) % (0x7c00L * 64)) == 0)
            {
                ge--; //don't load the next group if the data will end on the last byte
            }
            if (gs > baseGroupIdx || ge < baseGroupIdx)
            {
                return;
            }

            using (MemoryStream dest = new MemoryStream(crcPatchData))
            {
                if (gs != baseGroupIdx)
                {
                    dest.Seek((gs - baseGroupIdx) * WiiPartitionSection.GroupSize, SeekOrigin.Current);
                }

                long dstOffset = NStream.DataToHashedLen(fstOffset) % WiiPartitionSection.GroupSize; //offset in hashed group
                long total     = 0;

                for (int i = gs; i <= ge; i++)
                {
                    long dataPos = 0x7c00 * 64 * i;
                    int  dataLen = (int)Math.Min(WiiPartitionSection.GroupSize, (wp.Header.ReadUInt32B(0x2bc) * 4L) - (WiiPartitionSection.GroupSize * i)); //can be less than 2mb if partition is small (or were are at the end)
                    int  read    = dest.Read(wp.Data, 0, wp.Data.Length);
                    if (read == 0)
                    {
                        break;
                    }
                    dest.Seek(-read, SeekOrigin.Current);

                    wp.Populate(i, wp.Data, patchOffset, dataLen); //auto decrypted

                    while (length != total && dstOffset != WiiPartitionSection.GroupSize)
                    {
                        dstOffset += 0x400;                                                                                            //skip hashes
                        long l = fst.Read(wp.Decrypted, (int)dstOffset, (int)Math.Min(length - total, 0x8000 - (dstOffset % 0x8000))); //no padding etc as fst will be the same size
                        dstOffset += l;
                        total     += l;
                    }

                    Array.Clear(wp.Decrypted, dataLen, (int)wp.Size - dataLen);

                    int bnkCount      = (int)(dataLen / 0x8000);
                    int scrubbedCount = 0;
                    for (int bi = 0; bi < bnkCount; bi++)
                    {
                        wp.MarkBlockDirty(bi); //set to force hash generation
                        byte byt;
                        if (pi.ScrubManager.IsBlockScrubbed(wp.Offset + (bi * 0x8000), out byt))
                        {
                            wp.SetScrubbed(bi, byt);
                            scrubbedCount++;
                        }
                    }

                    repairBlocks(wp, scrubbedCount, bnkCount, true, false);

#if DECRYPT
                    dest.Write(wp.Decrypted, 0, dataLen);
#else
                    dest.Write(wp.Encrypted, 0, dataLen);
#endif
                    dstOffset = 0;
                }
            }
        }
示例#8
0
        public void Read(Context ctx, NStream inStream, Stream outStream, Coordinator pc)
        {
            try
            {
                WiiDiscHeaderSection hdr = (WiiDiscHeaderSection)inStream.DiscHeader;
                string idVer             = hdr.ReadString(0x200, 8);
                if (idVer != "NKIT v01")
                {
                    throw new Exception(string.Format("{0} not supported by this version", idVer));
                }
                bool          isNkit              = idVer.StartsWith("NKIT");
                uint          nkitCrc             = hdr.ReadUInt32B(0x208);
                long          imageSize           = hdr.ReadUInt32B(0x210) * 4L;
                string        junkId              = hdr.ReadString(0x214, 4);
                uint          updatePartitionCrc  = hdr.ReadUInt32B(0x218);
                MemorySection updateRemovedFiller = null;

                long discOffset = 0;
                List <NkitPartitionPatchInfo> patchInfos = new List <NkitPartitionPatchInfo>();
                discOffset += hdr.Size;
                string        lastPartitionId   = null;
                PartitionType lastPartitionType = PartitionType.Other;
                NCrc          crc           = new NCrc();
                long          dstPos        = 0;
                long          srcPos        = hdr.Size;
                ScrubManager  scrubFiller   = new ScrubManager(null);
                bool          isRecoverable = false;

                using (NDisc disc = new NDisc(_log, inStream))
                {
                    hdr.WriteUInt32B(0x200, 0);
                    hdr.WriteUInt32B(0x204, 0);
                    hdr.WriteUInt32B(0x208, 0);
                    hdr.WriteUInt32B(0x20C, 0);
                    hdr.WriteUInt32B(0x210, 0);
                    hdr.WriteUInt32B(0x214, 0);
                    hdr.WriteUInt32B(0x218, 0);

                    hdr.Write8(0x60, 0);
                    hdr.Write8(0x61, 0);

                    CryptoStream crcStream = new CryptoStream(outStream, crc, CryptoStreamMode.Write); //wrap to calculate crc
                    crcStream.Write(hdr.Data, 0, hdr.Data.Length);                                     //write the header
                    pc.ReaderCheckPoint1PreWrite(null, nkitCrc);                                       //size that will be output from this read
                    dstPos += hdr.Size;

                    crc.Snapshot("Disc Header");

                    foreach (WiiPartitionInfo part in hdr.Partitions)      //already sorted
                    {
                        if (updatePartitionCrc != 0 && srcPos == hdr.Size) //write update partition out
                        {
                            updateRemovedFiller = MemorySection.Read(inStream, hdr.Partitions.First().DiscOffset - srcPos);
                            srcPos += updateRemovedFiller.Size;
                            WiiPartitionInfo firstPart      = WiiDiscHeaderSection.CreatePartitionInfos(updateRemovedFiller, 0)?.FirstOrDefault(a => a.Type != PartitionType.Update);
                            string           updateFileName = RecoveryData.GetUpdatePartition(ctx.Settings, updatePartitionCrc);

                            if (updateFileName != null)
                            {
                                using (FileStream pf = File.OpenRead(updateFileName))
                                {
                                    pf.Copy(crcStream, pf.Length);
                                    dstPos += pf.Length;
                                }
                            }
                            else
                            {
                                string msg = string.Format("!! Update partition *_{0} missing - Adding filler. It may be Recoverable", updatePartitionCrc.ToString("X8"));
                                isRecoverable = true;
                                _log?.LogDetail(msg);
                                //throw pc.SetReaderException(new HandledException("Failed to convert: " + msg));
                            }
                            ByteStream.Zeros.Copy(crcStream, firstPart.DiscOffset - dstPos); //fill full gap
                            dstPos += firstPart.DiscOffset - dstPos;
                        }

                        NkitPartitionPatchInfo patchInfo = new NkitPartitionPatchInfo()
                        {
                            HashGroups = new Dictionary <long, MemorySection>()
                        };
                        patchInfos.Add(patchInfo);

                        if (part.DiscOffset > srcPos)
                        {
                            dstPos += writeFiller(ref srcPos, dstPos, dstPos + 0x1cL, inStream, crcStream, new JunkStream(lastPartitionType != PartitionType.Data ? hdr.ReadString(0, 4) : lastPartitionId, hdr.Read8(6), lastPartitionType == PartitionType.Update ? 0 : imageSize), scrubFiller);
                            inStream.Copy(ByteStream.Zeros, part.DiscOffset - srcPos); //padded to 0x8000
                            srcPos += part.DiscOffset - srcPos;
                        }

                        part.DiscOffset           = dstPos; //restore the original position
                        patchInfo.DiscOffset      = dstPos;
                        patchInfo.PartitionHeader = MemorySection.Read(inStream, 0x20000);
                        srcPos += patchInfo.PartitionHeader.Size;
                        long    size     = patchInfo.PartitionHeader.ReadUInt32B(0x2bc) * 4L;
                        LongRef origSize = new LongRef()
                        {
                            Value = 0
                        };
                        WiiPartitionGroupSection  wp = null;
                        WiiPartitionHeaderSection wh = new WiiPartitionHeaderSection(hdr, null, part.DiscOffset, patchInfo.PartitionHeader.Data, patchInfo.PartitionHeader.Data.Length);
                        MemorySection             ph = new MemorySection(new byte[0x8000 * 64]);
                        long         remaining       = long.MaxValue;//set after first block read
                        int          groupIndex      = 0;
                        WiiHashStore hashes          = new WiiHashStore();
                        patchInfo.ScrubManager = wh.ScrubManager;
                        bool patchBlock = false;
                        StreamCircularBuffer prtStream = null;

                        try
                        {
                            using (prtStream = new StreamCircularBuffer(0, null, null, output => srcPos += partitionStreamWrite(origSize, inStream, output, size, ctx.Dats, patchInfo, hashes, pc)))
                            {
                                int          gs          = 0;
                                int          ge          = 0;
                                int          i           = 0;
                                MemoryStream patchBlocks = null;

                                while (remaining > 0)
                                {
                                    int blocks = (int)Math.Min(64L, remaining / 0x7c00);
                                    for (int b = 0; b < blocks; b++)
                                    {
                                        prtStream.Read(ph.Data, (b * 0x8000) + 0x400, 0x7c00); //load aligned with no hashes

                                        if (remaining == long.MaxValue)                        //first loop
                                        {
                                            remaining = origSize.Value;

                                            if (ph.ReadString(0x400 + 0, 4) == "\0\0\0\0")
                                            {
                                                gs              = -1;
                                                ge              = -1;
                                                blocks          = (int)Math.Min(64L, remaining / 0x7c00);
                                                lastPartitionId = ph.ReadString(0x400 + 0, 4);
                                                patchInfo.PartitionHeader.WriteUInt32B(0x2bc, (uint)(NStream.DataToHashedLen(origSize.Value) / 4)); //restore real size
                                                crcStream.Write(patchInfo.PartitionHeader.Data, 0, patchInfo.PartitionHeader.Data.Length);
                                                dstPos += patchInfo.PartitionHeader.Size;
                                            }
                                            else
                                            {
                                                gs = (int)((ph.ReadUInt32B(0x400 + 0x424) * 4L) / (0x7c00L * 64));
                                                ge = (int)(((ph.ReadUInt32B(0x400 + 0x424) * 4L) + (ph.ReadUInt32B(0x400 + 0x428) * 4L)) / (0x7c00L * 64));
                                                if ((int)((part.DiscOffset + (ph.ReadUInt32B(0x400 + 0x428) * 4L)) % (0x7c00L * 64)) == 0)
                                                {
                                                    ge--; //don't load the next group if the data will end on the last byte
                                                }
                                                blocks          = (int)Math.Min(64L, remaining / 0x7c00);
                                                lastPartitionId = ph.ReadString(0x400 + 0, 4);

                                                patchInfo.PartitionHeader.WriteUInt32B(0x2bc, ph.ReadUInt32B(0x400 + 0x210)); //restore real size
                                                crcStream.Write(patchInfo.PartitionHeader.Data, 0, patchInfo.PartitionHeader.Data.Length);
                                                dstPos += patchInfo.PartitionHeader.Size;

                                                ph.WriteUInt32B(0x400 + 0x200, 0);
                                                ph.WriteUInt32B(0x400 + 0x204, 0);
                                                ph.WriteUInt32B(0x400 + 0x208, 0);
                                                ph.WriteUInt32B(0x400 + 0x20C, 0);
                                                ph.WriteUInt32B(0x400 + 0x210, 0);
                                                ph.WriteUInt32B(0x400 + 0x214, 0);
                                                ph.WriteUInt32B(0x400 + 0x218, 0);
                                            }
                                            wp = new WiiPartitionGroupSection(hdr, wh, ph.Data, part.DiscOffset, blocks * 0x8000, false);
                                            wh.Initialise(wp, origSize.Value);
                                        }
                                    }

                                    if (blocks < 64)
                                    {
                                        Array.Clear(ph.Data, blocks * 0x8000, ph.Data.Length - (blocks * 0x8000)); //clear remaining blocks
                                    }
                                    wp.Populate(groupIndex, ph.Data, dstPos, blocks * 0x8000);

                                    int scrubbed = 0;
                                    for (int bi = 0; bi < blocks; bi++)
                                    {
                                        wp.MarkBlockDirty(bi);
                                        byte byt;
                                        if (patchInfo.ScrubManager.IsBlockScrubbedScanMode(wp.Offset + (bi * 0x8000), out byt))
                                        {
                                            wp.SetScrubbed(bi, byt);
                                            scrubbed++;
                                        }
                                    }
                                    bool isFstBlocks = i >= gs && i <= ge;
                                    bool reqHashes   = hashes.IsPreserved(wp.Offset);                                                                                            //test with 0 partition based offset

                                    repairBlocks(wp, scrubbed, blocks, false, isFstBlocks);                                                                                      //only test if the hashes aren't preserved (only preserved for scrubbed/customs)

                                    if (reqHashes)                                                                                                                               //store with disc based offset
                                    {
                                        patchInfo.HashGroups.Add(wp.Offset + part.DiscOffset + patchInfo.PartitionHeader.Size, new MemorySection((byte[])wp.Decrypted.Clone())); //fetch the stored hashed that couldn't be recreated
                                    }
                                    groupIndex++;
                                    bool inFstArea = i >= gs && i <= ge;

                                    if (!patchBlock && (gs == i || reqHashes))
                                    {
                                        patchBlocks = new MemoryStream();
                                        crc.Snapshot(lastPartitionId + " Data");
                                        patchBlock = true;
                                    }
                                    else if (patchBlock && !inFstArea && !reqHashes)
                                    {
                                        crc.Snapshot(lastPartitionId + " Patch");
                                        crc.Crcs.Last().PatchData = patchBlocks.ToArray();
                                        patchBlocks.Dispose();
                                        patchBlock = false;
                                    }
#if DECRYPT
                                    outStream.Write(wp.Decrypted, 0, blocks * 0x8000);
                                    if (i >= gs && i <= ge)
                                    {
                                        fstBlocks.Write(wp.Decrypted, 0, blocks * 0x8000);
                                    }
#else
                                    crcStream.Write(wp.Encrypted, 0, blocks * 0x8000);
                                    if (patchBlock)
                                    {
                                        patchBlocks.Write(wp.Encrypted, 0, blocks * 0x8000);
                                    }
#endif

                                    remaining -= (blocks * 0x7c00);
                                    dstPos    += (blocks * 0x8000);
                                    i++;
                                }
                                if (patchBlock)
                                {
                                    crc.Snapshot(lastPartitionId + " Patch");
                                    crc.Crcs.Last().PatchData = patchBlocks.ToArray();
                                    patchBlocks.Dispose();
                                }
                            }
                            if (origSize.Value != prtStream.WriterPosition)
                            {
                                throw pc.SetReaderException(new HandledException("Partition read did not write the full amount to the circular buffer before completing"));
                            }
                        }
                        catch (Exception ex)
                        {
                            if (prtStream?.WriterException != null)
                            {
                                throw pc.SetReaderException(prtStream.WriterException, "Failed reading filesystem");
                            }
                            throw pc.SetReaderException(ex, "Failed converting the filesystem");;  //writer exception
                        }

                        srcPos += hashes.ReadPatchData(part.DiscOffset + patchInfo.PartitionHeader.Size, patchInfo.HashGroups, inStream);

                        //read hash patches
                        lastPartitionType = part.Type;
                    }

                    if (srcPos < inStream.Length)
                    {
                        JunkStream partJunk = new JunkStream(lastPartitionType != PartitionType.Data ? hdr.ReadString(0, 4) : lastPartitionId, hdr.Read8(6), lastPartitionType == PartitionType.Update ? 0 : imageSize);
                        dstPos += writeFiller(ref srcPos, dstPos, lastPartitionType == PartitionType.Update ? imageSize : dstPos + 0x1cL, inStream, crcStream, partJunk, scrubFiller);
                    }
                }

                crc.Snapshot("End");

                if (updatePartitionCrc != 0)
                {
                    hdr.Write((int)WiiDiscHeaderSection.PartitionTableOffset, updateRemovedFiller.Data, 0, (int)WiiDiscHeaderSection.PartitionTableLength); //restore the exact partition table if update was removed
                }
                else
                {
                    hdr.UpdateOffsets(); //just update the table with the new offsets
                }
                crc.Crcs[0].PatchData = hdr.Data;

                foreach (CrcItem ci in crc.Crcs.Where(a => a.PatchData != null))
                {
                    NkitPartitionPatchInfo patchInfo = patchInfos.FirstOrDefault(a => ci.Offset >= a.DiscOffset + a.PartitionHeader.Size && ci.Offset < a.DiscOffset + a.PartitionHeader.Size + a.Size);
                    if (patchInfo != null)
                    {
                        patchGroups(patchInfo, hdr, ci.Offset, ci.PatchData);
                    }
                    ci.PatchCrc = Crc.Compute(ci.PatchData);
                }

                if (imageSize != dstPos)
                {
                    throw pc.SetReaderException(new HandledException("Nkit image read output {0} bytes not the expected {1}!", dstPos.ToString(), imageSize.ToString()));
                }

                pc.ReaderCheckPoint2Complete(crc, isRecoverable, nkitCrc, crc.FullCrc(true), this.VerifyIsWrite, hdr.Data, nkitCrc == crc.FullCrc(true) ? "NKit Valid" : "NKit Invalid");
                pc.ReaderCheckPoint3Complete();
            }
            catch (Exception ex)
            {
                throw pc.SetReaderException(ex, "NkitReaderWii.Read - Read and convert");
            }
        }
示例#9
0
 internal void Initialise(WiiPartitionGroupSection firstSection, long newSize)
 {
     this.Initialise(firstSection);
     PartitionSize = newSize;
 }