ReactOS  0.4.15-dev-5606-gf34e425
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 350 of file debug.c.

352 {
356  PAGED_CODE();
357 
358  /* Get the Thread Object */
359  Status = ObReferenceObjectByHandle(ThreadHandle,
361  PsThreadType,
362  PreviousMode,
363  (PVOID*)&Thread,
364  NULL);
365 
366  if (!NT_SUCCESS(Status)) return Status;
367 
368  /* Make sure it's not a system thread */
369  if (Thread->SystemThread)
370  {
371  /* Fail */
373  }
374  else
375  {
376  /* Call the kernel API */
377  Status = PsGetContextThread(Thread, ThreadContext, PreviousMode);
378  }
379 
380  /* Dereference it and return */
382  return Status;
383 }
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3062
#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:494
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:2652
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
POBJECT_TYPE PsThreadType
Definition: thread.c:20
ULONG SystemThread
Definition: pstypes.h:1182
NTSTATUS NTAPI PsGetContextThread(IN PETHREAD Thread, IN OUT PCONTEXT ThreadContext, IN KPROCESSOR_MODE PreviousMode)
Definition: debug.c:119
#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 387 of file debug.c.

389 {
393  PAGED_CODE();
394 
395  /* Get the Thread Object */
396  Status = ObReferenceObjectByHandle(ThreadHandle,
398  PsThreadType,
399  PreviousMode,
400  (PVOID*)&Thread,
401  NULL);
402 
403  if (!NT_SUCCESS(Status)) return Status;
404 
405  /* Make sure it's not a system thread */
406  if (Thread->SystemThread)
407  {
408  /* Fail */
410  }
411  else
412  {
413  /* Call the kernel API */
414  Status = PsSetContextThread(Thread, ThreadContext, PreviousMode);
415  }
416 
417  /* Dereference it and return */
419  return Status;
420 }
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI PsSetContextThread(IN PETHREAD Thread, IN OUT PCONTEXT ThreadContext, IN KPROCESSOR_MODE PreviousMode)
Definition: debug.c:241
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3062
#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:494
#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:2652
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
POBJECT_TYPE PsThreadType
Definition: thread.c:20
ULONG SystemThread
Definition: pstypes.h:1182
#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 119 of file debug.c.

122 {
123  GET_SET_CTX_CONTEXT GetSetContext;
124  ULONG Size = 0, Flags = 0;
126 
127  /* Enter SEH */
128  _SEH2_TRY
129  {
130  /* Set default length */
131  Size = sizeof(CONTEXT);
132 
133  /* Read the flags */
134  Flags = ProbeForReadUlong(&ThreadContext->ContextFlags);
135 
136 #ifdef _M_IX86
137  /* Check if the caller wanted extended registers */
140  {
141  /* Cut them out of the size */
142  Size = FIELD_OFFSET(CONTEXT, ExtendedRegisters);
143  }
144 #endif
145 
146  /* Check if we came from user mode */
147  if (PreviousMode != KernelMode)
148  {
149  /* Probe the context */
150  ProbeForWrite(ThreadContext, Size, sizeof(ULONG));
151  }
152  }
154  {
155  /* Return the exception code */
157  }
158  _SEH2_END;
159 
160  /* Initialize the wait event */
162 
163  /* Set the flags and previous mode */
164  RtlZeroMemory(&GetSetContext.Context, Size);
165  GetSetContext.Context.ContextFlags = Flags;
166  GetSetContext.Mode = PreviousMode;
167 
168  /* Check if we're running in the same thread */
169  if (Thread == PsGetCurrentThread())
170  {
171  /* Setup APC parameters manually */
172  GetSetContext.Apc.SystemArgument1 = NULL;
173  GetSetContext.Apc.SystemArgument2 = Thread;
174 
175  /* Enter a guarded region to simulate APC_LEVEL */
177 
178  /* Manually call the APC */
179  PspGetOrSetContextKernelRoutine(&GetSetContext.Apc,
180  NULL,
181  NULL,
182  &GetSetContext.Apc.SystemArgument1,
183  &GetSetContext.Apc.SystemArgument2);
184 
185  /* Leave the guarded region */
187 
188  /* We are done */
190  }
191  else
192  {
193  /* Initialize the APC */
194  KeInitializeApc(&GetSetContext.Apc,
195  &Thread->Tcb,
198  NULL,
199  NULL,
200  KernelMode,
201  NULL);
202 
203  /* Queue it as a Get APC */
204  if (!KeInsertQueueApc(&GetSetContext.Apc, NULL, Thread, 2))
205  {
206  /* It was already queued, so fail */
208  }
209  else
210  {
211  /* Wait for the APC to complete */
212  Status = KeWaitForSingleObject(&GetSetContext.Event,
213  0,
214  KernelMode,
215  FALSE,
216  NULL);
217  }
218  }
219 
220  _SEH2_TRY
221  {
222  /* Copy the context */
223  RtlCopyMemory(ThreadContext, &GetSetContext.Context, Size);
224  }
226  {
227  /* Get the exception code */
229  }
230  _SEH2_END;
231 
232  /* Return status */
233  return Status;
234 }
_SEH2_TRY
Definition: create.c:4226
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:1103
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
_SEH2_END
Definition: create.c:4400
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
#define FALSE
Definition: types.h:117
#define KeLeaveGuardedRegion()
Definition: ke_x.h:68
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
PVOID SystemArgument1
Definition: ketypes.h:551
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
KPROCESSOR_MODE Mode
Definition: ps.h:86
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
#define KeEnterGuardedRegion()
Definition: ke_x.h:39
#define ProbeForReadUlong(Ptr)
Definition: probe.h:65
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
KEVENT Event
Definition: ps.h:85
#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:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
CONTEXT Context
Definition: ps.h:87
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:38

