From 7ee1250e4601535625f7e9dde1fa20f316ac444f Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 31 Oct 2011 09:15:39 +1100 Subject: [PATCH] mscoree: Implement ICorDebug EnumerateProcesses. --- dlls/mscoree/cordebug.c | 122 ++++++++++++++++++++++++++++++++- dlls/mscoree/mscoree_private.h | 10 +++ dlls/mscoree/tests/debugging.c | 26 +++++++ 3 files changed, 156 insertions(+), 2 deletions(-) diff --git a/dlls/mscoree/cordebug.c b/dlls/mscoree/cordebug.c index c5342bce81..04c6e585a6 100644 --- a/dlls/mscoree/cordebug.c +++ b/dlls/mscoree/cordebug.c @@ -45,6 +45,104 @@ static inline CorDebug *impl_from_ICorDebug( ICorDebug *iface ) return CONTAINING_RECORD(iface, CorDebug, ICorDebug_iface); } +static inline CorDebug *impl_from_ICorDebugProcessEnum( ICorDebugProcessEnum *iface ) +{ + return CONTAINING_RECORD(iface, CorDebug, ICorDebugProcessEnum_iface); +} + +static HRESULT WINAPI process_enum_QueryInterface(ICorDebugProcessEnum *iface, REFIID riid, void **ppvObject) +{ + CorDebug *This = impl_from_ICorDebugProcessEnum(iface); + + TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); + + if ( IsEqualGUID( riid, &IID_ICorDebugProcessEnum ) || + IsEqualGUID( riid, &IID_ICorDebugEnum ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = &This->ICorDebugProcessEnum_iface; + } + else + { + FIXME("Unsupported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + ICorDebug_AddRef(iface); + + return S_OK; +} + +static ULONG WINAPI process_enum_AddRef(ICorDebugProcessEnum *iface) +{ + CorDebug *This = impl_from_ICorDebugProcessEnum(iface); + TRACE("%p ref=%u\n", This, This->ref); + + return ICorDebug_AddRef(&This->ICorDebug_iface); +} + +static ULONG WINAPI process_enum_Release(ICorDebugProcessEnum *iface) +{ + CorDebug *This = impl_from_ICorDebugProcessEnum(iface); + TRACE("%p ref=%u\n", This, This->ref); + + return ICorDebug_Release(&This->ICorDebug_iface); +} + +static HRESULT WINAPI process_enum_Skip(ICorDebugProcessEnum *iface, ULONG celt) +{ + CorDebug *This = impl_from_ICorDebugProcessEnum(iface); + FIXME("stub %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI process_enum_Reset(ICorDebugProcessEnum *iface) +{ + CorDebug *This = impl_from_ICorDebugProcessEnum(iface); + FIXME("stub %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI process_enum_Clone(ICorDebugProcessEnum *iface, ICorDebugEnum **ppEnum) +{ + CorDebug *This = impl_from_ICorDebugProcessEnum(iface); + FIXME("stub %p %p\n", This, ppEnum); + return E_NOTIMPL; +} + +static HRESULT WINAPI process_enum_GetCount(ICorDebugProcessEnum *iface, ULONG *pcelt) +{ + CorDebug *This = impl_from_ICorDebugProcessEnum(iface); + TRACE("stub %p %p\n", This, pcelt); + + if(!pcelt) + return E_INVALIDARG; + + *pcelt = list_count(&This->processes); + + return S_OK; +} + +static HRESULT WINAPI process_enum_Next(ICorDebugProcessEnum *iface, ULONG celt, + ICorDebugProcess * processes[], ULONG *pceltFetched) +{ + CorDebug *This = impl_from_ICorDebugProcessEnum(iface); + FIXME("stub %p %d %p %p\n", This, celt, processes, pceltFetched); + return E_NOTIMPL; +} + +static const struct ICorDebugProcessEnumVtbl processenum_vtbl = +{ + process_enum_QueryInterface, + process_enum_AddRef, + process_enum_Release, + process_enum_Skip, + process_enum_Reset, + process_enum_Clone, + process_enum_GetCount, + process_enum_Next +}; + /*** IUnknown methods ***/ static HRESULT WINAPI CorDebug_QueryInterface(ICorDebug *iface, REFIID riid, void **ppvObject) { @@ -82,11 +180,21 @@ static ULONG WINAPI CorDebug_Release(ICorDebug *iface) { CorDebug *This = impl_from_ICorDebug( iface ); ULONG ref = InterlockedDecrement(&This->ref); + struct CorProcess *cursor, *cursor2; TRACE("%p ref=%u\n", This, ref); if (ref == 0) { + LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->processes, struct CorProcess, entry) + { + if(cursor->pProcess) + ICorDebugProcess_Release(cursor->pProcess); + + list_remove(&cursor->entry); + HeapFree(GetProcessHeap(), 0, cursor); + } + if(This->runtimehost) ICLRRuntimeHost_Release(This->runtimehost); @@ -183,8 +291,15 @@ static HRESULT WINAPI CorDebug_DebugActiveProcess(ICorDebug *iface, DWORD id, BO static HRESULT WINAPI CorDebug_EnumerateProcesses( ICorDebug *iface, ICorDebugProcessEnum **ppProcess) { CorDebug *This = impl_from_ICorDebug( iface ); - FIXME("stub %p %p\n", This, ppProcess); - return E_NOTIMPL; + TRACE("stub %p %p\n", This, ppProcess); + + if(!ppProcess) + return E_INVALIDARG; + + *ppProcess = &This->ICorDebugProcessEnum_iface; + ICorDebugProcessEnum_AddRef(*ppProcess); + + return S_OK; } static HRESULT WINAPI CorDebug_GetProcess(ICorDebug *iface, DWORD dwProcessId, ICorDebugProcess **ppProcess) @@ -227,11 +342,14 @@ HRESULT CorDebug_Create(ICLRRuntimeHost *runtimehost, IUnknown** ppUnk) return E_OUTOFMEMORY; This->ICorDebug_iface.lpVtbl = &cordebug_vtbl; + This->ICorDebugProcessEnum_iface.lpVtbl = &processenum_vtbl; This->ref = 1; This->pCallback = NULL; This->pCallback2 = NULL; This->runtimehost = runtimehost; + list_init(&This->processes); + if(This->runtimehost) ICLRRuntimeHost_AddRef(This->runtimehost); diff --git a/dlls/mscoree/mscoree_private.h b/dlls/mscoree/mscoree_private.h index 3c9ef1e699..71bf7389d4 100644 --- a/dlls/mscoree/mscoree_private.h +++ b/dlls/mscoree/mscoree_private.h @@ -72,9 +72,16 @@ struct RuntimeHost LONG ref; }; +typedef struct CorProcess +{ + struct list entry; + ICorDebugProcess *pProcess; +} CorProcess; + typedef struct CorDebug { ICorDebug ICorDebug_iface; + ICorDebugProcessEnum ICorDebugProcessEnum_iface; LONG ref; ICLRRuntimeHost *runtimehost; @@ -82,6 +89,9 @@ typedef struct CorDebug /* ICorDebug Callback */ ICorDebugManagedCallback *pCallback; ICorDebugManagedCallback2 *pCallback2; + + /* Debug Processes */ + struct list processes; } CorDebug; extern HRESULT get_runtime_info(LPCWSTR exefile, LPCWSTR version, LPCWSTR config_file, diff --git a/dlls/mscoree/tests/debugging.c b/dlls/mscoree/tests/debugging.c index fb5abe301c..bd961edc5d 100644 --- a/dlls/mscoree/tests/debugging.c +++ b/dlls/mscoree/tests/debugging.c @@ -418,6 +418,29 @@ static BOOL init_functionpointers(void) return TRUE; } +#define check_process_enum(core, e) _check_process_enum(__LINE__, core, e) +static void _check_process_enum(unsigned line, ICorDebug *pCorDebug, ULONG nExpected) +{ + HRESULT hr; + ICorDebugProcessEnum *pProcessEnum = NULL; + + hr = ICorDebug_EnumerateProcesses(pCorDebug, NULL); + ok_(__FILE__,line) (hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr); + + hr = ICorDebug_EnumerateProcesses(pCorDebug, &pProcessEnum); + ok_(__FILE__,line) (hr == S_OK, "expected S_OK got %08x\n", hr); + if(hr == S_OK) + { + ULONG cnt; + + hr = ICorDebugProcessEnum_GetCount(pProcessEnum, &cnt); + ok_(__FILE__,line) (hr == S_OK, "expected S_OK got %08x\n", hr); + ok_(__FILE__,line) (cnt == nExpected, "expected %d got %d\n", nExpected, cnt); + + ICorDebugProcessEnum_Release(pProcessEnum); + } +} + static void test_createDebugger(void) { HRESULT hr; @@ -455,6 +478,9 @@ static void test_createDebugger(void) hr = ICorDebug_SetManagedHandler(pCorDebug, &ManagedCallback); ok(hr == S_OK, "expected S_OK got %08x\n", hr); + + /* We should have no processes */ + check_process_enum(pCorDebug, 0); } ICorDebug_Release(pCorDebug); -- 2.32.0.93.g670b81a890