Inheritance: System.IO.BinaryWriter
Exemple #1
0
        /// <summary>
        /// Rename the filename, this does not set the fileid for all the qb types
        /// </summary>
        /// <param name="qbFilename">Source full filename.</param>
        /// <param name="newFullQbFilename">Full QB filename</param>
        /// <param name="fileType">.qb or .sqb=QB, .mqb=mid, .img=img .dbg=dbg  etc</param>
        /// <param name="extension">.qb.ngc for Wii for example</param>
        public void RenameFile(string qbFilename, string newQbFilename, QbKey itemType)
        {
            PakHeaderItem phi = _pakHeaders[qbFilename.ToLower()];

            phi.SetFilename(newQbFilename, itemType, _pakFormat.FileExtension, phi);

            using (BinaryEndianWriter bw = new BinaryEndianWriter(File.OpenWrite(_pakFormat.FullPakFilename)))
            {
                bw.BaseStream.Seek(phi.HeaderStart, SeekOrigin.Begin);
                writeHeaderItem(bw, phi);
            }

            //update the filename in the collection
            Dictionary <string, PakHeaderItem> p = new Dictionary <string, PakHeaderItem>(_pakHeaders.Count);

            foreach (PakHeaderItem ph in _pakHeaders.Values)
            {
                p.Add(ph.Filename.ToLower(), ph);
            }

            _pakHeaders = p;

            if (phi.PakFileType == PakItemType.Qb || phi.PakFileType == PakItemType.Sqb || phi.PakFileType == PakItemType.Midi)
            {
                try
                {
                    QbFile qbf = ReadQbFile(newQbFilename);
                    qbf.SetNewFileId();
                    ReplaceFile(newQbFilename, qbf);
                }
                catch
                {
                }
            }
        }
Exemple #2
0
        public void Write(Stream s)
        {
            BinaryEndianWriter bw = new BinaryEndianWriter(s);

            //using (BinaryEndianWriter bw = new BinaryEndianWriter(s))
            //{
            this.startLengthCheck(bw);

            bw.Write(_magic, this.PakFormat.EndianType);
            bw.Write(_fileSize, this.PakFormat.EndianType);

            foreach (QbItemBase qib in _items)
            {
                qib.Write(bw);
            }


            ApplicationException ex = this.testLengthCheck(this, bw);

            if (ex != null)
            {
                throw ex;
            }
            //}
        }
        internal override void Write(BinaryEndianWriter bw)
        {
            base.StartLengthCheck(bw);

            base.Write(bw);

            if (base.QbItemType != QbItemType.StructHeader)
            {
                bw.Write(_headerValue, base.Root.PakFormat.EndianType);
            }
            bw.Write(_iniNextItemPointer, base.Root.PakFormat.EndianType);

            foreach (QbItemBase qib in base.Items)
            {
                qib.Write(bw);
            }

            base.WriteEnd(bw);

            ApplicationException ex = base.TestLengthCheck(this, bw);

            if (ex != null)
            {
                throw ex;
            }
        }
        internal override void Write(BinaryEndianWriter bw)
        {
            base.StartLengthCheck(bw);

            base.Write(bw);

            foreach (string s in _strings)
            {
                bw.Write(stringToBytes(s));
                bw.Write((byte)0);
                if (_isUnicode)
                {
                    bw.Write((byte)0);
                }
            }

            while (base.StreamPos(bw) % 4 != 0)
            {
                bw.Write((byte)0);
            }

            base.WriteEnd(bw);

            ApplicationException ex = base.TestLengthCheck(this, bw);

            if (ex != null)
            {
                throw ex;
            }
        }
Exemple #5
0
        private ApplicationException testLengthCheck(object sender, BinaryEndianWriter bw)
        {
            uint len = this.Length;

            if (this.StreamPos(bw.BaseStream) - _lengthCheckStart != len)
            {
                return(new ApplicationException(QbFile.FormatWriteLengthExceptionMessage(sender, _lengthCheckStart, this.StreamPos(bw.BaseStream), len)));
            }
            else
            {
                return(null);
            }
        }
Exemple #6
0
        internal override void Write(BinaryEndianWriter bw)
        {
            base.StartLengthCheck(bw);

            bw.Write(_unknownData);

            base.WriteEnd(bw);

            ApplicationException ex = base.TestLengthCheck(this, bw);

            if (ex != null)
            {
                throw ex;
            }
        }
Exemple #7
0
        internal override void Write(BinaryEndianWriter bw)
        {
            base.StartLengthCheck(bw);

            base.Write(bw);
            foreach (QbItemBase qib in base.Items)
            {
                qib.Write(bw);
            }

            base.WriteEnd(bw);

            ApplicationException ex = base.TestLengthCheck(this, bw);

            if (ex != null)
            {
                throw ex;
            }
        }
Exemple #8
0
        internal override void Write(BinaryEndianWriter bw)
        {
            base.StartLengthCheck(bw);

            base.Write(bw);

            foreach (uint i in _values)
            {
                bw.Write(i, base.Root.PakFormat.EndianType);
            }

            base.WriteEnd(bw);

            ApplicationException ex = base.TestLengthCheck(this, bw);

            if (ex != null)
            {
                throw ex;
            }
        }
Exemple #9
0
        internal override void Write(BinaryEndianWriter bw)
        {
            base.StartLengthCheck(bw);

            base.Write(bw);
            bw.Write(_unknown, base.Root.PakFormat.EndianType);
            bw.Write((uint)_scriptData.Length, base.Root.PakFormat.EndianType);

            byte[] compScript;
            Lzss   lz = new Lzss();

            compScript = lz.Compress(_scriptData);

            if (compScript.Length >= _scriptData.Length)
            {
                compScript = _scriptData;
            }

            bw.Write((uint)compScript.Length, base.Root.PakFormat.EndianType);
            bw.Write(compScript);

            if (compScript.Length % 4 != 0)
            {
                for (int i = 0; i < 4 - (compScript.Length % 4); i++)
                {
                    bw.Write((byte)0);
                }
            }

            base.WriteEnd(bw);

            ApplicationException ex = base.TestLengthCheck(this, bw);

            if (ex != null)
            {
                throw ex;
            }
        }
Exemple #10
0
        /// <summary>
        /// Call after derived class has written its data in Write()
        /// </summary>
        /// <param name="br"></param>
        public virtual void WriteEnd(BinaryEndianWriter bw)
        {
            #region switch
            switch (_qbFormat)
            {
            case QbFormat.SectionValue:
                //Simple section type:
                //  ItemId, FileId, Value, Reserved
                bw.Write(_reserved, this.Root.PakFormat.EndianType);
                break;

            case QbFormat.StructItemValue:
                //case QbItemType.StructItemQbKeyString:
                //Simple struct type:
                //  ItemId, Value (4 byte), NextItemPointer
                bw.Write(_nextItemPointer, this.Root.PakFormat.EndianType);
                break;

            default:
                break;
            }
            #endregion
        }
Exemple #11
0
        private void writeHeaderItem(BinaryEndianWriter bwPakO, PakHeaderItem ph)
        {
            bwPakO.Write(ph.FileType.Crc, _pakFormat.EndianType);

            uint offset = ph.FileOffset;

            if (_requiresPab)
            {
                offset = (uint)_pakFormat.PakPabMinDataOffset + ((_pakFormat.PakPabMinDataOffset == 0 ? ph.HeaderStart : 0) + ph.FileOffset) - (uint)_pakFileLength;
            }

            bwPakO.Write(offset, _pakFormat.EndianType);
            bwPakO.Write(ph.FileLength, _pakFormat.EndianType);
            bwPakO.Write(ph.PakFullFileNameQbKey, _pakFormat.EndianType);
            bwPakO.Write(ph.FullFilenameQbKey, _pakFormat.EndianType);
            bwPakO.Write(ph.NameOnlyCrc, _pakFormat.EndianType);
            bwPakO.Write(ph.Unknown, _pakFormat.EndianType);
            bwPakO.Write((uint)ph.Flags, _pakFormat.EndianType);

            if ((ph.Flags & PakHeaderFlags.Filename) == PakHeaderFlags.Filename)
            {
                bwPakO.Write(Encoding.UTF8.GetBytes(ph.PaddedFileName), 0, PakHeaderItem.FileNameMaxLength);
            }
        }
Exemple #12
0
        public void ReplaceFsbFileWithWav(DatItem item, string wavFilename)
        {
            string tempWadFn = string.Format("{0}_{1}", _wadFilename, Guid.NewGuid().ToString("N"));

            byte[] buff;
            int filenameLen = 30;
            uint fileSize = 0;
            int diff;

            //save WAD to temp file
            using (FileStream fso = File.OpenWrite(tempWadFn))
            {
                using (FileStream fsi = File.OpenRead(_wadFilename))
                {
                    if (item.FileOffset != 0)
                        copy(fsi, fso, item.FileOffset);

                    using (FileStream fs = File.OpenRead(wavFilename))
                    {
                        //not fully correct for XBADPCM
                        WavSingleChunkHeader wh = WavProcessor.ParseWavSingleChunkHeader(fs);

                        long p = fso.Position;

                        BinaryEndianWriter bw = new BinaryEndianWriter(fso);

                        byte[] fsbFilename = new byte[filenameLen];

                        //http://www.fmod.org/forum/viewtopic.php?t=1551

                        //FileHeader

                        bw.Write(Encoding.Default.GetBytes("FSB3"));
                        bw.Write((uint)1, EndianType.Little); //1 sample in file
                        bw.Write((uint)80, EndianType.Little); //sampleheader length
                        bw.Write(wh.ChunkLength, EndianType.Little); //sampleheader length
                        bw.Write((uint)0x00030001, EndianType.Little); //header version 3.1
                        bw.Write((uint)0, EndianType.Little); //global mode flags

                        //p = fso.Position;

                        //SampleHeader (80 byte version)
                        bw.Write((UInt16)80, EndianType.Little); //sampleheader length
                        fsi.Seek(24 + 2, SeekOrigin.Current); //skip the start of the source fsb file name
                        fsi.Read(fsbFilename, 0, filenameLen);  //read filename from file being replaced
                        bw.Write(fsbFilename); //write filename

                        //sampleheader length (What's this about?)
                        uint lenSamp = (uint)Math.Round(((double)wh.SamplesPerSec / (double)wh.AvgBytesPerSec) * wh.ChunkLength);
                        if (lenSamp < 0xFA00)
                            lenSamp = 0xFA00; //set smallest allowed size? May be a memory allocation thing for FSB

                        bw.Write(lenSamp, EndianType.Little); //sampleheader length
                        bw.Write(wh.ChunkLength, EndianType.Little); //compressed bytes
                        bw.Write((uint)0x0, EndianType.Little); //loop start
                        bw.Write(lenSamp - 1, EndianType.Little); //loop end
                        bw.Write((uint)0x20400040, EndianType.Little); //sample mode
                        bw.Write(wh.SamplesPerSec, EndianType.Little); //frequency
                        bw.Write((ushort)0xFF, EndianType.Little); //default volume
                        bw.Write((ushort)0x0080, EndianType.Little); //default pan
                        bw.Write((ushort)0x0080, EndianType.Little); //default pri
                        bw.Write(wh.Channels, EndianType.Little); //channels
                        bw.Write((float)1, EndianType.Little); //min distance
                        bw.Write((float)10000, EndianType.Little); //max distance
                        bw.Write((uint)0x0, EndianType.Little); //varfreq
                        bw.Write((ushort)0x0, EndianType.Little); //varvol
                        bw.Write((ushort)0x0, EndianType.Little); //varpan

                        copy(fs, fso, wh.ChunkLength);
                        fileSize = (uint)(24 + 80 + wh.ChunkLength);

                        if (fileSize % DatWad.FileAlignment != 0)
                        {
                            buff = new byte[DatWad.FileAlignment - (fileSize % DatWad.FileAlignment)];
                            for (int i = 0; i < buff.Length; i++)
                                buff[i] = DatWad.FileAlignmentPadValue;
                            fso.Write(buff, 0, buff.Length);
                        }

                        //move past the rest of this file being replaced
                        long itemSize = item.FileSize;
                        if (item.FileSize % DatWad.FileAlignment != 0)
                            itemSize += (DatWad.FileAlignment - (item.FileSize % DatWad.FileAlignment));

                        if (itemSize < fsi.Length)
                            fsi.Seek(itemSize - (24 + 2 + filenameLen), SeekOrigin.Current);

                    }

                    diff = (int)(fso.Position - fsi.Position);

                    //copy the rest of the file
                    copy(fsi, fso, fsi.Length - fsi.Position);
                }
                fso.Flush();
            }

            //rename the temp wad file
            FileHelper.Delete(_wadFilename);

            //save dat headers
            //int diff = (int)fileSize - (int)item.FileSize;
            foreach (DatItem di in _datItems.Values)
            {
                if (di == item)
                    di.FileSize = fileSize;
                else
                    di.FileOffset = (uint)((int)di.FileOffset + (di.FileOffset > item.FileOffset ? diff : 0));
            }
            _headerFileSize = (uint)((int)_headerFileSize + diff);
            this.save();

            File.Move(tempWadFn, _wadFilename);
        }
