311 lines
8.0 KiB
C#
311 lines
8.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
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.IO;
|
|
|
|
namespace CPPConvert
|
|
{
|
|
public partial class frmCPPConvert : Form
|
|
{
|
|
public frmCPPConvert()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
private long _Offset;
|
|
private static long _lastPos = 0l;
|
|
private void ReadRecord(BinaryReader br)
|
|
{
|
|
long curPos = FS.Position;
|
|
int nxtPos = PathStartList[0];
|
|
if (nxtPos - 4 != curPos)
|
|
{
|
|
Console.WriteLine("curpos, nxtpos, lastpos\t{0:X08}\t{1:X08}", curPos - _lastPos, nxtPos- _lastPos);
|
|
FS.Seek(nxtPos - 4, SeekOrigin.Begin);
|
|
}
|
|
PathStartList.RemoveAt(0);
|
|
_lastPos = FS.Position;
|
|
string filePath = ReadString(br);
|
|
Console.WriteLine(filePath.Substring(120,filePath.Length-120));
|
|
string type = ReadString(br);
|
|
int pos = (int) FS.Position;
|
|
byte [] buf = ReadBuffer(br);
|
|
int size = buf.Length;
|
|
if (buf.Length > 4 && StartsWith(buf, "<?xml"))
|
|
{
|
|
int HowMany0Ds = 0;
|
|
int HowMany0As = 0;
|
|
int j = 0;
|
|
while (j < buf.Length - HowMany0As - HowMany0Ds)
|
|
{
|
|
if (buf[j] == 0x0D) HowMany0Ds++;
|
|
if (buf[j] == 0x0A) HowMany0As++;
|
|
j++;
|
|
}
|
|
int misMatch = HowMany0As - HowMany0Ds;
|
|
if (misMatch > 0)
|
|
{
|
|
FS.Position = pos + buf.Length + 4 - misMatch;
|
|
size -= misMatch;
|
|
}
|
|
}
|
|
|
|
//Console.WriteLine("filePath={0}\r\ntype={1}", filePath, type);
|
|
if(type.ToLower().Contains("procedure"))
|
|
{
|
|
tbResults.AppendText(string.Format("Extracted {0}\r\n",PartialName(filePath,type)));
|
|
SaveFile(filePath,type,buf,size);
|
|
}
|
|
}
|
|
private string PartialName(string filePath, string type)
|
|
{
|
|
int skipSlashes = 2 +type.Length - type.Replace("/", "").Length;
|
|
int start = filePath.Length;
|
|
while(skipSlashes-- > 0)
|
|
start = filePath.LastIndexOf('/', start-1);
|
|
return filePath.Substring(start+1);
|
|
}
|
|
private void SaveFile(string filePath, string type, byte[] buf,int size)
|
|
{
|
|
string fn = (tbDest.Text.EndsWith("/") ? tbDest.Text : tbDest.Text + "/") + PartialName(filePath, type);
|
|
BuildPath(fn);
|
|
FileStream fs = File.Create(fn);
|
|
BinaryWriter bw = new BinaryWriter(fs);
|
|
if (filePath.ToUpper().EndsWith(".PNG") && buf[4]==0xA)
|
|
{
|
|
bw.Write(buf, 0, 4);
|
|
bw.Write(Encoding.ASCII.GetBytes("\xD"));
|
|
bw.Write(buf, 4, size-4);
|
|
}
|
|
else
|
|
{
|
|
}
|
|
bw.Write(buf,0,size);
|
|
bw.Close();
|
|
}
|
|
private void BuildPath(string fn)
|
|
{
|
|
FileInfo fi = new FileInfo(fn);
|
|
fi.Directory.Create();
|
|
}
|
|
private string ReadString(BinaryReader br)
|
|
{
|
|
byte[] buffer = ReadBuffer(br);
|
|
return Encoding.BigEndianUnicode.GetString(buffer, 0, buffer.Length);
|
|
}
|
|
private byte[] ReadBuffer(BinaryReader br)
|
|
{
|
|
int size = ReadBytesToInt32(br);
|
|
if (size == -1) size = 0;
|
|
if(size > FS.Length || size < 0)
|
|
throw(new Exception(string.Format("Location {0:X08} has a buffer that is too big {1:X08}",FS.Position,size)));
|
|
byte[] buffer = new byte[size];
|
|
br.Read(buffer, 0, size);
|
|
_Offset += size;
|
|
return buffer;
|
|
}
|
|
private int ReadBytesToInt32(BinaryReader br)
|
|
{
|
|
byte[] buffer = new byte[4];
|
|
long off = Offset;
|
|
br.Read(buffer, 0, 4);
|
|
int i = BitConverter.ToInt32(buffer.Reverse().ToArray(), 0);
|
|
//if(i>255) Console.WriteLine("{0:X8} - {1:X8}", off,i);
|
|
_Offset += 4;
|
|
return i;
|
|
}
|
|
private void btnBrowse_Click(object sender, EventArgs e)
|
|
{
|
|
ofd.FileName = tbFile.Text;
|
|
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
|
tbFile.Text = ofd.FileName;
|
|
}
|
|
private void btnBrowseDest_Click(object sender, EventArgs e)
|
|
{
|
|
fbd.SelectedPath = tbDest.Text;
|
|
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
|
tbDest.Text = fbd.SelectedPath;
|
|
}
|
|
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
this.Close();
|
|
}
|
|
public long Offset
|
|
{
|
|
get
|
|
{
|
|
return FS.Seek(0, SeekOrigin.Current);
|
|
}
|
|
}
|
|
FileStream _FS;
|
|
public FileStream FS
|
|
{
|
|
get { return _FS; }
|
|
set { _FS = value; }
|
|
}
|
|
private List<int> _PathStartList;
|
|
|
|
public List<int> PathStartList
|
|
{
|
|
get { return _PathStartList; }
|
|
set { _PathStartList = value; }
|
|
}
|
|
private List<int> GetPathStartList(string findIt,FileStream fs)
|
|
{
|
|
List<int> lst= new List<int>();
|
|
BinaryReader br = new BinaryReader(FS);
|
|
int buflen = (int) FS.Length;
|
|
byte [] buf =br.ReadBytes(buflen);
|
|
byte[] bFindIt = Encoding.BigEndianUnicode.GetBytes(findIt);
|
|
int findlen = bFindIt.Length;
|
|
pb.Text = "Looking for C:/";
|
|
pb.Maximum = (int) fs.Length;
|
|
for (int i = 0; i < buflen - 4; i++)
|
|
{
|
|
if (buf[i] == bFindIt[0])
|
|
{
|
|
int k=0;
|
|
for (; k < findlen; k++)
|
|
if (buf[k + i] != bFindIt[k])
|
|
break;
|
|
if (k == findlen) lst.Add(i);
|
|
}
|
|
pb.Value = i;
|
|
}
|
|
pb.Text = "Done";
|
|
br.Close();
|
|
return lst;
|
|
}
|
|
|
|
private bool Foundit(byte[] buf, int offset, byte [] bFindIt)
|
|
{
|
|
for (int i = 0; i < bFindIt.Length; i++)
|
|
if (buf[i + offset] != (int)bFindIt[i])
|
|
return false;
|
|
return true;
|
|
}
|
|
private void processToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
tbResults.Clear();
|
|
ConvertCPP(tbFile.Text);
|
|
pb.Text = "All Done";
|
|
}
|
|
|
|
private void ConvertCPP(string fileName)
|
|
{
|
|
FS = File.OpenRead(fileName);
|
|
PathStartList = GetPathStartList("C:/", FS);
|
|
//Console.WriteLine("===> {0} Paths", PathStartList.Count);
|
|
FS = File.OpenRead(fileName);
|
|
BinaryReader br = new BinaryReader(FS);
|
|
try
|
|
{
|
|
_Offset = 0;
|
|
int nRecords = ReadBytesToInt32(br);
|
|
//Console.WriteLine("===> {0} Records", nRecords);
|
|
int i = 0;
|
|
pb.Text = "Splitting File";
|
|
pb.Maximum = nRecords;
|
|
while (_Offset < FS.Length && nRecords-- > 0)
|
|
{
|
|
ReadRecord(br);
|
|
pb.Value = ++i;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
tbResults.AppendText(string.Format("{0} - {1}-{2}\r\n{3}\r\n\r\n", fileName, ex.GetType().Name, ex.Message, ex.StackTrace));
|
|
}
|
|
finally
|
|
{
|
|
br.Close();
|
|
}
|
|
}
|
|
|
|
private void allToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
tbResults.Clear();
|
|
FileInfo[] myFiles = new FileInfo(tbFile.Text).Directory.GetFiles("*.cpp");
|
|
foreach (FileInfo fi in myFiles)
|
|
ConvertCPP(fi.FullName);
|
|
pb.Text = "All Done";
|
|
}
|
|
|
|
private void testToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
FS = File.OpenRead(tbFile.Text);
|
|
PathStartList = GetPathStartList("C:/", FS);
|
|
FS = File.OpenRead(tbFile.Text);
|
|
BinaryReader br = new BinaryReader(FS);
|
|
int nRecords = ReadBytesToInt32(br);
|
|
int bytesRead = 4;
|
|
int countByThree = 0;
|
|
while (bytesRead < FS.Length)
|
|
{
|
|
if(countByThree % 3 == 0)
|
|
{
|
|
long curPos = FS.Position;
|
|
int nxtPos = PathStartList[0];
|
|
if (nxtPos - 4 != curPos)
|
|
{
|
|
Console.WriteLine("curpos, nxtpos, lastpos\t{0:X08}\t{1:X08}", curPos - _lastPos, nxtPos - _lastPos);
|
|
FS.Seek(nxtPos - 4, SeekOrigin.Begin);
|
|
}
|
|
PathStartList.RemoveAt(0);
|
|
}
|
|
_lastPos = FS.Position;
|
|
long pos = FS.Position;
|
|
int size = ReadBytesToInt32(br);
|
|
bytesRead += 4;
|
|
byte[] buf = br.ReadBytes(size);
|
|
bytesRead += size;
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.Append(string.Format("{0:D4} {1:X08} {2:X08} ",countByThree ,pos,size));
|
|
for (int i = 0; i < 120 && i < size; i++)
|
|
{
|
|
if(buf[i] < 0x20)
|
|
sb.Append('.');
|
|
else
|
|
sb.Append((char) buf[i]);
|
|
}
|
|
Console.WriteLine(sb.ToString());
|
|
if (StartsWith(buf, "<?xml"))
|
|
{
|
|
int HowMany0Ds = 0;
|
|
int HowMany0As = 0;
|
|
int j = 0;
|
|
while (j < buf.Length - HowMany0As - HowMany0Ds)
|
|
{
|
|
if (buf[j] == 0x0D) HowMany0Ds++;
|
|
if (buf[j] == 0x0A) HowMany0As++;
|
|
j++;
|
|
}
|
|
int misMatch = HowMany0As - HowMany0Ds;
|
|
if (misMatch > 0)
|
|
{
|
|
FS.Position = pos + size + 4 - misMatch;
|
|
bytesRead -= misMatch;
|
|
}
|
|
}
|
|
countByThree++;
|
|
}
|
|
}
|
|
|
|
private bool StartsWith(byte[] buf, string findIt)
|
|
{
|
|
byte[] bFindIt = Encoding.ASCII.GetBytes(findIt);
|
|
int findlen = bFindIt.Length;
|
|
int k=0;
|
|
for (; k < findlen; k++)
|
|
if (buf[k] != bFindIt[k])
|
|
return false;
|
|
return true;
|
|
}
|
|
}
|
|
}
|