Reverting client/server communication around our pipes to fix access denied err.
Now simply opening files for pipes created by SoundGraphAccess server.
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 }