Exemple #13
0
        internal override void Write(BinaryEndianWriter bw)
        {
            base.StartLengthCheck(bw);

            base.Write(bw);
            bw.Write(_unknown, base.Root.PakFormat.EndianType);
            bw.Write((uint)_scriptData.Length, base.Root.PakFormat.EndianType);

            byte[] compScript;
            Lzss lz = new Lzss();
            compScript = lz.Compress(_scriptData);

            if (compScript.Length >= _scriptData.Length)
                compScript = _scriptData;

            bw.Write((uint)compScript.Length, base.Root.PakFormat.EndianType);
            bw.Write(compScript);

            if (compScript.Length % 4 != 0)
            {
                for (int i = 0; i < 4 - (compScript.Length % 4); i++)
                    bw.Write((byte)0);
            }

            base.WriteEnd(bw);

            ApplicationException ex = base.TestLengthCheck(this, bw);
            if (ex != null) throw ex;
        }
Exemple #14
0
 protected uint StreamPos(BinaryEndianWriter bw)
 {
     return Root.StreamPos(bw.BaseStream);
 }
Exemple #15
0
        private static long writeFsbToStream(FileStream fsWrite, string wavFilename, string internalFilename)
        {
            int filenameLen = 30;
            long pos = fsWrite.Position;
            long ret;

            //open XBADPCM file to write as FSB file
            using (FileStream fs = File.OpenRead(wavFilename))
            {
                //not fully correct for XBADPCM
                WavSingleChunkHeader wh = WavProcessor.ParseWavSingleChunkHeader(fs);

                BinaryEndianWriter bw = new BinaryEndianWriter(fsWrite);

                byte[] fsbFilename = new byte[filenameLen];

                //FileHeader

                bw.Write(Encoding.Default.GetBytes("FSB3"));
                bw.Write((uint)1, EndianType.Little); //1 sample in file
                bw.Write((uint)80, EndianType.Little); //sampleheader length
                bw.Write(wh.ChunkLength, EndianType.Little); //sampleheader length
                bw.Write((uint)0x00030001, EndianType.Little); //header version 3.1
                bw.Write((uint)0, EndianType.Little); //global mode flags

                //SampleHeader (80 byte version)
                bw.Write((UInt16)80, EndianType.Little); //sampleheader length
                bw.Write(Encoding.Default.GetBytes(internalFilename.ToLower().PadRight(filenameLen, '\0').Substring(0, filenameLen))); //write filename

                //sampleheader length
                uint lenSamp = (uint)Math.Round(((double)wh.SamplesPerSec / (double)wh.AvgBytesPerSec) * wh.ChunkLength);
                if (lenSamp < 0xFA00)
                    lenSamp = 0xFA00; //set smallest allowed size? May be a memory allocation thing for FSB

                bw.Write(lenSamp, EndianType.Little); //sampleheader length
                bw.Write(wh.ChunkLength, EndianType.Little); //compressed bytes
                bw.Write((uint)0x0, EndianType.Little); //loop start
                bw.Write(lenSamp - 1, EndianType.Little); //loop end
                bw.Write((uint)0x20400041, EndianType.Little); //sample mode
                bw.Write(wh.SamplesPerSec, EndianType.Little); //frequency
                bw.Write((ushort)0xFF, EndianType.Little); //default volume
                bw.Write((ushort)0xFFFF, EndianType.Little); //default pan
                bw.Write((ushort)0xFF, EndianType.Little); //default pri
                bw.Write(wh.Channels, EndianType.Little); //channels
                bw.Write((float)1, EndianType.Little); //min distance
                bw.Write((float)1000000, EndianType.Little); //max distance
                bw.Write((uint)0x0, EndianType.Little); //varfreq
                bw.Write((ushort)0x0, EndianType.Little); //varvol
                bw.Write((ushort)0x0, EndianType.Little); //varpan

                copy(fs, fsWrite, wh.ChunkLength);
                uint fileSize = (uint)(24 + 80 + wh.ChunkLength);
                byte[] buff;

                ret = fsWrite.Position - pos;

                if (fileSize % DatWad.FileAlignment != 0)
                {
                    buff = new byte[DatWad.FileAlignment - (fileSize % DatWad.FileAlignment)];
                    for (int i = 0; i < buff.Length; i++)
                        buff[i] = DatWad.FileAlignmentPadValue;
                    fsWrite.Write(buff, 0, buff.Length);
                }
            }

            return ret;
        }
Exemple #16
0
        internal override void Write(BinaryEndianWriter bw)
        {
            base.StartLengthCheck(bw);

            base.Write(bw);

            foreach (QbItemBase qib in base.Items)
                qib.Write(bw);

            base.WriteEnd(bw);

            ApplicationException ex = base.TestLengthCheck(this, bw);
            if (ex != null) throw ex;
        }
Exemple #17
0
        /// <summary>
        /// Write the item to the Binary Writer
        /// </summary>
        /// <param name="bw"></param>
        internal virtual void Write(BinaryEndianWriter bw)
        {
            bw.Write(_qbItemValue, this.Root.PakFormat.EndianType);

            #region switch

            uint qbKeyCrc = (_itemQbKey == null ? 0 : _itemQbKey.Crc);

            switch (_qbFormat)
            {
                case QbFormat.SectionPointer:
                    //Complex section type:
                    //  ItemId, FileId, Pointer, Reserved
                    bw.Write(qbKeyCrc, this.Root.PakFormat.EndianType);
                    bw.Write(_fileId, this.Root.PakFormat.EndianType);
                    bw.Write(_pointer, this.Root.PakFormat.EndianType);
                    bw.Write(_reserved, this.Root.PakFormat.EndianType);
                    break;

                case QbFormat.SectionValue:
                    //Simple section type:
                    //  ItemId, FileId
                    bw.Write(qbKeyCrc, this.Root.PakFormat.EndianType);
                    bw.Write(_fileId, this.Root.PakFormat.EndianType);
                    break;

                case QbFormat.StructItemPointer:
                    //Complex struct type:
                    //  ItemId, Pointer, NextItemPointer
                    bw.Write(qbKeyCrc, this.Root.PakFormat.EndianType);
                    bw.Write(_pointer, this.Root.PakFormat.EndianType);
                    bw.Write(_nextItemPointer, this.Root.PakFormat.EndianType);
                    break;

                case QbFormat.StructItemValue:
                    //Simple struct type:
                    //  ItemId, Value (4 byte), NextItemPointer
                    bw.Write(qbKeyCrc, this.Root.PakFormat.EndianType);
                    break;

                case QbFormat.ArrayPointer:
                    //Complex array type:
                    //  ItemCount, Pointer, Pointers -  (if length is 1 then pointer points to first item and Pointers are abscent)
                    bw.Write(_itemCount, this.Root.PakFormat.EndianType);
                    if (_itemCount == 0)
                        bw.Write(0, this.Root.PakFormat.EndianType);
                    else if (_itemCount > 1)
                        bw.Write(_pointer, this.Root.PakFormat.EndianType);
                    for (int i = 0; i < _itemCount; i++)
                        bw.Write(_pointers[i], this.Root.PakFormat.EndianType);
                    break;

                case QbFormat.ArrayValue:
                    //Simple array type:
                    //  ItemCount, Pointer, Pointers -  (if length is 1 then pointer points to first item and Pointers are abscent)
                    bw.Write(_itemCount, this.Root.PakFormat.EndianType);
                    if (_itemCount > 1)
                        bw.Write(_pointer, this.Root.PakFormat.EndianType);
                    break;

                case QbFormat.StructHeader:
                    break;
                case QbFormat.Floats:
                    break;
                case QbFormat.Unknown:
                    break;
                default:
                    break;
            }
            #endregion
        }
Exemple #18
0
 private void startLengthCheck(BinaryEndianWriter bw)
 {
     _lengthCheckStart = this.StreamPos(bw.BaseStream);
 }
