ReactOS  0.4.14-dev-98-gb0d4763
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 334 of file debug.c.

336 {
340  PAGED_CODE();
341 
342  /* Get the Thread Object */
343  Status = ObReferenceObjectByHandle(ThreadHandle,
345  PsThreadType,
346  PreviousMode,
347  (PVOID*)&Thread,
348  NULL);
349 
350  if (!NT_SUCCESS(Status)) return Status;
351 
352  /* Make sure it's not a system thread */
353  if (Thread->SystemThread)
354  {
355  /* Fail */
357  }
358  else
359  {
360  /* Call the kernel API */
361  Status = PsGetContextThread(Thread, ThreadContext, PreviousMode);
362  }
363 
364  /* Dereference it and return */
366  return Status;
367 }
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
#define PAGED_CODE()
Definition: video.h:57
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
smooth NULL
Definition: ftsmooth.c:416
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_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:1113
NTSTATUS NTAPI PsGetContextThread(IN PETHREAD Thread, IN OUT PCONTEXT ThreadContext, IN KPROCESSOR_MODE PreviousMode)
Definition: debug.c:104
Status
Definition: gdiplustypes.h:24
#define THREAD_GET_CONTEXT

Referenced by GetThreadContext().

◆ NtSetContextThread()

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

Definition at line 371 of file debug.c.

373 {
377  PAGED_CODE();
378 
379  /* Get the Thread Object */
380  Status = ObReferenceObjectByHandle(ThreadHandle,
382  PsThreadType,
383  PreviousMode,
384  (PVOID*)&Thread,
385  NULL);
386 
387  if (!NT_SUCCESS(Status)) return Status;
388 
389  /* Make sure it's not a system thread */
390  if (Thread->SystemThread)
391  {
392  /* Fail */
394  }
395  else
396  {
397  /* Call the kernel API */
398  Status = PsSetContextThread(Thread, ThreadContext, PreviousMode);
399  }
400 
401  /* Dereference it and return */
403  return Status;
404 }
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI PsSetContextThread(IN PETHREAD Thread, IN OUT PCONTEXT ThreadContext, IN KPROCESSOR_MODE PreviousMode)
Definition: debug.c:225
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
#define PAGED_CODE()
Definition: video.h:57
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
smooth NULL
Definition: ftsmooth.c:416
#define THREAD_SET_CONTEXT
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_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:1113
Status
Definition: gdiplustypes.h:24

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 ength */
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  GetSetContext.Context.ContextFlags = Flags;
150  GetSetContext.Mode = PreviousMode;
151 
152  /* Check if we're running in the same thread */
153  if (Thread == PsGetCurrentThread())
154  {
155  /* Setup APC parameters manually */
156  GetSetContext.Apc.SystemArgument1 = NULL;
157  GetSetContext.Apc.SystemArgument2 = Thread;
158 
159  /* Enter a guarded region to simulate APC_LEVEL */
161 
162  /* Manually call the APC */
163  PspGetOrSetContextKernelRoutine(&GetSetContext.Apc,
164  NULL,
165  NULL,
166  &GetSetContext.Apc.SystemArgument1,
167  &GetSetContext.Apc.SystemArgument2);
168 
169  /* Leave the guarded region */
171 
172  /* We are done */
174  }
175  else
176  {
177  /* Initialize the APC */
178  KeInitializeApc(&GetSetContext.Apc,
179  &Thread->Tcb,
182  NULL,
183  NULL,
184  KernelMode,
185  NULL);
186 
187  /* Queue it as a Get APC */
188  if (!KeInsertQueueApc(&GetSetContext.Apc, NULL, Thread, 2))
189  {
190  /* It was already queued, so fail */
192  }
193  else
194  {
195  /* Wait for the APC to complete */
196  Status = KeWaitForSingleObject(&GetSetContext.Event,
197  0,
198  KernelMode,
199  FALSE,
200  NULL);
201  }
202  }
203 
204  _SEH2_TRY
205  {
206  /* Copy the context */
207  RtlCopyMemory(ThreadContext, &GetSetContext.Context, Size);
208  }
210  {
211  /* Get the exception code */
213  }
214  _SEH2_END;
215 
216  /* Return status */
217  return Status;
218 }
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
struct _CONTEXT CONTEXT
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define CONTEXT_EXTENDED_REGISTERS
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
LONG NTSTATUS
Definition: precomp.h:26
KTHREAD Tcb
Definition: pstypes.h:1034
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
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4250
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
#define KeLeaveGuardedRegion()
Definition: ke_x.h:63
ULONG ContextFlags
Definition: compat.h:331
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#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
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
#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:254
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 _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
return STATUS_SUCCESS
Definition: btrfs.c:2966
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 225 of file debug.c.

