Пример #1
0
        /// <summary>
        /// Checks whether a file is a U8 file or not.
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static bool IsU8(byte[] file)
        {
            if (Lz77.IsLz77Compressed(file))
            {
                byte[] partOfFile = new byte[(file.Length > 2000) ? 2000 : file.Length];

                for (int i = 0; i < partOfFile.Length; i++)
                {
                    partOfFile[i] = file[i];
                }

                Lz77 l = new Lz77();
                partOfFile = l.Decompress(partOfFile);

                return(IsU8(partOfFile));
            }
            else
            {
                Headers.HeaderType h = Headers.DetectHeader(file);
                return(Shared.Swap(BitConverter.ToUInt32(file, (int)h)) == 0x55AA382D);
            }
        }
Пример #2
0
        private void parseU8(Stream u8File)
        {
            fireDebug("Pasing U8 File...");

            u8Header = new U8_Header();
            rootNode = new U8_Node();
            u8Nodes = new List<U8_Node>();
            stringTable = new List<string>();
            data = new List<byte[]>();

            fireDebug("   Detecting Header...");
            headerType = Headers.DetectHeader(u8File);
            Headers.HeaderType tempType = headerType;

            fireDebug("    -> {0}", headerType.ToString());

            if (headerType == Headers.HeaderType.IMD5)
            {
                fireDebug("   Reading IMD5 Header...");
                header = Headers.IMD5.Load(u8File);

                byte[] file = new byte[u8File.Length];
                u8File.Read(file, 0, file.Length);

                MD5 m = MD5.Create();
                byte[] newHash = m.ComputeHash(file, (int)headerType, (int)u8File.Length - (int)headerType);
                m.Clear();

                if (!Shared.CompareByteArrays(newHash, ((Headers.IMD5)header).Hash))
                {
                    fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\");
                    fireWarning(string.Format("Hashes of IMD5 header and file do not match! The content might be corrupted!"));
                }
            }
            else if (headerType == Headers.HeaderType.IMET || headerType == Headers.HeaderType.ShortIMET)
            {
                fireDebug("   Reading IMET Header...");
                header = Headers.IMET.Load(u8File);

                if (!((Headers.IMET)header).HashesMatch)
                {
                    fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\");
                    fireWarning(string.Format("The hash stored in the IMET header doesn't match the headers hash! The header and/or file might be corrupted!"));
                }
            }

            fireDebug("   Checking for Lz77 Compression...");
            if (Lz77.IsLz77Compressed(u8File))
            {
                fireDebug("    -> Lz77 Compression Found...");
                fireDebug("   Decompressing U8 Data...");

                Lz77 l = new Lz77();
                Stream decompressedFile = l.Decompress(u8File);

                tempType = Headers.DetectHeader(decompressedFile);
                u8File = decompressedFile;

                lz77 = true;
            }

            u8File.Seek((int)tempType, SeekOrigin.Begin);
            byte[] temp = new byte[4];

            //Read U8 Header
            fireDebug("   Reading U8 Header: Magic... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.U8Magic)
            { fireDebug("    -> Invalid Magic!"); throw new Exception("U8 Header: Invalid Magic!"); }

            fireDebug("   Reading U8 Header: Offset to Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.OffsetToRootNode)
            { fireDebug("    -> Invalid Offset to Rootnode"); throw new Exception("U8 Header: Invalid Offset to Rootnode!"); }

            fireDebug("   Reading U8 Header: Header Size... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            u8Header.HeaderSize = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            fireDebug("   Reading U8 Header: Offset to Data... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            u8Header.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            u8File.Seek(16, SeekOrigin.Current);

            //Read Rootnode
            fireDebug("   Reading Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            rootNode.Type = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0));
            rootNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2));

            u8File.Read(temp, 0, 4);
            rootNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            u8File.Read(temp, 0, 4);
            rootNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            int stringTablePosition = (int)((int)tempType + u8Header.OffsetToRootNode + rootNode.SizeOfData * 12);
            int nodePosition = (int)u8File.Position;

            //Read Nodes
            for (int i = 0; i < rootNode.SizeOfData - 1; i++)
            {
                fireDebug("   Reading Node #{1} of {2}... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper(), i + 1, rootNode.SizeOfData - 1);
                fireProgress((int)((i + 1) * 100 / (rootNode.SizeOfData - 1)));

                U8_Node tempNode = new U8_Node();
                string tempName = string.Empty;
                byte[] tempData = new byte[0];

                //Read Node Entry
                u8File.Seek(nodePosition, SeekOrigin.Begin);

                fireDebug("    -> Reading Node Entry... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
                u8File.Read(temp, 0, 4);
                tempNode.Type = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0));
                tempNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2));

                u8File.Read(temp, 0, 4);
                tempNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

                u8File.Read(temp, 0, 4);
                tempNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

                nodePosition = (int)u8File.Position;

                fireDebug("        -> {0}", tempNode.Type.ToString());

                //Read Node Name
                u8File.Seek(stringTablePosition + tempNode.OffsetToName, SeekOrigin.Begin);

                fireDebug("    -> Reading Node Name... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
                for (;;)
                {
                    char tempChar = (char)u8File.ReadByte();
                    if (tempChar == 0x00) break;

                    tempName += tempChar;

                    if (tempName.Length > 255) break;
                }

                fireDebug("        -> {0}", tempName);

                //Read Node Data
                if (tempNode.Type == U8_NodeType.File)
                {
                    u8File.Seek((int)tempType + tempNode.OffsetToData, SeekOrigin.Begin);

                    fireDebug("    -> Reading Node Data (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());

                    tempData = new byte[tempNode.SizeOfData];
                    u8File.Read(tempData, 0, tempData.Length);
                }

                if (tempName.ToLower() == "icon.bin") iconSize = getRealSize(tempData);
                else if (tempName.ToLower() == "banner.bin") bannerSize = getRealSize(tempData);
                else if (tempName.ToLower() == "sound.bin") soundSize = getRealSize(tempData);

                u8Nodes.Add(tempNode);
                stringTable.Add(tempName);
                data.Add(tempData);
            }

            fireDebug("Pasing U8 File Finished...");
        }
Пример #3
0
        /// <summary>
        /// Checks whether a file is a U8 file or not.
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static bool IsU8(byte[] file)
        {
            if (Lz77.IsLz77Compressed(file))
            {
                byte[] partOfFile = new byte[(file.Length > 2000) ? 2000 : file.Length];

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

                Lz77 l = new Lz77();
                partOfFile = l.Decompress(partOfFile);

                return IsU8(partOfFile);
            }
            else
            {
                Headers.HeaderType h = Headers.DetectHeader(file);
                return (Shared.Swap(BitConverter.ToUInt32(file, (int)h)) == 0x55AA382D);
            }
        }
Пример #4
0
        private void cbSourceSound_CheckedChanged(object sender, EventArgs e)
        {
            if (cbSourceSound.Checked)
            {
                tbAudioFile.Text = "Internal Sound";

                if (Lz77.IsLz77Compressed(sourceSound))
                { Lz77 l = new Lz77(); sourceSound = l.Decompress(sourceSound); }

                foreach (Label thisLabel in gbWaveInfo.Controls)
                    if (thisLabel.Name.ToLower().Contains("value"))
                    {
                        thisLabel.ForeColor = System.Drawing.Color.Black;
                        thisLabel.Text = "Gathering";
                    }

                bwGatherInfo.RunWorkerAsync(sourceSound);

                //this.Size = new System.Drawing.Size(510, 220);
                this.Size = new System.Drawing.Size(gbWaveInfo.Location.X + gbWaveInfo.Size.Width + 15, this.Size.Height);
            }
            else
            {
                if (tbAudioFile.Text == "Internal Sound")
                    tbAudioFile.Text = string.Empty;

                //this.Size = new System.Drawing.Size(358, 220);
                this.Size = new System.Drawing.Size(btnCancel.Location.X + btnCancel.Size.Width + 15, this.Size.Height);
            }
        }
Пример #5
0
        private void parseU8(Stream u8File)
        {
            fireDebug("Pasing U8 File...");

            u8Header    = new U8_Header();
            rootNode    = new U8_Node();
            u8Nodes     = new List <U8_Node>();
            stringTable = new List <string>();
            data        = new List <byte[]>();

            fireDebug("   Detecting Header...");
            headerType = Headers.DetectHeader(u8File);
            Headers.HeaderType tempType = headerType;

            fireDebug("    -> {0}", headerType.ToString());

            if (headerType == Headers.HeaderType.IMD5)
            {
                fireDebug("   Reading IMD5 Header...");
                header = Headers.IMD5.Load(u8File);

                byte[] file = new byte[u8File.Length];
                u8File.Read(file, 0, file.Length);

                MD5    m       = MD5.Create();
                byte[] newHash = m.ComputeHash(file, (int)headerType, (int)u8File.Length - (int)headerType);
                m.Clear();

                if (!Shared.CompareByteArrays(newHash, ((Headers.IMD5)header).Hash))
                {
                    fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\");
                    fireWarning(string.Format("Hashes of IMD5 header and file do not match! The content might be corrupted!"));
                }
            }
            else if (headerType == Headers.HeaderType.IMET || headerType == Headers.HeaderType.ShortIMET)
            {
                fireDebug("   Reading IMET Header...");
                header = Headers.IMET.Load(u8File);

                if (!((Headers.IMET)header).HashesMatch)
                {
                    fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\");
                    fireWarning(string.Format("The hash stored in the IMET header doesn't match the headers hash! The header and/or file might be corrupted!"));
                }
            }

            fireDebug("   Checking for Lz77 Compression...");
            if (Lz77.IsLz77Compressed(u8File))
            {
                fireDebug("    -> Lz77 Compression Found...");
                fireDebug("   Decompressing U8 Data...");

                Lz77   l = new Lz77();
                Stream decompressedFile = l.Decompress(u8File);

                tempType = Headers.DetectHeader(decompressedFile);
                u8File   = decompressedFile;

                lz77 = true;
            }

            u8File.Seek((int)tempType, SeekOrigin.Begin);
            byte[] temp = new byte[4];

            //Read U8 Header
            fireDebug("   Reading U8 Header: Magic... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.U8Magic)
            {
                fireDebug("    -> Invalid Magic!"); throw new Exception("U8 Header: Invalid Magic!");
            }

            fireDebug("   Reading U8 Header: Offset to Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.OffsetToRootNode)
            {
                fireDebug("    -> Invalid Offset to Rootnode"); throw new Exception("U8 Header: Invalid Offset to Rootnode!");
            }

            fireDebug("   Reading U8 Header: Header Size... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            u8Header.HeaderSize = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            fireDebug("   Reading U8 Header: Offset to Data... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            u8Header.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            u8File.Seek(16, SeekOrigin.Current);

            //Read Rootnode
            fireDebug("   Reading Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            rootNode.Type         = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0));
            rootNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2));

            u8File.Read(temp, 0, 4);
            rootNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            u8File.Read(temp, 0, 4);
            rootNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            int stringTablePosition = (int)((int)tempType + u8Header.OffsetToRootNode + rootNode.SizeOfData * 12);
            int nodePosition        = (int)u8File.Position;

            //Read Nodes
            for (int i = 0; i < rootNode.SizeOfData - 1; i++)
            {
                fireDebug("   Reading Node #{1} of {2}... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper(), i + 1, rootNode.SizeOfData - 1);
                fireProgress((int)((i + 1) * 100 / (rootNode.SizeOfData - 1)));

                U8_Node tempNode = new U8_Node();
                string  tempName = string.Empty;
                byte[]  tempData = new byte[0];

                //Read Node Entry
                u8File.Seek(nodePosition, SeekOrigin.Begin);

                fireDebug("    -> Reading Node Entry... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
                u8File.Read(temp, 0, 4);
                tempNode.Type         = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0));
                tempNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2));

                u8File.Read(temp, 0, 4);
                tempNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

                u8File.Read(temp, 0, 4);
                tempNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

                nodePosition = (int)u8File.Position;

                fireDebug("        -> {0}", tempNode.Type.ToString());

                //Read Node Name
                u8File.Seek(stringTablePosition + tempNode.OffsetToName, SeekOrigin.Begin);

                fireDebug("    -> Reading Node Name... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
                for (;;)
                {
                    char tempChar = (char)u8File.ReadByte();
                    if (tempChar == 0x00)
                    {
                        break;
                    }

                    tempName += tempChar;

                    if (tempName.Length > 255)
                    {
                        break;
                    }
                }

                fireDebug("        -> {0}", tempName);

                //Read Node Data
                if (tempNode.Type == U8_NodeType.File)
                {
                    u8File.Seek((int)tempType + tempNode.OffsetToData, SeekOrigin.Begin);

                    fireDebug("    -> Reading Node Data (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());

                    tempData = new byte[tempNode.SizeOfData];
                    u8File.Read(tempData, 0, tempData.Length);
                }

                if (tempName.ToLower() == "icon.bin")
                {
                    iconSize = getRealSize(tempData);
                }
                else if (tempName.ToLower() == "banner.bin")
                {
                    bannerSize = getRealSize(tempData);
                }
                else if (tempName.ToLower() == "sound.bin")
                {
                    soundSize = getRealSize(tempData);
                }

                u8Nodes.Add(tempNode);
                stringTable.Add(tempName);
                data.Add(tempData);
            }

            fireDebug("Pasing U8 File Finished...");
        }
Пример #6
0
        private void writeToStream(Stream writeStream)
        {
            fireDebug("Writing Wad...");

            //Create Footer Timestamp
            if (!keepOriginalFooter)
            {
                fireDebug("   Building Footer Timestamp...");
                createFooterTimestamp();
            }

            //Save Banner App
            if (hasBanner)
            {
                //Compress icon.bin and banner.bin
                if (lz77CompressBannerAndIcon || lz77DecompressBannerAndIcon)
                {
                    for (int i = 0; i < bannerApp.Nodes.Count; i++)
                    {
                        if (bannerApp.StringTable[i].ToLower() == "icon.bin" ||
                            bannerApp.StringTable[i].ToLower() == "banner.bin")
                        {
                            if (!Lz77.IsLz77Compressed(bannerApp.Data[i]) && lz77CompressBannerAndIcon)
                            {
                                fireDebug("   Compressing {0}...", bannerApp.StringTable[i]);

                                //Get the data without the IMD5 Header
                                byte[] fileData = new byte[bannerApp.Data[i].Length - 32];
                                Array.Copy(bannerApp.Data[i], 32, fileData, 0, fileData.Length);

                                //Compress the data
                                Lz77 l = new Lz77();
                                fileData = l.Compress(fileData);

                                //Add a new IMD5 Header
                                fileData = Headers.IMD5.AddHeader(fileData);
                                bannerApp.Data[i] = fileData;

                                //Update the node
                                bannerApp.Nodes[i].SizeOfData = (uint)fileData.Length;
                            }
                            else if (Lz77.IsLz77Compressed(bannerApp.Data[i]) && lz77DecompressBannerAndIcon)
                            {
                                fireDebug("   Decompressing {0}...", bannerApp.StringTable[i]);

                                //Get the data without the IMD5 Header
                                byte[] fileData = new byte[bannerApp.Data[i].Length - 32];
                                Array.Copy(bannerApp.Data[i], 32, fileData, 0, fileData.Length);

                                //Decompress the data
                                Lz77 l = new Lz77();
                                fileData = l.Decompress(fileData);

                                //Add a new IMD5 Header
                                fileData = Headers.IMD5.AddHeader(fileData);
                                bannerApp.Data[i] = fileData;

                                //Update the node
                                bannerApp.Nodes[i].SizeOfData = (uint)fileData.Length;
                            }
                        }
                    }
                }

                for (int i = 0; i < contents.Count; i++)
                    if (tmd.Contents[i].Index == 0x0000)
                    { fireDebug("   Saving Banner App..."); contents[i] = bannerApp.ToByteArray(); break; }
            }

            //Update Header (Content Size)
            fireDebug("   Updating Header...");
            int contentSize = 0;
            for (int i = 0; i < contents.Count - 1; i++)
                contentSize += Shared.AddPadding(contents[i].Length);

            contentSize += contents[contents.Count - 1].Length;

            wadHeader.ContentSize = (uint)contentSize;
            wadHeader.TmdSize = (uint)(484 + tmd.NumOfContents * 36);

            //Update Contents
            fireDebug("   Updating TMD Contents...");
            tmd.UpdateContents(contents.ToArray());

            //Write Header
            fireDebug("   Writing Wad Header... (Offset: 0x{0})", writeStream.Position.ToString("x8").ToUpper());
            writeStream.Seek(0, SeekOrigin.Begin);
            wadHeader.Write(writeStream);

            //Write Cert
            fireDebug("   Writing Certificate Chain... (Offset: 0x{0})", writeStream.Position.ToString("x8").ToUpper());
            writeStream.Seek(Shared.AddPadding((int)writeStream.Position), SeekOrigin.Begin);
            byte[] temp = cert.ToByteArray();
            writeStream.Write(temp, 0, temp.Length);

            //Write Tik
            fireDebug("   Writing Ticket... (Offset: 0x{0})", writeStream.Position.ToString("x8").ToUpper());
            writeStream.Seek(Shared.AddPadding((int)writeStream.Position), SeekOrigin.Begin);
            temp = tik.ToByteArray();
            writeStream.Write(temp, 0, temp.Length);

            //Write TMD
            fireDebug("   Writing TMD... (Offset: 0x{0})", writeStream.Position.ToString("x8").ToUpper());
            writeStream.Seek(Shared.AddPadding((int)writeStream.Position), SeekOrigin.Begin);
            temp = tmd.ToByteArray();
            writeStream.Write(temp, 0, temp.Length);

            //Write Contents
            ContentIndices[] contentList = tmd.GetSortedContentList();

            for (int i = 0; i < contentList.Length; i++)
            {
                writeStream.Seek(Shared.AddPadding((int)writeStream.Position), SeekOrigin.Begin);

                fireProgress((i + 1) * 100 / contents.Count);

                fireDebug("   Writing Content #{1} of {2}... (Offset: 0x{0})", writeStream.Position.ToString("x8").ToUpper(), i + 1, contents.Count);
                fireDebug("    -> Content ID: 0x{0}", tmd.Contents[contentList[i].Index].ContentID.ToString("x8"));
                fireDebug("    -> Index: 0x{0}", tmd.Contents[contentList[i].Index].Index.ToString("x4"));
                fireDebug("    -> Type: 0x{0} ({1})", ((ushort)tmd.Contents[contentList[i].Index].Type).ToString("x4"), tmd.Contents[contentList[i].Index].Type.ToString());
                fireDebug("    -> Size: {0} bytes", tmd.Contents[contentList[i].Index].Size);
                fireDebug("    -> Hash: {0}", Shared.ByteArrayToString(tmd.Contents[contentList[i].Index].Hash));

                temp = encryptContent(contents[contentList[i].Index], contentList[i].Index);
                writeStream.Write(temp, 0, temp.Length);
            }

            //Write Footer
            if (wadHeader.FooterSize > 0)
            {
                fireDebug("   Writing Footer... (Offset: 0x{0})", writeStream.Position.ToString("x8").ToUpper());
                writeStream.Seek(Shared.AddPadding((int)writeStream.Position), SeekOrigin.Begin);
                writeStream.Write(footer, 0, footer.Length);
            }

            //Padding
            while (writeStream.Position % 64 != 0)
                writeStream.WriteByte(0x00);

            fireDebug("Writing Wad Finished... (Written Bytes: {0})", writeStream.Position);
        }
Пример #7
0
        private void cmOptionsExtract_MouseClick(object sender, EventArgs e)
        {
            ToolStripMenuItem cmSender = sender as ToolStripMenuItem;

            if (cmSender.OwnerItem == tsExtractImages)
            {
                try
                {
                    FolderBrowserDialog fbd = new FolderBrowserDialog();

                    if (cmSender.Text.ToLower() == "both") { fbd.Description = "Select the path where the images will be extracted to. Two folders \"Banner\" and \"Icon\" will be created."; }
                    else { fbd.Description = "Select the path where the images will be extracted to."; }

                    if (fbd.ShowDialog() == DialogResult.OK)
                    {
                        string bannerPath;
                        string iconPath;

                        switch (cmSender.Text.ToLower())
                        {
                            case "banner":
                                bannerPath = fbd.SelectedPath;
                                iconPath = string.Empty;
                                break;
                            case "icon":
                                bannerPath = string.Empty;
                                iconPath = fbd.SelectedPath;
                                break;
                            default: //both
                                bannerPath = fbd.SelectedPath + Path.DirectorySeparatorChar + "Banner";
                                iconPath = fbd.SelectedPath + Path.DirectorySeparatorChar + "Icon";
                                break;
                        }

                        if (!string.IsNullOrEmpty(bannerPath))
                        {
                            if (!Directory.Exists(bannerPath)) Directory.CreateDirectory(bannerPath);

                            if (string.IsNullOrEmpty(replacedBanner))
                            {
                                for (int i = 0; i < bannerBin.NumOfNodes; i++)
                                {
                                    if (bannerBin.StringTable[i].ToLower().EndsWith(".tpl"))
                                    {
                                        Image img = TPL.Load(bannerBin.Data[i]).ExtractTexture();
                                        img.Save(bannerPath + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(bannerBin.StringTable[i]) + ".png");
                                    }
                                }
                            }
                            else
                            {
                                for (int i = 0; i < newBannerBin.NumOfNodes; i++)
                                {
                                    if (newBannerBin.StringTable[i].ToLower().EndsWith(".tpl"))
                                    {
                                        Image img = TPL.Load(newBannerBin.Data[i]).ExtractTexture();
                                        img.Save(bannerPath + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(newBannerBin.StringTable[i]) + ".png");
                                    }
                                }
                            }
                        }

                        if (!string.IsNullOrEmpty(iconPath))
                        {
                            if (!Directory.Exists(iconPath)) Directory.CreateDirectory(iconPath);

                            if (string.IsNullOrEmpty(replacedIcon))
                            {
                                for (int i = 0; i < iconBin.NumOfNodes; i++)
                                {
                                    if (iconBin.StringTable[i].ToLower().EndsWith(".tpl"))
                                    {
                                        Image img = TPL.Load(iconBin.Data[i]).ExtractTexture();
                                        img.Save(iconPath + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(iconBin.StringTable[i]) + ".png");
                                    }
                                }
                            }
                            else
                            {
                                for (int i = 0; i < newIconBin.NumOfNodes; i++)
                                {
                                    if (newIconBin.StringTable[i].ToLower().EndsWith(".tpl"))
                                    {
                                        Image img = TPL.Load(newIconBin.Data[i]).ExtractTexture();
                                        img.Save(iconPath + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(newIconBin.StringTable[i]) + ".png");
                                    }
                                }
                            }
                        }

                        infoBox("Extracted images successfully!");
                    }
                }
                catch (Exception ex) { errorBox(ex.Message); }
            }
            else if (cmSender.OwnerItem == tsExtractSound)
            {
                try
                {
                    byte[] soundFile = new byte[0];

                    if (string.IsNullOrEmpty(replacedSound))
                    {
                        for (int i = 0; i < sourceWad.BannerApp.NumOfNodes; i++)
                        {
                            if (sourceWad.BannerApp.StringTable[i].ToLower() == "sound.bin")
                                soundFile = sourceWad.BannerApp.Data[i];
                        }
                    }
                    else
                    { soundFile = newSoundBin; }

                    SaveFileDialog sfd = new SaveFileDialog();
                    if (cmSender.Name.ToLower() == "cmextractsoundasbin") { sfd.Filter = "BIN|*.bin"; sfd.FileName = "sound.bin"; }
                    else if (cmSender.Name.ToLower() == "cmextractsoundasaudio")
                    {
                        if (soundFile[32] == 'R' && soundFile[33] == 'I' && soundFile[34] == 'F' && soundFile[35] == 'F')
                        { sfd.Filter = "Wave|*.wav"; sfd.FileName = "sound.wav"; }
                        else if (soundFile[32] == 'B' && soundFile[33] == 'N' && soundFile[34] == 'S' && soundFile[35] == ' ')
                        { sfd.Filter = "Wave|*.wav"; sfd.FileName = "sound.wav"; }
                        else if (soundFile[32] == 'F' && soundFile[33] == 'O' && soundFile[34] == 'R' && soundFile[35] == 'M')
                        { sfd.Filter = "AIFF|*.aif;*.aiff"; sfd.FileName = "sound.aif"; }
                        else if (soundFile[32] == 'L' && soundFile[33] == 'Z' && soundFile[34] == '7' && soundFile[35] == '7')
                        {
                            if (soundFile[41] == 'R' && soundFile[42] == 'I' && soundFile[43] == 'F' && soundFile[44] == 'F')
                            { sfd.Filter = "Wave|*.wav"; sfd.FileName = "sound.wav"; }
                            else if (soundFile[41] == 'B' && soundFile[42] == 'N' && soundFile[43] == 'S' && soundFile[44] == ' ')
                            { sfd.Filter = "Wave|*.wav"; sfd.FileName = "sound.wave"; }
                            else if (soundFile[41] == 'F' && soundFile[42] == 'O' && soundFile[43] == 'R' && soundFile[44] == 'M')
                            { sfd.Filter = "AIFF|*.aif;*.aiff"; sfd.FileName = "sound.aif"; }
                            else throw new Exception("Unsupported Audio Format!");
                        }
                        else throw new Exception("Unsupported Audio Format!");
                    }

                    if (sfd.ShowDialog() == DialogResult.OK)
                    {
                        if (File.Exists(sfd.FileName)) File.Delete(sfd.FileName);

                        if (sfd.FileName.ToLower().EndsWith(".bin"))
                        {
                            File.WriteAllBytes(sfd.FileName, soundFile);
                            infoBox("The sound.bin was successfully extraced!");
                        }
                        else
                        {
                            soundFile = Headers.IMD5.RemoveHeader(soundFile);

                            if (Lz77.IsLz77Compressed(soundFile))
                            { Lz77 l = new Lz77(); soundFile = l.Decompress(soundFile); }

                            if (soundFile[0] == 'B' && soundFile[1] == 'N' && soundFile[2] == 'S' && soundFile[3] == ' ')
                            {
                                Wave w = BNS.BnsToWave(soundFile);
                                w.Save(sfd.FileName);
                                w.Dispose();
                            }
                            else
                                File.WriteAllBytes(sfd.FileName, soundFile);

                            infoBox(string.Format("The sound.bin was successfully converted to {0}!", Path.GetFileName(sfd.FileName)));
                        }
                    }
                }
                catch (Exception ex) { errorBox(ex.Message); }
            }
            else if (cmSender.OwnerItem == tsExtractBrl)
            {
                try
                {
                    FolderBrowserDialog fbd = new FolderBrowserDialog();
                    fbd.Description = "Select the path where the files will be extracted to.";

                    if (fbd.ShowDialog() == DialogResult.OK)
                    {
                        if (cmSender == cmExtractBrlyt || cmSender == cmExtractBothBrl)
                        {
                            //Extract brlyts
                            if (string.IsNullOrEmpty(replacedBanner))
                            {
                                for (int i = 0; i < bannerBin.NumOfNodes; i++)
                                {
                                    if (bannerBin.StringTable[i].ToLower().EndsWith(".brlyt"))
                                    { File.WriteAllBytes(fbd.SelectedPath + Path.DirectorySeparatorChar + bannerBin.StringTable[i], bannerBin.Data[i]); }
                                }
                            }
                            else
                            {
                                for (int i = 0; i < newBannerBin.NumOfNodes; i++)
                                {
                                    if (newBannerBin.StringTable[i].ToLower().EndsWith(".brlyt"))
                                    { File.WriteAllBytes(fbd.SelectedPath + Path.DirectorySeparatorChar + newBannerBin.StringTable[i], newBannerBin.Data[i]); }
                                }
                            }

                            if (string.IsNullOrEmpty(replacedIcon))
                            {
                                for (int i = 0; i < iconBin.NumOfNodes; i++)
                                {
                                    if (iconBin.StringTable[i].ToLower().EndsWith(".brlyt"))
                                    { File.WriteAllBytes(fbd.SelectedPath + Path.DirectorySeparatorChar + iconBin.StringTable[i], iconBin.Data[i]); }
                                }
                            }
                            else
                            {
                                for (int i = 0; i < newIconBin.NumOfNodes; i++)
                                {
                                    if (newIconBin.StringTable[i].ToLower().EndsWith(".brlyt"))
                                    { File.WriteAllBytes(fbd.SelectedPath + Path.DirectorySeparatorChar + newIconBin.StringTable[i], newIconBin.Data[i]); }
                                }
                            }
                        }

                        if (cmSender == cmExtractBothBrl || cmSender == cmExtractBrlan)
                        {
                            //Extract brlans
                            if (string.IsNullOrEmpty(replacedBanner))
                            {
                                for (int i = 0; i < bannerBin.NumOfNodes; i++)
                                {
                                    if (bannerBin.StringTable[i].ToLower().EndsWith(".brlan"))
                                    { File.WriteAllBytes(fbd.SelectedPath + Path.DirectorySeparatorChar + bannerBin.StringTable[i], bannerBin.Data[i]); }
                                }
                            }
                            else
                            {
                                for (int i = 0; i < newBannerBin.NumOfNodes; i++)
                                {
                                    if (newBannerBin.StringTable[i].ToLower().EndsWith(".brlan"))
                                    { File.WriteAllBytes(fbd.SelectedPath + Path.DirectorySeparatorChar + newBannerBin.StringTable[i], newBannerBin.Data[i]); }
                                }
                            }

                            if (string.IsNullOrEmpty(replacedIcon))
                            {
                                for (int i = 0; i < iconBin.NumOfNodes; i++)
                                {
                                    if (iconBin.StringTable[i].ToLower().EndsWith(".brlan"))
                                    { File.WriteAllBytes(fbd.SelectedPath + Path.DirectorySeparatorChar + iconBin.StringTable[i], iconBin.Data[i]); }
                                }
                            }
                            else
                            {
                                for (int i = 0; i < newIconBin.NumOfNodes; i++)
                                {
                                    if (newIconBin.StringTable[i].ToLower().EndsWith(".brlan"))
                                    { File.WriteAllBytes(fbd.SelectedPath + Path.DirectorySeparatorChar + newIconBin.StringTable[i], newIconBin.Data[i]); }
                                }
                            }
                        }

                        infoBox("Extracted files successfully!");
                    }
                }
                catch (Exception ex) { errorBox(ex.Message); }
            }
            else //DOL
            {
                try
                {
                    if (sourceWad.NumOfContents == 3)
                    {
                        int appIndex = 0;
                        if (sourceWad.BootIndex == 1) appIndex = 2;
                        else if (sourceWad.BootIndex == 2) appIndex = 1;

                        if (appIndex > 0)
                        {
                            SaveFileDialog sfd = new SaveFileDialog();
                            sfd.Filter = "Wii Executables|*.dol"; sfd.FileName = (string.IsNullOrEmpty(tbAllLanguages.Text) ? tbEnglish.Text : tbAllLanguages.Text) + ".dol";

                            if (sfd.ShowDialog() == DialogResult.OK)
                            {
                                if (File.Exists(sfd.FileName)) File.Delete(sfd.FileName);
                                File.WriteAllBytes(sfd.FileName, sourceWad.Contents[appIndex]);
                                infoBox(string.Format("The DOL file was successfully extracted to {0}!", Path.GetFileName(sfd.FileName)));
                            }
                        }
                        else errorBox("The DOL file couldn't be found!");
                    }
                    else errorBox("The DOL file couldn't be found!");
                }
                catch (Exception ex) { errorBox(ex.Message); }
            }
        }