Implementing IDebugProgram2 and IDebugThread2
In addition to implementing IDebugProgramNode2, the program object implements IDebugProgram2 and IDebugThread2 (since only one thread is running in the program being debugged). In those circumstances where a program would have more than one thread, IDebugThread2 would be implemented in its own class object.
To implement IDebugProgram2 and IDebugThread2
Open the Program.h file and insert the following bold lines:
class ATL_NO_VTABLE CProgram : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CProgram, &CLSID_Program>, public IDebugProgram2, public IDebugThread2, public IDebugProgramNode2
Also in Program.h, insert the following bold COM mapping macros to the BEGIN_COM_MAP structure. These entries have to be added manually since the interfaces in the previous step were added manually.
BEGIN_COM_MAP(CProgram) COM_INTERFACE_ENTRY(IDebugProgram2) COM_INTERFACE_ENTRY(IDebugThread2) COM_INTERFACE_ENTRY(IDebugProgramNode2) END_COM_MAP()
Also in Program.h, add the following bold lines. These are the declarations for the methods on the IDebugProgram2 and IDebugThread2 interfaces.
STDMETHOD(DetachDebugger_V7)(void); //////////////////////////////////////////////////////////// // IDebugProgram2 STDMETHOD(EnumThreads)(IEnumDebugThreads2** ppEnum); STDMETHOD(GetName)(BSTR* pbstrName); STDMETHOD(GetProcess)(IDebugProcess2** ppProcess); STDMETHOD(Terminate)(void); STDMETHOD(Attach)(IDebugEventCallback2* pCallback); STDMETHOD(Detach)(void); STDMETHOD(GetProgramId)(GUID* pguidProgramId); STDMETHOD(GetDebugProperty)(IDebugProperty2** ppProperty); STDMETHOD(Execute)(void); STDMETHOD(Continue)(IDebugThread2 *pThread); STDMETHOD(Step)(IDebugThread2 *pThread, STEPKIND sk, STEPUNIT step); STDMETHOD(CauseBreak)(void); //GetEngineInfo already defined for IDebugProgramNode2 STDMETHOD(EnumCodeContexts)( IDebugDocumentPosition2* pDocPos, IEnumDebugCodeContexts2** ppEnum); STDMETHOD(GetMemoryBytes)(IDebugMemoryBytes2** ppMemoryBytes); STDMETHOD(GetDisassemblyStream)( DISASSEMBLY_STREAM_SCOPE dwScope, IDebugCodeContext2* pCodeContext, IDebugDisassemblyStream2** ppDisassemblyStream); STDMETHOD(EnumModules)(IEnumDebugModules2** ppEnum); STDMETHOD(GetENCUpdate)(IDebugENCUpdate** ppUpdate); STDMETHOD(EnumCodePaths)( LPCOLESTR pszHint, IDebugCodeContext2* pStart, IDebugStackFrame2* pFrame, BOOL fSource, IEnumCodePaths2** ppEnum, IDebugCodeContext2** ppSafety); STDMETHOD(WriteDump)(DUMPTYPE DumpType, LPCOLESTR pszCrashDumpUrl); STDMETHOD(CanDetach)(void); //////////////////////////////////////////////////////////// // IDebugThread2 STDMETHOD(EnumFrameInfo)( FRAMEINFO_FLAGS dwFieldSpec, UINT nRadix, IEnumDebugFrameInfo2 **ppEnum); // GetName already defined for IDebugProgram STDMETHOD(SetThreadName)(LPCOLESTR pszName); STDMETHOD(GetProgram)(IDebugProgram2** ppProgram); STDMETHOD(CanSetNextStatement)( IDebugStackFrame2 *pStackFrame, IDebugCodeContext2 *pCodeContext); STDMETHOD(SetNextStatement)( IDebugStackFrame2 *pStackFrame, IDebugCodeContext2 *pCodeContext); STDMETHOD(GetThreadId)(DWORD* pdwThreadId); STDMETHOD(Suspend)(DWORD *pdwSuspendCount); STDMETHOD(Resume)(DWORD *pdwSuspendCount); STDMETHOD(GetThreadProperties)( THREADPROPERTY_FIELDS dwFields, THREADPROPERTIES *ptp); STDMETHOD(GetLogicalThread)( IDebugStackFrame2 *pStackFrame, IDebugLogicalThread2 **ppLogicalThread); DECLARE_PROTECT_FINAL_CONSTRUCT()
Open the Program.cpp file and add the following bold lines to the end of the file. These are the definitions for the methods on the IDebugProgram2 and IDebugThread2 interfaces. All return E_NOTIMPL at the moment (only a few will actually be implemented in TextInterpreter).
////////////////////////////////////////////////////////////////////////////// // IDebugProgram2 methods HRESULT CProgram::EnumThreads(IEnumDebugThreads2** ppEnum) { return E_NOTIMPL; } HRESULT CProgram::GetName(BSTR* pbstrName) { return E_NOTIMPL; } HRESULT CProgram::GetProcess(IDebugProcess2** ppProcess) { return E_NOTIMPL; } HRESULT CProgram::Terminate(void) { return E_NOTIMPL; } HRESULT CProgram::Attach(IDebugEventCallback2* pCallback) { return E_NOTIMPL; } HRESULT CProgram::Detach(void) { return E_NOTIMPL; } HRESULT CProgram::GetDebugProperty(IDebugProperty2** ppProperty) { return E_NOTIMPL; } HRESULT CProgram::CauseBreak(void) { return E_NOTIMPL; } HRESULT CProgram::EnumCodeContexts(IDebugDocumentPosition2* pDocPos, IEnumDebugCodeContexts2** ppEnum) { return E_NOTIMPL; } HRESULT CProgram::GetMemoryBytes(IDebugMemoryBytes2** ppMemoryBytes) { return E_NOTIMPL; } HRESULT CProgram::GetDisassemblyStream(DISASSEMBLY_STREAM_SCOPE dwScope, IDebugCodeContext2* pCodeContext, IDebugDisassemblyStream2** ppDisassemblyStream) { return E_NOTIMPL; } HRESULT CProgram::EnumModules(IEnumDebugModules2** ppEnum) { return E_NOTIMPL; } HRESULT CProgram::GetENCUpdate(IDebugENCUpdate** ppUpdate) { return E_NOTIMPL; } HRESULT CProgram::EnumCodePaths(LPCOLESTR pszHint, IDebugCodeContext2* pStart, IDebugStackFrame2* pFrame, BOOL fSource, IEnumCodePaths2** ppEnum, IDebugCodeContext2** ppSafety) { return E_NOTIMPL; } HRESULT CProgram::WriteDump(DUMPTYPE DumpType,LPCOLESTR pszCrashDumpUrl) { return E_NOTIMPL; } HRESULT CProgram::CanDetach(void) { return E_NOTIMPL; } HRESULT CProgram::GetProgramId(GUID* pguidProgramId) { //TODO: RETURN PROGRAM GUID return E_NOTIMPL; } HRESULT CProgram::Execute(void) { //TODO: BEGIN EXECUTION return E_NOTIMPL; } HRESULT CProgram::Continue(IDebugThread2 *pThread) { //TODO: CONTINUE EXECUTION return E_NOTIMPL; } HRESULT CProgram::Step(IDebugThread2 *pThread, STEPKIND sk, STEPUNIT step) { //TODO: STEP EXECUTION return E_NOTIMPL; } ////////////////////////////////////////////////////////////////////////////// //IDebugThread2 methods HRESULT CProgram::SetThreadName(LPCOLESTR pszName) { return E_NOTIMPL; } HRESULT CProgram::GetProgram(IDebugProgram2** ppProgram) { return E_NOTIMPL; } HRESULT CProgram::CanSetNextStatement(IDebugStackFrame2 *pStackFrame, IDebugCodeContext2 *pCodeContext) { return E_NOTIMPL; } HRESULT CProgram::SetNextStatement(IDebugStackFrame2 *pStackFrame, IDebugCodeContext2 *pCodeContext) { return E_NOTIMPL; } HRESULT CProgram::Suspend(DWORD *pdwSuspendCount) { return E_NOTIMPL; } HRESULT CProgram::Resume(DWORD *pdwSuspendCount) { return E_NOTIMPL; } HRESULT CProgram::GetThreadProperties(THREADPROPERTY_FIELDS dwFields, THREADPROPERTIES *ptp) { return E_NOTIMPL; } HRESULT CProgram::GetLogicalThread(IDebugStackFrame2 *pStackFrame, IDebugLogicalThread2 **ppLogicalThread) { return E_NOTIMPL; } HRESULT CProgram::GetThreadId(DWORD* pdwThreadId) { //TODO: RETURN THREAD ID return E_NOTIMPL; } HRESULT CProgram::EnumFrameInfo(FRAMEINFO_FLAGS dwFieldSpec, UINT nRadix, IEnumDebugFrameInfo2 **ppEnum) { //TODO: RETURN ENUMERATION OF FRAMES return E_NOTIMPL; }
Build the project to make sure there are no errors.