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 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 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 68 static ULONG WINAPI ManagedCallback2_AddRef(ICorDebugManagedCallback2 *iface) 69 { 70 return 2; 71 } 72 73 static ULONG WINAPI ManagedCallback2_Release(ICorDebugManagedCallback2 *iface) 74 { 75 return 1; 76 } 77 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 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 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 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 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 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 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 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 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 175 static ULONG WINAPI ManagedCallback_AddRef(ICorDebugManagedCallback *iface) 176 { 177 return 2; 178 } 179 180 static ULONG WINAPI ManagedCallback_Release(ICorDebugManagedCallback *iface) 181 { 182 return 1; 183 } 184 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 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 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 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 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 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 227 static HRESULT WINAPI ManagedCallback_CreateProcess(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess) 228 { 229 ok(0, "unexpected call\n"); 230 return E_NOTIMPL; 231 } 232 233 static HRESULT WINAPI ManagedCallback_ExitProcess(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess) 234 { 235 ok(0, "unexpected call\n"); 236 return E_NOTIMPL; 237 } 238 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 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 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 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 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 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 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 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 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 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 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 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 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 331 static HRESULT WINAPI ManagedCallback_ControlCTrap(ICorDebugManagedCallback *iface, ICorDebugProcess *pProcess) 332 { 333 ok(0, "unexpected call\n"); 334 return E_NOTIMPL; 335 } 336 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 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 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 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 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) 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 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 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