Пример #1
0
		private static void FswSend(Program.AppMessage msg, int lParam)
		{
			FswEnsurePaths();

			IpcMessage ipcMsg = new IpcMessage();
			byte[] pbID = CryptoRandom.Instance.GetRandomBytes(8);
			ipcMsg.ID = MemUtil.BytesToUInt64(pbID);
			ipcMsg.Time = DateTime.UtcNow.ToBinary();
			ipcMsg.Message = msg;
			ipcMsg.LParam = lParam;

			// Send just to others, not to own
			m_vProcessedMsgs.Add(ipcMsg);

			for(int r = 0; r < IpcComRetryCount; ++r)
			{
				try
				{
					List<IpcMessage> l = ReadMessagesPriv();
					CleanOldMessages(l);
					l.Add(ipcMsg);

					MemoryStream ms = new MemoryStream();
					BinaryWriter bw = new BinaryWriter(ms);
					bw.Write(IpcFileSig);
					bw.Write((uint)l.Count);
					for(int j = 0; j < l.Count; ++j)
						IpcMessage.Serialize(bw, l[j]);
					byte[] pbPlain = ms.ToArray();
					bw.Close();
					ms.Close();

					byte[] pbFile = ProtectedData.Protect(pbPlain, IpcOptEnt,
						DataProtectionScope.CurrentUser);

					FileStream fsWrite = new FileStream(m_strMsgFilePath,
						FileMode.Create, FileAccess.Write, FileShare.None);
					fsWrite.Write(pbFile, 0, pbFile.Length);
					fsWrite.Close();

					break;
				}
				catch(Exception) { }

				Thread.Sleep(IpcComRetryDelay);
			}

			CleanOldMessages(m_vProcessedMsgs);
		}
