25 typedef struct _EXIT_THREAD_CONTEXT
28 KEVENT CompletedEvent;
32 typedef struct _CAPTURE_BACKTRACE_THREAD_CONTEXT
36 KEVENT CompletedEvent;
38 ULONG FramesToCapture;
50 __inout PVOID *NormalContext,
51 __inout PVOID *SystemArgument1,
52 __inout PVOID *SystemArgument2
58 __inout PVOID *NormalContext,
59 __inout PVOID *SystemArgument1,
60 __inout PVOID *SystemArgument2
64 #pragma alloc_text(PAGE, KpiOpenThread)
65 #pragma alloc_text(PAGE, KpiOpenThreadProcess)
66 #pragma alloc_text(PAGE, KphTerminateThreadByPointerInternal)
67 #pragma alloc_text(PAGE, KpiTerminateThread)
68 #pragma alloc_text(PAGE, KpiTerminateThreadUnsafe)
69 #pragma alloc_text(PAGE, KphpExitThreadSpecialApc)
70 #pragma alloc_text(PAGE, KpiGetContextThread)
71 #pragma alloc_text(PAGE, KpiSetContextThread)
72 #pragma alloc_text(PAGE, KphCaptureStackBackTraceThread)
73 #pragma alloc_text(PAGE, KphpCaptureStackBackTraceThreadSpecialApc)
74 #pragma alloc_text(PAGE, KpiCaptureStackBackTraceThread)
75 #pragma alloc_text(PAGE, KpiQueryInformationThread)
76 #pragma alloc_text(PAGE, KpiSetInformationThread)
90 __out PHANDLE ThreadHandle,
91 __in ACCESS_MASK DesiredAccess,
93 __in KPROCESSOR_MODE AccessMode
103 if (AccessMode != KernelMode)
107 ProbeForWrite(ThreadHandle,
sizeof(HANDLE),
sizeof(HANDLE));
108 ProbeForRead(ClientId,
sizeof(
CLIENT_ID),
sizeof(ULONG));
109 clientId = *ClientId;
111 __except (EXCEPTION_EXECUTE_HANDLER)
113 return GetExceptionCode();
118 clientId = *ClientId;
128 status = PsLookupThreadByThreadId(clientId.
UniqueThread, &thread);
135 status = ObOpenObjectByPointer(
144 ObDereferenceObject(thread);
148 if (AccessMode != KernelMode)
152 *ThreadHandle = threadHandle;
154 __except (EXCEPTION_EXECUTE_HANDLER)
156 status = GetExceptionCode();
161 *ThreadHandle = threadHandle;
177 __in HANDLE ThreadHandle,
178 __in ACCESS_MASK DesiredAccess,
179 __out PHANDLE ProcessHandle,
180 __in KPROCESSOR_MODE AccessMode
186 HANDLE processHandle;
190 if (AccessMode != KernelMode)
194 ProbeForWrite(ProcessHandle,
sizeof(HANDLE),
sizeof(HANDLE));
196 __except (EXCEPTION_EXECUTE_HANDLER)
198 return GetExceptionCode();
202 status = ObReferenceObjectByHandle(
214 process = IoThreadToProcess(thread);
216 status = ObOpenObjectByPointer(
226 ObDereferenceObject(thread);
230 if (AccessMode != KernelMode)
234 *ProcessHandle = processHandle;
236 __except (EXCEPTION_EXECUTE_HANDLER)
238 status = GetExceptionCode();
243 *ProcessHandle = processHandle;
258 __in PETHREAD Thread,
259 __in NTSTATUS ExitStatus
262 PVOID PspTerminateThreadByPointer_I;
267 return STATUS_NOT_SUPPORTED;
271 if (!PspTerminateThreadByPointer_I)
273 dprintf(
"Unable to find PspTerminateThreadByPointer\n");
274 return STATUS_NOT_SUPPORTED;
279 dprintf(
"Calling XP-style PspTerminateThreadByPointer\n");
291 dprintf(
"Calling 03/Vista/7-style PspTerminateThreadByPointer\n");
295 Thread == PsGetCurrentThread()
301 ULONG directTerminate;
303 dprintf(
"Calling 8-style PspTerminateThreadByPointer\n");
304 directTerminate = Thread == PsGetCurrentThread();
312 push [directTerminate]
315 call [PspTerminateThreadByPointer_I]
324 Thread == PsGetCurrentThread()
333 dprintf(
"Calling 8.1-style PspTerminateThreadByPointer\n");
337 Thread == PsGetCurrentThread()
342 return STATUS_NOT_SUPPORTED;
355 __in HANDLE ThreadHandle,
356 __in NTSTATUS ExitStatus,
357 __in KPROCESSOR_MODE AccessMode
365 status = ObReferenceObjectByHandle(
377 if (thread != PsGetCurrentThread())
383 status = STATUS_CANT_TERMINATE_SELF;
386 ObDereferenceObject(thread);
404 __in HANDLE ThreadHandle,
405 __in NTSTATUS ExitStatus,
406 __in KPROCESSOR_MODE AccessMode
414 status = ObReferenceObjectByHandle(
426 if (thread != PsGetCurrentThread())
431 context.ExitStatus = ExitStatus;
449 status = KeWaitForSingleObject(
450 &context.CompletedEvent,
459 status = STATUS_UNSUCCESSFUL;
464 status = STATUS_CANT_TERMINATE_SELF;
467 ObDereferenceObject(thread);
475 __inout PVOID *NormalContext,
476 __inout PVOID *SystemArgument1,
477 __inout PVOID *SystemArgument2
485 exitStatus = context->ExitStatus;
488 KeSetEvent(&context->CompletedEvent, 0,
FALSE);
502 __in HANDLE ThreadHandle,
503 __inout PCONTEXT ThreadContext,
504 __in KPROCESSOR_MODE AccessMode
512 status = ObReferenceObjectByHandle(
525 ObDereferenceObject(thread);
538 __in HANDLE ThreadHandle,
539 __in PCONTEXT ThreadContext,
540 __in KPROCESSOR_MODE AccessMode
548 status = ObReferenceObjectByHandle(
561 ObDereferenceObject(thread);
583 __in ULONG FramesToSkip,
584 __in ULONG FramesToCapture,
585 __in_opt ULONG Flags,
586 __out_ecount(FramesToCapture) PVOID *BackTrace,
587 __out_opt PULONG BackTraceHash
608 FramesToCapture + FramesToSkip,
612 if (framesFound <= FramesToSkip)
618 for (i = 0, hash = 0; i < FramesToCapture; i++)
620 if (FramesToSkip + i >= framesFound)
623 BackTrace[i] = backTrace[FramesToSkip + i];
624 hash += PtrToUlong(BackTrace[i]);
628 *BackTraceHash = hash;
651 __in PETHREAD Thread,
652 __in ULONG FramesToSkip,
653 __in ULONG FramesToCapture,
654 __out_ecount(FramesToCapture) PVOID *BackTrace,
655 __out_opt PULONG CapturedFrames,
656 __out_opt PULONG BackTraceHash,
657 __in KPROCESSOR_MODE AccessMode
660 NTSTATUS status = STATUS_SUCCESS;
671 return STATUS_INVALID_PARAMETER_3;
673 backTraceSize = FramesToCapture *
sizeof(PVOID);
675 if (AccessMode != KernelMode)
679 ProbeForWrite(BackTrace, backTraceSize,
sizeof(PVOID));
682 ProbeForWrite(CapturedFrames,
sizeof(ULONG),
sizeof(ULONG));
684 ProbeForWrite(BackTraceHash,
sizeof(ULONG),
sizeof(ULONG));
686 __except (EXCEPTION_EXECUTE_HANDLER)
688 return GetExceptionCode();
693 if (backTraceSize == 0)
695 if (AccessMode != KernelMode)
704 __except (EXCEPTION_EXECUTE_HANDLER)
706 status = GetExceptionCode();
721 backTrace = ExAllocatePoolWithTag(NonPagedPool, backTraceSize,
'bhpK');
724 return STATUS_INSUFFICIENT_RESOURCES;
727 context.FramesToSkip = FramesToSkip;
728 context.FramesToCapture = FramesToCapture;
729 context.BackTrace = backTrace;
733 if (Thread == PsGetCurrentThread())
742 context.Local =
TRUE;
743 KeRaiseIrql(APC_LEVEL, &oldIrql);
751 KeLowerIrql(oldIrql);
755 context.Local =
FALSE;
771 status = KeWaitForSingleObject(
772 &context.CompletedEvent,
781 status = STATUS_UNSUCCESSFUL;
787 ASSERT(context.CapturedFrames <= FramesToCapture);
789 if (AccessMode != KernelMode)
793 memcpy(BackTrace, backTrace, context.CapturedFrames *
sizeof(PVOID));
796 *CapturedFrames = context.CapturedFrames;
798 *BackTraceHash = context.BackTraceHash;
800 __except (EXCEPTION_EXECUTE_HANDLER)
802 status = GetExceptionCode();
807 memcpy(BackTrace, backTrace, context.CapturedFrames *
sizeof(PVOID));
810 *CapturedFrames = context.CapturedFrames;
812 *BackTraceHash = context.BackTraceHash;
816 ExFreePoolWithTag(backTrace,
'bhpK');
824 __inout PVOID *NormalContext,
825 __inout PVOID *SystemArgument1,
826 __inout PVOID *SystemArgument2
834 context->FramesToSkip,
835 context->FramesToCapture,
838 &context->BackTraceHash
844 KeSetEvent(&context->CompletedEvent, 0,
FALSE);
867 __in HANDLE ThreadHandle,
868 __in ULONG FramesToSkip,
869 __in ULONG FramesToCapture,
870 __out_ecount(FramesToCapture) PVOID *BackTrace,
871 __out_opt PULONG CapturedFrames,
872 __out_opt PULONG BackTraceHash,
873 __in KPROCESSOR_MODE AccessMode
876 NTSTATUS status = STATUS_SUCCESS;
881 status = ObReferenceObjectByHandle(
902 ObDereferenceObject(thread);
920 __in HANDLE ThreadHandle,
922 __out_bcount(ProcessInformationLength) PVOID ThreadInformation,
923 __in ULONG ThreadInformationLength,
924 __out_opt PULONG ReturnLength,
925 __in KPROCESSOR_MODE AccessMode
934 if (AccessMode != KernelMode)
938 ProbeForWrite(ThreadInformation, ThreadInformationLength,
sizeof(ULONG));
941 ProbeForWrite(ReturnLength,
sizeof(ULONG),
sizeof(ULONG));
943 __except (EXCEPTION_EXECUTE_HANDLER)
945 return GetExceptionCode();
949 status = ObReferenceObjectByHandle(
961 switch (ThreadInformationClass)
969 if (ThreadInformationLength ==
sizeof(PVOID))
973 *(PVOID *)ThreadInformation = win32Thread;
975 __except (EXCEPTION_EXECUTE_HANDLER)
977 status = GetExceptionCode();
982 status = STATUS_INFO_LENGTH_MISMATCH;
985 returnLength =
sizeof(PVOID);
990 HANDLE newThreadHandle;
993 if (
NT_SUCCESS(status = ObOpenObjectByPointer(
1011 if (ThreadInformationLength ==
sizeof(ULONG))
1015 *(PULONG)ThreadInformation = ioPriority;
1017 __except (EXCEPTION_EXECUTE_HANDLER)
1019 status = GetExceptionCode();
1024 status = STATUS_INFO_LENGTH_MISMATCH;
1031 returnLength =
sizeof(ULONG);
1035 status = STATUS_INVALID_INFO_CLASS;
1040 ObDereferenceObject(thread);
1044 if (AccessMode != KernelMode)
1048 *ReturnLength = returnLength;
1050 __except (EXCEPTION_EXECUTE_HANDLER)
1057 *ReturnLength = returnLength;
1075 __in HANDLE ThreadHandle,
1077 __in_bcount(ThreadInformationLength) PVOID ThreadInformation,
1078 __in ULONG ThreadInformationLength,
1079 __in KPROCESSOR_MODE AccessMode
1087 if (AccessMode != KernelMode)
1091 ProbeForRead(ThreadInformation, ThreadInformationLength,
sizeof(ULONG));
1093 __except (EXCEPTION_EXECUTE_HANDLER)
1095 return GetExceptionCode();
1099 status = ObReferenceObjectByHandle(
1111 switch (ThreadInformationClass)
1115 HANDLE tokenHandle = NULL;
1116 PACCESS_TOKEN token;
1117 HANDLE newTokenHandle;
1119 if (ThreadInformationLength ==
sizeof(HANDLE))
1123 tokenHandle = *(PHANDLE)ThreadInformation;
1125 __except (EXCEPTION_EXECUTE_HANDLER)
1127 status = GetExceptionCode();
1132 status = STATUS_INFO_LENGTH_MISMATCH;
1137 if (
NT_SUCCESS(status = ObReferenceObjectByHandle(
1146 if (
NT_SUCCESS(status = ObOpenObjectByPointer(
1156 status = PsAssignImpersonationToken(thread, newTokenHandle);
1160 ObDereferenceObject(token);
1168 HANDLE newThreadHandle;
1170 if (ThreadInformationLength ==
sizeof(ULONG))
1174 ioPriority = *(PULONG)ThreadInformation;
1176 __except (EXCEPTION_EXECUTE_HANDLER)
1178 status = GetExceptionCode();
1183 status = STATUS_INFO_LENGTH_MISMATCH;
1188 if (
NT_SUCCESS(status = ObOpenObjectByPointer(
1192 THREAD_SET_INFORMATION,
1210 status = STATUS_INVALID_INFO_CLASS;
1214 ObDereferenceObject(thread);