示例#1
0
        public Transform(XElement node) : base(node)
        {
            Replace = node.Element(XmlTag.Replace).Value;

            Subs = new Dictionary <string, ITransformSubstitution>();
            var subs = node.Element(XmlTag.Subs);

            foreach (var s in subs.Elements(XmlTag.Sub))
            {
                var tag  = s.Element(XmlTag.Tag).As <string>();                  // The capture tag that has an associated substitution
                var guid = s.Element(XmlTag.Id).As <Guid>();                     // The unique id of the text transform
                var name = s.Element(XmlTag.Name).As <string>();                 // The friendly name of the transform
                try
                {
                    // Create a new instance of the appropriate transform and populate it with instance specific data
                    var sub = Substitutors.FirstOrDefault(x => string.Compare(x.Guid.ToString(), guid.ToString(), StringComparison.OrdinalIgnoreCase) == 0);
                    if (sub == null)
                    {
                        throw new Exception($"Text transform '{name}' (unique id: {guid}) was not found\r\nThis text transform will not behaviour correctly");
                    }
                    sub = (ITransformSubstitution)Activator.CreateInstance(sub.GetType());
                    sub.FromXml(s.Element(XmlTag.SubData));
                    Subs.Add(tag, sub);
                }
                catch (Exception ex)
                {
                    Log.Write(ELogLevel.Warn, ex, $"Text transform '{name}' ({guid}) failed to load");
                    Misc.ShowMessage(null, $"Text transform '{name}' ({guid}) failed to load\r\n{ex.Message}", Application.ProductName, MessageBoxIcon.Information);
                    Subs.Add(tag, new SubNoChange());
                }
            }

            PropertyChanged += HandlePatternChanged;
            UpdateSubs();
        }
示例#2
0
        /// <summary>Searches the file from 'start' looking for a match to 'pat'</summary>
        /// <returns>Returns true if a match is found, false otherwise. If true
        /// is returned 'found' contains the file byte offset of the first match</returns>
        private bool Find(Pattern pat, long start, bool backward, out long found)
        {
            long         at  = -1;
            DialogResult res = DialogResult.Cancel;

            try
            {
                var body = backward
                                        ? (start == FileByteRange.End
                                                ? "Searching backward from the end of the file..."
                                                : "Searching backward from the current selection position...")
                                        : (start == FileByteRange.Beg
                                                ? "Searching forward from the start of the file..."
                                                : "Searching forward from the current selection position...");

                // Although this search runs in a background thread, it's wrapped in a modal
                // dialog box, so it should be ok to use class members directly
                var search = new ProgressForm("Searching...", body, null, ProgressBarStyle.Marquee, (s, a, cb) =>
                {
                    var d             = new BLIData(this, Src, fileend_: m_fileend);
                    int last_progress = 0;
                    d.progress        = (scanned, length) =>
                    {
                        int progress = (int)(100 * Math_.Frac(0, scanned, length != 0?length:1));
                        if (progress != last_progress)
                        {
                            cb(new ProgressForm.UserState {
                                FractionComplete = progress * 0.01f
                            });
                            last_progress = progress;
                        }
                        return(!s.CancelPending);
                    };

                    // Searching....
                    DoFind(pat, start, backward, d, rng =>
                    {
                        at = rng.Beg;
                        return(false);
                    });

                    // We can call BuildLineIndex in this thread context because we know
                    // we're in a modal dialog.
                    if (at != -1 && !s.CancelPending)
                    {
                        this.BeginInvoke(() => SelectRowByAddr(at));
                    }
                })
                {
                    StartPosition = FormStartPosition.CenterParent
                };

                using (search)
                    res = search.ShowDialog(this, 500);
            }
            catch (OperationCanceledException) {}
            catch (Exception ex) { Misc.ShowMessage(this, "Find terminated by an error.", "Find error", MessageBoxIcon.Error, ex); }
            found = at;
            return(res == DialogResult.OK);
        }
示例#3
0
        /// <summary>Export the current code lookup list to a file</summary>
        private void ExportCodeLookupList()
        {
            // Prompt for the file to save
            var dg = new SaveFileDialog {
                Title = "Export code lookup list", Filter = Constants.XmlOrCsvFileFilter
            };

            if (dg.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }

            try
            {
                string extn = Path.GetExtension(dg.FileName);
                extn = extn != null?extn.Trim(new[] { '.' }) : "";

                // If a csv file is being saved, write out csv
                if (string.CompareOrdinal(extn, "csv") == 0)
                {
                    // Create a CSV object
                    var csv = new CSVData {
                        AutoSize = true
                    };
                    csv.Reserve(Values.Count, 2);
                    foreach (var c in Values)
                    {
                        CSVData.Row row = new CSVData.Row();
                        row.Add(c.Key);
                        row.Add(c.Value);
                        csv.Add(row);
                    }
                    csv.Save(dg.FileName);
                }
                // Otherwise write out xml
                else
                {
                    XDocument doc = new XDocument(new XElement(XmlTag.Root));
                    if (doc.Root == null)
                    {
                        throw new Exception("Failed to create root xml node");
                    }
                    var codes = new XElement(XmlTag.CodeValues);
                    foreach (var v in Values)
                    {
                        codes.Add(new XElement(XmlTag.CodeValue,
                                               new XElement(XmlTag.Code, v.Key),
                                               new XElement(XmlTag.Value, v.Value)
                                               ));
                    }
                    doc.Root.Add(codes);
                    doc.Save(dg.FileName, SaveOptions.None);
                }
            }
            catch (Exception ex)
            {
                Misc.ShowMessage(this, "Export failed.", "Export Failed", MessageBoxIcon.Error, ex);
            }
        }
示例#4
0
        /// <summary>Launch the custom data source</summary>
        private void LogCustomDataSource(ICustomLogDataSource src, LogDataSourceRunData launch)
        {
            BufferedCustomDataSource buffered_src = null;

            try
            {
                // Close any currently open file
                // Strictly, we don't have to close because OpenLogFile closes before opening
                // however if the user reopens the same process the existing process will hold
                // a lock to the capture file preventing the new process being created.
                Src = null;

                // Set options so that data always shows
                PrepareForStreamedData(launch.OutputFilepath);

                // Launch the process with standard output/error redirected to the temporary file
                buffered_src = new BufferedCustomDataSource(src, launch);

                // Give some UI feedback when the data source ends
                buffered_src.ConnectionDropped += (s, a) =>
                {
                    this.BeginInvoke(() => SetStaticStatusMessage(string.Format("{0} stopped", src.ShortName), Color.Black, Color.LightSalmon));
                };

                // Attach the optional selection changed handler
                if (launch.HandleSelectionChanged != null)
                {
                    SelectionChanged += (s, a) => launch.HandleSelectionChanged(a.Rows);
                }

                // Open the capture file created by buffered_src
                OpenSingleLogFile(buffered_src.Filepath, !buffered_src.TmpFile);
                buffered_src.Start();
                SetStaticStatusMessage("Connected", Color.Black, Color.LightGreen);

                // Pass over the ref
                if (m_buffered_custom_source != null)
                {
                    m_buffered_custom_source.Dispose();
                }
                m_buffered_custom_source = buffered_src;
                buffered_src             = null;
            }
            catch (Exception ex)
            {
                Log.Write(ELogLevel.Error, ex, $"Custom data source failed: {src.ShortName} -> {launch.OutputFilepath}");
                Misc.ShowMessage(this, $"Failed to launch {src.ShortName}.", "Data Source Failed", MessageBoxIcon.Error, ex);
            }
            finally
            {
                if (buffered_src != null)
                {
                    buffered_src.Dispose();
                }
            }
        }