Exemple #19
0
        public static void CreateDatWad(QbKey songQk, EndianType endianType, string datFilename, string wadFilename, string songFilename, string guitarFilename, string rhythmFilename, string previewFilename)
        {
            QbKey[] keys = new QbKey[4];
            int[] offsets = new int[5];
            int[] sizes = new int[4];

            FileHelper.Delete(wadFilename);
            FileHelper.Delete(datFilename);

            using (FileStream fsWad = File.OpenWrite(wadFilename))
            {
                offsets[0] = (int)fsWad.Position;
                keys[0] = QbKey.Create(string.Format("{0}_guitar", songQk.Text));
                sizes[0] = (int)writeFsbToStream(fsWad, guitarFilename, string.Concat(keys[0].Text, ".wav"));
                offsets[1] = (int)fsWad.Position;
                keys[1] = QbKey.Create(string.Format("{0}_preview", songQk.Text));
                sizes[1] = (int)writeFsbToStream(fsWad, previewFilename, string.Concat(keys[1].Text, ".wav"));
                offsets[2] = (int)fsWad.Position;
                keys[2] = QbKey.Create(string.Format("{0}_rhythm", songQk.Text));
                sizes[2] = (int)writeFsbToStream(fsWad, rhythmFilename, string.Concat(keys[2].Text, ".wav"));
                offsets[3] = (int)fsWad.Position;
                keys[3] = QbKey.Create(string.Format("{0}_song", songQk.Text));
                sizes[3] = (int)writeFsbToStream(fsWad, songFilename, string.Concat(keys[3].Text, ".wav"));
                offsets[4] = (int)fsWad.Position;
                fsWad.Flush();
            }

            using (FileStream fsDat = File.OpenWrite(datFilename))
            {
                using (BinaryEndianWriter bw = new BinaryEndianWriter(fsDat))
                {
                    int l = offsets[3] + sizes[3];
                    if (l % 16 != 0)
                        l += 16 - (l % 16);

                    bw.Write((uint)keys.Length, endianType);
                    bw.Write((uint)l, endianType);

                    for (int i = 0; i < offsets.Length - 1; i++)
                    {
                        bw.Write(keys[i].Crc, endianType);
                        bw.Write(offsets[i], endianType);
                        bw.Write(sizes[i], endianType);
                        bw.Write(new byte[] { 0,0,0,0,0,0,0,0 });
                    }
                    fsDat.Flush();
                }
            }
        }
Exemple #20
0
        private void writeHeaderItem(BinaryEndianWriter bwPakO, PakHeaderItem ph)
        {
            bwPakO.Write(ph.FileType.Crc, _pakFormat.EndianType);

            uint offset = ph.FileOffset;
            if (_requiresPab)
                offset = (uint)_pakFormat.PakPabMinDataOffset + ((_pakFormat.PakPabMinDataOffset == 0 ? ph.HeaderStart : 0) + ph.FileOffset) - (uint)_pakFileLength;

            bwPakO.Write(offset, _pakFormat.EndianType);
            bwPakO.Write(ph.FileLength, _pakFormat.EndianType);
            bwPakO.Write(ph.PakFullFileNameQbKey, _pakFormat.EndianType);
            bwPakO.Write(ph.FullFilenameQbKey, _pakFormat.EndianType);
            bwPakO.Write(ph.NameOnlyCrc, _pakFormat.EndianType);
            bwPakO.Write(ph.Unknown, _pakFormat.EndianType);
            bwPakO.Write((uint)ph.Flags, _pakFormat.EndianType);

            if ((ph.Flags & PakHeaderFlags.Filename) == PakHeaderFlags.Filename)
                bwPakO.Write(Encoding.UTF8.GetBytes(ph.PaddedFileName), 0, PakHeaderItem.FileNameMaxLength);
        }
Exemple #21
0
        public static void WriteSingleChunkHeader(WavSingleChunkHeader header, Stream wavStream)
        {
            BinaryEndianWriter w = new BinaryEndianWriter(wavStream);

            w.Write(Encoding.Default.GetBytes(header.FileId));
            w.Write(header.FileLength);
            w.Write(Encoding.Default.GetBytes(header.RiffType));

            w.Write(Encoding.Default.GetBytes(header.ChunkHeaderId));
            w.Write(header.ChunkHeaderLength);
            w.Write(header.FormatTag);
            w.Write(header.Channels);
            w.Write(header.SamplesPerSec);
            w.Write(header.AvgBytesPerSec);
            w.Write(header.BlockAlign);
            w.Write(header.BitsPerSample);
            w.Write(header.ExtraBytes);
            w.Write(Encoding.Default.GetBytes(header.ChunkId));
            w.Write(header.ChunkLength);
        }
Exemple #22
0
        private void replaceFile(string qbFilename, long newLength, bool remove, WriteDataToStream callback)
        {
            int filePad = _pakFormat.FilePadSize;

            PakHeaderItem phi = null;
            if (_pakHeaders.ContainsKey(qbFilename.ToLower()))
                phi = _pakHeaders[qbFilename.ToLower()];
            else
            {
                string fqk = QbKey.Create(qbFilename).Crc.ToString("X").PadLeft(8, '0').ToLower();

                if (_pakHeaders.ContainsKey(fqk))
                    phi = _pakHeaders[fqk];

            }

            if (phi != null)
            {
                long pad = filePad - (newLength % filePad);
                if (pad == filePad)
                    pad = 0;

                string newPakFilename = string.Format("{0}_{1}", _pakFormat.FullPakFilename, Guid.NewGuid().ToString("N"));
                string newPabFilename = string.Format("{0}_{1}", _pakFormat.FullPabFilename, Guid.NewGuid().ToString("N"));

                uint minOffset = uint.MaxValue;
                bool itemFound = false;
                uint nextOffset = 0;

                foreach (PakHeaderItem ph in _pakHeaders.Values)
                {
                    if (itemFound)
                    {
                        nextOffset = ph.FileOffset + ph.HeaderStart;
                        itemFound = false; //don't enter this if again
                    }

                    if (object.ReferenceEquals(phi, ph))
                        itemFound = true;

                    if (ph.HeaderStart + ph.FileOffset < minOffset)
                        minOffset = ph.HeaderStart + ph.FileOffset;
                }

                uint lastItemPad = 0;
                int repPad = filePad - ((int)phi.FileLength % filePad);
                if (repPad == filePad)
                    repPad = 0;

                //previously badly padded or last file
                if (nextOffset != 0 && (nextOffset - (phi.FileOffset + phi.HeaderStart)) % filePad != 0)
                    repPad = (int)((nextOffset - (phi.FileOffset + phi.HeaderStart)) - phi.FileLength);

                //position of the LAST header item
                long lastHeaderPos = 0;
                //the length of all the headers (like pak when there's a pab) with padding
                long allHeadersLen = minOffset;
                //position in the input file where our file is to be replaced (not including header pos)
                long fileReplacePos = (phi.HeaderStart + phi.FileOffset) - allHeadersLen;
                //position in the input file after the file that is to be replaced
                long fileAfterReplacePos = fileReplacePos + phi.FileLength + repPad; //item size before modifying header

                //open input pak
                using (FileStream fsPakI = File.Open(_pakFilename, FileMode.Open, FileAccess.Read))
                {
                    using (BinaryEndianReader brPakI = new BinaryEndianReader(fsPakI))
                    {
                        //open output pak temp file
                        using (FileStream fsPakO = File.Create(newPakFilename))
                        {
                            using (BinaryEndianWriter bwPakO = new BinaryEndianWriter(fsPakO))
                            {
                                long diffLen = 0;

                                //do not compensate for missing header when using zlib compression as the header is padded
                                if (remove && _pakFormat.CompressionType != CompressionType.ZLibChunk) //we need to cater for the header being removed on all items before it.
                                {
                                    diffLen = PakHeaderItem.FullHeaderLength;
                                    if ((phi.Flags & PakHeaderFlags.Filename) != PakHeaderFlags.Filename)
                                        diffLen -= PakHeaderItem.FileNameMaxLength;
                                }

                                //write out the headers
                                foreach (PakHeaderItem ph in _pakHeaders.Values)
                                {
                                    //apply offset change before finding file to be replaced
                                    //this will prevents the offset of the replaced file being changed
                                    ph.FileOffset = (uint)(ph.FileOffset - (long)diffLen);
                                    if (object.ReferenceEquals(phi, ph))
                                    {
                                        if (remove)
                                        {
                                            long remPad = filePad - (phi.FileLength % filePad);
                                            if (remPad == filePad)
                                                remPad = 0;

                                            diffLen = phi.FileLength + remPad; //now cater for the difference in file size
                                        }
                                        else
                                        {
                                            diffLen = (long)((ph.FileLength + repPad) - (newLength + pad));
                                            ph.FileLength = (uint)newLength; //0 for remove
                                        }
                                    }

                                    lastHeaderPos += PakHeaderItem.FullHeaderLength;

                                    if (!(remove && object.ReferenceEquals(phi, ph)))
                                        writeHeaderItem(bwPakO, ph);

                                    if ((ph.Flags & PakHeaderFlags.Filename) != PakHeaderFlags.Filename)
                                        lastHeaderPos -= PakHeaderItem.FileNameMaxLength;
                                }

                                //Move to the "last" header
                                fsPakI.Seek(lastHeaderPos, SeekOrigin.Begin);

                                //write out "last" HeaderType
                                bwPakO.Write(brPakI.ReadBytes(4));

                                //Modify and write the offset of the "last" header's data
                                uint lastOffset = brPakI.ReadUInt32(_pakFormat.EndianType);
                                lastOffset = (uint)(lastOffset - (long)diffLen);

                                //fix bad padding on last file
                                if (nextOffset == 0 && ((lastOffset - (phi.FileOffset + phi.HeaderStart) % filePad) % filePad) != 0)
                                {
                                    lastItemPad = (uint)filePad - (uint)(lastOffset % filePad);
                                    lastOffset += lastItemPad;
                                }

                                bwPakO.Write(lastOffset, _pakFormat.EndianType);

                                //write out the end of the last header
                                copyData(fsPakI, fsPakO, allHeadersLen - fsPakI.Position);

                            }
                        }
                    }
                }

                //open input pak
                using (FileStream fsPakI = File.Open(_requiresPab ? _pakFormat.FullPabFilename : _pakFilename, FileMode.Open, FileAccess.Read))
                {
                    using (BinaryEndianReader brPakI = new BinaryEndianReader(fsPakI))
                    {
                        //open output pak temp file
                        using (FileStream fsPakO = _requiresPab ? File.Open(newPabFilename, FileMode.Create) : File.Open(newPakFilename, FileMode.Append))
                        {
                            using (BinaryEndianWriter bwPakO = new BinaryEndianWriter(fsPakO))
                            {
                                if (!_requiresPab)
                                    fsPakI.Seek(allHeadersLen, SeekOrigin.Begin);

                                //Write out the data starting from the last header to the start of the file to be replaced (minus the length of the type and offset)
                                copyData(fsPakI, fsPakO, fileReplacePos);

                                //Write the new file into the pak file
                                int pos = (int)fsPakO.Position;
                                callback(fsPakO);
                                if (pad != 0)
                                    fsPakO.Write(new byte[pad], 0, (int)pad);

                                if (!_requiresPab)
                                    fileAfterReplacePos += allHeadersLen;

                                if (lastItemPad != 0)
                                    fileAfterReplacePos -= lastItemPad; // a bit of a hack as this was not applied when this var was set as we didn't know the values

                                //write the remainder of source the pak file
                                fsPakI.Seek(fileAfterReplacePos, SeekOrigin.Begin);
                                copyData(fsPakI, fsPakO, fsPakI.Length - fileAfterReplacePos);

                                fsPakO.Flush();
                            }
                        }
                    }
                }

                fixUncompressedFileLengths(newPakFilename, newPabFilename);

                File.Delete(_pakFilename);
                File.Move(newPakFilename, _pakFilename);
                if (_requiresPab)
                {
                    File.Delete(_pakFormat.FullPabFilename);
                    File.Move(newPabFilename, _pakFormat.FullPabFilename);
                }

                _pakFormat.Compress();
            }
            else
                throw new ApplicationException(string.Format("'{0}' does not exist in '{1}'", qbFilename, _pakFilename));
        }
