# HG changeset patch
# User StephaneLenclud
# Date 1422880121 -3600
# Node ID 38e7b78cf73256de9cc3c7fa2fc66134668cab19
# Parent  e9aefd454d1e1f0567ed91ee3bf9c4e804dd8f4a
Reverting client/server communication around our pipes to fix access denied err.
Now simply opening files for pipes created by SoundGraphAccess server.
diff -r e9aefd454d1e -r 38e7b78cf732 GUI/SoundGraphDisplay.cs
--- a/GUI/SoundGraphDisplay.cs	Mon Feb 02 12:51:06 2015 +0100
+++ b/GUI/SoundGraphDisplay.cs	Mon Feb 02 13:28:41 2015 +0100
@@ -59,8 +59,8 @@
                 client.Start();*/
             }
 
-            //Try loading SoundGraph iMON Disaply DLL
-            iServer = new SoundGraph.Server(@"\\.\pipe\sga-receiver", @"\\.\pipe\sga-sender");
+            //Start our SoundGraph server
+            iServer = new SoundGraph.Server(@"\\.\pipe\sga-inbound", @"\\.\pipe\sga-outbound");
             iServer.Start();
             //iServer.SendMessage("init:");
         }
@@ -103,6 +103,7 @@
             foreach (SensorFrontView icon in list)
                 icon.Dispose();
 
+            Quit();
             iServer.Stop();
 
         }
@@ -193,6 +194,11 @@
             iServer.SendMessage("set-vfd-text:" + aUpperLine);
         }
 
+        public void Quit()
+        {
+            iServer.SendMessage("quit:");
+        }
+
         /*
         public bool IsMainIconEnabled
         {
@@ -207,13 +213,6 @@
             }
         }*/
 
-        /*
-        public bool IsDllLoaded
-        {
-            get { return iSoundGraphDll!=IntPtr.Zero; }
-        }
-         */
-
 
     }
 }
