Beispiel #1
0
        public void Disassemble(int tofile0editor1)
        {
            //First Check if there are lines loading in MC list
            if (MachineCodes.Count != 0)
            {
                DisassemblyStarted.Invoke(); //just to notify anyone who's registered with the event ...

                //Now load one line at a time
                //Then decode it and place it in assembledLine, then invoke complete~
                for (int i = 0; i < MachineCodes.Count; i++)
                {
                    //here is da decoding part
                    string x = DecodeLine(MachineCodes.ElementAt <string>(i));
                    //Here is the part to store...
                    AssembledLines.Add(x);
                    //Incrment counter
                    Current_Inst_Address += 4;
                }
                //Current_Inst_Address = 4194308;
                //ResolveLabels();
                DisassemblyComplete.Invoke(tofile0editor1); //yay!
            }
            else
            {
                GeneralError.Invoke("Disassemble::Disassembler", "We ain't got no machine codes", "Lol, u messin with me? I didn't find any machine codes to disassemble!");
            }
        }
Beispiel #2
0
        //Main Methods
        public string DecodeLine(string MachineCode)
        {
            switch (getFormat(MachineCode))
            {
            case 0:
                return(decodeR(MachineCode));

            case 1:
                return(decodeI(MachineCode));

            case 2:
                return(decodeJ(MachineCode));

            case -1:
                UnsupportedFormat.Invoke("DecodeLine::Disassembler", "MC : " + MachineCode, "Sorry, but COPROC instructions aren't currently supported.. tuff luck chump");
                return("ERR-DecodeLine::Disassembler::Coproc_Error");

            default:
                GeneralError.Invoke("DecodeLine::Disassembler", "--", "Lol, this is some wierd shit for realz!");
                return("ERR-DecodeLine::Disassembler::LOL");
            }
        }
Beispiel #3
0
        public string decodeI(string iLine)
        {
            //I format can hold rs, rt and immediate
            //In that order OPCODE(6) RS(5) RT(5) IMM(16)
            string opcode = iLine.Substring(0, 6);
            string rs     = iLine.Substring(6, 5);
            string rt     = iLine.Substring(11, 5);
            string imm    = iLine.Substring(16);
            string imm_s  = imm;

            signExtend(ref imm_s, 32); //So just in case we have a signed op.

            //rs rt and imm, then decode opcode so you know where to place em;
            //Declare the elements of the big string to retrun

            int    imm_int  = Convert.ToInt32(imm, 2);
            int    imm_sint = Convert.ToInt32(imm_s, 2);
            string rs_name  = getRegName(rs); //so if the namer didn't get them just throw the word err
            string rt_name  = getRegName(rt);
            string mnemonic;
            string mipsline;
            ulong  fulladdress = (ulong)imm_sint * 4 + Current_Inst_Address + 4;

            //Ok We got Register names, and IM now we need to decode OPCode to see where they fit in the STRING :)
            //Start decoding OPcode and return :) we're done
            switch (opcode)
            {
            case "001000":     //Addi
                mnemonic = "addi";
                mipsline = mnemonic + " $" + rt_name + ", $" + rs_name + ", " + imm_sint;
                return(mipsline);

            case "001001":     //Addiu
                mnemonic = "addiu";
                mipsline = mnemonic + " $" + rt_name + ", $" + rs_name + ", " + imm_int;
                return(mipsline);

            case "001100":     //Andi
                mnemonic = "andi";
                mipsline = mnemonic + " $" + rt_name + ", $" + rs_name + ", " + imm_int;
                return(mipsline);

            case "000100":     //beq
                mnemonic = "beq";
                int iol = (int)(Current_Inst_Address + 4 - 4194304) / 4;
                iOfLinesMentionsLabel.Add(iol - 1);
                UnresolvedBLabelsLongs.Add(Current_Inst_Address + 4);
                unresolvedBlabel.Add(Current_Inst_Address + 4, imm_sint);
                mipsline = mnemonic + " $" + rt_name + ", $" + rs_name + ", " + "%" + fulladdress;
                return(mipsline);

            case "000101":     //bne
                mnemonic = "bne";
                iol      = (int)(Current_Inst_Address + 4 - 4194304) / 4;
                iOfLinesMentionsLabel.Add(iol - 1);
                UnresolvedBLabelsLongs.Add(Current_Inst_Address + 4);
                unresolvedBlabel.Add(Current_Inst_Address + 4, imm_sint);
                mipsline = mnemonic + " $" + rt_name + ", $" + rs_name + ", " + "%" + fulladdress;
                return(mipsline);

            case "100000":     //lb
                mnemonic = "lb";
                mipsline = mnemonic + " $" + rt_name + ", " + imm_sint + "($" + rs_name + ")";
                return(mipsline);

            case "100100":     //lbu
                mnemonic = "lbu";
                mipsline = mnemonic + " $" + rt_name + ", " + imm_int + "($" + rs_name + ")";
                return(mipsline);

            case "100001":     //lh
                mnemonic = "lh";
                mipsline = mnemonic + " $" + rt_name + ", " + imm_sint + "($" + rs_name + ")";
                return(mipsline);

            case "100101":     //lhu
                mnemonic = "lhu";
                mipsline = mnemonic + " $" + rt_name + ", " + imm_int + "($" + rs_name + ")";
                return(mipsline);

            case "100011":     //lw
                mnemonic = "lw";
                mipsline = mnemonic + " $" + rt_name + ", " + imm_int + "($" + rs_name + ")";
                return(mipsline);

            case "001101":     //ori
                mnemonic = "ori";
                mipsline = mnemonic + " $" + rt_name + ", $" + rs_name + ", " + imm_int;
                return(mipsline);

            case "101000":     //sb
                mnemonic = "sb";
                mipsline = mnemonic + " $" + rt_name + ", " + imm_int + "($" + rs_name + ")";
                return(mipsline);

            case "001010":     //slti
                mnemonic = "slti";
                mipsline = mnemonic + " $" + rt_name + ", $" + rs_name + ", " + imm_sint;
                return(mipsline);

            case "001011":     //sltiu
                mnemonic = "sltiu";
                mipsline = mnemonic + " $" + rt_name + ", $" + rs_name + ", " + imm_int;
                return(mipsline);

            case "101001":     //sh
                mnemonic = "sh";
                mipsline = mnemonic + " $" + rt_name + ", " + imm + "($" + rs_name + ")";
                return(mipsline);

            case "101011":     //sw
                mnemonic = "sw";
                mipsline = mnemonic + " $" + rt_name + ", " + imm + "($" + rs_name + ")";
                return(mipsline);

            case "001110":     //xori
                mnemonic = "xori";
                mipsline = mnemonic + " $" + rt_name + ", $" + rs_name + ", " + imm_int;
                return(mipsline);

            case "001111":     //Lui
                mnemonic = "lui";
                mipsline = mnemonic + " $" + rt_name + ", " + imm_int;
                return(mipsline);

                break;

            default:
                //unsupported, throw error
                GeneralError.Invoke("iFormatDecoder::Disassembler", "OPCODE: " + opcode, "Hi there, the disassembler encountered an unsupported i-format instruction");
                return("ERR");
            }
        }
Beispiel #4
0
        public string decodeR(string rLine)
        {
            //r format holds opcode, rs, rt, rd, sa , and funct...
            //OPCODE(6) RS(5) RT(5) RD(5) SA(5) FUNCT(6)
            string rs    = rLine.Substring(6, 5);
            string rt    = rLine.Substring(11, 5);
            string rd    = rLine.Substring(16, 5);
            string sa    = rLine.Substring(21, 5);
            string funct = rLine.Substring(26);

            //Lets first decode the rs, rd, rt , sa then see what funct it is and determine
            //the print format, just like in the Iformat;
            string rs_name = getRegName(rs);
            string rt_name = getRegName(rt);
            string rd_name = getRegName(rd);
            int    sa_int  = Convert.ToInt32(sa, 2);
            string mnemonic;
            string mipsline;

            //Ok now we got all the info except for funct, decode it and return string :)
            switch (funct)
            {
            case "100000":     //add
                mnemonic = "add";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            case "100001":     //addu
                mnemonic = "addu";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            case "100100":     //and
                mnemonic = "and";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            case "001000":     //jr
                mnemonic = "jr";
                mipsline = mnemonic + " $" + rs_name;
                return(mipsline);

            case "100111":     //nor
                mnemonic = "nor";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            case "100101":     //or
                mnemonic = "or";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            case "000000":     //sll
                mnemonic = "sll";
                mipsline = mnemonic + " $" + rd_name + ", $" + rt_name + ", " + sa_int;
                return(mipsline);

            case "000100":     //sllv
                mnemonic = "sllv";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            case "101010":     //slt
                mnemonic = "slt";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            case "101011":     //sltu
                mnemonic = "sltu";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            case "000011":     //sra
                mnemonic = "sra";
                mipsline = mnemonic + " $" + rd_name + ", $" + rt_name + ", " + sa_int;
                return(mipsline);

            case "000111":     //srav
                mnemonic = "srav";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            case "000010":     //srl
                mnemonic = "srl";
                mipsline = mnemonic + " $" + rd_name + ", $" + rt_name + ", " + sa_int;
                return(mipsline);

            case "000110":     //srlv
                mnemonic = "srlv";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            case "100010":     //sub
                mnemonic = "sub";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            case "100011":     //subu
                mnemonic = "subu";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            case "001100":     //syscall
                mnemonic = "syscall";
                mipsline = mnemonic;
                return(mipsline);

            case "100110":     //xor
                mnemonic = "xor";
                mipsline = mnemonic + " $" + rd_name + ", $" + rs_name + ", $" + rt_name;
                return(mipsline);

            default:
                GeneralError.Invoke("decodeR::Disassembler", "FUNCT: " + funct, "Unsupported R instruction found, sorry for that");
                return("ERR");
            }
        }
Beispiel #5
0
        /// <summary>
        /// Purges queues for messages older then the <see cref="MessagePurgeLifespan"/>
        /// </summary>
        /// <param name="cancellationToken">The cancellation token</param>
        public void PurgeOldMessages(CancellationToken cancellationToken)
        {
            while (cancellationToken.IsCancellationRequested == false)
            {
                // Ensure the service is not paused
                if (!IsPaused)
                {
                    try
                    {
                        // Get all files inside the Queue
                        DirectoryInfo          dirInfo = new DirectoryInfo(Folders.RootFolder);
                        IEnumerable <FileInfo> files   = dirInfo.EnumerateFiles("*.EML", SearchOption.AllDirectories);

                        // Purged Files Collection
                        List <FileInfo> purgedFiles = new List <FileInfo>();

                        // Date to Purge
                        DateTime purgeDate = DateTime.Now.Subtract(MessagePurgeLifespan);

                        // Retrieve all files on the queues
                        foreach (FileInfo fi in files)
                        {
                            // Refresh the FileInfo to get the proper CreationTime
                            fi.Refresh();

                            // Check Date
                            if (fi.CreationTime.CompareTo(purgeDate) < 0)
                            {
                                // Calls the Purge Event
                                PurgeFileEventArgs purgeFileEventArgs = new PurgeFileEventArgs(fi, purgeDate);
                                bool cancelPurge = false;

                                if (MessagePurging != null)
                                {
                                    MessagePurging.Invoke(this, purgeFileEventArgs);
                                    cancelPurge = purgeFileEventArgs.Cancel;
                                }

                                // Purge or Keep File
                                if (!cancelPurge)
                                {
                                    // Delete the file
                                    File.Delete(fi.FullName);

                                    // Add it to collection (since the refresh method was called before, the information does not get lost)
                                    purgedFiles.Add(fi);
                                }
                            }
                        }

                        // Trigger event if handled
                        if (purgedFiles.Count > 0)
                        {
                            MessagesPurged?.Invoke(this, new PurgeFilesEventArgs(purgedFiles, purgeDate));
                        }
                    }
                    catch (Exception e)
                    {
                        // Call the GeneralError Event Handler
                        GeneralError?.Invoke(this, new GeneralErrorEventArgs(e, nameof(PurgeOldMessages)));
                    }

                    // Wait for 10 minutes before trying it again (cancellationToken forces it to exit too)
                    Task.Delay(new TimeSpan(0, 10, 0)).Wait(cancellationToken);
                }
                else
                {
                    // Wait for 10 seconds trying it again (cancellationToken forces it to exit too)
                    Task.Delay(10000).Wait(cancellationToken);
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Process the Smtp Queue for messages already routed
        /// </summary>
        /// <param name="connectionNumber">The number of the connection on the same queue. This information is inserted on the header of the MimeMessage</param>
        /// <param name="smtpConfiguration">The configuration information for the queue</param>
        /// <param name="cancellationToken">The cancellation token</param>
        /// <remarks>This method is expected to run into multiple tasks, hence it uses a <see cref="ConcurrentQueue{T}"/></remarks>
        private void SendRoutedMessages(int connectionNumber, SmtpConfiguration smtpConfiguration, CancellationToken cancellationToken)
        {
            // Connects to the Smtp
            SmtpClient client = new SmtpClient();

            // Control the Number of Attempts
            int attempts    = 0;
            int maxAttempts = 20;

            while (cancellationToken.IsCancellationRequested == false)
            {
                try
                {
                    // Pull a message from the queue
                    RoutableMessage routableMessage = null;
                    bool            Dequeued        = false;

                    lock (SmtpQueues[smtpConfiguration.QueueNumber])
                    {
                        Dequeued = SmtpQueues[smtpConfiguration.QueueNumber].TryDequeue(out routableMessage);
                    }

                    if ((Dequeued) && (routableMessage != null))
                    {
                        try
                        {
                            // Append details to the header
                            var receiveByString = string.Format("Queue [{0}] at Connection [{1}] of Smtp Key [{2}] with Smtp Router Service; {3}",
                                                                (smtpConfiguration.QueueNumber + 1),
                                                                connectionNumber,
                                                                smtpConfiguration.Key,
                                                                DateTime.Now.ToString("ddd, dd MMM yyy HH:mm:ss %K"));

                            routableMessage.Message.Headers.Add("X-SM-SentBy", receiveByString);

                            // Append File Name to the Header
                            routableMessage.Message.Headers.Add("X-SM-FileName", Path.GetFileName(routableMessage.FileName));

                            // Create folder to store sent files
                            string SentFolder = smtpConfiguration.Folders.SentFolderWithGroupingOptions(routableMessage.CreationDateTime);
                            if (!Directory.Exists(SentFolder))
                            {
                                Directory.CreateDirectory(SentFolder);
                            }

                            // Sends the message with the active connection
                            bool messageSent = false;

                            // Reset attempts
                            attempts = 0;

                            while ((!messageSent) && (attempts <= maxAttempts))
                            {
                                // Increment number of attempts
                                attempts++;

                                try
                                {
                                    // Ensure to create a connection
                                    if (TryConnectToSmtp(ref client, smtpConfiguration))
                                    {
                                        // Tries to send the message
                                        if (client.TrySend(routableMessage.Message, routableMessage.MailFrom, routableMessage.Recipients, out Exception eSendException))
                                        {
                                            messageSent = true;

                                            // Move file to the sent folder
                                            File.Move(routableMessage.FileName, Path.Combine(SentFolder, Path.GetFileName(routableMessage.FileName)));

                                            // Notify that a message has been sent
                                            MessageSentSuccessfully?.Invoke(this, new MessageEventArgs(routableMessage));
                                        }
                                        else
                                        {
                                            // Notify the message has not been sent
                                            MessageNotSent?.Invoke(this, new MessageErrorEventArgs(routableMessage, eSendException));

                                            // Something happened, give it a few seconds before trying again
                                            Task.Delay(2000).Wait(cancellationToken);
                                        }

                                        // Disconnect the client
                                        if (client.IsConnected)
                                        {
                                            client.Disconnect(true);
                                        }
                                    }
                                    else
                                    {
                                        // Something happened, give it a few seconds before trying again
                                        Task.Delay(2000).Wait(cancellationToken);
                                    }
                                }
                                catch
                                {
                                    // Give it some time before trying again to connect on this loop
                                    Task.Delay(2000).Wait(cancellationToken);
                                }
                            }

                            // Check if message is still not sent
                            if (!messageSent)
                            {
                                if (attempts == maxAttempts)
                                {
                                    throw new MessageNotSentException(routableMessage, new Exception($"Reached the limit of attempts to send the message ({maxAttempts} times) without any success"));
                                }
                                else
                                {
                                    throw new MessageNotSentException(routableMessage, new Exception($"Unable to send the message after {attempts} attempts"));
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            // Move message to the error queue
                            File.Move(routableMessage.FileName, Path.Combine(smtpConfiguration.Folders.ErrorFolder, Path.GetFileName(routableMessage.FileName)));

                            // Notify that a message was not Sent
                            MessageNotSent?.Invoke(this, new MessageErrorEventArgs(routableMessage, e));
                        }
                    }
                    else
                    {
                        // Wait for a few seconds before trying again
                        Task.Delay(3000).Wait(cancellationToken);
                    }
                }
                catch (Exception e)
                {
                    // Nothing else to try, notifies system about the issue
                    GeneralError?.Invoke(this, new GeneralErrorEventArgs(new Exception($"General Error on '{nameof(SendRoutedMessages)}' method", e), nameof(SendRoutedMessages)));
                }
                finally
                {
                    // Disconnects client if needed
                    if (client != null)
                    {
                        if (client.IsConnected)
                        {
                            client.Disconnect(true);
                        }
                    }
                }
            }

            // Notify that the Smtp Connection has been closed
            SmtpConnectionEnded?.Invoke(this, new SmtpConnectionEventArgs(smtpConfiguration, connectionNumber, null));
        }
Beispiel #7
0
        /// <summary>
        /// Get messages form the <see cref="MessagesToRouteQueue"/> and routes them to the proper Smtp Queue
        /// </summary>
        /// <param name="cancellationToken">The cancellation token</param>
        /// <remarks>This method is expected to be run in different tasks at the same time, hence it uses a <see cref="ConcurrentQueue{T}"/> to avoid deadlocks</remarks>
        private void RouteMessages(CancellationToken cancellationToken)
        {
            while (cancellationToken.IsCancellationRequested == false)
            {
                if (!IsPaused)
                {
                    // Pull next message from the queue
                    bool            Dequeued        = false;
                    RoutableMessage routableMessage = null;

                    // Lock the Queue to Ensure Thread-Safety
                    lock (MessagesToRouteQueue)
                    {
                        Dequeued = MessagesToRouteQueue.TryDequeue(out routableMessage);
                    }

                    if ((Dequeued) && (routableMessage != null))
                    {
                        // The Message Current Location
                        string FileCurrentLocation = routableMessage.FileName;

                        // Route the message that just came from the queue
                        try
                        {
                            // Validate Incoming IP Address (unless the Force Routing flag is set)
                            if (!routableMessage.ForceRouting)
                            {
                                if (AcceptedIPAddresses?.Count > 0)
                                {
                                    // Check if Incoming IP Address is on the list
                                    if (!AcceptedIPAddresses.Contains(routableMessage.IPAddress))
                                    {
                                        throw new UnauthorizedSenderException(routableMessage, RejectReasons.NotInAcceptedAddressesList);
                                    }
                                }

                                if (RejectedIPAddresses?.Count > 0)
                                {
                                    // Check if Incoming IP Address is on the rejection list
                                    if (RejectedIPAddresses.Contains(routableMessage.IPAddress))
                                    {
                                        throw new UnauthorizedSenderException(routableMessage, RejectReasons.ExistsInRejectedAddressesList);
                                    }
                                }
                            }

                            // Validate Rules
                            if (RoutingRules == null)
                            {
                                throw new Exception("No rules configured to process routing. The message will be sent to the Error Queue after exceeding the Maximum Number of Attempts.");
                            }

                            if (RoutingRules?.Count == 0)
                            {
                                throw new Exception("No rules configured to process routing. The message will be sent to the Error Queue after exceeding the Maximum Number of Attempts.");
                            }

                            // Validate SMTP Configurations
                            if (DestinationSmtps == null)
                            {
                                throw new Exception("There is no SMTP configuration to route the emails to. The message will be sent to the Error Queue after exceeding the Maximum Number of Attempts");
                            }

                            if (DestinationSmtps?.Count == 0)
                            {
                                throw new Exception("There is no SMTP configuration to route the emails to. The message will be sent to the Error Queue after exceeding the Maximum Number of Attempts");
                            }

                            // Ensure there is a valid Routable Message
                            if (routableMessage == null)
                            {
                                throw new Exception("The Routable Message is not valid");
                            }

                            // Ensure there is a valid MimeMessage
                            if (routableMessage.Message == null)
                            {
                                throw new Exception("The MimeMessage is nov valid");
                            }

                            // The rule selected for use
                            RoutingRule selectedRule = null;

                            // Fetch Rules sorted by the Execution Sequence
                            foreach (RoutingRule rule in (from r in RoutingRules orderby r.ExecutionSequence select r))
                            {
                                // Try the rule
                                if (rule.Match(routableMessage))
                                {
                                    selectedRule = rule;

                                    // No need to continue loop
                                    break;
                                }
                            }

                            // Ensure a rule was found
                            if (selectedRule == null)
                            {
                                throw new Exception($"Unable to find a {nameof(RoutingRule)} for the given message");
                            }

                            // Verify SMTP Connection
                            if (string.IsNullOrWhiteSpace(selectedRule.SmtpConfigurationKey))
                            {
                                throw new Exception($"The {nameof(selectedRule.SmtpConfigurationKey)} is empty");
                            }

                            if (!DestinationSmtps.ContainsKey(selectedRule.SmtpConfigurationKey))
                            {
                                throw new Exception($"There is no Smtp configured for the key '{selectedRule.SmtpConfigurationKey}'");
                            }

                            SmtpConfiguration smtpConfiguration = DestinationSmtps[selectedRule.SmtpConfigurationKey];

                            if (smtpConfiguration == null)
                            {
                                throw new ArgumentNullException($"The Smtp by the key '{selectedRule.SmtpConfigurationKey}' is misconfigured");
                            }

                            // All checks passed, Send it to the proper queue

                            // Move files and enqueue
                            File.Move(routableMessage.FileName, Path.Combine(smtpConfiguration.Folders.InQueueFolder, Path.GetFileName(routableMessage.FileName)));
                            FileCurrentLocation      = Path.Combine(smtpConfiguration.Folders.InQueueFolder, Path.GetFileName(routableMessage.FileName));
                            routableMessage.FileName = FileCurrentLocation;
                            SmtpQueues[smtpConfiguration.QueueNumber].Enqueue(routableMessage);

                            // Notify the message was routed
                            MessageRoutedSuccessfully?.Invoke(this, new MessageEventArgs(routableMessage));
                        }
                        catch (UnauthorizedSenderException e)
                        {
                            // Move the message to the Rejected folder
                            try
                            {
                                File.Move(FileCurrentLocation, Path.Combine(Folders.RejectedFolder, Path.GetFileName(FileCurrentLocation)));
                            }
                            catch (Exception e2)
                            {
                                // That is a very unlikely situation
                                GeneralError?.Invoke(this, new GeneralErrorEventArgs(new Exception("Unable to move file to Rejected Folder", e2), nameof(RouteMessages)));
                            }

                            // Notify the message was not routed
                            MessageNotRouted?.Invoke(this, new MessageErrorEventArgs(routableMessage, e));
                        }
                        catch (Exception e)
                        {
                            // Move the message to the retry or error folder
                            try
                            {
                                File.Move(FileCurrentLocation, Path.Combine(Folders.ErrorFolder, Path.GetFileName(FileCurrentLocation)));
                            }
                            catch (Exception e2)
                            {
                                // That is a very unlikely situation
                                GeneralError?.Invoke(this, new GeneralErrorEventArgs(new Exception("Unable to move file to Error Folder", e2), nameof(RouteMessages)));
                            }

                            // Notify the message was not routed
                            MessageNotRouted?.Invoke(this, new MessageErrorEventArgs(routableMessage, new MessageNotRoutedException(routableMessage, e)));
                        }
                    }
                    else
                    {
                        // Wait two seconds before trying again
                        Task.Delay(2000).Wait(cancellationToken);
                    }
                }
                else
                {
                    // Nothing to do other than wait a few seconds before trying again
                    Task.Delay(5000).Wait(cancellationToken);
                }
            }
        }