public int EnumProperties(enum_DEBUGPROP_INFO_FLAGS dwFields, uint nRadix, ref Guid guidFilter, uint dwTimeout, out uint pcelt, out IEnumDebugPropertyInfo2 ppEnum) { int hr; pcelt = 0; ppEnum = null; try { if (guidFilter == AD7Guids.guidFilterLocalsPlusArgs || guidFilter == AD7Guids.guidFilterAllLocalsPlusArgs || guidFilter == AD7Guids.guidFilterAllLocals) { //CreateLocalsPlusArgsProperties(out elementsReturned, out enumObject); CreateLocalProperties(out pcelt, out ppEnum); hr = VSConstants.S_OK; } else if (guidFilter == AD7Guids.guidFilterLocals) { CreateLocalProperties(out pcelt, out ppEnum); hr = VSConstants.S_OK; } else if (guidFilter == AD7Guids.guidFilterArgs) { //CreateParameterProperties(out elementsReturned, out enumObject); hr = VSConstants.S_OK; } else { hr = VSConstants.E_NOTIMPL; } } catch (Exception e) { return(EngineUtils.UnexpectedException(e)); } return(hr); }
// 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(m_ad7ProgramId == Guid.Empty); m_ad7ProgramId = Guid.NewGuid(); STARTUPINFO si = new STARTUPINFO(); pi = new PROCESS_INFORMATION(); // try/finally free bool procOK = NativeMethods.CreateProcess(exe, args, IntPtr.Zero, IntPtr.Zero, false, ProcessCreationFlags.CREATE_SUSPENDED, IntPtr.Zero, null, ref si, out pi); pID = pi.dwProcessId; Task writepipeOK = WriteNamedPipeAsync(); Task readpipeOK = ReadNamedPipeAsync(); threadHandle = pi.hThread; IntPtr processHandle = pi.hProcess; // Inject LuaDebug into host IntPtr loadLibAddr = DLLInjector.GetProcAddress(DLLInjector.GetModuleHandle("kernel32.dll"), "LoadLibraryA"); string VS140ExtensionPath = Path.Combine(Path.GetDirectoryName(typeof(EngineConstants).Assembly.Location), "LuaDetour"); string luaDetoursDllName = Path.Combine(VS140ExtensionPath, "LuaDetours.dll"); if (!File.Exists(luaDetoursDllName)) { process = null; return(VSConstants.E_FAIL); } IntPtr allocMemAddress1 = DLLInjector.VirtualAllocEx(processHandle, IntPtr.Zero, (uint)((luaDetoursDllName.Length + 1) * Marshal.SizeOf(typeof(char))), DLLInjector.MEM_COMMIT | DLLInjector.MEM_RESERVE, DLLInjector.PAGE_READWRITE); UIntPtr bytesWritten1; DLLInjector.WriteProcessMemory(processHandle, allocMemAddress1, Encoding.Default.GetBytes(luaDetoursDllName), (uint)((luaDetoursDllName.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten1); IntPtr hRemoteThread1 = DLLInjector.CreateRemoteThread(processHandle, IntPtr.Zero, 0, loadLibAddr, allocMemAddress1, 0, IntPtr.Zero); IntPtr[] handles1 = new IntPtr[] { hRemoteThread1 }; uint index1; NativeMethods.CoWaitForMultipleHandles(0, -1, handles1.Length, handles1, out index1); string debugDllName = Path.Combine(VS140ExtensionPath, "LuaDebug32.dll"); IntPtr allocMemAddress2 = DLLInjector.VirtualAllocEx(processHandle, IntPtr.Zero, (uint)((debugDllName.Length + 1) * Marshal.SizeOf(typeof(char))), DLLInjector.MEM_COMMIT | DLLInjector.MEM_RESERVE, DLLInjector.PAGE_READWRITE); UIntPtr bytesWritten2; DLLInjector.WriteProcessMemory(processHandle, allocMemAddress2, Encoding.Default.GetBytes(debugDllName), (uint)((debugDllName.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten2); IntPtr hRemoteThread2 = DLLInjector.CreateRemoteThread(processHandle, IntPtr.Zero, 0, loadLibAddr, allocMemAddress2, 0, IntPtr.Zero); IntPtr[] handles = new IntPtr[] { hRemoteThread2 }; uint index2; NativeMethods.CoWaitForMultipleHandles(0, -1, handles.Length, handles, out index2); AD_PROCESS_ID adProcessId = new AD_PROCESS_ID(); adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM; adProcessId.dwProcessId = pi.dwProcessId; EngineUtils.RequireOk(port.GetProcess(adProcessId, out process)); debugProcess = process; return(VSConstants.S_OK); }