public static int Install(DebugUtilities debugUtilities, out SimpleEventHandler eventCallbacks, BREAKPOINT_HANDLER breakpointHandler = null)
            {
                var ec = new SimpleEventHandler(debugUtilities);

                if (breakpointHandler != null)
                {
                    ec._breakpointHandler = breakpointHandler;
                }
                IDebugEventCallbacks idec = ec;
                IntPtr unknownPtr         = Marshal.GetIUnknownForObject(idec);
                IntPtr idecPtr;
                Guid   guid = typeof(IDebugEventCallbacks).GUID;
                int    hr   = Marshal.QueryInterface(unknownPtr, ref guid, out idecPtr);

                if (FAILED(hr))
                {
                    ec.Dispose();
                    eventCallbacks = null;
                    return(hr);
                }

                debugUtilities.DebugClient.GetEventCallbacks(out ec._previousCallbacks); /* We will need to release this */
                hr = debugUtilities.DebugClient.SetEventCallbacks(idecPtr);
                if (FAILED(hr))
                {
                    ec.Dispose();
                    eventCallbacks = null;
                    return(hr);
                }

                ec._installed  = true;
                eventCallbacks = ec;
                return(hr);
            }
        private static int ConnectDebuggerDumpHelper(DebugUtilities debugUtilities, string dumpFile, out SimpleDebugger debuggerInformation)
        {
            int hr;

            SimpleOutputHandler debuggerOutputCallbacks = null;
            SimpleEventHandler  debuggerEventCallbacks  = null;

            debuggerInformation = null;

            hr = SimpleOutputHandler.Install(debugUtilities, out debuggerOutputCallbacks);
            if (hr != S_OK)
            {
                goto Error;
            }

            hr = SimpleEventHandler.Install(debugUtilities, out debuggerEventCallbacks);
            if (hr != S_OK)
            {
                goto ErrorWithDetach;
            }

            hr = debugUtilities.DebugClient.OpenDumpFileWide(dumpFile, 0);
            if (FAILED(hr))
            {
                goto ErrorWithDetach;
            }

            while (debuggerEventCallbacks.SessionIsActive == false)
            {
                hr = debugUtilities.DebugControl.WaitForEvent(DEBUG_WAIT.DEFAULT, 50);
                if (FAILED(hr))
                {
                    goto ErrorWithDetach;
                }
            }

            debuggerInformation = new SimpleDebugger(debugUtilities, 0, true, debuggerOutputCallbacks, debuggerEventCallbacks);

            goto Exit;

ErrorWithDetach:
            debugUtilities.DebugClient.DetachProcesses();
            debugUtilities.DebugClient.EndSession(DEBUG_END.ACTIVE_DETACH);
Error:
            if (debuggerEventCallbacks != null)
            {
                debuggerEventCallbacks.Dispose();
            }
            if (debuggerOutputCallbacks != null)
            {
                debuggerOutputCallbacks.Dispose();
            }
Exit:
            return(hr);
        }
        private static int ConnectDebuggerLiveHelper(DebugUtilities debugUtilities, uint processID, bool passive, out SimpleDebugger debuggerInformation)
        {
            int hr;

            IDebugControl       debugControl       = null;
            IDebugSystemObjects debugSystemObjects = null;

            SimpleOutputHandler debuggerOutputCallbacks = null;
            SimpleEventHandler  debuggerEventCallbacks  = null;

            debuggerInformation = null;

            hr = SimpleOutputHandler.Install(debugUtilities, out debuggerOutputCallbacks);
            if (hr != S_OK)
            {
                goto Error;
            }

            hr = SimpleEventHandler.Install(debugUtilities, out debuggerEventCallbacks);
            if (hr != S_OK)
            {
                goto ErrorWithDetach;
            }

            DEBUG_ATTACH attachFlags = passive ? DEBUG_ATTACH.NONINVASIVE | DEBUG_ATTACH.NONINVASIVE_NO_SUSPEND : DEBUG_ATTACH.INVASIVE_RESUME_PROCESS;

            hr = debugUtilities.DebugClient.AttachProcess(0, processID, attachFlags);
            if (hr != S_OK)
            {
                goto ErrorWithDetach;
            }

            while (debuggerEventCallbacks.SessionIsActive == false)
            {
                hr = debugControl.WaitForEvent(DEBUG_WAIT.DEFAULT, 50);
                if (FAILED(hr))
                {
                    goto ErrorWithDetach;
                }
            }

            bool foundMatchingProcess = false;
            uint numProcesses;

            debugSystemObjects.GetNumberProcesses(out numProcesses);
            uint[] systemProcessIDs = new uint[numProcesses];
            uint[] engineProcessIDs = new uint[numProcesses];
            hr = debugSystemObjects.GetProcessIdsByIndex(0, numProcesses, engineProcessIDs, systemProcessIDs);
            for (uint i = 0; i < numProcesses; ++i)
            {
                if (systemProcessIDs[i] == processID)
                {
                    foundMatchingProcess = true;
                    hr = debugSystemObjects.SetCurrentProcessId(engineProcessIDs[i]);
                    if (FAILED(hr))
                    {
                        debuggerOutputCallbacks.AddNoteLine(String.Format(CultureInfo.InvariantCulture, "ERROR! Failed to set the active process! hr={0:x8}", hr));
                        goto ErrorWithDetach;
                    }
                    break;
                }
            }
            if (foundMatchingProcess == false)
            {
                hr = E_FAIL;
                debuggerOutputCallbacks.AddNoteLine(String.Format(CultureInfo.InvariantCulture, "ERROR! The debugger engine could not find the requested process ID ({0})!", processID));
                goto ErrorWithDetach;
            }

            debuggerInformation = new SimpleDebugger(debugUtilities, processID, passive, debuggerOutputCallbacks, debuggerEventCallbacks);

            goto Exit;

ErrorWithDetach:
            debugUtilities.DebugClient.DetachProcesses();
            debugUtilities.DebugClient.EndSession(DEBUG_END.ACTIVE_DETACH);
Error:
            if (debuggerEventCallbacks != null)
            {
                debuggerEventCallbacks.Dispose();
            }
            if (debuggerOutputCallbacks != null)
            {
                debuggerOutputCallbacks.Dispose();
            }
Exit:
            return(hr);
        }