Пример #2
0
        public static int Main(string[] args)
        {
            if (args.Length >= 1)
            {
                Console.Out.WriteLine("Subprocess started!  Waiting for input...");
                var input = Console.In.ReadLine(); // will block until data is sent across stdin
                Console.Out.WriteLine($"Received '{input}'.  Exiting...");
                return(0);
            }

            var testEnvPairs = new Dictionary <string, string>
            {
                { "TESTKEY1", "TESTVAL1" },
                { "TESTKEY2", "TESTVAL2" },
                { "TESTKEY3", "__TEST__VAL=;--3" }
            };

            Task <bool> subprocessTask = Utils.RunSubprocess(
                currentAssembly: Assembly.GetExecutingAssembly(),
                environment: testEnvPairs,
                duringExecution: (int pid) =>
            {
                Logger.logger.Log($"Test PID: {pid}");

                Stream stream = ConnectionHelper.GetStandardTransport(pid);

                // 0x04 = ProcessCommandSet, 0x02 = ProcessInfo
                var processInfoMessage = new IpcMessage(0x04, 0x02);
                Logger.logger.Log($"Wrote: {processInfoMessage}");
                Stream continuationStream = IpcClient.SendMessage(stream, processInfoMessage, out IpcMessage response);
                Logger.logger.Log($"Received: {response}");

                Utils.Assert(response.Header.CommandSet == 0xFF, $"Response must have Server command set. Expected: 0xFF, Received: 0x{response.Header.CommandSet:X2}"); // server
                Utils.Assert(response.Header.CommandId == 0x00, $"Response must have OK command id. Expected: 0x00, Received: 0x{response.Header.CommandId:X2}");        // OK

                UInt32 continuationSizeInBytes = BitConverter.ToUInt32(response.Payload[0..4]);
                Logger.logger.Log($"continuation size: {continuationSizeInBytes} bytes");
                UInt16 future = BitConverter.ToUInt16(response.Payload[4..]);
Пример #3
0
        public static async Task <bool> TEST_AdvertiseAndProcessInfoCookiesMatch()
        {
            bool   fSuccess   = true;
            string serverName = ReverseServer.MakeServerAddress();

            Logger.logger.Log($"Server name is '{serverName}'");
            var server = new ReverseServer(serverName);

            using var memoryStream = new MemoryStream();
            Task <bool> subprocessTask = Utils.RunSubprocess(
                currentAssembly: Assembly.GetExecutingAssembly(),
                environment: new Dictionary <string, string> {
                { Utils.DiagnosticPortsEnvKey, $"{serverName},nosuspend" }
            },
                duringExecution: async(pid) =>
            {
                Stream stream          = await server.AcceptAsync();
                IpcAdvertise advertise = IpcAdvertise.Parse(stream);
                Logger.logger.Log(advertise.ToString());

                Logger.logger.Log($"Send ProcessInfo Diagnostics IPC Command");
                // send ProcessInfo command (0x04=ProcessCommandSet, 0x00=ProcessInfo commandid)
                var message = new IpcMessage(0x04, 0x00);
                Logger.logger.Log($"Sent: {message.ToString()}");
                IpcMessage response = IpcClient.SendMessage(stream, message);
                Logger.logger.Log($"received: {response.ToString()}");
                ProcessInfo info = ProcessInfo.TryParse(response.Payload);
                Logger.logger.Log($"ProcessInfo: {{ id={info.ProcessId}, cookie={info.RuntimeCookie}, cmdline={info.Commandline}, OS={info.OS}, arch={info.Arch} }}");

                Utils.Assert(info.RuntimeCookie.Equals(advertise.RuntimeInstanceCookie), $"The runtime cookie reported by ProcessInfo and Advertise must match.  ProcessInfo: {info.RuntimeCookie.ToString()}, Advertise: {advertise.RuntimeInstanceCookie.ToString()}");
                Logger.logger.Log($"ProcessInfo and Advertise Cookies are equal");
            }
                );

            fSuccess &= await subprocessTask;

            return(fSuccess);
        }
Пример #4
0
        /// <summary>
        /// Start trace collection.
        /// </summary>
        /// <param name="processId">Runtime process to trace</param>
        /// <param name="configuration">buffer size and provider configuration</param>
        /// <param name="sessionId">session id</param>
        /// <returns>Stream</returns>
        public static Stream CollectTracing(int processId, SessionConfiguration configuration, out ulong sessionId)
        {
            sessionId = 0;
            var message = new IpcMessage(DiagnosticsServerCommandSet.EventPipe, (byte)EventPipeCommandId.CollectTracing, configuration.Serialize());
            var stream  = IpcClient.SendMessage(processId, message, out var response);

            switch ((DiagnosticsServerCommandId)response.Header.CommandId)
            {
            case DiagnosticsServerCommandId.OK:
                sessionId = BitConverter.ToUInt64(response.Payload);
                break;

            case DiagnosticsServerCommandId.Error:
                // bad...
                var hr = BitConverter.ToInt32(response.Payload);
                throw new Exception($"Session start FAILED 0x{hr:X8}");

            default:
                break;
            }

            return(stream);
        }
Пример #5
0
        private async void ReceiveLoop(CancellationToken token)
        {
            try
            {
                while (!token.IsCancellationRequested && IsOpen)
                {
                    string s = await _ss.ReadStringAsync(token);

                    IpcMessage msg = null;
                    if (s == null)
                    {
                        throw new Exception("Got null string from server.");
                    }
                    try
                    {
                        msg = JsonConvert.DeserializeObject <IpcMessage>(s, new DictionaryDeserializer());
                    }
                    catch (JsonException ex)
                    {
                        Util.TraceException("Error parsing incoming JSON", ex);
                    }
                    if (msg != null)
                    {
                        OnMessageReceived(msg);
                    }
                }
            }
            catch (ArgumentException)
            {
                OnClosed();
            }
            catch (Exception ex)
            {
                Util.TraceException("Error receiving data from pipe.", ex);
                OnError(ex);
            }
        }
Пример #6
0
        public void CheckMessageProcessing()
        {
            using (MemoryStream ms = new MemoryStream())
            {
                // prep
                IpcMessage message = new IpcMessage()
                {
                    Service    = "IService",
                    Method     = "Sum",
                    Parameters = new object[] { 3, 5 }
                };

                IpcStream ipc = new IpcStream(ms, new List <Type>());

                ipc.WriteMessage(message);
                long startpos = ms.Position;
                ms.Seek(0, SeekOrigin.Begin);
                // ----


                Server s = new Server("testpipe");
                s.RegisterService <IService>(new Calculator());
                s.ProcessMessage(ipc, new Guid());


                // post
                ms.Seek(startpos, SeekOrigin.Begin);
                IpcMessage returnMessage = ipc.ReadMessage();

                var expectedMessage = new IpcMessage()
                {
                    Return = 8
                }.ToExpectedObject();

                expectedMessage.ShouldEqual(returnMessage);
            }
        }
Пример #7
0
        public virtual void Write(Meta meta)
        {
            object      data    = meta.Data;
            Type        type    = meta.Type;
            List <Task> waitFor = new List <Task>();

            if (meta.IsSerializable)
            {
                IpcMessage idMessage   = GetIdMessage(data, type);
                IpcMessage uuidMessage = GetUuidMessage(data, type);
                SubscribeToIpcMessageEvents(idMessage);
                SubscribeToIpcMessageEvents(uuidMessage);
                Task idWrite   = Task.Run(() => TryWrite(idMessage, data, 0, Logger));
                Task uuidWrite = Task.Run(() => TryWrite(uuidMessage, data, 0, Logger));

                waitFor.Add(idWrite);
                waitFor.Add(uuidWrite);
            }

            waitFor.Add(Task.Run(() => TryWriteObjectProperties(type, data)));
            waitFor.Add(Task.Run(() => WriteHash(meta)));

            Task.WaitAll(waitFor.ToArray());
        }
Пример #8
0
 public virtual bool Delete(object data, Type type = null)
 {
     try
     {
         if (data == null)
         {
             return(false);
         }
         type = type ?? data.GetType();
         string idHash = GetIdHash(data, type);
         IpcMessage.Delete(idHash, type, RootDirectory);
         string uuidHash = GetUuidHash(data, type);
         IpcMessage.Delete(uuidHash, type, RootDirectory);
         DeleteObjectProperties(type, data);
         DeleteHash(data, type);
         return(true);
     }
     catch (Exception ex)
     {
         Message = ex.Message;
         OnDeleteFailed();
         return(false);
     }
 }
Пример #9
0
        public bool SetEnvironmentVariable(string name, string val)
        {
            MethodInfo setEnvironmentVariable = typeof(DiagnosticsClient).GetMethod("SetEnvironmentVariable", BindingFlags.Public);

            if (setEnvironmentVariable != null)
            {
                throw new Exception("You updated DiagnosticsClient to a version that supports SetEnvironmentVariable, please remove this and use the real code.");
            }

            Console.WriteLine($"Sending SetEnvironmentVariable message name={name} value={val ?? "NULL"}.");

            using (var stream = new MemoryStream())
                using (var writer = new BinaryWriter(stream))
                {
                    writer.WriteString(name);
                    writer.WriteString(val);

                    writer.Flush();
                    byte[] payload = stream.ToArray();

                    var message = new IpcMessage(0x04, 0x03, payload);
                    Console.WriteLine($"Sent: {message.ToString()}");
                    IpcMessage response = IpcClient.SendMessage(ConnectionHelper.GetStandardTransport(_processId), message);
                    Console.WriteLine($"Received: {response.ToString()}");

                    if (response.Header.CommandSet != 255 || response.Header.CommandId != 0)
                    {
                        Console.WriteLine($"SetEnvironmentVariable failed.");
                        return(false);
                    }
                }

            Console.WriteLine($"Finished sending SetEnvironmentVariable message.");

            return(true);
        }
Пример #10
0
        private void SendSyncRequest(ARegisters Registers, bool UserBuffer)
        {
            long CmdPtr = Registers.Tpidr;
            long Size   = 0x100;
            int  Handle = 0;

            if (UserBuffer)
            {
                CmdPtr = (long)Registers.X0;
                Size   = (long)Registers.X1;
                Handle = (int)Registers.X2;
            }
            else
            {
                Handle = (int)Registers.X0;
            }

            byte[] CmdData = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size);

            HSession Session = Ns.Os.Handles.GetData <HSession>(Handle);

            IpcMessage Cmd = new IpcMessage(CmdData, CmdPtr, Session is HDomain);

            if (Session != null)
            {
                IpcHandler.IpcCall(Ns, Memory, Session, Cmd, CmdPtr, Handle);

                byte[] Response = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size);

                Registers.X0 = (int)SvcResult.Success;
            }
            else
            {
                Registers.X0 = (int)SvcResult.ErrBadIpcReq;
            }
        }
Пример #11
0
 public ServiceNotImplementedException(ServiceCtx context, string message, Exception inner)
     : base(message, inner)
 {
     Context = context;
     Request = context.Request;
 }
Пример #12
0
        public static async Task <bool> TEST_MultipleSessionsCanBeStartedWhilepaused()
        {
            bool   fSuccess   = true;
            string serverName = ReverseServer.MakeServerAddress();

            Logger.logger.Log($"Server name is '{serverName}'");
            var server = new ReverseServer(serverName);

            using var memoryStream1 = new MemoryStream();
            using var memoryStream2 = new MemoryStream();
            using var memoryStream3 = new MemoryStream();
            Task <bool> subprocessTask = Utils.RunSubprocess(
                currentAssembly: Assembly.GetExecutingAssembly(),
                environment: new Dictionary <string, string> {
                { Utils.DiagnosticsMonitorAddressEnvKey, serverName }
            },
                duringExecution: async(pid) =>
            {
                Stream stream          = await server.AcceptAsync();
                IpcAdvertise advertise = IpcAdvertise.Parse(stream);
                Logger.logger.Log(advertise.ToString());

                var config = new SessionConfiguration(
                    circularBufferSizeMB: 1000,
                    format: EventPipeSerializationFormat.NetTrace,
                    providers: new List <Provider> {
                    new Provider("Microsoft-Windows-DotNETRuntimePrivate", 0x80000000, EventLevel.Verbose)
                });

                Logger.logger.Log("Starting EventPipeSession over standard connection");
                using Stream eventStream1 = EventPipeClient.CollectTracing(pid, config, out var sessionId1);
                Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId1:x}");
                Task readerTask1 = eventStream1.CopyToAsync(memoryStream1);

                Logger.logger.Log("Starting EventPipeSession over standard connection");
                using Stream eventStream2 = EventPipeClient.CollectTracing(pid, config, out var sessionId2);
                Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId2:x}");
                Task readerTask2 = eventStream2.CopyToAsync(memoryStream2);

                Logger.logger.Log("Starting EventPipeSession over standard connection");
                using Stream eventStream3 = EventPipeClient.CollectTracing(pid, config, out var sessionId3);
                Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId3:x}");
                Task readerTask3 = eventStream3.CopyToAsync(memoryStream3);


                Logger.logger.Log($"Send ResumeRuntime Diagnostics IPC Command");
                // send ResumeRuntime command (0xFF=ServerCommandSet, 0x01=ResumeRuntime commandid)
                var message = new IpcMessage(0xFF, 0x01);
                Logger.logger.Log($"Sent: {message.ToString()}");
                IpcMessage response = IpcClient.SendMessage(stream, message);
                Logger.logger.Log($"received: {response.ToString()}");

                await Task.Delay(TimeSpan.FromSeconds(2));
                Logger.logger.Log("Stopping EventPipeSession over standard connection");
                EventPipeClient.StopTracing(pid, sessionId1);
                EventPipeClient.StopTracing(pid, sessionId2);
                EventPipeClient.StopTracing(pid, sessionId3);
                await readerTask1;
                await readerTask2;
                await readerTask3;
                Logger.logger.Log("Stopped EventPipeSession over standard connection");
            }
                );

            fSuccess &= await Utils.WaitTillTimeout(subprocessTask, TimeSpan.FromMinutes(1));

            int nStartupEventsSeen = 0;

            memoryStream1.Seek(0, SeekOrigin.Begin);
            using (var source = new EventPipeEventSource(memoryStream1))
            {
                var parser = new ClrPrivateTraceEventParser(source);
                parser.StartupEEStartupStart += (eventData) => nStartupEventsSeen++;
                source.Process();
            }

            memoryStream2.Seek(0, SeekOrigin.Begin);
            using (var source = new EventPipeEventSource(memoryStream2))
            {
                var parser = new ClrPrivateTraceEventParser(source);
                parser.StartupEEStartupStart += (eventData) => nStartupEventsSeen++;
                source.Process();
            }

            memoryStream3.Seek(0, SeekOrigin.Begin);
            using (var source = new EventPipeEventSource(memoryStream3))
            {
                var parser = new ClrPrivateTraceEventParser(source);
                parser.StartupEEStartupStart += (eventData) => nStartupEventsSeen++;
                source.Process();
            }

            Logger.logger.Log($"nStartupEventsSeen: {nStartupEventsSeen}");

            return(nStartupEventsSeen == 3 && fSuccess);
        }
        public void Send(string ipcEventName, IpcMessage param)
        {
            var mainWindow = Electron.WindowManager.BrowserWindows.First();

            Electron.IpcMain.Send(mainWindow, ipcEventName, param);
        }
