Reverting client/server communication around our pipes to fix access denied err. MiniDisplay
authorStephaneLenclud
Mon, 02 Feb 2015 13:28:41 +0100
branchMiniDisplay
changeset 43738e7b78cf732
parent 436 e9aefd454d1e
child 438 f590956d3234
Reverting client/server communication around our pipes to fix access denied err.
Now simply opening files for pipes created by SoundGraphAccess server.
GUI/SoundGraphDisplay.cs
GUI/SoundGraphServer.cs
     1.1 --- a/GUI/SoundGraphDisplay.cs	Mon Feb 02 12:51:06 2015 +0100
     1.2 +++ b/GUI/SoundGraphDisplay.cs	Mon Feb 02 13:28:41 2015 +0100
     1.3 @@ -59,8 +59,8 @@
     1.4                  client.Start();*/
     1.5              }
     1.6  
     1.7 -            //Try loading SoundGraph iMON Disaply DLL
     1.8 -            iServer = new SoundGraph.Server(@"\\.\pipe\sga-receiver", @"\\.\pipe\sga-sender");
     1.9 +            //Start our SoundGraph server
    1.10 +            iServer = new SoundGraph.Server(@"\\.\pipe\sga-inbound", @"\\.\pipe\sga-outbound");
    1.11              iServer.Start();
    1.12              //iServer.SendMessage("init:");
    1.13          }
    1.14 @@ -103,6 +103,7 @@
    1.15              foreach (SensorFrontView icon in list)
    1.16                  icon.Dispose();
    1.17  
    1.18 +            Quit();
    1.19              iServer.Stop();
    1.20  
    1.21          }
    1.22 @@ -193,6 +194,11 @@
    1.23              iServer.SendMessage("set-vfd-text:" + aUpperLine);
    1.24          }
    1.25  
    1.26 +        public void Quit()
    1.27 +        {
    1.28 +            iServer.SendMessage("quit:");
    1.29 +        }
    1.30 +
    1.31          /*
    1.32          public bool IsMainIconEnabled
    1.33          {
    1.34 @@ -207,13 +213,6 @@
    1.35              }
    1.36          }*/
    1.37  
    1.38 -        /*
    1.39 -        public bool IsDllLoaded
    1.40 -        {
    1.41 -            get { return iSoundGraphDll!=IntPtr.Zero; }
    1.42 -        }
    1.43 -         */
    1.44 -
    1.45  
    1.46      }
    1.47  }
     2.1 --- a/GUI/SoundGraphServer.cs	Mon Feb 02 12:51:06 2015 +0100
     2.2 +++ b/GUI/SoundGraphServer.cs	Mon Feb 02 13:28:41 2015 +0100
     2.3 @@ -10,6 +10,167 @@
     2.4  {
     2.5      public class Server
     2.6      {
     2.7 +        [Flags]
     2.8 +        public enum EFileAccess : uint
     2.9 +        {
    2.10 +            //
    2.11 +            // Standart Section
    2.12 +            //
    2.13 +
    2.14 +            AccessSystemSecurity = 0x1000000,   // AccessSystemAcl access type
    2.15 +            MaximumAllowed = 0x2000000,     // MaximumAllowed access type
    2.16 +
    2.17 +            Delete = 0x10000,
    2.18 +            ReadControl = 0x20000,
    2.19 +            WriteDAC = 0x40000,
    2.20 +            WriteOwner = 0x80000,
    2.21 +            Synchronize = 0x100000,
    2.22 +
    2.23 +            StandardRightsRequired = 0xF0000,
    2.24 +            StandardRightsRead = ReadControl,
    2.25 +            StandardRightsWrite = ReadControl,
    2.26 +            StandardRightsExecute = ReadControl,
    2.27 +            StandardRightsAll = 0x1F0000,
    2.28 +            SpecificRightsAll = 0xFFFF,
    2.29 +
    2.30 +            FILE_READ_DATA = 0x0001,        // file & pipe
    2.31 +            FILE_LIST_DIRECTORY = 0x0001,       // directory
    2.32 +            FILE_WRITE_DATA = 0x0002,       // file & pipe
    2.33 +            FILE_ADD_FILE = 0x0002,         // directory
    2.34 +            FILE_APPEND_DATA = 0x0004,      // file
    2.35 +            FILE_ADD_SUBDIRECTORY = 0x0004,     // directory
    2.36 +            FILE_CREATE_PIPE_INSTANCE = 0x0004, // named pipe
    2.37 +            FILE_READ_EA = 0x0008,          // file & directory
    2.38 +            FILE_WRITE_EA = 0x0010,         // file & directory
    2.39 +            FILE_EXECUTE = 0x0020,          // file
    2.40 +            FILE_TRAVERSE = 0x0020,         // directory
    2.41 +            FILE_DELETE_CHILD = 0x0040,     // directory
    2.42 +            FILE_READ_ATTRIBUTES = 0x0080,      // all
    2.43 +            FILE_WRITE_ATTRIBUTES = 0x0100,     // all
    2.44 +
    2.45 +            //
    2.46 +            // Generic Section
    2.47 +            //
    2.48 +
    2.49 +            GenericRead = 0x80000000,
    2.50 +            GenericWrite = 0x40000000,
    2.51 +            GenericExecute = 0x20000000,
    2.52 +            GenericAll = 0x10000000,
    2.53 +
    2.54 +            SPECIFIC_RIGHTS_ALL = 0x00FFFF,
    2.55 +            FILE_ALL_ACCESS =
    2.56 +            StandardRightsRequired |
    2.57 +            Synchronize |
    2.58 +            0x1FF,
    2.59 +
    2.60 +            FILE_GENERIC_READ =
    2.61 +            StandardRightsRead |
    2.62 +            FILE_READ_DATA |
    2.63 +            FILE_READ_ATTRIBUTES |
    2.64 +            FILE_READ_EA |
    2.65 +            Synchronize,
    2.66 +
    2.67 +            FILE_GENERIC_WRITE =
    2.68 +            StandardRightsWrite |
    2.69 +            FILE_WRITE_DATA |
    2.70 +            FILE_WRITE_ATTRIBUTES |
    2.71 +            FILE_WRITE_EA |
    2.72 +            FILE_APPEND_DATA |
    2.73 +            Synchronize,
    2.74 +
    2.75 +            FILE_GENERIC_EXECUTE =
    2.76 +            StandardRightsExecute |
    2.77 +              FILE_READ_ATTRIBUTES |
    2.78 +              FILE_EXECUTE |
    2.79 +              Synchronize
    2.80 +        }
    2.81 +
    2.82 +        [Flags]
    2.83 +        public enum EFileShare : uint
    2.84 +        {
    2.85 +            /// <summary>
    2.86 +            /// 
    2.87 +            /// </summary>
    2.88 +            None = 0x00000000,
    2.89 +            /// <summary>
    2.90 +            /// Enables subsequent open operations on an object to request read access. 
    2.91 +            /// Otherwise, other processes cannot open the object if they request read access. 
    2.92 +            /// If this flag is not specified, but the object has been opened for read access, the function fails.
    2.93 +            /// </summary>
    2.94 +            Read = 0x00000001,
    2.95 +            /// <summary>
    2.96 +            /// Enables subsequent open operations on an object to request write access. 
    2.97 +            /// Otherwise, other processes cannot open the object if they request write access. 
    2.98 +            /// If this flag is not specified, but the object has been opened for write access, the function fails.
    2.99 +            /// </summary>
   2.100 +            Write = 0x00000002,
   2.101 +            /// <summary>
   2.102 +            /// Enables subsequent open operations on an object to request delete access. 
   2.103 +            /// Otherwise, other processes cannot open the object if they request delete access.
   2.104 +            /// If this flag is not specified, but the object has been opened for delete access, the function fails.
   2.105 +            /// </summary>
   2.106 +            Delete = 0x00000004
   2.107 +        }
   2.108 +
   2.109 +        public enum ECreationDisposition : uint
   2.110 +        {
   2.111 +            /// <summary>
   2.112 +            /// Creates a new file. The function fails if a specified file exists.
   2.113 +            /// </summary>
   2.114 +            New = 1,
   2.115 +            /// <summary>
   2.116 +            /// Creates a new file, always. 
   2.117 +            /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes, 
   2.118 +            /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
   2.119 +            /// </summary>
   2.120 +            CreateAlways = 2,
   2.121 +            /// <summary>
   2.122 +            /// Opens a file. The function fails if the file does not exist. 
   2.123 +            /// </summary>
   2.124 +            OpenExisting = 3,
   2.125 +            /// <summary>
   2.126 +            /// Opens a file, always. 
   2.127 +            /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
   2.128 +            /// </summary>
   2.129 +            OpenAlways = 4,
   2.130 +            /// <summary>
   2.131 +            /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
   2.132 +            /// The calling process must open the file with the GENERIC_WRITE access right. 
   2.133 +            /// </summary>
   2.134 +            TruncateExisting = 5
   2.135 +        }
   2.136 +
   2.137 +        [Flags]
   2.138 +        public enum EFileAttributes : uint
   2.139 +        {
   2.140 +            None = 0x00000000,
   2.141 +            Readonly = 0x00000001,
   2.142 +            Hidden = 0x00000002,
   2.143 +            System = 0x00000004,
   2.144 +            Directory = 0x00000010,
   2.145 +            Archive = 0x00000020,
   2.146 +            Device = 0x00000040,
   2.147 +            Normal = 0x00000080,
   2.148 +            Temporary = 0x00000100,
   2.149 +            SparseFile = 0x00000200,
   2.150 +            ReparsePoint = 0x00000400,
   2.151 +            Compressed = 0x00000800,
   2.152 +            Offline = 0x00001000,
   2.153 +            NotContentIndexed = 0x00002000,
   2.154 +            Encrypted = 0x00004000,
   2.155 +            Write_Through = 0x80000000,
   2.156 +            Overlapped = 0x40000000,
   2.157 +            NoBuffering = 0x20000000,
   2.158 +            RandomAccess = 0x10000000,
   2.159 +            SequentialScan = 0x08000000,
   2.160 +            DeleteOnClose = 0x04000000,
   2.161 +            BackupSemantics = 0x02000000,
   2.162 +            PosixSemantics = 0x01000000,
   2.163 +            OpenReparsePoint = 0x00200000,
   2.164 +            OpenNoRecall = 0x00100000,
   2.165 +            FirstPipeInstance = 0x00080000
   2.166 +        }
   2.167 +
   2.168          [DllImport("kernel32.dll", SetLastError = true)]
   2.169          public static extern SafeFileHandle CreateNamedPipe(
   2.170             String pipeName,
   2.171 @@ -30,6 +191,19 @@
   2.172          public static extern int DisconnectNamedPipe(
   2.173             SafeFileHandle hNamedPipe);
   2.174  
   2.175 +        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
   2.176 +        public static extern SafeFileHandle CreateFile(
   2.177 +           string lpFileName,
   2.178 +           EFileAccess dwDesiredAccess,
   2.179 +           EFileShare dwShareMode,
   2.180 +           IntPtr lpSecurityAttributes,
   2.181 +           ECreationDisposition dwCreationDisposition,
   2.182 +           EFileAttributes dwFlagsAndAttributes,
   2.183 +           IntPtr hTemplateFile);
   2.184 +
   2.185 +        //[DllImport("kernel32.dll", SetLastError = true)]
   2.186 +        //static extern bool CloseHandle(IntPtr hHandle);
   2.187 +
   2.188          public const uint PIPE_ACCESS_DUPLEX = (0x00000003);
   2.189          public const uint FILE_FLAG_OVERLAPPED = (0x40000000);
   2.190          public const uint PIPE_ACCESS_OUTBOUND = (0x00000002);
   2.191 @@ -44,7 +218,6 @@
   2.192  
   2.193          //
   2.194          public string iPipeNameOutbound;
   2.195 -        Thread iThreadOutbound;
   2.196          SafeFileHandle iPipeOutbound;
   2.197          public FileStream iStreamOutbound;
   2.198          //
   2.199 @@ -53,6 +226,8 @@
   2.200          SafeFileHandle iPipeInbound;
   2.201          public FileStream iStreamInbound;
   2.202  
   2.203 +        private bool iQuit = false;
   2.204 +
   2.205  
   2.206          public Server(string aPipeNameOutbound, string aPipeNameInbound)
   2.207          {
   2.208 @@ -65,74 +240,72 @@
   2.209           */
   2.210          public void Start()
   2.211          {
   2.212 -            //Start outbound thread to send messages
   2.213 -            this.iThreadOutbound = new Thread(new ThreadStart(ThreadOutbound));
   2.214 -            this.iThreadOutbound.Start();
   2.215              //Start inbound thread to receive messages
   2.216              this.iThreadInbound = new Thread(new ThreadStart(ThreadInbound));
   2.217              this.iThreadInbound.Start();
   2.218          }
   2.219  
   2.220          /**
   2.221 -         * Outbound thread is sending messages to our client.
   2.222 +         * Stop our services.
   2.223           */
   2.224 -        private void ThreadOutbound()
   2.225 +        public void Stop()
   2.226          {
   2.227 -            
   2.228 -            //Create our outbound named pipe
   2.229 -            iPipeOutbound = CreateNamedPipe(this.iPipeNameOutbound, PIPE_ACCESS_OUTBOUND /*| FILE_FLAG_OVERLAPPED*/, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
   2.230 +            iQuit = true;
   2.231 +        }
   2.232  
   2.233 -            //Could not create named pipe
   2.234 -            if (iPipeOutbound.IsInvalid)
   2.235 -            {
   2.236 -                //TODO: error handling
   2.237 -                return;
   2.238 -            }
   2.239 -
   2.240 -            //Will complete once our client connects
   2.241 -            int success = ConnectNamedPipe(iPipeOutbound, IntPtr.Zero);
   2.242 -
   2.243 -            //could not connect client
   2.244 -            if (success == 0)
   2.245 -            {
   2.246 -                //TODO: error handling
   2.247 -                return;
   2.248 -            }
   2.249 -
   2.250 -            //Client now connected create our stream
   2.251 -            iStreamOutbound = new FileStream(iPipeOutbound, FileAccess.Write, BUFFER_SIZE, false);
   2.252 - 
   2.253 -        }
   2.254  
   2.255          /**
   2.256           * Inbound thread is receiving messages from our client
   2.257           */
   2.258          private void ThreadInbound()
   2.259          {
   2.260 -            //Client client = (Client)clientObj;
   2.261 -            //clientse.stream = new FileStream(clientse.handle, FileAccess.ReadWrite, BUFFER_SIZE, true);
   2.262  
   2.263 -            iPipeInbound = CreateNamedPipe(this.iPipeNameInbound, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
   2.264 -
   2.265 -            //could not create named pipe
   2.266 -            if (iPipeInbound.IsInvalid)
   2.267 -                return;
   2.268 -
   2.269 -            //Will complete once a client connects
   2.270 -            int success = ConnectNamedPipe(iPipeInbound, IntPtr.Zero);
   2.271 -
   2.272 -            //could not connect client
   2.273 -            if (success == 0)
   2.274 -                return;
   2.275 +            //Keep on trying to connect on our read pipe
   2.276 +            while ((iPipeInbound == null || iPipeInbound.IsInvalid) && !iQuit)
   2.277 +            {
   2.278 +                Trace.WriteLine("Trying to connect to inbound pipe...");
   2.279 +                iPipeInbound = CreateFile(iPipeNameInbound, EFileAccess.GenericRead, EFileShare.None, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.None, IntPtr.Zero);
   2.280 +                System.Threading.Thread.Sleep(1000);
   2.281 +            }
   2.282 +            
   2.283  
   2.284              //Client now connected create our inbound stream
   2.285 -            iStreamInbound = new FileStream(iPipeInbound, FileAccess.Read, BUFFER_SIZE, false);
   2.286 +            if (iPipeInbound!=null && !iPipeInbound.IsInvalid)
   2.287 +            {
   2.288 +                iStreamInbound = new FileStream(iPipeInbound, FileAccess.Read, BUFFER_SIZE, false);
   2.289 +                if (iStreamInbound.CanRead)
   2.290 +                {
   2.291 +                    Trace.WriteLine("Inbound stream ready!");
   2.292 +                }
   2.293 +            }
   2.294  
   2.295  
   2.296 +            //Keep on trying to connect to our write pipe
   2.297 +            while ((iPipeOutbound == null || iPipeOutbound.IsInvalid) && !iQuit)
   2.298 +            {
   2.299 +                Trace.WriteLine("Trying to connect to outbound pipe...");
   2.300 +                iPipeOutbound = CreateFile(iPipeNameOutbound, EFileAccess.GenericWrite, EFileShare.None, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.None, IntPtr.Zero);
   2.301 +                System.Threading.Thread.Sleep(1000);
   2.302 +            }
   2.303 +            
   2.304 +
   2.305 +            //Client now connected create our stream
   2.306 +            if (iPipeOutbound!=null && !iPipeOutbound.IsInvalid)
   2.307 +            {
   2.308 +                iStreamOutbound = new FileStream(iPipeOutbound, FileAccess.Write, BUFFER_SIZE, false);
   2.309 +
   2.310 +                if (iStreamOutbound.CanWrite)
   2.311 +                {
   2.312 +                    Trace.WriteLine("Outbound stream ready!");
   2.313 +                }
   2.314 +            }
   2.315 +
   2.316 +
   2.317 +            //Listening loop
   2.318              byte[] buffer = null;
   2.319              ASCIIEncoding encoder = new ASCIIEncoding();
   2.320  
   2.321 -            while (true)
   2.322 +            while (!iQuit)
   2.323              {                
   2.324                  int bytesRead = 0;
   2.325  
   2.326 @@ -171,16 +344,20 @@
   2.327                      byte[] Rc = new byte[ReadLength];
   2.328                      Buffer.BlockCopy(buffer, 0, Rc, 0, ReadLength);
   2.329  
   2.330 -                    Console.WriteLine(encoder.GetString(Rc, 0, ReadLength));
   2.331 +                    Trace.WriteLine(encoder.GetString(Rc, 0, ReadLength));
   2.332                      Trace.WriteLine("Received " + ReadLength + " Bytes: " + encoder.GetString(Rc, 0, ReadLength));
   2.333                      buffer.Initialize();
   2.334                  }
   2.335                 
   2.336              }
   2.337  
   2.338 + 
   2.339              //clean up resources
   2.340 -            iStreamInbound.Close();
   2.341 -            iPipeInbound.Close();            
   2.342 +            if (iStreamInbound!=null) iStreamInbound.Close();
   2.343 +            if (iPipeInbound != null) iPipeInbound.Close();
   2.344 +            //
   2.345 +            if (iStreamOutbound != null) iStreamOutbound.Close();
   2.346 +            if (iPipeOutbound != null) iPipeOutbound.Close();
   2.347          }
   2.348  
   2.349          /**
   2.350 @@ -192,7 +369,7 @@
   2.351                  ASCIIEncoding encoder = new ASCIIEncoding();
   2.352                  byte[] messageBuffer = encoder.GetBytes(message);
   2.353  
   2.354 -                if (iStreamOutbound.CanWrite)
   2.355 +                if (iStreamOutbound != null && iStreamOutbound.CanWrite)
   2.356                  {
   2.357                      iStreamOutbound.Write(messageBuffer, 0, messageBuffer.Length);
   2.358                      iStreamOutbound.Flush();
   2.359 @@ -201,20 +378,6 @@
   2.360  
   2.361          }
   2.362  
   2.363 -        /**
   2.364 -         * 
   2.365 -         */
   2.366 -        public void Stop()
   2.367 -        {
   2.368 -            //clean up resources
   2.369 -
   2.370 -            DisconnectNamedPipe(this.iPipeOutbound);
   2.371 -
   2.372 -            //TODO: more cleanup
   2.373 -            
   2.374 -
   2.375 -            this.iThreadOutbound.Abort();
   2.376 -        }
   2.377  
   2.378      }
   2.379  }