ReactOS  0.4.15-dev-5500-g82cf6c2
debugger.c File Reference
#include <k32.h>
#include <ndk/dbgkfuncs.h>
#include <debug.h>
Include dependency graph for debugger.c:

Go to the source code of this file.

Classes

struct  _DBGSS_THREAD_DATA
 

Macros

#define NDEBUG
 
#define DbgSsSetThreadData(d)   NtCurrentTeb()->DbgSsReserved[0] = d
 
#define DbgSsGetThreadData()   ((PDBGSS_THREAD_DATA)NtCurrentTeb()->DbgSsReserved[0])
 

Typedefs

typedef struct _DBGSS_THREAD_DATA DBGSS_THREAD_DATA
 
typedef struct _DBGSS_THREAD_DATAPDBGSS_THREAD_DATA
 

Functions

static HANDLE K32CreateDBMonMutex (VOID)
 
VOID WINAPI SaveThreadHandle (IN DWORD dwProcessId, IN DWORD dwThreadId, IN HANDLE hThread)
 
VOID WINAPI SaveProcessHandle (IN DWORD dwProcessId, IN HANDLE hProcess)
 
VOID WINAPI MarkThreadHandle (IN DWORD dwThreadId)
 
VOID WINAPI MarkProcessHandle (IN DWORD dwProcessId)
 
VOID WINAPI RemoveHandles (IN DWORD dwProcessId, IN DWORD dwThreadId)
 
VOID WINAPI CloseAllProcessHandles (IN DWORD dwProcessId)
 
HANDLE WINAPI ProcessIdToHandle (IN DWORD dwProcessId)
 
BOOL WINAPI CheckRemoteDebuggerPresent (IN HANDLE hProcess, OUT PBOOL pbDebuggerPresent)
 
BOOL WINAPI ContinueDebugEvent (IN DWORD dwProcessId, IN DWORD dwThreadId, IN DWORD dwContinueStatus)
 
BOOL WINAPI DebugActiveProcess (IN DWORD dwProcessId)
 
BOOL WINAPI DebugActiveProcessStop (IN DWORD dwProcessId)
 
BOOL WINAPI DebugBreakProcess (IN HANDLE Process)
 
BOOL WINAPI DebugSetProcessKillOnExit (IN BOOL KillOnExit)
 
BOOL WINAPI IsDebuggerPresent (VOID)
 
BOOL WINAPI WaitForDebugEvent (IN LPDEBUG_EVENT lpDebugEvent, IN DWORD dwMilliseconds)
 
VOID WINAPI OutputDebugStringA (IN LPCSTR _OutputString)
 
VOID WINAPI OutputDebugStringW (IN LPCWSTR OutputString)
 

Macro Definition Documentation

◆ DbgSsGetThreadData

#define DbgSsGetThreadData ( )    ((PDBGSS_THREAD_DATA)NtCurrentTeb()->DbgSsReserved[0])

Definition at line 31 of file debugger.c.

◆ DbgSsSetThreadData

#define DbgSsSetThreadData (   d)    NtCurrentTeb()->DbgSsReserved[0] = d

Definition at line 28 of file debugger.c.

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file debugger.c.

Typedef Documentation

◆ DBGSS_THREAD_DATA

◆ PDBGSS_THREAD_DATA

Function Documentation

◆ CheckRemoteDebuggerPresent()

BOOL WINAPI CheckRemoteDebuggerPresent ( IN HANDLE  hProcess,
OUT PBOOL  pbDebuggerPresent 
)

Definition at line 376 of file debugger.c.

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 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
#define FALSE
Definition: types.h:117
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SetLastError(x)
Definition: compat.h:752
#define NULL
Definition: types.h:112
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59

◆ CloseAllProcessHandles()

VOID WINAPI CloseAllProcessHandles ( IN DWORD  dwProcessId)

Definition at line 304 of file debugger.c.

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 }
#define CloseHandle
Definition: compat.h:739
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
HANDLE ProcessHandle
Definition: debugger.c:22
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
HANDLE ThreadHandle
Definition: debugger.c:21
struct _DBGSS_THREAD_DATA * Next
Definition: debugger.c:20

