mscoree: Implement ICorDebug EnumerateProcesses.
This commit is contained in:
parent
4ec87b3e8d
commit
7ee1250e46
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue