branch update for HEAD-2003091401
[reactos.git] / ntoskrnl / ps / tinfo.c
index 62675f6..3c4e2b3 100644 (file)
@@ -7,12 +7,15 @@
  * 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>
@@ -106,8 +109,38 @@ NtSetInformationThread(HANDLE              ThreadHandle,
        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))
@@ -329,12 +362,18 @@ VOID KeSetPreviousMode(ULONG Mode)
    PsGetCurrentThread()->Tcb.PreviousMode = Mode;
 }
 
+/*
+ * @implemented
+ */
 ULONG STDCALL
 KeGetPreviousMode (VOID)
 {
    return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
 }
 
+/*
+ * @implemented
+ */
 ULONG STDCALL
 ExGetPreviousMode (VOID)
 {