+ {
+ PKEVENT_PAIR EventPair;
+
+ if (ThreadInformationLength != sizeof(HANDLE))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ if (ExGetPreviousMode() == UserMode) /* FIXME: Validate this for all infoclasses and system services */
+ {
+ DPRINT("NtSetInformationThread:ThreadEventPair: Checking user pointer %08x...\n", ThreadInformation);
+ ProbeForRead(ThreadInformation, sizeof(HANDLE), sizeof(HANDLE)); /* FIXME: This entire function should be
+ * wrapped in an SEH frame... return (NTSTATUS)GetExceptionCode() on exception */
+ }
+
+ Status = ObReferenceObjectByHandle(*(PHANDLE)ThreadInformation,
+ STANDARD_RIGHTS_ALL,
+ ExEventPairObjectType,
+ ExGetPreviousMode(),
+ (PVOID*)&EventPair,
+ NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
+
+ ExpSwapThreadEventPair(Thread, EventPair); /* Note that the extra reference is kept intentionally */
+ Status = STATUS_SUCCESS;
+ break;
+ }