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(); - } } }