Referenced by DebugActiveProcessStop().

◆ ContinueDebugEvent()

BOOL WINAPI ContinueDebugEvent ( IN DWORD  dwProcessId,
IN DWORD  dwThreadId,
IN DWORD  dwContinueStatus 
)

Definition at line 413 of file debugger.c.

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 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
HANDLE UniqueProcess
Definition: compat.h:825
#define FALSE
Definition: types.h:117
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
NTSTATUS NTAPI DbgUiContinue(IN PCLIENT_ID ClientId, IN NTSTATUS ContinueStatus)
Definition: dbgui.c:47
Status
Definition: gdiplustypes.h:24
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1165
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define UlongToHandle(ul)
Definition: basetsd.h:97
HANDLE UniqueThread
Definition: compat.h:826
DWORD dwThreadId
Definition: fdebug.c:31
VOID WINAPI RemoveHandles(IN DWORD dwProcessId, IN DWORD dwThreadId)
Definition: debugger.c:268

Referenced by Main(), test_debug_children(), test_debug_loop(), test_DebuggingFlag(), test_NtSuspendProcess(), test_query_process_debug_flags(), test_query_process_debug_object_handle(), test_query_process_debug_port(), and wWinMain().

◆ DebugActiveProcess()

BOOL WINAPI DebugActiveProcess ( IN DWORD  dwProcessId)

Definition at line 445 of file debugger.c.

446 {
447  NTSTATUS Status, Status1;
448  HANDLE Handle;
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 }
HANDLE WINAPI ProcessIdToHandle(IN DWORD dwProcessId)
Definition: debugger.c:338
NTSTATUS NTAPI DbgUiConnectToDbg(VOID)
Definition: dbgui.c:25
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
NTSTATUS NTAPI DbgUiDebugActiveProcess(IN HANDLE Process)
Definition: dbgui.c:355
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
_In_ HANDLE Handle
Definition: extypes.h:390

Referenced by dll_entry_point(), doChild(), doDebugger(), Main(), test_debug_children(), test_debug_loop(), test_ExitProcess(), test_NtSuspendProcess(), test_query_process_debug_flags(), and wWinMain().

◆ DebugActiveProcessStop()

BOOL WINAPI DebugActiveProcessStop ( IN DWORD  dwProcessId)

Definition at line 486 of file debugger.c.

487 {
488  NTSTATUS Status, Status1;
489  HANDLE Handle;
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 }
HANDLE WINAPI ProcessIdToHandle(IN DWORD dwProcessId)
Definition: debugger.c:338
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI DbgUiStopDebugging(IN HANDLE Process)
Definition: dbgui.c:381
LONG NTSTATUS
Definition: precomp.h:26
VOID WINAPI CloseAllProcessHandles(IN DWORD dwProcessId)
Definition: debugger.c:304
#define FALSE
Definition: types.h:117
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SetLastError(x)
Definition: compat.h:752
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
_In_ HANDLE Handle
Definition: extypes.h:390

Referenced by test_query_process_debug_flags().

◆ DebugBreakProcess()

BOOL WINAPI DebugBreakProcess ( IN HANDLE  Process)

Definition at line 520 of file debugger.c.

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 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI DbgUiIssueRemoteBreakin(IN HANDLE Process)
Definition: dbgui.c:303
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219

◆ DebugSetProcessKillOnExit()

BOOL WINAPI DebugSetProcessKillOnExit ( IN BOOL  KillOnExit)

Definition at line 542 of file debugger.c.

