ReactOS 0.4.16-dev-311-g9382aa2
debugger.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Win32 Base API
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/kernel32/client/debugger.c
5 * PURPOSE: Wrappers for the NT Debug Implementation
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include <k32.h>
12
13#include <ndk/dbgkfuncs.h>
14
15#define NDEBUG
16#include <debug.h>
17
18typedef struct _DBGSS_THREAD_DATA
19{
27
28#define DbgSsSetThreadData(d) \
29 NtCurrentTeb()->DbgSsReserved[0] = d
30
31#define DbgSsGetThreadData() \
32 ((PDBGSS_THREAD_DATA)NtCurrentTeb()->DbgSsReserved[0])
33
34/* PRIVATE FUNCTIONS *********************************************************/
35
36static HANDLE
38{
43
44 /* SIDs to be used in the DACL */
45 PSID psidSystem = NULL;
46 PSID psidAdministrators = NULL;
47 PSID psidEveryone = NULL;
48
49 /* Buffer for the DACL */
50 PVOID pDaclBuf = NULL;
51
52 /* Minimum size of the DACL: an ACL descriptor and three ACCESS_ALLOWED_ACE
53 * headers. We will add the size of SIDs when they are known. */
54 SIZE_T nDaclBufSize =
55 sizeof(ACL) + 3 * FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
56
57 /* Security descriptor and attributes of the mutex */
58 SECURITY_DESCRIPTOR sdMutexSecurity;
59 SECURITY_ATTRIBUTES saMutexAttribs = {sizeof(saMutexAttribs),
60 &sdMutexSecurity,
61 TRUE};
62
63 /* Try to open the mutex */
65 TRUE,
66 L"DBWinMutex");
67 if (hMutex != NULL)
68 {
69 /* Success */
70 return hMutex;
71 }
72 /* Error other than the mutex not being found */
74 {
75 /* Failure */
76 return NULL;
77 }
78
79 /* If the mutex does not exist, set up its security, then create it */
80
81 /* Allocate the NT AUTHORITY\SYSTEM SID */
83 1,
85 0, 0, 0, 0, 0, 0, 0,
86 &psidSystem);
87 if (!NT_SUCCESS(Status))
88 goto Cleanup;
89
90 /* Allocate the BUILTIN\Administrators SID */
92 2,
95 0, 0, 0, 0, 0, 0,
96 &psidAdministrators);
97 if (!NT_SUCCESS(Status))
98 goto Cleanup;
99
100 /* Allocate the Everyone SID */
101 Status = RtlAllocateAndInitializeSid(&siaWorldAuth,
102 1,
104 0, 0, 0, 0, 0, 0, 0,
105 &psidEveryone);
106 if (!NT_SUCCESS(Status))
107 goto Cleanup;
108
109 /* Allocate space for the SIDs too */
110 nDaclBufSize += RtlLengthSid(psidSystem);
111 nDaclBufSize += RtlLengthSid(psidAdministrators);
112 nDaclBufSize += RtlLengthSid(psidEveryone);
113
114 /* Allocate the buffer for the DACL */
115 pDaclBuf = GlobalAlloc(GMEM_FIXED, nDaclBufSize);
116 if (pDaclBuf == NULL)
117 goto Cleanup;
118
119 /* Create the DACL */
120 Status = RtlCreateAcl(pDaclBuf, nDaclBufSize, ACL_REVISION);
121 if (!NT_SUCCESS(Status))
122 goto Cleanup;
123
124 /* Grant the minimum required access to Everyone */
130 psidEveryone);
131 if (!NT_SUCCESS(Status))
132 goto Cleanup;
133
134 /* Grant full access to BUILTIN\Administrators */
138 psidAdministrators);
139 if (!NT_SUCCESS(Status))
140 goto Cleanup;
141
142 /* Grant full access to NT AUTHORITY\SYSTEM */
146 psidSystem);
147 if (!NT_SUCCESS(Status))
148 goto Cleanup;
149
150 /* Create the security descriptor */
151 Status = RtlCreateSecurityDescriptor(&sdMutexSecurity,
153 if (!NT_SUCCESS(Status))
154 goto Cleanup;
155
156 /* Set the descriptor's DACL to the created ACL */
157 Status = RtlSetDaclSecurityDescriptor(&sdMutexSecurity,
158 TRUE,
159 pDaclBuf,
160 FALSE);
161 if (!NT_SUCCESS(Status))
162 goto Cleanup;
163
164 /* Create the mutex */
165 hMutex = CreateMutexW(&saMutexAttribs, FALSE, L"DBWinMutex");
166
167Cleanup:
168 /* Free the buffers */
169 if (pDaclBuf) GlobalFree(pDaclBuf);
170 if (psidEveryone) RtlFreeSid(psidEveryone);
171 if (psidAdministrators) RtlFreeSid(psidAdministrators);
172 if (psidSystem) RtlFreeSid(psidSystem);
173
174 return hMutex;
175}
176
177VOID
178WINAPI
182{
184
185 /* Allocate a thread structure */
186 ThreadData = RtlAllocateHeap(RtlGetProcessHeap(),
187 0,
188 sizeof(DBGSS_THREAD_DATA));
189 if (!ThreadData) return;
190
191 /* Fill it out */
192 ThreadData->ThreadHandle = hThread;
193 ThreadData->ProcessId = dwProcessId;
194 ThreadData->ThreadId = dwThreadId;
195 ThreadData->ProcessHandle = NULL;
196 ThreadData->HandleMarked = FALSE;
197
198 /* Link it */
201}
202
203VOID
204WINAPI
207{
209
210 /* Allocate a thread structure */
211 ThreadData = RtlAllocateHeap(RtlGetProcessHeap(),
212 0,
213 sizeof(DBGSS_THREAD_DATA));
214 if (!ThreadData) return;
215
216 /* Fill it out */
217 ThreadData->ProcessHandle = hProcess;
218 ThreadData->ProcessId = dwProcessId;
219 ThreadData->ThreadId = 0;
220 ThreadData->ThreadHandle = NULL;
221 ThreadData->HandleMarked = FALSE;
222
223 /* Link it */
226}
227
228VOID
229WINAPI
231{
233
234 /* Loop all thread data events */
236 {
237 /* Check if this one matches */
238 if (ThreadData->ThreadId == dwThreadId)
239 {
240 /* Mark the structure and break out */
241 ThreadData->HandleMarked = TRUE;
242 break;
243 }
244 }
245}
246
247VOID
248WINAPI
250{
252
253 /* Loop all thread data events */
255 {
256 /* Check if this one matches */
257 if ((ThreadData->ProcessId == dwProcessId) && !(ThreadData->ThreadId))
258 {
259 /* Mark the structure and break out */
260 ThreadData->HandleMarked = TRUE;
261 break;
262 }
263 }
264}
265
266VOID
267WINAPI
270{
272 PDBGSS_THREAD_DATA ThisData;
273
274 /* Loop all thread data events */
275 ThreadData = (PDBGSS_THREAD_DATA*)NtCurrentTeb()->DbgSsReserved;
276 ThisData = *ThreadData;
277 while(ThisData)
278 {
279 /* Check if this one matches */
280 if ((ThisData->HandleMarked) &&
281 ((ThisData->ProcessId == dwProcessId) || (ThisData->ThreadId == dwThreadId)))
282 {
283 /* Close open handles */
284 if (ThisData->ThreadHandle) CloseHandle(ThisData->ThreadHandle);
285 if (ThisData->ProcessHandle) CloseHandle(ThisData->ProcessHandle);
286
287 /* Unlink the thread data */
288 *ThreadData = ThisData->Next;
289
290 /* Free it*/
291 RtlFreeHeap(RtlGetProcessHeap(), 0, ThisData);
292 }
293 else
294 {
295 /* Move to the next one */
296 ThreadData = &ThisData->Next;
297 }
298 ThisData = *ThreadData;
299 }
300}
301
302VOID
303WINAPI
305{
307 PDBGSS_THREAD_DATA ThisData;
308
309 /* Loop all thread data events */
310 ThreadData = (PDBGSS_THREAD_DATA*)NtCurrentTeb()->DbgSsReserved;
311 ThisData = *ThreadData;
312 while(ThisData)
313 {
314 /* Check if this one matches */
315 if (ThisData->ProcessId == dwProcessId)
316 {
317 /* Close open handles */
318 if (ThisData->ThreadHandle) CloseHandle(ThisData->ThreadHandle);
319 if (ThisData->ProcessHandle) CloseHandle(ThisData->ProcessHandle);
320
321 /* Unlink the thread data */
322 *ThreadData = ThisData->Next;
323
324 /* Free it*/
325 RtlFreeHeap(RtlGetProcessHeap(), 0, ThisData);
326 }
327 else
328 {
329 /* Move to the next one */
330 ThreadData = &ThisData->Next;
331 }
332 ThisData = *ThreadData;
333 }
334}
335
336HANDLE
337WINAPI
339{
344
345 /* If we don't have a PID, look it up */
346 if (dwProcessId == MAXDWORD) dwProcessId = (DWORD_PTR)CsrGetProcessId();
347
348 /* Open a handle to the process */
350 ClientId.UniqueProcess = UlongToHandle(dwProcessId);
357 &ClientId);
358 if (!NT_SUCCESS(Status))
359 {
360 /* Fail */
362 return 0;
363 }
364
365 /* Return the handle */
366 return Handle;
367}
368
369/* PUBLIC FUNCTIONS **********************************************************/
370
371/*
372 * @implemented
373 */
374BOOL
375WINAPI
377 OUT PBOOL pbDebuggerPresent)
378{
379 HANDLE DebugPort;
381
382 /* Make sure we have an output and process*/
383 if (!(pbDebuggerPresent) || !(hProcess))
384 {
385 /* Fail */
387 return FALSE;
388 }
389
390 /* Check if the process has a debug object/port */
393 &DebugPort,
394 sizeof(DebugPort),
395 NULL);
396 if (NT_SUCCESS(Status))
397 {
398 /* Return the current state */
399 *pbDebuggerPresent = DebugPort != NULL;
400 return TRUE;
401 }
402
403 /* Otherwise, fail */
405 return FALSE;
406}
407
408/*
409 * @implemented
410 */
411BOOL
412WINAPI
415 IN DWORD dwContinueStatus)
416{
419
420 /* Set the Client ID */
421 ClientId.UniqueProcess = UlongToHandle(dwProcessId);
423
424 /* Continue debugging */
425 Status = DbgUiContinue(&ClientId, dwContinueStatus);
426 if (!NT_SUCCESS(Status))
427 {
428 /* Fail */
430 return FALSE;
431 }
432
433 /* Remove the process/thread handles */
434 RemoveHandles(dwProcessId, dwThreadId);
435
436 /* Success */
437 return TRUE;
438}
439
440/*
441 * @implemented
442 */
443BOOL
444WINAPI
446{
447 NTSTATUS Status, Status1;
449
450 /* Connect to the debugger */
452 if (!NT_SUCCESS(Status))
453 {
455 return FALSE;
456 }
457
458 /* Get the process handle */
459 Handle = ProcessIdToHandle(dwProcessId);
460 if (!Handle) return FALSE;
461
462 /* Now debug the process */
464
465 /* Close the handle since we're done */
466 Status1 = NtClose(Handle);
467 ASSERT(NT_SUCCESS(Status1));
468
469 /* Check if debugging worked */
470 if (!NT_SUCCESS(Status))
471 {
472 /* Fail */
474 return FALSE;
475 }
476
477 /* Success */
478 return TRUE;
479}
480
481/*
482 * @implemented
483 */
484BOOL
485WINAPI
487{
488 NTSTATUS Status, Status1;
490
491 /* Get the process handle */
492 Handle = ProcessIdToHandle(dwProcessId);
493 if (!Handle) return FALSE;
494
495 /* Close all the process handles */
496 CloseAllProcessHandles(dwProcessId);
497
498 /* Now stop debugging the process */
500 Status1 = NtClose(Handle);
501 ASSERT(NT_SUCCESS(Status1));
502
503 /* Check for failure */
504 if (!NT_SUCCESS(Status))
505 {
506 /* Fail */
508 return FALSE;
509 }
510
511 /* Success */
512 return TRUE;
513}
514
515/*
516 * @implemented
517 */
518BOOL
519WINAPI
521{
523
524 /* Send the breakin request */
526 if (!NT_SUCCESS(Status))
527 {
528 /* Failure */
530 return FALSE;
531 }
532
533 /* Success */
534 return TRUE;
535}
536
537/*
538 * @implemented
539 */
540BOOL
541WINAPI
543{
546 ULONG State;
547
548 /* Get the debug object */
550 if (!Handle)
551 {
552 /* Fail */
554 return FALSE;
555 }
556
557 /* Now set the kill-on-exit state */
558 State = KillOnExit != 0;
561 &State,
562 sizeof(State),
563 NULL);
564 if (!NT_SUCCESS(Status))
565 {
566 /* Fail */
568 return FALSE;
569 }
570
571 /* Success */
572 return TRUE;
573}
574
575/*
576 * @implemented
577 */
578BOOL
579WINAPI
581{
582 return (BOOL)NtCurrentPeb()->BeingDebugged;
583}
584
585/*
586 * @implemented
587 */
588BOOL
589WINAPI
591 IN DWORD dwMilliseconds)
592{
593 LARGE_INTEGER WaitTime;
595 DBGUI_WAIT_STATE_CHANGE WaitStateChange;
597
598 /* Convert to NT Timeout */
599 Timeout = BaseFormatTimeOut(&WaitTime, dwMilliseconds);
600
601 /* Loop while we keep getting interrupted */
602 do
603 {
604 /* Call the native API */
605 Status = DbgUiWaitStateChange(&WaitStateChange, Timeout);
606 } while ((Status == STATUS_ALERTED) || (Status == STATUS_USER_APC));
607
608 /* Check if the wait failed */
610 {
611 /* Set the error code and quit */
613 return FALSE;
614 }
615
616 /* Check if we timed out */
617 if (Status == STATUS_TIMEOUT)
618 {
619 /* Fail with a timeout error */
621 return FALSE;
622 }
623
624 /* Convert the structure */
625 Status = DbgUiConvertStateChangeStructure(&WaitStateChange, lpDebugEvent);
626 if (!NT_SUCCESS(Status))
627 {
628 /* Set the error code and quit */
630 return FALSE;
631 }
632
633 /* Check what kind of event this was */
634 switch (lpDebugEvent->dwDebugEventCode)
635 {
636 /* New thread was created */
638
639 /* Setup the thread data */
640 SaveThreadHandle(lpDebugEvent->dwProcessId,
641 lpDebugEvent->dwThreadId,
642 lpDebugEvent->u.CreateThread.hThread);
643 break;
644
645 /* New process was created */
647
648 /* Setup the process data */
649 SaveProcessHandle(lpDebugEvent->dwProcessId,
650 lpDebugEvent->u.CreateProcessInfo.hProcess);
651
652 /* Setup the thread data */
653 SaveThreadHandle(lpDebugEvent->dwProcessId,
654 lpDebugEvent->dwThreadId,
655 lpDebugEvent->u.CreateProcessInfo.hThread);
656 break;
657
658 /* Process was exited */
660
661 /* Mark the thread data as such and fall through */
662 MarkProcessHandle(lpDebugEvent->dwProcessId);
663
664 /* Thread was exited */
666
667 /* Mark the thread data */
668 MarkThreadHandle(lpDebugEvent->dwThreadId);
669 break;
670
671 /* Nothing to do */
676 case RIP_EVENT:
677 break;
678
679 /* Fail anything else */
680 default:
681 return FALSE;
682 }
683
684 /* Return success */
685 return TRUE;
686}
687
688/*
689 * @implemented
690 */
691VOID
692WINAPI
694{
696 {
697 ULONG_PTR a_nArgs[2];
698
699 a_nArgs[0] = (ULONG_PTR)(strlen(_OutputString) + 1);
700 a_nArgs[1] = (ULONG_PTR)_OutputString;
701
702 /* send the string to the user-mode debugger */
703 RaiseException(DBG_PRINTEXCEPTION_C, 0, 2, a_nArgs);
704 }
706 {
707 /* no user-mode debugger: try the systemwide debug message monitor, or the
708 kernel debugger as a last resort */
709
710 /* mutex used to synchronize invocations of OutputDebugString */
711 static HANDLE s_hDBMonMutex = NULL;
712 /* true if we already attempted to open/create the mutex */
713 static BOOL s_bDBMonMutexTriedOpen = FALSE;
714
715 /* local copy of the mutex handle */
716 volatile HANDLE hDBMonMutex = s_hDBMonMutex;
717 /* handle to the Section of the shared buffer */
718 volatile HANDLE hDBMonBuffer = NULL;
719
720 /* pointer to the mapped view of the shared buffer. It consist of the current
721 process id followed by the message string */
722 struct { DWORD ProcessId; CHAR Buffer[1]; } * pDBMonBuffer = NULL;
723
724 /* event: signaled by the debug message monitor when OutputDebugString can write
725 to the shared buffer */
726 volatile HANDLE hDBMonBufferReady = NULL;
727
728 /* event: to be signaled by OutputDebugString when it's done writing to the
729 shared buffer */
730 volatile HANDLE hDBMonDataReady = NULL;
731
732 /* mutex not opened, and no previous attempts to open/create it */
733 if (hDBMonMutex == NULL && !s_bDBMonMutexTriedOpen)
734 {
735 /* open/create the mutex */
736 hDBMonMutex = K32CreateDBMonMutex();
737 /* store the handle */
738 s_hDBMonMutex = hDBMonMutex;
739 }
740
742 {
743 volatile PCHAR a_cBuffer = NULL;
744
745 /* opening the mutex failed */
746 if (hDBMonMutex == NULL)
747 {
748 /* remember next time */
749 s_bDBMonMutexTriedOpen = TRUE;
750 }
751 /* opening the mutex succeeded */
752 else
753 {
754 do
755 {
756 /* synchronize with other invocations of OutputDebugString */
757 WaitForSingleObject(hDBMonMutex, INFINITE);
758
759 /* buffer of the system-wide debug message monitor */
760 hDBMonBuffer = OpenFileMappingW(SECTION_MAP_WRITE, FALSE, L"DBWIN_BUFFER");
761
762 /* couldn't open the buffer: send the string to the kernel debugger */
763 if (hDBMonBuffer == NULL) break;
764
765 /* map the buffer */
766 pDBMonBuffer = MapViewOfFile(hDBMonBuffer,
768 0,
769 0,
770 0);
771
772 /* couldn't map the buffer: send the string to the kernel debugger */
773 if (pDBMonBuffer == NULL) break;
774
775 /* open the event signaling that the buffer can be accessed */
776 hDBMonBufferReady = OpenEventW(SYNCHRONIZE, FALSE, L"DBWIN_BUFFER_READY");
777
778 /* couldn't open the event: send the string to the kernel debugger */
779 if (hDBMonBufferReady == NULL) break;
780
781 /* open the event to be signaled when the buffer has been filled */
782 hDBMonDataReady = OpenEventW(EVENT_MODIFY_STATE, FALSE, L"DBWIN_DATA_READY");
783 }
784 while(0);
785
786 /* we couldn't connect to the system-wide debug message monitor: send the
787 string to the kernel debugger */
788 if (hDBMonDataReady == NULL) ReleaseMutex(hDBMonMutex);
789 }
790
792 {
793 /* size of the current output block */
794 volatile SIZE_T nRoundLen;
795
796 /* size of the remainder of the string */
797 volatile SIZE_T nOutputStringLen;
798
799 /* output the whole string */
800 nOutputStringLen = strlen(_OutputString);
801
802 do
803 {
804 /* we're connected to the debug monitor:
805 write the current block to the shared buffer */
806 if (hDBMonDataReady)
807 {
808 /* wait a maximum of 10 seconds for the debug monitor
809 to finish processing the shared buffer */
810 if (WaitForSingleObject(hDBMonBufferReady, 10000) != WAIT_OBJECT_0)
811 {
812 /* timeout or failure: give up */
813 break;
814 }
815
816 /* write the process id into the buffer */
817 pDBMonBuffer->ProcessId = GetCurrentProcessId();
818
819 /* write only as many bytes as they fit in the buffer */
820 if (nOutputStringLen > (PAGE_SIZE - sizeof(DWORD) - 1))
821 nRoundLen = PAGE_SIZE - sizeof(DWORD) - 1;
822 else
823 nRoundLen = nOutputStringLen;
824
825 /* copy the current block into the buffer */
826 memcpy(pDBMonBuffer->Buffer, _OutputString, nRoundLen);
827
828 /* null-terminate the current block */
829 pDBMonBuffer->Buffer[nRoundLen] = 0;
830
831 /* signal that the data contains meaningful data and can be read */
832 SetEvent(hDBMonDataReady);
833 }
834 /* else, send the current block to the kernel debugger */
835 else
836 {
837 /* output in blocks of 512 characters */
838 a_cBuffer = (CHAR*)HeapAlloc(GetProcessHeap(), 0, 512);
839
840 if (!a_cBuffer)
841 {
842 DbgPrint("OutputDebugStringA: Failed\n");
843 break;
844 }
845
846 /* write a maximum of 511 bytes */
847 if (nOutputStringLen > 510)
848 nRoundLen = 510;
849 else
850 nRoundLen = nOutputStringLen;
851
852 /* copy the current block */
853 memcpy(a_cBuffer, _OutputString, nRoundLen);
854
855 /* null-terminate the current block */
856 a_cBuffer[nRoundLen] = 0;
857
858 /* send the current block to the kernel debugger */
859 DbgPrint("%s", a_cBuffer);
860
861 if (a_cBuffer)
862 {
863 HeapFree(GetProcessHeap(), 0, a_cBuffer);
864 a_cBuffer = NULL;
865 }
866 }
867
868 /* move to the next block */
869 _OutputString += nRoundLen;
870 nOutputStringLen -= nRoundLen;
871 }
872 /* repeat until the string has been fully output */
873 while (nOutputStringLen > 0);
874 }
875 /* ignore access violations and let other exceptions fall through */
877 {
878 if (a_cBuffer)
879 HeapFree(GetProcessHeap(), 0, a_cBuffer);
880
881 /* string copied verbatim from Microsoft's kernel32.dll */
882 DbgPrint("\nOutputDebugString faulted during output\n");
883 }
884 _SEH2_END;
885 }
887 {
888 /* close all the still open resources */
889 if (hDBMonBufferReady) CloseHandle(hDBMonBufferReady);
890 if (pDBMonBuffer) UnmapViewOfFile(pDBMonBuffer);
891 if (hDBMonBuffer) CloseHandle(hDBMonBuffer);
892 if (hDBMonDataReady) CloseHandle(hDBMonDataReady);
893
894 /* leave the critical section */
895 if (hDBMonDataReady != NULL)
896 ReleaseMutex(hDBMonMutex);
897 }
898 _SEH2_END;
899 }
900 _SEH2_END;
901}
902
903/*
904 * @implemented
905 */
906VOID
907WINAPI
909{
913
914 /* convert the string in ANSI */
915 RtlInitUnicodeString(&UnicodeString, OutputString);
917
918 /* OutputDebugStringW always prints something, even if conversion fails */
919 if (!NT_SUCCESS(Status)) AnsiString.Buffer = "";
920
921 /* Output the converted string */
923
924 /* free the converted string */
926}
927
928/* EOF */
#define NtCurrentPeb()
Definition: FLS.c:22
unsigned char BOOLEAN
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
LONG NTSTATUS
Definition: precomp.h:26
#define UlongToHandle(ul)
Definition: basetsd.h:97
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
SIZE_T LPDEBUG_EVENT
Definition: cordebug.idl:83
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
NTSTATUS NTAPI NtSetInformationDebugObject(IN HANDLE DebugHandle, IN DEBUGOBJECTINFOCLASS DebugObjectInformationClass, IN PVOID DebugInformation, IN ULONG DebugInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: dbgkobj.c:1921
@ DebugObjectKillProcessOnExitInformation
Definition: dbgktypes.h:58
NTSTATUS NTAPI DbgUiContinue(IN PCLIENT_ID ClientId, IN NTSTATUS ContinueStatus)
Definition: dbgui.c:47
NTSTATUS NTAPI DbgUiConvertStateChangeStructure(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange, OUT PVOID Win32DebugEvent)
Definition: dbgui.c:61
NTSTATUS NTAPI DbgUiDebugActiveProcess(IN HANDLE Process)
Definition: dbgui.c:355
NTSTATUS NTAPI DbgUiIssueRemoteBreakin(IN HANDLE Process)
Definition: dbgui.c:303
NTSTATUS NTAPI DbgUiStopDebugging(IN HANDLE Process)
Definition: dbgui.c:381
NTSTATUS NTAPI DbgUiConnectToDbg(VOID)
Definition: dbgui.c:25
NTSTATUS NTAPI DbgUiWaitStateChange(OUT PDBGUI_WAIT_STATE_CHANGE WaitStateChange, IN PLARGE_INTEGER TimeOut OPTIONAL)
Definition: dbgui.c:274
HANDLE NTAPI DbgUiGetThreadDebugObject(VOID)
Definition: dbgui.c:333
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SECTION_MAP_READ
Definition: compat.h:139
#define UnmapViewOfFile
Definition: compat.h:746
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define MapViewOfFile
Definition: compat.h:745
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
BOOL WINAPI DebugSetProcessKillOnExit(IN BOOL KillOnExit)
Definition: debugger.c:542
VOID WINAPI CloseAllProcessHandles(IN DWORD dwProcessId)
Definition: debugger.c:304
VOID WINAPI MarkProcessHandle(IN DWORD dwProcessId)
Definition: debugger.c:249
VOID WINAPI SaveThreadHandle(IN DWORD dwProcessId, IN DWORD dwThreadId, IN HANDLE hThread)
Definition: debugger.c:179
VOID WINAPI RemoveHandles(IN DWORD dwProcessId, IN DWORD dwThreadId)
Definition: debugger.c:268
BOOL WINAPI DebugActiveProcessStop(IN DWORD dwProcessId)
Definition: debugger.c:486
BOOL WINAPI ContinueDebugEvent(IN DWORD dwProcessId, IN DWORD dwThreadId, IN DWORD dwContinueStatus)
Definition: debugger.c:413
BOOL WINAPI DebugActiveProcess(IN DWORD dwProcessId)
Definition: debugger.c:445
struct _DBGSS_THREAD_DATA * PDBGSS_THREAD_DATA
VOID WINAPI SaveProcessHandle(IN DWORD dwProcessId, IN HANDLE hProcess)
Definition: debugger.c:205
static HANDLE K32CreateDBMonMutex(VOID)
Definition: debugger.c:37
VOID WINAPI OutputDebugStringW(IN LPCWSTR OutputString)
Definition: debugger.c:908
BOOL WINAPI DebugBreakProcess(IN HANDLE Process)
Definition: debugger.c:520
#define DbgSsSetThreadData(d)
Definition: debugger.c:28
HANDLE WINAPI ProcessIdToHandle(IN DWORD dwProcessId)
Definition: debugger.c:338
BOOL WINAPI WaitForDebugEvent(IN LPDEBUG_EVENT lpDebugEvent, IN DWORD dwMilliseconds)
Definition: debugger.c:590
VOID WINAPI OutputDebugStringA(IN LPCSTR _OutputString)
Definition: debugger.c:693
VOID WINAPI MarkThreadHandle(IN DWORD dwThreadId)
Definition: debugger.c:230
#define DbgSsGetThreadData()
Definition: debugger.c:31
struct _DBGSS_THREAD_DATA DBGSS_THREAD_DATA
BOOL WINAPI CheckRemoteDebuggerPresent(IN HANDLE hProcess, OUT PBOOL pbDebuggerPresent)
Definition: debugger.c:376
VOID WINAPI RaiseException(_In_ DWORD dwExceptionCode, _In_ DWORD dwExceptionFlags, _In_ DWORD nNumberOfArguments, _In_opt_ const ULONG_PTR *lpArguments)
Definition: except.c:700
PLARGE_INTEGER WINAPI BaseFormatTimeOut(OUT PLARGE_INTEGER Timeout, IN DWORD dwMilliseconds)
Definition: utils.c:288
static const WCHAR Cleanup[]
Definition: register.c:80
@ AnsiString
Definition: dnslib.h:19
#define INFINITE
Definition: serial.h:102
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SIZE
Definition: env_spec_w32.h:49
DWORD dwThreadId
Definition: fdebug.c:31
HANDLE NTAPI OpenFileMappingW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: filemap.c:297
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
#define DbgPrint
Definition: hal.h:12
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define PROCESS_SUSPEND_RESUME
Definition: pstypes.h:168
#define PROCESS_VM_READ
Definition: pstypes.h:162
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:167
#define PROCESS_VM_WRITE
Definition: pstypes.h:163
#define PROCESS_CREATE_THREAD
Definition: pstypes.h:159
#define PROCESS_VM_OPERATION
Definition: pstypes.h:161
@ ProcessDebugPort
Definition: winternl.h:395
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:91
#define NtCurrentTeb
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ASSERT(a)
Definition: mode.c:44
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
HANDLE hMutex
Definition: mutex.c:11
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
struct _ACL ACL
#define MUTANT_ALL_ACCESS
Definition: extypes.h:110
#define MUTANT_QUERY_STATE
Definition: extypes.h:109
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
NTSYSAPI PVOID NTAPI RtlFreeSid(_In_ _Post_invalid_ PSID Sid)
HANDLE hThread
Definition: wizard.c:28
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define SYNCHRONIZE
Definition: nt_native.h:61
#define SECTION_MAP_WRITE
Definition: nt_native.h:1288
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define READ_CONTROL
Definition: nt_native.h:58
#define DWORD
Definition: nt_native.h:44
#define MAXDWORD
NTSYSAPI NTSTATUS NTAPI RtlAllocateAndInitializeSid(IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount, IN ULONG SubAuthority0, IN ULONG SubAuthority1, IN ULONG SubAuthority2, IN ULONG SubAuthority3, IN ULONG SubAuthority4, IN ULONG SubAuthority5, IN ULONG SubAuthority6, IN ULONG SubAuthority7, OUT PSID *Sid)
Definition: sid.c:290
NTSTATUS NTAPI NtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId)
Definition: process.c:1440
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
#define STATUS_ALERTED
Definition: ntstatus.h:80
#define STATUS_USER_APC
Definition: ntstatus.h:78
#define DBG_UNABLE_TO_PROVIDE_HANDLE
Definition: ntstatus.h:49
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define DBG_PRINTEXCEPTION_C
Definition: ntstatus.h:53
#define L(x)
Definition: ntvdm.h:50
static ULONG Timeout
Definition: ping.c:61
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
HANDLE NTAPI CsrGetProcessId(VOID)
Definition: connect.c:507
HANDLE UniqueThread
Definition: compat.h:826
HANDLE UniqueProcess
Definition: compat.h:825
HANDLE ProcessHandle
Definition: debugger.c:22
struct _DBGSS_THREAD_DATA * Next
Definition: debugger.c:20
BOOLEAN HandleMarked
Definition: debugger.c:25
HANDLE ThreadHandle
Definition: debugger.c:21
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:682
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:576
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:618
HANDLE WINAPI DECLSPEC_HOTPATCH OpenMutexW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:605
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
#define DWORD_PTR
Definition: treelist.c:76
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define RIP_EVENT
Definition: winbase.h:111
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CREATE_PROCESS_DEBUG_EVENT
Definition: winbase.h:105
#define LOAD_DLL_DEBUG_EVENT
Definition: winbase.h:108
#define EVENT_MODIFY_STATE
Definition: winbase.h:164
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define EXIT_PROCESS_DEBUG_EVENT
Definition: winbase.h:107
#define GMEM_FIXED
Definition: winbase.h:319
#define OUTPUT_DEBUG_STRING_EVENT
Definition: winbase.h:110
#define EXCEPTION_DEBUG_EVENT
Definition: winbase.h:103
#define WAIT_OBJECT_0
Definition: winbase.h:432
#define CREATE_THREAD_DEBUG_EVENT
Definition: winbase.h:104
#define UNLOAD_DLL_DEBUG_EVENT
Definition: winbase.h:109
BOOL WINAPI IsDebuggerPresent(void)
Definition: debugger.c:580
#define EXIT_THREAD_DEBUG_EVENT
Definition: winbase.h:106
BOOL * PBOOL
Definition: windef.h:161
#define WINAPI
Definition: msvc.h:6
#define ERROR_SEM_TIMEOUT
Definition: winerror.h:193
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
#define SECURITY_WORLD_RID
Definition: setypes.h:541
#define SECURITY_LOCAL_SYSTEM_RID
Definition: setypes.h:574
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define ACL_REVISION
Definition: setypes.h:39
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175