ReactOS  0.4.15-dev-1384-g878186b
debug.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for debug.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI PsGetContextThread (IN PETHREAD Thread, IN OUT PCONTEXT ThreadContext, IN KPROCESSOR_MODE PreviousMode)
 
NTSTATUS NTAPI PsSetContextThread (IN PETHREAD Thread, IN OUT PCONTEXT ThreadContext, IN KPROCESSOR_MODE PreviousMode)
 
NTSTATUS NTAPI NtGetContextThread (IN HANDLE ThreadHandle, IN OUT PCONTEXT ThreadContext)
 
NTSTATUS NTAPI NtSetContextThread (IN HANDLE ThreadHandle, IN PCONTEXT ThreadContext)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file debug.c.

Function Documentation

◆ NtGetContextThread()

NTSTATUS NTAPI NtGetContextThread ( IN HANDLE  ThreadHandle,
IN OUT PCONTEXT  ThreadContext 
)

Definition at line 335 of file debug.c.

337 {
341  PAGED_CODE();
342 
343  /* Get the Thread Object */
344  Status = ObReferenceObjectByHandle(ThreadHandle,
346  PsThreadType,
347  PreviousMode,
348  (PVOID*)&Thread,
349  NULL);
350 
351  if (!NT_SUCCESS(Status)) return Status;
352 
353  /* Make sure it's not a system thread */
354  if (Thread->SystemThread)
355  {
356  /* Fail */
358  }
359  else
360  {
361  /* Call the kernel API */
362  Status = PsGetContextThread(Thread, ThreadContext, PreviousMode);
363  }
364 
365  /* Dereference it and return */
367  return Status;
368 }
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
POBJECT_TYPE PsThreadType
Definition: thread.c:20
ULONG SystemThread
Definition: pstypes.h:1124
NTSTATUS NTAPI PsGetContextThread(IN PETHREAD Thread, IN OUT PCONTEXT ThreadContext, IN KPROCESSOR_MODE PreviousMode)
Definition: debug.c:104
#define NULL
Definition: types.h:112
#define THREAD_GET_CONTEXT
#define PAGED_CODE()

Referenced by GetThreadContext().

◆ NtSetContextThread()

NTSTATUS NTAPI NtSetContextThread ( IN HANDLE  ThreadHandle,
IN PCONTEXT  ThreadContext 
)

Definition at line 372 of file debug.c.

374 {
378  PAGED_CODE();
379 
380  /* Get the Thread Object */
381  Status = ObReferenceObjectByHandle(ThreadHandle,
383  PsThreadType,
384  PreviousMode,
385  (PVOID*)&Thread,
386  NULL);
387 
388  if (!NT_SUCCESS(Status)) return Status;
389 
390  /* Make sure it's not a system thread */
391  if (Thread->SystemThread)
392  {
393  /* Fail */
395  }
396  else
397  {
398  /* Call the kernel API */
399  Status = PsSetContextThread(Thread, ThreadContext, PreviousMode);
400  }
401 
402  /* Dereference it and return */
404  return Status;
405 }
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI PsSetContextThread(IN PETHREAD Thread, IN OUT PCONTEXT ThreadContext, IN KPROCESSOR_MODE PreviousMode)
Definition: debug.c:226
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
#define THREAD_SET_CONTEXT
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
POBJECT_TYPE PsThreadType
Definition: thread.c:20
ULONG SystemThread
Definition: pstypes.h:1124
#define NULL
Definition: types.h:112
#define PAGED_CODE()

Referenced by SetThreadContext().

◆ PsGetContextThread()

NTSTATUS NTAPI PsGetContextThread ( IN PETHREAD  Thread,
IN OUT PCONTEXT  ThreadContext,
IN KPROCESSOR_MODE  PreviousMode 
)

Definition at line 104 of file debug.c.

