convert DefaultSetInfoBufferCheck and DefaultQueryInfoBufferCheck to inlined functions
[reactos.git] / reactos / ntoskrnl / ps / query.c
index b6dbac1..9641831 100644 (file)
@@ -16,7 +16,6 @@
 
 /* GLOBALS ******************************************************************/
 
-
 static const INFORMATION_CLASS_INFO PsProcessInfoClass[] =
 {
   ICI_SQ_SAME( sizeof(PROCESS_BASIC_INFORMATION),     sizeof(ULONG), ICIF_QUERY ),                     /* ProcessBasicInformation */
@@ -26,7 +25,7 @@ static const INFORMATION_CLASS_INFO PsProcessInfoClass[] =
   ICI_SQ_SAME( sizeof(KERNEL_USER_TIMES),             sizeof(ULONG), ICIF_QUERY ),                     /* ProcessTimes */
   ICI_SQ_SAME( sizeof(KPRIORITY),                     sizeof(ULONG), ICIF_SET ),                       /* ProcessBasePriority */
   ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_SET ),                       /* ProcessRaisePriority */
-  ICI_SQ_SAME( sizeof(HANDLE),                        sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessDebugPort */
+  ICI_SQ_SAME( sizeof(HANDLE),                        sizeof(ULONG), ICIF_QUERY ),                     /* ProcessDebugPort */
   ICI_SQ_SAME( sizeof(HANDLE),                        sizeof(ULONG), ICIF_SET ),                       /* ProcessExceptionPort */
   ICI_SQ_SAME( sizeof(PROCESS_ACCESS_TOKEN),          sizeof(ULONG), ICIF_SET ),                       /* ProcessAccessToken */
   ICI_SQ_SAME( 0 /* FIXME */,                         sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessLdtInformation */
@@ -63,7 +62,7 @@ static const INFORMATION_CLASS_INFO PsProcessInfoClass[] =
   ICI_SQ_SAME( 0,                                     1,             0 ),                              /* ProcessUnknown33 */
   ICI_SQ_SAME( 0,                                     1,             0 ),                              /* ProcessUnknown34 */
   ICI_SQ_SAME( 0,                                     1,             0 ),                              /* ProcessUnknown35 */
-  
+
   ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_QUERY),                      /* ProcessCookie */
 };
 