Пример #14
0
        public static async Task <bool> TEST_MultipleConnectPortsSuspend()
        {
            bool   fSuccess              = true;
            var    serverAndNames        = new List <(ReverseServer, string)>();
            string dotnetDiagnosticPorts = "";

            for (int i = 0; i < s_NumberOfPorts; i++)
            {
                string serverName = ReverseServer.MakeServerAddress();
                var    server     = new ReverseServer(serverName);
                Logger.logger.Log($"Server {i} address is '{serverName}'");
                serverAndNames.Add((server, serverName));
                dotnetDiagnosticPorts += $"{serverName};";
            }
            Logger.logger.Log($"export DOTNET_DiagnosticPorts={dotnetDiagnosticPorts}");

            var    advertisements = new List <IpcAdvertise>();
            Object sync           = new Object();

            int         subprocessId   = -1;
            Task <bool> subprocessTask = Utils.RunSubprocess(
                currentAssembly: Assembly.GetExecutingAssembly(),
                environment: new Dictionary <string, string>
            {
                { Utils.DiagnosticPortsEnvKey, dotnetDiagnosticPorts }
            },
                duringExecution: async(int pid) =>
            {
                subprocessId = pid;
                // Create an eventpipe session that will tell us when
                // the EEStartupStarted event happens.  This will tell us
                // the the runtime has been resumed.  This should only happen
                // AFTER all suspend ports have sent the resume command.
                var config = new SessionConfiguration(
                    circularBufferSizeMB: 1000,
                    format: EventPipeSerializationFormat.NetTrace,
                    providers: new List <Provider> {
                    new Provider("Microsoft-Windows-DotNETRuntimePrivate", 0x80000000, EventLevel.Verbose),
                    // workaround for https://github.com/dotnet/runtime/issues/44072 which happens because the
                    // above provider only sends 2 events and that can cause EventPipeEventSource (from TraceEvent)
                    // to not dispatch the events if the EventBlock is a size not divisible by 8 (the reading alignment in TraceEvent).
                    // Adding this provider keeps data flowing over the pipe so the reader doesn't get stuck waiting for data
                    // that won't come otherwise.
                    new Provider("Microsoft-DotNETCore-SampleProfiler")
                });
                Logger.logger.Log("Starting EventPipeSession over standard connection");
                using Stream eventStream = EventPipeClient.CollectTracing(pid, config, out var sessionId);
                Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}");

                var mre = new ManualResetEvent(false);

                Task readerTask = Task.Run(async() =>
                {
                    Logger.logger.Log($"Creating EventPipeEventSource");
                    using var source              = new EventPipeEventSource(eventStream);
                    var parser                    = new ClrPrivateTraceEventParser(source);
                    parser.StartupEEStartupStart += (eventData) => mre.Set();
                    Logger.logger.Log($"Created EventPipeEventSource");
                    Logger.logger.Log($"Starting processing");
                    await Task.Run(() => source.Process());
                    Logger.logger.Log($"Finished processing");
                });

                for (int i = 0; i < s_NumberOfPorts; i++)
                {
                    fSuccess &= !mre.WaitOne(0);
                    Logger.logger.Log($"Runtime HAS NOT resumed (expects: true): {fSuccess}");
                    var(server, _)         = serverAndNames[i];
                    int serverIndex        = i;
                    Stream stream          = await server.AcceptAsync();
                    IpcAdvertise advertise = IpcAdvertise.Parse(stream);
                    lock (sync)
                        advertisements.Add(advertise);
                    Logger.logger.Log($"Server {serverIndex} got advertise {advertise.ToString()}");

                    // send resume command on this connection
                    var message = new IpcMessage(0x04, 0x01);
                    Logger.logger.Log($"Port {serverIndex} sent: {message.ToString()}");
                    IpcMessage response = IpcClient.SendMessage(stream, message);
                    Logger.logger.Log($"Port {serverIndex} received: {response.ToString()}");
                }

                Logger.logger.Log($"Waiting on EEStartupStarted event");
                mre.WaitOne();
                Logger.logger.Log($"Saw EEStartupStarted Event");

                Logger.logger.Log($"Stopping EventPipeSession");
                EventPipeClient.StopTracing(pid, sessionId);
                await readerTask;
                Logger.logger.Log($"Stopped EventPipeSession");

                // runtime should have resumed now
                fSuccess &= mre.WaitOne(0);
                Logger.logger.Log($"Runtime HAS resumed (expects: true): {fSuccess}");
            }
                );


            fSuccess &= await subprocessTask;
            foreach (var(server, _) in serverAndNames)
            {
                server.Shutdown();
            }

            if (advertisements.Count() > 0)
            {
                Guid referenceCookie = advertisements[0].RuntimeInstanceCookie;
                foreach (var adv in advertisements)
                {
                    fSuccess &= (int)adv.ProcessId == subprocessId;
                    fSuccess &= adv.RuntimeInstanceCookie.Equals(referenceCookie);
                }
            }
            else
            {
                fSuccess &= false;
            }

            return(fSuccess);
        }
Пример #15
0
        private bool Process(int serverSessionHandle, ulong recvListAddr)
        {
            KProcess process     = KernelStatic.GetCurrentProcess();
            KThread  thread      = KernelStatic.GetCurrentThread();
            ulong    messagePtr  = thread.TlsAddress;
            ulong    messageSize = 0x100;

            byte[] reqData = new byte[messageSize];

            process.CpuMemory.Read(messagePtr, reqData);

            IpcMessage request  = new IpcMessage(reqData, (long)messagePtr);
            IpcMessage response = new IpcMessage();

            ulong tempAddr    = recvListAddr;
            int   sizesOffset = request.RawData.Length - ((request.RecvListBuff.Count * 2 + 3) & ~3);

            bool noReceive = true;

            for (int i = 0; i < request.ReceiveBuff.Count; i++)
            {
                noReceive &= (request.ReceiveBuff[i].Position == 0);
            }

            if (noReceive)
            {
                for (int i = 0; i < request.RecvListBuff.Count; i++)
                {
                    ulong size = (ulong)BinaryPrimitives.ReadInt16LittleEndian(request.RawData.AsSpan().Slice(sizesOffset + i * 2, 2));

                    response.PtrBuff.Add(new IpcPtrBuffDesc(tempAddr, (uint)i, size));

                    request.RecvListBuff[i] = new IpcRecvListBuffDesc(tempAddr, size);

                    tempAddr += size;
                }
            }

            bool shouldReply         = true;
            bool isTipcCommunication = false;

            using (MemoryStream raw = new MemoryStream(request.RawData))
            {
                BinaryReader reqReader = new BinaryReader(raw);

                if (request.Type == IpcMessageType.HipcRequest ||
                    request.Type == IpcMessageType.HipcRequestWithContext)
                {
                    response.Type = IpcMessageType.HipcResponse;

                    using (MemoryStream resMs = new MemoryStream())
                    {
                        BinaryWriter resWriter = new BinaryWriter(resMs);

                        ServiceCtx context = new ServiceCtx(
                            _context.Device,
                            process,
                            process.CpuMemory,
                            thread,
                            request,
                            response,
                            reqReader,
                            resWriter);

                        _sessions[serverSessionHandle].CallHipcMethod(context);

                        response.RawData = resMs.ToArray();
                    }
                }
                else if (request.Type == IpcMessageType.HipcControl ||
                         request.Type == IpcMessageType.HipcControlWithContext)
                {
                    uint magic = (uint)reqReader.ReadUInt64();
                    uint cmdId = (uint)reqReader.ReadUInt64();

                    switch (cmdId)
                    {
                    case 0:
                        request = FillResponse(response, 0, _sessions[serverSessionHandle].ConvertToDomain());
                        break;

                    case 3:
                        request = FillResponse(response, 0, PointerBufferSize);
                        break;

                    // TODO: Whats the difference between IpcDuplicateSession/Ex?
                    case 2:
                    case 4:
                        int unknown = reqReader.ReadInt32();

                        _context.Syscall.CreateSession(false, 0, out int dupServerSessionHandle, out int dupClientSessionHandle);

                        AddSessionObj(dupServerSessionHandle, _sessions[serverSessionHandle]);

                        response.HandleDesc = IpcHandleDesc.MakeMove(dupClientSessionHandle);

                        request = FillResponse(response, 0);

                        break;

                    default: throw new NotImplementedException(cmdId.ToString());
                    }
                }
                else if (request.Type == IpcMessageType.HipcCloseSession || request.Type == IpcMessageType.TipcCloseSession)
                {
                    _context.Syscall.CloseHandle(serverSessionHandle);
                    _sessionHandles.Remove(serverSessionHandle);
                    IpcService service = _sessions[serverSessionHandle];
                    if (service is IDisposable disposableObj)
                    {
                        disposableObj.Dispose();
                    }
                    _sessions.Remove(serverSessionHandle);
                    shouldReply = false;
                }
                // If the type is past 0xF, we are using TIPC
                else if (request.Type > IpcMessageType.TipcCloseSession)
                {
                    isTipcCommunication = true;

                    // Response type is always the same as request on TIPC.
                    response.Type = request.Type;

                    using (MemoryStream resMs = new MemoryStream())
                    {
                        BinaryWriter resWriter = new BinaryWriter(resMs);

                        ServiceCtx context = new ServiceCtx(
                            _context.Device,
                            process,
                            process.CpuMemory,
                            thread,
                            request,
                            response,
                            reqReader,
                            resWriter);

                        _sessions[serverSessionHandle].CallTipcMethod(context);

                        response.RawData = resMs.ToArray();
                    }

                    process.CpuMemory.Write(messagePtr, response.GetBytesTipc());
                }
                else
                {
                    throw new NotImplementedException(request.Type.ToString());
                }

                if (!isTipcCommunication)
                {
                    process.CpuMemory.Write(messagePtr, response.GetBytes((long)messagePtr, recvListAddr | ((ulong)PointerBufferSize << 48)));
                }

                return(shouldReply);
            }
        }
Пример #16
0
        public static Job ReinstantiateSuspendedJob(IIpcMessageStore messageStore, string instanceId)
        {
            IpcMessage message = messageStore.GetMessage <Job>(instanceId);

            return(message.Read <Job>());
        }
Пример #17
0
        public static async Task <bool> TEST_CanStartAndStopSessionWhilepaused()
        {
            bool   fSuccess   = true;
            string serverName = ReverseServer.MakeServerAddress();

            Logger.logger.Log($"Server name is '{serverName}'");
            var server = new ReverseServer(serverName);

            using var memoryStream1 = new MemoryStream();
            using var memoryStream2 = new MemoryStream();
            using var memoryStream3 = new MemoryStream();
            Task <bool> subprocessTask = Utils.RunSubprocess(
                currentAssembly: Assembly.GetExecutingAssembly(),
                environment: new Dictionary <string, string> {
                { Utils.DiagnosticPortsEnvKey, $"{serverName}" }
            },
                duringExecution: async(pid) =>
            {
                Stream stream          = await server.AcceptAsync();
                IpcAdvertise advertise = IpcAdvertise.Parse(stream);
                Logger.logger.Log(advertise.ToString());

                var config = new SessionConfiguration(
                    circularBufferSizeMB: 1000,
                    format: EventPipeSerializationFormat.NetTrace,
                    providers: new List <Provider> {
                    new Provider("Microsoft-Windows-DotNETRuntime", UInt64.MaxValue, EventLevel.Verbose)
                });

                Logger.logger.Log("Starting EventPipeSession over standard connection");
                using Stream eventStream1 = EventPipeClient.CollectTracing(pid, config, out var sessionId1);
                Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId1:x}");
                Task readerTask1 = eventStream1.CopyToAsync(memoryStream1);

                Logger.logger.Log("Starting EventPipeSession over standard connection");
                using Stream eventStream2 = EventPipeClient.CollectTracing(pid, config, out var sessionId2);
                Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId2:x}");
                Task readerTask2 = eventStream2.CopyToAsync(memoryStream2);

                Logger.logger.Log("Starting EventPipeSession over standard connection");
                using Stream eventStream3 = EventPipeClient.CollectTracing(pid, config, out var sessionId3);
                Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId3:x}");
                Task readerTask3 = eventStream3.CopyToAsync(memoryStream3);

                await Task.Delay(TimeSpan.FromSeconds(1));
                Logger.logger.Log("Stopping EventPipeSession over standard connection");
                EventPipeClient.StopTracing(pid, sessionId1);
                EventPipeClient.StopTracing(pid, sessionId2);
                EventPipeClient.StopTracing(pid, sessionId3);
                await readerTask1;
                await readerTask2;
                await readerTask3;
                Logger.logger.Log("Stopped EventPipeSession over standard connection");

                Logger.logger.Log($"Send ResumeRuntime Diagnostics IPC Command");
                // send ResumeRuntime command (0x04=ProcessCommandSet, 0x01=ResumeRuntime commandid)
                var message = new IpcMessage(0x04, 0x01);
                Logger.logger.Log($"Sent: {message.ToString()}");
                IpcMessage response = IpcClient.SendMessage(stream, message);
                Logger.logger.Log($"received: {response.ToString()}");
            }
                );

            fSuccess &= await subprocessTask;

            return(fSuccess);
        }
Пример #18
0
 private void HandleNameRequest(IpcMessage message)
 {
     Write(new NetIpcClientNameResponseMessage(client.ClientName, message.MessageId));
 }
Пример #19
0
 private void HandleGetAutoReconnect(IpcMessage message)
 {
     Write(new NetIpcAutoReconnectResponseMessage(client.AutoReconnect, message.MessageId));
 }
 public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message) : base(message)
 {
     Service = service;
     Context = context;
     Request = context.Request;
 }
Пример #21
0
 public void SendIpcMessage(ProcessType target, IpcMessage message)
 {
     var r = MarshalFromNative<CefBrowser>();
     var action = (CefBrowserCapiDelegates.SendProcessMessageCallback)
                  Marshal.GetDelegateForFunctionPointer(r.SendProcessMessage,
                                                        typeof (
                                                            CefBrowserCapiDelegates.SendProcessMessageCallback));
     action(Handle, (CefProcessId) target, message.Handle);
 }
Пример #22
0
 public Task SendAsync(IpcMessage message) => SendAsync(message, CancellationToken.None);
Пример #23
0
 public bool OnRequestUpdate(IpcMessage msg)
 {
     msg.SendReply <ApplicationUpdate>(m_ipcServer, IpcCall.Update, m_lastFetchedUpdate);
     return(true);
 }
Пример #24
0
 public void Handle(IpcMessage param)
 {
     Console.WriteLine("Execute LogHandler.Handle");
 }
Пример #25
0
            public static IpcMessage Deserialize(BinaryReader br)
            {
                if(br == null) { Debug.Assert(false); return null; }

                IpcMessage msg = new IpcMessage();

                msg.ID = br.ReadUInt64();
                msg.Time = br.ReadInt64();
                msg.Message = (Program.AppMessage)br.ReadInt32();
                msg.LParam = br.ReadInt32();

                return msg;
            }
Пример #26
0
 public override async Task SendMessageAsync(IpcMessage message)
 {
     await ipcProvider.SendMessageAsync(message);
 }
Пример #27
0
 void ipc_MessageReceived(IpcMessage msg)
 {
     if (InvokeRequired)
         Invoke(new MessageReceivedHandler(ipc_MessageReceived), new object[] { msg });
     else
         switch (msg)
         {
             case IpcMessage.Show:
                 if (WindowState == FormWindowState.Minimized)
                     WindowState = FormWindowState.Normal;
                 Show();
                 Activate();
                 break;
             case IpcMessage.ScreenAnnotate:
                 ShowAnnoTools(false);
                 break;
         }
 }
Пример #28
0
        public static async Task <bool> TEST_ProcessInfoBeforeAndAfterSuspension()
        {
            // This test only applies to platforms where the PAL is used
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                return(true);
            }

            // This test only applies to CoreCLR (this checks if we're running on Mono)
            if (Type.GetType("Mono.RuntimeStructs") != null)
            {
                return(true);
            }

            bool   fSuccess   = true;
            string serverName = ReverseServer.MakeServerAddress();

            Logger.logger.Log($"Server name is '{serverName}'");
            var server = new ReverseServer(serverName);

            using var memoryStream1 = new MemoryStream();
            using var memoryStream2 = new MemoryStream();
            using var memoryStream3 = new MemoryStream();
            Task <bool> subprocessTask = Utils.RunSubprocess(
                currentAssembly: Assembly.GetExecutingAssembly(),
                environment: new Dictionary <string, string> {
                { Utils.DiagnosticPortsEnvKey, $"{serverName}" }
            },
                duringExecution: async(pid) =>
            {
                Process currentProcess = Process.GetCurrentProcess();

                Stream stream          = await server.AcceptAsync();
                IpcAdvertise advertise = IpcAdvertise.Parse(stream);
                Logger.logger.Log(advertise.ToString());

                Logger.logger.Log($"Get ProcessInfo while process is suspended");
                // 0x04 = ProcessCommandSet, 0x04 = ProcessInfo2
                var message = new IpcMessage(0x04, 0x04);
                Logger.logger.Log($"Sent: {message.ToString()}");
                IpcMessage response = IpcClient.SendMessage(stream, message);
                Logger.logger.Log($"received: {response.ToString()}");

                ProcessInfo2 pi2Before = ProcessInfo2.TryParse(response.Payload);
                Utils.Assert(pi2Before.Commandline.Equals(currentProcess.MainModule.FileName), $"Before resuming, the commandline should be the mock value of the host executable path '{currentProcess.MainModule.FileName}'. Observed: '{pi2Before.Commandline}'");

                // recycle
                stream    = await server.AcceptAsync();
                advertise = IpcAdvertise.Parse(stream);
                Logger.logger.Log(advertise.ToString());

                // Start EP session to know when runtime is resumed
                var config = new SessionConfiguration(
                    circularBufferSizeMB: 1000,
                    format: EventPipeSerializationFormat.NetTrace,
                    providers: new List <Provider> {
                    new Provider("Microsoft-Windows-DotNETRuntimePrivate", 0x80000000, EventLevel.Verbose),
                    new Provider("Microsoft-DotNETCore-SampleProfiler")
                });
                Logger.logger.Log("Starting EventPipeSession over standard connection");
                using Stream eventStream = EventPipeClient.CollectTracing(pid, config, out var sessionId);
                Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}");

                TaskCompletionSource <bool> runtimeResumed = new(false, TaskCreationOptions.RunContinuationsAsynchronously);

                var eventPipeTask = Task.Run(() =>
                {
                    Logger.logger.Log("Creating source");
                    using var source              = new EventPipeEventSource(eventStream);
                    var parser                    = new ClrPrivateTraceEventParser(source);
                    parser.StartupEEStartupStart += (_) => runtimeResumed.SetResult(true);
                    source.Process();
                    Logger.logger.Log("stopping processing");
                });

                Logger.logger.Log($"Send ResumeRuntime Diagnostics IPC Command");
                // send ResumeRuntime command (0x04=ProcessCommandSet, 0x01=ResumeRuntime commandid)
                message = new IpcMessage(0x04, 0x01);
                Logger.logger.Log($"Sent: {message.ToString()}");
                response = IpcClient.SendMessage(stream, message);
                Logger.logger.Log($"received: {response.ToString()}");

                // recycle
                stream    = await server.AcceptAsync();
                advertise = IpcAdvertise.Parse(stream);
                Logger.logger.Log(advertise.ToString());

                // wait a little bit to make sure the runtime of the target is fully up, i.e., g_EEStarted == true
                // on resource constrained CI machines this may not be instantaneous
                Logger.logger.Log($"awaiting resume");
                await Utils.WaitTillTimeout(runtimeResumed.Task, TimeSpan.FromSeconds(10));
                Logger.logger.Log($"resumed");

                // await Task.Delay(TimeSpan.FromSeconds(1));
                Logger.logger.Log("Stopping EventPipeSession over standard connection");
                EventPipeClient.StopTracing(pid, sessionId);
                Logger.logger.Log($"Await reader task");
                await eventPipeTask;
                Logger.logger.Log("Stopped EventPipeSession over standard connection");

                ProcessInfo2 pi2After = default;

                // The timing is not exact. There is a small window after resuming where the mock
                // value is still present. Retry several times to catch it.
                var retryTask = Task.Run(async() =>
                {
                    int i = 0;
                    do
                    {
                        Logger.logger.Log($"Get ProcessInfo after resumption: attempt {i++}");
                        // 0x04 = ProcessCommandSet, 0x04 = ProcessInfo2
                        message = new IpcMessage(0x04, 0x04);
                        Logger.logger.Log($"Sent: {message.ToString()}");
                        response = IpcClient.SendMessage(stream, message);
                        Logger.logger.Log($"received: {response.ToString()}");

                        pi2After = ProcessInfo2.TryParse(response.Payload);

                        // recycle
                        stream    = await server.AcceptAsync();
                        advertise = IpcAdvertise.Parse(stream);
                        Logger.logger.Log(advertise.ToString());
                    } while (pi2After.Commandline.Equals(pi2Before.Commandline));
                });

                await Utils.WaitTillTimeout(retryTask, TimeSpan.FromSeconds(10));

                Utils.Assert(!pi2After.Commandline.Equals(pi2Before.Commandline), $"After resuming, the commandline should be the correct value. Observed: Before='{pi2Before.Commandline}' After='{pi2After.Commandline}'");
            }
                );

            fSuccess &= await subprocessTask;

            return(fSuccess);
        }
