2020-01-22 17:33:34 +00:00

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;
}
}
}