Пример #1
0
        internal bool Initialize(bool readHeader)
        {
            if (_id != null)
            {
                return(_headerRead);
            }

            List <long> IsoDecParts = new List <long>();

            _headerRead = readHeader;
            try
            {
                if (readHeader)
                {
                    _currentBlockIndex = -1;

                    _id = read(4);
                    string id = Encoding.ASCII.GetString(_id);

                    if (id == "WBFS")
                    {
                        uint hdSecSize = this.readUInt32B(); //n_hd_sec
                        long pos       = (uint)(1 << this.read8()) + 0x100;
                        _clusterSize = 1 << this.read8();
                        int clusters = (int)(FullSizeWii5 / _clusterSize) * 2;

                        //if ((hdSecSize * _clusterSize) / 0x1000L != _stream.Length) //WBFS header check
                        //    Debug.WriteLine("MatchFail");

                        _stream.Copy(ByteStream.Zeros, pos - 10);

                        MemorySection ms = MemorySection.Read(_stream, 2 * clusters);
                        uint          pointer;
                        long          maxPointer = 0;
                        long          blank      = 0;
                        long          blankTmp   = 0;
                        long          fileSize   = _stream.Length;
                        for (int i = 0; i < clusters; i++)
                        {
                            if ((pointer = ms.ReadUInt16B(i * 2)) != 0)
                            {
                                _imageSize += _clusterSize;
                            }
                            if (pointer == 0)
                            {
                                blankTmp++;
                            }
                            else if (pointer * (long)_clusterSize < fileSize)
                            {
                                blank     += blankTmp;
                                blankTmp   = 0;
                                maxPointer = Math.Max(maxPointer, pointer * (long)_clusterSize);
                            }
                            _clusterTable.Add(pointer);
                        }
                        _streamDataStart = _stream.Position;
                        _imageSize       = _readLength = lenCalc(Math.Max(maxPointer + (blank * _clusterSize), _imageSize));
                        _isWbfs          = _isWii = true; //must set after above code has ran
                        setDiscHeader(false, null);
                    }
                    else if ((id == "WII5" || id == "WII9") && !_isGamecube) //IsoDec :(
                    {
                        int    sectorSize = id == "WII5" ? 0x1182800 : 0x1FB5000;
                        string discId     = this.readString(4);
                        byte[] md5        = this.read(16);
                        int    partitions = (int)this.readUInt32L();
                        for (int i = 0; i < partitions; i++)
                        {
                            var part = new //throw away
                            {
                                DataOffset         = (long)((ulong)this.readUInt32L() << 2),
                                DataSize           = (long)((ulong)this.readUInt32L() << 2),
                                PartitionOffset    = (long)((ulong)this.readUInt32L() << 2),
                                PartitionEndOffset = (long)((ulong)this.readUInt32L() << 2),
                                PartitionKey       = this.read(16)
                            };
                            IsoDecParts.Add(part.PartitionOffset);
                        }
                        ;

                        _clusterSize  = 0x400; //1k
                        _clusterTable = new List <uint>();
                        int           c  = (sectorSize - (28 + (partitions * 32))) / 4;
                        MemorySection ms = MemorySection.Read(_stream, 4 * c);
                        for (int i = 0; i < c; i++)
                        {
                            _clusterTable.Add(ms.ReadUInt32L(i * 4));
                        }
                        _imageSize       = _readLength = (id == "WII5" ? FullSizeWii5 : FullSizeWii9);
                        _isIsoDec        = _isWii = true;
                        _streamDataStart = _stream.Position;
                        setDiscHeader(false, IsoDecParts.ToArray());
                    }
                    else if (id == "GCML") //GC IsoDec
                    {
                        string discId = this.readString(4);
                        byte[] md5    = this.read(16);
                        _clusterTable = new List <uint>();
                        _clusterSize  = 0x800; //2k
                        int           c  = (0x2B8800 - 24) / 4;
                        MemorySection ms = MemorySection.Read(_stream, 4 * c);
                        for (int i = 0; i < c; i++)
                        {
                            _clusterTable.Add(ms.ReadUInt32L(i * 4));
                        }
                        _streamDataStart = _stream.Position;
                        _IsoDecMultiply  = 0x1L; //none
                        _imageSize       = _readLength = FullSizeGameCube;
                        _isIsoDec        = _isGamecube = true;
                        setDiscHeader(false, null);
                    }
                    else if (BitConverter.ToString(_id) == "01-C0-0B-B1") //GCZ - C001B10B as big endian
                    {
                        MemorySection ms = MemorySection.Read(_stream, 0x20 - 4);

                        long compSize = (long)ms.ReadUInt64L(0x8 - 4);
                        _imageSize   = _readLength = (long)ms.ReadUInt64L(0x10 - 4);
                        _clusterSize = (int)ms.ReadUInt32L(0x18 - 4);
                        uint blocks = ms.ReadUInt32L(0x1C - 4);
                        _currentBlock = new byte[_clusterSize];

                        MemorySection pnt        = MemorySection.Read(_stream, blocks * 8);
                        MemorySection hsh        = MemorySection.Read(_stream, blocks * 4);
                        ulong         dataOffset = (ulong)(pnt.Size + hsh.Size + 0x20);
                        _clusterTable           = new List <uint>();
                        _clusterTableCompressed = new List <uint>();

                        for (int i = 0; i < blocks; i++)
                        {
                            ulong offset     = pnt.ReadUInt64L(i * 8) + dataOffset; //offset in raw file
                            bool  compressed = (offset & 0x8000000000000000) == 0;
                            offset &= ~0x8000000000000000;
                            _clusterTable.Add((uint)offset); //divide by 4 for wii
                            _clusterTableCompressed.Add((uint)(compressed ? 1 : 0));
                        }

                        _isGcz = true;
                        MemorySection xx = MemorySection.Read(this, 4);
                        _id = xx.Read(0, 4);

                        setDiscHeader(true, null);
                    }
                    else
                    {
                        _streamDataStart = 0;
                        _isIso           = true;
                        _imageSize       = _readLength = _stream.Length;
                        setDiscHeader(true, null); //true sets length too
                        _clusterSize = _isWii ? 0x400 : 0x800;
                    }
                    this.ResetJunk();
                    return(true);
                }
                else
                {
                    _imageSize       = _readLength = _stream.Length; //partial streams not disc
                    this.Position    = 0;
                    _streamDataStart = 0;
                }
                return(false);
            }
            catch (Exception ex)
            {
                throw new HandledException(ex, "NStream.Initialize - Read Header");
            }
        }