Пример #29
0
        private void Process(IpcRequest message)
        {
            byte[] reqData = new byte[message.MessageSize];

            message.Process.CpuMemory.Read(message.MessagePtr, reqData);

            IpcMessage request  = new IpcMessage(reqData, (long)message.MessagePtr);
            IpcMessage response = new IpcMessage();

            using (MemoryStream raw = new MemoryStream(request.RawData))
            {
                BinaryReader reqReader = new BinaryReader(raw);

                if (request.Type == IpcMessageType.Request ||
                    request.Type == IpcMessageType.RequestWithContext)
                {
                    response.Type = IpcMessageType.Response;

                    using (MemoryStream resMs = new MemoryStream())
                    {
                        BinaryWriter resWriter = new BinaryWriter(resMs);

                        ServiceCtx context = new ServiceCtx(
                            message.Device,
                            message.Process,
                            message.Process.CpuMemory,
                            message.Thread,
                            message.Session,
                            request,
                            response,
                            reqReader,
                            resWriter);

                        message.Session.Service.CallMethod(context);

                        response.RawData = resMs.ToArray();
                    }
                }
                else if (request.Type == IpcMessageType.Control ||
                         request.Type == IpcMessageType.ControlWithContext)
                {
                    uint magic = (uint)reqReader.ReadUInt64();
                    uint cmdId = (uint)reqReader.ReadUInt64();

                    switch (cmdId)
                    {
                    case 0:
                        request = FillResponse(response, 0, message.Session.Service.ConvertToDomain());
                        break;

                    case 3:
                        request = FillResponse(response, 0, 0x1000);
                        break;

                    // TODO: Whats the difference between IpcDuplicateSession/Ex?
                    case 2:
                    case 4:
                        int unknown = reqReader.ReadInt32();

                        if (message.Process.HandleTable.GenerateHandle(message.Session, out int handle) != KernelResult.Success)
                        {
                            throw new InvalidOperationException("Out of handles!");
                        }

                        response.HandleDesc = IpcHandleDesc.MakeMove(handle);

                        request = FillResponse(response, 0);

                        break;

                    default: throw new NotImplementedException(cmdId.ToString());
                    }
                }
                else if (request.Type == IpcMessageType.CloseSession)
                {
                    message.SignalDone(KernelResult.PortRemoteClosed);
                    return;
                }
                else
                {
                    throw new NotImplementedException(request.Type.ToString());
                }

                message.Process.CpuMemory.Write(message.MessagePtr, response.GetBytes((long)message.MessagePtr));
            }

            message.SignalDone(KernelResult.Success);
        }
Пример #30
0
            public static void Serialize(BinaryWriter bw, IpcMessage msg)
            {
                if((bw == null) || (msg == null)) { Debug.Assert(false); return; }

                bw.Write(msg.ID);
                bw.Write(msg.Time);
                bw.Write((int)msg.Message);
                bw.Write(msg.LParam);
            }
Пример #31
0
 void ipcMessager_MessageReceived(IpcMessage msg)
 {
     if (MessageReceived != null)
         MessageReceived(msg);
 }
Пример #32
0
 public void Serialize(Stream stream, IpcMessage message) {
   // Note: We need "WithLengthPrefix" method to enable serialization over
   //  a "live" stream, such as "NetworkStream".
   Serializer.SerializeWithLengthPrefix(stream, message, PrefixStyle.Base128);
   //Serializer.Serialize(stream, message);
 }
Пример #33
0
        public static int Main(string[] args)
        {
            if (args.Length > 0 && args[0].Equals("RunTest", StringComparison.OrdinalIgnoreCase))
            {
                Console.WriteLine("In RunTest, exiting.");
                return(100);
            }

            string serverName     = ReverseServer.MakeServerAddress();
            Task   backgroundTask = Task.Run(() =>
            {
                ReverseServer server = null;
                try
                {
                    Task task = Task.Run(async() =>
                    {
                        server = new ReverseServer(serverName);
                        using (Stream serverStream = await server.AcceptAsync())
                        {
                            IpcAdvertise advertise = IpcAdvertise.Parse(serverStream);
                            Console.WriteLine($"Got IpcAdvertise: {advertise}");

                            int processId = (int)advertise.ProcessId;

                            // While we are paused in startup send the profiler startup command
                            string profilerPath             = GetProfilerPath();
                            DiagnosticsIPCWorkaround client = new DiagnosticsIPCWorkaround(processId);
                            client.SetStartupProfiler(ReverseStartupProfilerGuid, profilerPath);

                            if (!client.SetEnvironmentVariable("ReverseServerTest_OverwriteMe", "Overwritten"))
                            {
                                throw new Exception("Failed setting environment variable.");
                            }

                            if (!client.SetEnvironmentVariable("ReverseServerTest_ClearMe", null))
                            {
                                throw new Exception("Failed clearing environment variable.");
                            }

                            // Resume runtime message
                            IpcMessage resumeMessage = new IpcMessage(0x04, 0x01);
                            Console.WriteLine($"Sent resume runtime message: {resumeMessage.ToString()}");
                            IpcMessage resumeResponse = IpcClient.SendMessage(serverStream, resumeMessage);
                            Logger.logger.Log($"Received: {resumeResponse.ToString()}");
                        }
                    });

                    task.Wait();
                }
                catch (Exception e)
                {
                    Console.WriteLine($"ReverseServer saw exception {e.Message}");
                    Console.WriteLine(e.StackTrace);


                    Console.WriteLine($"Inner exception {e.InnerException?.Message}");
                    Console.WriteLine(e.InnerException?.StackTrace);
                }
                finally
                {
                    server?.Shutdown();
                }
            });

            Dictionary <string, string> envVars = new Dictionary <string, string>()
            {
                { "ReverseServerTest_OverwriteMe", "OriginalValue" },
                { "ReverseServerTest_ClearMe", "OriginalValue" }
            };

            return(ProfilerTestRunner.Run(profileePath: System.Reflection.Assembly.GetExecutingAssembly().Location,
                                          testName: "ReverseStartup",
                                          profilerClsid: Guid.Empty,
                                          profileeOptions: ProfileeOptions.NoStartupAttach | ProfileeOptions.ReverseDiagnosticsMode,
                                          envVars: envVars,
                                          reverseServerName: serverName));
        }
