예제 #1
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region IDebugPortSupplier2 Members

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort)
        {
            //
            // Attempt to find a port matching the requested name, refreshes and iterates updated ports via EnumPorts.
            //

            LoggingUtils.PrintFunction();

            try
            {
                string requestPortName;

                LoggingUtils.RequireOk(CanAddPort());

                LoggingUtils.RequireOk(pRequest.GetPortName(out requestPortName));

                ppPort = null;

                foreach (KeyValuePair <Guid, IDebugPort2> keyPair in m_registeredPorts)
                {
                    string portName;

                    IDebugPort2 registeredPort = keyPair.Value;

                    LoggingUtils.RequireOk(registeredPort.GetPortName(out portName));

                    if (portName.Equals(requestPortName))
                    {
                        ppPort = registeredPort;

                        break;
                    }
                }

                if (ppPort == null)
                {
                    Guid portId;

                    ppPort = CreatePort(pRequest);

                    LoggingUtils.RequireOk(ppPort.GetPortId(out portId));

                    m_registeredPorts.Add(portId, ppPort);
                }

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                ppPort = null;

                return(Constants.E_FAIL);
            }
        }
예제 #2
0
        /// <summary>
        /// Remove the given port.
        /// </summary>
        public int RemovePort(IDebugPort2 pPort)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "DebugPortSupplier.RemovePort");
            string name;

            if (!ErrorHandler.Succeeded(pPort.GetPortName(out name)))
            {
                return(VSConstants.S_FALSE);
            }
            return(ports.Remove(name) ? VSConstants.S_OK : VSConstants.S_FALSE);
        }
예제 #3
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region IDebugPortSupplier2 Members

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort)
        {
            //
            // Attempt to find a port matching the requested name, otherwise one is created.
            //

            LoggingUtils.PrintFunction();

            try
            {
                string requestPortName;

                LoggingUtils.RequireOk(CanAddPort());

                LoggingUtils.RequireOk(pRequest.GetPortName(out requestPortName));

                if (string.IsNullOrWhiteSpace(requestPortName))
                {
                    throw new InvalidOperationException("Invalid/empty port name");
                }

                ppPort = null;

                foreach (KeyValuePair <Guid, IDebugPort2> keyPair in m_registeredPorts)
                {
                    string portName;

                    IDebugPort2 registeredPort = keyPair.Value;

                    LoggingUtils.RequireOk(registeredPort.GetPortName(out portName));

                    if (portName.Equals(requestPortName))
                    {
                        ppPort = registeredPort;

                        break;
                    }
                }

                if (ppPort == null)
                {
                    //
                    // Create and track a new port for this request.
                    //

                    Guid portId;

                    LoggingUtils.RequireOk(CreatePort(pRequest, out ppPort));

                    LoggingUtils.RequireOk(ppPort.GetPortId(out portId));

                    m_registeredPorts.Add(portId, ppPort);
                }

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                ppPort = null;

                return(Constants.E_FAIL);
            }
        }
예제 #4
0
        // Launches a process by means of the debug engine.
        // Normally, Visual Studio launches a program using the IDebugPortEx2::LaunchSuspended method and then attaches the debugger
        // to the suspended program. However, there are circumstances in which the debug engine may need to launch a program
        // (for example, if the debug engine is part of an interpreter and the program being debugged is an interpreted language),
        // in which case Visual Studio uses the IDebugEngineLaunch2::LaunchSuspended method
        // The IDebugEngineLaunch2::ResumeProcess method is called to start the process after the process has been successfully launched in a suspended state.
        int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 port, string exe, string args, string dir, string env, string options, enum_LAUNCH_FLAGS launchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 ad7Callback, out IDebugProcess2 process)
        {
            //Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
            //Debug.Assert(m_pollThread == null);
            Debug.Assert(m_engineCallback == null);
            Debug.Assert(debuggedProcess == null);
            Debug.Assert(m_ad7ProgramId == Guid.Empty);

            process = null;

            try
            {
                //string commandLine = EngineUtils.BuildCommandLine(exe, args);

                //ProcessLaunchInfo processLaunchInfo = new ProcessLaunchInfo(exe, commandLine, dir, env, options, (uint)launchFlags, hStdInput, hStdOutput, hStdError);

                // We are being asked to debug a process when we currently aren't debugging anything
                //m_pollThread = new WorkerThread();
                string portname;
                port.GetPortName(out portname);
                m_engineCallback = new EngineCallback(this, ad7Callback);

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(options);
                XmlElement root                      = (XmlElement)doc.ChildNodes[0];
                string     ipaddress                 = root.GetAttribute("targetaddress");
                int        ipport                    = Int32.Parse(root.GetAttribute("port"));
                int        connectiontries           = Int32.Parse(root.GetAttribute("connectiontries"));
                int        connectiondelay           = Int32.Parse(root.GetAttribute("connectiondelay"));
                bool       autoruninterpreter        = Boolean.Parse(root.GetAttribute("autoruninterpreter"));
                bool       suspendonstartup          = Boolean.Parse(root.GetAttribute("suspendonstartup"));
                List <SquirrelDebugFileContext> ctxs = new List <SquirrelDebugFileContext>();
                foreach (XmlElement e in doc.GetElementsByTagName("context"))
                {
                    string rootpath  = e.GetAttribute("rootpath");
                    string pathfixup = e.GetAttribute("pathfixup");
                    SquirrelDebugFileContext sdfc = new SquirrelDebugFileContext(rootpath, pathfixup);
                    ctxs.Add(sdfc);
                }

                // Complete the win32 attach on the poll thread
                //THIS IS A MASSIVE HACK
                //the 'options' parameter is formatted this way "targetaddress,port,autorunintepreter,suspendonstartup,projectfolder,pathfixup"
                //I should find a better way to pass this params

                //fix working dir)
                dir = dir.Replace('/', '\\');
                Process proc = null;
                if (autoruninterpreter)
                {
                    proc = new Process();
                    proc.EnableRaisingEvents       = false;
                    proc.StartInfo.UseShellExecute = false;
                    baseDir = proc.StartInfo.WorkingDirectory = dir;
                    proc.StartInfo.FileName = exe;

                    proc.StartInfo.Arguments = args;
                    proc.StartInfo.RedirectStandardOutput = false;
                    proc.StartInfo.RedirectStandardError  = false;

                    proc.Start();
                }

                AD_PROCESS_ID adProcessId = new AD_PROCESS_ID();

                if (proc != null)
                {
                    adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM;
                    adProcessId.dwProcessId   = (uint)proc.Id;
                }
                else
                {
                    adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
                    adProcessId.guidProcessId = Guid.NewGuid();
                }


                EngineUtils.RequireOk(port.GetProcess(adProcessId, out process));

                debuggedProcess                  = (SquirrelProcess)process;
                debuggedProcess.Engine           = this;
                debuggedProcess.Process          = proc;
                debuggedProcess.Name             = proc != null? proc.StartInfo.FileName : "remoteprocess";
                debuggedProcess.EngineCallback   = m_engineCallback;
                debuggedProcess.IpAddress        = ipaddress;
                debuggedProcess.IpPort           = ipport;
                debuggedProcess.SuspendOnStartup = suspendonstartup;
                debuggedProcess.FileContexts     = ctxs.ToArray();
                //debuggedProcess.ConnectionTries = connectiontries;
                //debuggedProcess.ConnectionDelay = connectiondelay;
                //debuggedProcess.PathFixup = pathfixup;
                //debuggedProcess.ProjectFolder = projectfolder;

                /*DebuggedThread thread = new DebuggedThread(1);
                 * DebuggedModule module = new DebuggedModule("the module");
                 *
                 * m_engineCallback.OnModuleLoad(module);
                 * m_engineCallback.OnSymbolSearch(module, "nothing", 0);
                 * m_engineCallback.OnThreadStart(thread);
                 * m_engineCallback.OnLoadComplete(thread);*/

                return(EngineConstants.S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HRESULT);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #5
0
 /// <summary>
 /// Remove the given port.
 /// </summary>
 public int RemovePort(IDebugPort2 pPort)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "DebugPortSupplier.RemovePort");
     string name;
     if (!ErrorHandler.Succeeded(pPort.GetPortName(out name)))
         return VSConstants.S_FALSE;
     return ports.Remove(name) ? VSConstants.S_OK : VSConstants.S_FALSE;
 }