Exemple #23
0
        private PakHeaderItem createBlankFile(string newQbFilename, QbKey itemType, bool filenameInHeader)
        {
            //update the filename in the collection
            List<PakHeaderItem> hd = new List<PakHeaderItem>(_pakHeaders.Values);

            PakHeaderItem newHdr = new PakHeaderItem();
            newHdr.FileLength = 0; // (uint)(new FileInfo(localFilename)).Length;
            newHdr.FileOffset = hd[0].FileOffset + (uint)(filenameInHeader ? PakHeaderItem.FullHeaderLength : 0x20);
            newHdr.Flags = (PakHeaderFlags)(filenameInHeader ? PakHeaderFlags.Filename : 0);
            newHdr.HeaderStart = 0;
            newHdr.IsStoredInPak = true;
            newHdr.Filename = newQbFilename;
            newHdr.FileType = itemType;
            hd.Insert(0, newHdr);

            //update the filename in the collection
            bool pastNew = false;
            Dictionary<string, PakHeaderItem> p = new Dictionary<string, PakHeaderItem>(_pakHeaders.Count);

            bool hasFoundMatch = filenameInHeader;

            foreach (PakHeaderItem ph in hd)
            {
                //small hack to determine which items need to be filled - Find another header with
                if (!hasFoundMatch && ((ph.Flags & PakHeaderFlags.Filename) != PakHeaderFlags.Filename) && ph != newHdr)
                {
                    newHdr.SetFilename(newQbFilename, itemType, _pakFormat.FileExtension, ph);
                    hasFoundMatch = true;
                }

                if (pastNew)
                    ph.HeaderStart += (uint)(filenameInHeader ? PakHeaderItem.FullHeaderLength : 0x20);
                else if (ph != newHdr)
                    ph.FileOffset += (uint)(filenameInHeader ? PakHeaderItem.FullHeaderLength : 0x20);
                else // (ph == newHdr)
                    pastNew = true;

                p.Add(ph.Filename.ToLower(), ph);
            }

            if (!hasFoundMatch)
                newHdr.SetFilename(newQbFilename, itemType, _pakFormat.FileExtension, null);

            _pakFileLength += (uint)(filenameInHeader ? PakHeaderItem.FullHeaderLength : PakHeaderItem.FullHeaderLength - PakHeaderItem.FileNameMaxLength);

            _pakHeaders = p;

            string newPakFilename = string.Format("{0}_{1}", _pakFilename, Guid.NewGuid().ToString("N"));
            using (FileStream fsO = File.Open(newPakFilename, FileMode.CreateNew))
            {
                using (BinaryEndianWriter bw = new BinaryEndianWriter(fsO))
                {
                    writeHeaderItem(bw, newHdr);
                    using (FileStream fsI = File.OpenRead(_pakFilename))
                        copyData(fsI, fsO, new FileInfo(_pakFilename).Length);
                }
            }

            File.Delete(_pakFilename);
            File.Move(newPakFilename, _pakFilename);

            return newHdr;
        }
Exemple #24
0
        /// <summary>
        /// Rename the filename, this does not set the fileid for all the qb types
        /// </summary>
        /// <param name="qbFilename">Source full filename.</param>
        /// <param name="newFullQbFilename">Full QB filename</param>
        /// <param name="fileType">.qb or .sqb=QB, .mqb=mid, .img=img .dbg=dbg  etc</param>
        /// <param name="extension">.qb.ngc for Wii for example</param>
        public void RenameFile(string qbFilename, string newQbFilename, QbKey itemType)
        {
            PakHeaderItem phi = _pakHeaders[qbFilename.ToLower()];

            phi.SetFilename(newQbFilename, itemType, _pakFormat.FileExtension, phi);

            using (BinaryEndianWriter bw = new BinaryEndianWriter(File.OpenWrite(_pakFormat.FullPakFilename)))
            {
                bw.BaseStream.Seek(phi.HeaderStart, SeekOrigin.Begin);
                writeHeaderItem(bw, phi);
            }

            //update the filename in the collection
            Dictionary<string, PakHeaderItem> p = new Dictionary<string,PakHeaderItem>(_pakHeaders.Count);
            foreach (PakHeaderItem ph in _pakHeaders.Values)
                p.Add(ph.Filename.ToLower(), ph);

            _pakHeaders = p;

            if (phi.PakFileType == PakItemType.Qb || phi.PakFileType == PakItemType.Sqb || phi.PakFileType == PakItemType.Midi)
            {
                try
                {
                    QbFile qbf = ReadQbFile(newQbFilename);
                    qbf.SetNewFileId();
                    ReplaceFile(newQbFilename, qbf);
                }
                catch
                {
                }
            }
        }
Exemple #25
0
        /// <summary>
        /// Adds silence to wav files alter volume
        /// </summary>
        /// <param name="silenceInsertLength">Milliseconds to insert at start of wav</param>
        /// <param name="volume">0=silent, 1=100%</param>
        /// <param name="maxLength">If the wav is longer than this then crop (includes silence), if 0 then don't crop</param>
        /// <param name="srcFilenames">Filenames to pad</param>
        public static void SetLengthSilenceAndVolume(float silenceInsertLength, float maxLength, float volume, string fileName)
        {
            FileStream inS;
            FileStream outS;
            WavSingleChunkHeader h;
            uint silenceLen;
            string tmpName;

            //uint origChunkLen;

            int copied;
            byte[] buff = new byte[10000];

            for (int i = 0; i < buff.Length; i++)
                buff[i] = 0;

            tmpName = string.Format("{0}_{1}", fileName, Guid.NewGuid().ToString("N"));

            using (inS = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                using (outS = new FileStream(tmpName, FileMode.CreateNew, FileAccess.ReadWrite))
                {
                    h = ParseWavSingleChunkHeader(inS);

                    //origChunkLen = h.ChunkLength;

                    silenceLen = (uint)((float)h.AvgBytesPerSec * (silenceInsertLength / 1000F));
                    silenceLen -= silenceLen % h.BlockAlign;

                    uint newLenBytes = maxLength != 0 ? (uint)((float)h.AvgBytesPerSec * (maxLength / 1000F)) : h.ChunkLength + silenceLen;
                    newLenBytes -= newLenBytes % h.BlockAlign;

                    h.ChunkLength = (uint)((uint)inS.Length - h.DataOffset) + silenceLen;

                    if (h.ChunkLength > newLenBytes)
                        h.ChunkLength = newLenBytes;

                    h.ChunkLength -= h.ChunkLength % h.BlockAlign;
                    h.FileLength = (h.ChunkLength + (uint)h.DataOffset) - 8;

                    WriteSingleChunkHeader(h, outS);

                    copied = 0;
                    int len = 0;
                    while (copied < silenceLen)
                    {
                        len = buff.Length;
                        if (copied + buff.Length > silenceLen)
                            len = (int)silenceLen - copied;

                        outS.Write(buff, 0, len);
                        copied += len;
                    }

                    //origChunkLen = h.ChunkLength; //we need to copy this much

                    //copy audio and set volume
                    BinaryEndianWriter bw = new BinaryEndianWriter(outS);
                    BinaryEndianReader br = new BinaryEndianReader(inS);
                    int b32;
                    while (copied != h.ChunkLength) //length is block aligned so don't worry about channel count
                    {
                        b32 = (int)br.ReadInt16(EndianType.Little);
                        b32 = (int)((float)b32 * volume);

                        b32 = Math.Max((int)short.MinValue, Math.Min((int)short.MaxValue, b32));

                        bw.Write((short)b32, EndianType.Little);
                        copied += 2;
                    }

                    //copied = (int)origChunkLen;  //we've copied this much (silence included)
                    //while (copied < h.ChunkLength) //pad to the length we said it was in the header
                    //{
                    //    inS.Read(buff, 0, buff.Length);
                    //    if (copied + buff.Length < h.ChunkLength)
                    //        outS.Write(buff, 0, buff.Length);
                    //    else
                    //        outS.Write(buff, 0, (int)h.ChunkLength % - copied);
                    //    copied += buff.Length;
                    //}

                    outS.Flush();
                }
            }
            if (File.Exists(fileName))
            {
                if (File.Exists(tmpName))
                    FileHelper.Move(tmpName, fileName);
            }
        }
Exemple #26
0
        internal override void Write(BinaryEndianWriter bw)
        {
            base.StartLengthCheck(bw);

            base.Write(bw);

            foreach (string s in _strings)
            {
                bw.Write(stringToBytes(s));
                bw.Write((byte)0);
                if (_isUnicode)
                    bw.Write((byte)0);
            }

            while (base.StreamPos(bw) % 4 != 0)
                bw.Write((byte)0);

            base.WriteEnd(bw);

            ApplicationException ex = base.TestLengthCheck(this, bw);
            if (ex != null) throw ex;
        }
