public async Task PingPong_Async() { // Create names for two pipes string outName = Path.GetRandomFileName(); string inName = Path.GetRandomFileName(); // Create the two named pipes, one for each direction, then create // another process with which to communicate using (var outbound = new NamedPipeServerStream(outName, PipeDirection.Out)) using (var inbound = new NamedPipeClientStream(".", inName, PipeDirection.In)) using (RemoteInvoke(PingPong_OtherProcess, outName, inName)) { // Wait for both pipes to be connected await Task.WhenAll(outbound.WaitForConnectionAsync(), inbound.ConnectAsync()); // Repeatedly write then read a byte to and from the other process var data = new byte[1]; for (byte i = 0; i < 10; i++) { data[0] = i; await outbound.WriteAsync(data, 0, data.Length); data[0] = 0; int received = await inbound.ReadAsync(data, 0, data.Length); Assert.Equal(1, received); Assert.Equal(i, data[0]); } } }
public static void CreateWithNegativeOneServerInstances_DefaultsToMaxServerInstances() { // When passed -1 as the maxnumberofserverisntances, the NamedPipeServerStream.Windows class // will translate that to the platform specific maximum number (255) using (var server = new NamedPipeServerStream(GetUniquePipeName(), PipeDirection.InOut, -1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) using (var server2 = new NamedPipeServerStream(PipeDirection.InOut, false, true, server.SafePipeHandle)) using (var server3 = new NamedPipeServerStream(PipeDirection.InOut, false, true, server.SafePipeHandle)) { } }
public void GetAccessControl_NamedPipe_BeforeWaitingToConnect() { string pipeName = GetUniquePipeName(); var server = new NamedPipeServerStream(pipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); var client = new NamedPipeClientStream(".", pipeName, PipeDirection.In, PipeOptions.Asynchronous); Assert.NotNull(server.GetAccessControl()); server.SetAccessControl(new PipeSecurity()); Assert.Throws<InvalidOperationException>(() => client.GetAccessControl()); Assert.Throws<InvalidOperationException>(() => client.SetAccessControl(new PipeSecurity())); }
protected override ServerClientPair CreateServerClientPair() { ServerClientPair ret = new ServerClientPair(); string pipeName = GetUniquePipeName(); var readablePipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); var writeablePipe = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous); Task serverConnect = Task.Factory.FromAsync(readablePipe.BeginWaitForConnection, readablePipe.EndWaitForConnection, null); writeablePipe.Connect(); serverConnect.Wait(); ret.readablePipe = readablePipe; ret.writeablePipe = writeablePipe; return ret; }
protected override ServerClientPair CreateServerClientPair() { ServerClientPair ret = new ServerClientPair(); string pipeName = GetUniquePipeName(); var writeablePipe = new NamedPipeServerStream(pipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); var readablePipe = new NamedPipeClientStream(".", pipeName, PipeDirection.In, PipeOptions.Asynchronous); Task clientConnect = readablePipe.ConnectAsync(); writeablePipe.WaitForConnection(); clientConnect.Wait(); ret.readablePipe = readablePipe; ret.writeablePipe = writeablePipe; return ret; }
public async Task RunAsClient_Windows() { string pipeName = Path.GetRandomFileName(); using (var server = new NamedPipeServerStream(pipeName)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation)) { Task serverTask = server.WaitForConnectionAsync(); client.Connect(); await serverTask; bool ran = false; server.RunAsClient(() => ran = true); Assert.True(ran, "Expected delegate to have been invoked"); } }
[PlatformSpecific(PlatformID.Windows)] // Unix implementation uses bidirectional sockets public void ConnectWithConflictingDirections_Throws_UnauthorizedAccessException() { string serverName1 = GetUniquePipeName(); using (NamedPipeServerStream server = new NamedPipeServerStream(serverName1, PipeDirection.Out)) using (NamedPipeClientStream client = new NamedPipeClientStream(".", serverName1, PipeDirection.Out)) { Assert.Throws<UnauthorizedAccessException>(() => client.Connect()); Assert.False(client.IsConnected); } string serverName2 = GetUniquePipeName(); using (NamedPipeServerStream server = new NamedPipeServerStream(serverName2, PipeDirection.In)) using (NamedPipeClientStream client = new NamedPipeClientStream(".", serverName2, PipeDirection.In)) { Assert.Throws<UnauthorizedAccessException>(() => client.Connect()); Assert.False(client.IsConnected); } }
private static int PingPong_OtherProcess(string inName, string outName) { // Create pipes with the supplied names using (var inbound = new NamedPipeClientStream(".", inName, PipeDirection.In)) using (var outbound = new NamedPipeServerStream(outName, PipeDirection.Out)) { // Wait for the connections to be established Task.WaitAll(inbound.ConnectAsync(), outbound.WaitForConnectionAsync()); // Repeatedly read then write bytes from and to the other process for (int i = 0; i < 10; i++) { int b = inbound.ReadByte(); outbound.WriteByte((byte)b); } } return SuccessExitCode; }
public void GetAccessControl_NamedPipeServerStream_Broken() { string pipeName = GetUniquePipeName(); var server = new NamedPipeServerStream(pipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); var client = new NamedPipeClientStream(".", pipeName, PipeDirection.In, PipeOptions.Asynchronous); Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); Assert.NotNull(server.GetAccessControl()); server.SetAccessControl(new PipeSecurity()); Assert.NotNull(client.GetAccessControl()); client.SetAccessControl(new PipeSecurity()); client.Dispose(); Assert.Throws<IOException>(() => server.Write(new byte[] { 0 }, 0, 1)); // Sets the servers PipeState to Broken server.SetAccessControl(new PipeSecurity()); }
private static int ServerConnectAsId(string pipeName, string pairIDString) { uint pairID = uint.Parse(pairIDString); Assert.NotEqual(-1, seteuid(pairID)); using (var outbound = new NamedPipeServerStream(pipeName, PipeDirection.Out)) using (var handle = RemoteInvoke(ClientConnectAsID, pipeName, pairIDString)) { // Connect as the unpriveleged user, but RunAsClient as the superuser outbound.WaitForConnection(); Assert.NotEqual(-1, seteuid(0)); bool ran = false; uint ranAs = 0; outbound.RunAsClient(() => { ran = true; ranAs = geteuid(); }); Assert.True(ran, "Expected delegate to have been invoked"); Assert.Equal(pairID, ranAs); } return SuccessExitCode; }
public void PingPong_Sync() { // Create names for two pipes string outName = Path.GetRandomFileName(); string inName = Path.GetRandomFileName(); // Create the two named pipes, one for each direction, then create // another process with which to communicate using (var outbound = new NamedPipeServerStream(outName, PipeDirection.Out)) using (var inbound = new NamedPipeClientStream(".", inName, PipeDirection.In)) using (RemoteInvoke(PingPong_OtherProcess, outName, inName)) { // Wait for both pipes to be connected Task.WaitAll(outbound.WaitForConnectionAsync(), inbound.ConnectAsync()); // Repeatedly write then read a byte to and from the other process for (byte i = 0; i < 10; i++) { outbound.WriteByte(i); int received = inbound.ReadByte(); Assert.Equal(i, received); } } }
public void NameTooLong_MaxLengthPerPlatform() { // Increase a name's length until it fails ArgumentOutOfRangeException e = null; string name = Path.GetRandomFileName(); for (int i = 0; ; i++) { try { name += 'c'; using (var s = new NamedPipeServerStream(name)) using (var c = new NamedPipeClientStream(name)) { Task t = s.WaitForConnectionAsync(); c.Connect(); t.GetAwaiter().GetResult(); } } catch (ArgumentOutOfRangeException exc) { e = exc; break; } } Assert.NotNull(e); Assert.NotNull(e.ActualValue); // Validate the length was expected string path = (string)e.ActualValue; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { Assert.Equal(108, path.Length); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { Assert.Equal(104, path.Length); } else { Assert.InRange(path.Length, 92, int.MaxValue); } }
[PlatformSpecific(PlatformID.Windows)] // Unix currently doesn't support message mode public async Task Windows_MessagePipeTransissionMode(PipeOptions serverOptions) { byte[] msg1 = new byte[] { 5, 7, 9, 10 }; byte[] msg2 = new byte[] { 2, 4 }; byte[] received1 = new byte[] { 0, 0, 0, 0 }; byte[] received2 = new byte[] { 0, 0 }; byte[] received3 = new byte[] { 0, 0, 0, 0 }; byte[] received4 = new byte[] { 0, 0, 0, 0 }; byte[] received5 = new byte[] { 0, 0 }; byte[] received6 = new byte[] { 0, 0, 0, 0 }; string pipeName = GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Message, serverOptions)) { using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation)) { server.ReadMode = PipeTransmissionMode.Message; Assert.Equal(PipeTransmissionMode.Message, server.ReadMode); Task clientTask = Task.Run(() => { client.Connect(); client.Write(msg1, 0, msg1.Length); client.Write(msg2, 0, msg2.Length); client.Write(msg1, 0, msg1.Length); client.Write(msg1, 0, msg1.Length); client.Write(msg2, 0, msg2.Length); client.Write(msg1, 0, msg1.Length); int serverCount = client.NumberOfServerInstances; Assert.Equal(1, serverCount); }); server.WaitForConnection(); int len1 = server.Read(received1, 0, msg1.Length); Assert.True(server.IsMessageComplete); Assert.Equal(msg1.Length, len1); Assert.Equal(msg1, received1); int len2 = server.Read(received2, 0, msg2.Length); Assert.True(server.IsMessageComplete); Assert.Equal(msg2.Length, len2); Assert.Equal(msg2, received2); int expectedRead = msg1.Length - 1; int len3 = server.Read(received3, 0, expectedRead); // read one less than message Assert.False(server.IsMessageComplete); Assert.Equal(expectedRead, len3); for (int i = 0; i < expectedRead; ++i) { Assert.Equal(msg1[i], received3[i]); } expectedRead = msg1.Length - expectedRead; Assert.Equal(expectedRead, server.Read(received3, len3, expectedRead)); Assert.True(server.IsMessageComplete); Assert.Equal(msg1, received3); Assert.Equal(msg1.Length, await server.ReadAsync(received4, 0, msg1.Length)); Assert.True(server.IsMessageComplete); Assert.Equal(msg1, received4); Assert.Equal(msg2.Length, await server.ReadAsync(received5, 0, msg2.Length)); Assert.True(server.IsMessageComplete); Assert.Equal(msg2, received5); expectedRead = msg1.Length - 1; Assert.Equal(expectedRead, await server.ReadAsync(received6, 0, expectedRead)); // read one less than message Assert.False(server.IsMessageComplete); for (int i = 0; i < expectedRead; ++i) { Assert.Equal(msg1[i], received6[i]); } expectedRead = msg1.Length - expectedRead; Assert.Equal(expectedRead, await server.ReadAsync(received6, msg1.Length - expectedRead, expectedRead)); Assert.True(server.IsMessageComplete); Assert.Equal(msg1, received6); await clientTask; } } }
public static void Windows_BufferSizeRoundtripping() { int desiredBufferSize = 10; string pipeName = GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, desiredBufferSize, desiredBufferSize)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.In)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); Assert.Equal(desiredBufferSize, server.OutBufferSize); Assert.Equal(desiredBufferSize, client.InBufferSize); } using (var server = new NamedPipeServerStream(pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, desiredBufferSize, desiredBufferSize)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.Out)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); Assert.Equal(desiredBufferSize, server.InBufferSize); Assert.Equal(0, client.OutBufferSize); } }
public void Unix_SetReadModeTo__PipeTransmissionModeByte() { string pipeName = GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.Out)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); server.ReadMode = PipeTransmissionMode.Byte; client.ReadMode = PipeTransmissionMode.Byte; } using (var server = new NamedPipeServerStream(pipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.In)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); client.ReadMode = PipeTransmissionMode.Byte; server.ReadMode = PipeTransmissionMode.Byte; } using (var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); server.ReadMode = PipeTransmissionMode.Byte; client.ReadMode = PipeTransmissionMode.Byte; } }
public static void Unix_GetHandleOfNewServerStream_Throws_InvalidOperationException() { var pipe = new NamedPipeServerStream(GetUniquePipeName(), PipeDirection.Out, 1, PipeTransmissionMode.Byte); Assert.Throws<InvalidOperationException>(() => pipe.SafePipeHandle); }
public static void OSX_BufferSizeNotSupported() { int desiredBufferSize = 10; string pipeName = GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, desiredBufferSize, desiredBufferSize)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.Out)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); Assert.Throws<PlatformNotSupportedException>(() => server.InBufferSize); Assert.Throws<PlatformNotSupportedException>(() => client.OutBufferSize); } }
private void StartNewPipeServer() { _pipeServer = new NamedPipeServerStream(PipeName, PipeDirection.In, 254, PipeTransmissionMode.Message, PipeOptions.Asynchronous); _pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, null); }
public override void Start() { try { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { PipeSecurity pipeSecurity = new PipeSecurity(); WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); if (principal.IsInRole(WindowsBuiltInRole.Administrator)) { // Allow the Administrators group full access to the pipe. pipeSecurity.AddAccessRule(new PipeAccessRule( new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).Translate(typeof(NTAccount)), PipeAccessRights.FullControl, AccessControlType.Allow)); } else { // Allow the current user read/write access to the pipe. pipeSecurity.AddAccessRule(new PipeAccessRule( WindowsIdentity.GetCurrent().User, PipeAccessRights.ReadWrite, AccessControlType.Allow)); } // Unfortunately, .NET Core does not support passing in a PipeSecurity object into the constructor for // NamedPipeServerStream so we are creating native Named Pipes and securing them using native APIs. The // issue on .NET Core regarding Named Pipe security is here: https://github.com/dotnet/corefx/issues/30170 // 99% of this code was borrowed from PowerShell here: // https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/engine/remoting/common/RemoteSessionNamedPipe.cs#L124-L256 this.inOutPipeServer = NamedPipeNative.CreateNamedPipe(inOutPipeName, pipeSecurity); if (this.outPipeName != null) { this.outPipeServer = NamedPipeNative.CreateNamedPipe(outPipeName, pipeSecurity); } } else { // This handles the Unix case since PipeSecurity is not supported on Unix. // Instead, we use chmod in Start-EditorServices.ps1 this.inOutPipeServer = new NamedPipeServerStream( pipeName: inOutPipeName, direction: PipeDirection.InOut, maxNumberOfServerInstances: 1, transmissionMode: PipeTransmissionMode.Byte, options: PipeOptions.Asynchronous); if (this.outPipeName != null) { this.outPipeServer = new NamedPipeServerStream( pipeName: outPipeName, direction: PipeDirection.Out, maxNumberOfServerInstances: 1, transmissionMode: PipeTransmissionMode.Byte, options: PipeOptions.None); } } ListenForConnection(); } catch (IOException e) { this.logger.Write( LogLevel.Verbose, "Named pipe server failed to start due to exception:\r\n\r\n" + e.Message); throw e; } }
/// <summary> /// Creates a new instance of <see cref="FFmpegWriter"/>. /// </summary> public FFmpegWriter(FFmpegVideoWriterArgs args) { var settings = ServiceProvider.Get <FFmpegSettings>(); _videoBuffer = new byte[args.ImageProvider.Width * args.ImageProvider.Height * 4]; Console.WriteLine($"Video Buffer Allocated: {_videoBuffer.Length}"); var videoPipeName = GetPipeName(); var argsBuilder = new FFmpegArgsBuilder(); argsBuilder.AddInputPipe(videoPipeName) .AddArg("-thread_queue_size 512") .AddArg($"-framerate {args.FrameRate}") .SetFormat("rawvideo") .AddArg("-pix_fmt rgb32") .SetVideoSize(args.ImageProvider.Width, args.ImageProvider.Height); var output = argsBuilder.AddOutputFile(args.FileName) .AddArg(args.VideoArgsProvider(args.VideoQuality)) .SetFrameRate(args.FrameRate); if (settings.Resize) { var width = settings.ResizeWidth; var height = settings.ResizeHeight; if (width % 2 == 1) { ++width; } if (height % 2 == 1) { ++height; } output.AddArg($"-vf scale={width}:{height}"); } if (args.AudioProvider != null) { var audioPipeName = GetPipeName(); argsBuilder.AddInputPipe(audioPipeName) .AddArg("-thread_queue_size 512") .SetFormat("s16le") .SetAudioCodec("pcm_s16le") .SetAudioFrequency(args.Frequency) .SetAudioChannels(args.Channels); output.AddArg(args.AudioArgsProvider(args.AudioQuality)); // UpdatePeriod * Frequency * (Bytes per Second) * Channels * 2 var audioBufferSize = (int)((1000.0 / args.FrameRate) * 44.1 * 2 * 2 * 2); _audioPipe = new NamedPipeServerStream(audioPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, audioBufferSize); } _ffmpegIn = new NamedPipeServerStream(videoPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, _videoBuffer.Length); output.AddArg(args.OutputArgs); _ffmpegProcess = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), args.FileName); }
private void ServerThread() { PipeSecurity security = new PipeSecurity(); using (WindowsIdentity myself = WindowsIdentity.GetCurrent()) { try { // Anyone can talk to us LibraryLogging.Debug("Setting PipeAccess R/W for world: {0}", Abstractions.Windows.Security.GetWellknownSID(WellKnownSidType.WorldSid)); security.AddAccessRule(new PipeAccessRule(Abstractions.Windows.Security.GetWellknownSID(WellKnownSidType.WorldSid), PipeAccessRights.ReadWrite, AccessControlType.Allow)); // But only we have full control (including the 'create' right, which allows us to be the server side of this equation) LibraryLogging.Debug("Setting PipeAccess FullControl for myself: {0}", WindowsIdentity.GetCurrent().Name); security.AddAccessRule(new PipeAccessRule(WindowsIdentity.GetCurrent().Owner, PipeAccessRights.FullControl, AccessControlType.Allow)); } catch (Exception e) { LibraryLogging.Error("Unable to set all pipe access rules, the security of the pGina service pipe is in an unknown state!: {0}", e); } } while (Running) { try { using (NamedPipeServerStream pipeServer = new NamedPipeServerStream(Name, PipeDirection.InOut, MaxClients, PipeTransmissionMode.Byte, PipeOptions.WriteThrough, 0, 0, security, HandleInheritability.None)) { try { pipeServer.WaitForConnection(); } catch (Exception e) { LibraryLogging.Error("Error in server connection handler: {0}", e); continue; } // Handle this connection, note that we always expect client to initiate the // flow of messages, so we do not include an initial message using (BinaryReader reader = new BinaryReader(pipeServer, Encoding.Unicode /*, true*/)) { using (BinaryWriter writer = new BinaryWriter(pipeServer, Encoding.Unicode /*, true*/)) { HandlePipeConnection(reader, writer, null); } } } } catch (Exception e) { LibraryLogging.Error("Error while trying to open pipe server: {0}", e); if (Running) { dynamic s_settings = new Abstractions.Settings.DynamicSettings(); Abstractions.Windows.Networking.sendMail(s_settings.GetSettings(new string[] { "notify_pass" }), "", "", String.Format("pGina: PipeServer error {0}", Environment.MachineName), e.ToString()); } } } }
public InterComServer(string pipeName) : base(null) { _PipeName = pipeName; // Nur für übertragung der IP und Port für die interne Plugin-Kommunikation. _MainPipe = new NamedPipeServerStream(_PipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); Random rnd = new Random(); byte[] ipData = new byte[4]; int port = 0; int retry = 0; _AuthToken = (ulong)(rnd.Next(int.MinValue, int.MaxValue) << 32) | (ulong)rnd.Next(int.MinValue, int.MaxValue); _OpenConns = new List <InterComEndPoint>(); _IsRunning = true; while (true) { try { rnd.NextBytes(ipData); port = rnd.Next(32000, 65000); ipData[0] = 127; // soll eine Local IP im bereich 127.0.0.0/8 sein. //ipData[1] = 0; // soll eine Local IP im bereich 127.0.0.0/8 sein. //ipData[2] = 0; // soll eine Local IP im bereich 127.0.0.0/8 sein. //ipData[3] = 1; // soll eine Local IP im bereich 127.0.0.0/8 sein. IPAddress addr = new IPAddress(ipData); _IpEp = new IPEndPoint(addr, port); _IcSckt.Bind(_IpEp); _IcSckt.Listen(32); using (MemoryStream ms = new MemoryStream()) using (BinaryWriter w = new BinaryWriter(ms)) { w.Write(_IpEp.Address.GetAddressBytes()); w.Write(_IpEp.Port); w.Write(_AuthToken); w.Flush(); _PipeData = ms.ToArray(); } _TListener = new Thread(Listener); _TListener.Start(); break; } catch (Exception ex) { if (retry++ > 25) { throw ex; } } } _MainPipe.BeginWaitForConnection(PipeConnect, null); }
private void TaskLoop() { NamedPipeServerStream server = null; try { server = NewServer(); if (Started != null) { Started(this, EventArgs.Empty); } while (true) { if (CancellationTokenSource.IsCancellationRequested) { server.Dispose(); server = null; break; } server.WaitForConnection(); StreamReader reader = new StreamReader(server); StreamWriter writer = new StreamWriter(server); try { while (true) { if (Connected != null) { Connected(this, new Tuple <StreamReader, StreamWriter>(reader, writer)); } if (!server.IsConnected) { server.Dispose(); server = null; break; } server.WaitForPipeDrain(); } } catch (IOException ee) { if (server != null) { server.Dispose(); server = null; } Console.WriteLine(ee.ToString()); } if (CancellationTokenSource.IsCancellationRequested) { if (server != null) { server.Dispose(); server = null; } break; } server = NewServer(); } if (Stopped != null) { Stopped(this, EventArgs.Empty); } } catch (ThreadAbortException ee) { } catch (Exception ee) { if (ErrorOccurred != null) { ErrorOccurred(this, ee); } } }
/// <summary> /// This method handles the asynchronous message pump. It waits for messages to show up on the queue /// and calls FireDataAvailable for each such packet. It will terminate when the terminate event is /// set. /// </summary> private void PacketPumpProc() { #if FEATURE_NAMED_PIPES_FULL_DUPLEX NamedPipeServerStream localPipeServer = _pipeServer; PipeStream localWritePipe = _pipeServer; PipeStream localReadPipe = _pipeServer; #else PipeStream localWritePipe = _pipeClientToServer; PipeStream localReadPipe = _pipeServerToClient; #endif AutoResetEvent localPacketAvailable = _packetAvailable; AutoResetEvent localTerminatePacketPump = _terminatePacketPump; ConcurrentQueue <INodePacket> localPacketQueue = _packetQueue; DateTime originalWaitStartTime = DateTime.UtcNow; bool gotValidConnection = false; while (!gotValidConnection) { DateTime restartWaitTime = DateTime.UtcNow; // We only wait to wait the difference between now and the last original start time, in case we have multiple hosts attempting // to attach. This prevents each attempt from resetting the timer. TimeSpan usedWaitTime = restartWaitTime - originalWaitStartTime; int waitTimeRemaining = Math.Max(0, CommunicationsUtilities.NodeConnectionTimeout - (int)usedWaitTime.TotalMilliseconds); try { #if FEATURE_NAMED_PIPES_FULL_DUPLEX // Wait for a connection #if FEATURE_APM IAsyncResult resultForConnection = localPipeServer.BeginWaitForConnection(null, null); #else Task connectionTask = localPipeServer.WaitForConnectionAsync(); #endif CommunicationsUtilities.Trace("Waiting for connection {0} ms...", waitTimeRemaining); #if FEATURE_APM bool connected = resultForConnection.AsyncWaitHandle.WaitOne(waitTimeRemaining, false); #else bool connected = connectionTask.Wait(waitTimeRemaining); #endif if (!connected) { CommunicationsUtilities.Trace("Connection timed out waiting a host to contact us. Exiting comm thread."); ChangeLinkStatus(LinkStatus.ConnectionFailed); return; } CommunicationsUtilities.Trace("Parent started connecting. Reading handshake from parent"); #if FEATURE_APM localPipeServer.EndWaitForConnection(resultForConnection); #endif #endif // The handshake protocol is a simple long exchange. The host sends us a long, and we // respond with another long. Once the handshake is complete, both sides can be assured the // other is ready to accept data. // To avoid mixing client and server builds, the long is the MSBuild binary timestamp. // Compatibility issue here. // Previous builds of MSBuild 4.0 would exchange just a byte. // Host would send either 0x5F or 0x60 depending on whether it was the toolset or not respectively. // Client would return either 0xF5 or 0x06 respectively. // Therefore an old host on a machine with new clients running will hang, // sending a byte and waiting for a byte until it eventually times out; // because the new client will want 7 more bytes before it returns anything. // The other way around is not a problem, because the old client would immediately return the (wrong) // byte on receiving the first byte of the long sent by the new host, and the new host would disconnect. // To avoid the hang, special case here: // Make sure our handshakes always start with 00. // If we received ONLY one byte AND it's 0x5F or 0x60, return 0xFF (it doesn't matter what as long as // it will cause the host to reject us; new hosts expect 00 and old hosts expect F5 or 06). try { long handshake = localReadPipe.ReadLongForHandshake(/* reject these leads */ new byte[] { 0x5F, 0x60 }, 0xFF /* this will disconnect the host; it expects leading 00 or F5 or 06 */); #if FEATURE_SECURITY_PERMISSIONS WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent(); string remoteUserName = localPipeServer.GetImpersonationUserName(); #endif if (handshake != GetHostHandshake()) { CommunicationsUtilities.Trace("Handshake failed. Received {0} from host not {1}. Probably the host is a different MSBuild build.", handshake, GetHostHandshake()); #if FEATURE_NAMED_PIPES_FULL_DUPLEX localPipeServer.Disconnect(); #else localWritePipe.Dispose(); localReadPipe.Dispose(); #endif continue; } #if FEATURE_SECURITY_PERMISSIONS // We will only talk to a host that was started by the same user as us. Even though the pipe access is set to only allow this user, we want to ensure they // haven't attempted to change those permissions out from under us. This ensures that the only way they can truly gain access is to be impersonating the // user we were started by. WindowsIdentity clientIdentity = null; localPipeServer.RunAsClient(delegate() { clientIdentity = WindowsIdentity.GetCurrent(true); }); if (clientIdentity == null || !String.Equals(clientIdentity.Name, currentIdentity.Name, StringComparison.OrdinalIgnoreCase)) { CommunicationsUtilities.Trace("Handshake failed. Host user is {0} but we were created by {1}.", (clientIdentity == null) ? "<unknown>" : clientIdentity.Name, currentIdentity.Name); localPipeServer.Disconnect(); continue; } #endif } catch (IOException #if FEATURE_NAMED_PIPES_FULL_DUPLEX e #endif ) { // We will get here when: // 1. The host (OOP main node) connects to us, it immediately checks for user privileges // and if they don't match it disconnects immediately leaving us still trying to read the blank handshake // 2. The host is too old sending us bits we automatically reject in the handshake #if FEATURE_NAMED_PIPES_FULL_DUPLEX CommunicationsUtilities.Trace("Client connection failed but we will wait for another connection. Exception: {0}", e.Message); if (localPipeServer.IsConnected) { localPipeServer.Disconnect(); } continue; #else throw; #endif } gotValidConnection = true; } catch (Exception e) { if (ExceptionHandling.IsCriticalException(e)) { throw; } CommunicationsUtilities.Trace("Client connection failed. Exiting comm thread. {0}", e); #if FEATURE_NAMED_PIPES_FULL_DUPLEX if (localPipeServer.IsConnected) { localPipeServer.Disconnect(); } #else localWritePipe.Dispose(); localReadPipe.Dispose(); #endif ExceptionHandling.DumpExceptionToFile(e); ChangeLinkStatus(LinkStatus.Failed); return; } } CommunicationsUtilities.Trace("Writing handshake to parent"); localWritePipe.WriteLongForHandshake(GetClientHandshake()); ChangeLinkStatus(LinkStatus.Active); RunReadLoop( new BufferedReadStream(localReadPipe), localWritePipe, localPacketQueue, localPacketAvailable, localTerminatePacketPump); CommunicationsUtilities.Trace("Ending read loop"); try { #if FEATURE_NAMED_PIPES_FULL_DUPLEX if (localPipeServer.IsConnected) { localPipeServer.WaitForPipeDrain(); localPipeServer.Disconnect(); } #else localReadPipe.Dispose(); localWritePipe.WaitForPipeDrain(); localWritePipe.Dispose(); #endif } catch (Exception) { // We don't really care if Disconnect somehow fails, but it gives us a chance to do the right thing. } }
private static void ProcessConnection(NamedPipeServerStream stream) { Console.WriteLine("Connection established processing"); ProcessConnectionCore(stream); Console.WriteLine("Connection completed"); }
private void toggleGlobalHook_CheckedChanged(object sender, EventArgs e) { if (!toggleGlobalHook.Enabled) { return; } toggleGlobalHook.Enabled = false; if (toggleGlobalHook.Checked) { if (!Helpers.IsElevated) { DialogResult res = MessageBox.Show("RenderDoc needs to restart with admin privileges. Restart?", "Restart as admin", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (res == DialogResult.Yes) { string capfile = Path.GetTempFileName() + ".cap"; AutoStart.Checked = false; SaveSettings(capfile); var process = new Process(); process.StartInfo = new System.Diagnostics.ProcessStartInfo(Application.ExecutablePath, capfile); process.StartInfo.Verb = "runas"; try { process.Start(); } catch (Exception) { // don't restart if it failed for some reason (e.g. user clicked no to UAC) toggleGlobalHook.Checked = false; toggleGlobalHook.Enabled = true; return; } m_Core.Config.Serialize(Core.ConfigFilename); m_Core.Config.ReadOnly = true; m_Core.AppWindow.Close(); return; } else { toggleGlobalHook.Checked = false; toggleGlobalHook.Enabled = true; return; } } exePath.Enabled = exeBrowse.Enabled = workDirPath.Enabled = workDirBrowse.Enabled = cmdline.Enabled = capture.Enabled = save.Enabled = load.Enabled = false; foreach (Control c in capOptsFlow.Controls) { c.Enabled = false; } foreach (Control c in actionsFlow.Controls) { c.Enabled = false; } toggleGlobalHook.Text = "Disable Global Hook"; var path = Path.GetDirectoryName(Path.GetFullPath(Application.ExecutablePath)); var regfile = Path.Combine(Path.GetTempPath(), "RenderDoc_RestoreGlobalHook.reg"); try { if (Environment.Is64BitProcess) { EnableAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE").CreateSubKey("Wow6432Node"), path, "x86\\renderdocshim32.dll", out prevAppInitWoW64Enabled, out prevAppInitWoW64); EnableAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), path, "renderdocshim64.dll", out prevAppInitEnabled, out prevAppInit); using (FileStream s = File.OpenWrite(regfile)) { using (StreamWriter sw = new StreamWriter(s)) { sw.WriteLine("Windows Registry Editor Version 5.00"); sw.WriteLine(""); sw.WriteLine("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\Windows]"); sw.WriteLine(String.Format("\"LoadAppInit_DLLs\"=dword:{0:X8}", prevAppInitWoW64Enabled)); sw.WriteLine(String.Format("\"AppInit_DLLs\"=\"{0}\"", prevAppInitWoW64)); sw.WriteLine(""); sw.WriteLine("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows]"); sw.WriteLine(String.Format("\"LoadAppInit_DLLs\"=dword:{0:X8}", prevAppInitEnabled)); sw.WriteLine(String.Format("\"AppInit_DLLs\"=\"{0}\"", prevAppInit)); sw.Flush(); } } } else { // if this is a 64-bit OS, it will re-direct our request to Wow6432Node anyway, so we // don't need to handle that manually EnableAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), path, "renderdocshim32.dll", out prevAppInitEnabled, out prevAppInit); using (FileStream s = File.OpenWrite(regfile)) { using (StreamWriter sw = new StreamWriter(s)) { sw.WriteLine("Windows Registry Editor Version 5.00"); sw.WriteLine(""); sw.WriteLine("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows]"); sw.WriteLine(String.Format("\"LoadAppInit_DLLs\"=dword:{0:X8}", prevAppInitEnabled)); sw.WriteLine(String.Format("\"AppInit_DLLs\"=\"{0}\"", prevAppInit)); sw.Flush(); } } } } catch (System.Exception ex) { MessageBox.Show("Aborting. Couldn't save backup .reg file to " + regfile + Environment.NewLine + ex.ToString(), "Cannot save registry backup", MessageBoxButtons.OK, MessageBoxIcon.Error); exePath.Enabled = exeBrowse.Enabled = workDirPath.Enabled = workDirBrowse.Enabled = cmdline.Enabled = capture.Enabled = save.Enabled = load.Enabled = true; foreach (Control c in capOptsFlow.Controls) { c.Enabled = true; } foreach (Control c in actionsFlow.Controls) { c.Enabled = true; } // won't recurse because it's not enabled yet toggleGlobalHook.Checked = false; toggleGlobalHook.Text = "Enable Global Hook"; toggleGlobalHook.Enabled = true; return; } ExitPipeThread(); pipeExit = false; try { pipe32 = new NamedPipeServerStream("RenderDoc.GlobalHookControl32"); pipe64 = new NamedPipeServerStream("RenderDoc.GlobalHookControl64"); } catch (System.IO.IOException ex) { // tidy up and exit MessageBox.Show("Aborting. Couldn't create named pipe:" + Environment.NewLine + ex.Message, "Cannot create named pipe", MessageBoxButtons.OK, MessageBoxIcon.Error); exePath.Enabled = exeBrowse.Enabled = workDirPath.Enabled = workDirBrowse.Enabled = cmdline.Enabled = capture.Enabled = save.Enabled = load.Enabled = true; foreach (Control c in capOptsFlow.Controls) { c.Enabled = true; } foreach (Control c in actionsFlow.Controls) { c.Enabled = true; } // need to revert registry entries too if (Environment.Is64BitProcess) { RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE").CreateSubKey("Wow6432Node"), prevAppInitWoW64Enabled, prevAppInitWoW64); RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), prevAppInitEnabled, prevAppInit); } else { // if this is a 64-bit OS, it will re-direct our request to Wow6432Node anyway, so we // don't need to handle that manually RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), prevAppInitEnabled, prevAppInit); } if (File.Exists(regfile)) { File.Delete(regfile); } // won't recurse because it's not enabled yet toggleGlobalHook.Checked = false; toggleGlobalHook.Text = "Enable Global Hook"; toggleGlobalHook.Enabled = true; return; } pipeThread = Helpers.NewThread(new ThreadStart(PipeTick)); pipeThread.Start(); string exe = exePath.Text; string logfile = exe; if (logfile.Contains("/")) { logfile = logfile.Substring(logfile.LastIndexOf('/') + 1); } if (logfile.Contains("\\")) { logfile = logfile.Substring(logfile.LastIndexOf('\\') + 1); } if (logfile.Contains(".")) { logfile = logfile.Substring(0, logfile.IndexOf('.')); } logfile = m_Core.TempLogFilename(logfile); StaticExports.StartGlobalHook(exe, logfile, GetSettings().Options); } else { ExitPipeThread(); exePath.Enabled = exeBrowse.Enabled = workDirPath.Enabled = workDirBrowse.Enabled = cmdline.Enabled = capture.Enabled = save.Enabled = load.Enabled = true; foreach (Control c in capOptsFlow.Controls) { c.Enabled = true; } foreach (Control c in actionsFlow.Controls) { c.Enabled = true; } toggleGlobalHook.Text = "Enable Global Hook"; if (Environment.Is64BitProcess) { RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE").CreateSubKey("Wow6432Node"), prevAppInitWoW64Enabled, prevAppInitWoW64); RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), prevAppInitEnabled, prevAppInit); } else { // if this is a 64-bit OS, it will re-direct our request to Wow6432Node anyway, so we // don't need to handle that manually RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), prevAppInitEnabled, prevAppInit); } var regfile = Path.Combine(Path.GetTempPath(), "RenderDoc_RestoreGlobalHook.reg"); if (File.Exists(regfile)) { File.Delete(regfile); } } toggleGlobalHook.Enabled = true; UpdateGlobalHook(); }
/// <summary> /// Creates a new instance of <see cref="FFmpegWriter"/>. /// </summary> public FFmpegWriter(FFmpegVideoWriterArgs Args) { if (!FFmpegService.FFmpegExists) { throw new FFmpegNotFoundException(); } var nv12 = Args.ImageProvider.DummyFrame is INV12Frame; var settings = ServiceProvider.Get <FFmpegSettings>(); var w = Args.ImageProvider.Width; var h = Args.ImageProvider.Height; _videoBuffer = new byte[(int)(w * h * (nv12 ? 1.5 : 4))]; Console.WriteLine($"Video Buffer Allocated: {_videoBuffer.Length}"); var videoPipeName = GetPipeName(); var argsBuilder = new FFmpegArgsBuilder(); argsBuilder.AddInputPipe(videoPipeName) .AddArg("thread_queue_size", 512) .AddArg("framerate", Args.FrameRate) .SetFormat("rawvideo") .AddArg("pix_fmt", nv12 ? "nv12" : "rgb32") .SetVideoSize(w, h); var output = argsBuilder.AddOutputFile(Args.FileName) .SetFrameRate(Args.FrameRate); Args.VideoCodec.Apply(settings, Args, output); if (settings.Resize) { var width = settings.ResizeWidth; var height = settings.ResizeHeight; if (width % 2 == 1) { ++width; } if (height % 2 == 1) { ++height; } output.AddArg("vf", $"scale={width}:{height}"); } if (Args.AudioProvider != null) { var audioPipeName = GetPipeName(); argsBuilder.AddInputPipe(audioPipeName) .AddArg("thread_queue_size", 512) .SetFormat("s16le") .SetAudioCodec("pcm_s16le") .SetAudioFrequency(Args.Frequency) .SetAudioChannels(Args.Channels); Args.VideoCodec.AudioArgsProvider(Args.AudioQuality, output); // UpdatePeriod * Frequency * (Bytes per Second) * Channels * 2 var audioBufferSize = (int)((1000.0 / Args.FrameRate) * 44.1 * 2 * 2 * 2); _audioPipe = new NamedPipeServerStream(audioPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, audioBufferSize); } _ffmpegIn = new NamedPipeServerStream(videoPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, _videoBuffer.Length); _ffmpegProcess = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), Args.FileName, out _); }
private void background_CommandServer_DoWork(object sender, DoWorkEventArgs e) { if (Thread.CurrentThread.Name == null) { Thread.CurrentThread.Name = "CommandServer"; } NamedPipeServerStream pipeServer = null; try { PipeSecurity pipeSecurity = new PipeSecurity(); pipeSecurity.AddAccessRule(new PipeAccessRule("Everyone", PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow)); pipeServer = new NamedPipeServerStream("pipeBloodSpiderDetectorIn", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.None, 512, 512, pipeSecurity, HandleInheritability.None); //pipeServer = new NamedPipeServerStream("pipeBloodSpiderDetectorIn", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous); pipeServer.WaitForConnection(); StreamString ss = new StreamString(pipeServer); //verify identity ss.WriteString("BloodSpider_Service"); //get command from client var command = ss.ReadString(); var split = command.Split(new string[] { "|" }, StringSplitOptions.None); switch (split[0].ToUpperInvariant().Trim()) { case "VERSION": Version ver = Assembly.GetExecutingAssembly().GetName().Version; ss.WriteString(ver.Major.ToString() + "." + ver.Minor.ToString() + "." + ver.Build.ToString()); break; case "ULD_YES": startReaderThread(); break; case "ULD_PATH_RESP": settings = Common.Statics.ReadSettingsFile(split[1]); if (settings != null && settings.Options != null) { if (settings.Options.Rows.Count > 0 && (bool)settings.Options.Rows[0]["AutoUpload"]) { //auto upload startReaderThread(); } else { //no auto upload, require user input if (Common.Statics.deviceFound != null) { pipeWrite("ULD", "Found Meter", "Would you like to upload data from the " + Common.Statics.deviceFound.DeviceDescription + "?", 1); } } } break; case "CHECK_FOR_UPDATES": pipeWrite("UPDATE_CHECK_FINISHED", CheckForUpdates(), String.Empty, 1); break; case "REPORT_BUG": break; default: break; } ; } catch (Exception ex) { Errors.ServiceError(ex); Detector.ReportException("W0003", ex); } finally { if (pipeServer != null) { pipeServer.Close(); } } }
private async Task RunNamedPipeServer(CancellationToken token) { var pipeSecurity = new PipeSecurity(); pipeSecurity.AddAccessRule( new PipeAccessRule( WindowsIdentity.GetCurrent().Owner, PipeAccessRights.FullControl, AccessControlType.Allow)); while (true) { try { using (var pipe = new NamedPipeServerStream( PipeName, PipeDirection.InOut, 1, // Translates to FILE_FLAG_FIRST_PIPE_INSTANCE PipeTransmissionMode.Message, PipeOptions.None, 0, 0, pipeSecurity)) { await pipe.WaitForConnectionAsync(token).ConfigureAwait(false); // // The server expects: // IN: <int32> number of arguments // IN: <string> argument #n // IN: (repeat...) // OUT: return code // OUT: process ID // using (var reader = new BinaryReader(pipe)) using (var writer = new BinaryWriter(pipe)) { int argsCount = reader.ReadInt32(); var args = new string[argsCount]; for (int i = 0; i < argsCount; i++) { args[i] = reader.ReadString(); } try { int result = HandleSubsequentInvocation(args); writer.Write(result); writer.Write(Process.GetCurrentProcess().Id); } catch (Exception e) { HandleSubsequentInvocationException(e); writer.Write(-1); } } } } catch (TaskCanceledException) { return; } catch (IOException e) { HandleSubsequentInvocationException(e); } } }
public AlexCommunication() { _namedPipeServerStream = new NamedPipeServerStream(GuiDebuggerConstants.NamedPipeName, PipeDirection.InOut); _namedPipeServerStream.BeginWaitForConnection(OnClientConnect, null); }
[PlatformSpecific(PlatformID.Windows)] // NumberOfServerInstances > 1 isn't supported and has undefined behavior on Unix public static void ServerCountOverMaxServerInstances_Throws_IOException() { string uniqueServerName = GetUniquePipeName(); using (NamedPipeServerStream server = new NamedPipeServerStream(uniqueServerName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) { Assert.Throws<IOException>(() => new NamedPipeServerStream(uniqueServerName)); } }
internal WinSSHClient(NamedPipeServerStream pipeServer) { this.pipeServer = pipeServer; }
/// <summary> /// This method handles the asynchronous message pump. It waits for messages to show up on the queue /// and calls FireDataAvailable for each such packet. It will terminate when the terminate event is /// set. /// </summary> private void PacketPumpProc() { NamedPipeServerStream localPipeServer = _pipeServer; AutoResetEvent localPacketAvailable = _packetAvailable; AutoResetEvent localTerminatePacketPump = _terminatePacketPump; ConcurrentQueue<INodePacket> localPacketQueue = _packetQueue; DateTime originalWaitStartTime = DateTime.UtcNow; bool gotValidConnection = false; while (!gotValidConnection) { gotValidConnection = true; DateTime restartWaitTime = DateTime.UtcNow; // We only wait to wait the difference between now and the last original start time, in case we have multiple hosts attempting // to attach. This prevents each attempt from resetting the timer. TimeSpan usedWaitTime = restartWaitTime - originalWaitStartTime; int waitTimeRemaining = Math.Max(0, CommunicationsUtilities.NodeConnectionTimeout - (int)usedWaitTime.TotalMilliseconds); try { // Wait for a connection #if FEATURE_APM IAsyncResult resultForConnection = localPipeServer.BeginWaitForConnection(null, null); CommunicationsUtilities.Trace("Waiting for connection {0} ms...", waitTimeRemaining); bool connected = resultForConnection.AsyncWaitHandle.WaitOne(waitTimeRemaining, false); #else Task connectionTask = localPipeServer.WaitForConnectionAsync(); CommunicationsUtilities.Trace("Waiting for connection {0} ms...", waitTimeRemaining); bool connected = connectionTask.Wait(waitTimeRemaining); #endif if (!connected) { CommunicationsUtilities.Trace("Connection timed out waiting a host to contact us. Exiting comm thread."); ChangeLinkStatus(LinkStatus.ConnectionFailed); return; } CommunicationsUtilities.Trace("Parent started connecting. Reading handshake from parent"); #if FEATURE_APM localPipeServer.EndWaitForConnection(resultForConnection); #endif // The handshake protocol is a series of int exchanges. The host sends us a each component, and we // verify it. Afterwards, the host sends an "End of Handshake" signal, to which we respond in kind. // Once the handshake is complete, both sides can be assured the other is ready to accept data. Handshake handshake = GetHandshake(); try { int[] handshakeComponents = handshake.RetrieveHandshakeComponents(); for (int i = 0; i < handshakeComponents.Length; i++) { int handshakePart = _pipeServer.ReadIntForHandshake(i == 0 ? (byte?)CommunicationsUtilities.handshakeVersion : null /* this will disconnect a < 16.8 host; it expects leading 00 or F5 or 06. 0x00 is a wildcard */ #if NETCOREAPP2_1 || MONO , ClientConnectTimeout /* wait a long time for the handshake from this side */ #endif ); if (handshakePart != handshakeComponents[i]) { CommunicationsUtilities.Trace("Handshake failed. Received {0} from host not {1}. Probably the host is a different MSBuild build.", handshakePart, handshakeComponents[i]); _pipeServer.WriteIntForHandshake(i + 1); gotValidConnection = false; break; } } if (gotValidConnection) { // To ensure that our handshake and theirs have the same number of bytes, receive and send a magic number indicating EOS. #if NETCOREAPP2_1 || MONO _pipeServer.ReadEndOfHandshakeSignal(false, ClientConnectTimeout); /* wait a long time for the handshake from this side */ #else _pipeServer.ReadEndOfHandshakeSignal(false); #endif CommunicationsUtilities.Trace("Successfully connected to parent."); _pipeServer.WriteEndOfHandshakeSignal(); #if FEATURE_SECURITY_PERMISSIONS // We will only talk to a host that was started by the same user as us. Even though the pipe access is set to only allow this user, we want to ensure they // haven't attempted to change those permissions out from under us. This ensures that the only way they can truly gain access is to be impersonating the // user we were started by. WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent(); WindowsIdentity clientIdentity = null; localPipeServer.RunAsClient(delegate () { clientIdentity = WindowsIdentity.GetCurrent(true); }); if (clientIdentity == null || !String.Equals(clientIdentity.Name, currentIdentity.Name, StringComparison.OrdinalIgnoreCase)) { CommunicationsUtilities.Trace("Handshake failed. Host user is {0} but we were created by {1}.", (clientIdentity == null) ? "<unknown>" : clientIdentity.Name, currentIdentity.Name); gotValidConnection = false; continue; } #endif } } catch (IOException e) { // We will get here when: // 1. The host (OOP main node) connects to us, it immediately checks for user privileges // and if they don't match it disconnects immediately leaving us still trying to read the blank handshake // 2. The host is too old sending us bits we automatically reject in the handshake // 3. We expected to read the EndOfHandshake signal, but we received something else CommunicationsUtilities.Trace("Client connection failed but we will wait for another connection. Exception: {0}", e.Message); gotValidConnection = false; } catch (InvalidOperationException) { gotValidConnection = false; } if (!gotValidConnection) { if (localPipeServer.IsConnected) { localPipeServer.Disconnect(); } continue; } ChangeLinkStatus(LinkStatus.Active); } catch (Exception e) { if (ExceptionHandling.IsCriticalException(e)) { throw; } CommunicationsUtilities.Trace("Client connection failed. Exiting comm thread. {0}", e); if (localPipeServer.IsConnected) { localPipeServer.Disconnect(); } ExceptionHandling.DumpExceptionToFile(e); ChangeLinkStatus(LinkStatus.Failed); return; } } RunReadLoop( new BufferedReadStream(_pipeServer), _pipeServer, localPacketQueue, localPacketAvailable, localTerminatePacketPump); CommunicationsUtilities.Trace("Ending read loop"); try { if (localPipeServer.IsConnected) { localPipeServer.WaitForPipeDrain(); localPipeServer.Disconnect(); } } catch (Exception) { // We don't really care if Disconnect somehow fails, but it gives us a chance to do the right thing. } }
public void Pipe_Reader() { int i = 0; // Open the named pipe. var server = new NamedPipeServerStream("Data"); if (this.InvokeRequired) { Engine_Activation_Delegate Engine_Activation = new Engine_Activation_Delegate(this.Engine_Activation); this.Invoke(Engine_Activation); } //Console.WriteLine("Waiting for connection..."); server.WaitForConnection(); //Console.WriteLine("Connected."); var br = new BinaryReader(server); //var bw = new BinaryWriter(server); while (true) { try { i++; var len = (int)br.ReadUInt32(); if (len == 0) { MessageBox.Show("len equals zero"); } var str = new string(br.ReadChars(len)); // Read string if (i == 1) { if (this.InvokeRequired) { this.Invoke((MethodInvoker) delegate { textBox1.Text += str; }); break; } } //if (i == 2) //{ // if (this.InvokeRequired) // { // this.Invoke((MethodInvoker)delegate // { // textBox3.Text += str; // }); // break; // } //} } catch { //MessageBox.Show("Error"); } } Pipe_Writer(server); }
[PlatformSpecific(PlatformID.Windows)] // Unix doesn't currently support message mode public void Windows_SetReadModeTo__PipeTransmissionModeByte() { string pipeName = GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.Out)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); // Throws regardless of connection status for the pipe that is set to PipeDirection.In Assert.Throws<UnauthorizedAccessException>(() => server.ReadMode = PipeTransmissionMode.Byte); client.ReadMode = PipeTransmissionMode.Byte; } using (var server = new NamedPipeServerStream(pipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.In)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); // Throws regardless of connection status for the pipe that is set to PipeDirection.In Assert.Throws<UnauthorizedAccessException>(() => client.ReadMode = PipeTransmissionMode.Byte); server.ReadMode = PipeTransmissionMode.Byte; } using (var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); server.ReadMode = PipeTransmissionMode.Byte; client.ReadMode = PipeTransmissionMode.Byte; } }
private void PipeServerThread() { try { s = new NamedPipeServerStream(PipeDirection.InOut, false, false, sph); s.WaitForConnection(); //sph.Close(); sph = null; } catch { return; } try { while (1 == 1) { int command = s.ReadByte(); switch (command) { case -1: case Commands.EXIT: return; //pipe closed case Commands.TEST: s.WriteByte((byte)(s.ReadByte() ^ 0xce)); break; case Commands.INITMODULELIST: initModuleList(); break; case Commands.GETMETHODENTRYPOINT: getMethodEntryPoint(); break; case Commands.GETMETHODPARAMETERS: getMethodParameters(); break; case Commands.GETFIELDTYPENAME: getFieldTypeName(); break; case Commands.GETFIELDVALUE: getFieldValue(); break; case Commands.SETFIELDVALUE: setFieldValue(); break; case Commands.LOADMODULE: loadModule(); break; case Commands.WRAPOBJECT: wrapObject(); break; case Commands.UNWRAPOBJECT: unwrapObject(); break; case Commands.INVOKEMETHOD: invokeMethod(); break; case Commands.FIND_MODULEID_WITH_CLASSLIST: findModuleIDWithClassList(); break; } } } catch { } finally { s.Close(); } }
public void InvalidReadMode_Throws_ArgumentOutOfRangeException(PipeDirection serverDirection, PipeDirection clientDirection) { string pipeName = GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, serverDirection, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) using (var client = new NamedPipeClientStream(".", pipeName, clientDirection)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); Assert.Throws<ArgumentOutOfRangeException>(() => server.ReadMode = (PipeTransmissionMode)999); Assert.Throws<ArgumentOutOfRangeException>(() => client.ReadMode = (PipeTransmissionMode)999); } }
public void StartServer() { Task.Factory.StartNew(() => { var countSize = Marshal.SizeOf(typeof(CountData)); var priceSize = Marshal.SizeOf(typeof(PriceData)); var positionSize = Marshal.SizeOf(typeof(PositionData)); var operationSize = Marshal.SizeOf(typeof(OperationData)); var positionOrderSize = Marshal.SizeOf(typeof(PositionData)); var inputCount = new byte[countSize]; var inputPrice = new byte[priceSize]; var inputPosition = new byte[positionSize]; var inputOperation = new byte[operationSize]; var inputPositionOrder = new byte[positionOrderSize]; try { using (NamedPipeServerStream serverPipe = new NamedPipeServerStream(_connectionAddress, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) { serverPipe.BeginWaitForConnection(a => { try { serverPipe.EndWaitForConnection(a); } catch (Exception) { _isClosing = true; } }, null); while (_isClosing == false) { if (serverPipe.IsConnected) { // Get price serverPipe.Read(inputPrice, 0, priceSize); var price = Communication.ConvertFrom <PriceData>(inputPrice); Delegation.SetPriceDelegates(price); // Send order serverPipe.Write(Communication.ConvertTo <OrderData>(_order), 0, Marshal.SizeOf(typeof(OrderData))); // Get trade result serverPipe.Read(inputOperation, 0, operationSize); var deal = Communication.ConvertFrom <OperationData>(inputOperation); if (_order.OrderStatus == 1) { Delegation.SetDealDelegates(deal, _order); _order = new OrderData(); _order.OrderStatus = 0; } // Get orders count serverPipe.Read(inputCount, 0, countSize); var posCounters = Communication.ConvertFrom <CountData>(inputCount); // Get order list var posOrders = new List <PositionData>(); for (var i = 0; i < posCounters.OrdersCount; i++) { serverPipe.Read(inputPositionOrder, 0, positionOrderSize); posOrders.Add(Communication.ConvertFrom <PositionData>(inputPositionOrder)); } Delegation.SetPositionOrderDelegates(posOrders); // Get position list var posPositions = new List <PositionData>(); for (var i = 0; i < posCounters.PositionsCount; i++) { serverPipe.Read(inputPosition, 0, positionSize); posPositions.Add(Communication.ConvertFrom <PositionData>(inputPosition)); } Delegation.SetPositionDelegates(posPositions); } } serverPipe.Disconnect(); } } catch (Exception) { _isClosing = true; } Delegation.SetChannelCloseDelegates("No connection"); }); }
public void Unix_MultipleServerDisposal_DoesntDeletePipe() { // Test for when multiple servers are created and linked to the same FIFO. The original ServerStream // that created the FIFO is disposed. The other servers should still be valid and useable. string serverName = GetUniquePipeName(); var server1 = new NamedPipeServerStream(serverName, PipeDirection.In); // Creates the FIFO var server2 = new NamedPipeServerStream(serverName, PipeDirection.In); var client1 = new NamedPipeClientStream(".", serverName, PipeDirection.Out); var client2 = new NamedPipeClientStream(".", serverName, PipeDirection.Out); Task server1Task = server1.WaitForConnectionAsync(); // Opens a handle to the FIFO Task server2Task = server2.WaitForConnectionAsync(); // Opens a handle to the same FIFO as server1 Task client1Task = client1.ConnectAsync(); Task.WaitAll(server1Task, server2Task, client1Task); // client1 connects to server1 AND server2 Assert.True(server1.IsConnected); Assert.True(server2.IsConnected); // Get rid of client1/server1 and make sure server2 isn't connected (so that it can connect to client2) server1.Dispose(); client1.Dispose(); server2.Disconnect(); Assert.False(server2.IsConnected); server2Task = server2.WaitForConnectionAsync(); // Opens a handle to the same FIFO Task client2Task = client2.ConnectAsync(); Task.WaitAll(server2Task, client2Task); // Should not block! Assert.True(server2.IsConnected); }
public static void initServerPipe(String sPipe, String sAES) { NamedPipeServerStream oPipe = new NamedPipeServerStream(sPipe, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Message); Console.WriteLine("\n[?] Pipe open on : " + sPipe); oPipe.WaitForConnection(); Console.WriteLine("\n[>] Client connected"); // -= ECDH Key Exchange =- //----------------------------- ECDiffieHellmanCng server = hCrypto.initECDH(); Console.WriteLine("[+] ECDiffieHellmanCng initialized.."); Console.WriteLine(" |_ Hash Algorithm : " + server.HashAlgorithm); Console.WriteLine(" |_ Public Key : \n" + hPickman.HexDump(server.PublicKey.ToByteArray())); // Encrypt & Send data to client Byte[] bServerPub = hCrypto.toAES(sAES, server.PublicKey.ToByteArray()); oPipe.Write(bServerPub, 0, bServerPub.Length); // Decrypt, Get client public key & derive secret hPickman.ECDH_SHARED_KEY_MAT oSessionKey = new hPickman.ECDH_SHARED_KEY_MAT(); Byte[] bMessage = hPickman.ReadPipeMessage(oPipe); try { oSessionKey = hCrypto.deriveECDH(server, hCrypto.fromAES(sAES, bMessage)); } catch (Exception ex) { Console.WriteLine("\n[!] Failed to decode client public key.."); Console.WriteLine(" |_ " + ex.Message); return; } Console.WriteLine("[+] Received client ECDH public key"); Console.WriteLine(" |_ AES Encrypted Public Key : \n" + hPickman.HexDump(bMessage)); Console.WriteLine("[>] Derived Shared Secret"); Console.WriteLine(hPickman.HexDump(oSessionKey.bDerivedKey)); Console.WriteLine("[>] Derived Shared IV"); Console.WriteLine(hPickman.HexDump(oSessionKey.bIV)); // -= Connection Loop =- //----------------------------- // You can define a connection loop here if you like //while (true) //{ //} // -= Send some text back and forth =- //----------------------------- // Read a client message bMessage = hPickman.ReadPipeMessage(oPipe); Byte[] bsMessage = hCrypto.fromAES(oSessionKey, bMessage); Console.WriteLine("[Client Received] : " + hPickman.UTF32ToString(bsMessage) + "\n"); // Send a server message String sMessage = "You know, there are things that won’t do for Newbury Street—things that are out of place here, and that can’t be conceived here, anyhow. It’s my business to catch the overtones of the soul, and you won’t find those in a parvenu set of artificial streets on made land. Back Bay isn’t Boston—it isn’t anything yet, because it’s had no time to pick up memories and attract local spirits. If there are any ghosts here, they’re the tame ghosts of a salt marsh and a shallow cove; and I want human ghosts—the ghosts of beings highly organised enough to have looked on hell and known the meaning of what they saw."; Console.WriteLine("[Server Sending] : " + sMessage + "\n"); Byte[] bChat = hPickman.StringToUTF32(sMessage); Byte[] bCrypt = hCrypto.toAES(oSessionKey, bChat); oPipe.Write(bCrypt, 0, bCrypt.Length); // Read a client message bMessage = hPickman.ReadPipeMessage(oPipe); bsMessage = hCrypto.fromAES(oSessionKey, bMessage); Console.WriteLine("[Client] : " + hPickman.UTF32ToString(bsMessage) + "\n"); }
[PlatformSpecific(TestPlatforms.Windows)] // Unix currently doesn't support message mode public void Windows_MessagePipeTransmissionMode(PipeOptions serverOptions) { byte[] msg1 = new byte[] { 5, 7, 9, 10 }; byte[] msg2 = new byte[] { 2, 4 }; byte[] received1 = new byte[] { 0, 0, 0, 0 }; byte[] received2 = new byte[] { 0, 0 }; byte[] received3 = new byte[] { 0, 0, 0, 0 }; byte[] received4 = new byte[] { 0, 0, 0, 0 }; byte[] received5 = new byte[] { 0, 0 }; byte[] received6 = new byte[] { 0, 0, 0, 0 }; string pipeName = GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Message, serverOptions)) { using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation)) { server.ReadMode = PipeTransmissionMode.Message; Assert.Equal(PipeTransmissionMode.Message, server.ReadMode); client.Connect(); Task clientTask = Task.Run(() => { client.Write(msg1, 0, msg1.Length); client.Write(msg2, 0, msg2.Length); client.Write(msg1, 0, msg1.Length); client.Write(msg1, 0, msg1.Length); client.Write(msg2, 0, msg2.Length); client.Write(msg1, 0, msg1.Length); int serverCount = client.NumberOfServerInstances; Assert.Equal(1, serverCount); }); Task serverTask = Task.Run(async() => { server.WaitForConnection(); int len1 = server.Read(received1, 0, msg1.Length); Assert.True(server.IsMessageComplete); Assert.Equal(msg1.Length, len1); Assert.Equal(msg1, received1); int len2 = server.Read(received2, 0, msg2.Length); Assert.True(server.IsMessageComplete); Assert.Equal(msg2.Length, len2); Assert.Equal(msg2, received2); int expectedRead = msg1.Length - 1; int len3 = server.Read(received3, 0, expectedRead); // read one less than message Assert.False(server.IsMessageComplete); Assert.Equal(expectedRead, len3); for (int i = 0; i < expectedRead; ++i) { Assert.Equal(msg1[i], received3[i]); } expectedRead = msg1.Length - expectedRead; Assert.Equal(expectedRead, server.Read(received3, len3, expectedRead)); Assert.True(server.IsMessageComplete); Assert.Equal(msg1, received3); Assert.Equal(msg1.Length, await server.ReadAsync(received4, 0, msg1.Length)); Assert.True(server.IsMessageComplete); Assert.Equal(msg1, received4); Assert.Equal(msg2.Length, await server.ReadAsync(received5, 0, msg2.Length)); Assert.True(server.IsMessageComplete); Assert.Equal(msg2, received5); expectedRead = msg1.Length - 1; Assert.Equal(expectedRead, await server.ReadAsync(received6, 0, expectedRead)); // read one less than message Assert.False(server.IsMessageComplete); for (int i = 0; i < expectedRead; ++i) { Assert.Equal(msg1[i], received6[i]); } expectedRead = msg1.Length - expectedRead; Assert.Equal(expectedRead, await server.ReadAsync(received6, msg1.Length - expectedRead, expectedRead)); Assert.True(server.IsMessageComplete); Assert.Equal(msg1, received6); }); Assert.True(Task.WaitAll(new[] { clientTask, serverTask }, TimeSpan.FromSeconds(15))); } } }
private void SendCommand(NamedPipeServerStream pipe, Utility.TaskMsg task) { try { if (task.ModuleTask.Assembly.Length > 2048) { int achunksize = 1024; Utility.TaskMsg ctask = new Utility.TaskMsg { TaskType = task.TaskType, Agentid = task.Agentid, AgentPivot = task.AgentPivot, Chunked = true }; string assembly = task.ModuleTask.Assembly; //Chunnk number int chunks = assembly.Length / achunksize; if (assembly.Length % achunksize != 0) { chunks++; } ctask.ChunkNumber = chunks; Utility.ModuleConfig cmodconf = new Utility.ModuleConfig { Method = task.ModuleTask.Method, Moduleclass = task.ModuleTask.Moduleclass, Parameters = task.ModuleTask.Parameters }; int iter = 0; do { //Console.WriteLine("Sendcommand iter " + iter); int remaining = assembly.Length - (iter * achunksize); if (remaining > achunksize) { remaining = achunksize; } cmodconf.Assembly = assembly.Substring(iter * achunksize, remaining); ctask.ModuleTask = cmodconf; string responsechunkmsg = new JavaScriptSerializer().Serialize(ctask); //Console.WriteLine("Sendcommand responsechunkmsg " + responsechunkmsg); byte[] responsechunkmsgbyte = Encoding.Default.GetBytes(responsechunkmsg); var responsechunk = Encoding.Default.GetBytes(Convert.ToBase64String(responsechunkmsgbyte)); pipe.Write(responsechunk, 0, responsechunk.Length); iter++; }while (chunks > iter); } else { task.Chunked = false; string command_src = new JavaScriptSerializer().Serialize(task); byte[] taskbyte = Encoding.Default.GetBytes(command_src); string taskb64 = Convert.ToBase64String(taskbyte); pipe.Write(Encoding.Default.GetBytes(taskb64), 0, Encoding.Default.GetBytes(taskb64).Length); } Console.WriteLine("End sendcommand"); } catch (Exception e) { Console.WriteLine("Error during sendcommand {0}", e.Message); } }
public override async void Init(ITransportCallback transportCallback, LaunchOptions options, Logger logger, HostWaitLoop waitLoop = null) { LocalLaunchOptions localOptions = options as LocalLaunchOptions; Encoding encNoBom = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); string commandPipeName; string outputPipeName; string pidPipeName; List <string> cmdArgs = new List <string>(); string windowtitle = FormattableString.Invariant($"cppdbg: {Path.GetFileName(options.ExePath)}"); if (PlatformUtilities.IsWindows()) { // Create Windows Named pipes commandPipeName = Utilities.GetMIEngineTemporaryFilename("In"); outputPipeName = Utilities.GetMIEngineTemporaryFilename("Out"); pidPipeName = Utilities.GetMIEngineTemporaryFilename("Pid"); string errorPipeName = Utilities.GetMIEngineTemporaryFilename("Error"); NamedPipeServerStream inputToDebugger = new NamedPipeServerStream(commandPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte); NamedPipeServerStream outputFromDebugger = new NamedPipeServerStream(outputPipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte); NamedPipeServerStream errorFromDebugger = new NamedPipeServerStream(errorPipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte); NamedPipeServerStream pidPipe = new NamedPipeServerStream(pidPipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte); _pidReader = new StreamReader(pidPipe, encNoBom, false, UnixUtilities.StreamBufferSize); string thisModulePath = typeof(RunInTerminalTransport).GetTypeInfo().Assembly.ManifestModule.FullyQualifiedName; string launchCommand = Path.Combine(Path.GetDirectoryName(thisModulePath), "WindowsDebugLauncher.exe"); if (!File.Exists(launchCommand)) { string errorMessage = string.Format(CultureInfo.CurrentCulture, MICoreResources.Error_InternalFileMissing, launchCommand); transportCallback.OnStdErrorLine(errorMessage); transportCallback.OnDebuggerProcessExit(null); return; } cmdArgs.Add(launchCommand); cmdArgs.Add("--stdin=" + commandPipeName); cmdArgs.Add("--stdout=" + outputPipeName); cmdArgs.Add("--stderr=" + errorPipeName); cmdArgs.Add("--pid=" + pidPipeName); cmdArgs.Add("--dbgExe=" + localOptions.MIDebuggerPath); cmdArgs.Add(localOptions.GetMiDebuggerArgs()); _waitForConnection = Task.WhenAll( inputToDebugger.WaitForConnectionAsync(), outputFromDebugger.WaitForConnectionAsync(), errorFromDebugger.WaitForConnectionAsync(), pidPipe.WaitForConnectionAsync()); _commandStream = new StreamWriter(inputToDebugger, encNoBom); _outputStream = new StreamReader(outputFromDebugger, encNoBom, false, UnixUtilities.StreamBufferSize); _errorStream = new StreamReader(errorFromDebugger, encNoBom, false, UnixUtilities.StreamBufferSize); } else { // Do Linux style pipes commandPipeName = UnixUtilities.MakeFifo(identifier: "In", logger: logger); outputPipeName = UnixUtilities.MakeFifo(identifier: "Out", logger: logger); pidPipeName = UnixUtilities.MakeFifo(identifier: "Pid", logger: logger); // Create filestreams FileStream stdInStream = new FileStream(commandPipeName, FileMode.Open); FileStream stdOutStream = new FileStream(outputPipeName, FileMode.Open); _pidReader = new StreamReader(new FileStream(pidPipeName, FileMode.Open), encNoBom, false, UnixUtilities.StreamBufferSize); string debuggerCmd = UnixUtilities.GetDebuggerCommand(localOptions); // Default working directory is next to the app string debuggeeDir; if (Path.IsPathRooted(options.ExePath) && File.Exists(options.ExePath)) { debuggeeDir = Path.GetDirectoryName(options.ExePath); } else { // If we don't know where the app is, default to HOME, and if we somehow can't get that, go with the root directory. debuggeeDir = Environment.GetEnvironmentVariable("HOME"); if (string.IsNullOrEmpty(debuggeeDir)) { debuggeeDir = "/"; } } string dbgCmdScript = Path.Combine(Path.GetTempPath(), Utilities.GetMIEngineTemporaryFilename(identifier: "Cmd")); string launchDebuggerCommand = UnixUtilities.LaunchLocalDebuggerCommand( debuggeeDir, commandPipeName, outputPipeName, pidPipeName, dbgCmdScript, debuggerCmd, localOptions.GetMiDebuggerArgs()); logger?.WriteTextBlock("DbgCmd:", launchDebuggerCommand); using (FileStream dbgCmdStream = new FileStream(dbgCmdScript, FileMode.CreateNew)) using (StreamWriter dbgCmdWriter = new StreamWriter(dbgCmdStream, encNoBom) { AutoFlush = true }) { dbgCmdWriter.WriteLine("#!/bin/sh"); dbgCmdWriter.Write(launchDebuggerCommand); dbgCmdWriter.Flush(); } if (PlatformUtilities.IsOSX()) { string osxLaunchScript = GetOSXLaunchScript(); // Call osascript with a path to the AppleScript. The apple script takes 2 parameters: a title for the terminal and the launch script. cmdArgs.Add("/usr/bin/osascript"); cmdArgs.Add(osxLaunchScript); cmdArgs.Add(FormattableString.Invariant($"\"{windowtitle}\"")); cmdArgs.Add(FormattableString.Invariant($"sh {dbgCmdScript} ;")); // needs a semicolon because this command is running through the launchscript. } else { cmdArgs.Add("sh"); cmdArgs.Add(dbgCmdScript); } _outputStream = new StreamReader(stdOutStream, encNoBom, false, UnixUtilities.StreamBufferSize); _commandStream = new StreamWriter(stdInStream, encNoBom); } RunInTerminalLauncher launcher = new RunInTerminalLauncher(windowtitle, localOptions.Environment); launcher.Launch( cmdArgs, localOptions.UseExternalConsole, LaunchSuccess, (error) => { transportCallback.OnStdErrorLine(error); throw new InvalidOperationException(error); }, logger); logger?.WriteLine("Wait for connection completion."); if (_waitForConnection != null) { // Add a timeout for waiting for connection - 20 seconds Task waitOrTimeout = Task.WhenAny(_waitForConnection, Task.Delay(20000)); await waitOrTimeout; if (waitOrTimeout.Status != TaskStatus.RanToCompletion) { string errorMessage = String.Format(CultureInfo.CurrentCulture, MICoreResources.Error_DebuggerInitializeFailed_NoStdErr, "WindowsDebugLauncher.exe"); transportCallback.OnStdErrorLine(errorMessage); transportCallback.OnDebuggerProcessExit(null); return; } } base.Init(transportCallback, options, logger, waitLoop); }
static void Main(string[] args) { ///////////// Commane line options ///////////////////////// if (args.Length == 0) { // generate list of active serial ports string[] names = SerialPort.GetPortNames(); Console.WriteLine("Serial ports:"); foreach (string name in names) { Console.WriteLine(name); } Console.Write("Choose one:"); // read name port (String) port = Console.ReadLine(); } else if (args.Length == 1) { port = args[0]; } else { Console.WriteLine("Usage: wsbridge <portname>"); Console.WriteLine("or leave portname blank for a list of ports."); Environment.Exit(0); } ///////////////// Open serial port ///////////////////////// try { serialPort = new SerialPort(port, 115200, Parity.None, 8, StopBits.One); serialPort.Open(); } catch (Exception e) { // ooops, serial port can't be opened. throw exception, print message, and exit Console.WriteLine("Error opening serial port. Msg = " + e.Message); Environment.Exit(0); } Console.WriteLine("Serial port opened successfully."); ///////////////////// create pipe ///////////////////////// try { wspipe = new NamedPipeServerStream("wireshark", PipeDirection.Out); } catch (Exception e) { Console.WriteLine("Error opening pipe. Msg = " + e.Message); serialPort.Close(); Environment.Exit(0); } ///////////// wait for wireshark to connect to pipe ///////////// Console.WriteLine("Waiting for connection to wireshark."); Console.WriteLine("Open wireshark and connect to interface: Local:\\\\.\\pipe\\wireshark"); wspipe.WaitForConnection(); // block process Console.WriteLine("Client connected."); //////////// connect binary writer to pipe to write binary data into it ////////// ws = new BinaryWriter(wspipe); ///////////// add serial data capture event /////////////////////// // serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived); state = FSM.START_CAPTURE; // set start state ///////////// keep track of time started. this will be used for timestamps //////////// start_time_in_ticks = DateTime.Now.Ticks; //////////// generate header to identify the packet capture //////////////// write_global_hdr(); // run forever /////////////////// initialize module /////////////////////////// Console.WriteLine("Initialize Status:"); closeCAN_Channel(); setupCAN_BitRate('6'); openCAN_Channel(); //Thread.Sleep(milliseconds); //closeCAN_Channel(); //closeCAN_Channel(); //closeCAN_Channel(); //closeCAN_Channel(); //closeCAN_Channel(); //closeCAN_Channel(); // setTimeStamp(true); while (true) { serialPort_DataReceived(); switch (state) { // Read Data case FSM.SUCCESS: CanCommand CAN_Stuct = createStuctFromCommand(); write_frame((uint)CAN_Stuct.lengthData + 8, CAN_Stuct); state = FSM.START_CAPTURE; break; } } }
public static unsafe void Run(string id = "", bool isTask = false) { StreamWriter outputFile; TextWriter stdout = null; if (!isTask) { outputFile = File.CreateText(id + OUTPUT_PATH); outputFile.AutoFlush = true; stdout = Console.Out; Console.SetOut(outputFile); } string mmf_file_path = GetTempPath(id); while (true) { using (var pipe = new NamedPipeServerStream(PIPE_NAME_PREFIX + id, PipeDirection.InOut, 1)) using (var mmf = MemoryMappedFile.CreateFromFile( File.Open(mmf_file_path, FileMode.OpenOrCreate), null, 10000, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false)) using (MemoryMappedViewAccessor view = mmf.CreateViewAccessor()) { byte *mmfPtr = null; view.SafeMemoryMappedViewHandle.AcquirePointer(ref mmfPtr); Console.WriteLine($"Server({id}) started. Waiting for the client....."); pipe.WaitForConnection(); Console.WriteLine("Python client connected!"); try { using (BinaryWriter bw = new BinaryWriter(pipe)) using (BinaryReader br = new BinaryReader(pipe)) { bw.Write(Encoding.Default.GetBytes(mmf_file_path)); while (true) { byte function_id = br.ReadByte(); if (function_id == (byte)FunctionId.Terminate) { CTS.Cancel(); if (!isTask) { Console.SetOut(stdout); } return; } else if (function_id == (byte)FunctionId.NewThread) { //int len = br.ReadInt32(); //string threadId = Encoding.Default.GetString(br.ReadBytes(len)); int threadId = br.ReadInt32(); Console.WriteLine($"New Thread {threadId} is created."); RunningThreads.Add( Task.Factory.StartNew(() => Run(id + threadId, true), CTS.Token)); bw.Write((byte)4); continue; } //Debug.WriteLine($"Function {function_id} is requested"); List <dynamic> arguments = new List <dynamic>(); while (true) { char type = br.ReadChar(); if (type == 'i') { arguments.Add(br.ReadInt32()); } else if (type == 'b') { arguments.Add(br.ReadBoolean()); } else if (type == 's') { int len = br.ReadInt32(); string str = Encoding.Default.GetString(br.ReadBytes(len)); arguments.Add(str); } else if (type == 'o') { var bytes = br.ReadBytes(Option.Size); unsafe { fixed(byte *ptr = bytes) { Option *opPtr = (Option *)ptr; arguments.Add(*opPtr); } } } else if (type == '4') // End of Transmission { break; } else { Console.WriteLine("Undefined value is received: " + type); break; } } try { int size = FunctionTable.CallById((FunctionId)function_id, arguments, in mmfPtr); //Debug.WriteLine($"Server writes a structure of size {size} to mmf"); bw.Write(size); // Send the size of returned structure. } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } } } } catch (IOException e) { Console.WriteLine("ERROR: " + e.Message); Console.WriteLine("Connection closed."); } } } }
public void Pipe_Reader() { // Open the named pipe. var server = new NamedPipeServerStream("Data"); //if (this.InvokeRequired) //{ // Engine_Activation_Delegate Engine_Activation = new Engine_Activation_Delegate(this.Engine_Activation); // this.Invoke(Engine_Activation); //} //Console.WriteLine("Waiting for connection..."); server.WaitForConnection(); //Console.WriteLine("Connected."); var br = new BinaryReader(server); //var bw = new BinaryWriter(server); int i = 0; bool Temp = true; // Checks If The Client Is Already Connected while (true) { try { var len = (int)br.ReadUInt32(); if (len == 0) { MessageBox.Show("len equals zero"); } if (Temp) { var str = new string(br.ReadChars(len)); // Read string if (i == 0) { //if (this.InvokeRequired) //{ // this.Invoke((MethodInvoker)delegate // { // MessageBox.Show(str); // }); //} Temp = false; i++; continue; } } else { var len2 = (int)9; if (len2 == 0) { MessageBox.Show("len equals zero"); } if (!Temp) { var str = new string(br.ReadChars(len)); // Read string if (this.InvokeRequired) { //this.Invoke((MethodInvoker)delegate //{ // MessageBox.Show("I == 1 " + str); //}); } Pipe_Writer(server); } } } catch { //MessageBox.Show("Error"); } } }
// Creates a multi-threaded named pipe server. It keeps the specified number of "free" // instances that are listening for incoming connections. The total number of instances // never exceeds 254, which may or may not be the limit imposed by .NET or Win32 API. // The docs are confusing on this matter. public PipeServer(string name, int freeInstances, Func <Stream, CancellationToken, Task> handler) { const int MaxNamedPipeServerInstances = 254; if (name == null) { throw new ArgumentNullException(nameof(name)); } if (name == "" || name.Contains(':')) { throw new ArgumentException($"Invalid name: {name}"); } if (handler == null) { throw new ArgumentNullException(nameof(handler)); } if (File.Exists(@"\\.\pipe\" + name)) { throw new Exception($"Pipe already exists: {name}"); } if (freeInstances <= 0 || freeInstances > MaxNamedPipeServerInstances) { throw new ArgumentException($"Invalid number of free instances: {freeInstances}"); } var monitor = new object(); int free = 0; int active = 0; Task wake = null; _srv = AcceptLoop(); void Update(Action update) { lock (monitor) { update.Invoke(); if (wake.Status == TaskStatus.Created) { try { wake.Start(); } catch (InvalidOperationException) { Debug.Assert(wake.IsCanceled); } } } } async Task RunServer() { NamedPipeServerStream srv = null; bool connected = false; // NamedPipeServerStream has a nasty bug. It sometimes forgets to unregister from a CancellationToken // after an async operation completes. If we call WaitForConnectionAsync(_cancel.Token) and it fails // to unregister, our call to _cancel.Cancel() in Stop() will trigger the forgotten cancellation handler, // which will attempt to cancel IO that has already competed via a handle that has already been closed. // This will result in an exception flying out of _cancel.Cancel(). We could pass `false` to that Cancel() // call and catch all exceptions, but it will expose us to a memory leak due to the accumulation of // forgotten cancellation handlers. To work around this problem, we create a separate // CancellationTokenSource for every pipe. using (var c = CancellationTokenSource.CreateLinkedTokenSource(_cancel.Token)) { try { // Allow all authenticated users to access the pipe. var security = new PipeSecurity(); security.AddAccessRule( new PipeAccessRule( new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow)); srv = new NamedPipeServerStream( pipeName: name, direction: PipeDirection.InOut, maxNumberOfServerInstances: NamedPipeServerStream.MaxAllowedServerInstances, transmissionMode: PipeTransmissionMode.Byte, options: PipeOptions.Asynchronous | PipeOptions.WriteThrough, inBufferSize: 0, outBufferSize: 0, pipeSecurity: security); await srv.WaitForConnectionAsync(c.Token); connected = true; Update(() => { --free; ++active; }); await handler.Invoke(srv, c.Token); } finally { if (connected) { try { srv.Disconnect(); } catch { } } if (srv != null) { try { srv.Dispose(); } catch { } } Update(() => { if (connected) { --active; } else { --free; } }); } } } async Task AcceptLoop() { try { while (true) { int start; lock (monitor) { Debug.Assert(free >= 0 && free <= freeInstances); Debug.Assert(active >= 0 && free + active <= MaxNamedPipeServerInstances); start = Math.Min(freeInstances - free, MaxNamedPipeServerInstances - free - active); free += start; wake = new Task(delegate { }, _cancel.Token); } Debug.Assert(start >= 0); while (start-- > 0) { Task _ = RunServer(); } await wake; } } catch (Exception e) { bool ok = _cancel.IsCancellationRequested && e is TaskCanceledException; _cancel.Cancel(); while (true) { lock (monitor) { if (free == 0 && active == 0) { break; } wake = new Task(delegate { }); } await wake; } _cancel.Dispose(); if (!ok) { throw; } } } }
public async Task ParseArgumentsAsync(NamedPipeServerStream connection, Dictionary <string, object> message, string arguments) { switch (arguments) { case "Bitlocker": var bitlockerAction = (string)message["action"]; if (bitlockerAction == "Unlock") { var drive = (string)message["drive"]; var password = (string)message["password"]; Win32API.UnlockBitlockerDrive(drive, password); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Bitlocker", "Unlock" } }, message.Get("RequestID", (string)null)); } break; case "SetVolumeLabel": var driveName = (string)message["drivename"]; var newLabel = (string)message["newlabel"]; Win32API.SetVolumeLabel(driveName, newLabel); await Win32API.SendMessageAsync(connection, new ValueSet() { { "SetVolumeLabel", driveName } }, message.Get("RequestID", (string)null)); break; case "GetIconOverlay": var fileIconPath = (string)message["filePath"]; var thumbnailSize = (int)(long)message["thumbnailSize"]; var isOverlayOnly = (bool)message["isOverlayOnly"]; var iconOverlay = Win32API.StartSTATask(() => Win32API.GetFileIconAndOverlay(fileIconPath, thumbnailSize, true, isOverlayOnly)).Result; await Win32API.SendMessageAsync(connection, new ValueSet() { { "Icon", iconOverlay.icon }, { "Overlay", iconOverlay.overlay } }, message.Get("RequestID", (string)null)); break; case "GetIconWithoutOverlay": var fileIconPath2 = (string)message["filePath"]; var thumbnailSize2 = (int)(long)message["thumbnailSize"]; var icon2 = Win32API.StartSTATask(() => Win32API.GetFileIconAndOverlay(fileIconPath2, thumbnailSize2, false)).Result; await Win32API.SendMessageAsync(connection, new ValueSet() { { "Icon", icon2.icon }, }, message.Get("RequestID", (string)null)); break; case "ShellFolder": // Enumerate shell folder contents and send response to UWP var folderPath = (string)message["folder"]; var responseEnum = new ValueSet(); var folderContentsList = await Win32API.StartSTATask(() => { var flc = new List <ShellFileItem>(); try { using (var shellFolder = new ShellFolder(folderPath)) { foreach (var folderItem in shellFolder) { try { var shellFileItem = ShellFolderExtensions.GetShellFileItem(folderItem); flc.Add(shellFileItem); } catch (FileNotFoundException) { // Happens if files are being deleted } finally { folderItem.Dispose(); } } } } catch { } return(flc); }); responseEnum.Add("Enumerate", JsonConvert.SerializeObject(folderContentsList)); await Win32API.SendMessageAsync(connection, responseEnum, message.Get("RequestID", (string)null)); break; case "GetSelectedIconsFromDLL": var selectedIconInfos = Win32API.ExtractSelectedIconsFromDLL((string)message["iconFile"], JsonConvert.DeserializeObject <List <int> >((string)message["iconIndexes"]), Convert.ToInt32(message["requestedIconSize"])); await Win32API.SendMessageAsync(connection, new ValueSet() { { "IconInfos", JsonConvert.SerializeObject(selectedIconInfos) }, }, message.Get("RequestID", (string)null)); break; case "SetAsDefaultExplorer": { var enable = (bool)message["Value"]; var destFolder = Path.Combine(ApplicationData.Current.LocalFolder.Path, "FilesOpenDialog"); Directory.CreateDirectory(destFolder); if (enable) { foreach (var file in Directory.GetFiles(Path.Combine(Package.Current.InstalledPath, "Files.Launcher", "Assets", "FilesOpenDialog"))) { File.Copy(file, Path.Combine(destFolder, Path.GetFileName(file)), true); } } try { using var regProcess = Process.Start("regedit.exe", @$ "/s " "{Path.Combine(destFolder, enable ? " SetFilesAsDefault.reg " : " UnsetFilesAsDefault.reg ")}" ""); regProcess.WaitForExit(); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", true } }, message.Get("RequestID", (string)null)); } catch { // Canceled UAC await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", false } }, message.Get("RequestID", (string)null)); } } break; case "SetAsOpenFileDialog": { var enable = (bool)message["Value"]; var destFolder = Path.Combine(ApplicationData.Current.LocalFolder.Path, "FilesOpenDialog"); Directory.CreateDirectory(destFolder); if (enable) { foreach (var file in Directory.GetFiles(Path.Combine(Package.Current.InstalledPath, "Files.Launcher", "Assets", "FilesOpenDialog"))) { File.Copy(file, Path.Combine(destFolder, Path.GetFileName(file)), true); } } try { using var regProc32 = Process.Start("regsvr32.exe", @$ "/s /n {(!enable ? " / u " : " ")} /i:user " "{Path.Combine(destFolder, " CustomOpenDialog32.dll ")}" ""); regProc32.WaitForExit(); using var regProc64 = Process.Start("regsvr32.exe", @$ "/s /n {(!enable ? " / u " : " ")} /i:user " "{Path.Combine(destFolder, " CustomOpenDialog64.dll ")}" ""); regProc64.WaitForExit(); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", true } }, message.Get("RequestID", (string)null)); } catch { await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", false } }, message.Get("RequestID", (string)null)); } } break; case "GetFileAssociation": { var filePath = (string)message["filepath"]; await Win32API.SendMessageAsync(connection, new ValueSet() { { "FileAssociation", await Win32API.GetFileAssociationAsync(filePath, true) } }, message.Get("RequestID", (string)null)); } break; } }
public static void Windows_CreateFromDisposedServerHandle_Throws_ObjectDisposedException(PipeDirection direction) { // The pipe is closed when we try to make a new Stream with it var pipe = new NamedPipeServerStream(GetUniquePipeName(), direction, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); SafePipeHandle handle = pipe.SafePipeHandle; pipe.Dispose(); Assert.Throws<ObjectDisposedException>(() => new NamedPipeServerStream(direction, true, true, pipe.SafePipeHandle).Dispose()); }
public static void ClientConnectWrongConflictingDirection() { const string serverName1 = "testServer4"; using (NamedPipeServerStream server = new NamedPipeServerStream(serverName1, PipeDirection.Out)) using (NamedPipeClientStream client = new NamedPipeClientStream(".", serverName1, PipeDirection.Out)) { Assert.Throws<UnauthorizedAccessException>(() => client.Connect()); Assert.False(client.IsConnected); } const string serverName2 = "testServer5"; using (NamedPipeServerStream server = new NamedPipeServerStream(serverName2, PipeDirection.In)) using (NamedPipeClientStream client = new NamedPipeClientStream(".", serverName2, PipeDirection.In)) { Assert.Throws<UnauthorizedAccessException>(() => client.Connect()); Assert.False(client.IsConnected); } }
public static void Windows_CreateFromAlreadyBoundHandle_Throws_ArgumentException(PipeDirection direction) { // The pipe is already bound var pipe = new NamedPipeServerStream(GetUniquePipeName(), direction, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); Assert.Throws<ArgumentException>(() => new NamedPipeServerStream(direction, true, true, pipe.SafePipeHandle)); pipe.Dispose(); }
public async Task Unix_GetImpersonationUserName_Succeed() { string pipeName = GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation)) { Task serverTask = server.WaitForConnectionAsync(); client.Connect(); await serverTask; string name = server.GetImpersonationUserName(); Assert.NotNull(name); Assert.False(string.IsNullOrWhiteSpace(name)); } }
[PlatformSpecific(PlatformID.Windows)] // NumberOfServerInstances > 1 isn't supported and has undefined behavior on Unix public static void Windows_ServerCloneWithDifferentDirection_Throws_UnauthorizedAccessException() { string uniqueServerName = GetUniquePipeName(); using (NamedPipeServerStream server = new NamedPipeServerStream(uniqueServerName, PipeDirection.In, 2, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) { Assert.Throws<UnauthorizedAccessException>(() => new NamedPipeServerStream(uniqueServerName, PipeDirection.Out)); } }
public static void Unix_BufferSizeRoundtripping(PipeDirection direction) { int desiredBufferSize = 0; string pipeName = GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, desiredBufferSize, desiredBufferSize)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); desiredBufferSize = server.OutBufferSize * 2; } using (var server = new NamedPipeServerStream(pipeName, direction, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, desiredBufferSize, desiredBufferSize)) using (var client = new NamedPipeClientStream(".", pipeName, direction == PipeDirection.In ? PipeDirection.Out : PipeDirection.In)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); if ((direction & PipeDirection.Out) != 0) { Assert.InRange(server.OutBufferSize, desiredBufferSize, int.MaxValue); } if ((direction & PipeDirection.In) != 0) { Assert.InRange(server.InBufferSize, desiredBufferSize, int.MaxValue); } } }
/* /// <summary> /// Reads configuration and tries to mount every found device. /// </summary> /// <returns>Returns count of mounted SystemDevices, if none returns zero.</returns> private int MountAllDevices() { int mountedPartitions = 0; // this method can't do very much without partitions if (config.EncryptedDiskPartitions.Count <= 0) { LogAppend("WarnNoDisks"); return mountedPartitions; } // walk through every partition in configuration foreach (EncryptedDiskPartition enc_disk_partition in config.EncryptedDiskPartitions) if (MountPartition(enc_disk_partition)) mountedPartitions++; // walk through every container file in configuration foreach (EncryptedContainerFile encContainerFile in config.EncryptedContainerFiles) if (MountContainerFile(encContainerFile)) mountedPartitions++; LogAppend("MountedPartitions", mountedPartitions.ToString()); return mountedPartitions; } /// <summary> /// Mount a specific encrypted partition. /// </summary> /// <param name="encDiskPartition">The encrypted partition to mount.</param> /// <returns>Returns true on successful mount, else false.</returns> private bool MountPartition(EncryptedDiskPartition encDiskPartition) { bool mountSuccess = false; LogAppend("SearchDiskLocal"); // is the partition marked as active? if (!encDiskPartition.IsActive) { // log and skip disk if marked as inactive LogAppend("DiskDriveConfDisabled", encDiskPartition.DiskCaption); return mountSuccess; } else LogAppend("DiskConfEnabled", encDiskPartition.DiskCaption); // find local disk ManagementObject diskPhysical = SystemDevices.GetDiskDriveBySignature(encDiskPartition.DiskCaption, encDiskPartition.DiskSignature); // is the disk online? if not, skip it if (diskPhysical == null) { // disk is offline, log and skip LogAppend("DiskDriveOffline", encDiskPartition.DiskCaption); return mountSuccess; } else LogAppend("DiskIsOnline", diskPhysical["Caption"].ToString()); // get the index of the parent disk uint diskIndex = uint.Parse(diskPhysical["Index"].ToString()); // get the index of this partition ("real" index is zero-based) uint partIndex = encDiskPartition.PartitionIndex - 1; // get original device id from local disk String deviceId = null; try { if (encDiskPartition.PartitionIndex > 0) deviceId = SystemDevices.GetPartitionByIndex(diskIndex, partIndex)["DeviceID"].ToString(); else deviceId = SystemDevices.GetTCCompatibleDiskPath(diskIndex); } catch (NullReferenceException) { LogAppend("ErrVolumeOffline", encDiskPartition.ToString()); return mountSuccess; } LogAppend("DiskDeviceId", deviceId); // convert device id in truecrypt compatible name String tcDevicePath = SystemDevices.GetTCCompatibleName(deviceId); LogAppend("DiskDrivePath", tcDevicePath); // try to mount and return true on success return MountEncryptedMedia(encDiskPartition, tcDevicePath); } /// <summary> /// Mount a specific container file. /// </summary> /// <param name="containerFile">The container file to mount.</param> /// <returns>Returns true on successful mount, else false.</returns> private bool MountContainerFile(EncryptedContainerFile containerFile) { bool mountSuccess = false; LogAppend("SearchConFile"); // skip the file if inactive if (!containerFile.IsActive) { LogAppend("ConConfDisabled", containerFile.FileName); return mountSuccess; } else LogAppend("ConConfEnabled", containerFile.FileName); // check if file exists on local system if (!File.Exists(containerFile.FileName)) { LogAppend("ErrConFileNotExists", containerFile.FileName); return mountSuccess; } else LogAppend("ConFileFound", containerFile.FileName); // try to mount the volume and return true on success return MountEncryptedMedia(containerFile, containerFile.FileName); } */ /// <summary> /// Mounts a specific media. /// </summary> /// <param name="encMedia">The encrypted media to mount.</param> /// <param name="encVolume">The device path or file name to mount.</param> /// <returns>Returns true on successful mount, else false.</returns> private void MountEncryptedMedia(EncryptedMedia encMedia, String encVolume) { String password = string.Empty; bool mountSuccess = false; bool bShowPasswdDlg = false; // if already mounted skip everything if (mountedVolumes.Contains(encMedia)) { throw new AlreadyMountedException(encMedia + " is already mounted."); } // local drive letter must not be assigned! if (SystemDevices.GetLogicalDisk(encMedia.Letter.Letter) != null) { throw new DriveLetterInUseException(); } // prompt password dialog to fetch password from user if (bShowPasswdDlg) { LogAppend("InfoPasswordDialog"); if (pwDlg == null) pwDlg = new PasswordDialog(encMedia.ToString()); else pwDlg.VolumeLabel = encMedia.ToString(); // launch a new password dialog and annoy the user if (pwDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) { LogAppend("PasswordFetchOk"); password = pwDlg.Password; #if DEBUG LogAppend(null, "Password: {0}", password); #endif } else { LogAppend("PasswordDialogCanceled"); return mountSuccess; } } // warn if important CLI flags are missing (probably the users fault) if (string.IsNullOrEmpty(config.TrueCrypt.CommandLineArguments)) LogAppend("WarnTCArgs"); // log what we read LogAppend("TCArgumentLine", config.TrueCrypt.CommandLineArguments); // fill in the attributes we got above String tcArgsReady = config.TrueCrypt.CommandLineArguments + "/l" + encMedia.DriveLetterCurrent + " /v \"" + encVolume + "\"" + " /p \"" + password + "\""; // unset password (it's now in the argument line) password = null; #if DEBUG LogAppend(null, "Full argument line: {0}", tcArgsReady); #endif // add specified mount options to argument line if (!string.IsNullOrEmpty(encMedia.MountOptions)) { LogAppend("AddMountOpts", encMedia.MountOptions); tcArgsReady += " " + encMedia.MountOptions; #if DEBUG LogAppend(null, "Full argument line: {0}", tcArgsReady); #endif } else LogAppend("NoMountOpts"); // add key files if (!string.IsNullOrEmpty(encMedia.KeyFilesArgumentLine)) { LogAppend("AddKeyFiles", encMedia.KeyFiles.Count.ToString()); tcArgsReady += " " + encMedia.KeyFilesArgumentLine; #if DEBUG LogAppend(null, "Full argument line: {0}", tcArgsReady); #endif } else LogAppend("NoKeyFiles"); // if not exists, exit if (string.IsNullOrEmpty(config.TrueCrypt.ExecutablePath)) { // password is in here, so free it tcArgsReady = null; // damn just a few more steps! -.- LogAppend("ErrTCNotFound"); buttonStartWorker.Enabled = false; buttonStopWorker.Enabled = false; LogAppend("CheckCfgTC"); return mountSuccess; } else LogAppend("TCPath", config.TrueCrypt.ExecutablePath); // create new process Process tcLauncher = new Process(); // set exec name tcLauncher.StartInfo.FileName = Configuration.LauncherLocation; // set arguments tcLauncher.StartInfo.Arguments = '"' + config.TrueCrypt.ExecutablePath + "\" " + tcArgsReady; // use CreateProcess() tcLauncher.StartInfo.UseShellExecute = false; #if DEBUG LogAppend(null, "StartInfo.Arguments: {0}", tcLauncher.StartInfo.Arguments); #endif // arr, fire the canon! - well, try it... try { LogAppend("StartProcess"); tcLauncher.Start(); } catch (Win32Exception ex) { // dammit, dammit, dammit! something went wrong at the very end... LogAppend("ErrGeneral", ex.Message); buttonStartWorker.Enabled = false; buttonStopWorker.Enabled = false; LogAppend("CheckTCConf"); return mountSuccess; } LogAppend("ProcessStarted"); // Status LogAppend("WaitDevLaunch"); Cursor.Current = Cursors.WaitCursor; // Wait for incoming message using (NamedPipeServerStream npServer = new NamedPipeServerStream("TrueCryptMessage")) { npServer.WaitForConnection(); using (StreamReader sReader = new StreamReader(npServer, Encoding.Unicode)) { String input = sReader.ReadToEnd(); #if DEBUG LogAppend(null, "Pipe: {0}", input); #endif if (input != "OK") { LogAppend("ErrTrueCryptMsg", input); if (config.TrueCrypt.ShowErrors) { #if DEBUG MessageBox.Show(string.Format(langRes.GetString("MsgTDiskTimeout"), encMedia, input), langRes.GetString("MsgHDiskTimeout"), MessageBoxButtons.OK, MessageBoxIcon.Warning); #endif notifyIconSysTray.BalloonTipTitle = langRes.GetString("MsgHDiskTimeout"); notifyIconSysTray.BalloonTipIcon = ToolTipIcon.Warning; notifyIconSysTray.BalloonTipText = string.Format(langRes.GetString("MsgTDiskTimeout"), encMedia, input); notifyIconSysTray.ShowBalloonTip(config.BalloonTimePeriod); } LogAppend("MountCanceled", encMedia.ToString()); Cursor.Current = Cursors.Default; return mountSuccess; } else LogAppend("InfoLauncherOk"); } } Cursor.Current = Cursors.Default; LogAppend("LogicalDiskOnline", encMedia.DriveLetterCurrent); // mount was successful mountSuccess = true; // display balloon tip on successful mount MountBalloonTip(encMedia); // if set, open device content in windows explorer if (encMedia.OpenExplorer) { LogAppend("OpenExplorer", encMedia.DriveLetterCurrent); try { Process.Start("explorer.exe", encMedia.DriveLetterCurrent + @":\"); } catch (Exception eex) { // error in windows explorer (what a surprise) LogAppend("ErrGeneral", eex.Message); LogAppend("ErrExplorerOpen"); } } // add the current mounted media to the dismount sys tray list AddMountedMedia(encMedia); return mountSuccess; }
public static bool StartListening() { if (connected) { return(false); //only one connection... } if (Application.RunningOnExtender) { Logger.ReportInfo("Running on an extender. Not starting client listener."); return(true); //no comms for extenders } NamedPipeServerStream pipe; try { pipe = new NamedPipeServerStream(Kernel.MBCLIENT_MUTEX_ID); } catch (IOException) { Logger.ReportInfo("Client listener already going - activating that instance of MB..."); //already started - must be another instance of MB Core - tell it to come to front string entryPoint = EntryPointResolver.EntryPointPath; if (string.IsNullOrEmpty(entryPoint)) { SendCommandToCore("activate"); } else //nav to the proper entrypoint { Logger.ReportInfo("Navigating current instance to entrypoint " + entryPoint); SendCommandToCore("activateentrypoint," + entryPoint); } //and exit return(false); } connected = true; Async.Queue("MBClient Listener", () => { bool process = true; while (process) { pipe.WaitForConnection(); //wait for someone to tell us something string[] commandAndArgs; try { // Read the request from the client. StreamReader sr = new StreamReader(pipe); commandAndArgs = sr.ReadLine().Split(','); } catch (Exception e) { Logger.ReportException("Error during IPC communication. Attempting to re-start listener", e); try { //be sure we're cleaned up pipe.Disconnect(); pipe.Close(); } catch { //we don't care if these fail now - and they very well may } finally { connected = false; } StartListening(); return; } try { string command = commandAndArgs[0]; switch (command.ToLower()) { case "play": //request to play something - our argument will be the GUID of the item to play Guid id = new Guid(commandAndArgs[1]); Logger.ReportInfo("Playing ..."); //to be implemented... break; case "activateentrypoint": //re-load ourselves and nav to the entrypoint Kernel.Instance.ReLoadRoot(); Microsoft.MediaCenter.UI.Application.DeferredInvoke(_ => { MediaBrowser.Application.CurrentInstance.LaunchEntryPoint(commandAndArgs[1]); }); //and tell MC to navigate to us Microsoft.MediaCenter.Hosting.AddInHost.Current.ApplicationContext.ReturnToApplication(); break; case "activate": Logger.ReportInfo("Asked to activate by another process.."); //if we were in an entrypoint and we just got told to activate - we need to re-load and go to real root if (Application.CurrentInstance.IsInEntryPoint) { Kernel.Instance.ReLoadRoot(); Microsoft.MediaCenter.UI.Application.DeferredInvoke(_ => { MediaBrowser.Application.CurrentInstance.LaunchEntryPoint(""); //this will start at root }); } else { //just need to back up to the root Application.CurrentInstance.BackToRoot(); } // set npv visibility according to current state Application.CurrentInstance.ShowNowPlaying = Application.CurrentInstance.IsPlaying || Application.CurrentInstance.IsExternalWmcApplicationPlaying; //tell MC to navigate to us Microsoft.MediaCenter.Hosting.AddInHost.Current.ApplicationContext.ReturnToApplication(); break; case "shutdown": //close MB Logger.ReportInfo("Shutting down due to request from a client (possibly new instance of MB)."); Application.CurrentInstance.Close(); break; case "closeconnection": //exit this connection Logger.ReportInfo("Service requested we stop listening."); process = false; break; } } catch (Exception e) { Logger.ReportException("Error trying to process IPC command", e); } try { pipe.Disconnect(); } catch (Exception e) { Logger.ReportException("Unexpected Error trying to close IPC connection", e); } } pipe.Close(); connected = false; }); return(true); }
// TODO debug mode in a separate debug window public async Task LaunchGame(string accountName, string password, CancellationToken cancellationToken = default) { var tcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); var thread = new Thread(StaThread); thread.SetApartmentState(ApartmentState.STA); thread.Start(); await tcs.Task; void StaThread() { const string launcherClassName = "LAUNCHER_CLASS"; const string launcherWindowsTitle = "LAUNCHER_WINDOW"; var wndClass = new WNDCLASSEX { cbSize = (uint)Marshal.SizeOf <WNDCLASSEX>(), lpszClassName = launcherClassName, lpfnWndProc = WndProc }; RegisterClassEx(ref wndClass); var windowHandle = CreateWindowEx(0, launcherClassName, launcherWindowsTitle, 0, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); var pid = Process.Start("Binaries\\TERA.exe", $"-LANGUAGEEXT={_configuration.Language}"); // Create and listen to the secret named pipe Task.Run(() => { var pipename = $"{pid.Id}cout"; using var pipeServer = new NamedPipeServerStream(pipename, PipeDirection.In); // Wait for a client to connect pipeServer.WaitForConnection(); Debug.WriteLine($"TERA connected to the named pipe {pipename}", "PIPE"); try { using var sr = new StreamReader(pipeServer); string temp; while ((temp = sr.ReadLine()) != null) { Debug.WriteLine($"Message: {temp}", "PIPE"); } } // Catch the IOException that is raised if the pipe is broken or disconnected catch (IOException e) { Debug.WriteLine($"Error: {e}", "PIPE"); } }, cancellationToken); pid.WaitForExit(); DefWindowProc(windowHandle, 0x10, IntPtr.Zero, IntPtr.Zero); UnregisterClass(launcherClassName, IntPtr.Zero); tcs.SetResult(0x0); } // Handle incomming game events IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { // We only care for WM_COPYDATA messages const uint wmCopyData = 0x004A; if (msg != wmCopyData) { return(DefWindowProc(hWnd, msg, wParam, lParam)); } var copyData = Marshal.PtrToStructure <COPYDATASTRUCT>(lParam); var eventId = copyData.dwData; if (copyData.cbData > 0) { var managedArray = new byte[copyData.cbData]; Marshal.Copy(copyData.lpData, managedArray, 0, copyData.cbData); var hex = BitConverter.ToString(managedArray).Replace("-", ""); Debug.WriteLine($"dwData: {eventId}, len: {copyData.cbData}, data: {hex}", "WND_PROC"); } else { Debug.WriteLine($"dwData: {eventId}, len: {copyData.cbData}", "WND_PROC"); } // Handle requests by the game client switch (eventId) { case 1: SendResponseMessage(wParam, hWnd, 2, Encoding.Unicode.GetBytes(accountName)); break; case 3: SendResponseMessage(wParam, hWnd, 4, _client.GetTicket(accountName, password)); break; case 5: SendResponseMessage(wParam, hWnd, 6, _client.GetServerList().ToByteArray()); break; } return(new IntPtr(1)); } }
[PlatformSpecific(PlatformID.Windows)] // Win32 P/Invokes to verify the user name public async Task Windows_GetImpersonationUserName_Succeed() { string pipeName = GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName)) { using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation)) { string expectedUserName; Task serverTask = server.WaitForConnectionAsync(); client.Connect(); await serverTask; Assert.True(Interop.TryGetImpersonationUserName(server.SafePipeHandle, out expectedUserName), "GetNamedPipeHandleState failed"); Assert.Equal(expectedUserName, server.GetImpersonationUserName()); } } }
public async Task ClonedServer_ActsAsOriginalServer() { byte[] msg1 = new byte[] { 5, 7, 9, 10 }; byte[] received1 = new byte[] { 0, 0, 0, 0 }; using (NamedPipePair pair = CreateNamedPipePair()) { NamedPipeServerStream serverBase = pair.serverStream; NamedPipeClientStream client = pair.clientStream; pair.Connect(); if (pair.writeToServer) { Task<int> clientTask = client.ReadAsync(received1, 0, received1.Length); using (NamedPipeServerStream server = new NamedPipeServerStream(PipeDirection.Out, false, true, serverBase.SafePipeHandle)) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Assert.Equal(1, client.NumberOfServerInstances); } server.Write(msg1, 0, msg1.Length); int receivedLength = await clientTask; Assert.Equal(msg1.Length, receivedLength); Assert.Equal(msg1, received1); } } else { Task clientTask = client.WriteAsync(msg1, 0, msg1.Length); using (NamedPipeServerStream server = new NamedPipeServerStream(PipeDirection.In, false, true, serverBase.SafePipeHandle)) { int receivedLength = server.Read(received1, 0, msg1.Length); Assert.Equal(msg1.Length, receivedLength); Assert.Equal(msg1, received1); await clientTask; } } } }
/// <summary> /// This method handles the asynchronous message pump. It waits for messages to show up on the queue /// and calls FireDataAvailable for each such packet. It will terminate when the terminate event is /// set. /// </summary> private void PacketPumpProc() { NamedPipeServerStream localPipeServer = _pipeServer; AutoResetEvent localPacketAvailable = _packetAvailable; AutoResetEvent localTerminatePacketPump = _terminatePacketPump; Queue <INodePacket> localPacketQueue = _packetQueue; DateTime originalWaitStartTime = DateTime.UtcNow; bool gotValidConnection = false; while (!gotValidConnection) { DateTime restartWaitTime = DateTime.UtcNow; // We only wait to wait the difference between now and the last original start time, in case we have multiple hosts attempting // to attach. This prevents each attempt from resetting the timer. TimeSpan usedWaitTime = restartWaitTime - originalWaitStartTime; int waitTimeRemaining = Math.Max(0, CommunicationsUtilities.NodeConnectionTimeout - (int)usedWaitTime.TotalMilliseconds); try { // Wait for a connection IAsyncResult resultForConnection = localPipeServer.BeginWaitForConnection(null, null); CommunicationsUtilities.Trace("Waiting for connection {0} ms...", waitTimeRemaining); bool connected = resultForConnection.AsyncWaitHandle.WaitOne(waitTimeRemaining, false); if (!connected) { CommunicationsUtilities.Trace("Connection timed out waiting a host to contact us. Exiting comm thread."); ChangeLinkStatus(LinkStatus.ConnectionFailed); return; } CommunicationsUtilities.Trace("Parent started connecting. Reading handshake from parent"); localPipeServer.EndWaitForConnection(resultForConnection); // The handshake protocol is a simple long exchange. The host sends us a long, and we // respond with another long. Once the handshake is complete, both sides can be assured the // other is ready to accept data. // To avoid mixing client and server builds, the long is the MSBuild binary timestamp. // Compatibility issue here. // Previous builds of MSBuild 4.0 would exchange just a byte. // Host would send either 0x5F or 0x60 depending on whether it was the toolset or not respectively. // Client would return either 0xF5 or 0x06 respectively. // Therefore an old host on a machine with new clients running will hang, // sending a byte and waiting for a byte until it eventually times out; // because the new client will want 7 more bytes before it returns anything. // The other way around is not a problem, because the old client would immediately return the (wrong) // byte on receiving the first byte of the long sent by the new host, and the new host would disconnect. // To avoid the hang, special case here: // Make sure our handshakes always start with 00. // If we received ONLY one byte AND it's 0x5F or 0x60, return 0xFF (it doesn't matter what as long as // it will cause the host to reject us; new hosts expect 00 and old hosts expect F5 or 06). try { long handshake = localPipeServer.ReadLongForHandshake(/* reject these leads */ new byte[] { 0x5F, 0x60 }, 0xFF /* this will disconnect the host; it expects leading 00 or F5 or 06 */); WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent(); string remoteUserName = localPipeServer.GetImpersonationUserName(); if (handshake != GetHostHandshake()) { CommunicationsUtilities.Trace("Handshake failed. Received {0} from host not {1}. Probably the host is a different MSBuild build.", handshake, GetHostHandshake()); localPipeServer.Disconnect(); continue; } // We will only talk to a host that was started by the same user as us. Even though the pipe access is set to only allow this user, we want to ensure they // haven't attempted to change those permissions out from under us. This ensures that the only way they can truly gain access is to be impersonating the // user we were started by. WindowsIdentity clientIdentity = null; localPipeServer.RunAsClient(delegate() { clientIdentity = WindowsIdentity.GetCurrent(true); }); if (clientIdentity == null || !String.Equals(clientIdentity.Name, currentIdentity.Name, StringComparison.OrdinalIgnoreCase)) { CommunicationsUtilities.Trace("Handshake failed. Host user is {0} but we were created by {1}.", (clientIdentity == null) ? "<unknown>" : clientIdentity.Name, currentIdentity.Name); localPipeServer.Disconnect(); continue; } } catch (IOException e) { // We will get here when: // 1. The host (OOP main node) connects to us, it immediately checks for user priviledges // and if they don't match it disconnects immediately leaving us still trying to read the blank handshake // 2. The host is too old sending us bits we automatically reject in the handshake CommunicationsUtilities.Trace("Client connection failed but we will wait for another connection. Exception: {0}", e.Message); if (localPipeServer.IsConnected) { localPipeServer.Disconnect(); } continue; } gotValidConnection = true; } catch (Exception e) { if (ExceptionHandling.IsCriticalException(e)) { throw; } CommunicationsUtilities.Trace("Client connection failed. Exiting comm thread. {0}", e); if (localPipeServer.IsConnected) { localPipeServer.Disconnect(); } ExceptionHandling.DumpExceptionToFile(e); ChangeLinkStatus(LinkStatus.Failed); return; } } CommunicationsUtilities.Trace("Writing handshake to parent"); localPipeServer.WriteLongForHandshake(GetClientHandshake()); ChangeLinkStatus(LinkStatus.Active); // Ordering of the wait handles is important. The first signalled wait handle in the array // will be returned by WaitAny if multiple wait handles are signalled. We prefer to have the // terminate event triggered so that we cannot get into a situation where packets are being // spammed to the endpoint and it never gets an opportunity to shutdown. CommunicationsUtilities.Trace("Entering read loop."); byte[] headerByte = new byte[5]; IAsyncResult result = localPipeServer.BeginRead(headerByte, 0, headerByte.Length, null, null); bool exitLoop = false; do { // Ordering is important. We want packetAvailable to supercede terminate otherwise we will not properly wait for all // packets to be sent by other threads which are shutting down, such as the logging thread. WaitHandle[] handles = new WaitHandle[] { result.AsyncWaitHandle, localPacketAvailable, localTerminatePacketPump }; int waitId = WaitHandle.WaitAny(handles); switch (waitId) { case 0: { int bytesRead = 0; try { bytesRead = localPipeServer.EndRead(result); } catch (Exception e) { // Lost communications. Abort (but allow node reuse) CommunicationsUtilities.Trace("Exception reading from server. {0}", e); ExceptionHandling.DumpExceptionToFile(e); ChangeLinkStatus(LinkStatus.Inactive); exitLoop = true; break; } if (bytesRead != headerByte.Length) { // Incomplete read. Abort. if (bytesRead == 0) { CommunicationsUtilities.Trace("Parent disconnected abruptly"); } else { CommunicationsUtilities.Trace("Incomplete header read from server. {0} of {1} bytes read", bytesRead, headerByte.Length); } ChangeLinkStatus(LinkStatus.Failed); exitLoop = true; break; } NodePacketType packetType = (NodePacketType)Enum.ToObject(typeof(NodePacketType), headerByte[0]); int packetLength = BitConverter.ToInt32(headerByte, 1); try { _packetFactory.DeserializeAndRoutePacket(0, packetType, NodePacketTranslator.GetReadTranslator(localPipeServer, _sharedReadBuffer)); } catch (Exception e) { // Error while deserializing or handling packet. Abort. CommunicationsUtilities.Trace("Exception while deserializing packet {0}: {1}", packetType, e); ExceptionHandling.DumpExceptionToFile(e); ChangeLinkStatus(LinkStatus.Failed); exitLoop = true; break; } result = localPipeServer.BeginRead(headerByte, 0, headerByte.Length, null, null); } break; case 1: case 2: try { int packetCount = localPacketQueue.Count; // Write out all the queued packets. while (packetCount > 0) { INodePacket packet; lock (_packetQueue) { packet = localPacketQueue.Dequeue(); } MemoryStream packetStream = new MemoryStream(); INodePacketTranslator writeTranslator = NodePacketTranslator.GetWriteTranslator(packetStream); packetStream.WriteByte((byte)packet.Type); // Pad for packet length packetStream.Write(BitConverter.GetBytes((int)0), 0, 4); // Reset the position in the write buffer. packet.Translate(writeTranslator); // Now write in the actual packet length packetStream.Position = 1; packetStream.Write(BitConverter.GetBytes((int)packetStream.Length - 5), 0, 4); localPipeServer.Write(packetStream.GetBuffer(), 0, (int)packetStream.Length); packetCount--; } } catch (Exception e) { // Error while deserializing or handling packet. Abort. CommunicationsUtilities.Trace("Exception while serializing packets: {0}", e); ExceptionHandling.DumpExceptionToFile(e); ChangeLinkStatus(LinkStatus.Failed); exitLoop = true; break; } if (waitId == 2) { CommunicationsUtilities.Trace("Disconnecting voluntarily"); ChangeLinkStatus(LinkStatus.Failed); exitLoop = true; } break; default: ErrorUtilities.ThrowInternalError("waitId {0} out of range.", waitId); break; } }while (!exitLoop); CommunicationsUtilities.Trace("Ending read loop"); try { if (localPipeServer.IsConnected) { localPipeServer.WaitForPipeDrain(); localPipeServer.Disconnect(); } } catch (Exception) { // We don't really care if Disconnect somehow fails, but it gives us a chance to do the right thing. } }