Пример #34
0
        public static async Task <bool> TEST_SuspendDefaultPort()
        {
            bool fSuccess = true;

            int         subprocessId   = -1;
            Task <bool> subprocessTask = Utils.RunSubprocess(
                currentAssembly: Assembly.GetExecutingAssembly(),
                environment: new Dictionary <string, string>
            {
                { Utils.DiagnosticPortSuspend, "1" }
            },
                duringExecution: async(int pid) =>
            {
                subprocessId = pid;
                // Create an eventpipe session that will tell us when
                // the EEStartupStarted event happens.  This will tell us
                // the the runtime has been resumed.  This should only happen
                // AFTER all suspend ports have sent the resume command.
                var config = new SessionConfiguration(
                    circularBufferSizeMB: 1000,
                    format: EventPipeSerializationFormat.NetTrace,
                    providers: new List <Provider> {
                    new Provider("Microsoft-Windows-DotNETRuntimePrivate", 0x80000000, EventLevel.Verbose),
                    // workaround for https://github.com/dotnet/runtime/issues/44072 which happens because the
                    // above provider only sends 2 events and that can cause EventPipeEventSource (from TraceEvent)
                    // to not dispatch the events if the EventBlock is a size not divisible by 8 (the reading alignment in TraceEvent).
                    // Adding this provider keeps data flowing over the pipe so the reader doesn't get stuck waiting for data
                    // that won't come otherwise.
                    new Provider("Microsoft-DotNETCore-SampleProfiler")
                });
                Logger.logger.Log("Starting EventPipeSession over standard connection");
                using Stream eventStream = EventPipeClient.CollectTracing(pid, config, out var sessionId);
                Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}");

                var mre = new ManualResetEvent(false);

                Task readerTask = Task.Run(async() =>
                {
                    Logger.logger.Log($"Creating EventPipeEventSource");
                    using var source              = new EventPipeEventSource(eventStream);
                    var parser                    = new ClrPrivateTraceEventParser(source);
                    parser.StartupEEStartupStart += (eventData) => mre.Set();
                    Logger.logger.Log($"Created EventPipeEventSource");
                    Logger.logger.Log($"Starting processing");
                    await Task.Run(() => source.Process());
                    Logger.logger.Log($"Finished processing");
                });


                fSuccess &= !mre.WaitOne(0);
                Logger.logger.Log($"Runtime HAS NOT resumed (expects: true): {fSuccess}");

                // send resume command on this connection
                var message = new IpcMessage(0x04, 0x01);
                Logger.logger.Log($"Sent: {message.ToString()}");
                IpcMessage response = IpcClient.SendMessage(ConnectionHelper.GetStandardTransport(pid), message);
                Logger.logger.Log($"Received: {response.ToString()}");

                Logger.logger.Log($"Waiting for EEStartupStarted event");
                mre.WaitOne();
                Logger.logger.Log($"Saw EEStartupStarted event!");

                Logger.logger.Log($"Stopping EventPipeSession");
                EventPipeClient.StopTracing(pid, sessionId);
                await readerTask;
                Logger.logger.Log($"Stopped EventPipeSession");

                // runtime should have resumed now
                fSuccess &= mre.WaitOne(0);
                Logger.logger.Log($"Runtime HAS resumed (expects: true): {fSuccess}");
            }
                );


            fSuccess &= await subprocessTask;

            return(fSuccess);
        }
Пример #35
0
 public void SendMessage(IpcMessage msg)
 {
     if (MessageReceived != null)
         MessageReceived(msg);
 }
Пример #36
0
 private void HandleStateRequest(IpcMessage message)
 {
     Write(new NetIpcStateResponseMessage(message.MessageId, client.IsConnected));
 }
Пример #37
0
 private void OnMessageReceived(IpcMessage message)
 {
     MessageReceived?.Invoke(this, new IpcMessageEventArgs(message));
 }