Exemple #27
0
        public static void CreatePreview(int offset, int length, int fade, float volume, bool volumeApplied, string dstFilename, params AudioFile[] srcFilenames)
        {
            if (srcFilenames == null || srcFilenames.Length == 0 || (srcFilenames.Length == 1 && (srcFilenames[0] == null || srcFilenames[0].Name.Length == 0)))
                return;

            FileHelper.Delete(dstFilename);

            WavSingleChunkHeader[] whi = new WavSingleChunkHeader[srcFilenames.Length];
            BinaryEndianReader[] br = new BinaryEndianReader[srcFilenames.Length];
            float[] vols = new float[srcFilenames.Length];

            int outWav = 0; //use this input wav as the format for the output wav
            int maxLen = 0;

            for (int c = 0; c < srcFilenames.Length; c++)
            {
                br[c] = new BinaryEndianReader(File.OpenRead(srcFilenames[c].Name));
                whi[c] = ParseWavSingleChunkHeader(br[c].BaseStream);
                if (!volumeApplied)
                    vols[c] = srcFilenames[c].Volume / 100F; //get percentage
                else
                    vols[c] = 1; //100%

                //move to the correct point in each wav
                uint wOffset = (uint)(whi[c].AvgBytesPerSec * ((float)offset / 1000));
                wOffset -= wOffset % whi[c].BlockAlign;
                br[c].BaseStream.Seek((long)wOffset, SeekOrigin.Current);

                if (whi[c].AudioLength > maxLen)
                    maxLen = whi[c].AudioLength;

                if (whi[c].Channels == 2)
                    outWav = c;
            }

            WavSingleChunkHeader who = new WavSingleChunkHeader();

            if (length == 0)
                length = maxLen;

            uint wLength = (uint)(whi[outWav].AvgBytesPerSec * ((float)length / 1000));
            wLength -= wLength % whi[outWav].BlockAlign;

            who.FileId = "RIFF";
            who.FileLength = (uint)(br[outWav].BaseStream.Length - whi[outWav].FileLength) + wLength;
            who.RiffType = "WAVE";

            who.ChunkHeaderId = "fmt ";
            who.ChunkHeaderLength = whi[outWav].ChunkHeaderLength;
            who.FormatTag = whi[outWav].FormatTag;
            who.Channels = whi[outWav].Channels;
            who.SamplesPerSec = whi[outWav].SamplesPerSec;
            who.AvgBytesPerSec = whi[outWav].AvgBytesPerSec;
            who.BlockAlign = whi[outWav].BlockAlign;
            who.BitsPerSample = whi[outWav].BitsPerSample;
            who.ExtraBytes = whi[outWav].ExtraBytes;

            who.ChunkId = "data";
            who.ChunkLength = wLength;

            using (FileStream fso = File.OpenWrite(dstFilename))
            {
                WriteSingleChunkHeader(who, fso);

                int loops = (int)((who.AvgBytesPerSec / who.BlockAlign) * ((float)length / 1000));
                int fadeLen = (int)((who.AvgBytesPerSec / who.BlockAlign) * ((float)fade / 1000));

                Double maxVol = (volume / (float)srcFilenames.Length);  //reduce volume Audio in game
                maxVol *= 1F + ((srcFilenames.Length - 1) * 0.33F);  //add an extra third per file to cater for volume loss

                Double vol = 0; //initial volume
                if (fade == 0)
                    vol = maxVol;

                int b32;

                BinaryEndianWriter bw = new BinaryEndianWriter(fso);

                Double step = (double)(maxVol - 0) / fadeLen; //fade in
                if (Double.IsInfinity(step))
                    step = 0;
                int allLeft = 0;
                int allRight = 0;

                long[] streamPos = new long[br.Length]; //fast way to track pos in stream
                for (int c = 0; c < br.Length; c++)
                    streamPos[c] = br[c].BaseStream.Position;
                long[] streamLen = new long[br.Length]; //fast way to get length of stream
                for (int c = 0; c < br.Length; c++)
                    streamLen[c] = br[c].BaseStream.Length;

                for (int i = 0; i != loops; i++)
                {
                    if (i == fadeLen)
                        step = 0; //use max volume
                    if (i == loops - fadeLen) //fade out
                        step = (double)(0 - maxVol) / fadeLen;

                    allLeft = 0;
                    allRight = 0;

                    for (int c = 0; c < br.Length; c++) //each input stream
                    {
                        BinaryEndianReader b = br[c];
                        WavSingleChunkHeader w = whi[c];

                        //Left channel
                        b32 = 0;
                        if (streamPos[c] + 2 < streamLen[c])
                        {
                            b32 = (int)(b.ReadInt16(EndianType.Little) * vols[c]);
                            streamPos[c] += 2;
                        }
                        allLeft += (int)(b32 * vol);
                        allLeft = (short)Math.Max((int)short.MinValue, Math.Min((int)short.MaxValue, allLeft));

                        if (who.Channels > 1)
                        {
                            if (w.Channels > 1)
                            {
                                //Right channel
                                b32 = 0;
                                if (streamPos[c] + 2 < streamLen[c])
                                {
                                    b32 = (int)(b.ReadInt16(EndianType.Little) * vols[c]);
                                    streamPos[c] += 2;
                                }
                            }
                            allRight += (int)(b32 * vol);
                            allRight = (short)Math.Max((int)short.MinValue, Math.Min((int)short.MaxValue, allRight));
                        }
                    }

                    bw.Write((short)allLeft);
                    if (who.Channels > 1)
                        bw.Write((short)allRight);

                    vol += step;
                }

                foreach (BinaryEndianReader b in br)
                    b.Close();

                fso.Flush();
            }
        }
Exemple #28
0
        private void save()
        {
            using (FileStream fs = File.OpenWrite(_datFilename))
            {
                using (BinaryEndianWriter bw = new BinaryEndianWriter(fs))
                {
                    bw.Write((uint)_datItems.Count, _endianType);
                    bw.Write(_headerFileSize, _endianType);

                    foreach (DatItem di in _datItems.Values)
                    {
                        bw.Write(di.ItemQbKey.Crc, _endianType);
                        bw.Write(di.FileOffset, _endianType);
                        bw.Write(di.FileSize, _endianType);
                        bw.Write(di.Reserved);
                    }
                    fs.Flush();
                }
            }
        }
Exemple #29
0
        public void Write(Stream s)
        {
            BinaryEndianWriter bw = new BinaryEndianWriter(s);
            //using (BinaryEndianWriter bw = new BinaryEndianWriter(s))
            //{
                this.startLengthCheck(bw);

                bw.Write(_magic, this.PakFormat.EndianType);
                bw.Write(_fileSize, this.PakFormat.EndianType);

                foreach (QbItemBase qib in _items)
                    qib.Write(bw);

                ApplicationException ex = this.testLengthCheck(this, bw);
                if (ex != null) throw ex;
            //}
        }
Exemple #30
0
        private PakHeaderItem createBlankFile(string newQbFilename, QbKey itemType, bool filenameInHeader)
        {
            //update the filename in the collection
            List <PakHeaderItem> hd = new List <PakHeaderItem>(_pakHeaders.Values);

            PakHeaderItem newHdr = new PakHeaderItem();

            newHdr.FileLength    = 0; // (uint)(new FileInfo(localFilename)).Length;
            newHdr.FileOffset    = hd[0].FileOffset + (uint)(filenameInHeader ? PakHeaderItem.FullHeaderLength : 0x20);
            newHdr.Flags         = (PakHeaderFlags)(filenameInHeader ? PakHeaderFlags.Filename : 0);
            newHdr.HeaderStart   = 0;
            newHdr.IsStoredInPak = true;
            newHdr.Filename      = newQbFilename;
            newHdr.FileType      = itemType;
            hd.Insert(0, newHdr);

            //update the filename in the collection
            bool pastNew = false;
            Dictionary <string, PakHeaderItem> p = new Dictionary <string, PakHeaderItem>(_pakHeaders.Count);

            bool hasFoundMatch = filenameInHeader;

            foreach (PakHeaderItem ph in hd)
            {
                //small hack to determine which items need to be filled - Find another header with
                if (!hasFoundMatch && ((ph.Flags & PakHeaderFlags.Filename) != PakHeaderFlags.Filename) && ph != newHdr)
                {
                    newHdr.SetFilename(newQbFilename, itemType, _pakFormat.FileExtension, ph);
                    hasFoundMatch = true;
                }

                if (pastNew)
                {
                    ph.HeaderStart += (uint)(filenameInHeader ? PakHeaderItem.FullHeaderLength : 0x20);
                }
                else if (ph != newHdr)
                {
                    ph.FileOffset += (uint)(filenameInHeader ? PakHeaderItem.FullHeaderLength : 0x20);
                }
                else // (ph == newHdr)
                {
                    pastNew = true;
                }

                p.Add(ph.Filename.ToLower(), ph);
            }

            if (!hasFoundMatch)
            {
                newHdr.SetFilename(newQbFilename, itemType, _pakFormat.FileExtension, null);
            }

            _pakFileLength += (uint)(filenameInHeader ? PakHeaderItem.FullHeaderLength : PakHeaderItem.FullHeaderLength - PakHeaderItem.FileNameMaxLength);

            _pakHeaders = p;

            string newPakFilename = string.Format("{0}_{1}", _pakFilename, Guid.NewGuid().ToString("N"));

            using (FileStream fsO = File.Open(newPakFilename, FileMode.CreateNew))
            {
                using (BinaryEndianWriter bw = new BinaryEndianWriter(fsO))
                {
                    writeHeaderItem(bw, newHdr);
                    using (FileStream fsI = File.OpenRead(_pakFilename))
                        copyData(fsI, fsO, new FileInfo(_pakFilename).Length);
                }
            }

            File.Delete(_pakFilename);
            File.Move(newPakFilename, _pakFilename);

            return(newHdr);
        }
Exemple #31
0
        private static uint recurseFiles(bool isRoot, DirectoryInfo dir, BinaryEndianWriter bwFst, BinaryEndianWriter bwStr, ref ulong totalSize, uint parentDirectory, Stream stream, ulong dataOffset, bool deleteWhileBuilding)
        {
            uint fileCount = 0;
            uint t; //temp uint

            uint rootPlaceHolder = 0;

            if (isRoot)
            {
                bwFst.Write(0x01000000, EndianType.Big);
                bwFst.Write(0x00000000, EndianType.Big);
                rootPlaceHolder = (uint)bwFst.BaseStream.Position;
                bwFst.Write(0x00000000, EndianType.Big); //write the file count to the saved space
            }

            FileInfo[] files = dir.GetFiles();
            DirectoryInfo[] directories = dir.GetDirectories();

            FileInfo f = null;
            DirectoryInfo d = null;

            uint fIdx = 0;
            uint dIdx = 0;

            while (fIdx < files.Length || dIdx < directories.Length)
            {
                //process files and folders in order
                f = (fIdx < files.Length) ? files[fIdx] : null;
                d = (dIdx < directories.Length) ? directories[dIdx] : null;
                if ((f != null && d != null && !compareNamesALessThanB(f.Name, d.Name)) || f == null)
                {
                    f = null;
                    dIdx++;
                }
                else
                {
                    d = null;
                    fIdx++;
                }

                if (d != null)
                {
                    //add the current folder
                    t = (0x01000000) | ((uint)bwStr.BaseStream.Position & 0x00ffffff);  //01=folder | folder name offset
                    bwFst.Write(t, EndianType.Big);

                    bwFst.Write(parentDirectory, EndianType.Big); //parent id

                    uint placeholderPos = (uint)bwFst.BaseStream.Position;
                    bwFst.Write(parentDirectory, EndianType.Big); //placeholder for file count

                    //write to file names stream
                    bwStr.Write(Encoding.Default.GetBytes(d.Name), 0, d.Name.Length);
                    bwStr.Write((byte)0x00); //null terminated

                    fileCount++;
                    fileCount += recurseFiles(false, d, bwFst, bwStr, ref totalSize, fileCount + parentDirectory, stream, dataOffset, deleteWhileBuilding);

                    bwFst.Seek((int)placeholderPos, SeekOrigin.Begin);
                    bwFst.Write(fileCount + parentDirectory + 1, EndianType.Big); //write the file count to the saved space
                    bwFst.Seek(0, SeekOrigin.End);
                }
                else
                {
                    //add the current file
                    t = (0x00000000) | ((uint)bwStr.BaseStream.Position & 0x00ffffff);  //00=file | file name offset
                    bwFst.Write(t, EndianType.Big);
                    ulong fstPos = totalSize;
                    bwFst.Write((uint)(totalSize >> 2), EndianType.Big); //file offset
                    bwFst.Write((uint)((uint)f.Length), EndianType.Big); //file length

                    fileCount++;

                    t = (uint)f.Length;
                    if (t % 4 != 0)
                        t += 4 - (t % 4);
                    totalSize += t;

                    bwStr.Write(Encoding.Default.GetBytes(f.Name), 0, f.Name.Length);
                    bwStr.Write((byte)0x00); //null terminated

                    if (stream != null)
                    {
                        //test file is in the correct location
                        if (fstPos != 0 && ((ulong)stream.Position - dataOffset) != fstPos)
                            throw new ApplicationException("Bad fstPos");

                        copyStream(f.FullName, stream, 4);

                        //test file is padded to the correct length
                        if (fstPos != 0 && ((ulong)stream.Position - dataOffset) != totalSize)
                            throw new ApplicationException("Bad fstPos");

                        if (deleteWhileBuilding)
                            FileHelper.Delete(f.FullName);
                    }
                }

            }

            if (isRoot)
            {
                fileCount++; //add on the 1 for the root directory header
                bwFst.Seek((int)rootPlaceHolder, SeekOrigin.Begin);
                bwFst.Write(fileCount, EndianType.Big); //write the file count to the saved space
                bwFst.Seek(0, SeekOrigin.End);

                if (bwStr.BaseStream.Position % 4 != 0)
                    bwStr.Write(new byte[4 - (bwStr.BaseStream.Position % 4)]);
            }

            return fileCount;
        }
