* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* Created 22/05/98
+ * Updated 09/08/2003 by Skywing (skywing@valhallalegends.com)
+ * to suppport thread-eventpairs.
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/ps.h>
+#include <internal/ex.h>
#include <internal/safe.h>
#include <internal/debug.h>
break;
case ThreadEventPair:
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+ {
+ 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;
+ }
case ThreadQuerySetWin32StartAddress:
if (ThreadInformationLength != sizeof(ULONG))
PsGetCurrentThread()->Tcb.PreviousMode = Mode;
}
+/*
+ * @implemented
+ */
ULONG STDCALL
KeGetPreviousMode (VOID)
{
return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
}
+/*
+ * @implemented
+ */
ULONG STDCALL
ExGetPreviousMode (VOID)
{