ReactOS  0.4.15-dev-5500-g82cf6c2
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 
18 typedef 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 
36 static HANDLE
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 }
176 
177 VOID
178 WINAPI
181  IN HANDLE hThread)
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 }
202 
203 VOID
204 WINAPI
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 }
227 
228 VOID
229 WINAPI
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 
247 VOID
248 WINAPI
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 
266 VOID
267 WINAPI
268 RemoveHandles(IN DWORD dwProcessId,
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 
302 VOID
303 WINAPI
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 
336 HANDLE
337 WINAPI
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 }
368 
369 /* PUBLIC FUNCTIONS **********************************************************/
370 
371 /*
372  * @implemented
373  */
374 BOOL
375 WINAPI
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  */
411 BOOL
412 WINAPI
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  */
443 BOOL
444 WINAPI
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 }
480 
481 /*
482  * @implemented
483  */
484 BOOL
485 WINAPI
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 }
514 
515 /*
516  * @implemented
517  */
518 BOOL
519 WINAPI
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  */
540 BOOL
541 WINAPI
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 }
574 
575 /*
576  * @implemented
577  */
578 BOOL
579 WINAPI
581 {
582  return (BOOL)NtCurrentPeb()->BeingDebugged;
583 }
584 
585 /*
586  * @implemented
587  */
588 BOOL
589 WINAPI
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  */
691 VOID
692 WINAPI
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 }
902 
903 /*
904  * @implemented
905  */
906 VOID
907 WINAPI
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 */
HANDLE NTAPI DbgUiGetThreadDebugObject(VOID)
Definition: dbgui.c:333
_SEH2_TRY
Definition: create.c:4226
signed char * PCHAR
Definition: retypes.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
HANDLE WINAPI ProcessIdToHandle(IN DWORD dwProcessId)
Definition: debugger.c:338
NTSTATUS NTAPI DbgUiConnectToDbg(VOID)
Definition: dbgui.c:25
#define IN
Definition: typedefs.h:39
#define SECURITY_LOCAL_SYSTEM_RID
Definition: setypes.h:574
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define CloseHandle
Definition: compat.h:739
#define MapViewOfFile
Definition: compat.h:745
#define DWORD_PTR
Definition: treelist.c:76
#define DbgPrint
Definition: hal.h:12
VOID WINAPI OutputDebugStringA(IN LPCSTR _OutputString)
Definition: debugger.c:693
VOID WINAPI MarkProcessHandle(IN DWORD dwProcessId)
Definition: debugger.c:249
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:166
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
BOOL WINAPI IsDebuggerPresent(VOID)
Definition: debugger.c:580
NTSTATUS NTAPI DbgUiStopDebugging(IN HANDLE Process)
Definition: dbgui.c:381
NTSYSAPI PVOID NTAPI RtlFreeSid(_In_ _Post_invalid_ PSID Sid)
#define DbgSsSetThreadData(d)
Definition: debugger.c:28
char CHAR
Definition: xmlstorage.h:175
static HANDLE K32CreateDBMonMutex(VOID)
Definition: debugger.c:37
LONG NTSTATUS
Definition: precomp.h:26
BOOL WINAPI ContinueDebugEvent(IN DWORD dwProcessId, IN DWORD dwThreadId, IN DWORD dwContinueStatus)
Definition: debugger.c:413
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
_In_ ULONG _In_ ULONG State
Definition: potypes.h:516
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
BOOLEAN HandleMarked
Definition: debugger.c:25
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
#define LOAD_DLL_DEBUG_EVENT
Definition: winbase.h:107
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_opt_ PCUNICODE_STRING UnicodeString
Definition: wdfstring.h:64
_SEH2_END
Definition: create.c:4400
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
#define PROCESS_SUSPEND_RESUME
Definition: pstypes.h:167
HANDLE UniqueProcess
Definition: compat.h:825
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
struct _DBGSS_THREAD_DATA * PDBGSS_THREAD_DATA
#define STATUS_ALERTED
Definition: ntstatus.h:80
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
#define DWORD
Definition: nt_native.h:44
BOOL WINAPI DebugSetProcessKillOnExit(IN BOOL KillOnExit)
Definition: debugger.c:542
PLARGE_INTEGER WINAPI BaseFormatTimeOut(OUT PLARGE_INTEGER Timeout, IN DWORD dwMilliseconds)
Definition: utils.c:288
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define PROCESS_CREATE_THREAD
Definition: pstypes.h:158
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:682
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI CloseAllProcessHandles(IN DWORD dwProcessId)
Definition: debugger.c:304
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
unsigned int BOOL
Definition: ntddk_ex.h:94
#define MUTANT_ALL_ACCESS
Definition: extypes.h:110
VOID WINAPI MarkThreadHandle(IN DWORD dwThreadId)
Definition: debugger.c:230
HANDLE WINAPI DECLSPEC_HOTPATCH OpenMutexW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:605
unsigned char BOOLEAN
struct _ACL ACL
#define UNLOAD_DLL_DEBUG_EVENT
Definition: winbase.h:108
SIZE_T LPDEBUG_EVENT
Definition: cordebug.idl:83
#define MAXDWORD
Definition: bufpool.h:45
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
const char * LPCSTR
Definition: xmlstorage.h:183
HANDLE hMutex
Definition: mutex.c:11
BOOL * PBOOL
Definition: windef.h:161
NTSTATUS NTAPI DbgUiContinue(IN PCLIENT_ID ClientId, IN NTSTATUS ContinueStatus)
Definition: dbgui.c:47
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
NTSTATUS NTAPI DbgUiDebugActiveProcess(IN HANDLE Process)
Definition: dbgui.c:355
#define SECTION_MAP_WRITE
Definition: nt_native.h:1288
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
HANDLE ProcessHandle
Definition: debugger.c:22
Status
Definition: gdiplustypes.h:24
#define EXIT_PROCESS_DEBUG_EVENT
Definition: winbase.h:106
#define WAIT_OBJECT_0
Definition: winbase.h:406
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1165
#define PROCESS_VM_WRITE
Definition: pstypes.h:162
#define GetProcessHeap()
Definition: compat.h:736
BOOL WINAPI DebugActiveProcessStop(IN DWORD dwProcessId)
Definition: debugger.c:486
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define ASSERT(a)
Definition: mode.c:44
#define CREATE_THREAD_DEBUG_EVENT
Definition: winbase.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define UlongToHandle(ul)
Definition: basetsd.h:97
VOID WINAPI OutputDebugStringW(IN LPCWSTR OutputString)
Definition: debugger.c:908
BOOL WINAPI DebugBreakProcess(IN HANDLE Process)
Definition: debugger.c:520
#define WINAPI
Definition: msvc.h:6
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DBG_UNABLE_TO_PROVIDE_HANDLE
Definition: ntstatus.h:49
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
#define SetLastError(x)
Definition: compat.h:752
NTSTATUS NTAPI DbgUiConvertStateChangeStructure(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange, OUT PVOID Win32DebugEvent)
Definition: dbgui.c:61
#define SECURITY_WORLD_RID
Definition: setypes.h:541
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSTATUS NTAPI DbgUiWaitStateChange(OUT PDBGUI_WAIT_STATE_CHANGE WaitStateChange, IN PLARGE_INTEGER TimeOut OPTIONAL)
Definition: dbgui.c:274
HANDLE UniqueThread
Definition: compat.h:826
#define READ_CONTROL
Definition: nt_native.h:58
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:618
BOOL WINAPI WaitForDebugEvent(IN LPDEBUG_EVENT lpDebugEvent, IN DWORD dwMilliseconds)
Definition: debugger.c:590
DWORD dwThreadId
Definition: fdebug.c:31
NTSTATUS NTAPI DbgUiIssueRemoteBreakin(IN HANDLE Process)
Definition: dbgui.c:303
#define GMEM_FIXED
Definition: winbase.h:293
#define SECTION_MAP_READ
Definition: compat.h:139
#define DbgSsGetThreadData()
Definition: debugger.c:31
#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
static const WCHAR Cleanup[]
Definition: register.c:80
#define SYNCHRONIZE
Definition: nt_native.h:61
HANDLE NTAPI OpenFileMappingW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: filemap.c:297
BOOL WINAPI CheckRemoteDebuggerPresent(IN HANDLE hProcess, OUT PBOOL pbDebuggerPresent)
Definition: debugger.c:376
_SEH2_FINALLY
Definition: create.c:4371
VOID WINAPI SaveProcessHandle(IN DWORD dwProcessId, IN HANDLE hProcess)
Definition: debugger.c:205
#define STATUS_USER_APC
Definition: ntstatus.h:78
VOID WINAPI RemoveHandles(IN DWORD dwProcessId, IN DWORD dwThreadId)
Definition: debugger.c:268
ULONG_PTR SIZE_T
Definition: typedefs.h:80
static ULONG Timeout
Definition: ping.c:61
struct _DBGSS_THREAD_DATA DBGSS_THREAD_DATA
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
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 NtCurrentPeb()
Definition: FLS.c:22
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
VOID WINAPI SaveThreadHandle(IN DWORD dwProcessId, IN DWORD dwThreadId, IN HANDLE hThread)
Definition: debugger.c:179
#define EXCEPTION_DEBUG_EVENT
Definition: winbase.h:102
HANDLE NTAPI CsrGetProcessId(VOID)
Definition: connect.c:507
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 ERROR_SEM_TIMEOUT
Definition: winerror.h:193
#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
HANDLE hThread
Definition: wizard.c:28
#define EXIT_THREAD_DEBUG_EVENT
Definition: winbase.h:105
#define ACL_REVISION
Definition: setypes.h:39
#define PROCESS_VM_READ
Definition: pstypes.h:161
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
_In_ HANDLE Handle
Definition: extypes.h:390
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
#define OUTPUT_DEBUG_STRING_EVENT
Definition: winbase.h:109
#define EVENT_MODIFY_STATE
Definition: winbase.h:163
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define PROCESS_VM_OPERATION
Definition: pstypes.h:160
#define CREATE_PROCESS_DEBUG_EVENT
Definition: winbase.h:104
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
BOOL WINAPI DebugActiveProcess(IN DWORD dwProcessId)
Definition: debugger.c:445
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
HANDLE ThreadHandle
Definition: debugger.c:21
#define INFINITE
Definition: serial.h:102
#define UnmapViewOfFile
Definition: compat.h:746
#define MUTANT_QUERY_STATE
Definition: extypes.h:109
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652
struct _DBGSS_THREAD_DATA * Next
Definition: debugger.c:20
#define HeapFree(x, y, z)
Definition: compat.h:735
#define RIP_EVENT
Definition: winbase.h:110
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1158
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59