GUI/SoundGraphServer.cs
author StephaneLenclud
Thu, 18 Apr 2013 23:25:10 +0200
branchMiniDisplay
changeset 444 9b09e2ee0968
parent 439 06369ace500d
permissions -rw-r--r--
Front View plug-in does not init if no sensor added.
Fixing some format to make strings shorter.
Now trying to start SoundGraphAccess.exe process from same directory.
Packed mode now can display three sensors along with the current time.
     1 using System;
     2 using Microsoft.Win32.SafeHandles;
     3 using System.Text;
     4 using System.Runtime.InteropServices;
     5 using System.Threading;
     6 using System.IO;
     7 using System.Diagnostics;
     8 
     9 namespace SoundGraph
    10 {
    11     public class Server
    12     {
    13         [Flags]
    14         public enum EFileAccess : uint
    15         {
    16             //
    17             // Standart Section
    18             //
    19 
    20             AccessSystemSecurity = 0x1000000,   // AccessSystemAcl access type
    21             MaximumAllowed = 0x2000000,     // MaximumAllowed access type
    22 
    23             Delete = 0x10000,
    24             ReadControl = 0x20000,
    25             WriteDAC = 0x40000,
    26             WriteOwner = 0x80000,
    27             Synchronize = 0x100000,
    28 
    29             StandardRightsRequired = 0xF0000,
    30             StandardRightsRead = ReadControl,
    31             StandardRightsWrite = ReadControl,
    32             StandardRightsExecute = ReadControl,
    33             StandardRightsAll = 0x1F0000,
    34             SpecificRightsAll = 0xFFFF,
    35 
    36             FILE_READ_DATA = 0x0001,        // file & pipe
    37             FILE_LIST_DIRECTORY = 0x0001,       // directory
    38             FILE_WRITE_DATA = 0x0002,       // file & pipe
    39             FILE_ADD_FILE = 0x0002,         // directory
    40             FILE_APPEND_DATA = 0x0004,      // file
    41             FILE_ADD_SUBDIRECTORY = 0x0004,     // directory
    42             FILE_CREATE_PIPE_INSTANCE = 0x0004, // named pipe
    43             FILE_READ_EA = 0x0008,          // file & directory
    44             FILE_WRITE_EA = 0x0010,         // file & directory
    45             FILE_EXECUTE = 0x0020,          // file
    46             FILE_TRAVERSE = 0x0020,         // directory
    47             FILE_DELETE_CHILD = 0x0040,     // directory
    48             FILE_READ_ATTRIBUTES = 0x0080,      // all
    49             FILE_WRITE_ATTRIBUTES = 0x0100,     // all
    50 
    51             //
    52             // Generic Section
    53             //
    54 
    55             GenericRead = 0x80000000,
    56             GenericWrite = 0x40000000,
    57             GenericExecute = 0x20000000,
    58             GenericAll = 0x10000000,
    59 
    60             SPECIFIC_RIGHTS_ALL = 0x00FFFF,
    61             FILE_ALL_ACCESS =
    62             StandardRightsRequired |
    63             Synchronize |
    64             0x1FF,
    65 
    66             FILE_GENERIC_READ =
    67             StandardRightsRead |
    68             FILE_READ_DATA |
    69             FILE_READ_ATTRIBUTES |
    70             FILE_READ_EA |
    71             Synchronize,
    72 
    73             FILE_GENERIC_WRITE =
    74             StandardRightsWrite |
    75             FILE_WRITE_DATA |
    76             FILE_WRITE_ATTRIBUTES |
    77             FILE_WRITE_EA |
    78             FILE_APPEND_DATA |
    79             Synchronize,
    80 
    81             FILE_GENERIC_EXECUTE =
    82             StandardRightsExecute |
    83               FILE_READ_ATTRIBUTES |
    84               FILE_EXECUTE |
    85               Synchronize
    86         }
    87 
    88         [Flags]
    89         public enum EFileShare : uint
    90         {
    91             /// <summary>
    92             /// 
    93             /// </summary>
    94             None = 0x00000000,
    95             /// <summary>
    96             /// Enables subsequent open operations on an object to request read access. 
    97             /// Otherwise, other processes cannot open the object if they request read access. 
    98             /// If this flag is not specified, but the object has been opened for read access, the function fails.
    99             /// </summary>
   100             Read = 0x00000001,
   101             /// <summary>
   102             /// Enables subsequent open operations on an object to request write access. 
   103             /// Otherwise, other processes cannot open the object if they request write access. 
   104             /// If this flag is not specified, but the object has been opened for write access, the function fails.
   105             /// </summary>
   106             Write = 0x00000002,
   107             /// <summary>
   108             /// Enables subsequent open operations on an object to request delete access. 
   109             /// Otherwise, other processes cannot open the object if they request delete access.
   110             /// If this flag is not specified, but the object has been opened for delete access, the function fails.
   111             /// </summary>
   112             Delete = 0x00000004
   113         }
   114 
   115         public enum ECreationDisposition : uint
   116         {
   117             /// <summary>
   118             /// Creates a new file. The function fails if a specified file exists.
   119             /// </summary>
   120             New = 1,
   121             /// <summary>
   122             /// Creates a new file, always. 
   123             /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes, 
   124             /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
   125             /// </summary>
   126             CreateAlways = 2,
   127             /// <summary>
   128             /// Opens a file. The function fails if the file does not exist. 
   129             /// </summary>
   130             OpenExisting = 3,
   131             /// <summary>
   132             /// Opens a file, always. 
   133             /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
   134             /// </summary>
   135             OpenAlways = 4,
   136             /// <summary>
   137             /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
   138             /// The calling process must open the file with the GENERIC_WRITE access right. 
   139             /// </summary>
   140             TruncateExisting = 5
   141         }
   142 
   143         [Flags]
   144         public enum EFileAttributes : uint
   145         {
   146             None = 0x00000000,
   147             Readonly = 0x00000001,
   148             Hidden = 0x00000002,
   149             System = 0x00000004,
   150             Directory = 0x00000010,
   151             Archive = 0x00000020,
   152             Device = 0x00000040,
   153             Normal = 0x00000080,
   154             Temporary = 0x00000100,
   155             SparseFile = 0x00000200,
   156             ReparsePoint = 0x00000400,
   157             Compressed = 0x00000800,
   158             Offline = 0x00001000,
   159             NotContentIndexed = 0x00002000,
   160             Encrypted = 0x00004000,
   161             Write_Through = 0x80000000,
   162             Overlapped = 0x40000000,
   163             NoBuffering = 0x20000000,
   164             RandomAccess = 0x10000000,
   165             SequentialScan = 0x08000000,
   166             DeleteOnClose = 0x04000000,
   167             BackupSemantics = 0x02000000,
   168             PosixSemantics = 0x01000000,
   169             OpenReparsePoint = 0x00200000,
   170             OpenNoRecall = 0x00100000,
   171             FirstPipeInstance = 0x00080000
   172         }
   173 
   174         [DllImport("kernel32.dll", SetLastError = true)]
   175         public static extern SafeFileHandle CreateNamedPipe(
   176            String pipeName,
   177            uint dwOpenMode,
   178            uint dwPipeMode,
   179            uint nMaxInstances,
   180            uint nOutBufferSize,
   181            uint nInBufferSize,
   182            uint nDefaultTimeOut,
   183            IntPtr lpSecurityAttributes);
   184 
   185         [DllImport("kernel32.dll", SetLastError = true)]
   186         public static extern int ConnectNamedPipe(
   187            SafeFileHandle hNamedPipe,
   188            IntPtr lpOverlapped);
   189 
   190         [DllImport("kernel32.dll", SetLastError = true)]
   191         public static extern int DisconnectNamedPipe(
   192            SafeFileHandle hNamedPipe);
   193 
   194         [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
   195         public static extern SafeFileHandle CreateFile(
   196            string lpFileName,
   197            EFileAccess dwDesiredAccess,
   198            EFileShare dwShareMode,
   199            IntPtr lpSecurityAttributes,
   200            ECreationDisposition dwCreationDisposition,
   201            EFileAttributes dwFlagsAndAttributes,
   202            IntPtr hTemplateFile);
   203 
   204         //[DllImport("kernel32.dll", SetLastError = true)]
   205         //static extern bool CloseHandle(IntPtr hHandle);
   206 
   207         public const uint PIPE_ACCESS_DUPLEX = (0x00000003);
   208         public const uint FILE_FLAG_OVERLAPPED = (0x40000000);
   209         public const uint PIPE_ACCESS_OUTBOUND = (0x00000002);
   210         public const uint PIPE_ACCESS_INBOUND = (0x00000001);
   211         public const uint PIPE_TYPE_BYTE = (0x00000000);
   212         public const uint PIPE_UNLIMITED_INSTANCES = 255;
   213           
   214         
   215 
   216 
   217         public const int BUFFER_SIZE = 256;
   218 
   219         //
   220         public string iPipeNameOutbound;
   221         SafeFileHandle iPipeOutbound;
   222         public FileStream iStreamOutbound;
   223         //
   224         public string iPipeNameInbound;
   225         Thread iThreadInbound;
   226         SafeFileHandle iPipeInbound;
   227         public FileStream iStreamInbound;
   228 
   229         private bool iQuit = false;
   230 
   231 
   232         public Server(string aPipeNameOutbound, string aPipeNameInbound)
   233         {
   234             iPipeNameOutbound = aPipeNameOutbound;
   235             iPipeNameInbound = aPipeNameInbound;
   236         }
   237        
   238         /**
   239          * Start our services.
   240          */
   241         public void Start()
   242         {
   243             //Start inbound thread to receive messages
   244             this.iThreadInbound = new Thread(new ThreadStart(ThreadInbound));
   245             this.iThreadInbound.Start();
   246         }
   247 
   248         /**
   249          * Stop our services.
   250          */
   251         public void Stop()
   252         {
   253             iQuit = true;
   254         }
   255 
   256 
   257         /**
   258          * Inbound thread is receiving messages from our client
   259          */
   260         private void ThreadInbound()
   261         {
   262 
   263             //Keep on trying to connect on our read pipe
   264             while ((iPipeInbound == null || iPipeInbound.IsInvalid) && !iQuit)
   265             {
   266                 Trace.WriteLine("Trying to connect to inbound pipe...");
   267                 iPipeInbound = CreateFile(iPipeNameInbound, EFileAccess.GenericRead, EFileShare.None, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.None, IntPtr.Zero);
   268                 System.Threading.Thread.Sleep(1000);
   269             }
   270             
   271 
   272             //Client now connected create our inbound stream
   273             if (iPipeInbound!=null && !iPipeInbound.IsInvalid)
   274             {
   275                 iStreamInbound = new FileStream(iPipeInbound, FileAccess.Read, BUFFER_SIZE, false);
   276                 if (iStreamInbound.CanRead)
   277                 {
   278                     Trace.WriteLine("Inbound stream ready!");
   279                 }
   280             }
   281 
   282 
   283             //Keep on trying to connect to our write pipe
   284             while ((iPipeOutbound == null || iPipeOutbound.IsInvalid) && !iQuit)
   285             {
   286                 Trace.WriteLine("Trying to connect to outbound pipe...");
   287                 iPipeOutbound = CreateFile(iPipeNameOutbound, EFileAccess.GenericWrite, EFileShare.None, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.None, IntPtr.Zero);
   288                 System.Threading.Thread.Sleep(1000);
   289             }
   290             
   291 
   292             //Client now connected create our stream
   293             if (iPipeOutbound!=null && !iPipeOutbound.IsInvalid)
   294             {
   295                 iStreamOutbound = new FileStream(iPipeOutbound, FileAccess.Write, BUFFER_SIZE, false);
   296 
   297                 if (iStreamOutbound.CanWrite)
   298                 {
   299                     Trace.WriteLine("Outbound stream ready!");
   300                 }
   301             }
   302 
   303 
   304             //Listening loop
   305             byte[] buffer = null;
   306             ASCIIEncoding encoder = new ASCIIEncoding();
   307 
   308             while (!iQuit)
   309             {                
   310                 int bytesRead = 0;
   311 
   312                 try
   313                 {
   314                     buffer = new byte[BUFFER_SIZE];
   315                     bytesRead = iStreamInbound.Read(buffer, 0, BUFFER_SIZE);
   316                 }
   317                 catch
   318                 {
   319                     //read error has occurred
   320                     break;
   321                 }
   322 
   323                 //client has disconnected
   324                 if (bytesRead == 0)
   325                     break;
   326 
   327                 //fire message received event
   328                 //if (this.MessageReceived != null)
   329                 //    this.MessageReceived(clientse, encoder.GetString(buffer, 0, bytesRead));
   330 
   331                 int ReadLength = 0;
   332                 for (int i = 0; i < BUFFER_SIZE; i++)
   333                 {
   334                     //if (buffer[i].ToString("x2") != "cc")
   335                     if (buffer[i] != 0)
   336                     {
   337                         ReadLength++;
   338                     }
   339                     else
   340                         break;
   341                 }
   342                 if (ReadLength > 0)
   343                 {
   344                     byte[] Rc = new byte[ReadLength];
   345                     Buffer.BlockCopy(buffer, 0, Rc, 0, ReadLength);
   346                     string msg = encoder.GetString(Rc, 0, ReadLength);
   347                     Trace.WriteLine(msg);
   348                     Trace.WriteLine("Received " + ReadLength + " Bytes: " + msg);
   349                     buffer.Initialize();
   350                 }
   351                
   352             }
   353 
   354  
   355             //clean up resources
   356             if (iStreamInbound!=null) iStreamInbound.Close();
   357             if (iPipeInbound != null) iPipeInbound.Close();
   358             //
   359             if (iStreamOutbound != null) iStreamOutbound.Close();
   360             if (iPipeOutbound != null) iPipeOutbound.Close();
   361         }
   362 
   363         /**
   364          * Send a message to our client.
   365          */
   366         public void SendMessage(string message)
   367         {
   368             byte[] m8 = new byte[message.Length];
   369             int i = 0;
   370             foreach (char c in message)
   371             {
   372                 m8[i]=System.Convert.ToByte(c);
   373                 i++;
   374             }
   375 
   376             //ASCIIEncoding encoder = new ASCIIEncoding();
   377             //byte[] messageBuffer = encoder.GetBytes(message);
   378 
   379             if (iStreamOutbound != null && iStreamOutbound.CanWrite)
   380             {
   381                 //iStreamOutbound.Write(messageBuffer, 0, messageBuffer.Length);
   382                 iStreamOutbound.Write(m8, 0, message.Length);
   383                 iStreamOutbound.Flush();
   384             }
   385 
   386 
   387         }
   388 
   389 
   390     }
   391 }