/*
 *
 * Copyright 2011 Alistair Leslie-Hughes
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"

#include "winuser.h"
#include "winnls.h"
#include "winreg.h"
#include "ole2.h"
#include "shellapi.h"
#include "mscoree.h"
#include "corhdr.h"
#include "metahost.h"
#include "cordebug.h"
#include "wine/list.h"
#include "mscoree_private.h"
#include "wine/debug.h"


WINE_DEFAULT_DEBUG_CHANNEL( mscoree );

typedef struct DebugProcess
{
    ICorDebugProcess ICorDebugProcess_iface;

    CorDebug *cordebug;

    DWORD dwProcessID;
    HANDLE handle;
    HANDLE thread;

    LONG ref;
} DebugProcess;

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 inline DebugProcess *impl_from_ICorDebugProcess( ICorDebugProcess *iface )
{
    return CONTAINING_RECORD(iface, DebugProcess, ICorDebugProcess_iface);
}

/* ICorDebugProcess Interface */
static HRESULT WINAPI cordebugprocess_QueryInterface(ICorDebugProcess *iface,
                REFIID riid, void **ppvObject)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);

    TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);

    if ( IsEqualGUID( riid, &IID_ICorDebugProcess ) ||
         IsEqualGUID( riid, &IID_ICorDebugController ) ||
         IsEqualGUID( riid, &IID_IUnknown ) )
    {
        *ppvObject = &This->ICorDebugProcess_iface;
    }
    else
    {
        FIXME("Unsupported interface %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    ICorDebugProcess_AddRef(iface);

    return S_OK;
}

static ULONG WINAPI cordebugprocess_AddRef(ICorDebugProcess *iface)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("%p ref=%u\n", This, ref);

    return ref;
}

static ULONG WINAPI cordebugprocess_Release(ICorDebugProcess *iface)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("%p ref=%u\n", This, ref);

    if (ref == 0)
    {
        if(This->handle)
            CloseHandle(This->handle);

        if(This->thread)
            CloseHandle(This->thread);

        if(This->cordebug)
            ICorDebug_Release(&This->cordebug->ICorDebug_iface);

        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI cordebugprocess_Stop(ICorDebugProcess *iface, DWORD dwTimeoutIgnored)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_Continue(ICorDebugProcess *iface, BOOL fIsOutOfBand)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    TRACE("%p\n", This);

    if(This->thread)
        ResumeThread(This->thread);

    return S_OK;
}

static HRESULT WINAPI cordebugprocess_IsRunning(ICorDebugProcess *iface, BOOL *pbRunning)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_HasQueuedCallbacks(ICorDebugProcess *iface,
                ICorDebugThread *pThread, BOOL *pbQueued)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_EnumerateThreads(ICorDebugProcess *iface,
                ICorDebugThreadEnum **ppThreads)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_SetAllThreadsDebugState(ICorDebugProcess *iface,
                CorDebugThreadState state, ICorDebugThread *pExceptThisThread)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_Detach(ICorDebugProcess *iface)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_Terminate(ICorDebugProcess *iface, UINT exitCode)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    BOOL ret = TRUE;

    TRACE("%p\n", This);

    if(This->handle)
    {
        ret = TerminateProcess(This->handle, exitCode);
        CloseHandle(This->handle);
        This->handle = NULL;
    }
    return ret ? S_OK : E_FAIL;
}

static HRESULT WINAPI cordebugprocess_CanCommitChanges(ICorDebugProcess *iface,
                ULONG cSnapshots, ICorDebugEditAndContinueSnapshot * pSnapshots[],
                ICorDebugErrorInfoEnum **pError)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_CommitChanges(ICorDebugProcess *iface,
                ULONG cSnapshots, ICorDebugEditAndContinueSnapshot * pSnapshots[],
                ICorDebugErrorInfoEnum **pError)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_GetID(ICorDebugProcess *iface, DWORD *pdwProcessId)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    TRACE("%p\n", This);

    if(!pdwProcessId)
        return E_INVALIDARG;

    *pdwProcessId = This->dwProcessID;

    return S_OK;
}