示例#5
0
        /// <summary>Searches the entire file and bookmarks all locations that match the find pattern</summary>
        private void FindBookmarkAll()
        {
            if (!PreFind())
            {
                return;
            }

            try
            {
                Log.Write(ELogLevel.Info, "FindBookmarkAll");

                var          pat  = FindUI.Pattern;
                const string body = "Bookmarking all found instances...";

                // Although this search runs in a background thread, it's wrapped in a modal
                // dialog box, so it should be ok to use class members directly
                var search = new ProgressForm("Searching...", body, null, ProgressBarStyle.Marquee, (s, a, cb) =>
                {
                    var d = new BLIData(this, Src, fileend_: m_fileend);

                    int last_progress = 0;
                    d.progress        = (scanned, length) =>
                    {
                        int progress = (int)(100 * Math_.Frac(0, scanned, length != 0?length:1));
                        if (progress != last_progress)
                        {
                            cb(new ProgressForm.UserState {
                                FractionComplete = progress * 0.01f
                            });
                            last_progress = progress;
                        }
                        return(!s.CancelPending);
                    };

                    // Searching....
                    DoFind(pat, 0, false, d, rng =>
                    {
                        this.BeginInvoke(() => SetBookmark(rng, Bit.EState.Set));
                        return(true);
                    });
                })
                {
                    StartPosition = FormStartPosition.CenterParent
                };

                using (search)
                    search.ShowDialog(this, 500);
            }
            catch (OperationCanceledException) {}
            catch (Exception ex)
            {
                Misc.ShowMessage(this, "Find terminated by an error.", "Find error", MessageBoxIcon.Error, ex);
            }
        }
        /// <summary>Open a TCP network connection and log anything read</summary>
        private void LogTcpNetConnection(NetConn conn)
        {
            BufferedTcpNetConn buffered_tcp_netconn = null;

            try
            {
                // Close any currently open file
                // Strictly, we don't have to close because OpenLogFile closes before opening
                // however if the user reopens the same connection the existing connection will
                // hold a lock on the capture file preventing the new connection being created.
                Src = null;

                // Set options so that data always shows
                PrepareForStreamedData(conn.OutputFilepath);

                // Launch the process with standard output/error redirected to the temporary file
                buffered_tcp_netconn = new BufferedTcpNetConn(conn);

                // Give some UI feedback if the connection drops
                buffered_tcp_netconn.ConnectionDropped += (s, a) =>
                {
                    this.BeginInvoke(() => SetStaticStatusMessage("Connection dropped", Color.Black, Color.LightSalmon));
                };

                // Open the capture file created by buffered_process
                OpenSingleLogFile(buffered_tcp_netconn.Filepath, !buffered_tcp_netconn.TmpFile);
                buffered_tcp_netconn.Start(this);
                SetStaticStatusMessage("Connected", Color.Black, Color.LightGreen);

                // Pass over the ref
                if (m_buffered_tcp_netconn != null)
                {
                    m_buffered_tcp_netconn.Dispose();
                }
                m_buffered_tcp_netconn = buffered_tcp_netconn;
                buffered_tcp_netconn   = null;
            }
            catch (OperationCanceledException) {}
            catch (Exception ex)
            {
                Log.Write(ELogLevel.Error, ex, $"Failed to connect {conn.Hostname}:{conn.Port} -> {conn.OutputFilepath}");
                Misc.ShowMessage(this, $"Failed to connect to {conn.Hostname}:{conn.Port}.", Application.ProductName, MessageBoxIcon.Error, ex);
            }
            finally
            {
                if (buffered_tcp_netconn != null)
                {
                    buffered_tcp_netconn.Dispose();
                }
            }
        }
示例#7
0
        /// <summary>Launch a process, piping its output into a temporary file</summary>
        private void LaunchProcess(LaunchApp conn)
        {
            Debug.Assert(conn != null);
            BufferedProcess buffered_process = null;

            try
            {
                // Close any currently open file
                // Strictly, we don't have to close because OpenLogFile closes before opening
                // however if the user reopens the same process the existing process will hold
                // a lock to the capture file preventing the new process being created.
                Src = null;

                // Set options so that data always shows
                PrepareForStreamedData(conn.OutputFilepath);

                // Launch the process with standard output/error redirected to the temporary file
                buffered_process = new BufferedProcess(conn);

                // Give some UI feedback when the process ends
                buffered_process.ConnectionDropped += (s, a) =>
                {
                    this.BeginInvoke(() => SetStaticStatusMessage(string.Format("{0} exited", Path.GetFileName(conn.Executable)), Color.Black, Color.LightSalmon));
                };

                // Open the capture file created by buffered_process
                OpenSingleLogFile(buffered_process.Filepath, !buffered_process.TmpFile);
                buffered_process.Start();
                SetStaticStatusMessage("Connected", Color.Black, Color.LightGreen);

                // Pass over the ref
                if (m_buffered_process != null)
                {
                    m_buffered_process.Dispose();
                }
                m_buffered_process = buffered_process;
                buffered_process   = null;
            }
            catch (Exception ex)
            {
                Log.Write(ELogLevel.Error, ex, $"Failed to launch child process {conn.Executable} {conn.Arguments} -> {conn.OutputFilepath}");
                Misc.ShowMessage(this, $"Failed to launch child process {conn.Executable}.", Application.ProductName, MessageBoxIcon.Error, ex);
            }
            finally
            {
                if (buffered_process != null)
                {
                    buffered_process.Dispose();
                }
            }
        }