@@ -76,7 +75,7 @@ static const struct
 {
    BOOLEAN Implemented;
    ULONG Size;
-} QueryInformationData[MaxThreadInfoClass + 1] = 
+} QueryInformationData[MaxThreadInfoClass + 1] =
 {
     {TRUE, sizeof(THREAD_BASIC_INFORMATION)},  // ThreadBasicInformation
     {TRUE, sizeof(KERNEL_USER_TIMES)},         // ThreadTimes
@@ -102,7 +101,7 @@ static const struct
 {
    BOOLEAN Implemented;
    ULONG Size;
-} SetInformationData[MaxThreadInfoClass + 1] = 
+} SetInformationData[MaxThreadInfoClass + 1] =
 {
     {TRUE, 0},                 // ThreadBasicInformation
     {TRUE, 0},                 // ThreadTimes
@@ -139,24 +138,24 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
    PEPROCESS Process;
    KPROCESSOR_MODE PreviousMode;
    NTSTATUS Status = STATUS_SUCCESS;
-   
+
    PAGED_CODE();
-   
+
    PreviousMode = ExGetPreviousMode();
-   
-   DefaultQueryInfoBufferCheck(ProcessInformationClass,
-                               PsProcessInfoClass,
-                               ProcessInformation,
-                               ProcessInformationLength,
-                               ReturnLength,
-                               PreviousMode,
-                               &Status);
+
+   Status = DefaultQueryInfoBufferCheck(ProcessInformationClass,
+                                        PsProcessInfoClass,
+                                        sizeof(PsProcessInfoClass) / sizeof(PsProcessInfoClass[0]),
+                                        ProcessInformation,
+                                        ProcessInformationLength,
+                                        ReturnLength,
+                                        PreviousMode);
    if(!NT_SUCCESS(Status))
    {
      DPRINT1("NtQueryInformationProcess() failed, Status: 0x%x\n", Status);
      return Status;
    }
-   
+
    if(ProcessInformationClass != ProcessCookie)
    {
      Status = ObReferenceObjectByHandle(ProcessHandle,
@@ -177,7 +176,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
         real handle actually represents the current process. */
      return STATUS_INVALID_PARAMETER;
    }
-   
+
    switch (ProcessInformationClass)
      {
       case ProcessBasicInformation:
@@ -191,9 +190,9 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
          ProcessBasicInformationP->PebBaseAddress = Process->Peb;
          ProcessBasicInformationP->AffinityMask = Process->Pcb.Affinity;
          ProcessBasicInformationP->UniqueProcessId =
-           Process->UniqueProcessId;
+           (ULONG)Process->UniqueProcessId;
          ProcessBasicInformationP->InheritedFromUniqueProcessId =
-           Process->InheritedFromUniqueProcessId;
+           (ULONG)Process->InheritedFromUniqueProcessId;
          ProcessBasicInformationP->BasePriority =
            Process->Pcb.BasePriority;
 
@@ -255,7 +254,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
         _SEH_END;
         break;
       }
-      
+
       case ProcessLdtInformation:
       case ProcessWorkingSetWatch:
       case ProcessWx86Information:
@@ -265,7 +264,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
       case ProcessHandleCount:
       {
        ULONG HandleCount = ObpGetHandleCountByHandleTable(Process->ObjectTable);
-         
+
        _SEH_TRY
        {
           *(PULONG)ProcessInformation = HandleCount;
@@ -288,7 +287,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
 
         _SEH_TRY
         {
-          SessionInfo->SessionId = Process->SessionId;
+          SessionInfo->SessionId = Process->Session;
           if (ReturnLength)
           {
             *ReturnLength = sizeof(PROCESS_SESSION_INFORMATION);
@@ -301,7 +300,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
         _SEH_END;
         break;
       }
-      
+
       case ProcessWow64Information:
         DPRINT1("We currently don't support the ProcessWow64Information information class!\n");
        Status = STATUS_NOT_IMPLEMENTED;
@@ -310,7 +309,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
       case ProcessVmCounters:
       {
        PVM_COUNTERS pOut = (PVM_COUNTERS)ProcessInformation;
-         
+
        _SEH_TRY
        {
          pOut->PeakVirtualSize            = Process->PeakVirtualSize;
@@ -319,16 +318,16 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
           * incompatibilities in current headers (no unnamed union),
           * I opted for cast.
           */
-         pOut->VirtualSize                = (ULONG)Process->VirtualSize.QuadPart;
+         pOut->VirtualSize                = (ULONG)Process->VirtualSize;
          pOut->PageFaultCount             = Process->Vm.PageFaultCount;
          pOut->PeakWorkingSetSize         = Process->Vm.PeakWorkingSetSize;
          pOut->WorkingSetSize             = Process->Vm.WorkingSetSize;
-         pOut->QuotaPeakPagedPoolUsage    = Process->QuotaPeakPoolUsage[0]; // TODO: Verify!
-         pOut->QuotaPagedPoolUsage        = Process->QuotaPoolUsage[0];     // TODO: Verify!
-         pOut->QuotaPeakNonPagedPoolUsage = Process->QuotaPeakPoolUsage[1]; // TODO: Verify!
-         pOut->QuotaNonPagedPoolUsage     = Process->QuotaPoolUsage[1];     // TODO: Verify!
-         pOut->PagefileUsage              = Process->PagefileUsage;
-         pOut->PeakPagefileUsage          = Process->PeakPagefileUsage;
+         pOut->QuotaPeakPagedPoolUsage    = Process->QuotaPeak[0]; // TODO: Verify!
+         pOut->QuotaPagedPoolUsage        = Process->QuotaUsage[0];     // TODO: Verify!
+         pOut->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1]; // TODO: Verify!
+         pOut->QuotaNonPagedPoolUsage     = Process->QuotaUsage[1];     // TODO: Verify!
+         pOut->PagefileUsage              = Process->QuotaUsage[2];
+         pOut->PeakPagefileUsage          = Process->QuotaPeak[2];
 
          if (ReturnLength)
          {
@@ -365,7 +364,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
       case ProcessPriorityBoost:
       {
        PULONG BoostEnabled = (PULONG)ProcessInformation;
-         
+
        _SEH_TRY
        {
          *BoostEnabled = Process->Pcb.DisableBoost ? FALSE : TRUE;
@@ -386,7 +385,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
       case ProcessDeviceMap:
       {
         PROCESS_DEVICEMAP_INFORMATION DeviceMap;
-          
+
         ObQueryDeviceMapInformation(Process, &DeviceMap);
 
         _SEH_TRY
@@ -446,7 +445,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
 
           if(Attached)
             KeAttachProcess(&Process->Pcb);
-          
+
           _SEH_TRY
           {
             ProcParams = Process->Peb->ProcessParameters;
@@ -457,7 +456,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
             Status = _SEH_GetExceptionCode();
           }
           _SEH_END;
-          
+
           if(NT_SUCCESS(Status))
           {
             if(ProcessInformationLength < sizeof(UNICODE_STRING) + ImagePathLen + sizeof(WCHAR))
@@ -468,6 +467,8 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
             {
               PWSTR StrSource = NULL;
 
+              RtlZeroMemory(&LocalDest, sizeof(LocalDest));
+
               /* create a DstPath structure on the stack */
               _SEH_TRY
               {
@@ -542,7 +543,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
               }
             }
           }
-          
+
           /* don't forget to detach from the process!!! */
           if(Attached)
             KeDetachProcess();
@@ -554,11 +555,11 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
         }
         break;
       }
-      
+
       case ProcessCookie:
       {
         ULONG Cookie;
-        
+
         /* receive the process cookie, this is only allowed for the current
            process! */
 
@@ -570,16 +571,16 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
           LARGE_INTEGER SystemTime;
           ULONG NewCookie;
           PKPRCB Prcb;
-          
+
           /* generate a new cookie */
-          
+
           KeQuerySystemTime(&SystemTime);
-          
+
           Prcb = KeGetCurrentPrcb();
 
           NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^
                       SystemTime.u.LowPart ^ SystemTime.u.HighPart;
-          
+
           /* try to set the new cookie, return the current one if another thread
              set it in the meanwhile */
           Cookie = InterlockedCompareExchange((LONG*)&Process->Cookie,
@@ -591,7 +592,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
             Cookie = NewCookie;
           }
         }
-        
+
         _SEH_TRY
         {
           *(PULONG)ProcessInformation = Cookie;
@@ -605,7 +606,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
           Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-        
+
         break;
       }
 
@@ -631,7 +632,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
    {
      ObDereferenceObject(Process);
    }
-   
+
    return Status;
 }
 
@@ -648,39 +649,38 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
    KPROCESSOR_MODE PreviousMode;
    ACCESS_MASK Access;
    NTSTATUS Status = STATUS_SUCCESS;
-   
+
    PAGED_CODE();
-   
+
    PreviousMode = ExGetPreviousMode();
 
-   DefaultSetInfoBufferCheck(ProcessInformationClass,
-                             PsProcessInfoClass,
-                             ProcessInformation,
-                             ProcessInformationLength,
-                             PreviousMode,
-                             &Status);
+   Status = DefaultSetInfoBufferCheck(ProcessInformationClass,
+                                      PsProcessInfoClass,
+                                      sizeof(PsProcessInfoClass) / sizeof(PsProcessInfoClass[0]),
+                                      ProcessInformation,
+                                      ProcessInformationLength,
+                                      PreviousMode);
    if(!NT_SUCCESS(Status))
    {
      DPRINT1("NtSetInformationProcess() %d %x  %x called\n", ProcessInformationClass, ProcessInformation, ProcessInformationLength);
      DPRINT1("NtSetInformationProcess() %x failed, Status: 0x%x\n", Status);
      return Status;
    }
-   
+
    switch(ProcessInformationClass)
    {
      case ProcessSessionInformation:
        Access = PROCESS_SET_INFORMATION | PROCESS_SET_SESSIONID;
        break;
      case ProcessExceptionPort:
-     case ProcessDebugPort:
-       Access = PROCESS_SET_INFORMATION | PROCESS_SET_PORT;
+       Access = PROCESS_SET_INFORMATION | PROCESS_SUSPEND_RESUME;
        break;
 
      default:
        Access = PROCESS_SET_INFORMATION;
        break;
    }
-   
+
    Status = ObReferenceObjectByHandle(ProcessHandle,
                                      Access,
                                      PsProcessType,
@@ -700,87 +700,6 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
        Status = STATUS_NOT_IMPLEMENTED;
        break;
 
-      case ProcessDebugPort:
-      {
-        HANDLE PortHandle = NULL;
-
-        /* make a safe copy of the buffer on the stack */
-        _SEH_TRY
-        {
-          PortHandle = *(PHANDLE)ProcessInformation;
-          Status = (PortHandle != NULL ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER);
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-
-        if(NT_SUCCESS(Status))
-        {
-          PEPORT DebugPort;
-
-          /* in case we had success reading from the buffer, verify the provided
-           * LPC port handle
-           */
-          Status = ObReferenceObjectByHandle(PortHandle,
-                                             0,
-                                             LpcPortObjectType,
-                                             PreviousMode,
-                                             (PVOID)&DebugPort,
-                                             NULL);
-          if(NT_SUCCESS(Status))
-          {
-            /* lock the process to be thread-safe! */
-
-            Status = PsLockProcess(Process, FALSE);
-            if(NT_SUCCESS(Status))
-            {
-              /*
-               * according to "NT Native API" documentation, setting the debug
-               * port is only permitted once!
-               */
-              if(Process->DebugPort == NULL)
-              {
-                /* keep the reference to the handle! */
-                Process->DebugPort = DebugPort;
-                
-                if(Process->Peb)
-                {
-                  /* we're now debugging the process, so set the flag in the PEB
-                     structure. However, to access it we need to attach to the
-                     process so we're sure we're in the right context! */
-
-                  KeAttachProcess(&Process->Pcb);
-                  _SEH_TRY
-                  {
-                    Process->Peb->BeingDebugged = TRUE;
-                  }
-                  _SEH_HANDLE
-                  {
-                    DPRINT1("Trying to set the Peb->BeingDebugged field of process 0x%x failed, exception: 0x%x\n", Process, _SEH_GetExceptionCode());
-                  }
-                  _SEH_END;
-                  KeDetachProcess();
-                }
-                Status = STATUS_SUCCESS;
-              }
-              else
-              {
-                ObDereferenceObject(DebugPort);
-                Status = STATUS_PORT_ALREADY_SET;
-              }
-              PsUnlockProcess(Process);
-            }
-            else
-            {
-              ObDereferenceObject(DebugPort);
-            }
-          }
-        }
-        break;
-      }
-
       case ProcessExceptionPort:
       {
         HANDLE PortHandle = NULL;
@@ -796,11 +715,11 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
           Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-        
+
         if(NT_SUCCESS(Status))
         {
           PEPORT ExceptionPort;
-          
+
           /* in case we had success reading from the buffer, verify the provided
            * LPC port handle
            */
@@ -813,7 +732,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
           if(NT_SUCCESS(Status))
           {
             /* lock the process to be thread-safe! */
-            
+
             Status = PsLockProcess(Process, FALSE);
             if(NT_SUCCESS(Status))
             {
@@ -882,12 +801,14 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
         _SEH_END;
         break;
       }
-      
+
       case ProcessSessionInformation:
       {
         PROCESS_SESSION_INFORMATION SessionInfo;
         Status = STATUS_SUCCESS;
-        
+
+        RtlZeroMemory(&SessionInfo, sizeof(SessionInfo));
+
         _SEH_TRY
         {
           /* copy the structure to the stack */
@@ -898,11 +819,11 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
           Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-        
+
         if(NT_SUCCESS(Status))
         {
           /* we successfully copied the structure to the stack, continue processing */
-          
+
           /*
            * setting the session id requires the SeTcbPrivilege!
            */
@@ -914,13 +835,13 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             Status = STATUS_PRIVILEGE_NOT_HELD;
             break;
           }
-          
+
           /* FIXME - update the session id for the process token */
 
           Status = PsLockProcess(Process, FALSE);
           if(NT_SUCCESS(Status))
           {
-            Process->SessionId = SessionInfo.SessionId;
+            Process->Session = SessionInfo.SessionId;
 
             /* Update the session id in the PEB structure */
             if(Process->Peb != NULL)
@@ -949,7 +870,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
         }
         break;
       }
-      
+
       case ProcessPriorityClass:
       {
         PROCESS_PRIORITY_CLASS ppc;
@@ -963,14 +884,14 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
           Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-        
+
         if(NT_SUCCESS(Status))
         {
         }
-        
+
         break;
       }
-       
+
       case ProcessLdtInformation:
       case ProcessLdtSize:
       case ProcessIoPortHandlers:
@@ -988,6 +909,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
       case ProcessWx86Information:
       case ProcessHandleCount:
       case ProcessWow64Information:
+      case ProcessDebugPort:
       default:
        Status = STATUS_INVALID_INFO_CLASS;
      }
@@ -1001,7 +923,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
  *     PiQuerySystemProcessInformation
  *
  * DESCRIPTION
- *     Compute the size of a process+thread snapshot as 
+ *     Compute the size of a process+thread snapshot as
  *     expected by NtQuerySystemInformation.
  *
  * RETURN VALUE
@@ -1023,16 +945,16 @@ PiQuerySystemProcessInformation(PVOID Buffer,
        PEPROCESS       CurrentP;
        PLIST_ENTRY     CurrentEntryT;
        PETHREAD        CurrentT;
-       
+
        ULONG           RequiredSize = 0L;
        BOOLEAN         SizeOnly = FALSE;
 
        ULONG           SpiSize = 0L;
-       
+
        PSYSTEM_PROCESS_INFORMATION     pInfoP = (PSYSTEM_PROCESS_INFORMATION) SnapshotBuffer;
        PSYSTEM_PROCESS_INFORMATION     pInfoPLast = NULL;
        PSYSTEM_THREAD_INFO             pInfoT = NULL;
-       
+
 
    /* Lock the process list. */
    ExAcquireFastMutex(&PspActiveProcessMutex);
@@ -1069,14 +991,14 @@ PiQuerySystemProcessInformation(PVOID Buffer,
                        SizeOnly = TRUE;
                        continue;
                }
-               /* 
-                * Get a reference to the 
+               /*
+                * Get a reference to the
                 * process descriptor we are
                 * handling.
                 */
                CurrentP = CONTAINING_RECORD(
                                CurrentEntryP,
-                               EPROCESS, 
+                               EPROCESS,
                                ProcessListEntry
                                );
                /*
@@ -1093,9 +1015,9 @@ PiQuerySystemProcessInformation(PVOID Buffer,
                /* THREAD */
                for (   pInfoT = & CurrentP->ThreadSysInfo [0],
                        CurrentEntryT = CurrentP->ThreadListHead.Flink;
-                       
+
                        (CurrentEntryT != & CurrentP->ThreadListHead);
-                       
+
                        pInfoT = & CurrentP->ThreadSysInfo [pInfoP->ThreadCount],
                        CurrentEntryT = CurrentEntryT->Flink
                        )
@@ -1122,14 +1044,14 @@ PiQuerySystemProcessInformation(PVOID Buffer,
                                SizeOnly = TRUE;
                                continue;
                        }
-                       /* 
-                        * Get a reference to the 
+                       /*
+                        * Get a reference to the
                         * thread descriptor we are
                         * handling.
                         */
                        CurrentT = CONTAINING_RECORD(
                                        CurrentEntryT,
-                                       KTHREAD, 
+                                       KTHREAD,
                                        ThreadListEntry
                                        );
                        /*
@@ -1152,7 +1074,7 @@ PiQuerySystemProcessInformation(PVOID Buffer,
                        pInfoT->State           = CurrentT-> ;  /* DWORD */
                        pInfoT->WaitReason      = CurrentT-> ;  /* KWAIT_REASON */
                        /*
-                        * Count the number of threads 
+                        * Count the number of threads
                         * this process has.
                         */
                        ++ pInfoP->ThreadCount;
@@ -1169,9 +1091,9 @@ PiQuerySystemProcessInformation(PVOID Buffer,
                 */
                pInfoPLast = pInfoP;
                /*
-                * Compute the offset of the 
+                * Compute the offset of the
                 * SYSTEM_PROCESS_INFORMATION
-                * descriptor in the snapshot 
+                * descriptor in the snapshot
                 * buffer for the next process.
                 */
                (ULONG) pInfoP += SpiSize;
@@ -1198,7 +1120,7 @@ PiQuerySystemProcessInformation(PVOID Buffer,
         * Mark the end of the snapshot.
         */
        pInfoP->RelativeOffset = 0L;
-       /* OK */        
+       /* OK */
        return STATUS_SUCCESS;
 #endif
 }
@@ -1213,7 +1135,6 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
                        IN ULONG ThreadInformationLength)
 {
   PETHREAD Thread;
-  NTSTATUS Status;
   union
   {
      KPRIORITY Priority;
@@ -1222,8 +1143,12 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
      HANDLE Handle;
      PVOID Address;
   }u;
-  
+  KPROCESSOR_MODE PreviousMode;
+  NTSTATUS Status = STATUS_SUCCESS;
+
   PAGED_CODE();
+  
+  PreviousMode = ExGetPreviousMode();
 
   if (ThreadInformationClass <= MaxThreadInfoClass &&
       !SetInformationData[ThreadInformationClass].Implemented)
@@ -1240,20 +1165,43 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
       return STATUS_INFO_LENGTH_MISMATCH;
     }
 
+  if (PreviousMode != KernelMode)
+    {
+      _SEH_TRY
+        {
+          ProbeForRead(ThreadInformation,
+                       SetInformationData[ThreadInformationClass].Size,
+                       1);
+          RtlCopyMemory(&u.Priority,
+                        ThreadInformation,
+                        SetInformationData[ThreadInformationClass].Size);
+        }
+      _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+      _SEH_END;
+      
+      if (!NT_SUCCESS(Status))
+        {
+          return Status;
+        }
+    }
+  else
+    {
+      RtlCopyMemory(&u.Priority,
+                    ThreadInformation,
+                    SetInformationData[ThreadInformationClass].Size);
+    }
+
+  /* FIXME: This is REALLY wrong. Some types don't need THREAD_SET_INFORMATION */
+  /* FIXME: We should also check for certain things before doing the reference */
   Status = ObReferenceObjectByHandle (ThreadHandle,
                                      THREAD_SET_INFORMATION,
                                      PsThreadType,
                                      ExGetPreviousMode (),
                                      (PVOID*)&Thread,
                                      NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-
-   Status = MmCopyFromCaller(&u.Priority,
-                            ThreadInformation,
-                            SetInformationData[ThreadInformationClass].Size);
    if (NT_SUCCESS(Status))
      {
        switch (ThreadInformationClass)
@@ -1266,19 +1214,31 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
               }
             KeSetPriorityThread(&Thread->Tcb, u.Priority);
             break;
-       
+
            case ThreadBasePriority:
             KeSetBasePriorityThread (&Thread->Tcb, u.Increment);
             break;
-       
+
            case ThreadAffinityMask:
-            Status = KeSetAffinityThread(&Thread->Tcb, u.Affinity);
+               
+               /* Check if this is valid */
+               DPRINT1("%lx, %lx\n", Thread->ThreadsProcess->Pcb.Affinity, u.Affinity);
+               if ((Thread->ThreadsProcess->Pcb.Affinity & u.Affinity) !=
+                   u.Affinity)
+               {
+                   DPRINT1("Wrong affinity given\n");
+                   Status = STATUS_INVALID_PARAMETER;
+               }
+               else
+               {
+                       Status = KeSetAffinityThread(&Thread->Tcb, u.Affinity);
+               }
             break;
-       
+
            case ThreadImpersonationToken:
             Status = PsAssignImpersonationToken (Thread, u.Handle);
             break;
-               
+
            case ThreadQuerySetWin32StartAddress:
             Thread->Win32StartAddress = u.Address;
             break;
@@ -1287,9 +1247,9 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
             /* Shoult never occure if the data table is correct */
             KEBUGCHECK(0);
         }
+       ObDereferenceObject (Thread);
      }
-  ObDereferenceObject (Thread);
-
+  
   return Status;
 }
 
@@ -1304,7 +1264,6 @@ NtQueryInformationThread (IN      HANDLE          ThreadHandle,
                          OUT   PULONG          ReturnLength  OPTIONAL)
 {
    PETHREAD Thread;
-   NTSTATUS Status;
    union
    {
       THREAD_BASIC_INFORMATION TBI;
@@ -1313,8 +1272,12 @@ NtQueryInformationThread (IN     HANDLE          ThreadHandle,
       LARGE_INTEGER Count;
       BOOLEAN Last;
    }u;
-   
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
+
    PAGED_CODE();
+   
+   PreviousMode = ExGetPreviousMode();
 
    if (ThreadInformationClass <= MaxThreadInfoClass &&
        !QueryInformationData[ThreadInformationClass].Implemented)
@@ -1331,6 +1294,30 @@ NtQueryInformationThread (IN     HANDLE          ThreadHandle,
        return STATUS_INFO_LENGTH_MISMATCH;
      }
 
+   if (PreviousMode != KernelMode)
+     {
+       _SEH_TRY
+         {
+           ProbeForWrite(ThreadInformation,
+                         QueryInformationData[ThreadInformationClass].Size,
+                         1);
+           if (ReturnLength != NULL)
+             {
+               ProbeForWriteUlong(ReturnLength);
+             }
+         }
+       _SEH_HANDLE
+         {
+           Status = _SEH_GetExceptionCode();
+         }
+       _SEH_END;
+       
+       if (!NT_SUCCESS(Status))
+         {
+           return Status;
+         }
+     }
+
    Status = ObReferenceObjectByHandle(ThreadHandle,
                                      THREAD_QUERY_INFORMATION,
                                      PsThreadType,
@@ -1346,17 +1333,17 @@ NtQueryInformationThread (IN    HANDLE          ThreadHandle,
      {
        case ThreadBasicInformation:
          /* A test on W2K agains ntdll shows NtQueryInformationThread return STATUS_PENDING
-          * as ExitStatus for current/running thread, while KETHREAD's ExitStatus is 
+          * as ExitStatus for current/running thread, while KETHREAD's ExitStatus is
           * 0. So do the conversion here:
           * -Gunnar     */
          u.TBI.ExitStatus = (Thread->ExitStatus == 0) ? STATUS_PENDING : Thread->ExitStatus;
-        u.TBI.TebBaseAddress = Thread->Tcb.Teb;
+        u.TBI.TebBaseAddress = (PVOID)Thread->Tcb.Teb;
         u.TBI.ClientId = Thread->Cid;
         u.TBI.AffinityMask = Thread->Tcb.Affinity;
         u.TBI.Priority = Thread->Tcb.Priority;
-        u.TBI.BasePriority = Thread->Tcb.BasePriority;
+        u.TBI.BasePriority = KeQueryBasePriorityThread(&Thread->Tcb);
         break;
-       
+
        case ThreadTimes:
         u.TTI.KernelTime.QuadPart = Thread->Tcb.KernelTime * 100000LL;
          u.TTI.UserTime.QuadPart = Thread->Tcb.UserTime * 100000LL;
@@ -1389,23 +1376,41 @@ NtQueryInformationThread (IN    HANDLE          ThreadHandle,
         /* Shoult never occure if the data table is correct */
         KEBUGCHECK(0);
      }
-   if (QueryInformationData[ThreadInformationClass].Size)
+
+   if (PreviousMode != KernelMode)
      {
-       Status = MmCopyToCaller(ThreadInformation,
-                               &u.TBI,
-                              QueryInformationData[ThreadInformationClass].Size);
+       _SEH_TRY
+         {
+           if (QueryInformationData[ThreadInformationClass].Size)
+             {
+               RtlCopyMemory(ThreadInformation,
+                             &u.TBI,
+                             QueryInformationData[ThreadInformationClass].Size);
+             }
+           if (ReturnLength != NULL)
+             {
+               *ReturnLength = QueryInformationData[ThreadInformationClass].Size;
+             }
+         }
+       _SEH_HANDLE
+         {
+           Status = _SEH_GetExceptionCode();
+         }
+       _SEH_END;
      }
-   if (ReturnLength)
+   else
      {
-       NTSTATUS Status2;
-       static ULONG Null = 0;
-       Status2 = MmCopyToCaller(ReturnLength,
-                               NT_SUCCESS(Status) ? &QueryInformationData[ThreadInformationClass].Size : &Null,
-                               sizeof(ULONG));
-       if (NT_SUCCESS(Status))
+       if (QueryInformationData[ThreadInformationClass].Size)
          {
-          Status = Status2;
-        }
+           RtlCopyMemory(ThreadInformation,
+                         &u.TBI,
+                         QueryInformationData[ThreadInformationClass].Size);
+         }
+
+       if (ReturnLength != NULL)
+         {
+           *ReturnLength = QueryInformationData[ThreadInformationClass].Size;
+         }
      }
 
    ObDereferenceObject(Thread);