static HRESULT WINAPI cordebugprocess_GetHandle(ICorDebugProcess *iface, HPROCESS *phProcessHandle)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    TRACE("%p\n", This);

    if(!phProcessHandle)
        return E_INVALIDARG;

    *phProcessHandle = This->handle;

    return S_OK;
}

static HRESULT WINAPI cordebugprocess_GetThread(ICorDebugProcess *iface, DWORD dwThreadId,
                ICorDebugThread **ppThread)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_EnumerateObjects(ICorDebugProcess *iface,
                ICorDebugObjectEnum **ppObjects)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_IsTransitionStub(ICorDebugProcess *iface,
                CORDB_ADDRESS address, BOOL *pbTransitionStub)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_IsOSSuspended(ICorDebugProcess *iface,
                DWORD threadID, BOOL *pbSuspended)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_GetThreadContext(ICorDebugProcess *iface,
                DWORD threadID, ULONG32 contextSize, BYTE context[])
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_SetThreadContext(ICorDebugProcess *iface,
                DWORD threadID, ULONG32 contextSize, BYTE context[])
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_ReadMemory(ICorDebugProcess *iface,
                CORDB_ADDRESS address, DWORD size, BYTE buffer[],
                SIZE_T *read)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_WriteMemory(ICorDebugProcess *iface,
                CORDB_ADDRESS address, DWORD size, BYTE buffer[],
                SIZE_T *written)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_ClearCurrentException(ICorDebugProcess *iface,
                DWORD threadID)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_EnableLogMessages(ICorDebugProcess *iface,
                BOOL fOnOff)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_ModifyLogSwitch(ICorDebugProcess *iface,
                WCHAR *pLogSwitchName, LONG lLevel)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_EnumerateAppDomains(ICorDebugProcess *iface,
                ICorDebugAppDomainEnum **ppAppDomains)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_GetObject(ICorDebugProcess *iface,
                ICorDebugValue **ppObject)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_ThreadForFiberCookie(ICorDebugProcess *iface,
                DWORD fiberCookie, ICorDebugThread **ppThread)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI cordebugprocess_GetHelperThreadID(ICorDebugProcess *iface,
                DWORD *pThreadID)
{
    DebugProcess *This = impl_from_ICorDebugProcess(iface);
    FIXME("stub %p\n", This);
    return E_NOTIMPL;
}


/***************************************/
static const ICorDebugProcessVtbl cordebugprocessVtbl = {
    cordebugprocess_QueryInterface,
    cordebugprocess_AddRef,
    cordebugprocess_Release,
    cordebugprocess_Stop,
    cordebugprocess_Continue,
    cordebugprocess_IsRunning,
    cordebugprocess_HasQueuedCallbacks,
    cordebugprocess_EnumerateThreads,
    cordebugprocess_SetAllThreadsDebugState,
    cordebugprocess_Detach,
    cordebugprocess_Terminate,
    cordebugprocess_CanCommitChanges,
    cordebugprocess_CommitChanges,
    cordebugprocess_GetID,
    cordebugprocess_GetHandle,
    cordebugprocess_GetThread,
    cordebugprocess_EnumerateObjects,
    cordebugprocess_IsTransitionStub,
    cordebugprocess_IsOSSuspended,
    cordebugprocess_GetThreadContext,
    cordebugprocess_SetThreadContext,
    cordebugprocess_ReadMemory,
    cordebugprocess_WriteMemory,
    cordebugprocess_ClearCurrentException,
    cordebugprocess_EnableLogMessages,
    cordebugprocess_ModifyLogSwitch,
    cordebugprocess_EnumerateAppDomains,
    cordebugprocess_GetObject,
    cordebugprocess_ThreadForFiberCookie,
    cordebugprocess_GetHelperThreadID
};