示例#8
0
 /// <summary>Called when scanning ends with an error. Shows an error dialog and turns off file watching</summary>
 private void BuildLineIndexTerminatedWithError(Exception err)
 {
     // Disable watched files, so we don't get an endless blizzard of error messages
     if (Settings.WatchEnabled)
     {
         EnableWatch(false);
         Misc.ShowHint(m_btn_watch, "File watching disabled due to error.");
     }
     Log.Write(ELogLevel.Error, err, $"Failed to build index list for {Src.Name}");
     if (err is NoLinesException)
     {
         Misc.ShowMessage(this, err.Message, "Scanning file terminated", MessageBoxIcon.Information);
     }
     else
     {
         Misc.ShowMessage(this, "Scanning the log file ended with an error.", "Scanning file terminated", MessageBoxIcon.Error, err);
     }
 }
示例#9
0
        /// <summary>
        /// Export the file 'filepath' using current filters to the stream 'outp'.
        /// Note: this method throws if an exception occurs in the background thread.</summary>
        /// <param name="d">A copy of the data needed to do the export</param>
        /// <param name="ranges">Byte ranges within 'filepath' to be exported</param>
        /// <param name="row_delimiter">The delimiter that defines rows (robitised)</param>
        /// <param name="col_delimiter">The delimiter that defines columns (robitised)</param>
        /// <param name="outp">The stream to write the exported file to</param>
        private bool DoExportWithProgress(BLIData d, IEnumerable <RangeI> ranges, string row_delimiter, string col_delimiter, StreamWriter outp)
        {
            DialogResult res = DialogResult.Cancel;

            try
            {
                // Although this search runs in a background thread, it's wrapped in a modal
                // dialog box, so it should be ok to use class members directly
                var export = new ProgressForm("Exporting...", null, null, ProgressBarStyle.Continuous, (s, a, cb) =>
                {
                    // Report progress and test for cancel
                    int last_progress = -1;
                    d.progress        = (scanned, length) =>
                    {
                        int progress = (int)(100 * Math_.Frac(0, scanned, length != 0?length:1));
                        if (progress != last_progress)
                        {
                            cb(new ProgressForm.UserState {
                                FractionComplete = progress * 0.01f
                            });
                            last_progress = progress;
                        }
                        return(!s.CancelPending);
                    };

                    // Do the export
                    DoExport(d, ranges, row_delimiter, col_delimiter, outp);
                })
                {
                    StartPosition = FormStartPosition.CenterParent
                };

                using (export)
                    res = export.ShowDialog(this);
            }
            catch (OperationCanceledException) { }
            catch (Exception ex) { Misc.ShowMessage(this, "Exporting terminated due to an error.", "Export error", MessageBoxIcon.Error, ex); }
            return(res == DialogResult.OK);
        }