228 {
229  GET_SET_CTX_CONTEXT GetSetContext;
230  ULONG Size = 0, Flags = 0;
232 
233  /* Enter SEH */
234  _SEH2_TRY
235  {
236  /* Set default length */
237  Size = sizeof(CONTEXT);
238 
239  /* Read the flags */
240  Flags = ProbeForReadUlong(&ThreadContext->ContextFlags);
241 
242 #ifdef _M_IX86
243  /* Check if the caller wanted extended registers */
246  {
247  /* Cut them out of the size */
248  Size = FIELD_OFFSET(CONTEXT, ExtendedRegisters);
249  }
250 #endif
251 
252  /* Check if we came from user mode */
253  if (PreviousMode != KernelMode)
254  {
255  /* Probe the context */
256  ProbeForRead(ThreadContext, Size, sizeof(ULONG));
257  }
258 
259  /* Copy the context */
260  RtlCopyMemory(&GetSetContext.Context, ThreadContext, Size);
261  }
263  {
264  /* Return the exception code */
266  }
267  _SEH2_END;
268 
269  /* Initialize the wait event */
271 
272  /* Set the flags and previous mode */
273  GetSetContext.Context.ContextFlags = Flags;
274  GetSetContext.Mode = PreviousMode;
275 
276  /* Check if we're running in the same thread */
277  if (Thread == PsGetCurrentThread())
278  {
279  /* Setup APC parameters manually */
280  GetSetContext.Apc.SystemArgument1 = UlongToPtr(1);
281  GetSetContext.Apc.SystemArgument2 = Thread;
282 
283  /* Enter a guarded region to simulate APC_LEVEL */
285 
286  /* Manually call the APC */
287  PspGetOrSetContextKernelRoutine(&GetSetContext.Apc,
288  NULL,
289  NULL,
290  &GetSetContext.Apc.SystemArgument1,
291  &GetSetContext.Apc.SystemArgument2);
292 
293  /* Leave the guarded region */
295 
296  /* We are done */
298  }
299  else
300  {
301  /* Initialize the APC */
302  KeInitializeApc(&GetSetContext.Apc,
303  &Thread->Tcb,
306  NULL,
307  NULL,
308  KernelMode,
309  NULL);
310 
311  /* Queue it as a Get APC */
312  if (!KeInsertQueueApc(&GetSetContext.Apc, UlongToPtr(1), Thread, 2))
313  {
314  /* It was already queued, so fail */
316  }
317  else
318  {
319  /* Wait for the APC to complete */
320  Status = KeWaitForSingleObject(&GetSetContext.Event,
321  0,
322  KernelMode,
323  FALSE,
324  NULL);
325  }
326  }
327 
328  /* Return status */
329  return Status;
330 }
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
struct _CONTEXT CONTEXT
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define CONTEXT_EXTENDED_REGISTERS
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
LONG NTSTATUS
Definition: precomp.h:26
KTHREAD Tcb
Definition: pstypes.h:1034
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
_SEH2_TRY
Definition: create.c:4250
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
#define KeLeaveGuardedRegion()
Definition: ke_x.h:63
#define UlongToPtr(u)
Definition: config.h:106
ULONG ContextFlags
Definition: compat.h:331
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#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
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
#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:254
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 _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
return STATUS_SUCCESS
Definition: btrfs.c:2966
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().