1 /*
2  * Copyright 2011 Alistair Leslie-Hughes
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #define COBJMACROS
20 #include <stdio.h>
21 
22 #include "windows.h"
23 #include "ole2.h"
24 #include "corerror.h"
25 #include "mscoree.h"
26 #include "corhdr.h"
27 
28 #include "wine/test.h"
29 
30 #include "initguid.h"
31 #include "cordebug.h"
32 
33 static HMODULE hmscoree;
34 
35 static HRESULT (WINAPI *pCreateDebuggingInterfaceFromVersion)(int, LPCWSTR, IUnknown **);
36 
37 const WCHAR v2_0[] = {'v','2','.','0','.','5','0','7','2','7',0};
38 
debugstr_guid(REFIID riid)39 static const char *debugstr_guid(REFIID riid)
40 {
41     static char buf[50];
42 
43     if(!riid)
44         return "(null)";
45 
46     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
47             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
48             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
49             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
50 
51     return buf;
52 }
53 
ManagedCallback2_QueryInterface(ICorDebugManagedCallback2 * iface,REFIID riid,void ** ppv)54 static HRESULT WINAPI ManagedCallback2_QueryInterface(ICorDebugManagedCallback2 *iface, REFIID riid, void **ppv)
55 {
56     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ICorDebugManagedCallback2, riid))
57     {
58         *ppv = iface;
59         return S_OK;
60     }
61 
62     ok(0, "unexpected riid (%s)\n", debugstr_guid(riid));
63 
64     *ppv = NULL;
65     return E_NOINTERFACE;
66 }
67 
ManagedCallback2_AddRef(ICorDebugManagedCallback2 * iface)68 static ULONG WINAPI ManagedCallback2_AddRef(ICorDebugManagedCallback2 *iface)
69 {
70     return 2;
71 }
72 
ManagedCallback2_Release(ICorDebugManagedCallback2 * iface)73 static ULONG WINAPI ManagedCallback2_Release(ICorDebugManagedCallback2 *iface)
74 {
75     return 1;
76 }
77 
ManagedCallback2_FunctionRemapOpportunity(ICorDebugManagedCallback2 * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,ICorDebugFunction * pOldFunction,ICorDebugFunction * pNewFunction,ULONG32 oldILOffset)78 static HRESULT WINAPI ManagedCallback2_FunctionRemapOpportunity(ICorDebugManagedCallback2 *iface,
79                 ICorDebugAppDomain *pAppDomain, ICorDebugThread *pThread,
80                 ICorDebugFunction *pOldFunction, ICorDebugFunction *pNewFunction,
81                 ULONG32 oldILOffset)
82 {
83     ok(0, "unexpected call\n");
84     return E_NOTIMPL;
85 }
86 
ManagedCallback2_CreateConnection(ICorDebugManagedCallback2 * iface,ICorDebugProcess * pProcess,CONNID dwConnectionId,WCHAR * pConnName)87 static HRESULT WINAPI ManagedCallback2_CreateConnection(ICorDebugManagedCallback2 *iface,
88                 ICorDebugProcess *pProcess, CONNID dwConnectionId, WCHAR *pConnName)
89 {
90     ok(0, "unexpected call\n");
91     return E_NOTIMPL;
92 }
93 
ManagedCallback2_ChangeConnection(ICorDebugManagedCallback2 * iface,ICorDebugProcess * pProcess,CONNID dwConnectionId)94 static HRESULT WINAPI ManagedCallback2_ChangeConnection(ICorDebugManagedCallback2 *iface,
95                 ICorDebugProcess *pProcess, CONNID dwConnectionId)
96 {
97     ok(0, "unexpected call\n");
98     return E_NOTIMPL;
99 }
100 
ManagedCallback2_DestroyConnection(ICorDebugManagedCallback2 * iface,ICorDebugProcess * pProcess,CONNID dwConnectionId)101 static HRESULT WINAPI ManagedCallback2_DestroyConnection(ICorDebugManagedCallback2 *iface,
102                 ICorDebugProcess *pProcess, CONNID dwConnectionId)
103 {
104     ok(0, "unexpected call\n");
105     return E_NOTIMPL;
106 }
107 
ManagedCallback2_Exception(ICorDebugManagedCallback2 * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,ICorDebugFrame * pFrame,ULONG32 nOffset,CorDebugExceptionCallbackType dwEventType,DWORD dwFlags)108 static HRESULT WINAPI ManagedCallback2_Exception(ICorDebugManagedCallback2 *iface,
109                 ICorDebugAppDomain *pAppDomain, ICorDebugThread *pThread,
110                 ICorDebugFrame *pFrame, ULONG32 nOffset,
111                 CorDebugExceptionCallbackType dwEventType, DWORD dwFlags)
112 {
113     ok(0, "unexpected call\n");
114     return E_NOTIMPL;
115 }
116 
ManagedCallback2_ExceptionUnwind(ICorDebugManagedCallback2 * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,CorDebugExceptionUnwindCallbackType dwEventType,DWORD dwFlags)117 static HRESULT WINAPI ManagedCallback2_ExceptionUnwind(ICorDebugManagedCallback2 *iface,
118                 ICorDebugAppDomain *pAppDomain, ICorDebugThread *pThread,
119                 CorDebugExceptionUnwindCallbackType dwEventType, DWORD dwFlags)
120 {
121     ok(0, "unexpected call\n");
122     return E_NOTIMPL;
123 }
124 
ManagedCallback2_FunctionRemapComplete(ICorDebugManagedCallback2 * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,ICorDebugFunction * pFunction)125 static HRESULT WINAPI ManagedCallback2_FunctionRemapComplete(ICorDebugManagedCallback2 *iface,
126                 ICorDebugAppDomain *pAppDomain, ICorDebugThread *pThread,
127                 ICorDebugFunction *pFunction)
128 {
129     ok(0, "unexpected call\n");
130     return E_NOTIMPL;
131 }
132 
ManagedCallback2_MDANotification(ICorDebugManagedCallback2 * iface,ICorDebugController * pController,ICorDebugThread * pThread,ICorDebugMDA * pMDA)133 static HRESULT WINAPI ManagedCallback2_MDANotification(ICorDebugManagedCallback2 *iface,
134                 ICorDebugController *pController, ICorDebugThread *pThread,
135                 ICorDebugMDA *pMDA)
136 {
137     ok(0, "unexpected call\n");
138     return E_NOTIMPL;
139 }
140 
141 static struct ICorDebugManagedCallback2Vtbl managedCallback2Vtbl = {
142     ManagedCallback2_QueryInterface,
143     ManagedCallback2_AddRef,
144     ManagedCallback2_Release,
145     ManagedCallback2_FunctionRemapOpportunity,
146     ManagedCallback2_CreateConnection,
147     ManagedCallback2_ChangeConnection,
148     ManagedCallback2_DestroyConnection,
149     ManagedCallback2_Exception,
150     ManagedCallback2_ExceptionUnwind,
151     ManagedCallback2_FunctionRemapComplete,
152     ManagedCallback2_MDANotification
153 };
154 
155 static ICorDebugManagedCallback2 ManagedCallback2 = { &managedCallback2Vtbl };
156 
ManagedCallback_QueryInterface(ICorDebugManagedCallback * iface,REFIID riid,void ** ppv)157 static HRESULT WINAPI ManagedCallback_QueryInterface(ICorDebugManagedCallback *iface, REFIID riid, void **ppv)
158 {
159     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ICorDebugManagedCallback, riid))
160     {
161         *ppv = iface;
162         return S_OK;
163     }
164     else if(IsEqualGUID(&IID_ICorDebugManagedCallback2, riid))
165     {
166         *ppv = (void**)&ManagedCallback2;
167         return S_OK;
168     }
169 
170     ok(0, "unexpected riid (%s)\n", debugstr_guid(riid));
171     *ppv = NULL;
172     return E_NOINTERFACE;
173 }
174 
ManagedCallback_AddRef(ICorDebugManagedCallback * iface)175 static ULONG WINAPI ManagedCallback_AddRef(ICorDebugManagedCallback *iface)
176 {
177     return 2;
178 }
179 
ManagedCallback_Release(ICorDebugManagedCallback * iface)180 static ULONG WINAPI ManagedCallback_Release(ICorDebugManagedCallback *iface)
181 {
182     return 1;
183 }
184 
ManagedCallback_Breakpoint(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,ICorDebugBreakpoint * pBreakpoint)185 static HRESULT WINAPI ManagedCallback_Breakpoint(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
186                     ICorDebugThread *pThread, ICorDebugBreakpoint *pBreakpoint)
187 {
188     ok(0, "unexpected call\n");
189     return E_NOTIMPL;
190 }
191 
ManagedCallback_StepComplete(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,ICorDebugStepper * pStepper,CorDebugStepReason reason)192 static HRESULT WINAPI ManagedCallback_StepComplete(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
193                     ICorDebugThread *pThread, ICorDebugStepper *pStepper, CorDebugStepReason reason)
194 {
195     ok(0, "unexpected call\n");
196     return E_NOTIMPL;
197 }
198 
ManagedCallback_Break(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * thread)199 static HRESULT WINAPI ManagedCallback_Break(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
200                     ICorDebugThread *thread)
201 {
202     ok(0, "unexpected call\n");
203     return E_NOTIMPL;
204 }
205 
ManagedCallback_Exception(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,BOOL unhandled)206 static HRESULT WINAPI ManagedCallback_Exception(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
207                     ICorDebugThread *pThread, BOOL unhandled)
208 {
209     ok(0, "unexpected call\n");
210     return E_NOTIMPL;
211 }
212 
ManagedCallback_EvalComplete(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,ICorDebugEval * pEval)213 static HRESULT WINAPI ManagedCallback_EvalComplete(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
214                     ICorDebugThread *pThread, ICorDebugEval *pEval)
215 {
216     ok(0, "unexpected call\n");
217     return E_NOTIMPL;
218 }
219 
ManagedCallback_EvalException(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,ICorDebugEval * pEval)220 static HRESULT WINAPI ManagedCallback_EvalException(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
221                     ICorDebugThread *pThread, ICorDebugEval *pEval)
222 {
223     ok(0, "unexpected call\n");
224     return E_NOTIMPL;
225 }
226 
ManagedCallback_CreateProcess(ICorDebugManagedCallback * iface,ICorDebugProcess * pProcess)227 static HRESULT WINAPI ManagedCallback_CreateProcess(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess)
228 {
229     ok(0, "unexpected call\n");
230     return E_NOTIMPL;
231 }
232 
ManagedCallback_ExitProcess(ICorDebugManagedCallback * iface,ICorDebugProcess * pProcess)233 static HRESULT WINAPI ManagedCallback_ExitProcess(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess)
234 {
235     ok(0, "unexpected call\n");
236     return E_NOTIMPL;
237 }
238 
ManagedCallback_CreateThread(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * thread)239 static HRESULT WINAPI ManagedCallback_CreateThread(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
240                     ICorDebugThread *thread)
241 {
242     ok(0, "unexpected call\n");
243     return E_NOTIMPL;
244 }
245 
ManagedCallback_ExitThread(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * thread)246 static HRESULT WINAPI ManagedCallback_ExitThread(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
247                     ICorDebugThread *thread)
248 {
249     ok(0, "unexpected call\n");
250     return E_NOTIMPL;
251 }
252 
ManagedCallback_LoadModule(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugModule * pModule)253 static HRESULT WINAPI ManagedCallback_LoadModule(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
254                     ICorDebugModule *pModule)
255 {
256     ok(0, "unexpected call\n");
257     return E_NOTIMPL;
258 }
259 
ManagedCallback_UnloadModule(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugModule * pModule)260 static HRESULT WINAPI ManagedCallback_UnloadModule(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
261                     ICorDebugModule *pModule)
262 {
263     ok(0, "unexpected call\n");
264     return E_NOTIMPL;
265 }
266 
ManagedCallback_LoadClass(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugClass * c)267 static HRESULT WINAPI ManagedCallback_LoadClass(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
268                     ICorDebugClass *c)
269 {
270     ok(0, "unexpected call\n");
271     return E_NOTIMPL;
272 }
273 
ManagedCallback_UnloadClass(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugClass * c)274 static HRESULT WINAPI ManagedCallback_UnloadClass(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
275                     ICorDebugClass *c)
276 {
277     ok(0, "unexpected call\n");
278     return E_NOTIMPL;
279 }
280 
ManagedCallback_DebuggerError(ICorDebugManagedCallback * iface,ICorDebugProcess * pProcess,HRESULT errorHR,DWORD errorCode)281 static HRESULT WINAPI ManagedCallback_DebuggerError(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess,
282                     HRESULT errorHR, DWORD errorCode)
283 {
284     ok(0, "unexpected call\n");
285     return E_NOTIMPL;
286 }
287 
ManagedCallback_LogMessage(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,LONG lLevel,WCHAR * pLogSwitchName,WCHAR * pMessage)288 static HRESULT WINAPI ManagedCallback_LogMessage(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
289                     ICorDebugThread *pThread, LONG lLevel, WCHAR *pLogSwitchName, WCHAR *pMessage)
290 {
291     ok(0, "unexpected call\n");
292     return E_NOTIMPL;
293 }
294 
ManagedCallback_LogSwitch(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,LONG lLevel,ULONG ulReason,WCHAR * pLogSwitchName,WCHAR * pParentName)295 static HRESULT WINAPI ManagedCallback_LogSwitch(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
296                     ICorDebugThread *pThread, LONG lLevel, ULONG ulReason,
297                     WCHAR *pLogSwitchName, WCHAR *pParentName)
298 {
299     ok(0, "unexpected call\n");
300     return E_NOTIMPL;
301 }
302 
ManagedCallback_CreateAppDomain(ICorDebugManagedCallback * iface,ICorDebugProcess * pProcess,ICorDebugAppDomain * pAppDomain)303 static HRESULT WINAPI ManagedCallback_CreateAppDomain(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess,
304                     ICorDebugAppDomain *pAppDomain)
305 {
306     ok(0, "unexpected call\n");
307     return E_NOTIMPL;
308 }
309 
ManagedCallback_ExitAppDomain(ICorDebugManagedCallback * iface,ICorDebugProcess * pProcess,ICorDebugAppDomain * pAppDomain)310 static HRESULT WINAPI ManagedCallback_ExitAppDomain(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess,
311                     ICorDebugAppDomain *pAppDomain)
312 {
313     ok(0, "unexpected call\n");
314     return E_NOTIMPL;
315 }
316 
ManagedCallback_LoadAssembly(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugAssembly * pAssembly)317 static HRESULT WINAPI ManagedCallback_LoadAssembly(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
318                     ICorDebugAssembly *pAssembly)
319 {
320     ok(0, "unexpected call\n");
321     return E_NOTIMPL;
322 }
323 
ManagedCallback_UnloadAssembly(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugAssembly * pAssembly)324 static HRESULT WINAPI ManagedCallback_UnloadAssembly(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
325                     ICorDebugAssembly *pAssembly)
326 {
327     ok(0, "unexpected call\n");
328     return E_NOTIMPL;
329 }
330 
ManagedCallback_ControlCTrap(ICorDebugManagedCallback * iface,ICorDebugProcess * pProcess)331 static HRESULT WINAPI ManagedCallback_ControlCTrap(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess)
332 {
333     ok(0, "unexpected call\n");
334     return E_NOTIMPL;
335 }
336 
ManagedCallback_NameChange(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread)337 static HRESULT WINAPI ManagedCallback_NameChange(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
338                     ICorDebugThread *pThread)
339 {
340     ok(0, "unexpected call\n");
341     return E_NOTIMPL;
342 }
343 
ManagedCallback_UpdateModuleSymbols(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugModule * pModule,IStream * pSymbolStream)344 static HRESULT WINAPI ManagedCallback_UpdateModuleSymbols(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
345                     ICorDebugModule *pModule, IStream *pSymbolStream)
346 {
347     ok(0, "unexpected call\n");
348     return E_NOTIMPL;
349 }
350 
ManagedCallback_EditAndContinueRemap(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,ICorDebugFunction * pFunction,BOOL fAccurate)351 static HRESULT WINAPI ManagedCallback_EditAndContinueRemap(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
352                     ICorDebugThread *pThread, ICorDebugFunction *pFunction, BOOL fAccurate)
353 {
354     ok(0, "unexpected call\n");
355     return E_NOTIMPL;
356 }
357 
ManagedCallback_BreakpointSetError(ICorDebugManagedCallback * iface,ICorDebugAppDomain * pAppDomain,ICorDebugThread * pThread,ICorDebugBreakpoint * pBreakpoint,DWORD dwError)358 static HRESULT WINAPI ManagedCallback_BreakpointSetError(ICorDebugManagedCallback *iface, ICorDebugAppDomain *pAppDomain,
359                     ICorDebugThread *pThread, ICorDebugBreakpoint *pBreakpoint, DWORD dwError)
360 {
361     ok(0, "unexpected call\n");
362     return E_NOTIMPL;
363 }
364 
365 static ICorDebugManagedCallbackVtbl managedCallbackVtbl = {
366     ManagedCallback_QueryInterface,
367     ManagedCallback_AddRef,
368     ManagedCallback_Release,
369     ManagedCallback_Breakpoint,
370     ManagedCallback_StepComplete,
371     ManagedCallback_Break,
372     ManagedCallback_Exception,
373     ManagedCallback_EvalComplete,
374     ManagedCallback_EvalException,
375     ManagedCallback_CreateProcess,
376     ManagedCallback_ExitProcess,
377     ManagedCallback_CreateThread,
378     ManagedCallback_ExitThread,
379     ManagedCallback_LoadModule,
380     ManagedCallback_UnloadModule,
381     ManagedCallback_LoadClass,
382     ManagedCallback_UnloadClass,
383     ManagedCallback_DebuggerError,
384     ManagedCallback_LogMessage,
385     ManagedCallback_LogSwitch,
386     ManagedCallback_CreateAppDomain,
387     ManagedCallback_ExitAppDomain,
388     ManagedCallback_LoadAssembly,
389     ManagedCallback_UnloadAssembly,
390     ManagedCallback_ControlCTrap,
391     ManagedCallback_NameChange,
392     ManagedCallback_UpdateModuleSymbols,
393     ManagedCallback_EditAndContinueRemap,
394     ManagedCallback_BreakpointSetError
395 };
396 
397 static ICorDebugManagedCallback ManagedCallback = { &managedCallbackVtbl };
398 
init_functionpointers(void)399 static BOOL init_functionpointers(void)
400 {
401     hmscoree = LoadLibraryA("mscoree.dll");
402 
403     if (!hmscoree)
404     {
405         win_skip("mscoree.dll not available\n");
406         return FALSE;
407     }
408 
409     pCreateDebuggingInterfaceFromVersion = (void *)GetProcAddress(hmscoree, "CreateDebuggingInterfaceFromVersion");
410 
411     if (!pCreateDebuggingInterfaceFromVersion)
412     {
413         win_skip("functions not available\n");
414         FreeLibrary(hmscoree);
415         return FALSE;
416     }
417 
418     return TRUE;
419 }
420 
421 #define check_process_enum(core, e) _check_process_enum(__LINE__, core, e)
_check_process_enum(unsigned line,ICorDebug * pCorDebug,ULONG nExpected)422 static void _check_process_enum(unsigned line, ICorDebug *pCorDebug, ULONG nExpected)
423 {
424     HRESULT hr;
425     ICorDebugProcessEnum *pProcessEnum = NULL;
426 
427     hr = ICorDebug_EnumerateProcesses(pCorDebug, NULL);
428     ok_(__FILE__,line) (hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr);
429 
430     hr = ICorDebug_EnumerateProcesses(pCorDebug, &pProcessEnum);
431     ok_(__FILE__,line) (hr == S_OK, "expected S_OK got %08x\n", hr);
432     if(hr == S_OK)
433     {
434         ULONG cnt;
435 
436         hr = ICorDebugProcessEnum_GetCount(pProcessEnum, &cnt);
437         ok_(__FILE__,line) (hr == S_OK, "expected S_OK got %08x\n", hr);
438         ok_(__FILE__,line) (cnt == nExpected, "expected %d got %d\n", nExpected, cnt);
439 
440         ICorDebugProcessEnum_Release(pProcessEnum);
441     }
442 }
443 
test_createDebugger(void)444 static void test_createDebugger(void)
445 {
446     HRESULT hr;
447     IUnknown *pUnk;
448     ICorDebug *pCorDebug;
449 
450     hr = pCreateDebuggingInterfaceFromVersion(0, v2_0, &pUnk);
451     ok(hr == E_INVALIDARG, "CreateDebuggingInterfaceFromVersion returned %08x\n", hr);
452 
453     hr = pCreateDebuggingInterfaceFromVersion(1, v2_0, &pUnk);
454     ok(hr == E_INVALIDARG, "CreateDebuggingInterfaceFromVersion returned %08x\n", hr);
455 
456     hr = pCreateDebuggingInterfaceFromVersion(2, v2_0, &pUnk);
457     ok(hr == E_INVALIDARG, "CreateDebuggingInterfaceFromVersion returned %08x\n", hr);
458 
459     hr = pCreateDebuggingInterfaceFromVersion(4, v2_0, &pUnk);
460     ok(hr == E_INVALIDARG, "CreateDebuggingInterfaceFromVersion returned %08x\n", hr);
461 
462     hr = pCreateDebuggingInterfaceFromVersion(3, v2_0, NULL);
463     ok(hr == E_INVALIDARG, "CreateDebuggingInterfaceFromVersion returned %08x\n", hr);
464 
465     hr = pCreateDebuggingInterfaceFromVersion(3, v2_0, &pUnk);
466     if(hr == S_OK)
467     {
468         hr = IUnknown_QueryInterface(pUnk, &IID_ICorDebug, (void**)&pCorDebug);
469         ok(hr == S_OK, "expected S_OK got %08x\n", hr);
470         if(hr == S_OK)
471         {
472             hr = ICorDebug_Initialize(pCorDebug);
473             ok(hr == S_OK, "expected S_OK got %08x\n", hr);
474             if(hr == S_OK)
475             {
476                 hr = ICorDebug_SetManagedHandler(pCorDebug, NULL);
477                 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr);
478 
479                 hr = ICorDebug_SetManagedHandler(pCorDebug, &ManagedCallback);
480                 ok(hr == S_OK, "expected S_OK got %08x\n", hr);
481 
482                 /* We should have no processes */
483                 check_process_enum(pCorDebug, 0);
484             }
485 
486             ICorDebug_Release(pCorDebug);
487         }
488         IUnknown_Release(pUnk);
489     }
490     else
491     {
492         skip(".NET 2.0 or mono not installed.\n");
493     }
494 }
495 
START_TEST(debugging)496 START_TEST(debugging)
497 {
498     CoInitialize(NULL);
499 
500     if (!init_functionpointers())
501         return;
502 
503     test_createDebugger();
504 
505     FreeLibrary(hmscoree);
506     CoUninitialize();
507 }
508