示例#10
0
        /// <summary>Import the code lookup list from a file</summary>
        private void ImportCodeLookupList()
        {
            // If there's an existing list, ask before clearing it
            if (Values.Count != 0)
            {
                var res = MsgBox.Show(this, "Replace the current list with code/value pairs loaded from file?", "Confirm Replace Codes", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (res != DialogResult.OK)
                {
                    return;
                }
            }

            // Prompt for the file to load
            var dg = new OpenFileDialog {
                Title = "Import code lookup list", Filter = Constants.XmlOrCsvFileFilter
            };

            if (dg.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }

            try
            {
                string extn = Path.GetExtension(dg.FileName);
                extn = extn != null?extn.Trim(new[] { '.' }) : "";

                // Load into a temp list
                var  values         = new List <Pair>();
                bool partial_import = false;

                // Load from CSV
                if (string.Compare(extn, "csv", true) == 0)
                {
                    var csv = CSVData.Load(dg.FileName, ignore_comment_rows: false);
                    foreach (var row in csv.Rows)
                    {
                        partial_import |= row.Count != 0 && row.Count != 2;
                        if (row.Count < 2)
                        {
                            continue;
                        }
                        values.Add(new Pair(row[0], row[1]));
                    }
                }
                // Load from xml
                else
                {
                    XDocument doc = XDocument.Load(dg.FileName);
                    if (doc.Root == null)
                    {
                        throw new Exception("XML file invalid, no root node found");
                    }
                    var codes = doc.Root.Element(XmlTag.CodeValues);
                    if (codes == null)
                    {
                        throw new Exception("XML file invalid, no 'codevalues' element found");
                    }
                    foreach (var code in codes.Elements(XmlTag.CodeValue))
                    {
                        var cnode = code.Element(XmlTag.Code);
                        var vnode = code.Element(XmlTag.Value);
                        if (cnode != null && vnode != null)
                        {
                            values.Add(new Pair(cnode.Value, vnode.Value));
                        }
                        else
                        {
                            partial_import = true;
                        }
                    }
                }

                // If errors where found during the import, ask the user if they still want to continue
                if (partial_import)
                {
                    var res = MsgBox.Show(this, "Some imported data was ignored because it was invalid.\r\nContinue with import?", "Partial Import", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                    if (res != DialogResult.OK)
                    {
                        return;
                    }
                }

                // If successful, replace the existing list
                Values.Clear();
                Values.AddRange(values);
                m_src.ResetBindings(false);
            }
            catch (Exception ex)
            {
                Misc.ShowMessage(this, "Import failed.", "Import Failed", MessageBoxIcon.Error, ex);
            }
        }
示例#11
0
        /// <summary>Search for the full path of adb.exe</summary>
        private void AutoDetectAdbPath()
        {
            // If the full path is saved in the settings, use that (if it's valid)
            if (Path_.FileExists(m_settings.AdbFullPath))
            {
                SetAdbPath(m_settings.AdbFullPath);
                return;
            }

            // Quick check the most likely spot
            var likely_path = Path.Combine(Environment.GetEnvironmentVariable("ANDROID_HOME") ?? string.Empty, @"platform-tools\adb.exe");

            if (Path_.FileExists(likely_path))
            {
                SetAdbPath(likely_path);
                return;
            }

            // Not found? longer search...
            const string msg =
                "Searching for the Android Debugging Bridge application...\r\n" +
                "\r\n" +
                "Trying Path: {0}...\r\n" +
                "\r\n" +
                "Click cancel to locate it manually.";

            var adb_path     = string.Empty;
            var search_paths = new[]
            {
                Environment.GetEnvironmentVariable("ANDROID_HOME"),
                Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + @"\Android\android-sdk\platform-tools",
                Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @"\Android\android-sdk\platform-tools",
                @"D:\Program Files (x86)\Android\android-sdk\platform-tools",
                @"D:\Program Files\Android\android-sdk\platform-tools",
                @"E:\Program Files (x86)\Android\android-sdk\platform-tools",
                @"E:\Program Files\Android\android-sdk\platform-tools",
                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
                Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
                Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
                @"C:\"
            };

            var res = DialogResult.Cancel;

            try
            {
                // Search for 'adb.exe'
                var find_adb = new ProgressForm("Locating 'adb.exe'...", string.Format(msg, string.Empty), Icon, ProgressBarStyle.Marquee, (s, a, cb) =>
                {
                    foreach (var path in search_paths)
                    {
                        if (s.CancelPending || adb_path.HasValue())
                        {
                            break;
                        }

                        if (path == null || !Directory.Exists(path))
                        {
                            continue;
                        }

                        cb(new ProgressForm.UserState {
                            Description = string.Format(msg, path), ForceLayout = false
                        });
                        Func <string, bool> progress = dir =>
                        {
                            cb(ProgressForm.UserState.Empty);
                            return(!s.CancelPending);
                        };

                        foreach (var fi in Path_.EnumFileSystem(path, SearchOption.AllDirectories, regex_filter:@"adb\.exe", progress:progress))
                        {
                            // Found one!
                            adb_path = fi.FullName;
                            return;
                        }
                    }
                })
                {
                    StartPosition = FormStartPosition.CenterParent,
                    ClientSize    = new Size(640, 280),
                };
                using (find_adb)
                    res = find_adb.ShowDialog(this);
            }
            catch (OperationCanceledException) {}
            catch (Exception ex) { Misc.ShowMessage(this, "An error occurred while searching for 'adb.exe'", "Locating 'adb.exe' failed", MessageBoxIcon.Error, ex); }
            if (res != DialogResult.OK)
            {
                return;
            }

            SetAdbPath(adb_path);
        }