GUI/SoundGraphServer.cs
branchMiniDisplay
changeset 437 38e7b78cf732
parent 436 e9aefd454d1e
child 439 06369ace500d
     1.1 --- a/GUI/SoundGraphServer.cs	Mon Feb 02 12:51:06 2015 +0100
     1.2 +++ b/GUI/SoundGraphServer.cs	Mon Feb 02 13:28:41 2015 +0100
     1.3 @@ -10,6 +10,167 @@
     1.4  {
     1.5      public class Server
     1.6      {
     1.7 +        [Flags]
     1.8 +        public enum EFileAccess : uint
     1.9 +        {
    1.10 +            //
    1.11 +            // Standart Section
    1.12 +            //
    1.13 +
    1.14 +            AccessSystemSecurity = 0x1000000,   // AccessSystemAcl access type
    1.15 +            MaximumAllowed = 0x2000000,     // MaximumAllowed access type
    1.16 +
    1.17 +            Delete = 0x10000,
    1.18 +            ReadControl = 0x20000,
    1.19 +            WriteDAC = 0x40000,
    1.20 +            WriteOwner = 0x80000,
    1.21 +            Synchronize = 0x100000,
    1.22 +
    1.23 +            StandardRightsRequired = 0xF0000,
    1.24 +            StandardRightsRead = ReadControl,
    1.25 +            StandardRightsWrite = ReadControl,
    1.26 +            StandardRightsExecute = ReadControl,
    1.27 +            StandardRightsAll = 0x1F0000,
    1.28 +            SpecificRightsAll = 0xFFFF,
    1.29 +
    1.30 +            FILE_READ_DATA = 0x0001,        // file & pipe
    1.31 +            FILE_LIST_DIRECTORY = 0x0001,       // directory
    1.32 +            FILE_WRITE_DATA = 0x0002,       // file & pipe
    1.33 +            FILE_ADD_FILE = 0x0002,         // directory
    1.34 +            FILE_APPEND_DATA = 0x0004,      // file
    1.35 +            FILE_ADD_SUBDIRECTORY = 0x0004,     // directory
    1.36 +            FILE_CREATE_PIPE_INSTANCE = 0x0004, // named pipe
    1.37 +            FILE_READ_EA = 0x0008,          // file & directory
    1.38 +            FILE_WRITE_EA = 0x0010,         // file & directory
    1.39 +            FILE_EXECUTE = 0x0020,          // file
    1.40 +            FILE_TRAVERSE = 0x0020,         // directory
    1.41 +            FILE_DELETE_CHILD = 0x0040,     // directory
    1.42 +            FILE_READ_ATTRIBUTES = 0x0080,      // all
    1.43 +            FILE_WRITE_ATTRIBUTES = 0x0100,     // all
    1.44 +
    1.45 +            //
    1.46 +            // Generic Section
    1.47 +            //
    1.48 +
    1.49 +            GenericRead = 0x80000000,
    1.50 +            GenericWrite = 0x40000000,
    1.51 +            GenericExecute = 0x20000000,
    1.52 +            GenericAll = 0x10000000,
    1.53 +
    1.54 +            SPECIFIC_RIGHTS_ALL = 0x00FFFF,
    1.55 +            FILE_ALL_ACCESS =
    1.56 +            StandardRightsRequired |
    1.57 +            Synchronize |
    1.58 +            0x1FF,
    1.59 +
    1.60 +            FILE_GENERIC_READ =
    1.61 +            StandardRightsRead |
    1.62 +            FILE_READ_DATA |
    1.63 +            FILE_READ_ATTRIBUTES |
    1.64 +            FILE_READ_EA |
    1.65 +            Synchronize,
    1.66 +
    1.67 +            FILE_GENERIC_WRITE =
    1.68 +            StandardRightsWrite |
    1.69 +            FILE_WRITE_DATA |
    1.70 +            FILE_WRITE_ATTRIBUTES |
    1.71 +            FILE_WRITE_EA |
    1.72 +            FILE_APPEND_DATA |
    1.73 +            Synchronize,
    1.74 +
    1.75 +            FILE_GENERIC_EXECUTE =
    1.76 +            StandardRightsExecute |
    1.77 +              FILE_READ_ATTRIBUTES |
    1.78 +              FILE_EXECUTE |
    1.79 +              Synchronize
    1.80 +        }
    1.81 +
    1.82 +        [Flags]
    1.83 +        public enum EFileShare : uint
    1.84 +        {
    1.85 +            /// <summary>
    1.86 +            /// 
    1.87 +            /// </summary>
    1.88 +            None = 0x00000000,
    1.89 +            /// <summary>
    1.90 +            /// Enables subsequent open operations on an object to request read access. 
    1.91 +            /// Otherwise, other processes cannot open the object if they request read access. 
    1.92 +            /// If this flag is not specified, but the object has been opened for read access, the function fails.
    1.93 +            /// </summary>
    1.94 +            Read = 0x00000001,
    1.95 +            /// <summary>
    1.96 +            /// Enables subsequent open operations on an object to request write access. 
    1.97 +            /// Otherwise, other processes cannot open the object if they request write access. 
    1.98 +            /// If this flag is not specified, but the object has been opened for write access, the function fails.
    1.99 +            /// </summary>
   1.100 +            Write = 0x00000002,
   1.101 +            /// <summary>
   1.102 +            /// Enables subsequent open operations on an object to request delete access. 
   1.103 +            /// Otherwise, other processes cannot open the object if they request delete access.
   1.104 +            /// If this flag is not specified, but the object has been opened for delete access, the function fails.
   1.105 +            /// </summary>
   1.106 +            Delete = 0x00000004
   1.107 +        }
   1.108 +
   1.109 +        public enum ECreationDisposition : uint
   1.110 +        {
   1.111 +            /// <summary>
   1.112 +            /// Creates a new file. The function fails if a specified file exists.
   1.113 +            /// </summary>
   1.114 +            New = 1,
   1.115 +            /// <summary>
   1.116 +            /// Creates a new file, always. 
   1.117 +            /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes, 
   1.118 +            /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
   1.119 +            /// </summary>
   1.120 +            CreateAlways = 2,
   1.121 +            /// <summary>
   1.122 +            /// Opens a file. The function fails if the file does not exist. 
   1.123 +            /// </summary>
   1.124 +            OpenExisting = 3,
   1.125 +            /// <summary>
   1.126 +            /// Opens a file, always. 
   1.127 +            /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
   1.128 +            /// </summary>
   1.129 +            OpenAlways = 4,
   1.130 +            /// <summary>
   1.131 +            /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
   1.132 +            /// The calling process must open the file with the GENERIC_WRITE access right. 
   1.133 +            /// </summary>
   1.134 +            TruncateExisting = 5
   1.135 +        }
   1.136 +
   1.137 +        [Flags]
   1.138 +        public enum EFileAttributes : uint
   1.139 +        {
   1.140 +            None = 0x00000000,
   1.141 +            Readonly = 0x00000001,
   1.142 +            Hidden = 0x00000002,
   1.143 +            System = 0x00000004,
   1.144 +            Directory = 0x00000010,
   1.145 +            Archive = 0x00000020,
   1.146 +            Device = 0x00000040,
   1.147 +            Normal = 0x00000080,
   1.148 +            Temporary = 0x00000100,
   1.149 +            SparseFile = 0x00000200,
   1.150 +            ReparsePoint = 0x00000400,
   1.151 +            Compressed = 0x00000800,
   1.152 +            Offline = 0x00001000,
   1.153 +            NotContentIndexed = 0x00002000,
   1.154 +            Encrypted = 0x00004000,
   1.155 +            Write_Through = 0x80000000,
   1.156 +            Overlapped = 0x40000000,
   1.157 +            NoBuffering = 0x20000000,
   1.158 +            RandomAccess = 0x10000000,
   1.159 +            SequentialScan = 0x08000000,
   1.160 +            DeleteOnClose = 0x04000000,
   1.161 +            BackupSemantics = 0x02000000,
   1.162 +            PosixSemantics = 0x01000000,
   1.163 +            OpenReparsePoint = 0x00200000,
   1.164 +            OpenNoRecall = 0x00100000,
   1.165 +            FirstPipeInstance = 0x00080000
   1.166 +        }
   1.167 +
   1.168          [DllImport("kernel32.dll", SetLastError = true)]
   1.169          public static extern SafeFileHandle CreateNamedPipe(
   1.170             String pipeName,
   1.171 @@ -30,6 +191,19 @@
   1.172          public static extern int DisconnectNamedPipe(
   1.173             SafeFileHandle hNamedPipe);
   1.174  
   1.175 +        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
   1.176 +        public static extern SafeFileHandle CreateFile(
   1.177 +           string lpFileName,
   1.178 +           EFileAccess dwDesiredAccess,
   1.179 +           EFileShare dwShareMode,
   1.180 +           IntPtr lpSecurityAttributes,
   1.181 +           ECreationDisposition dwCreationDisposition,
   1.182 +           EFileAttributes dwFlagsAndAttributes,
   1.183 +           IntPtr hTemplateFile);
   1.184 +
   1.185 +        //[DllImport("kernel32.dll", SetLastError = true)]
   1.186 +        //static extern bool CloseHandle(IntPtr hHandle);
   1.187 +
   1.188          public const uint PIPE_ACCESS_DUPLEX = (0x00000003);
   1.189          public const uint FILE_FLAG_OVERLAPPED = (0x40000000);
   1.190          public const uint PIPE_ACCESS_OUTBOUND = (0x00000002);
   1.191 @@ -44,7 +218,6 @@
   1.192  
   1.193          //
   1.194          public string iPipeNameOutbound;
   1.195 -        Thread iThreadOutbound;
   1.196          SafeFileHandle iPipeOutbound;
   1.197          public FileStream iStreamOutbound;
   1.198          //
   1.199 @@ -53,6 +226,8 @@
   1.200          SafeFileHandle iPipeInbound;
   1.201          public FileStream iStreamInbound;
   1.202  
   1.203 +        private bool iQuit = false;
   1.204 +
   1.205  
   1.206          public Server(string aPipeNameOutbound, string aPipeNameInbound)
   1.207          {
   1.208 @@ -65,74 +240,72 @@
   1.209           */
   1.210          public void Start()
   1.211          {
   1.212 -            //Start outbound thread to send messages
   1.213 -            this.iThreadOutbound = new Thread(new ThreadStart(ThreadOutbound));
   1.214 -            this.iThreadOutbound.Start();
   1.215              //Start inbound thread to receive messages
   1.216              this.iThreadInbound = new Thread(new ThreadStart(ThreadInbound));
   1.217              this.iThreadInbound.Start();
   1.218          }
   1.219  
   1.220          /**
   1.221 -         * Outbound thread is sending messages to our client.
   1.222 +         * Stop our services.
   1.223           */
   1.224 -        private void ThreadOutbound()
   1.225 +        public void Stop()
   1.226          {
   1.227 -            
   1.228 -            //Create our outbound named pipe
   1.229 -            iPipeOutbound = CreateNamedPipe(this.iPipeNameOutbound, PIPE_ACCESS_OUTBOUND /*| FILE_FLAG_OVERLAPPED*/, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
   1.230 +            iQuit = true;
   1.231 +        }
   1.232  
   1.233 -            //Could not create named pipe
   1.234 -            if (iPipeOutbound.IsInvalid)
   1.235 -            {
   1.236 -                //TODO: error handling
   1.237 -                return;
   1.238 -            }
   1.239 -
   1.240 -            //Will complete once our client connects
   1.241 -            int success = ConnectNamedPipe(iPipeOutbound, IntPtr.Zero);
   1.242 -
   1.243 -            //could not connect client
   1.244 -            if (success == 0)
   1.245 -            {
   1.246 -                //TODO: error handling
   1.247 -                return;
   1.248 -            }
   1.249 -
   1.250 -            //Client now connected create our stream
   1.251 -            iStreamOutbound = new FileStream(iPipeOutbound, FileAccess.Write, BUFFER_SIZE, false);
   1.252 - 
   1.253 -        }
   1.254  
   1.255          /**
   1.256           * Inbound thread is receiving messages from our client
   1.257           */
   1.258          private void ThreadInbound()
   1.259          {
   1.260 -            //Client client = (Client)clientObj;
   1.261 -            //clientse.stream = new FileStream(clientse.handle, FileAccess.ReadWrite, BUFFER_SIZE, true);
   1.262  
   1.263 -            iPipeInbound = CreateNamedPipe(this.iPipeNameInbound, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
   1.264 -
   1.265 -            //could not create named pipe
   1.266 -            if (iPipeInbound.IsInvalid)
   1.267 -                return;
   1.268 -
   1.269 -            //Will complete once a client connects
   1.270 -            int success = ConnectNamedPipe(iPipeInbound, IntPtr.Zero);
   1.271 -
   1.272 -            //could not connect client
   1.273 -            if (success == 0)
   1.274 -                return;
   1.275 +            //Keep on trying to connect on our read pipe
   1.276 +            while ((iPipeInbound == null || iPipeInbound.IsInvalid) && !iQuit)
   1.277 +            {
   1.278 +                Trace.WriteLine("Trying to connect to inbound pipe...");
   1.279 +                iPipeInbound = CreateFile(iPipeNameInbound, EFileAccess.GenericRead, EFileShare.None, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.None, IntPtr.Zero);
   1.280 +                System.Threading.Thread.Sleep(1000);
   1.281 +            }
   1.282 +            
   1.283  
   1.284              //Client now connected create our inbound stream
   1.285 -            iStreamInbound = new FileStream(iPipeInbound, FileAccess.Read, BUFFER_SIZE, false);
   1.286 +            if (iPipeInbound!=null && !iPipeInbound.IsInvalid)
   1.287 +            {
   1.288 +                iStreamInbound = new FileStream(iPipeInbound, FileAccess.Read, BUFFER_SIZE, false);
   1.289 +                if (iStreamInbound.CanRead)
   1.290 +                {
   1.291 +                    Trace.WriteLine("Inbound stream ready!");
   1.292 +                }
   1.293 +            }
   1.294  
   1.295  
   1.296 +            //Keep on trying to connect to our write pipe
   1.297 +            while ((iPipeOutbound == null || iPipeOutbound.IsInvalid) && !iQuit)
   1.298 +            {
   1.299 +                Trace.WriteLine("Trying to connect to outbound pipe...");
   1.300 +                iPipeOutbound = CreateFile(iPipeNameOutbound, EFileAccess.GenericWrite, EFileShare.None, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.None, IntPtr.Zero);
   1.301 +                System.Threading.Thread.Sleep(1000);
   1.302 +            }
   1.303 +            
   1.304 +
   1.305 +            //Client now connected create our stream
   1.306 +            if (iPipeOutbound!=null && !iPipeOutbound.IsInvalid)
   1.307 +            {
   1.308 +                iStreamOutbound = new FileStream(iPipeOutbound, FileAccess.Write, BUFFER_SIZE, false);
   1.309 +
   1.310 +                if (iStreamOutbound.CanWrite)
   1.311 +                {
   1.312 +                    Trace.WriteLine("Outbound stream ready!");
   1.313 +                }
   1.314 +            }
   1.315 +
   1.316 +
   1.317 +            //Listening loop
   1.318              byte[] buffer = null;
   1.319              ASCIIEncoding encoder = new ASCIIEncoding();
   1.320  
   1.321 -            while (true)
   1.322 +            while (!iQuit)
   1.323              {                
   1.324                  int bytesRead = 0;
   1.325  
   1.326 @@ -171,16 +344,20 @@
   1.327                      byte[] Rc = new byte[ReadLength];
   1.328                      Buffer.BlockCopy(buffer, 0, Rc, 0, ReadLength);
   1.329  
   1.330 -                    Console.WriteLine(encoder.GetString(Rc, 0, ReadLength));
   1.331 +                    Trace.WriteLine(encoder.GetString(Rc, 0, ReadLength));
   1.332                      Trace.WriteLine("Received " + ReadLength + " Bytes: " + encoder.GetString(Rc, 0, ReadLength));
   1.333                      buffer.Initialize();
   1.334                  }
   1.335                 
   1.336              }
   1.337  
   1.338 + 
   1.339              //clean up resources
   1.340 -            iStreamInbound.Close();
   1.341 -            iPipeInbound.Close();            
   1.342 +            if (iStreamInbound!=null) iStreamInbound.Close();
   1.343 +            if (iPipeInbound != null) iPipeInbound.Close();
   1.344 +            //
   1.345 +            if (iStreamOutbound != null) iStreamOutbound.Close();
   1.346 +            if (iPipeOutbound != null) iPipeOutbound.Close();
   1.347          }
   1.348  
   1.349          /**
   1.350 @@ -192,7 +369,7 @@
   1.351                  ASCIIEncoding encoder = new ASCIIEncoding();
   1.352                  byte[] messageBuffer = encoder.GetBytes(message);
   1.353  
   1.354 -                if (iStreamOutbound.CanWrite)
   1.355 +                if (iStreamOutbound != null && iStreamOutbound.CanWrite)
   1.356                  {
   1.357                      iStreamOutbound.Write(messageBuffer, 0, messageBuffer.Length);
   1.358                      iStreamOutbound.Flush();
   1.359 @@ -201,20 +378,6 @@
   1.360  
   1.361          }
   1.362  
   1.363 -        /**
   1.364 -         * 
   1.365 -         */
   1.366 -        public void Stop()
   1.367 -        {
   1.368 -            //clean up resources
   1.369 -
   1.370 -            DisconnectNamedPipe(this.iPipeOutbound);
   1.371 -
   1.372 -            //TODO: more cleanup
   1.373 -            
   1.374 -
   1.375 -            this.iThreadOutbound.Abort();
   1.376 -        }
   1.377  
   1.378      }
   1.379  }