diff -r e9aefd454d1e -r 38e7b78cf732 GUI/SoundGraphServer.cs
--- a/GUI/SoundGraphServer.cs	Mon Feb 02 12:51:06 2015 +0100
+++ b/GUI/SoundGraphServer.cs	Mon Feb 02 13:28:41 2015 +0100
@@ -10,6 +10,167 @@
 {
     public class Server
     {
+        [Flags]
+        public enum EFileAccess : uint
+        {
+            //
+            // Standart Section
+            //
+
+            AccessSystemSecurity = 0x1000000,   // AccessSystemAcl access type
+            MaximumAllowed = 0x2000000,     // MaximumAllowed access type
+
+            Delete = 0x10000,
+            ReadControl = 0x20000,
+            WriteDAC = 0x40000,
+            WriteOwner = 0x80000,
+            Synchronize = 0x100000,
+
+            StandardRightsRequired = 0xF0000,
+            StandardRightsRead = ReadControl,
+            StandardRightsWrite = ReadControl,
+            StandardRightsExecute = ReadControl,
+            StandardRightsAll = 0x1F0000,
+            SpecificRightsAll = 0xFFFF,
+
+            FILE_READ_DATA = 0x0001,        // file & pipe
+            FILE_LIST_DIRECTORY = 0x0001,       // directory
+            FILE_WRITE_DATA = 0x0002,       // file & pipe
+            FILE_ADD_FILE = 0x0002,         // directory
+            FILE_APPEND_DATA = 0x0004,      // file
+            FILE_ADD_SUBDIRECTORY = 0x0004,     // directory
+            FILE_CREATE_PIPE_INSTANCE = 0x0004, // named pipe
+            FILE_READ_EA = 0x0008,          // file & directory
+            FILE_WRITE_EA = 0x0010,         // file & directory
+            FILE_EXECUTE = 0x0020,          // file
+            FILE_TRAVERSE = 0x0020,         // directory
+            FILE_DELETE_CHILD = 0x0040,     // directory
+            FILE_READ_ATTRIBUTES = 0x0080,      // all
+            FILE_WRITE_ATTRIBUTES = 0x0100,     // all
+
+            //
+            // Generic Section
+            //
+
+            GenericRead = 0x80000000,
+            GenericWrite = 0x40000000,
+            GenericExecute = 0x20000000,
+            GenericAll = 0x10000000,
+
+            SPECIFIC_RIGHTS_ALL = 0x00FFFF,
+            FILE_ALL_ACCESS =
+            StandardRightsRequired |
+            Synchronize |
+            0x1FF,
+
+            FILE_GENERIC_READ =
+            StandardRightsRead |
+            FILE_READ_DATA |
+            FILE_READ_ATTRIBUTES |
+            FILE_READ_EA |
+            Synchronize,
+
+            FILE_GENERIC_WRITE =
+            StandardRightsWrite |
+            FILE_WRITE_DATA |
+            FILE_WRITE_ATTRIBUTES |
+            FILE_WRITE_EA |
+            FILE_APPEND_DATA |
+            Synchronize,
+
+            FILE_GENERIC_EXECUTE =
+            StandardRightsExecute |
+              FILE_READ_ATTRIBUTES |
+              FILE_EXECUTE |
+              Synchronize
+        }
+
+        [Flags]
+        public enum EFileShare : uint
+        {
+            /// 
+            /// 
+            /// 
+            None = 0x00000000,
+            /// 
+            /// Enables subsequent open operations on an object to request read access. 
+            /// Otherwise, other processes cannot open the object if they request read access. 
+            /// If this flag is not specified, but the object has been opened for read access, the function fails.
+            /// 
+            Read = 0x00000001,
+            /// 
+            /// Enables subsequent open operations on an object to request write access. 
+            /// Otherwise, other processes cannot open the object if they request write access. 
+            /// If this flag is not specified, but the object has been opened for write access, the function fails.
+            /// 
+            Write = 0x00000002,
+            /// 
+            /// Enables subsequent open operations on an object to request delete access. 
+            /// Otherwise, other processes cannot open the object if they request delete access.
+            /// If this flag is not specified, but the object has been opened for delete access, the function fails.
+            /// 
+            Delete = 0x00000004
+        }
+
+        public enum ECreationDisposition : uint
+        {
+            /// 
+            /// Creates a new file. The function fails if a specified file exists.
+            /// 
+            New = 1,
+            /// 
+            /// Creates a new file, always. 
+            /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes, 
+            /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
+            /// 
+            CreateAlways = 2,
+            /// 
+            /// Opens a file. The function fails if the file does not exist. 
+            /// 
+            OpenExisting = 3,
+            /// 
+            /// Opens a file, always. 
+            /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
+            /// 
+            OpenAlways = 4,
+            /// 
+            /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
+            /// The calling process must open the file with the GENERIC_WRITE access right. 
+            /// 
+            TruncateExisting = 5
+        }
+
+        [Flags]
+        public enum EFileAttributes : uint
+        {
+            None = 0x00000000,
+            Readonly = 0x00000001,
+            Hidden = 0x00000002,
+            System = 0x00000004,
+            Directory = 0x00000010,
+            Archive = 0x00000020,
+            Device = 0x00000040,
+            Normal = 0x00000080,
+            Temporary = 0x00000100,
+            SparseFile = 0x00000200,
+            ReparsePoint = 0x00000400,
+            Compressed = 0x00000800,
+            Offline = 0x00001000,
+            NotContentIndexed = 0x00002000,
+            Encrypted = 0x00004000,
+            Write_Through = 0x80000000,
+            Overlapped = 0x40000000,
+            NoBuffering = 0x20000000,
+            RandomAccess = 0x10000000,
+            SequentialScan = 0x08000000,
+            DeleteOnClose = 0x04000000,
+            BackupSemantics = 0x02000000,
+            PosixSemantics = 0x01000000,
+            OpenReparsePoint = 0x00200000,
+            OpenNoRecall = 0x00100000,
+            FirstPipeInstance = 0x00080000
+        }
+
         [DllImport("kernel32.dll", SetLastError = true)]
         public static extern SafeFileHandle CreateNamedPipe(
            String pipeName,
@@ -30,6 +191,19 @@
         public static extern int DisconnectNamedPipe(
            SafeFileHandle hNamedPipe);
 
+        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+        public static extern SafeFileHandle CreateFile(
+           string lpFileName,
+           EFileAccess dwDesiredAccess,
+           EFileShare dwShareMode,
+           IntPtr lpSecurityAttributes,
+           ECreationDisposition dwCreationDisposition,
+           EFileAttributes dwFlagsAndAttributes,
+           IntPtr hTemplateFile);
+
+        //[DllImport("kernel32.dll", SetLastError = true)]
+        //static extern bool CloseHandle(IntPtr hHandle);
+
         public const uint PIPE_ACCESS_DUPLEX = (0x00000003);
         public const uint FILE_FLAG_OVERLAPPED = (0x40000000);
         public const uint PIPE_ACCESS_OUTBOUND = (0x00000002);
@@ -44,7 +218,6 @@
 
         //
         public string iPipeNameOutbound;
-        Thread iThreadOutbound;
         SafeFileHandle iPipeOutbound;
         public FileStream iStreamOutbound;
         //
@@ -53,6 +226,8 @@
         SafeFileHandle iPipeInbound;
         public FileStream iStreamInbound;
 
+        private bool iQuit = false;
+
 
         public Server(string aPipeNameOutbound, string aPipeNameInbound)
         {
@@ -65,74 +240,72 @@
          */
         public void Start()
         {
-            //Start outbound thread to send messages
-            this.iThreadOutbound = new Thread(new ThreadStart(ThreadOutbound));
-            this.iThreadOutbound.Start();
             //Start inbound thread to receive messages
             this.iThreadInbound = new Thread(new ThreadStart(ThreadInbound));
             this.iThreadInbound.Start();
         }
 
         /**
-         * Outbound thread is sending messages to our client.
+         * Stop our services.
          */
-        private void ThreadOutbound()
+        public void Stop()
         {
-            
-            //Create our outbound named pipe
-            iPipeOutbound = CreateNamedPipe(this.iPipeNameOutbound, PIPE_ACCESS_OUTBOUND /*| FILE_FLAG_OVERLAPPED*/, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
+            iQuit = true;
+        }
 
-            //Could not create named pipe
-            if (iPipeOutbound.IsInvalid)
-            {
-                //TODO: error handling
-                return;
-            }
-
-            //Will complete once our client connects
-            int success = ConnectNamedPipe(iPipeOutbound, IntPtr.Zero);
-
-            //could not connect client
-            if (success == 0)
-            {
-                //TODO: error handling
-                return;
-            }
-
-            //Client now connected create our stream
-            iStreamOutbound = new FileStream(iPipeOutbound, FileAccess.Write, BUFFER_SIZE, false);
- 
-        }
 
         /**
          * Inbound thread is receiving messages from our client
          */
         private void ThreadInbound()
         {
-            //Client client = (Client)clientObj;
-            //clientse.stream = new FileStream(clientse.handle, FileAccess.ReadWrite, BUFFER_SIZE, true);
 
-            iPipeInbound = CreateNamedPipe(this.iPipeNameInbound, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
-
-            //could not create named pipe
-            if (iPipeInbound.IsInvalid)
-                return;
-
-            //Will complete once a client connects
-            int success = ConnectNamedPipe(iPipeInbound, IntPtr.Zero);
-
-            //could not connect client
-            if (success == 0)
-                return;
+            //Keep on trying to connect on our read pipe
+            while ((iPipeInbound == null || iPipeInbound.IsInvalid) && !iQuit)
+            {
+                Trace.WriteLine("Trying to connect to inbound pipe...");
+                iPipeInbound = CreateFile(iPipeNameInbound, EFileAccess.GenericRead, EFileShare.None, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.None, IntPtr.Zero);
+                System.Threading.Thread.Sleep(1000);
+            }
+            
 
             //Client now connected create our inbound stream
-            iStreamInbound = new FileStream(iPipeInbound, FileAccess.Read, BUFFER_SIZE, false);
+            if (iPipeInbound!=null && !iPipeInbound.IsInvalid)
+            {
+                iStreamInbound = new FileStream(iPipeInbound, FileAccess.Read, BUFFER_SIZE, false);
+                if (iStreamInbound.CanRead)
+                {
+                    Trace.WriteLine("Inbound stream ready!");
+                }
+            }
 
 
+            //Keep on trying to connect to our write pipe
+            while ((iPipeOutbound == null || iPipeOutbound.IsInvalid) && !iQuit)
+            {
+                Trace.WriteLine("Trying to connect to outbound pipe...");
+                iPipeOutbound = CreateFile(iPipeNameOutbound, EFileAccess.GenericWrite, EFileShare.None, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.None, IntPtr.Zero);
+                System.Threading.Thread.Sleep(1000);
+            }
+            
+
+            //Client now connected create our stream
+            if (iPipeOutbound!=null && !iPipeOutbound.IsInvalid)
+            {
+                iStreamOutbound = new FileStream(iPipeOutbound, FileAccess.Write, BUFFER_SIZE, false);
+
+                if (iStreamOutbound.CanWrite)
+                {
+                    Trace.WriteLine("Outbound stream ready!");
+                }
+            }
+
+
+            //Listening loop
             byte[] buffer = null;
             ASCIIEncoding encoder = new ASCIIEncoding();
 
-            while (true)
+            while (!iQuit)
             {                
                 int bytesRead = 0;
 
@@ -171,16 +344,20 @@
                     byte[] Rc = new byte[ReadLength];
                     Buffer.BlockCopy(buffer, 0, Rc, 0, ReadLength);
 
-                    Console.WriteLine(encoder.GetString(Rc, 0, ReadLength));
+                    Trace.WriteLine(encoder.GetString(Rc, 0, ReadLength));
                     Trace.WriteLine("Received " + ReadLength + " Bytes: " + encoder.GetString(Rc, 0, ReadLength));
                     buffer.Initialize();
                 }
                
             }
 
+ 
             //clean up resources
-            iStreamInbound.Close();
-            iPipeInbound.Close();            
+            if (iStreamInbound!=null) iStreamInbound.Close();
+            if (iPipeInbound != null) iPipeInbound.Close();
+            //
+            if (iStreamOutbound != null) iStreamOutbound.Close();
+            if (iPipeOutbound != null) iPipeOutbound.Close();
         }
 
         /**
@@ -192,7 +369,7 @@
                 ASCIIEncoding encoder = new ASCIIEncoding();
                 byte[] messageBuffer = encoder.GetBytes(message);
 
-                if (iStreamOutbound.CanWrite)
+                if (iStreamOutbound != null && iStreamOutbound.CanWrite)
                 {
                     iStreamOutbound.Write(messageBuffer, 0, messageBuffer.Length);
                     iStreamOutbound.Flush();
@@ -201,20 +378,6 @@
 
         }
 
-        /**
-         * 
-         */
-        public void Stop()
-        {
-            //clean up resources
-
-            DisconnectNamedPipe(this.iPipeOutbound);
-
-            //TODO: more cleanup
-            
-
-            this.iThreadOutbound.Abort();
-        }
 
     }
 }