static HRESULT CorDebugProcess_Create(CorDebug *cordebug, IUnknown** ppUnk, LPPROCESS_INFORMATION lpProcessInformation)
{
    DebugProcess *This;

    This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
    if ( !This )
        return E_OUTOFMEMORY;

    if(!DuplicateHandle(GetCurrentProcess(), lpProcessInformation->hProcess,
                    GetCurrentProcess(), &This->handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
    {
        ERR("Failed to duplicate process handle\n");
        HeapFree(GetProcessHeap(), 0, This);
        return E_FAIL;
    }
    if(!DuplicateHandle(GetCurrentProcess(), lpProcessInformation->hThread,
                    GetCurrentProcess(), &This->thread, 0, FALSE, DUPLICATE_SAME_ACCESS))
    {
        CloseHandle(This->handle);

        ERR("Failed to duplicate thread handle\n");
        HeapFree(GetProcessHeap(), 0, This);
        return E_FAIL;
    }

    This->ICorDebugProcess_iface.lpVtbl = &cordebugprocessVtbl;
    This->ref = 1;
    This->cordebug = cordebug;
    This->dwProcessID = lpProcessInformation->dwProcessId;

    if(This->cordebug)
        ICorDebug_AddRef(&This->cordebug->ICorDebug_iface);

    *ppUnk = (IUnknown*)This;

    return S_OK;
}

/* ICorDebugProcessEnum Interface */
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;
    }

    ICorDebugProcessEnum_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)
{
    CorDebug *This = impl_from_ICorDebug( iface );

    TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);

    if ( IsEqualGUID( riid, &IID_ICorDebug ) ||
         IsEqualGUID( riid, &IID_IUnknown ) )
    {
        *ppvObject = &This->ICorDebug_iface;
    }
    else
    {
        FIXME("Unsupported interface %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    ICorDebug_AddRef( iface );

    return S_OK;
}

static ULONG WINAPI CorDebug_AddRef(ICorDebug *iface)
{
    CorDebug *This = impl_from_ICorDebug( iface );
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("%p ref=%u\n", This, ref);

    return ref;
}

static ULONG WINAPI CorDebug_Release(ICorDebug *iface)
{
    CorDebug *This = impl_from_ICorDebug( iface );
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("%p ref=%u\n", This, ref);

    if (ref == 0)
    {
        if(!list_empty(&This->processes))
            ERR("Processes haven't been removed Correctly\n");

        if(This->runtimehost)
            ICLRRuntimeHost_Release(This->runtimehost);

        if(This->pCallback)
            ICorDebugManagedCallback2_Release(This->pCallback2);

        if(This->pCallback)
            ICorDebugManagedCallback_Release(This->pCallback);

        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

/*** ICorDebug methods ***/
static HRESULT WINAPI CorDebug_Initialize(ICorDebug *iface)
{
    CorDebug *This = impl_from_ICorDebug( iface );
    FIXME("stub %p\n", This);
    return S_OK;
}

static HRESULT WINAPI CorDebug_Terminate(ICorDebug *iface)
{
    struct CorProcess *cursor, *cursor2;
    CorDebug *This = impl_from_ICorDebug( iface );
    TRACE("stub %p\n", This);

    LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->processes, struct CorProcess, entry)
    {
        if(cursor->pProcess)
        {
            ICorDebugProcess_Terminate(cursor->pProcess, 0);
            ICorDebugProcess_Release(cursor->pProcess);
        }

        list_remove(&cursor->entry);
        HeapFree(GetProcessHeap(), 0, cursor);
    }

    return S_OK;
}

static HRESULT WINAPI CorDebug_SetManagedHandler(ICorDebug *iface, ICorDebugManagedCallback *pCallback)
{
    CorDebug *This = impl_from_ICorDebug( iface );
    HRESULT hr;
    ICorDebugManagedCallback2 *pCallback2;

    TRACE("%p (%p)\n", This, pCallback);

    if(!pCallback)
        return E_INVALIDARG;

    hr = ICorDebugManagedCallback_QueryInterface(pCallback, &IID_ICorDebugManagedCallback2, (void**)&pCallback2);
    if(hr == S_OK)
    {
        if(This->pCallback2)
            ICorDebugManagedCallback2_Release(This->pCallback2);

        if(This->pCallback)
            ICorDebugManagedCallback_Release(This->pCallback);

        This->pCallback = pCallback;
        This->pCallback2 = pCallback2;

        ICorDebugManagedCallback_AddRef(This->pCallback);
    }
    else
    {
        WARN("Debugging without interface ICorDebugManagedCallback2 is currently not supported.\n");
    }

    return hr;
}

static HRESULT WINAPI CorDebug_SetUnmanagedHandler(ICorDebug *iface, ICorDebugUnmanagedCallback *pCallback)
{
    CorDebug *This = impl_from_ICorDebug( iface );
    FIXME("stub %p %p\n", This, pCallback);
    return E_NOTIMPL;
}

static HRESULT WINAPI CorDebug_CreateProcess(ICorDebug *iface, LPCWSTR lpApplicationName,
            LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,
            LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles,
            DWORD dwCreationFlags, PVOID lpEnvironment,LPCWSTR lpCurrentDirectory,
            LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation,
            CorDebugCreateProcessFlags debuggingFlags, ICorDebugProcess **ppProcess)
{
    CorDebug *This = impl_from_ICorDebug( iface );
    ICorDebugProcess *pDebugProcess;
    HRESULT hr;

    TRACE("stub %p %s %s %p %p %d %d %p %s %p %p %d %p\n", This, debugstr_w(lpApplicationName),
            debugstr_w(lpCommandLine), lpProcessAttributes, lpThreadAttributes,
            bInheritHandles, dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
            lpStartupInfo, lpProcessInformation, debuggingFlags, ppProcess);

    if(CreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes,
            bInheritHandles, dwCreationFlags | CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory,
            lpStartupInfo, lpProcessInformation))
    {
        hr = CorDebugProcess_Create(This, (IUnknown**)&pDebugProcess, lpProcessInformation);
        if(hr == S_OK)
        {
            struct CorProcess *new_process = HeapAlloc( GetProcessHeap(), 0, sizeof(CorProcess) );

            new_process->pProcess = pDebugProcess;
            list_add_tail(&This->processes, &new_process->entry);

            ICorDebugProcess_AddRef(pDebugProcess);
            *ppProcess = pDebugProcess;

            if(This->pCallback)
                ICorDebugManagedCallback_CreateProcess(This->pCallback, pDebugProcess);
        }
        else
        {
            TerminateProcess(lpProcessInformation->hProcess, 0);
        }
    }
    else
        hr = E_FAIL;

    return hr;
}

static HRESULT WINAPI CorDebug_DebugActiveProcess(ICorDebug *iface, DWORD id, BOOL win32Attach,
            ICorDebugProcess **ppProcess)
{
    CorDebug *This = impl_from_ICorDebug( iface );
    FIXME("stub %p %d %d %p\n", This, id, win32Attach, ppProcess);
    return E_NOTIMPL;
}

static HRESULT WINAPI CorDebug_EnumerateProcesses( ICorDebug *iface, ICorDebugProcessEnum **ppProcess)
{
    CorDebug *This = impl_from_ICorDebug( iface );
    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)
{
    CorDebug *This = impl_from_ICorDebug( iface );
    FIXME("stub %p %d %p\n", This, dwProcessId, ppProcess);
    return E_NOTIMPL;
}

static HRESULT WINAPI CorDebug_CanLaunchOrAttach(ICorDebug *iface, DWORD dwProcessId,
            BOOL win32DebuggingEnabled)
{
    CorDebug *This = impl_from_ICorDebug( iface );
    FIXME("stub %p %d %d\n", This, dwProcessId, win32DebuggingEnabled);
    return S_OK;
}

static const struct ICorDebugVtbl cordebug_vtbl =
{
    CorDebug_QueryInterface,
    CorDebug_AddRef,
    CorDebug_Release,
    CorDebug_Initialize,
    CorDebug_Terminate,
    CorDebug_SetManagedHandler,
    CorDebug_SetUnmanagedHandler,
    CorDebug_CreateProcess,
    CorDebug_DebugActiveProcess,
    CorDebug_EnumerateProcesses,
    CorDebug_GetProcess,
    CorDebug_CanLaunchOrAttach
};

HRESULT CorDebug_Create(ICLRRuntimeHost *runtimehost, IUnknown** ppUnk)
{
    CorDebug *This;

    This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
    if ( !This )
        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);

    *ppUnk = (IUnknown*)This;

    return S_OK;
}