107 {
108  GET_SET_CTX_CONTEXT GetSetContext;
109  ULONG Size = 0, Flags = 0;
111 
112  /* Enter SEH */
113  _SEH2_TRY
114  {
115  /* Set default length */
116  Size = sizeof(CONTEXT);
117 
118  /* Read the flags */
119  Flags = ProbeForReadUlong(&ThreadContext->ContextFlags);
120 
121 #ifdef _M_IX86
122  /* Check if the caller wanted extended registers */
125  {
126  /* Cut them out of the size */
127  Size = FIELD_OFFSET(CONTEXT, ExtendedRegisters);
128  }
129 #endif
130 
131  /* Check if we came from user mode */
132  if (PreviousMode != KernelMode)
133  {
134  /* Probe the context */
135  ProbeForWrite(ThreadContext, Size, sizeof(ULONG));
136  }
137  }
139  {
140  /* Return the exception code */
142  }
143  _SEH2_END;
144 
145  /* Initialize the wait event */
147 
148  /* Set the flags and previous mode */
149  RtlZeroMemory(&GetSetContext.Context, Size);
150  GetSetContext.Context.ContextFlags = Flags;
151  GetSetContext.Mode = PreviousMode;
152 
153  /* Check if we're running in the same thread */
154  if (Thread == PsGetCurrentThread())
155  {
156  /* Setup APC parameters manually */
157  GetSetContext.Apc.SystemArgument1 = NULL;
158  GetSetContext.Apc.SystemArgument2 = Thread;
159 
160  /* Enter a guarded region to simulate APC_LEVEL */
162 
163  /* Manually call the APC */
164  PspGetOrSetContextKernelRoutine(&GetSetContext.Apc,
165  NULL,
166  NULL,
167  &GetSetContext.Apc.SystemArgument1,
168  &GetSetContext.Apc.SystemArgument2);
169 
170  /* Leave the guarded region */
172 
173  /* We are done */
175  }
176  else
177  {
178  /* Initialize the APC */
179  KeInitializeApc(&GetSetContext.Apc,
180  &Thread->Tcb,
183  NULL,
184  NULL,
185  KernelMode,
186  NULL);
187 
188  /* Queue it as a Get APC */
189  if (!KeInsertQueueApc(&GetSetContext.Apc, NULL, Thread, 2))
190  {
191  /* It was already queued, so fail */
193  }
194  else
195  {
196  /* Wait for the APC to complete */
197  Status = KeWaitForSingleObject(&GetSetContext.Event,
198  0,
199  KernelMode,
200  FALSE,
201  NULL);
202  }
203  }
204 
205  _SEH2_TRY
206  {
207  /* Copy the context */
208  RtlCopyMemory(ThreadContext, &GetSetContext.Context, Size);
209  }
211  {
212  /* Get the exception code */
214  }
215  _SEH2_END;
216 
217  /* Return status */
218  return Status;
219 }
VOID NTAPI KeInitializeApc(IN PKAPC Apc, IN PKTHREAD Thread, IN KAPC_ENVIRONMENT TargetEnvironment, IN PKKERNEL_ROUTINE KernelRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, IN PKNORMAL_ROUTINE NormalRoutine, IN KPROCESSOR_MODE Mode, IN PVOID Context)
Definition: apc.c:651
#define CONTEXT_EXTENDED_REGISTERS
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
LONG NTSTATUS
Definition: precomp.h:26
KTHREAD Tcb
Definition: pstypes.h:1045
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
struct _CONTEXT CONTEXT
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4226
#define FALSE
Definition: types.h:117
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define KeLeaveGuardedRegion()
Definition: ke_x.h:63
ULONG ContextFlags
Definition: nt_native.h:1426
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
PVOID SystemArgument1
Definition: ketypes.h:551
KPROCESSOR_MODE Mode
Definition: ps.h:80
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define KeEnterGuardedRegion()
Definition: ke_x.h:34
#define ProbeForReadUlong(Ptr)
Definition: probe.h:65
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_SEH2_END
Definition: create.c:4400
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
KEVENT Event
Definition: ps.h:79
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
BOOLEAN NTAPI KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost)
Definition: apc.c:735
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
CONTEXT Context
Definition: ps.h:81
PVOID SystemArgument2
Definition: ketypes.h:552
VOID NTAPI PspGetOrSetContextKernelRoutine(IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2)
Definition: psctx.c:45

Referenced by NtGetContextThread().

◆ PsSetContextThread()

NTSTATUS NTAPI PsSetContextThread ( IN PETHREAD  Thread,
IN OUT PCONTEXT  ThreadContext,
IN KPROCESSOR_MODE  PreviousMode 
)

Definition at line 226 of file debug.c.