543 {
544  HANDLE Handle;
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 }
HANDLE NTAPI DbgUiGetThreadDebugObject(VOID)
Definition: dbgui.c:333
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
_In_ ULONG _In_ ULONG State
Definition: potypes.h:516
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define FALSE
Definition: types.h:117
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NULL
Definition: types.h:112
NTSTATUS NTAPI NtSetInformationDebugObject(IN HANDLE DebugHandle, IN DEBUGOBJECTINFOCLASS DebugObjectInformationClass, IN PVOID DebugInformation, IN ULONG DebugInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: dbgkobj.c:1921
_In_ HANDLE Handle
Definition: extypes.h:390
unsigned int ULONG
Definition: retypes.h:1

Referenced by wWinMain().

◆ IsDebuggerPresent()

BOOL WINAPI IsDebuggerPresent ( VOID  )

Definition at line 580 of file debugger.c.

581 {
582  return (BOOL)NtCurrentPeb()->BeingDebugged;
583 }
unsigned int BOOL
Definition: ntddk_ex.h:94
#define NtCurrentPeb()
Definition: FLS.c:22

Referenced by _CrtDbgReportWindow(), ConsoleControlDispatcher(), init_funcs(), InitThreads(), and wmain().

◆ K32CreateDBMonMutex()

static HANDLE K32CreateDBMonMutex ( VOID  )
static

Definition at line 37 of file debugger.c.

38 {
41  HANDLE hMutex;
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 */
73  else if (GetLastError() != ERROR_FILE_NOT_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 */
125  Status = RtlAddAccessAllowedAce(pDaclBuf,
126  ACL_REVISION,
127  SYNCHRONIZE |
128  READ_CONTROL |
130  psidEveryone);
131  if (!NT_SUCCESS(Status))
132  goto Cleanup;
133 
134  /* Grant full access to BUILTIN\Administrators */
135  Status = RtlAddAccessAllowedAce(pDaclBuf,
136  ACL_REVISION,
138  psidAdministrators);
139  if (!NT_SUCCESS(Status))
140  goto Cleanup;
141 
142  /* Grant full access to NT AUTHORITY\SYSTEM */
143  Status = RtlAddAccessAllowedAce(pDaclBuf,
144  ACL_REVISION,
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 
167 Cleanup:
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 }
#define SECURITY_LOCAL_SYSTEM_RID
Definition: setypes.h:574
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define TRUE
Definition: types.h:120
NTSYSAPI PVOID NTAPI RtlFreeSid(_In_ _Post_invalid_ PSID Sid)
LONG NTSTATUS
Definition: precomp.h:26
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
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
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
#define MUTANT_ALL_ACCESS
Definition: extypes.h:110
HANDLE WINAPI DECLSPEC_HOTPATCH OpenMutexW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:605
struct _ACL ACL
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
HANDLE hMutex
Definition: mutex.c:11
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
Status
Definition: gdiplustypes.h:24
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
#define SECURITY_WORLD_RID
Definition: setypes.h:541
#define READ_CONTROL
Definition: nt_native.h:58
#define GMEM_FIXED
Definition: winbase.h:293
static const WCHAR Cleanup[]
Definition: register.c:80
#define SYNCHRONIZE
Definition: nt_native.h:61
ULONG_PTR SIZE_T
Definition: typedefs.h:80
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:576
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
#define ACL_REVISION
Definition: setypes.h:39
#define MUTANT_QUERY_STATE
Definition: extypes.h:109
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652

Referenced by OutputDebugStringA().

◆ MarkProcessHandle()

VOID WINAPI MarkProcessHandle ( IN DWORD  dwProcessId)

Definition at line 249 of file debugger.c.

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 }
#define TRUE
Definition: types.h:120
#define DbgSsGetThreadData()
Definition: debugger.c:31

Referenced by WaitForDebugEvent().

◆ MarkThreadHandle()

VOID WINAPI MarkThreadHandle ( IN DWORD  dwThreadId)

Definition at line 230 of file debugger.c.

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 }
#define TRUE
Definition: types.h:120
DWORD dwThreadId
Definition: fdebug.c:31
#define DbgSsGetThreadData()
Definition: debugger.c:31

Referenced by WaitForDebugEvent().

◆ OutputDebugStringA()

VOID WINAPI OutputDebugStringA ( IN LPCSTR  _OutputString)

Definition at line 693 of file debugger.c.

694 {
695  _SEH2_TRY
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 
741  _SEH2_TRY
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 
791  _SEH2_TRY
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 }
_SEH2_TRY
Definition: create.c:4226
signed char * PCHAR
Definition: retypes.h:7
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2709
#define CloseHandle
Definition: compat.h:739
#define MapViewOfFile
Definition: compat.h:745
#define DbgPrint
Definition: hal.h:12
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
char CHAR
Definition: xmlstorage.h:175
static HANDLE K32CreateDBMonMutex(VOID)
Definition: debugger.c:37
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
_SEH2_END
Definition: create.c:4400
#define DWORD
Definition: nt_native.h:44
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:682
uint32_t ULONG_PTR
Definition: typedefs.h:65
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: bufpool.h:45
#define SECTION_MAP_WRITE
Definition: nt_native.h:1288
#define WAIT_OBJECT_0
Definition: winbase.h:406
#define GetProcessHeap()
Definition: compat.h:736
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:618
#define SECTION_MAP_READ
Definition: compat.h:139
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define DBG_PRINTEXCEPTION_C
Definition: ntstatus.h:53
#define SYNCHRONIZE
Definition: nt_native.h:61
HANDLE NTAPI OpenFileMappingW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: filemap.c:297
_SEH2_FINALLY
Definition: create.c:4371
ULONG_PTR SIZE_T
Definition: typedefs.h:80
VOID WINAPI RaiseException(IN DWORD dwExceptionCode, IN DWORD dwExceptionFlags, IN DWORD nNumberOfArguments, IN CONST ULONG_PTR *lpArguments OPTIONAL)
Definition: except.c:700
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define NULL
Definition: types.h:112
#define EVENT_MODIFY_STATE
Definition: winbase.h:163
#define ULONG_PTR
Definition: config.h:101
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define INFINITE
Definition: serial.h:102
#define UnmapViewOfFile
Definition: compat.h:746
#define HeapFree(x, y, z)
Definition: compat.h:735
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1158

Referenced by OutputDebugStringW().

◆ OutputDebugStringW()

VOID WINAPI OutputDebugStringW ( IN LPCWSTR  OutputString)

Definition at line 908 of file debugger.c.

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 }
VOID WINAPI OutputDebugStringA(IN LPCSTR _OutputString)
Definition: debugger.c:693
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_opt_ PCUNICODE_STRING UnicodeString
Definition: wdfstring.h:64
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)

