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 }