229 {
230  GET_SET_CTX_CONTEXT GetSetContext;
231  ULONG Size = 0, Flags = 0;
233 
234  /* Enter SEH */
235  _SEH2_TRY
236  {
237  /* Set default length */
238  Size = sizeof(CONTEXT);
239 
240  /* Read the flags */
241  Flags = ProbeForReadUlong(&ThreadContext->ContextFlags);
242 
243 #ifdef _M_IX86
244  /* Check if the caller wanted extended registers */
247  {
248  /* Cut them out of the size */
249  Size = FIELD_OFFSET(CONTEXT, ExtendedRegisters);
250  }
251 #endif
252 
253  /* Check if we came from user mode */
254  if (PreviousMode != KernelMode)
255  {
256  /* Probe the context */
257  ProbeForRead(ThreadContext, Size, sizeof(ULONG));
258  }
259 
260  /* Copy the context */
261  RtlCopyMemory(&GetSetContext.Context, ThreadContext, Size);
262  }
264  {
265  /* Return the exception code */
267  }
268  _SEH2_END;
269 
270  /* Initialize the wait event */
272 
273  /* Set the flags and previous mode */
274  GetSetContext.Context.ContextFlags = Flags;
275  GetSetContext.Mode = PreviousMode;
276 
277  /* Check if we're running in the same thread */
278  if (Thread == PsGetCurrentThread())
279  {
280  /* Setup APC parameters manually */
281  GetSetContext.Apc.SystemArgument1 = UlongToPtr(1);
282  GetSetContext.Apc.SystemArgument2 = Thread;
283 
284  /* Enter a guarded region to simulate APC_LEVEL */
286 
287  /* Manually call the APC */
288  PspGetOrSetContextKernelRoutine(&GetSetContext.Apc,
289  NULL,
290  NULL,
291  &GetSetContext.Apc.SystemArgument1,
292  &GetSetContext.Apc.SystemArgument2);
293 
294  /* Leave the guarded region */
296 
297  /* We are done */
299  }
300  else
301  {
302  /* Initialize the APC */
303  KeInitializeApc(&GetSetContext.Apc,
304  &Thread->Tcb,
307  NULL,
308  NULL,
309  KernelMode,
310  NULL);
311 
312  /* Queue it as a Get APC */
313  if (!KeInsertQueueApc(&GetSetContext.Apc, UlongToPtr(1), Thread, 2))
314  {
315  /* It was already queued, so fail */
317  }
318  else
319  {
320  /* Wait for the APC to complete */
321  Status = KeWaitForSingleObject(&GetSetContext.Event,
322  0,
323  KernelMode,
324  FALSE,
325  NULL);
326  }
327  }
328 
329  /* Return status */
330  return Status;
331 }
VOID NTAPI KeInitializeApc(IN PKAPC Apc, IN PKTHREAD Thread, IN KAPC_ENVIRONMENT TargetEnvironment, IN PKKERNEL_ROUTINE KernelRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, IN PKNORMAL_ROUTINE NormalRoutine, IN KPROCESSOR_MODE Mode, IN PVOID Context)
Definition: apc.c:651
#define CONTEXT_EXTENDED_REGISTERS
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
LONG NTSTATUS
Definition: precomp.h:26
KTHREAD Tcb
Definition: pstypes.h:1045
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
struct _CONTEXT CONTEXT
_SEH2_TRY
Definition: create.c:4226
#define FALSE
Definition: types.h:117
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define KeLeaveGuardedRegion()
Definition: ke_x.h:63
#define UlongToPtr(u)
Definition: config.h:106
ULONG ContextFlags
Definition: nt_native.h:1426
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
PVOID SystemArgument1
Definition: ketypes.h:551
KPROCESSOR_MODE Mode
Definition: ps.h:80
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define KeEnterGuardedRegion()
Definition: ke_x.h:34
#define ProbeForReadUlong(Ptr)
Definition: probe.h:65
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
_SEH2_END
Definition: create.c:4400
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
KEVENT Event
Definition: ps.h:79
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
BOOLEAN NTAPI KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost)
Definition: apc.c:735
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
CONTEXT Context
Definition: ps.h:81
PVOID SystemArgument2
Definition: ketypes.h:552
VOID NTAPI PspGetOrSetContextKernelRoutine(IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2)
Definition: psctx.c:45

Referenced by NtSetContextThread().