◆ ProcessIdToHandle()

HANDLE WINAPI ProcessIdToHandle ( IN DWORD  dwProcessId)

Definition at line 338 of file debugger.c.

339 {
342  HANDLE Handle;
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 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define DWORD_PTR
Definition: treelist.c:76
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:166
LONG NTSTATUS
Definition: precomp.h:26
#define PROCESS_SUSPEND_RESUME
Definition: pstypes.h:167
HANDLE UniqueProcess
Definition: compat.h:825
NTSTATUS NTAPI NtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId)
Definition: process.c:1440
#define PROCESS_CREATE_THREAD
Definition: pstypes.h:158
#define MAXDWORD
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
Status
Definition: gdiplustypes.h:24
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1165
#define PROCESS_VM_WRITE
Definition: pstypes.h:162
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define UlongToHandle(ul)
Definition: basetsd.h:97
HANDLE UniqueThread
Definition: compat.h:826
HANDLE NTAPI CsrGetProcessId(VOID)
Definition: connect.c:507
#define NULL
Definition: types.h:112
#define PROCESS_VM_READ
Definition: pstypes.h:161
_In_ HANDLE Handle
Definition: extypes.h:390
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define PROCESS_VM_OPERATION
Definition: pstypes.h:160

Referenced by DebugActiveProcess(), and DebugActiveProcessStop().

◆ RemoveHandles()

VOID WINAPI RemoveHandles ( IN DWORD  dwProcessId,
IN DWORD  dwThreadId 
)

Definition at line 268 of file debugger.c.

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 }
#define CloseHandle
Definition: compat.h:739
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
BOOLEAN HandleMarked
Definition: debugger.c:25
HANDLE ProcessHandle
Definition: debugger.c:22
DWORD dwThreadId
Definition: fdebug.c:31
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
HANDLE ThreadHandle
Definition: debugger.c:21
struct _DBGSS_THREAD_DATA * Next
Definition: debugger.c:20

Referenced by ContinueDebugEvent().

◆ SaveProcessHandle()

