ReactOS 0.4.16-dev-306-g647d351
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,
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}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ExGetPreviousMode
Definition: ex.h:140
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
Status
Definition: gdiplustypes.h:25
#define THREAD_GET_CONTEXT
NTSTATUS NTAPI PsGetContextThread(IN PETHREAD Thread, IN OUT PCONTEXT ThreadContext, IN KPROCESSOR_MODE PreviousMode)
Definition: debug.c:119
POBJECT_TYPE PsThreadType
Definition: thread.c:20
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
ULONG SystemThread
Definition: pstypes.h:1183
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103

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,
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}
#define THREAD_SET_CONTEXT
NTSTATUS NTAPI PsSetContextThread(IN PETHREAD Thread, IN OUT PCONTEXT ThreadContext, IN KPROCESSOR_MODE PreviousMode)
Definition: debug.c:241

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 */
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 */
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 */
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,
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,
215 FALSE,
216 NULL);
217 }
218 }
219
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}
#define FALSE
Definition: types.h:117
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define KeLeaveGuardedRegion()
Definition: ke_x.h:68
#define KeEnterGuardedRegion()
Definition: ke_x.h:39
#define KernelMode
Definition: asm.h:34
@ OriginalApcEnvironment
Definition: ketypes.h:767
struct _CONTEXT CONTEXT
@ NotificationEvent
BOOLEAN NTAPI KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost)
Definition: apc.c:735
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
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
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define ProbeForReadUlong(Ptr)
Definition: probe.h:65
#define CONTEXT_EXTENDED_REGISTERS
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG ContextFlags
Definition: nt_native.h:1426
KTHREAD Tcb
Definition: pstypes.h:1104
CONTEXT Context
Definition: ps.h:87
KEVENT Event
Definition: ps.h:85
KPROCESSOR_MODE Mode
Definition: ps.h:86
PVOID SystemArgument1
Definition: ketypes.h:563
PVOID SystemArgument2
Definition: ketypes.h:564
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

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 */
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 */
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 */
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,
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,
339 FALSE,
340 NULL);
341 }
342 }
343
344 /* Return status */
345 return Status;
346}
#define UlongToPtr(u)
Definition: config.h:106
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102

Referenced by NtSetContextThread().