| /* |
| * 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 <stdio.h> |
| |
| #include "windows.h" |
| #include "ole2.h" |
| #include "corerror.h" |
| #include "mscoree.h" |
| #include "corhdr.h" |
| |
| #include "wine/test.h" |
| |
| #include "initguid.h" |
| #include "cordebug.h" |
| |
| static HMODULE hmscoree; |
| |
| static HRESULT (WINAPI *pCreateDebuggingInterfaceFromVersion)(int, LPCWSTR, IUnknown **); |
| |
| const WCHAR v2_0[] = {'v','2','.','0','.','5','0','7','2','7',0}; |
| |
| static HRESULT WINAPI ManagedCallback2_QueryInterface(ICorDebugManagedCallback2 *iface, REFIID riid, void **ppv) |
| { |
| if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ICorDebugManagedCallback2, riid)) |
| { |
| *ppv = iface; |
| return S_OK; |
| } |
| |
| ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid)); |
| |
| *ppv = NULL; |
| return E_NOINTERFACE; |
| } |
| |
| static ULONG WINAPI ManagedCallback2_AddRef(ICorDebugManagedCallback2 *iface) |
| { |
| return 2; |
| } |
| |
| static ULONG WINAPI ManagedCallback2_Release(ICorDebugManagedCallback2 *iface) |
| { |
| return 1; |
| } |
| |
| static HRESULT WINAPI ManagedCallback2_FunctionRemapOpportunity(ICorDebugManagedCallback2 *iface, |
| ICorDebugAppDomain *pAppDomain, ICorDebugThread *pThread, |
| ICorDebugFunction *pOldFunction, ICorDebugFunction *pNewFunction, |
| ULONG32 oldILOffset) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback2_CreateConnection(ICorDebugManagedCallback2 *iface, |
| ICorDebugProcess *pProcess, CONNID dwConnectionId, WCHAR *pConnName) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback2_ChangeConnection(ICorDebugManagedCallback2 *iface, |
| ICorDebugProcess *pProcess, CONNID dwConnectionId) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback2_DestroyConnection(ICorDebugManagedCallback2 *iface, |
| ICorDebugProcess *pProcess, CONNID dwConnectionId) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback2_Exception(ICorDebugManagedCallback2 *iface, |
| ICorDebugAppDomain *pAppDomain, ICorDebugThread *pThread, |
| ICorDebugFrame *pFrame, ULONG32 nOffset, |
| CorDebugExceptionCallbackType dwEventType, DWORD dwFlags) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback2_ExceptionUnwind(ICorDebugManagedCallback2 *iface, |
| ICorDebugAppDomain *pAppDomain, ICorDebugThread *pThread, |
| CorDebugExceptionUnwindCallbackType dwEventType, DWORD dwFlags) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback2_FunctionRemapComplete(ICorDebugManagedCallback2 *iface, |
| ICorDebugAppDomain *pAppDomain, ICorDebugThread *pThread, |
| ICorDebugFunction *pFunction) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback2_MDANotification(ICorDebugManagedCallback2 *iface, |
| ICorDebugController *pController, ICorDebugThread *pThread, |
| ICorDebugMDA *pMDA) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static struct ICorDebugManagedCallback2Vtbl managedCallback2Vtbl = { |
| ManagedCallback2_QueryInterface, |
| ManagedCallback2_AddRef, |
| ManagedCallback2_Release, |
| ManagedCallback2_FunctionRemapOpportunity, |
| ManagedCallback2_CreateConnection, |
| ManagedCallback2_ChangeConnection, |
| ManagedCallback2_DestroyConnection, |
| ManagedCallback2_Exception, |
| ManagedCallback2_ExceptionUnwind, |
| ManagedCallback2_FunctionRemapComplete, |
| ManagedCallback2_MDANotification |
| }; |
| |
| static ICorDebugManagedCallback2 ManagedCallback2 = { &managedCallback2Vtbl }; |
| |
| static HRESULT WINAPI ManagedCallback_QueryInterface(ICorDebugManagedCallback *iface, REFIID riid, void **ppv) |
| { |
| if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ICorDebugManagedCallback, riid)) |
| { |
| *ppv = iface; |
| return S_OK; |
| } |
| else if(IsEqualGUID(&IID_ICorDebugManagedCallback2, riid)) |
| { |
| *ppv = (void**)&ManagedCallback2; |
| return S_OK; |
| } |
| |
| ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid)); |
| *ppv = NULL; |
| return E_NOINTERFACE; |
| } |
| |
| static ULONG WINAPI ManagedCallback_AddRef(ICorDebugManagedCallback *iface) |
| { |
| return 2; |
| } |
| |
| static ULONG WINAPI ManagedCallback_Release(ICorDebugManagedCallback *iface) |
| { |
| return 1; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_Breakpoint(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *pThread, ICorDebugBreakpoint *pBreakpoint) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_StepComplete(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *pThread, ICorDebugStepper *pStepper, CorDebugStepReason reason) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_Break(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *thread) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_Exception(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *pThread, BOOL unhandled) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_EvalComplete(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *pThread, ICorDebugEval *pEval) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_EvalException(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *pThread, ICorDebugEval *pEval) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_CreateProcess(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_ExitProcess(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_CreateThread(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *thread) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_ExitThread(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *thread) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_LoadModule(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugModule *pModule) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_UnloadModule(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugModule *pModule) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_LoadClass(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugClass *c) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_UnloadClass(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugClass *c) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_DebuggerError(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess, |
| HRESULT errorHR, DWORD errorCode) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_LogMessage(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *pThread, LONG lLevel, WCHAR *pLogSwitchName, WCHAR *pMessage) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_LogSwitch(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *pThread, LONG lLevel, ULONG ulReason, |
| WCHAR *pLogSwitchName, WCHAR *pParentName) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_CreateAppDomain(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess, |
| ICorDebugAppDomain *pAppDomain) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_ExitAppDomain(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess, |
| ICorDebugAppDomain *pAppDomain) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_LoadAssembly(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugAssembly *pAssembly) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_UnloadAssembly(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugAssembly *pAssembly) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_ControlCTrap(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_NameChange(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *pThread) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_UpdateModuleSymbols(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugModule *pModule, IStream *pSymbolStream) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_EditAndContinueRemap(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *pThread, ICorDebugFunction *pFunction, BOOL fAccurate) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI ManagedCallback_BreakpointSetError(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain, |
| ICorDebugThread *pThread, ICorDebugBreakpoint *pBreakpoint, DWORD dwError) |
| { |
| ok(0, "unexpected call\n"); |
| return E_NOTIMPL; |
| } |
| |
| static ICorDebugManagedCallbackVtbl managedCallbackVtbl = { |
| ManagedCallback_QueryInterface, |
| ManagedCallback_AddRef, |
| ManagedCallback_Release, |
| ManagedCallback_Breakpoint, |
| ManagedCallback_StepComplete, |
| ManagedCallback_Break, |
| ManagedCallback_Exception, |
| ManagedCallback_EvalComplete, |
| ManagedCallback_EvalException, |
| ManagedCallback_CreateProcess, |
| ManagedCallback_ExitProcess, |
| ManagedCallback_CreateThread, |
| ManagedCallback_ExitThread, |
| ManagedCallback_LoadModule, |
| ManagedCallback_UnloadModule, |
| ManagedCallback_LoadClass, |
| ManagedCallback_UnloadClass, |
| ManagedCallback_DebuggerError, |
| ManagedCallback_LogMessage, |
| ManagedCallback_LogSwitch, |
| ManagedCallback_CreateAppDomain, |
| ManagedCallback_ExitAppDomain, |
| ManagedCallback_LoadAssembly, |
| ManagedCallback_UnloadAssembly, |
| ManagedCallback_ControlCTrap, |
| ManagedCallback_NameChange, |
| ManagedCallback_UpdateModuleSymbols, |
| ManagedCallback_EditAndContinueRemap, |
| ManagedCallback_BreakpointSetError |
| }; |
| |
| static ICorDebugManagedCallback ManagedCallback = { &managedCallbackVtbl }; |
| |
| static BOOL init_functionpointers(void) |
| { |
| hmscoree = LoadLibraryA("mscoree.dll"); |
| |
| if (!hmscoree) |
| { |
| win_skip("mscoree.dll not available\n"); |
| return FALSE; |
| } |
| |
| pCreateDebuggingInterfaceFromVersion = (void *)GetProcAddress(hmscoree, "CreateDebuggingInterfaceFromVersion"); |
| |
| if (!pCreateDebuggingInterfaceFromVersion) |
| { |
| win_skip("functions not available\n"); |
| FreeLibrary(hmscoree); |
| return FALSE; |
| } |
| |
| 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; |
| IUnknown *pUnk; |
| ICorDebug *pCorDebug; |
| |
| hr = pCreateDebuggingInterfaceFromVersion(0, v2_0, &pUnk); |
| ok(hr == E_INVALIDARG, "CreateDebuggingInterfaceFromVersion returned %08x\n", hr); |
| |
| hr = pCreateDebuggingInterfaceFromVersion(1, v2_0, &pUnk); |
| ok(hr == E_INVALIDARG, "CreateDebuggingInterfaceFromVersion returned %08x\n", hr); |
| |
| hr = pCreateDebuggingInterfaceFromVersion(2, v2_0, &pUnk); |
| ok(hr == E_INVALIDARG, "CreateDebuggingInterfaceFromVersion returned %08x\n", hr); |
| |
| hr = pCreateDebuggingInterfaceFromVersion(4, v2_0, &pUnk); |
| ok(hr == E_INVALIDARG, "CreateDebuggingInterfaceFromVersion returned %08x\n", hr); |
| |
| hr = pCreateDebuggingInterfaceFromVersion(3, v2_0, NULL); |
| ok(hr == E_INVALIDARG, "CreateDebuggingInterfaceFromVersion returned %08x\n", hr); |
| |
| hr = pCreateDebuggingInterfaceFromVersion(3, v2_0, &pUnk); |
| if(hr == S_OK) |
| { |
| hr = IUnknown_QueryInterface(pUnk, &IID_ICorDebug, (void**)&pCorDebug); |
| ok(hr == S_OK, "expected S_OK got %08x\n", hr); |
| if(hr == S_OK) |
| { |
| hr = ICorDebug_Initialize(pCorDebug); |
| ok(hr == S_OK, "expected S_OK got %08x\n", hr); |
| if(hr == S_OK) |
| { |
| hr = ICorDebug_SetManagedHandler(pCorDebug, NULL); |
| ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr); |
| |
| 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); |
| } |
| IUnknown_Release(pUnk); |
| } |
| else |
| { |
| skip(".NET 2.0 or mono not installed.\n"); |
| } |
| } |
| |
| START_TEST(debugging) |
| { |
| CoInitialize(NULL); |
| |
| if (!init_functionpointers()) |
| return; |
| |
| test_createDebugger(); |
| |
| FreeLibrary(hmscoree); |
| CoUninitialize(); |
| } |