VOID WINAPI SaveProcessHandle ( IN DWORD  dwProcessId,
IN HANDLE  hProcess 
)

Definition at line 205 of file debugger.c.

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 */
224  ThreadData->Next = DbgSsGetThreadData();
226 }
#define DbgSsSetThreadData(d)
Definition: debugger.c:28
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
#define FALSE
Definition: types.h:117
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define DbgSsGetThreadData()
Definition: debugger.c:31
#define NULL
Definition: types.h:112

Referenced by WaitForDebugEvent().

◆ SaveThreadHandle()

VOID WINAPI SaveThreadHandle ( IN DWORD  dwProcessId,
IN DWORD  dwThreadId,
IN HANDLE  hThread 
)

Definition at line 179 of file debugger.c.

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 */
199  ThreadData->Next = DbgSsGetThreadData();
201 }
#define DbgSsSetThreadData(d)
Definition: debugger.c:28
#define FALSE
Definition: types.h:117
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
DWORD dwThreadId
Definition: fdebug.c:31
#define DbgSsGetThreadData()
Definition: debugger.c:31
#define NULL
Definition: types.h:112
HANDLE hThread
Definition: wizard.c:28

Referenced by WaitForDebugEvent().

◆ WaitForDebugEvent()

BOOL WINAPI WaitForDebugEvent ( IN LPDEBUG_EVENT  lpDebugEvent,
IN DWORD  dwMilliseconds 
)

Definition at line 590 of file debugger.c.

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 }
VOID WINAPI MarkProcessHandle(IN DWORD dwProcessId)
Definition: debugger.c:249
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define LOAD_DLL_DEBUG_EVENT
Definition: winbase.h:107
#define STATUS_ALERTED
Definition: ntstatus.h:80
PLARGE_INTEGER WINAPI BaseFormatTimeOut(OUT PLARGE_INTEGER Timeout, IN DWORD dwMilliseconds)
Definition: utils.c:288
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define FALSE
Definition: types.h:117
VOID WINAPI MarkThreadHandle(IN DWORD dwThreadId)
Definition: debugger.c:230
#define UNLOAD_DLL_DEBUG_EVENT
Definition: winbase.h:108
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
Status
Definition: gdiplustypes.h:24
#define EXIT_PROCESS_DEBUG_EVENT
Definition: winbase.h:106
#define CREATE_THREAD_DEBUG_EVENT
Definition: winbase.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DBG_UNABLE_TO_PROVIDE_HANDLE
Definition: ntstatus.h:49
#define SetLastError(x)
Definition: compat.h:752
NTSTATUS NTAPI DbgUiConvertStateChangeStructure(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange, OUT PVOID Win32DebugEvent)
Definition: dbgui.c:61
NTSTATUS NTAPI DbgUiWaitStateChange(OUT PDBGUI_WAIT_STATE_CHANGE WaitStateChange, IN PLARGE_INTEGER TimeOut OPTIONAL)
Definition: dbgui.c:274
VOID WINAPI SaveProcessHandle(IN DWORD dwProcessId, IN HANDLE hProcess)
Definition: debugger.c:205
#define STATUS_USER_APC
Definition: ntstatus.h:78
static ULONG Timeout
Definition: ping.c:61
VOID WINAPI SaveThreadHandle(IN DWORD dwProcessId, IN DWORD dwThreadId, IN HANDLE hThread)
Definition: debugger.c:179
#define EXCEPTION_DEBUG_EVENT
Definition: winbase.h:102
#define ERROR_SEM_TIMEOUT
Definition: winerror.h:193
#define EXIT_THREAD_DEBUG_EVENT
Definition: winbase.h:105
#define OUTPUT_DEBUG_STRING_EVENT
Definition: winbase.h:109
#define CREATE_PROCESS_DEBUG_EVENT
Definition: winbase.h:104
#define RIP_EVENT
Definition: winbase.h:110

Referenced by dll_entry_point(), Main(), test_debug_children(), test_debug_loop(), test_DebuggingFlag(), test_NtSuspendProcess(), test_query_process_debug_flags(), test_query_process_debug_object_handle(), test_query_process_debug_port(), and wWinMain().