Exemple #32
0
 protected void StartLengthCheck(BinaryEndianWriter bw)
 {
     _lengthCheckStart = this.StreamPos(bw);
 }
Exemple #33
0
        private void xBoxCompress(string uncompFilename, string compFilename)
        {
            if (uncompFilename.ToLower() == compFilename.ToLower()) //nothing to do
            {
                return;
            }

            if (File.Exists(compFilename))
            {
                File.Delete(compFilename);
            }

            try
            {
                if (this.CompressionType == CompressionType.ZLib)
                {
                    using (FileStream outFileStream = new FileStream(compFilename, FileMode.Create))
                    {
                        using (ZlibOutputStream outZStream = new ZlibOutputStream(outFileStream, true, JZlib.Z_BEST_COMPRESSION))
                        {
                            using (FileStream inFileStream = new FileStream(uncompFilename, FileMode.Open, FileAccess.Read))
                            {
                                copyStream(inFileStream, outZStream);
                            }
                        }
                    }
                }
                else if (this.CompressionType == CompressionType.ZLibChunk)
                {
                    List <uint> sizes   = new List <uint>();
                    List <uint> offsets = new List <uint>();
                    byte[]      header  = new byte[ZlibFilePad];

                    int  pad = 0;
                    long lastUncompressedChunk;
                    long endPos;

                    EndianType et = this.EndianType;

                    int part = 0;

                    using (FileStream inFileStream = new FileStream(uncompFilename, FileMode.Open, FileAccess.Read))
                    {
                        long pos;
                        do
                        {
                            using (FileStream outFileStream = new FileStream(compFilename, inFileStream.Position == 0 ? FileMode.Create : FileMode.Append))
                            {
                                part++;

                                pad = (int)(outFileStream.Position % ZlibBlockPad);
                                if (pad != 0 && outFileStream.Position != 0)
                                {
                                    outFileStream.Write(header, 0, (int)ZlibBlockPad - pad);
                                }

                                pos = outFileStream.Position;

                                outFileStream.Write(Encoding.ASCII.GetBytes("CHNK"), 0, 4);
                                outFileStream.Write(header, 0, (int)_zLibHeaderLen - 4);

                                lastUncompressedChunk = (long)_zLibChunkSize;
                                if (inFileStream.Position + lastUncompressedChunk > inFileStream.Length)
                                {
                                    lastUncompressedChunk = inFileStream.Length - inFileStream.Position;
                                }

                                using (ZlibOutputStream outZStream = new ZlibOutputStream(outFileStream, true, JZlib.Z_BEST_COMPRESSION))
                                {
                                    copyStream(inFileStream, outZStream, (int)lastUncompressedChunk);

                                    offsets.Add((uint)pos);
                                    sizes.Add((uint)(outFileStream.Position - pos) - _zLibHeaderLen);
                                }
                            }
                        } while (inFileStream.Position < inFileStream.Length);

                        using (FileStream outFileStream = new FileStream(compFilename, inFileStream.Position == 0 ? FileMode.Create : FileMode.Append))
                        {
                            //find the end of the last file.
                            endPos = (int)(outFileStream.Position % ZlibBlockPad);
                            if (endPos != 0)
                            {
                                endPos = ZlibBlockPad - endPos;
                            }
                            endPos += outFileStream.Position;

                            //pad the compressed file
                            pad = (int)(outFileStream.Position % ZlibFilePad);
                            if (pad != 0 && outFileStream.Position != 0)
                            {
                                outFileStream.Write(header, 0, (int)ZlibFilePad - pad);
                            }
                        }

                        using (FileStream outFileStream = new FileStream(compFilename, FileMode.Open))
                        {
                            using (BinaryEndianWriter bw = new BinaryEndianWriter(outFileStream))
                            {
                                long       uncompressedTotal = 0;
                                EndianType e = this.EndianType;

                                for (int i = 0; i < offsets.Count; i++)
                                {
                                    outFileStream.Seek(offsets[i] + 4, SeekOrigin.Begin);
                                    bw.Write((uint)_zLibHeaderLen, e);                                                      //headerlen
                                    bw.Write((uint)sizes[i], e);                                                            //blocklen
                                    bw.Write((uint)(i != offsets.Count - 1 ? offsets[i + 1] - offsets[i] : 0xffffffff), e); //chunklen ffs if last item

                                    //next blocklen 00's if last block
                                    if (i == offsets.Count - 1)  //last item
                                    {
                                        bw.Write((uint)0x00000000, e);
                                    }
                                    else if (i + 1 == offsets.Count - 1) //secondlast item
                                    {
                                        bw.Write((uint)(endPos - offsets[i + 1]), e);
                                    }
                                    else
                                    {
                                        bw.Write((uint)offsets[i + 2] - offsets[i + 1], e);
                                    }

                                    bw.Write((uint)(i != offsets.Count - 1 ? _zLibChunkSize : lastUncompressedChunk), e); //uncompressed size
                                    bw.Write((uint)uncompressedTotal, e);
                                    uncompressedTotal += (i != offsets.Count - 1 ? _zLibChunkSize : lastUncompressedChunk);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException(string.Format("Compress Failed: {0}", ex));
            }

            //using (FileStream sf = File.OpenRead(uncompFilename))
            //{
            //    using (FileStream df = File.Create(compFilename))
            //    {
            //        using (DeflateStream ds = new DeflateStream(df, CompressionMode.Compress))
            //        {
            //            byte[] b = new byte[10000];
            //            int c = 0;
            //            do
            //            {
            //                c = sf.Read(b, 0, b.Length);
            //                ds.Write(b, 0, c);
            //            }
            //            while (c == b.Length);
            //        }
            //    }
            //}
        }
Exemple #34
0
        private void replaceFile(string qbFilename, long newLength, bool remove, WriteDataToStream callback)
        {
            int filePad = _pakFormat.FilePadSize;

            PakHeaderItem phi = null;

            if (_pakHeaders.ContainsKey(qbFilename.ToLower()))
            {
                phi = _pakHeaders[qbFilename.ToLower()];
            }
            else
            {
                string fqk = QbKey.Create(qbFilename).Crc.ToString("X").PadLeft(8, '0').ToLower();

                if (_pakHeaders.ContainsKey(fqk))
                {
                    phi = _pakHeaders[fqk];
                }
            }

            if (phi != null)
            {
                long pad = filePad - (newLength % filePad);
                if (pad == filePad)
                {
                    pad = 0;
                }

                string newPakFilename = string.Format("{0}_{1}", _pakFormat.FullPakFilename, Guid.NewGuid().ToString("N"));
                string newPabFilename = string.Format("{0}_{1}", _pakFormat.FullPabFilename, Guid.NewGuid().ToString("N"));

                uint minOffset  = uint.MaxValue;
                bool itemFound  = false;
                uint nextOffset = 0;

                foreach (PakHeaderItem ph in _pakHeaders.Values)
                {
                    if (itemFound)
                    {
                        nextOffset = ph.FileOffset + ph.HeaderStart;
                        itemFound  = false; //don't enter this if again
                    }

                    if (object.ReferenceEquals(phi, ph))
                    {
                        itemFound = true;
                    }

                    if (ph.HeaderStart + ph.FileOffset < minOffset)
                    {
                        minOffset = ph.HeaderStart + ph.FileOffset;
                    }
                }

                uint lastItemPad = 0;
                int  repPad      = filePad - ((int)phi.FileLength % filePad);
                if (repPad == filePad)
                {
                    repPad = 0;
                }

                //previously badly padded or last file
                if (nextOffset != 0 && (nextOffset - (phi.FileOffset + phi.HeaderStart)) % filePad != 0)
                {
                    repPad = (int)((nextOffset - (phi.FileOffset + phi.HeaderStart)) - phi.FileLength);
                }


                //position of the LAST header item
                long lastHeaderPos = 0;
                //the length of all the headers (like pak when there's a pab) with padding
                long allHeadersLen = minOffset;
                //position in the input file where our file is to be replaced (not including header pos)
                long fileReplacePos = (phi.HeaderStart + phi.FileOffset) - allHeadersLen;
                //position in the input file after the file that is to be replaced
                long fileAfterReplacePos = fileReplacePos + phi.FileLength + repPad; //item size before modifying header

                //open input pak
                using (FileStream fsPakI = File.Open(_pakFilename, FileMode.Open, FileAccess.Read))
                {
                    using (BinaryEndianReader brPakI = new BinaryEndianReader(fsPakI))
                    {
                        //open output pak temp file
                        using (FileStream fsPakO = File.Create(newPakFilename))
                        {
                            using (BinaryEndianWriter bwPakO = new BinaryEndianWriter(fsPakO))
                            {
                                long diffLen = 0;

                                //do not compensate for missing header when using zlib compression as the header is padded
                                if (remove && _pakFormat.CompressionType != CompressionType.ZLibChunk) //we need to cater for the header being removed on all items before it.
                                {
                                    diffLen = PakHeaderItem.FullHeaderLength;
                                    if ((phi.Flags & PakHeaderFlags.Filename) != PakHeaderFlags.Filename)
                                    {
                                        diffLen -= PakHeaderItem.FileNameMaxLength;
                                    }
                                }


                                //write out the headers
                                foreach (PakHeaderItem ph in _pakHeaders.Values)
                                {
                                    //apply offset change before finding file to be replaced
                                    //this will prevents the offset of the replaced file being changed
                                    ph.FileOffset = (uint)(ph.FileOffset - (long)diffLen);
                                    if (object.ReferenceEquals(phi, ph))
                                    {
                                        if (remove)
                                        {
                                            long remPad = filePad - (phi.FileLength % filePad);
                                            if (remPad == filePad)
                                            {
                                                remPad = 0;
                                            }

                                            diffLen = phi.FileLength + remPad; //now cater for the difference in file size
                                        }
                                        else
                                        {
                                            diffLen       = (long)((ph.FileLength + repPad) - (newLength + pad));
                                            ph.FileLength = (uint)newLength; //0 for remove
                                        }
                                    }

                                    lastHeaderPos += PakHeaderItem.FullHeaderLength;

                                    if (!(remove && object.ReferenceEquals(phi, ph)))
                                    {
                                        writeHeaderItem(bwPakO, ph);
                                    }


                                    if ((ph.Flags & PakHeaderFlags.Filename) != PakHeaderFlags.Filename)
                                    {
                                        lastHeaderPos -= PakHeaderItem.FileNameMaxLength;
                                    }
                                }

                                //Move to the "last" header
                                fsPakI.Seek(lastHeaderPos, SeekOrigin.Begin);

                                //write out "last" HeaderType
                                bwPakO.Write(brPakI.ReadBytes(4));

                                //Modify and write the offset of the "last" header's data
                                uint lastOffset = brPakI.ReadUInt32(_pakFormat.EndianType);
                                lastOffset = (uint)(lastOffset - (long)diffLen);

                                //fix bad padding on last file
                                if (nextOffset == 0 && ((lastOffset - (phi.FileOffset + phi.HeaderStart) % filePad) % filePad) != 0)
                                {
                                    lastItemPad = (uint)filePad - (uint)(lastOffset % filePad);
                                    lastOffset += lastItemPad;
                                }

                                bwPakO.Write(lastOffset, _pakFormat.EndianType);

                                //write out the end of the last header
                                copyData(fsPakI, fsPakO, allHeadersLen - fsPakI.Position);
                            }
                        }
                    }
                }

                //open input pak
                using (FileStream fsPakI = File.Open(_requiresPab ? _pakFormat.FullPabFilename : _pakFilename, FileMode.Open, FileAccess.Read))
                {
                    using (BinaryEndianReader brPakI = new BinaryEndianReader(fsPakI))
                    {
                        //open output pak temp file
                        using (FileStream fsPakO = _requiresPab ? File.Open(newPabFilename, FileMode.Create) : File.Open(newPakFilename, FileMode.Append))
                        {
                            using (BinaryEndianWriter bwPakO = new BinaryEndianWriter(fsPakO))
                            {
                                if (!_requiresPab)
                                {
                                    fsPakI.Seek(allHeadersLen, SeekOrigin.Begin);
                                }

                                //Write out the data starting from the last header to the start of the file to be replaced (minus the length of the type and offset)
                                copyData(fsPakI, fsPakO, fileReplacePos);

                                //Write the new file into the pak file
                                int pos = (int)fsPakO.Position;
                                callback(fsPakO);
                                if (pad != 0)
                                {
                                    fsPakO.Write(new byte[pad], 0, (int)pad);
                                }

                                if (!_requiresPab)
                                {
                                    fileAfterReplacePos += allHeadersLen;
                                }

                                if (lastItemPad != 0)
                                {
                                    fileAfterReplacePos -= lastItemPad; // a bit of a hack as this was not applied when this var was set as we didn't know the values
                                }
                                //write the remainder of source the pak file
                                fsPakI.Seek(fileAfterReplacePos, SeekOrigin.Begin);
                                copyData(fsPakI, fsPakO, fsPakI.Length - fileAfterReplacePos);

                                fsPakO.Flush();
                            }
                        }
                    }
                }

                fixUncompressedFileLengths(newPakFilename, newPabFilename);


                File.Delete(_pakFilename);
                File.Move(newPakFilename, _pakFilename);
                if (_requiresPab)
                {
                    File.Delete(_pakFormat.FullPabFilename);
                    File.Move(newPabFilename, _pakFormat.FullPabFilename);
                }


                _pakFormat.Compress();
            }
            else
            {
                throw new ApplicationException(string.Format("'{0}' does not exist in '{1}'", qbFilename, _pakFilename));
            }
        }
Exemple #35
0
        /// <summary>
        /// Call after derived class has written its data in Write()
        /// </summary>
        /// <param name="br"></param>
        public virtual void WriteEnd(BinaryEndianWriter bw)
        {
            #region switch
            switch (_qbFormat)
            {
                case QbFormat.SectionValue:
                    //Simple section type:
                    //  ItemId, FileId, Value, Reserved
                    bw.Write(_reserved, this.Root.PakFormat.EndianType);
                    break;

                case QbFormat.StructItemValue:
                    //case QbItemType.StructItemQbKeyString:
                    //Simple struct type:
                    //  ItemId, Value (4 byte), NextItemPointer
                        bw.Write(_nextItemPointer, this.Root.PakFormat.EndianType);
                    break;

                default:
                    break;
            }
            #endregion
        }
Exemple #36
0
        public static void BuildPartition(string partitionBinFilename,
                                          string mainDolFilename,
                                          string appLoaderImgFilename,
                                          string bi2BinFilename,
                                          string bootBinFilename,
                                          string sourceDirectory,
                                          string partitionFilename,
                                          bool deleteWhileBuilding)
        {
            ulong totalSize = 0;

            BinaryEndianReader brFst = null;
            BinaryEndianWriter bwFst = new BinaryEndianWriter(new MemoryStream());
            BinaryEndianWriter bwStr = new BinaryEndianWriter(new MemoryStream());
            BinaryEndianWriter bwBootBin = null;
            BinaryEndianWriter bwPartitionBin = null;
            BinaryEndianWriter bwB12Bin = null;

            try
            {

                DirectoryInfo inputFolder = new DirectoryInfo(sourceDirectory);

                //DateTime n = DateTime.Now;
                uint fileCount = recurseFiles(true, inputFolder, bwFst, bwStr, ref totalSize, 0, null, 0, deleteWhileBuilding);
                //System.Diagnostics.Debug.WriteLine((DateTime.Now - n).Ticks);

                // get the file sizes we need - apploader and main.dol
                FileInfo appLoaderImg = new FileInfo(appLoaderImgFilename);
                FileInfo mainDol = new FileInfo(mainDolFilename);

                // now calculate the relative offsets
                uint pad1Size = 0x100 - (((uint)appLoaderImg.Length + 0x2440) % 0x100);
                uint pad2Size = 0x100 - ((uint)mainDol.Length % 0x100);

                // just a pad out for no real reason :)
                uint pad3Size = 0x2000;

                uint mainDolOffset = 0x2440 + (uint)appLoaderImg.Length + pad1Size;
                uint fstOffset = mainDolOffset + pad2Size + (uint)mainDol.Length;

                // modify the data size in partition.bin
                // read in partition.bin
                bwPartitionBin = new BinaryEndianWriter(new MemoryStream(File.ReadAllBytes(partitionBinFilename)));

                // now Actual size = scaled up by sizes
                totalSize += pad1Size + 0x2440 + pad2Size + pad3Size + (uint)mainDol.Length + (uint)appLoaderImg.Length;

                ulong dataSize = (totalSize / 0x7c00) * 0x8000;
                if (dataSize % 0x7c00 != 0)
                    dataSize += 0x8000;

                bwPartitionBin.Seek(0x2BC, SeekOrigin.Begin);
                bwPartitionBin.Write((uint)dataSize >> 2, EndianType.Big);

                // generate a boot.bin
                bwBootBin = new BinaryEndianWriter(new MemoryStream(File.ReadAllBytes(bootBinFilename)));
                // now the size offsets
                bwBootBin.Seek(0x420, SeekOrigin.Begin);
                bwBootBin.Write(mainDolOffset >> 2, EndianType.Big);
                bwBootBin.Write(fstOffset >> 2, EndianType.Big);
                bwBootBin.Write((uint)(bwFst.BaseStream.Length + bwStr.BaseStream.Length) >> 2, EndianType.Big);
                bwBootBin.Write((uint)(bwFst.BaseStream.Length + bwStr.BaseStream.Length) >> 2, EndianType.Big);

                // calculate what we need to modify the FST entries by
                ulong dataOffset = 0x2440 + pad1Size + (uint)appLoaderImg.Length + (uint)mainDol.Length + pad2Size + (uint)bwFst.BaseStream.Length + (uint)bwStr.BaseStream.Length + pad3Size;
                dataOffset = (dataOffset >> 2);

                // modify the fst.bin to include all the correct offsets
                brFst = new BinaryEndianReader(bwFst.BaseStream);
                brFst.BaseStream.Seek(8, SeekOrigin.Begin);
                uint fstEntries = brFst.ReadUInt32(EndianType.Big);

                for (int i = 1; i < fstEntries; i++) //1 as we've already skipped the root
                {
                    if (brFst.ReadByte() == 0) //file
                    {
                        brFst.BaseStream.Seek(3, SeekOrigin.Current); //skip the rest of the uint
                        uint temp = brFst.ReadUInt32(EndianType.Big);
                        bwFst.BaseStream.Seek(-4, SeekOrigin.Current); //THE STREAMS ARE THE SAME (be careful of bugs when the position moves)
                        bwFst.Write((uint)dataOffset + temp, EndianType.Big);
                        brFst.BaseStream.Seek(4, SeekOrigin.Current); //skip the rest of the file
                    }
                    else
                        brFst.BaseStream.Seek(0xc - 1, SeekOrigin.Current); //skip the rest of the directory
                }

                using (FileStream fs = new FileStream(partitionFilename, FileMode.Create))
                {
                    copyStream(bwPartitionBin.BaseStream, fs, 4);

                    copyStream(bwBootBin.BaseStream, fs, 4);

                    copyStream(bi2BinFilename, fs, 4);

                    copyStream(appLoaderImgFilename, fs, 4);

                    fs.Write(new byte[pad1Size], 0, (int)pad1Size);

                    copyStream(mainDolFilename, fs, 4);

                    fs.Write(new byte[pad2Size], 0, (int)pad2Size);

                    copyStream(bwFst.BaseStream, fs, 4);

                    copyStream(bwStr.BaseStream, fs, 4);

                    fs.Write(new byte[pad3Size], 0, (int)pad3Size);

                    //copy all the files to the end of the partition
                    totalSize = dataOffset; //will give the offsets the correct value (not that it matters here heh)
                    bwFst.BaseStream.Seek(0, SeekOrigin.Begin);
                    bwStr.BaseStream.Seek(0, SeekOrigin.Begin);
                    recurseFiles(true, inputFolder, bwFst, bwStr, ref totalSize, 0, fs, (ulong)fs.Position - dataOffset, deleteWhileBuilding);

                    if (deleteWhileBuilding)
                    {
                        try
                        {
                            inputFolder.Delete(true);
                        }
                        catch
                        {
                        }
                    }
                }

            }
            finally
            {
                if (brFst != null)
                    brFst.Close();
                bwFst.Close();
                bwStr.Close();
                if (bwBootBin != null)
                    bwBootBin.Close();
                if (bwPartitionBin != null)
                    bwPartitionBin.Close();
                if (bwB12Bin != null)
                    bwB12Bin.Close();
            }
        }
Exemple #37
0
 protected void StartLengthCheck(BinaryEndianWriter bw)
 {
     _lengthCheckStart = this.StreamPos(bw);
 }
Exemple #38
0
 private void startLengthCheck(BinaryEndianWriter bw)
 {
     _lengthCheckStart = this.StreamPos(bw.BaseStream);
 }
Exemple #39
0
 protected ApplicationException TestLengthCheck(object sender, BinaryEndianWriter bw)
 {
     uint len = this.Length;
     if (this.StreamPos(bw) - _lengthCheckStart != len)
     {
         return new ApplicationException(QbFile.FormatWriteLengthExceptionMessage(sender, _lengthCheckStart, this.StreamPos(bw), len));
     }
     else
         return null;
 }
Exemple #40
0
 protected uint StreamPos(BinaryEndianWriter bw)
 {
     return(Root.StreamPos(bw.BaseStream));
 }
Exemple #41
0
        internal override void Write(BinaryEndianWriter bw)
        {
            base.StartLengthCheck(bw);

            base.Write(bw);

            foreach (uint i in _values)
                bw.Write(i, base.Root.PakFormat.EndianType);

            base.WriteEnd(bw);

            ApplicationException ex = base.TestLengthCheck(this, bw);
            if (ex != null) throw ex;
        }
Exemple #42
0
        /// <summary>
        /// Write the item to the Binary Writer
        /// </summary>
        /// <param name="bw"></param>
        internal virtual void Write(BinaryEndianWriter bw)
        {
            bw.Write(_qbItemValue, this.Root.PakFormat.EndianType);

            #region switch

            uint qbKeyCrc = (_itemQbKey == null ? 0 : _itemQbKey.Crc);

            switch (_qbFormat)
            {
            case QbFormat.SectionPointer:
                //Complex section type:
                //  ItemId, FileId, Pointer, Reserved
                bw.Write(qbKeyCrc, this.Root.PakFormat.EndianType);
                bw.Write(_fileId, this.Root.PakFormat.EndianType);
                bw.Write(_pointer, this.Root.PakFormat.EndianType);
                bw.Write(_reserved, this.Root.PakFormat.EndianType);
                break;

            case QbFormat.SectionValue:
                //Simple section type:
                //  ItemId, FileId
                bw.Write(qbKeyCrc, this.Root.PakFormat.EndianType);
                bw.Write(_fileId, this.Root.PakFormat.EndianType);
                break;

            case QbFormat.StructItemPointer:
                //Complex struct type:
                //  ItemId, Pointer, NextItemPointer
                bw.Write(qbKeyCrc, this.Root.PakFormat.EndianType);
                bw.Write(_pointer, this.Root.PakFormat.EndianType);
                bw.Write(_nextItemPointer, this.Root.PakFormat.EndianType);
                break;

            case QbFormat.StructItemValue:
                //Simple struct type:
                //  ItemId, Value (4 byte), NextItemPointer
                bw.Write(qbKeyCrc, this.Root.PakFormat.EndianType);
                break;

            case QbFormat.ArrayPointer:
                //Complex array type:
                //  ItemCount, Pointer, Pointers -  (if length is 1 then pointer points to first item and Pointers are abscent)
                bw.Write(_itemCount, this.Root.PakFormat.EndianType);
                if (_itemCount == 0)
                {
                    bw.Write(0, this.Root.PakFormat.EndianType);
                }
                else if (_itemCount > 1)
                {
                    bw.Write(_pointer, this.Root.PakFormat.EndianType);
                }
                for (int i = 0; i < _itemCount; i++)
                {
                    bw.Write(_pointers[i], this.Root.PakFormat.EndianType);
                }
                break;

            case QbFormat.ArrayValue:
                //Simple array type:
                //  ItemCount, Pointer, Pointers -  (if length is 1 then pointer points to first item and Pointers are abscent)
                bw.Write(_itemCount, this.Root.PakFormat.EndianType);
                if (_itemCount > 1)
                {
                    bw.Write(_pointer, this.Root.PakFormat.EndianType);
                }
                break;


            case QbFormat.StructHeader:
                break;

            case QbFormat.Floats:
                break;

            case QbFormat.Unknown:
                break;

            default:
                break;
            }
            #endregion
        }
Exemple #43
0
        internal override void Write(BinaryEndianWriter bw)
        {
            base.StartLengthCheck(bw);

            base.Write(bw);

            if (base.QbItemType != QbItemType.StructHeader)
                bw.Write(_headerValue, base.Root.PakFormat.EndianType);
            bw.Write(_iniNextItemPointer, base.Root.PakFormat.EndianType);

            foreach (QbItemBase qib in base.Items)
                qib.Write(bw);

            base.WriteEnd(bw);

            ApplicationException ex = base.TestLengthCheck(this, bw);
            if (ex != null) throw ex;
        }
Exemple #44
0
        private void xBoxCompress(string uncompFilename, string compFilename)
        {
            if (uncompFilename.ToLower() == compFilename.ToLower()) //nothing to do
                return;

            if (File.Exists(compFilename))
                File.Delete(compFilename);

            try
            {
                if (this.CompressionType == CompressionType.ZLib)
                {
                    using (FileStream outFileStream = new FileStream(compFilename, FileMode.Create))
                    {
                        using (ZlibOutputStream outZStream = new ZlibOutputStream(outFileStream, true, JZlib.Z_BEST_COMPRESSION))
                        {
                            using (FileStream inFileStream = new FileStream(uncompFilename, FileMode.Open, FileAccess.Read))
                            {
                                copyStream(inFileStream, outZStream);
                            }
                        }
                    }
                }
                else if (this.CompressionType == CompressionType.ZLibChunk)
                {
                    List<uint> sizes = new List<uint>();
                    List<uint> offsets = new List<uint>();
                    byte[] header = new byte[ZlibFilePad];

                    int pad = 0;
                    long lastUncompressedChunk;
                    long endPos;

                    EndianType et = this.EndianType;

                    int part = 0;

                    using (FileStream inFileStream = new FileStream(uncompFilename, FileMode.Open, FileAccess.Read))
                    {
                        long pos;
                        do
                        {
                            using (FileStream outFileStream = new FileStream(compFilename, inFileStream.Position == 0 ? FileMode.Create : FileMode.Append))
                            {
                                part++;

                                pad = (int)(outFileStream.Position % ZlibBlockPad);
                                if (pad != 0 && outFileStream.Position != 0)
                                    outFileStream.Write(header, 0, (int)ZlibBlockPad - pad);

                                pos = outFileStream.Position;

                                outFileStream.Write(Encoding.ASCII.GetBytes("CHNK"), 0, 4);
                                outFileStream.Write(header, 0, (int)_zLibHeaderLen - 4);

                                lastUncompressedChunk = (long)_zLibChunkSize;
                                if (inFileStream.Position + lastUncompressedChunk > inFileStream.Length)
                                    lastUncompressedChunk = inFileStream.Length - inFileStream.Position;

                                using (ZlibOutputStream outZStream = new ZlibOutputStream(outFileStream, true, JZlib.Z_BEST_COMPRESSION))
                                {
                                    copyStream(inFileStream, outZStream, (int)lastUncompressedChunk);

                                    offsets.Add((uint)pos);
                                    sizes.Add((uint)(outFileStream.Position - pos) - _zLibHeaderLen);
                                }

                            }

                        } while (inFileStream.Position < inFileStream.Length);

                        using (FileStream outFileStream = new FileStream(compFilename, inFileStream.Position == 0 ? FileMode.Create : FileMode.Append))
                        {
                            //find the end of the last file.
                            endPos = (int)(outFileStream.Position % ZlibBlockPad);
                            if (endPos != 0)
                                endPos = ZlibBlockPad - endPos;
                            endPos += outFileStream.Position;

                            //pad the compressed file
                            pad = (int)(outFileStream.Position % ZlibFilePad);
                            if (pad != 0 && outFileStream.Position != 0)
                                outFileStream.Write(header, 0, (int)ZlibFilePad - pad);
                        }

                        using (FileStream outFileStream = new FileStream(compFilename, FileMode.Open))
                        {
                            using (BinaryEndianWriter bw = new BinaryEndianWriter(outFileStream))
                            {
                                long uncompressedTotal = 0;
                                EndianType e = this.EndianType;

                                for (int i = 0; i < offsets.Count; i++)
                                {
                                    outFileStream.Seek(offsets[i] + 4, SeekOrigin.Begin);
                                    bw.Write((uint)_zLibHeaderLen, e); //headerlen
                                    bw.Write((uint)sizes[i], e); //blocklen
                                    bw.Write((uint)(i != offsets.Count - 1 ? offsets[i + 1] - offsets[i] : 0xffffffff), e); //chunklen ffs if last item

                                    //next blocklen 00's if last block
                                    if (i == offsets.Count - 1)  //last item
                                        bw.Write((uint)0x00000000, e);
                                    else if (i + 1 == offsets.Count - 1) //secondlast item
                                        bw.Write((uint)(endPos - offsets[i + 1]), e);
                                    else
                                        bw.Write((uint)offsets[i + 2] - offsets[i + 1], e);

                                    bw.Write((uint)(i != offsets.Count - 1 ? _zLibChunkSize : lastUncompressedChunk), e); //uncompressed size
                                    bw.Write((uint)uncompressedTotal, e);
                                    uncompressedTotal += (i != offsets.Count - 1 ? _zLibChunkSize : lastUncompressedChunk);
                                }
                            }
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException(string.Format("Compress Failed: {0}", ex));
            }

            //using (FileStream sf = File.OpenRead(uncompFilename))
            //{
            //    using (FileStream df = File.Create(compFilename))
            //    {
            //        using (DeflateStream ds = new DeflateStream(df, CompressionMode.Compress))
            //        {
            //            byte[] b = new byte[10000];
            //            int c = 0;
            //            do
            //            {
            //                c = sf.Read(b, 0, b.Length);
            //                ds.Write(b, 0, c);
            //            }
            //            while (c == b.Length);
            //        }
            //    }
            //}
        }