1 /* 2 * 3 * Copyright 2011 Alistair Leslie-Hughes 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include "mscoree_private.h" 21 22 typedef struct DebugProcess 23 { 24 ICorDebugProcess ICorDebugProcess_iface; 25 26 CorDebug *cordebug; 27 28 DWORD dwProcessID; 29 HANDLE handle; 30 HANDLE thread; 31 32 LONG ref; 33 } DebugProcess; 34 35 static inline CorDebug *impl_from_ICorDebug( ICorDebug *iface ) 36 { 37 return CONTAINING_RECORD(iface, CorDebug, ICorDebug_iface); 38 } 39 40 static inline CorDebug *impl_from_ICorDebugProcessEnum( ICorDebugProcessEnum *iface ) 41 { 42 return CONTAINING_RECORD(iface, CorDebug, ICorDebugProcessEnum_iface); 43 } 44 45 static inline DebugProcess *impl_from_ICorDebugProcess( ICorDebugProcess *iface ) 46 { 47 return CONTAINING_RECORD(iface, DebugProcess, ICorDebugProcess_iface); 48 } 49 50 /* ICorDebugProcess Interface */ 51 static HRESULT WINAPI cordebugprocess_QueryInterface(ICorDebugProcess *iface, 52 REFIID riid, void **ppvObject) 53 { 54 DebugProcess *This = impl_from_ICorDebugProcess(iface); 55 56 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); 57 58 if ( IsEqualGUID( riid, &IID_ICorDebugProcess ) || 59 IsEqualGUID( riid, &IID_ICorDebugController ) || 60 IsEqualGUID( riid, &IID_IUnknown ) ) 61 { 62 *ppvObject = &This->ICorDebugProcess_iface; 63 } 64 else 65 { 66 FIXME("Unsupported interface %s\n", debugstr_guid(riid)); 67 return E_NOINTERFACE; 68 } 69 70 ICorDebugProcess_AddRef(iface); 71 72 return S_OK; 73 } 74 75 static ULONG WINAPI cordebugprocess_AddRef(ICorDebugProcess *iface) 76 { 77 DebugProcess *This = impl_from_ICorDebugProcess(iface); 78 ULONG ref = InterlockedIncrement(&This->ref); 79 80 TRACE("%p ref=%u\n", This, ref); 81 82 return ref; 83 } 84 85 static ULONG WINAPI cordebugprocess_Release(ICorDebugProcess *iface) 86 { 87 DebugProcess *This = impl_from_ICorDebugProcess(iface); 88 ULONG ref = InterlockedDecrement(&This->ref); 89 90 TRACE("%p ref=%u\n", This, ref); 91 92 if (ref == 0) 93 { 94 if(This->handle) 95 CloseHandle(This->handle); 96 97 if(This->thread) 98 CloseHandle(This->thread); 99 100 if(This->cordebug) 101 ICorDebug_Release(&This->cordebug->ICorDebug_iface); 102 103 HeapFree(GetProcessHeap(), 0, This); 104 } 105 106 return ref; 107 } 108 109 static HRESULT WINAPI cordebugprocess_Stop(ICorDebugProcess *iface, DWORD dwTimeoutIgnored) 110 { 111 DebugProcess *This = impl_from_ICorDebugProcess(iface); 112 FIXME("stub %p\n", This); 113 return E_NOTIMPL; 114 } 115 116 static HRESULT WINAPI cordebugprocess_Continue(ICorDebugProcess *iface, BOOL fIsOutOfBand) 117 { 118 DebugProcess *This = impl_from_ICorDebugProcess(iface); 119 TRACE("%p\n", This); 120 121 if(This->thread) 122 ResumeThread(This->thread); 123 124 return S_OK; 125 } 126 127 static HRESULT WINAPI cordebugprocess_IsRunning(ICorDebugProcess *iface, BOOL *pbRunning) 128 { 129 DebugProcess *This = impl_from_ICorDebugProcess(iface); 130 FIXME("stub %p\n", This); 131 return E_NOTIMPL; 132 } 133 134 static HRESULT WINAPI cordebugprocess_HasQueuedCallbacks(ICorDebugProcess *iface, 135 ICorDebugThread *pThread, BOOL *pbQueued) 136 { 137 DebugProcess *This = impl_from_ICorDebugProcess(iface); 138 FIXME("stub %p\n", This); 139 return E_NOTIMPL; 140 } 141 142 static HRESULT WINAPI cordebugprocess_EnumerateThreads(ICorDebugProcess *iface, 143 ICorDebugThreadEnum **ppThreads) 144 { 145 DebugProcess *This = impl_from_ICorDebugProcess(iface); 146 FIXME("stub %p\n", This); 147 return E_NOTIMPL; 148 } 149 150 static HRESULT WINAPI cordebugprocess_SetAllThreadsDebugState(ICorDebugProcess *iface, 151 CorDebugThreadState state, ICorDebugThread *pExceptThisThread) 152 { 153 DebugProcess *This = impl_from_ICorDebugProcess(iface); 154 FIXME("stub %p\n", This); 155 return E_NOTIMPL; 156 } 157 158 static HRESULT WINAPI cordebugprocess_Detach(ICorDebugProcess *iface) 159 { 160 DebugProcess *This = impl_from_ICorDebugProcess(iface); 161 FIXME("stub %p\n", This); 162 return E_NOTIMPL; 163 } 164 165 static HRESULT WINAPI cordebugprocess_Terminate(ICorDebugProcess *iface, UINT exitCode) 166 { 167 DebugProcess *This = impl_from_ICorDebugProcess(iface); 168 BOOL ret = TRUE; 169 170 TRACE("%p\n", This); 171 172 if(This->handle) 173 { 174 ret = TerminateProcess(This->handle, exitCode); 175 CloseHandle(This->handle); 176 This->handle = NULL; 177 } 178 return ret ? S_OK : E_FAIL; 179 } 180 181 static HRESULT WINAPI cordebugprocess_CanCommitChanges(ICorDebugProcess *iface, 182 ULONG cSnapshots, ICorDebugEditAndContinueSnapshot * pSnapshots[], 183 ICorDebugErrorInfoEnum **pError) 184 { 185 DebugProcess *This = impl_from_ICorDebugProcess(iface); 186 FIXME("stub %p\n", This); 187 return E_NOTIMPL; 188 } 189 190 static HRESULT WINAPI cordebugprocess_CommitChanges(ICorDebugProcess *iface, 191 ULONG cSnapshots, ICorDebugEditAndContinueSnapshot * pSnapshots[], 192 ICorDebugErrorInfoEnum **pError) 193 { 194 DebugProcess *This = impl_from_ICorDebugProcess(iface); 195 FIXME("stub %p\n", This); 196 return E_NOTIMPL; 197 } 198 199 static HRESULT WINAPI cordebugprocess_GetID(ICorDebugProcess *iface, DWORD *pdwProcessId) 200 { 201 DebugProcess *This = impl_from_ICorDebugProcess(iface); 202 TRACE("%p\n", This); 203 204 if(!pdwProcessId) 205 return E_INVALIDARG; 206 207 *pdwProcessId = This->dwProcessID; 208 209 return S_OK; 210 } 211 212 static HRESULT WINAPI cordebugprocess_GetHandle(ICorDebugProcess *iface, HPROCESS *phProcessHandle) 213 { 214 DebugProcess *This = impl_from_ICorDebugProcess(iface); 215 TRACE("%p\n", This); 216 217 if(!phProcessHandle) 218 return E_INVALIDARG; 219 220 *phProcessHandle = This->handle; 221 222 return S_OK; 223 } 224 225 static HRESULT WINAPI cordebugprocess_GetThread(ICorDebugProcess *iface, DWORD dwThreadId, 226 ICorDebugThread **ppThread) 227 { 228 DebugProcess *This = impl_from_ICorDebugProcess(iface); 229 FIXME("stub %p\n", This); 230 return E_NOTIMPL; 231 } 232 233 static HRESULT WINAPI cordebugprocess_EnumerateObjects(ICorDebugProcess *iface, 234 ICorDebugObjectEnum **ppObjects) 235 { 236 DebugProcess *This = impl_from_ICorDebugProcess(iface); 237 FIXME("stub %p\n", This); 238 return E_NOTIMPL; 239 } 240 241 static HRESULT WINAPI cordebugprocess_IsTransitionStub(ICorDebugProcess *iface, 242 CORDB_ADDRESS address, BOOL *pbTransitionStub) 243 { 244 DebugProcess *This = impl_from_ICorDebugProcess(iface); 245 FIXME("stub %p\n", This); 246 return E_NOTIMPL; 247 } 248 249 static HRESULT WINAPI cordebugprocess_IsOSSuspended(ICorDebugProcess *iface, 250 DWORD threadID, BOOL *pbSuspended) 251 { 252 DebugProcess *This = impl_from_ICorDebugProcess(iface); 253 FIXME("stub %p\n", This); 254 return E_NOTIMPL; 255 } 256 257 static HRESULT WINAPI cordebugprocess_GetThreadContext(ICorDebugProcess *iface, 258 DWORD threadID, ULONG32 contextSize, BYTE context[]) 259 { 260 DebugProcess *This = impl_from_ICorDebugProcess(iface); 261 FIXME("stub %p\n", This); 262 return E_NOTIMPL; 263 } 264 265 static HRESULT WINAPI cordebugprocess_SetThreadContext(ICorDebugProcess *iface, 266 DWORD threadID, ULONG32 contextSize, BYTE context[]) 267 { 268 DebugProcess *This = impl_from_ICorDebugProcess(iface); 269 FIXME("stub %p\n", This); 270 return E_NOTIMPL; 271 } 272 273 static HRESULT WINAPI cordebugprocess_ReadMemory(ICorDebugProcess *iface, 274 CORDB_ADDRESS address, DWORD size, BYTE buffer[], 275 SIZE_T *read) 276 { 277 DebugProcess *This = impl_from_ICorDebugProcess(iface); 278 FIXME("stub %p\n", This); 279 return E_NOTIMPL; 280 } 281 282 static HRESULT WINAPI cordebugprocess_WriteMemory(ICorDebugProcess *iface, 283 CORDB_ADDRESS address, DWORD size, BYTE buffer[], 284 SIZE_T *written) 285 { 286 DebugProcess *This = impl_from_ICorDebugProcess(iface); 287 FIXME("stub %p\n", This); 288 return E_NOTIMPL; 289 } 290 291 static HRESULT WINAPI cordebugprocess_ClearCurrentException(ICorDebugProcess *iface, 292 DWORD threadID) 293 { 294 DebugProcess *This = impl_from_ICorDebugProcess(iface); 295 FIXME("stub %p\n", This); 296 return E_NOTIMPL; 297 } 298 299 static HRESULT WINAPI cordebugprocess_EnableLogMessages(ICorDebugProcess *iface, 300 BOOL fOnOff) 301 { 302 DebugProcess *This = impl_from_ICorDebugProcess(iface); 303 FIXME("stub %p\n", This); 304 return E_NOTIMPL; 305 } 306 307 static HRESULT WINAPI cordebugprocess_ModifyLogSwitch(ICorDebugProcess *iface, 308 WCHAR *pLogSwitchName, LONG lLevel) 309 { 310 DebugProcess *This = impl_from_ICorDebugProcess(iface); 311 FIXME("stub %p\n", This); 312 return E_NOTIMPL; 313 } 314 315 static HRESULT WINAPI cordebugprocess_EnumerateAppDomains(ICorDebugProcess *iface, 316 ICorDebugAppDomainEnum **ppAppDomains) 317 { 318 DebugProcess *This = impl_from_ICorDebugProcess(iface); 319 FIXME("stub %p\n", This); 320 return E_NOTIMPL; 321 } 322 323 static HRESULT WINAPI cordebugprocess_GetObject(ICorDebugProcess *iface, 324 ICorDebugValue **ppObject) 325 { 326 DebugProcess *This = impl_from_ICorDebugProcess(iface); 327 FIXME("stub %p\n", This); 328 return E_NOTIMPL; 329 } 330 331 static HRESULT WINAPI cordebugprocess_ThreadForFiberCookie(ICorDebugProcess *iface, 332 DWORD fiberCookie, ICorDebugThread **ppThread) 333 { 334 DebugProcess *This = impl_from_ICorDebugProcess(iface); 335 FIXME("stub %p\n", This); 336 return E_NOTIMPL; 337 } 338 339 static HRESULT WINAPI cordebugprocess_GetHelperThreadID(ICorDebugProcess *iface, 340 DWORD *pThreadID) 341 { 342 DebugProcess *This = impl_from_ICorDebugProcess(iface); 343 FIXME("stub %p\n", This); 344 return E_NOTIMPL; 345 } 346 347 348 /***************************************/ 349 static const ICorDebugProcessVtbl cordebugprocessVtbl = { 350 cordebugprocess_QueryInterface, 351 cordebugprocess_AddRef, 352 cordebugprocess_Release, 353 cordebugprocess_Stop, 354 cordebugprocess_Continue, 355 cordebugprocess_IsRunning, 356 cordebugprocess_HasQueuedCallbacks, 357 cordebugprocess_EnumerateThreads, 358 cordebugprocess_SetAllThreadsDebugState, 359 cordebugprocess_Detach, 360 cordebugprocess_Terminate, 361 cordebugprocess_CanCommitChanges, 362 cordebugprocess_CommitChanges, 363 cordebugprocess_GetID, 364 cordebugprocess_GetHandle, 365 cordebugprocess_GetThread, 366 cordebugprocess_EnumerateObjects, 367 cordebugprocess_IsTransitionStub, 368 cordebugprocess_IsOSSuspended, 369 cordebugprocess_GetThreadContext, 370 cordebugprocess_SetThreadContext, 371 cordebugprocess_ReadMemory, 372 cordebugprocess_WriteMemory, 373 cordebugprocess_ClearCurrentException, 374 cordebugprocess_EnableLogMessages, 375 cordebugprocess_ModifyLogSwitch, 376 cordebugprocess_EnumerateAppDomains, 377 cordebugprocess_GetObject, 378 cordebugprocess_ThreadForFiberCookie, 379 cordebugprocess_GetHelperThreadID 380 }; 381 382 383 static HRESULT CorDebugProcess_Create(CorDebug *cordebug, IUnknown** ppUnk, LPPROCESS_INFORMATION lpProcessInformation) 384 { 385 DebugProcess *This; 386 387 This = HeapAlloc( GetProcessHeap(), 0, sizeof *This ); 388 if ( !This ) 389 return E_OUTOFMEMORY; 390 391 if(!DuplicateHandle(GetCurrentProcess(), lpProcessInformation->hProcess, 392 GetCurrentProcess(), &This->handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) 393 { 394 ERR("Failed to duplicate process handle\n"); 395 HeapFree(GetProcessHeap(), 0, This); 396 return E_FAIL; 397 } 398 if(!DuplicateHandle(GetCurrentProcess(), lpProcessInformation->hThread, 399 GetCurrentProcess(), &This->thread, 0, FALSE, DUPLICATE_SAME_ACCESS)) 400 { 401 CloseHandle(This->handle); 402 403 ERR("Failed to duplicate thread handle\n"); 404 HeapFree(GetProcessHeap(), 0, This); 405 return E_FAIL; 406 } 407 408 This->ICorDebugProcess_iface.lpVtbl = &cordebugprocessVtbl; 409 This->ref = 1; 410 This->cordebug = cordebug; 411 This->dwProcessID = lpProcessInformation->dwProcessId; 412 413 if(This->cordebug) 414 ICorDebug_AddRef(&This->cordebug->ICorDebug_iface); 415 416 *ppUnk = (IUnknown*)&This->ICorDebugProcess_iface; 417 418 return S_OK; 419 } 420 421 /* ICorDebugProcessEnum Interface */ 422 static HRESULT WINAPI process_enum_QueryInterface(ICorDebugProcessEnum *iface, REFIID riid, void **ppvObject) 423 { 424 CorDebug *This = impl_from_ICorDebugProcessEnum(iface); 425 426 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); 427 428 if ( IsEqualGUID( riid, &IID_ICorDebugProcessEnum ) || 429 IsEqualGUID( riid, &IID_ICorDebugEnum ) || 430 IsEqualGUID( riid, &IID_IUnknown ) ) 431 { 432 *ppvObject = &This->ICorDebugProcessEnum_iface; 433 } 434 else 435 { 436 FIXME("Unsupported interface %s\n", debugstr_guid(riid)); 437 return E_NOINTERFACE; 438 } 439 440 ICorDebugProcessEnum_AddRef(iface); 441 442 return S_OK; 443 } 444 445 static ULONG WINAPI process_enum_AddRef(ICorDebugProcessEnum *iface) 446 { 447 CorDebug *This = impl_from_ICorDebugProcessEnum(iface); 448 TRACE("%p ref=%u\n", This, This->ref); 449 450 return ICorDebug_AddRef(&This->ICorDebug_iface); 451 } 452 453 static ULONG WINAPI process_enum_Release(ICorDebugProcessEnum *iface) 454 { 455 CorDebug *This = impl_from_ICorDebugProcessEnum(iface); 456 TRACE("%p ref=%u\n", This, This->ref); 457 458 return ICorDebug_Release(&This->ICorDebug_iface); 459 } 460 461 static HRESULT WINAPI process_enum_Skip(ICorDebugProcessEnum *iface, ULONG celt) 462 { 463 CorDebug *This = impl_from_ICorDebugProcessEnum(iface); 464 FIXME("stub %p\n", This); 465 return E_NOTIMPL; 466 } 467 468 static HRESULT WINAPI process_enum_Reset(ICorDebugProcessEnum *iface) 469 { 470 CorDebug *This = impl_from_ICorDebugProcessEnum(iface); 471 FIXME("stub %p\n", This); 472 return E_NOTIMPL; 473 } 474 475 static HRESULT WINAPI process_enum_Clone(ICorDebugProcessEnum *iface, ICorDebugEnum **ppEnum) 476 { 477 CorDebug *This = impl_from_ICorDebugProcessEnum(iface); 478 FIXME("stub %p %p\n", This, ppEnum); 479 return E_NOTIMPL; 480 } 481 482 static HRESULT WINAPI process_enum_GetCount(ICorDebugProcessEnum *iface, ULONG *pcelt) 483 { 484 CorDebug *This = impl_from_ICorDebugProcessEnum(iface); 485 TRACE("stub %p %p\n", This, pcelt); 486 487 if(!pcelt) 488 return E_INVALIDARG; 489 490 *pcelt = list_count(&This->processes); 491 492 return S_OK; 493 } 494 495 static HRESULT WINAPI process_enum_Next(ICorDebugProcessEnum *iface, ULONG celt, 496 ICorDebugProcess * processes[], ULONG *pceltFetched) 497 { 498 CorDebug *This = impl_from_ICorDebugProcessEnum(iface); 499 FIXME("stub %p %d %p %p\n", This, celt, processes, pceltFetched); 500 return E_NOTIMPL; 501 } 502 503 static const struct ICorDebugProcessEnumVtbl processenum_vtbl = 504 { 505 process_enum_QueryInterface, 506 process_enum_AddRef, 507 process_enum_Release, 508 process_enum_Skip, 509 process_enum_Reset, 510 process_enum_Clone, 511 process_enum_GetCount, 512 process_enum_Next 513 }; 514 515 /*** IUnknown methods ***/ 516 static HRESULT WINAPI CorDebug_QueryInterface(ICorDebug *iface, REFIID riid, void **ppvObject) 517 { 518 CorDebug *This = impl_from_ICorDebug( iface ); 519 520 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); 521 522 if ( IsEqualGUID( riid, &IID_ICorDebug ) || 523 IsEqualGUID( riid, &IID_IUnknown ) ) 524 { 525 *ppvObject = &This->ICorDebug_iface; 526 } 527 else 528 { 529 FIXME("Unsupported interface %s\n", debugstr_guid(riid)); 530 return E_NOINTERFACE; 531 } 532 533 ICorDebug_AddRef( iface ); 534 535 return S_OK; 536 } 537 538 static ULONG WINAPI CorDebug_AddRef(ICorDebug *iface) 539 { 540 CorDebug *This = impl_from_ICorDebug( iface ); 541 ULONG ref = InterlockedIncrement(&This->ref); 542 543 TRACE("%p ref=%u\n", This, ref); 544 545 return ref; 546 } 547 548 static ULONG WINAPI CorDebug_Release(ICorDebug *iface) 549 { 550 CorDebug *This = impl_from_ICorDebug( iface ); 551 ULONG ref = InterlockedDecrement(&This->ref); 552 553 TRACE("%p ref=%u\n", This, ref); 554 555 if (ref == 0) 556 { 557 if(!list_empty(&This->processes)) 558 ERR("Processes haven't been removed Correctly\n"); 559 560 if(This->runtimehost) 561 ICLRRuntimeHost_Release(This->runtimehost); 562 563 if(This->pCallback) 564 ICorDebugManagedCallback2_Release(This->pCallback2); 565 566 if(This->pCallback) 567 ICorDebugManagedCallback_Release(This->pCallback); 568 569 HeapFree(GetProcessHeap(), 0, This); 570 } 571 572 return ref; 573 } 574 575 /*** ICorDebug methods ***/ 576 static HRESULT WINAPI CorDebug_Initialize(ICorDebug *iface) 577 { 578 CorDebug *This = impl_from_ICorDebug( iface ); 579 FIXME("stub %p\n", This); 580 return S_OK; 581 } 582 583 static HRESULT WINAPI CorDebug_Terminate(ICorDebug *iface) 584 { 585 struct CorProcess *cursor, *cursor2; 586 CorDebug *This = impl_from_ICorDebug( iface ); 587 TRACE("stub %p\n", This); 588 589 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->processes, struct CorProcess, entry) 590 { 591 if(cursor->pProcess) 592 { 593 ICorDebugProcess_Terminate(cursor->pProcess, 0); 594 ICorDebugProcess_Release(cursor->pProcess); 595 } 596 597 list_remove(&cursor->entry); 598 HeapFree(GetProcessHeap(), 0, cursor); 599 } 600 601 return S_OK; 602 } 603 604 static HRESULT WINAPI CorDebug_SetManagedHandler(ICorDebug *iface, ICorDebugManagedCallback *pCallback) 605 { 606 CorDebug *This = impl_from_ICorDebug( iface ); 607 HRESULT hr; 608 ICorDebugManagedCallback2 *pCallback2; 609 610 TRACE("%p (%p)\n", This, pCallback); 611 612 if(!pCallback) 613 return E_INVALIDARG; 614 615 hr = ICorDebugManagedCallback_QueryInterface(pCallback, &IID_ICorDebugManagedCallback2, (void**)&pCallback2); 616 if(hr == S_OK) 617 { 618 if(This->pCallback2) 619 ICorDebugManagedCallback2_Release(This->pCallback2); 620 621 if(This->pCallback) 622 ICorDebugManagedCallback_Release(This->pCallback); 623 624 This->pCallback = pCallback; 625 This->pCallback2 = pCallback2; 626 627 ICorDebugManagedCallback_AddRef(This->pCallback); 628 } 629 else 630 { 631 WARN("Debugging without interface ICorDebugManagedCallback2 is currently not supported.\n"); 632 } 633 634 return hr; 635 } 636 637 static HRESULT WINAPI CorDebug_SetUnmanagedHandler(ICorDebug *iface, ICorDebugUnmanagedCallback *pCallback) 638 { 639 CorDebug *This = impl_from_ICorDebug( iface ); 640 FIXME("stub %p %p\n", This, pCallback); 641 return E_NOTIMPL; 642 } 643 644 static HRESULT WINAPI CorDebug_CreateProcess(ICorDebug *iface, LPCWSTR lpApplicationName, 645 LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, 646 LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, 647 DWORD dwCreationFlags, PVOID lpEnvironment,LPCWSTR lpCurrentDirectory, 648 LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation, 649 CorDebugCreateProcessFlags debuggingFlags, ICorDebugProcess **ppProcess) 650 { 651 CorDebug *This = impl_from_ICorDebug( iface ); 652 ICorDebugProcess *pDebugProcess; 653 HRESULT hr; 654 655 TRACE("stub %p %s %s %p %p %d %d %p %s %p %p %d %p\n", This, debugstr_w(lpApplicationName), 656 debugstr_w(lpCommandLine), lpProcessAttributes, lpThreadAttributes, 657 bInheritHandles, dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory), 658 lpStartupInfo, lpProcessInformation, debuggingFlags, ppProcess); 659 660 if(CreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, 661 bInheritHandles, dwCreationFlags | CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, 662 lpStartupInfo, lpProcessInformation)) 663 { 664 hr = CorDebugProcess_Create(This, (IUnknown**)&pDebugProcess, lpProcessInformation); 665 if(hr == S_OK) 666 { 667 struct CorProcess *new_process = HeapAlloc( GetProcessHeap(), 0, sizeof(CorProcess) ); 668 669 new_process->pProcess = pDebugProcess; 670 list_add_tail(&This->processes, &new_process->entry); 671 672 ICorDebugProcess_AddRef(pDebugProcess); 673 *ppProcess = pDebugProcess; 674 675 if(This->pCallback) 676 ICorDebugManagedCallback_CreateProcess(This->pCallback, pDebugProcess); 677 } 678 else 679 { 680 TerminateProcess(lpProcessInformation->hProcess, 0); 681 } 682 } 683 else 684 hr = E_FAIL; 685 686 return hr; 687 } 688 689 static HRESULT WINAPI CorDebug_DebugActiveProcess(ICorDebug *iface, DWORD id, BOOL win32Attach, 690 ICorDebugProcess **ppProcess) 691 { 692 CorDebug *This = impl_from_ICorDebug( iface ); 693 FIXME("stub %p %d %d %p\n", This, id, win32Attach, ppProcess); 694 return E_NOTIMPL; 695 } 696 697 static HRESULT WINAPI CorDebug_EnumerateProcesses( ICorDebug *iface, ICorDebugProcessEnum **ppProcess) 698 { 699 CorDebug *This = impl_from_ICorDebug( iface ); 700 TRACE("stub %p %p\n", This, ppProcess); 701 702 if(!ppProcess) 703 return E_INVALIDARG; 704 705 *ppProcess = &This->ICorDebugProcessEnum_iface; 706 ICorDebugProcessEnum_AddRef(*ppProcess); 707 708 return S_OK; 709 } 710 711 static HRESULT WINAPI CorDebug_GetProcess(ICorDebug *iface, DWORD dwProcessId, ICorDebugProcess **ppProcess) 712 { 713 CorDebug *This = impl_from_ICorDebug( iface ); 714 FIXME("stub %p %d %p\n", This, dwProcessId, ppProcess); 715 return E_NOTIMPL; 716 } 717 718 static HRESULT WINAPI CorDebug_CanLaunchOrAttach(ICorDebug *iface, DWORD dwProcessId, 719 BOOL win32DebuggingEnabled) 720 { 721 CorDebug *This = impl_from_ICorDebug( iface ); 722 FIXME("stub %p %d %d\n", This, dwProcessId, win32DebuggingEnabled); 723 return S_OK; 724 } 725 726 static const struct ICorDebugVtbl cordebug_vtbl = 727 { 728 CorDebug_QueryInterface, 729 CorDebug_AddRef, 730 CorDebug_Release, 731 CorDebug_Initialize, 732 CorDebug_Terminate, 733 CorDebug_SetManagedHandler, 734 CorDebug_SetUnmanagedHandler, 735 CorDebug_CreateProcess, 736 CorDebug_DebugActiveProcess, 737 CorDebug_EnumerateProcesses, 738 CorDebug_GetProcess, 739 CorDebug_CanLaunchOrAttach 740 }; 741 742 HRESULT CorDebug_Create(ICLRRuntimeHost *runtimehost, IUnknown** ppUnk) 743 { 744 CorDebug *This; 745 746 This = HeapAlloc( GetProcessHeap(), 0, sizeof *This ); 747 if ( !This ) 748 return E_OUTOFMEMORY; 749 750 This->ICorDebug_iface.lpVtbl = &cordebug_vtbl; 751 This->ICorDebugProcessEnum_iface.lpVtbl = &processenum_vtbl; 752 This->ref = 1; 753 This->pCallback = NULL; 754 This->pCallback2 = NULL; 755 This->runtimehost = runtimehost; 756 757 list_init(&This->processes); 758 759 if(This->runtimehost) 760 ICLRRuntimeHost_AddRef(This->runtimehost); 761 762 *ppUnk = (IUnknown*)&This->ICorDebug_iface; 763 764 return S_OK; 765 } 766