Пример #38
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            bool   activate   = false;
            bool   scan       = false;
            bool   kill       = false;
            bool   clear      = false;
            string ip         = System.String.Empty;
            int    index      = 0;
            bool   connect    = false;
            bool   resetPP    = false;
            bool   begin      = false;
            bool   stop       = false;
            bool   monitorTCP = false;
            bool   monitorIO  = false;
            bool   stream     = false;
            Target targ       = null;

            if (!DA.GetData(0, ref activate))
            {
                ;
            }
            if (!DA.GetData(1, ref scan))
            {
                ;
            }
            if (!DA.GetData(2, ref kill))
            {
                ;
            }
            if (!DA.GetData(3, ref clear))
            {
                ;
            }
            if (!DA.GetData(4, ref ip))
            {
                ;
            }
            if (!DA.GetData(5, ref index))
            {
                ;
            }
            if (!DA.GetData(6, ref connect))
            {
                ;
            }
            if (!DA.GetData(7, ref resetPP))
            {
                ;
            }
            if (!DA.GetData(8, ref begin))
            {
                ;
            }
            if (!DA.GetData(9, ref stop))
            {
                ;
            }
            if (!DA.GetData(10, ref monitorTCP))
            {
                ;
            }
            if (!DA.GetData(11, ref monitorIO))
            {
                ;
            }
            if (!DA.GetData(12, ref stream))
            {
                ;
            }
            if (!DA.GetData(13, ref targ))
            {
                ;
            }

            this.controllerIndex = index;
            this.start           = begin;

            double cRobX = 0;
            double cRobY = 0;
            double cRobZ = 0;

            double cRobQ1 = 0;
            double cRobQ2 = 0;
            double cRobQ3 = 0;
            double cRobQ4 = 0;

            Quaternion cRobQuat = new Quaternion();


            //Check for valid licence

            /*if (bool (Core.AuthTest.loggedIn) != true)
             * {
             *  new GH_RuntimeMessage("Please sign in to confirm your licence", GH_RuntimeMessageLevel.Error);
             *  return;
             * }*/


            if (activate)
            {
                if (scan)
                {
                    // Scan the network for controllers and add them to our controller array
                    scanner.Scan();
                    controllers = scanner.GetControllers();

                    if (controllers.Length > 0)
                    {
                        log.Add("Controllers found:");

                        // List the controller names that were found on the network.
                        for (int i = 0; i < controllers.Length; i++)
                        {
                            log.Add(controllers[i].ControllerName);
                        }
                    }
                    else
                    {
                        log.Add("Scan timed out. No controllers were found.");
                    }
                }

                if (kill && controller != null)
                {
                    controller.Logoff();
                    controller.Dispose();
                    controller = null;

                    log.Add("Process killed! Abandon ship!");
                }

                if (clear)
                {
                    log.Clear();
                    log.Add("Log cleared.");
                }

                if (connect)
                {
                    if (controller == null && controllers.Length > 0)
                    {
                        string controllerID = controllers[index].ControllerName;
                        log.Add("Selected robot controller: " + controllers[index].ControllerName + ".");

                        if (controllers[index].Availability == Availability.Available)
                        {
                            log.Add("Robot controller " + controllers[index].ControllerName + " is available.");

                            if (controller != null)
                            {
                                controller.Logoff();
                                controller.Dispose();
                                controller = null;
                            }

                            controller = ControllerFactory.CreateFrom(controllers[index]);
                            controller.Logon(UserInfo.DefaultUser);
                            log.Add("Connection to robot controller " + controller.SystemName + " established.");

                            // Get T_ROB1 queue to send messages to the RAPID task.
                            if (!controller.Ipc.Exists("RMQ_T_ROB1"))
                            {
                                controller.Ipc.CreateQueue("RMQ_T_ROB1", 10, Ipc.MaxMessageSize);
                            }

                            tasks = controller.Rapid.GetTasks();
                            IpcQueue robotQueue = controller.Ipc.GetQueue("RMQ_T_ROB1");
                            int      queueID    = robotQueue.QueueId;
                            string   queueName  = robotQueue.QueueName;

                            log.Add("Established RMQ for T_ROB1 on network controller.");
                            log.Add("Rapid Message Queue ID:" + queueID.ToString() + ".");
                            log.Add("Rapid Message Queue Name:" + queueName + ".");
                            RobotQueue = robotQueue;
                        }
                        else
                        {
                            log.Add("Selected controller not available.");
                        }

                        ControllerID = controllerID;
                    }
                    else
                    {
                        if (controller != null)
                        {
                            return;
                        }
                        else
                        {
                            string exceptionMessage = "No robot controllers found on network.";
                            ControllerID = "No Controller";
                            log.Add(exceptionMessage);
                        }
                    }
                }

                if (resetPP && controller != null)
                {
                    using (Mastership m = Mastership.Request(controller.Rapid))
                    {
                        // Reset program pointer to main.
                        tasks[0].ResetProgramPointer();
                        log.Add("Program pointer set to main on the active task.");
                    }
                }

                if (begin)
                {
                    // Execute robot tasks present on controller.
                    try
                    {
                        if (controller.OperatingMode == ControllerOperatingMode.Auto)
                        {
                            using (Mastership m = Mastership.Request(controller.Rapid))
                            {
                                // Perform operation.
                                tasks[0].Start();
                                log.Add("Robot program started on robot " + controller.SystemName + ".");
                            }
                        }
                        else
                        {
                            log.Add("Automatic mode is required to start execution from a remote client.");
                        }
                    }
                    catch (System.InvalidOperationException ex)
                    {
                        log.Add("Mastership is held by another client." + ex.Message);
                    }
                    catch (System.Exception ex)
                    {
                        log.Add("Unexpected error occurred: " + ex.Message);
                    }
                }

                if (stop)
                {
                    try
                    {
                        if (controller.OperatingMode == ControllerOperatingMode.Auto)
                        {
                            using (Mastership m = Mastership.Request(controller.Rapid))
                            {
                                // Stop operation.
                                tasks[0].Stop(StopMode.Immediate);
                                log.Add("Robot program stopped on robot " + controller.SystemName + ".");
                            }
                        }
                        else
                        {
                            log.Add("Automatic mode is required to stop execution from a remote client.");
                        }
                    }
                    catch (System.InvalidOperationException ex)
                    {
                        log.Add("Mastership is held by another client." + ex.Message);
                    }
                    catch (System.Exception ex)
                    {
                        log.Add("Unexpected error occurred: " + ex.Message);
                    }
                }

                // If active, update the status of the TCP.
                if (monitorTCP)
                {
                    if (tcpMonitoringOn == 0)
                    {
                        log.Add("TCP monitoring started.");
                    }

                    cRobTarg = tasks[0].GetRobTarget();

                    cRobX = Math.Round(cRobTarg.Trans.X, 3);
                    cRobY = Math.Round(cRobTarg.Trans.Y, 3);
                    cRobZ = Math.Round(cRobTarg.Trans.Z, 3);

                    Point3d cRobPos = new Point3d(cRobX, cRobY, cRobZ);

                    cRobQ1 = Math.Round(cRobTarg.Rot.Q1, 5);
                    cRobQ2 = Math.Round(cRobTarg.Rot.Q2, 5);
                    cRobQ3 = Math.Round(cRobTarg.Rot.Q3, 5);
                    cRobQ4 = Math.Round(cRobTarg.Rot.Q4, 5);

                    cRobQuat = new Quaternion(cRobQ1, cRobQ2, cRobQ3, cRobQ4);

                    tcp = Util.QuaternionToPlane(cRobPos, cRobQuat);

                    tcpMonitoringOn += 1;
                    tcpMonitoringOff = 0;
                }
                else if (tcpMonitoringOn > 0)
                {
                    if (tcpMonitoringOff == 0)
                    {
                        log.Add("TCP monitoring stopped.");
                    }

                    tcpMonitoringOff += 1;
                    tcpMonitoringOn   = 0;
                }


                // If active, update the status of the IO system.
                if (monitorIO)
                {
                    if (ioMonitoringOn == 0)
                    {
                        log.Add("Signal monitoring started.");
                    }

                    // Filter only the digital IO system signals.
                    IOFilterTypes    dSignalFilter = IOFilterTypes.Common;
                    SignalCollection dSignals      = controller.IOSystem.GetSignals(dSignalFilter);

                    IOstatus.Clear();
                    // Iterate through the found collection and print them to the IO monitoring list.
                    foreach (Signal signal in dSignals)
                    {
                        string sigVal = signal.ToString() + ": " + signal.Value.ToString();
                        IOstatus.Add(sigVal);
                    }

                    ioMonitoringOn += 1;
                    ioMonitoringOff = 0;
                }
                else if (ioMonitoringOn > 0)
                {
                    if (ioMonitoringOff == 0)
                    {
                        log.Add("Signal monitoring stopped.");
                    }

                    ioMonitoringOff += 1;
                    ioMonitoringOn   = 0;
                }


                if (stream)
                {
                    if (targ != null)
                    {
                        IpcMessage message = new IpcMessage();

                        pos.X = (float)targ.Position.X;
                        pos.Y = (float)targ.Position.Y;
                        pos.Z = (float)targ.Position.Z;


                        ori.Q1 = targ.Quaternion.A;
                        ori.Q2 = targ.Quaternion.B;
                        ori.Q3 = targ.Quaternion.C;
                        ori.Q4 = targ.Quaternion.D;

                        pose.Trans = pos;
                        pose.Rot   = ori;

                        string content = "SD;[" +
                                         "\"Linear\"," +
                                         pos.ToString() + "," +
                                         ori.ToString() + "," +
                                         pose.ToString() +
                                         "]";

                        byte[] data = new UTF8Encoding().GetBytes(content);

                        message.SetData(data);
                        RobotQueue.Send(message);
                    }
                }


                // Output the status of the connection.
                Status = log;

                DA.SetDataList(0, log);
                DA.SetDataList(1, IOstatus);
                DA.SetData(2, new GH_Plane(tcp));

                ExpireSolution(true);
            }
        }
Пример #39
0
 public void SendMessage(IpcMessage msg)
 {
     // grab the remote object.
     IpcMessager service = (IpcMessager)Activator.GetObject(typeof(IpcMessager), IpcMessagerUrl);
     // send message
     if (service != null)
     {
         service.SendMessage(msg);
         int n = service.GetCount();
         Console.WriteLine("The remote object has been called {0} times.", n);
     }
 }