private static void OutputChildControls(byte[] data, string indentation) { using (MemoryStream stream = new MemoryStream(data)) { DelphiBinaryReader reader = new DelphiBinaryReader(stream); int count = reader.ReadInteger(); for (int i = 0; i < count; i++) { string name = (string) reader.ReadValue(); WriteLine("{0}{1}", indentation, name); //TODO: figure out what this number means Debug.Assert(reader.ReadByte() == 1); while (reader.PeekChar() != 0) { OutputProperty(reader, indentation + " "); } Debug.Assert(reader.ReadByte() == 0); } Debug.Assert(stream.Position == stream.Length); } }
public static void Run() { string dataRoot = @"C:\Temp\SLXData\ActiveForms_bin"; SortedDictionary<string, long> plugins = new SortedDictionary<string, long>(); foreach (DirectoryInfo directory in new DirectoryInfo(dataRoot).GetDirectories()) { foreach (DirectoryInfo subDirectory in directory.GetDirectories()) { foreach (FileInfo file in subDirectory.GetFiles()) { plugins.Add(file.FullName, file.Length); } } } string[] fileNames = new string[plugins.Count]; plugins.Keys.CopyTo(fileNames, 0); long[] fileSizes = new long[plugins.Count]; plugins.Values.CopyTo(fileSizes, 0); Array.Sort(fileSizes, fileNames); IFormFlatteningService flattener = new FormFlatteningService(); foreach (string fileName in fileNames) { Console.WriteLine(fileName); byte[] data = File.ReadAllBytes(fileName); DelphiComponent component; using (DelphiBinaryReader binaryReader = new DelphiBinaryReader(data)) { component = binaryReader.ReadComponent(true); } IList<string> beforeNames = new List<string>(); GatherControlNames(component, beforeNames); flattener.Flatten(component, false); IList<string> afterNames = new List<string>(); GatherControlNames(component, afterNames); Debug.Assert(beforeNames.Count == afterNames.Count); for (int i = 0; i < beforeNames.Count; i++) { Debug.Assert(beforeNames[i] == afterNames[i]); } foreach (DelphiComponent childComponent in component.Components) { foreach (DelphiComponent grandComponent in childComponent.Components) { Debug.Assert(grandComponent != null); Debug.Assert(!grandComponent.Properties.ContainsKey("CLSID")); } } } }
public static Image ParseGlyphData(byte[] data) { Image image; using (DelphiBinaryReader binaryReader = new DelphiBinaryReader(data)) { image = ParseGlyphData(binaryReader); Debug.Assert(binaryReader.BaseStream.Position == binaryReader.BaseStream.Length); } return image; }
protected override void OnBuild() { byte[] data; if (Component.TryGetPropertyValue("Picture.Data", out data)) { Image image; using (DelphiBinaryReader binaryReader = new DelphiBinaryReader(data)) { string type = binaryReader.ReadString(); Debug.Assert(type == "TBitmap"); image = BorlandUtils.ParseGlyphData(binaryReader); Debug.Assert(binaryReader.BaseStream.Position == binaryReader.BaseStream.Length); } string name = Component.Name; if (name.StartsWith("img")) { name = name.Substring(3); } string extension; if (image is Metafile) //vector { extension = "emf"; } else if (image.GetFrameCount(FrameDimension.Time) > 1 || //animated (image.PixelFormat & PixelFormat.Indexed) == PixelFormat.Indexed) //indexed { extension = "gif"; } else if ((image.PixelFormat & PixelFormat.Alpha) == PixelFormat.Alpha) //transparency { extension = "png"; } else { extension = "jpg"; } string fullName = string.Format("{0}_{1}x{2}.{3}", name, image.Width, image.Height, extension); Context.GlobalImageResourceManager.AddUpdateResource(fullName, image); ((QFImage) QfControl).Image = string.Format("[Localization!Global_Images:{0}]", fullName); } }
public static Image ParseGlyphData(DelphiBinaryReader binaryReader) { byte[] data = binaryReader.ReadBinary(); Bitmap bmp; using (Stream stream = new MemoryStream(data)) { using (Image image = Image.FromStream(stream)) { bmp = new Bitmap(image); bmp.MakeTransparent(); } } return bmp; }
private static void OutputComponent(DelphiBinaryReader reader, string indentation) { string type = reader.ReadString(); string name = reader.ReadString(); WriteLine("{0}object {1}: {2}", indentation, name, type); while (reader.PeekChar() != 0) { OutputProperty(reader, indentation + " "); } Debug.Assert(reader.ReadByte() == 0); while (reader.PeekChar() != 0) { OutputComponent(reader, indentation + " "); } Debug.Assert(reader.ReadByte() == 0); WriteLine("{0}end", indentation); }
private static void OutputControlData(byte[] data, string indentation) { using (MemoryStream stream = new MemoryStream(data)) { DelphiBinaryReader reader = new DelphiBinaryReader(stream); string prefix = Encoding.Default.GetString(reader.ReadBytes(4)); if (prefix == "\x10\a\0\0") { //TODO: figure out CRViewer.ControlData return; } else if (prefix == "\u201C\xB2\0\0") { //TODO: figure out DirDialog.ControlData return; } else if (prefix == "!C4\x12") { //TODO: figure out CommonDialog.ControlData return; } else if (prefix == "\xFF\xFE<\0") { //TODO: figure out ChartSpace2.ControlData return; } else if (prefix == "\x17\0\x02\0") { //TODO: figure out SigPlus.ControlData return; } else if (prefix != "TPF0") { throw new DelphiException("Invalid component prefix: " + prefix); } OutputComponent(reader, indentation); Debug.Assert(stream.Position == stream.Length); } }
private static void Run(bool extractBinary, bool extractText, bool extractScript) { string dataRoot = @"C:\Temp\SLXData\ActiveForms"; SortedDictionary<string, long> plugins = new SortedDictionary<string, long>(); foreach (DirectoryInfo directory in new DirectoryInfo(dataRoot).GetDirectories()) { foreach (DirectoryInfo subDirectory in directory.GetDirectories()) { foreach (FileInfo file in subDirectory.GetFiles()) { //if (file.FullName.Contains("natobook") && !file.FullName.Contains("eventix")) //if (file.Length > 600000) { plugins.Add(file.FullName, file.Length); } } } } string[] fileNames = new string[plugins.Count]; plugins.Keys.CopyTo(fileNames, 0); long[] fileSizes = new long[plugins.Count]; plugins.Values.CopyTo(fileSizes, 0); Array.Sort(fileSizes, fileNames); foreach (string fileName in fileNames) { Console.WriteLine(fileName); string binFileName = Path.ChangeExtension(fileName.Replace(dataRoot, dataRoot + "_bin"), "bin"); string txtFileName = Path.ChangeExtension(fileName.Replace(dataRoot, dataRoot + "_txt"), "txt"); string vbsFileName = Path.ChangeExtension(fileName.Replace(dataRoot, dataRoot + "_vbs"), "vbs"); Directory.CreateDirectory(Path.GetDirectoryName(binFileName)); Directory.CreateDirectory(Path.GetDirectoryName(txtFileName)); Directory.CreateDirectory(Path.GetDirectoryName(vbsFileName)); byte[] strData = File.ReadAllBytes(fileName); byte[] binData = BorlandUtils.ObjectTextToBinary(strData); if (extractBinary) { File.WriteAllBytes(binFileName, binData); } if (extractText || extractScript) { if (extractText) { _txtWriter = new StreamWriter(txtFileName); } try { using (MemoryStream stream = new MemoryStream(binData)) { DelphiComponent component = new DelphiBinaryReader(stream).ReadComponent(true); if (extractScript) { object script; if (component.Properties.TryGetValue("Script", out script) && script != null) { File.WriteAllText(vbsFileName, script.ToString()); } } if (extractText) { OutputComponent(component, string.Empty); } Debug.Assert(stream.Position == stream.Length); } } finally { if (extractText) { _txtWriter.Dispose(); } } } } }
private static void Output_Items_Data(byte[] data, string indentation) { using (MemoryStream stream = new MemoryStream(data)) { DelphiBinaryReader reader = new DelphiBinaryReader(stream); int firstInt = reader.ReadInt32(); if (firstInt == data.Length) { int rootCount = reader.ReadInt32(); int totalChildren = 0; for (int i = 0; i < rootCount; i++) { WriteLine("{0}[{1}]", indentation, i); OutputProperty("SmallImageIndex", reader.ReadInt32(), indentation + " "); OutputProperty("StateImageIndex", reader.ReadInt32(), indentation + " "); OutputProperty("LargeImageIndex", reader.ReadInt32(), indentation + " "); int childCount = reader.ReadInt32(); OutputProperty("Indent", reader.ReadInt32(), indentation + " "); OutputProperty("Caption", reader.ReadString(), indentation + " "); totalChildren += childCount; for (int j = 0; j < childCount; j++) { WriteLine("{0}[{1}]", indentation + " ", j); OutputProperty("Caption", reader.ReadString(), indentation + " "); } } WriteLine("{0}SubItemProperties", indentation); for (int i = 0; i < totalChildren; i++) { WriteLine("{0}[{1}]", indentation + " ", i); OutputProperty("SmallImageIndex", reader.ReadInt16(), indentation + " "); } } else { for (int i = 0; i < firstInt; i++) { WriteLine("{0}[{1}]", indentation, i); OutputTreeNode(reader, 0, indentation + " "); } } Debug.Assert(stream.Position == stream.Length); } }
private static void Output_Series(byte[] data, string indentation) { using (MemoryStream stream = new MemoryStream(data)) { DelphiBinaryReader reader = new DelphiBinaryReader(stream); int count = reader.ReadInt32(); for (int i = 0; i < count; i++) { int len = reader.ReadInt32(); string type = reader.ReadString(len); WriteLine("{0}{1}", indentation, type); OutputComponent(reader.ReadComponent(true), indentation + " "); OutputProperty("SQL", reader.ReadString(reader.ReadInt32()), indentation + " "); //TODO: figure out what these numbers mean Debug.Assert(reader.ReadInt32() == 0); Debug.Assert(reader.ReadInt32() == 0); } Debug.Assert(stream.Position == stream.Length); } }
private void ParseProperty(DelphiBinaryReader reader, IDictionary<string, object> properties) { string key = reader.ReadString(); object value; switch (key) { case "PopupMenu": case "PopupMenuX": case "ImageList": case "ImagesList": case "LargeImagesList": case "SmallImagesList": case "StateImagesList": case "_ImageList": DelphiComponent component = reader.ReadComponent(false); _componentSimplifier.Simplify(component); value = component; break; default: value = reader.ReadValue(); break; } properties.Add(key, value); }
private static void OutputTreeNode(DelphiBinaryReader reader, int level, string indentation) { //TODO: figure out what this number means Debug.Assert(reader.ReadInt32() == level + 26); OutputProperty("SmallImageIndex", reader.ReadInt32(), indentation); OutputProperty("SelectedImageIndex", reader.ReadInt32(), indentation); OutputProperty("StateImageIndex", reader.ReadInt32(), indentation); OutputProperty("LargeImageIndex", reader.ReadInt32(), indentation); OutputProperty("Indent", reader.ReadInt32(), indentation); int childCount = reader.ReadInt32(); OutputProperty("Caption", reader.ReadString(), indentation); for (int i = 0; i < childCount; i++) { WriteLine("{0}[{1}]", indentation + " ", i); OutputTreeNode(reader, level + 1, indentation + " "); } }
private void Parse(Plugin plugin) { DelphiComponent component; using (MemoryStream stream = new MemoryStream(plugin.Blob.Data)) { stream.Position = 0xE; using (DelphiBinaryReader binaryReader = new DelphiBinaryReader(stream)) { component = binaryReader.ReadComponent(true); } } _componentSimplifier.Simplify(component); byte[] data; if (component.TryGetPropertyValue("Toolbars.WhenItems", out data)) { using (DelphiBinaryReader binaryReader = new DelphiBinaryReader(data)) { component = ParseItems(binaryReader, true); } foreach (DelphiComponent groupComponent in component.Components) { string group; string defaultDock; if (groupComponent.TryGetPropertyValue("DefaultDock", out defaultDock) && defaultDock == "wtdLeft") { groupComponent.TryGetPropertyValue("Caption", out group); } else { group = null; } foreach (DelphiComponent itemComponent in groupComponent.Components) { string caption; if (itemComponent.TryGetPropertyValue("Caption", out caption) && !string.IsNullOrEmpty(caption)) { string action; string argument; itemComponent.TryGetPropertyValue("Caption", out caption); itemComponent.TryGetPropertyValue("WhenClick.Action", out action); itemComponent.TryGetPropertyValue("WhenClick.Argument", out argument); Image glyph = (itemComponent.TryGetPropertyValue("Glyph.Data", out data) ? BorlandUtils.ParseGlyphData(data) : null); _context.Navigation.Add(new NavigationInfo(plugin, caption, group, action, argument, glyph)); } } } } }
private DelphiComponent ParseComponent(DelphiBinaryReader reader) { DelphiComponent component = new DelphiComponent(); component.Type = reader.ReadString(); component.Name = reader.ReadString(); while (reader.PeekChar() != 0) { ParseProperty(reader, component.Properties); } byte b = reader.ReadByte(); Debug.Assert(b == 0); while (reader.PeekChar() != 0) { component.Components.Add(ParseComponent(reader)); } b = reader.ReadByte(); Debug.Assert(b == 0); return component; }
private static void OutputLicense(byte[] data, string indentation) { using (MemoryStream stream = new MemoryStream(data)) { DelphiBinaryReader reader = new DelphiBinaryReader(stream); int size = reader.ReadInteger(); if (size > 0) { //TODO: figure out what this number means Debug.Assert(reader.ReadByte() == 6); Debug.Assert(reader.ReadByte() == size); //TODO: figure out what this data means byte[] licenseData = reader.ReadBytes(size); WriteLine("{0}{1}", indentation, Encoding.Unicode.GetString(licenseData)); } Debug.Assert(stream.Position == stream.Length); } }
protected void _changePassword_Click(object sender, EventArgs e) { DelphiComponent dc = new DelphiComponent(); Sage.SalesLogix.SystemInformation si = Sage.SalesLogix.SystemInformationRules.GetSystemInfo(); DelphiBinaryReader delphi = new DelphiBinaryReader(si.Data); dc = delphi.ReadComponent(true); string minPasswordLength = dc.Properties["MinPasswordLength"].ToString(); bool noBlankPassword = (bool)dc.Properties["NoBlankPassword"]; bool alphaNumPassword = (bool)dc.Properties["AlphaNumPassword"]; bool noNameInPassword = (bool)dc.Properties["NoNameInPassword"]; Regex objAlphaNumericPattern = new Regex("[a-zA-Z][0-9]"); string changingUser = string.Empty; // Get the user name of the person who's getting their password changed Sage.Entity.Interfaces.IUser us = User.LookupResultValue as IUser; if (us != null) { changingUser = us.UserName; } else { changingUser = slxUserService.UserName; } string newPassword = _newPassword.Text; if (Convert.ToInt32(minPasswordLength) != 0) { if (newPassword.Length < Convert.ToInt32(minPasswordLength)) { lblMessage.Text = string.Format(GetLocalResourceObject("minPasswordLength").ToString(), minPasswordLength); // "Password length must be {0} chars or greater!" return; } if (alphaNumPassword && !objAlphaNumericPattern.IsMatch(newPassword)) { lblMessage.Text = GetLocalResourceObject("alphaNumPassword").ToString();// "Passwords must be alphanumeric!"; return; } } else if (noBlankPassword && newPassword.Length == 0) { lblMessage.Text = GetLocalResourceObject("noBlankPassword").ToString();//Passwords can not be blank!"; return; } if (noNameInPassword && newPassword.ToUpper().Contains(changingUser.ToUpper())) { if (curUser.ToUpper().Contains("ADMIN") && !changingUser.ToUpper().Contains("ADMIN")) lblMessage.Text = GetLocalResourceObject("noNameInPasswordAdmin").ToString(); // "Passwords cannot contain the user name!"; else lblMessage.Text = GetLocalResourceObject("noNameInPasswordUser").ToString(); //"Passwords cannot contain your user name!"; return; } // save values if (newPassword == _confirmPassword.Text) { ChangePasswordOptions options = new ChangePasswordOptions(); options.NewPassword = newPassword; string curUser = slxUserService.GetUser().Id; if (curUser.ToString().Trim() != "ADMIN") { options.UserId = curUser; } else { options.UserId = ((IUser)this.User.LookupResultValue).Id.ToString(); } options.Save(); if (_newPassword.Text.Length == 0) { lblMessage.Text = GetLocalResourceObject("PasswordBlank").ToString(); } else { lblMessage.Text = string.Empty; } } else { lblMessage.Text = GetLocalResourceObject("PasswordNotMatch").ToString(); } }
private static void OutputGlyphData(byte[] data, string indentation) { using (MemoryStream stream = new MemoryStream(data)) { DelphiBinaryReader reader = new DelphiBinaryReader(stream); byte[] imageData = reader.ReadBinary(); using (Stream imageStream = new MemoryStream(imageData)) { Image image = Image.FromStream(imageStream); WriteLine("{0}{1}", indentation, image.Size); } Debug.Assert(stream.Position == stream.Length); } }
private static void OutputEvents(byte[] data, string indentation) { using (MemoryStream stream = new MemoryStream(data)) { DelphiBinaryReader reader = new DelphiBinaryReader(stream); int count = reader.ReadInteger(); for (int i = 0; i < count; i++) { int eventIndex = reader.ReadInteger(); Debug.Assert((eventIndex >= 1 && eventIndex <= 23) || (eventIndex >= 201 && eventIndex <= 206) || eventIndex == 0x60000017 || eventIndex == 0x60000018); string str = (string) reader.ReadValue(); WriteLine("{0}{1} ({2})", indentation, str, eventIndex); } Debug.Assert(stream.Position == stream.Length); } }
private static void OutputDataBindings(byte[] data, string indentation) { using (MemoryStream stream = new MemoryStream(data)) { DelphiBinaryReader reader = new DelphiBinaryReader(stream); int count = reader.ReadInteger(); for (int i = 0; i < count; i++) { int propertyIndex = reader.ReadInteger(); Debug.Assert( propertyIndex == -518 || propertyIndex == -517 || (propertyIndex >= 1 && propertyIndex <= 9) || propertyIndex == 11 || propertyIndex == 12 || propertyIndex == 14 || propertyIndex == 16 || propertyIndex == 17 || propertyIndex == 19 || propertyIndex == 21 || (propertyIndex >= 29 && propertyIndex <= 33) || propertyIndex == 36 || propertyIndex == 39 || propertyIndex == 43 || (propertyIndex >= 101 && propertyIndex <= 105) || propertyIndex == 222 || propertyIndex == 0x60020010 || propertyIndex == 0x60020012 || propertyIndex == 0x60020016 || propertyIndex == 0x60020018 || propertyIndex == 0x6002001A); string str = (string) reader.ReadValue(); WriteLine("{0}{1} ({2})", indentation, str, propertyIndex); } Debug.Assert(stream.Position == stream.Length); } }
private DelphiComponent ParseControlData(byte[] data) { using (DelphiBinaryReader binaryReader = new DelphiBinaryReader(data)) { string prefix = Encoding.GetEncoding("iso-8859-1").GetString(binaryReader.ReadBytes(4)); if (prefix != "TPF0") { throw new DelphiException("Invalid component prefix: " + prefix); } DelphiComponent controlData = ParseComponent(binaryReader); Debug.Assert(binaryReader.BaseStream.Position == binaryReader.BaseStream.Length); return controlData; } }
private static void OutputQueryBuilderCookie(string value, string indentation) { WriteLine(); int len = value.Length/2; byte[] data = new byte[len]; for (int i = 0; i < len; i++) { data[i] = Convert.ToByte(value.Substring(i*2, 2), 16); } using (MemoryStream stream = new MemoryStream(data)) { DelphiComponent component = new DelphiBinaryReader(stream).ReadComponent(true); OutputComponent(component, indentation); Debug.Assert(stream.Position == stream.Length); } }
private static void OutputPictureData(byte[] data, string indentation) { using (MemoryStream stream = new MemoryStream(data)) { DelphiBinaryReader reader = new DelphiBinaryReader(stream); string type = reader.ReadString(); if (type == "TBitmap") { byte[] imageData = reader.ReadBinary(); if (imageData.Length > 0) { using (Stream imageStream = new MemoryStream(imageData)) { Image image = Image.FromStream(imageStream); WriteLine("{0}{1}", indentation, image.Size); } } } else if (type == "TIcon") { byte[] imageData = reader.ReadBytes(data.Length - 6); using (Stream imageStream = new MemoryStream(imageData)) { Icon image = new Icon(imageStream); WriteLine("{0}{1}", indentation, image.Size); } } else if (type == "TMetafile") { int len = reader.ReadInt32(); byte[] imageData = reader.ReadBytes(len - 4); using (Stream imageStream = new MemoryStream(imageData)) { Image image = Image.FromStream(imageStream); WriteLine("{0}{1}", indentation, image.Size); } } else { Debug.Assert(false); } Debug.Assert(stream.Position == stream.Length); } }
private void Parse(Plugin plugin) { DelphiComponent component; using (DelphiBinaryReader binaryReader = new DelphiBinaryReader(new MemoryStream(BorlandUtils.ObjectTextToBinary(plugin.Blob.Data)))) { component = binaryReader.ReadComponent(true); } _componentSimplifier.Simplify(component); string baseTable; string detailsViewName; component.TryGetPropertyValue("BaseTable", out baseTable); component.TryGetPropertyValue("DetailsViewName", out detailsViewName); MainViewInfo mainView = new MainViewInfo(plugin, baseTable, detailsViewName); _context.MainViews.Add(mainView.FullName, mainView); //TODO: might need EntityNameSingular, EntityNamePlural, EntityFieldName string script; if (component.TryGetPropertyValue("ScriptText", out script) && !string.IsNullOrEmpty(script)) { //TODO: need to add proper script support for main views ScriptInfo scriptInfo = new ScriptInfo(plugin, script); _context.Scripts.Add(scriptInfo.PrefixedFullName, scriptInfo); } }
public string SaveAsPDF(string OutputFileName = null, string OutputFilePath = null) { if (OutputFileName == null) { OutputFileName = string.Format("{0}-{1}.pdf", this.ReportName, Environment.TickCount); } if (OutputFilePath == null || !Directory.Exists(OutputFilePath)) { OutputFilePath = Path.GetTempPath(); } var fileName = Path.Combine(OutputFilePath, SanitizeFileName(OutputFileName)); Log.Debug("File name to output report to: " + fileName); try { if (File.Exists(fileName)) { File.Delete(fileName); } } catch { } var plugin = Plugin.LoadByName(this.ReportName, this.ReportFamily, PluginType.CrystalReport); if (plugin != null) { var tempRpt = Path.GetTempFileName() + ".rpt"; using (var stream = new MemoryStream(plugin.Blob.Data)) { using (var reader = new DelphiBinaryReader(stream)) { reader.ReadComponent(true); using (var file = File.OpenWrite(tempRpt)) { stream.CopyTo(file); } } } using (var report = new SlxReport()) { report.Load(tempRpt); report.UpdateDbConnectionInfo(this.ConnectionString); if (!string.IsNullOrEmpty(report.RecordSelectionFormula)) { report.RecordSelectionFormula = string.Format("{0}({0}{1}{0}) and {0}{2}", System.Environment.NewLine, report.RecordSelectionFormula, this.RecordSelectionFormula); } else { report.RecordSelectionFormula = this.RecordSelectionFormula; } if (this.Parameters.Count > 0) { this.Parameters.ForEach(param => report.SetParameterValue(param.Key, param.Value)); } report.ExportAsPdfEx(fileName, plugin.Name, true); report.Close(); } } else { throw new ArgumentException("The report plugin for " + this.ReportPlugin + "can not be found."); } return(fileName); }
private static void OutputProperty(DelphiBinaryReader reader, string indentation) { string key = reader.ReadString(); switch (key) { case "PopupMenu": case "PopupMenuX": case "ImageList": case "ImagesList": case "LargeImagesList": case "SmallImagesList": case "StateImagesList": case "_ImageList": WriteLine("{0}{1}", indentation, key); OutputComponent(reader.ReadComponent(false), indentation + " "); break; default: object value = reader.ReadValue(); OutputProperty(key, value, indentation); break; } }
private DelphiComponent ParseItems(DelphiBinaryReader binaryReader, bool isPrefixed) { DelphiComponent component = binaryReader.ReadComponent(isPrefixed); _componentSimplifier.Simplify(component); byte b = binaryReader.ReadByte(); Debug.Assert(b == 1); while (binaryReader.PeekChar() != 0) { component.Components.Add(ParseItems(binaryReader, false)); } binaryReader.ReadByte(); return component; }
private ICollection<DelphiComponent> ParseChildControls(byte[] data) { using (DelphiBinaryReader binaryReader = new DelphiBinaryReader(new MemoryStream(data))) { int count = binaryReader.ReadInteger(); ICollection<DelphiComponent> childControls = new List<DelphiComponent>(); for (int i = 0; i < count; i++) { DelphiComponent component = new DelphiComponent(); component.Name = (string) binaryReader.ReadValue(); //TODO: figure out what this number means byte b = binaryReader.ReadByte(); Debug.Assert(b == 1); while (binaryReader.PeekChar() != 0) { ParseProperty(binaryReader, component.Properties); } b = binaryReader.ReadByte(); Debug.Assert(b == 0); childControls.Add(component); } Debug.Assert(binaryReader.BaseStream.Position == binaryReader.BaseStream.Length); return childControls; } }