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