Referenced by NtGetContextThread().

◆ PsSetContextThread()

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

Definition at line 241 of file debug.c.

244 {
245  GET_SET_CTX_CONTEXT GetSetContext;
246  ULONG Size = 0, Flags = 0;
248 
249  /* Enter SEH */
250  _SEH2_TRY
251  {
252  /* Set default length */
253  Size = sizeof(CONTEXT);
254 
255  /* Read the flags */
256  Flags = ProbeForReadUlong(&ThreadContext->ContextFlags);
257 
258 #ifdef _M_IX86
259  /* Check if the caller wanted extended registers */
262  {
263  /* Cut them out of the size */
264  Size = FIELD_OFFSET(CONTEXT, ExtendedRegisters);
265  }
266 #endif
267 
268  /* Check if we came from user mode */
269  if (PreviousMode != KernelMode)
270  {
271  /* Probe the context */
272  ProbeForRead(ThreadContext, Size, sizeof(ULONG));
273  }
274 
275  /* Copy the context */
276  RtlCopyMemory(&GetSetContext.Context, ThreadContext, Size);
277  }
279  {
280  /* Return the exception code */
282  }
283  _SEH2_END;
284 
285  /* Initialize the wait event */
287 
288  /* Set the flags and previous mode */
289  GetSetContext.Context.ContextFlags = Flags;
290  GetSetContext.Mode = PreviousMode;
291 
292  /* Check if we're running in the same thread */
293  if (Thread == PsGetCurrentThread())
294  {
295  /* Setup APC parameters manually */
296  GetSetContext.Apc.SystemArgument1 = UlongToPtr(1);
297  GetSetContext.Apc.SystemArgument2 = Thread;
298 
299  /* Enter a guarded region to simulate APC_LEVEL */
301 
302  /* Manually call the APC */
303  PspGetOrSetContextKernelRoutine(&GetSetContext.Apc,
304  NULL,
305  NULL,
306  &GetSetContext.Apc.SystemArgument1,
307  &GetSetContext.Apc.SystemArgument2);
308 
309  /* Leave the guarded region */
311 
312  /* We are done */
314  }
315  else
316  {
317  /* Initialize the APC */
318  KeInitializeApc(&GetSetContext.Apc,
319  &Thread->Tcb,
322  NULL,
323  NULL,
324  KernelMode,
325  NULL);
326 
327  /* Queue it as a Get APC */
328  if (!KeInsertQueueApc(&GetSetContext.Apc, UlongToPtr(1), Thread, 2))
329  {
330  /* It was already queued, so fail */
332  }
333  else
334  {
335  /* Wait for the APC to complete */
336  Status = KeWaitForSingleObject(&GetSetContext.Event,
337  0,
338  KernelMode,
339  FALSE,
340  NULL);
341  }
342  }
343 
344  /* Return status */
345  return Status;
346 }
_SEH2_TRY
Definition: create.c:4226
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:1103
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
_SEH2_END
Definition: create.c:4400
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
#define FALSE
Definition: types.h:117
#define KeLeaveGuardedRegion()
Definition: ke_x.h:68
#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
PVOID SystemArgument1
Definition: ketypes.h:551
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
KPROCESSOR_MODE Mode
Definition: ps.h:86
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
#define KeEnterGuardedRegion()
Definition: ke_x.h:39
#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
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
KEVENT Event
Definition: ps.h:85
#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:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
CONTEXT Context
Definition: ps.h:87
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:38

Referenced by NtSetContextThread().