Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.IO;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using System.Globalization;
- using System.Diagnostics;
- namespace ExtractQrc
- {
- public partial class FormMain : Form
- {
- int _version;
- long _treeOffset, _nameOffset, _dataOffset;
- public FormMain()
- {
- InitializeComponent();
- }
- private void ButtonSelectFile_Click(object sender, EventArgs e)
- {
- if (string.IsNullOrEmpty(textBoxTree.Text) || string.IsNullOrEmpty(textBoxName.Text) || string.IsNullOrEmpty(textBoxData.Text))
- {
- MessageBox.Show("Ben faut mettre des trucs dans les cases :o");
- return;
- }
- if (!long.TryParse(textBoxTree.Text, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out _treeOffset))
- {
- MessageBox.Show("Pas un nombre le tree offset ...");
- return;
- }
- if (!long.TryParse(textBoxName.Text, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out _nameOffset))
- {
- MessageBox.Show("Pas un nombre le name offset ...");
- return;
- }
- if (!long.TryParse(textBoxData.Text, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out _dataOffset))
- {
- MessageBox.Show("Pas un nombre le data offset ...");
- return;
- }
- _version = (int)numericUpDownVersion.Value;
- OpenFileDialog ofd = new OpenFileDialog();
- if (ofd.ShowDialog(this) != DialogResult.OK)
- return;
- try
- {
- using (FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read))
- {
- ExtractQrc(fs);
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show("Erreur : " + ex.Message);
- }
- }
- enum Flags
- {
- // must match rcc.h
- Compressed = 0x01,
- Directory = 0x02,
- CompressedZstd = 0x04
- };
- private void ExtractQrc(FileStream fs)
- {
- fs.Seek(_treeOffset, SeekOrigin.Begin);
- string currentPath = string.Empty;
- int nameOff = ReadInt32BE(fs);
- short flags = ReadInt16BE(fs);
- if ((flags & (short)Flags.Directory) > 0)
- {
- //currentPath += GetName(fs, nameOff) + Path.DirectorySeparatorChar;
- //Directory.CreateDirectory(currentPath);
- int child_count = ReadInt32BE(fs);
- int child_node = ReadInt32BE(fs);
- Trace.WriteLine("Path: \"root\" Child count: " + child_count + " Child node: " + child_node);
- ExtractNode(fs, currentPath, child_node, 1);
- }
- else
- {
- MessageBox.Show("o.O le root node n'est pas un fichier, j'y crois pas une seconde");
- }
- }
- private void ExtractNode(FileStream fs, string currentPath, int node, int count)
- {
- Trace.WriteLine("ExtractNode > " + node);
- for (int i = node; i < node + count; ++i)
- {
- fs.Seek(_treeOffset + i * (14 + (_version >= 0x02 ? 8 : 0)), SeekOrigin.Begin);
- int nameOff = ReadInt32BE(fs);
- short flags = ReadInt16BE(fs);
- if ((flags & (short)Flags.Directory) > 0)
- {
- string segment = GetName(fs, nameOff);
- string newPath = currentPath + segment + Path.DirectorySeparatorChar;
- Directory.CreateDirectory(newPath);
- int child_count = ReadInt32BE(fs);
- int child_node = ReadInt32BE(fs);
- uint hash = qt_hash(segment);
- Trace.WriteLine("Dir Path: \"" + newPath + "\" Current node : " + i + " Child count: " + child_count + " Child node: " + child_node + " hash : 0x" + hash.ToString("X8"));
- long pos = fs.Position;
- ExtractNode(fs, newPath, child_node, child_count);
- fs.Seek(pos, SeekOrigin.Begin);
- }
- else
- {
- short country = ReadInt16BE(fs);
- short language = ReadInt16BE(fs);
- string filename = GetName(fs, nameOff);
- Trace.WriteLine("File Path: \"" + currentPath + "\" Current node : " + i + " Filename : " + filename);
- }
- }
- Trace.WriteLine("< ExtractNode");
- }
- private string GetName(FileStream fs, long offset)
- {
- long pos = fs.Position;
- fs.Seek(_nameOffset + offset, SeekOrigin.Begin);
- ushort len = ReadUInt16BE(fs);
- fs.Position += 4; //jump past hash
- byte[] bname = new byte[len * 2];
- fs.Read(bname, 0, len * 2);
- string sname = Encoding.BigEndianUnicode.GetString(bname);
- fs.Seek(pos, SeekOrigin.Begin);
- return sname;
- }
- private static uint qt_hash(string key, uint chained = 0)
- {
- int n = key.Length;
- uint h = chained;
- for (int i = 0; i < n; i++)
- {
- h = (h << 4) + key[i];
- h ^= (h & 0xf0000000) >> 23;
- h &= 0x0fffffff;
- }
- return h;
- }
- private static int ReadInt32BE(FileStream fs)
- {
- byte[] buffer = new byte[4];
- fs.Read(buffer, 0, 4);
- if (BitConverter.IsLittleEndian)
- Array.Reverse(buffer);
- return BitConverter.ToInt32(buffer, 0);
- }
- private static short ReadInt16BE(FileStream fs)
- {
- byte[] buffer = new byte[2];
- fs.Read(buffer, 0, 2);
- if (BitConverter.IsLittleEndian)
- Array.Reverse(buffer);
- return BitConverter.ToInt16(buffer, 0);
- }
- private static ushort ReadUInt16BE(FileStream fs)
- {
- byte[] buffer = new byte[2];
- fs.Read(buffer, 0, 2);
- if (BitConverter.IsLittleEndian)
- Array.Reverse(buffer);
- return BitConverter.ToUInt16(buffer, 0);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement