Advertisement
GlobalAccessSoftware

SmesaMmfIpc.cs (Memory Mapped Data Sharing and secondary instances invoked.

Jul 4th, 2022
1,073
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  3. // SmesaMmfIpc.cs from SmesaNewTab.cs
  4. // v2.6.1.34 Features Memory Mapped file
  5. // form of Inter-Process-Communications.
  6. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  7. // v2.6.0.32 15-Feb-2018 -JpE-
  8. // v2.6.1.32 20-Feb-2018 0151 Threading.
  9. // v3.0.0.36 28-Feb-2018 0420 MyApp WPF.
  10. // v3.0.1.37 01-Mar-2018 Reverted Hybrid
  11. // v3.1.1.39 08-Mar-2018 Awesome and
  12. // Inspiring! Args passed while running!
  13. // v3.1.3.41 19-Mar-2018 2331 Final Adj!
  14. // v3.1.3.43 20-Mar-2018 PrefClick Code.
  15. // v3.3.5.48 21-Apr-18 Integrated w/PB+
  16. // v4.3.5.49 22-Apr-2018 Integrated.
  17. // v4.4.5.53 14-May Bring to Front mods.
  18. // v4.7.0.71 19-Sep About Colors.
  19. // v4.7.0.72 21-Sep-2018 RC
  20. // v4.8.1.79 11-Oct Peruse & Polish.
  21. // v4.8.2.80 15-Oct B2F Mechanism
  22. // v4.8.2.81 23-Oct Mapper2 interfaced
  23. // v4.8.3.85 09-Nov-2018 Favorites Mods.
  24. // v4.9.4.90 27-Nov-2018 ReadRemovals() and
  25. // GetSelectedIndex() integration completed.
  26. // NOTE: See calls to GetSelectedIndex();
  27. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  28.  
  29. using System;
  30. using System.IO;
  31. using System.Linq;
  32. using System.Text;
  33. using System.Diagnostics;
  34. using System.Windows.Forms;
  35. using System.Collections.Generic;
  36. using System.Security.Permissions;
  37. using System.IO.MemoryMappedFiles;
  38. using System.Collections.ObjectModel;
  39. using System.Runtime.InteropServices;
  40.  
  41. // Custom NameSpace & Class Library (.dll)
  42. using MyCustomLibrary;
  43.  
  44. // Aliases
  45. using MCD = MyCustomLibrary.Dialogs;
  46. using SMS = MyEditor.Properties.Settings;
  47. using SMR = MyEditor.Properties.Resources;
  48. using SNM = MyCustomLibrary.SafeNativeMethods;
  49.  
  50. namespace MyEditor
  51. {
  52.   public partial class Smesa
  53.   {
  54. #region Server side IPC MsgN Mods v4.8.2.81.G03
  55.  
  56.     /// <summary> if (byte 8190 was flipped
  57.     /// to 1) then bring Editor to front.
  58.     /// I correctly assumed that
  59.     /// 0 is same as null in byte files.
  60.     /// SO, I will call B2F if 1 and rewrite
  61.     /// a zero. If 0 is found return back!
  62.     /// If something else found, from 2-255,
  63.     /// then that's future growth.
  64.     /// v4.8.2.81.G02 : 2018-Oct-23
  65.     /// Purposely Designed to leave many uses
  66.     /// for other msgs to Smesa from abroad
  67.     /// as reuses of the same Watcher
  68.     /// Event/Delegate & !Handler.
  69.     /// </summary>
  70.     /// <param name="length"></param>
  71.     private int CheckForMsgN(long length)
  72.     {
  73.       Mx2.WaitOne();
  74.       var file = Mapped;
  75.       var args = new object[]
  76.       { file, SMS.Default.EditorSize,
  77.         SMS.Default.EditorOffset1 -2,
  78.         // See Note Above about  ^ this.
  79.         length, true, Path
  80.           .GetFileNameWithoutExtension(
  81.             file), false };
  82.       var bites = MemoryMapper
  83.         .ReverseReadBytes(args);
  84.       if (bites.Count == 0)
  85.       { Mx2.ReleaseMutex();
  86.         return 4; }
  87.       if (bites.Count == 1)
  88.       { if ( bites[0] == 0)
  89.         { Mx2.ReleaseMutex();
  90.           return 3; }
  91.         if ( bites[0] == 1)
  92.         { if (TabControl.InvokeRequired)
  93.             Invoke(new Invoker3(B2F));
  94.           else B2F();
  95.           //  ^ Bring M.E. to Front. Then
  96.           // Reset v bites to 0. (aka NULL)
  97.           args[3] = new Collection<byte> {0};
  98.           if (!MemoryMapper
  99.             .ReverseWriteBytes(args))
  100.           { MessageBox.Show(SMR.MsgN);
  101.             Mx2.ReleaseMutex();
  102.             return 2; } }
  103.         if (bites[0] > 1) PbSignal(bites[0]);
  104.       } else BatchRead(bites);
  105.       Mx2.ReleaseMutex(); // NOTE:
  106.       return 1;
  107.     }
  108.  
  109.     // todo future <byte> msgs to Smesa from abroad.
  110.     #region Future Mods
  111.  
  112.     /* Don't forget that you're going to want
  113.      * to Zero out any other bites used, or NOT.
  114.      * Some may become resident as things evolve.
  115.      * v4.8.2.81 23-Oct-2018
  116.      */
  117.  
  118.     private static void PbSignal(byte p)
  119.     {
  120.       if (p == 2) DoThis();
  121.       if (p == 3) DoThat();
  122.       // etc, etc.
  123.     }
  124.  
  125.     private static void DoThat()
  126.     {
  127.       const string x = "Doing that!";
  128.       MessageBox.Show(x);
  129.  
  130.       // expansion ready
  131.     }
  132.  
  133.     private static void DoThis()
  134.     {
  135.       const string x = "Doing this!";
  136.       MessageBox.Show(x);
  137.  
  138.       // expansion ready
  139.     }
  140.  
  141.     private static void
  142.       BatchRead(IList<byte> result)
  143.     {
  144.       const string x = "Batch Read!";
  145.       MessageBox.Show(
  146.         string.Format(
  147.           x + "\n\ndefault = {0}\n\n" +
  148.           "Count is {1}", result[0],
  149.           result.Count));
  150.       // extreme expansion ready
  151.     }
  152.     #endregion Future Mods using MsgN & IPC
  153.  
  154. #endregion IPC MsgN Mods v4.8.2.81.G03
  155.     //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  156.  
  157.  
  158. #region Server-Side MMF-IPC Handling
  159.  
  160.     // Inter-Process-Communications (IPC) with
  161.     // Memory Mapped File (MMF) & File Watcher.
  162.     // Smesa is Owner & 1st Instance Server-Side
  163.     // Code MmfClientSideWrite is Client for 2nd
  164.     // Instances of MyEditor. (Now in MCT2)
  165.  
  166.  
  167.     /// <summary>
  168.     /// Only ran, once at launch, and
  169.     /// whenever a msg comes in from abroad.
  170.     /// This creates _mmf, Delegate, Eventhandler
  171.     /// & a Reader for it. 2nd instances just
  172.     /// never see this Server-Side code period.
  173.     /// </summary>
  174.     /// <param name="read"></param>
  175.     [ComVisible(false)]
  176.     private void MmfServerSide(bool read = false)
  177.     {
  178.       if (Watcher != null)
  179.         Watcher.EnableRaisingEvents = false;
  180.       var temp = MmfManage(read);
  181.       // NOTE: Clean Exit if not a Mail Run.
  182.       if (temp.Count < 1) // v MsgN Hook v48281
  183.       {
  184.         if (read && CheckForMsgN(1) > 2)
  185.           CheckForRemovals(); // <===<< v49386
  186.       }
  187.       else ServerSideMsgReceived(temp);
  188.       // Mail Received ^ acting on it!
  189.       if (Watcher != null) Watcher
  190.         .EnableRaisingEvents = true;
  191.     }
  192.  
  193.     // FOR RELEASE TESTING & DEBUGGING PRINTBLASTER
  194.     private static void SetPaths(string mapped)
  195.     {
  196.       var pb  = BlasterPath =
  197.         WriteShared.AppRoot + SMR.PrintApp;
  198.       var dir = string.IsNullOrEmpty(pb)
  199.         || !File.Exists(pb)
  200.           ? Path.GetDirectoryName(mapped)
  201.           : Path.GetDirectoryName(BlasterPath);
  202.       EditorPath = dir + SMR.EdApp;
  203.       var docs = MyToolbox.GetDocFolder;
  204.       var file = docs + SMR.PathMe;
  205.       File.WriteAllText(file, EditorPath);
  206.       File.SetLastAccessTime(
  207.         file, DateTime.Now);
  208.       var path = docs + SMR.PathEd;
  209.       var maps = dir + "\\" +
  210.         Path.GetFileName(mapped);
  211.       File.WriteAllText(path, maps);
  212.       File.SetLastAccessTime(
  213.         path, DateTime.Now);
  214.       // v4.8.2.80
  215.       dir = Path.GetDirectoryName(mapped);
  216.       var me = dir + SMR.ME;
  217.       File.WriteAllText(me, dir);
  218.     }
  219.  
  220.     private static void LogOut()
  221.     {
  222.       var dir = Path.GetDirectoryName(Mapped);
  223.       var log = dir + SMR.ME;
  224.       if (File.Exists(log)) File.Delete(log);
  225.     }
  226.  
  227.     /// <summary> Args passed in from 2nd Instance!
  228.     /// Acts on Msg Passed from 2nd Instance client.
  229.     /// Awesome and inspiring mods! (Rev3.4)
  230.     /// </summary>
  231.     /// <param name="temp"></param>
  232.     private void ServerSideMsgReceived(
  233.       ICollection<string> temp)
  234.     {
  235.       if (TabControl.InvokeRequired)
  236.       { // If Called From Worker Thread
  237.         Invoke(new Invoker1(TabPrompt));
  238.         temp.Add(Convert.ToString(_tab));
  239.         _myContext.Post(MultiSelect, temp);
  240.         Invoke(new Invoker3(B2F)); }
  241.       else // also handles UI thread (test) calls.
  242.       { temp.Add(Convert.ToString(
  243.         TabPrompt(TabControl.SelectedIndex)));
  244.         MultiSelect(temp);
  245.         B2F(); } }
  246.  
  247.     /// <summary> This has 2b seperate for
  248.     /// Invokers (as above) re-written for
  249.     /// SafeNativeCode Class: Must be static.
  250.     /// v4.4.5.53 15-May-2018
  251.     /// </summary>
  252.     private static void B2F()
  253.     {
  254.       SNM.B2F(Process
  255.         .GetCurrentProcess()
  256.           .MainWindowHandle);
  257.     }
  258.  
  259.     private static Collection<string>
  260.       MmfManage(bool read)
  261.     {
  262.       var size = SMS.Default.EditorSize;
  263.       var temp = new Collection<string>();
  264.       using (var t =
  265.         MemoryMappedFile.CreateFromFile(
  266.           Mapped, FileMode.OpenOrCreate,
  267.           Path.GetFileNameWithoutExtension(
  268.           Mapped), size))
  269.       { if (read)
  270.         { // 1st instance Gets Msg from
  271.           // 2nd instance OR other Apps.
  272.           #region Read Mail
  273.  
  274.           var view   = SMS.Default.EditorView1;
  275.           var offset = SMS.Default.EditorOffset1;
  276.           using (var reader = t.CreateViewAccessor(
  277.             offset, view, MemoryMappedFileAccess.ReadWrite))
  278.           {
  279.             // Assessor itself is now Offset.
  280.             var position = 0;
  281.             while (position <= view)
  282.             {
  283.               var strl = reader.ReadUInt16(position);
  284.               //  ^^^^ = This next byte-array's length.
  285.               if (strl < 1) break; // No More Are Used.
  286.               var buff = new byte[strl];
  287.               reader.ReadArray(
  288.                 position += 2, buff, 0, strl);
  289.               position += strl;
  290.               var str = Encoding.UTF32.GetString(buff);
  291.               if (string.IsNullOrEmpty(str)) break;
  292.               temp.Add(str);
  293.             } // Remember how many bytes were used...
  294.             var used = position; // <-= Speed Enhancement!
  295.             // Mail Read, Now Shred only the bytes used.
  296.             position = 0;
  297.             // REM: ^ Accessor itself is now offset.
  298.             while (position <= used // was <
  299.               // stops at end ^^^^ of current msg...
  300.               && position <= view) //<-= or file.
  301.             {
  302.               // then zeros v out used bytes for next write.
  303.               reader.Write(position, (ushort) 0);
  304.               position += 2;
  305.             }
  306.           }
  307.           #endregion Reader
  308.         }
  309.       }
  310.       return temp;
  311.     }
  312.  
  313.     /* Only seen by the 1st Instance of our App. */
  314.     private void WaitForProcess2()
  315.     {
  316.       if (InvokeRequired)
  317.         Invoke(new Invoker1(WaitCursor));
  318.       else // Display v Spinning Blue Donut!
  319.         Cursor = Cursors.WaitCursor;
  320.       List<Process> pros;
  321.       var p = Process.GetCurrentProcess();
  322.       do { p.WaitForExit(250);
  323.         pros = Process.GetProcessesByName(
  324.           Process.GetCurrentProcess()
  325.             .ProcessName).ToList();
  326.       } while (pros.Count > 1);
  327.       if (InvokeRequired)
  328.         Invoke(new Invoker1(ArrowCursor));
  329.       else Cursor = Cursors.Arrow;
  330.     }
  331.  
  332.     private void ArrowCursor()
  333.     {
  334.       Cursor = Cursors.Arrow;
  335.     }
  336.  
  337.     private void WaitCursor()
  338.     {
  339.       Cursor = Cursors.WaitCursor;
  340.     }
  341. #endregion Server-Side MMF-IPC
  342.     //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  343.  
  344.  
  345. #region Server-Side MMF Watcher, Event & Handler
  346.  
  347.     /* Only seen by the 1st Instance of our App. */
  348.  
  349.     private void MmfChangedEventHandler(
  350.       object sender, EventArgs e)
  351.     {
  352.       if (!SMS.Default.MultiTab) return;
  353.       // It's a Mail Run, brb!
  354.       WaitForProcess2();
  355.       // Okay, Mail Read and Shred, Bye!
  356.       MmfServerSide(true);
  357.     }
  358.  
  359.     // Only seen by the 1st Instance of our App.
  360.     [PermissionSet(SecurityAction.Demand,
  361.       Name  = "FullTrust")]
  362.     private void MmfEventDelegate()
  363.     {
  364.       var m = Mapped;
  365.       Watcher.NotifyFilter =
  366.         NotifyFilters.LastWrite;
  367.       Watcher.InternalBufferSize  = 2048;
  368.         //SMS.Default.EditorSize
  369.       Watcher.EnableRaisingEvents = false;
  370.       // Setup File System Watcher:
  371.       Watcher.Path   = // for Mapped File.
  372.         Path.GetDirectoryName(m);
  373.       Watcher.Filter = Path.GetFileName(m);
  374.       if (File.Exists(m)) File.Delete(m);
  375.       // Setup Server-Side of memory-mapped-file:
  376.       MmfServerSide();
  377.       // Create Eventhandler...
  378.       Watcher.Changed += MmfChangedEventHandler;
  379.       Watcher.EnableRaisingEvents = true;
  380.     }
  381. #endregion SS MMF Watcher, Event & Handler
  382.     //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  383.  
  384.  
  385.   }
  386. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement