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