View difference between Paste ID: wLgpkEz9 and 9NxEMYwc
SHOW: | | - or go back to the newest paste.
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
}