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/MainForm.cs Sat Feb 09 17:18:09 2013 +0100
1.2 +++ b/GUI/MainForm.cs Fri Apr 12 02:30:14 2013 +0200
1.3 @@ -505,6 +505,7 @@
1.4 Close();
1.5 }
1.6
1.7 +
1.8 private void timer_Tick(object sender, EventArgs e) {
1.9 computer.Accept(updateVisitor);
1.10 treeView.Invalidate();
2.1 --- a/GUI/SoundGraphDisplay.cs Sat Feb 09 17:18:09 2013 +0100
2.2 +++ b/GUI/SoundGraphDisplay.cs Fri Apr 12 02:30:14 2013 +0200
2.3 @@ -59,8 +59,8 @@
2.4 client.Start();*/
2.5 }
2.6
2.7 - //Try loading SoundGraph iMON Disaply DLL
2.8 - iServer = new SoundGraph.Server(@"\\.\pipe\sga-receiver", @"\\.\pipe\sga-sender");
2.9 + //Start our SoundGraph server
2.10 + iServer = new SoundGraph.Server(@"\\.\pipe\sga-inbound", @"\\.\pipe\sga-outbound");
2.11 iServer.Start();
2.12 //iServer.SendMessage("init:");
2.13 }
2.14 @@ -103,6 +103,7 @@
2.15 foreach (SensorFrontView icon in list)
2.16 icon.Dispose();
2.17
2.18 + Quit();
2.19 iServer.Stop();
2.20
2.21 }
2.22 @@ -193,6 +194,11 @@
2.23 iServer.SendMessage("set-vfd-text:" + aUpperLine);
2.24 }
2.25
2.26 + public void Quit()
2.27 + {
2.28 + iServer.SendMessage("quit:");
2.29 + }
2.30 +
2.31 /*
2.32 public bool IsMainIconEnabled
2.33 {
2.34 @@ -207,13 +213,6 @@
2.35 }
2.36 }*/
2.37
2.38 - /*
2.39 - public bool IsDllLoaded
2.40 - {
2.41 - get { return iSoundGraphDll!=IntPtr.Zero; }
2.42 - }
2.43 - */
2.44 -
2.45
2.46 }
2.47 }
3.1 --- a/GUI/SoundGraphServer.cs Sat Feb 09 17:18:09 2013 +0100
3.2 +++ b/GUI/SoundGraphServer.cs Fri Apr 12 02:30:14 2013 +0200
3.3 @@ -10,6 +10,167 @@
3.4 {
3.5 public class Server
3.6 {
3.7 + [Flags]
3.8 + public enum EFileAccess : uint
3.9 + {
3.10 + //
3.11 + // Standart Section
3.12 + //
3.13 +
3.14 + AccessSystemSecurity = 0x1000000, // AccessSystemAcl access type
3.15 + MaximumAllowed = 0x2000000, // MaximumAllowed access type
3.16 +
3.17 + Delete = 0x10000,
3.18 + ReadControl = 0x20000,
3.19 + WriteDAC = 0x40000,
3.20 + WriteOwner = 0x80000,
3.21 + Synchronize = 0x100000,
3.22 +
3.23 + StandardRightsRequired = 0xF0000,
3.24 + StandardRightsRead = ReadControl,
3.25 + StandardRightsWrite = ReadControl,
3.26 + StandardRightsExecute = ReadControl,
3.27 + StandardRightsAll = 0x1F0000,
3.28 + SpecificRightsAll = 0xFFFF,
3.29 +
3.30 + FILE_READ_DATA = 0x0001, // file & pipe
3.31 + FILE_LIST_DIRECTORY = 0x0001, // directory
3.32 + FILE_WRITE_DATA = 0x0002, // file & pipe
3.33 + FILE_ADD_FILE = 0x0002, // directory
3.34 + FILE_APPEND_DATA = 0x0004, // file
3.35 + FILE_ADD_SUBDIRECTORY = 0x0004, // directory
3.36 + FILE_CREATE_PIPE_INSTANCE = 0x0004, // named pipe
3.37 + FILE_READ_EA = 0x0008, // file & directory
3.38 + FILE_WRITE_EA = 0x0010, // file & directory
3.39 + FILE_EXECUTE = 0x0020, // file
3.40 + FILE_TRAVERSE = 0x0020, // directory
3.41 + FILE_DELETE_CHILD = 0x0040, // directory
3.42 + FILE_READ_ATTRIBUTES = 0x0080, // all
3.43 + FILE_WRITE_ATTRIBUTES = 0x0100, // all
3.44 +
3.45 + //
3.46 + // Generic Section
3.47 + //
3.48 +
3.49 + GenericRead = 0x80000000,
3.50 + GenericWrite = 0x40000000,
3.51 + GenericExecute = 0x20000000,
3.52 + GenericAll = 0x10000000,
3.53 +
3.54 + SPECIFIC_RIGHTS_ALL = 0x00FFFF,
3.55 + FILE_ALL_ACCESS =
3.56 + StandardRightsRequired |
3.57 + Synchronize |
3.58 + 0x1FF,
3.59 +
3.60 + FILE_GENERIC_READ =
3.61 + StandardRightsRead |
3.62 + FILE_READ_DATA |
3.63 + FILE_READ_ATTRIBUTES |
3.64 + FILE_READ_EA |
3.65 + Synchronize,
3.66 +
3.67 + FILE_GENERIC_WRITE =
3.68 + StandardRightsWrite |
3.69 + FILE_WRITE_DATA |
3.70 + FILE_WRITE_ATTRIBUTES |
3.71 + FILE_WRITE_EA |
3.72 + FILE_APPEND_DATA |
3.73 + Synchronize,
3.74 +
3.75 + FILE_GENERIC_EXECUTE =
3.76 + StandardRightsExecute |
3.77 + FILE_READ_ATTRIBUTES |
3.78 + FILE_EXECUTE |
3.79 + Synchronize
3.80 + }
3.81 +
3.82 + [Flags]
3.83 + public enum EFileShare : uint
3.84 + {
3.85 + /// <summary>
3.86 + ///
3.87 + /// </summary>
3.88 + None = 0x00000000,
3.89 + /// <summary>
3.90 + /// Enables subsequent open operations on an object to request read access.
3.91 + /// Otherwise, other processes cannot open the object if they request read access.
3.92 + /// If this flag is not specified, but the object has been opened for read access, the function fails.
3.93 + /// </summary>
3.94 + Read = 0x00000001,
3.95 + /// <summary>
3.96 + /// Enables subsequent open operations on an object to request write access.
3.97 + /// Otherwise, other processes cannot open the object if they request write access.
3.98 + /// If this flag is not specified, but the object has been opened for write access, the function fails.
3.99 + /// </summary>
3.100 + Write = 0x00000002,
3.101 + /// <summary>
3.102 + /// Enables subsequent open operations on an object to request delete access.
3.103 + /// Otherwise, other processes cannot open the object if they request delete access.
3.104 + /// If this flag is not specified, but the object has been opened for delete access, the function fails.
3.105 + /// </summary>
3.106 + Delete = 0x00000004
3.107 + }
3.108 +
3.109 + public enum ECreationDisposition : uint
3.110 + {
3.111 + /// <summary>
3.112 + /// Creates a new file. The function fails if a specified file exists.
3.113 + /// </summary>
3.114 + New = 1,
3.115 + /// <summary>
3.116 + /// Creates a new file, always.
3.117 + /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes,
3.118 + /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
3.119 + /// </summary>
3.120 + CreateAlways = 2,
3.121 + /// <summary>
3.122 + /// Opens a file. The function fails if the file does not exist.
3.123 + /// </summary>
3.124 + OpenExisting = 3,
3.125 + /// <summary>
3.126 + /// Opens a file, always.
3.127 + /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
3.128 + /// </summary>
3.129 + OpenAlways = 4,
3.130 + /// <summary>
3.131 + /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
3.132 + /// The calling process must open the file with the GENERIC_WRITE access right.
3.133 + /// </summary>
3.134 + TruncateExisting = 5
3.135 + }
3.136 +
3.137 + [Flags]
3.138 + public enum EFileAttributes : uint
3.139 + {
3.140 + None = 0x00000000,
3.141 + Readonly = 0x00000001,
3.142 + Hidden = 0x00000002,
3.143 + System = 0x00000004,
3.144 + Directory = 0x00000010,
3.145 + Archive = 0x00000020,
3.146 + Device = 0x00000040,
3.147 + Normal = 0x00000080,
3.148 + Temporary = 0x00000100,
3.149 + SparseFile = 0x00000200,
3.150 + ReparsePoint = 0x00000400,
3.151 + Compressed = 0x00000800,
3.152 + Offline = 0x00001000,
3.153 + NotContentIndexed = 0x00002000,
3.154 + Encrypted = 0x00004000,
3.155 + Write_Through = 0x80000000,
3.156 + Overlapped = 0x40000000,
3.157 + NoBuffering = 0x20000000,
3.158 + RandomAccess = 0x10000000,
3.159 + SequentialScan = 0x08000000,
3.160 + DeleteOnClose = 0x04000000,
3.161 + BackupSemantics = 0x02000000,
3.162 + PosixSemantics = 0x01000000,
3.163 + OpenReparsePoint = 0x00200000,
3.164 + OpenNoRecall = 0x00100000,
3.165 + FirstPipeInstance = 0x00080000
3.166 + }
3.167 +
3.168 [DllImport("kernel32.dll", SetLastError = true)]
3.169 public static extern SafeFileHandle CreateNamedPipe(
3.170 String pipeName,
3.171 @@ -30,6 +191,19 @@
3.172 public static extern int DisconnectNamedPipe(
3.173 SafeFileHandle hNamedPipe);
3.174
3.175 + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
3.176 + public static extern SafeFileHandle CreateFile(
3.177 + string lpFileName,
3.178 + EFileAccess dwDesiredAccess,
3.179 + EFileShare dwShareMode,
3.180 + IntPtr lpSecurityAttributes,
3.181 + ECreationDisposition dwCreationDisposition,
3.182 + EFileAttributes dwFlagsAndAttributes,
3.183 + IntPtr hTemplateFile);
3.184 +
3.185 + //[DllImport("kernel32.dll", SetLastError = true)]
3.186 + //static extern bool CloseHandle(IntPtr hHandle);
3.187 +
3.188 public const uint PIPE_ACCESS_DUPLEX = (0x00000003);
3.189 public const uint FILE_FLAG_OVERLAPPED = (0x40000000);
3.190 public const uint PIPE_ACCESS_OUTBOUND = (0x00000002);
3.191 @@ -44,7 +218,6 @@
3.192
3.193 //
3.194 public string iPipeNameOutbound;
3.195 - Thread iThreadOutbound;
3.196 SafeFileHandle iPipeOutbound;
3.197 public FileStream iStreamOutbound;
3.198 //
3.199 @@ -53,6 +226,8 @@
3.200 SafeFileHandle iPipeInbound;
3.201 public FileStream iStreamInbound;
3.202
3.203 + private bool iQuit = false;
3.204 +
3.205
3.206 public Server(string aPipeNameOutbound, string aPipeNameInbound)
3.207 {
3.208 @@ -65,74 +240,72 @@
3.209 */
3.210 public void Start()
3.211 {
3.212 - //Start outbound thread to send messages
3.213 - this.iThreadOutbound = new Thread(new ThreadStart(ThreadOutbound));
3.214 - this.iThreadOutbound.Start();
3.215 //Start inbound thread to receive messages
3.216 this.iThreadInbound = new Thread(new ThreadStart(ThreadInbound));
3.217 this.iThreadInbound.Start();
3.218 }
3.219
3.220 /**
3.221 - * Outbound thread is sending messages to our client.
3.222 + * Stop our services.
3.223 */
3.224 - private void ThreadOutbound()
3.225 + public void Stop()
3.226 {
3.227 -
3.228 - //Create our outbound named pipe
3.229 - iPipeOutbound = CreateNamedPipe(this.iPipeNameOutbound, PIPE_ACCESS_OUTBOUND /*| FILE_FLAG_OVERLAPPED*/, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
3.230 + iQuit = true;
3.231 + }
3.232
3.233 - //Could not create named pipe
3.234 - if (iPipeOutbound.IsInvalid)
3.235 - {
3.236 - //TODO: error handling
3.237 - return;
3.238 - }
3.239 -
3.240 - //Will complete once our client connects
3.241 - int success = ConnectNamedPipe(iPipeOutbound, IntPtr.Zero);
3.242 -
3.243 - //could not connect client
3.244 - if (success == 0)
3.245 - {
3.246 - //TODO: error handling
3.247 - return;
3.248 - }
3.249 -
3.250 - //Client now connected create our stream
3.251 - iStreamOutbound = new FileStream(iPipeOutbound, FileAccess.Write, BUFFER_SIZE, false);
3.252 -
3.253 - }
3.254
3.255 /**
3.256 * Inbound thread is receiving messages from our client
3.257 */
3.258 private void ThreadInbound()
3.259 {
3.260 - //Client client = (Client)clientObj;
3.261 - //clientse.stream = new FileStream(clientse.handle, FileAccess.ReadWrite, BUFFER_SIZE, true);
3.262
3.263 - iPipeInbound = CreateNamedPipe(this.iPipeNameInbound, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
3.264 -
3.265 - //could not create named pipe
3.266 - if (iPipeInbound.IsInvalid)
3.267 - return;
3.268 -
3.269 - //Will complete once a client connects
3.270 - int success = ConnectNamedPipe(iPipeInbound, IntPtr.Zero);
3.271 -
3.272 - //could not connect client
3.273 - if (success == 0)
3.274 - return;
3.275 + //Keep on trying to connect on our read pipe
3.276 + while ((iPipeInbound == null || iPipeInbound.IsInvalid) && !iQuit)
3.277 + {
3.278 + Trace.WriteLine("Trying to connect to inbound pipe...");
3.279 + iPipeInbound = CreateFile(iPipeNameInbound, EFileAccess.GenericRead, EFileShare.None, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.None, IntPtr.Zero);
3.280 + System.Threading.Thread.Sleep(1000);
3.281 + }
3.282 +
3.283
3.284 //Client now connected create our inbound stream
3.285 - iStreamInbound = new FileStream(iPipeInbound, FileAccess.Read, BUFFER_SIZE, false);
3.286 + if (iPipeInbound!=null && !iPipeInbound.IsInvalid)
3.287 + {
3.288 + iStreamInbound = new FileStream(iPipeInbound, FileAccess.Read, BUFFER_SIZE, false);
3.289 + if (iStreamInbound.CanRead)
3.290 + {
3.291 + Trace.WriteLine("Inbound stream ready!");
3.292 + }
3.293 + }
3.294
3.295
3.296 + //Keep on trying to connect to our write pipe
3.297 + while ((iPipeOutbound == null || iPipeOutbound.IsInvalid) && !iQuit)
3.298 + {
3.299 + Trace.WriteLine("Trying to connect to outbound pipe...");
3.300 + iPipeOutbound = CreateFile(iPipeNameOutbound, EFileAccess.GenericWrite, EFileShare.None, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.None, IntPtr.Zero);
3.301 + System.Threading.Thread.Sleep(1000);
3.302 + }
3.303 +
3.304 +
3.305 + //Client now connected create our stream
3.306 + if (iPipeOutbound!=null && !iPipeOutbound.IsInvalid)
3.307 + {
3.308 + iStreamOutbound = new FileStream(iPipeOutbound, FileAccess.Write, BUFFER_SIZE, false);
3.309 +
3.310 + if (iStreamOutbound.CanWrite)
3.311 + {
3.312 + Trace.WriteLine("Outbound stream ready!");
3.313 + }
3.314 + }
3.315 +
3.316 +
3.317 + //Listening loop
3.318 byte[] buffer = null;
3.319 ASCIIEncoding encoder = new ASCIIEncoding();
3.320
3.321 - while (true)
3.322 + while (!iQuit)
3.323 {
3.324 int bytesRead = 0;
3.325
3.326 @@ -171,16 +344,20 @@
3.327 byte[] Rc = new byte[ReadLength];
3.328 Buffer.BlockCopy(buffer, 0, Rc, 0, ReadLength);
3.329
3.330 - Console.WriteLine(encoder.GetString(Rc, 0, ReadLength));
3.331 + Trace.WriteLine(encoder.GetString(Rc, 0, ReadLength));
3.332 Trace.WriteLine("Received " + ReadLength + " Bytes: " + encoder.GetString(Rc, 0, ReadLength));
3.333 buffer.Initialize();
3.334 }
3.335
3.336 }
3.337
3.338 +
3.339 //clean up resources
3.340 - iStreamInbound.Close();
3.341 - iPipeInbound.Close();
3.342 + if (iStreamInbound!=null) iStreamInbound.Close();
3.343 + if (iPipeInbound != null) iPipeInbound.Close();
3.344 + //
3.345 + if (iStreamOutbound != null) iStreamOutbound.Close();
3.346 + if (iPipeOutbound != null) iPipeOutbound.Close();
3.347 }
3.348
3.349 /**
3.350 @@ -192,7 +369,7 @@
3.351 ASCIIEncoding encoder = new ASCIIEncoding();
3.352 byte[] messageBuffer = encoder.GetBytes(message);
3.353
3.354 - if (iStreamOutbound.CanWrite)
3.355 + if (iStreamOutbound != null && iStreamOutbound.CanWrite)
3.356 {
3.357 iStreamOutbound.Write(messageBuffer, 0, messageBuffer.Length);
3.358 iStreamOutbound.Flush();
3.359 @@ -201,20 +378,6 @@
3.360
3.361 }
3.362
3.363 - /**
3.364 - *
3.365 - */
3.366 - public void Stop()
3.367 - {
3.368 - //clean up resources
3.369 -
3.370 - DisconnectNamedPipe(this.iPipeOutbound);
3.371 -
3.372 - //TODO: more cleanup
3.373 -
3.374 -
3.375 - this.iThreadOutbound.Abort();
3.376 - }
3.377
3.378 }
3.379 }