- NDK 0.98, now with versionned headers. Too many changes to list, see the TinyKRNL...
[reactos.git] / reactos / ntoskrnl / ps / query.c
index 3e6034c..be90e24 100644 (file)
@@ -62,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 */
 };
 
@@ -75,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
@@ -101,7 +101,7 @@ static const struct
 {
    BOOLEAN Implemented;
    ULONG Size;
-} SetInformationData[MaxThreadInfoClass + 1] = 
+} SetInformationData[MaxThreadInfoClass + 1] =
 {
     {TRUE, 0},                 // ThreadBasicInformation
     {TRUE, 0},                 // ThreadTimes
@@ -138,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,
@@ -176,7 +176,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
         real handle actually represents the current process. */
      return STATUS_INVALID_PARAMETER;
    }
-   
+
    switch (ProcessInformationClass)
      {
       case ProcessBasicInformation:
@@ -190,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;
 
@@ -254,7 +254,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
         _SEH_END;
         break;
       }
-      
+
       case ProcessLdtInformation:
       case ProcessWorkingSetWatch:
       case ProcessWx86Information:
@@ -264,7 +264,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
       case ProcessHandleCount:
       {
        ULONG HandleCount = ObpGetHandleCountByHandleTable(Process->ObjectTable);
-         
+
        _SEH_TRY
        {
           *(PULONG)ProcessInformation = HandleCount;
@@ -287,7 +287,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
 
         _SEH_TRY
         {
-          SessionInfo->SessionId = Process->SessionId;
+          SessionInfo->SessionId = Process->Session;
           if (ReturnLength)
           {
             *ReturnLength = sizeof(PROCESS_SESSION_INFORMATION);
@@ -300,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;
@@ -309,7 +309,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
       case ProcessVmCounters:
       {
        PVM_COUNTERS pOut = (PVM_COUNTERS)ProcessInformation;
-         
+
        _SEH_TRY
        {
          pOut->PeakVirtualSize            = Process->PeakVirtualSize;
@@ -318,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)
          {
@@ -364,7 +364,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
       case ProcessPriorityBoost:
       {
        PULONG BoostEnabled = (PULONG)ProcessInformation;
-         
+
        _SEH_TRY
        {
          *BoostEnabled = Process->Pcb.DisableBoost ? FALSE : TRUE;
@@ -385,7 +385,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
       case ProcessDeviceMap:
       {
         PROCESS_DEVICEMAP_INFORMATION DeviceMap;
-          
+
         ObQueryDeviceMapInformation(Process, &DeviceMap);
 
         _SEH_TRY
@@ -427,139 +427,59 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
 
       case ProcessImageFileName:
       {
-        /*
-         * We DO NOT return the file name stored in the EPROCESS structure.
-         * Propably if we can't find a PEB or ProcessParameters structure for the
-         * process!
-         */
-        if(Process->Peb != NULL)
-        {
-          PRTL_USER_PROCESS_PARAMETERS ProcParams = NULL;
-          UNICODE_STRING LocalDest;
-          BOOLEAN Attached;
           ULONG ImagePathLen = 0;
+          PROS_SECTION_OBJECT Section;
           PUNICODE_STRING DstPath = (PUNICODE_STRING)ProcessInformation;
+          PWSTR SrcBuffer = NULL, DstBuffer = (PWSTR)(DstPath + 1);
 
-          /* we need to attach to the process to make sure we're in the right context! */
-          Attached = Process != PsGetCurrentProcess();
+          Section = (PROS_SECTION_OBJECT)Process->SectionObject;
 
-          if(Attached)
-            KeAttachProcess(&Process->Pcb);
-          
-          _SEH_TRY
+          if (Section != NULL && Section->FileObject != NULL)
           {
-            ProcParams = Process->Peb->ProcessParameters;
-            ImagePathLen = ProcParams->ImagePathName.Length;
+              /* FIXME - check for SEC_IMAGE and/or SEC_FILE instead
+                         of relying on FileObject being != NULL? */
+              SrcBuffer = Section->FileObject->FileName.Buffer;
+              if (SrcBuffer != NULL)
+              {
+                  ImagePathLen = Section->FileObject->FileName.Length;
+              }
           }
-          _SEH_HANDLE
+
+          if(ProcessInformationLength < sizeof(UNICODE_STRING) + ImagePathLen + sizeof(WCHAR))
           {
-            Status = _SEH_GetExceptionCode();
+              Status = STATUS_INFO_LENGTH_MISMATCH;
           }
-          _SEH_END;
-          
-          if(NT_SUCCESS(Status))
+          else
           {
-            if(ProcessInformationLength < sizeof(UNICODE_STRING) + ImagePathLen + sizeof(WCHAR))
-            {
-              Status = STATUS_INFO_LENGTH_MISMATCH;
-            }
-            else
-            {
-              PWSTR StrSource = NULL;
-              
-              RtlZeroMemory(&LocalDest, sizeof(LocalDest));
-
-              /* create a DstPath structure on the stack */
               _SEH_TRY
               {
-                LocalDest.Length = ImagePathLen;
-                LocalDest.MaximumLength = ImagePathLen + sizeof(WCHAR);
-                LocalDest.Buffer = (PWSTR)(DstPath + 1);
-
-                /* save a copy of the pointer to the source buffer */
-                StrSource = ProcParams->ImagePathName.Buffer;
+                  /* copy the string manually, don't use RtlCopyUnicodeString with DstPath! */
+                  DstPath->Length = ImagePathLen;
+                  DstPath->MaximumLength = ImagePathLen + sizeof(WCHAR);
+                  DstPath->Buffer = DstBuffer;
+                  if (ImagePathLen != 0)
+                  {
+                      RtlCopyMemory(DstBuffer,
+                                    SrcBuffer,
+                                    ImagePathLen);
+                  }
+                  DstBuffer[ImagePathLen / sizeof(WCHAR)] = L'\0';
+                                
+                  Status = STATUS_SUCCESS;
               }
               _SEH_HANDLE
               {
-                Status = _SEH_GetExceptionCode();
+                  Status = _SEH_GetExceptionCode();
               }
               _SEH_END;
-
-              if(NT_SUCCESS(Status))
-              {
-                /* now, let's allocate some anonymous memory to copy the string to.
-                   we can't just copy it to the buffer the caller pointed as it might
-                   be user memory in another context */
-                PWSTR PathCopy = ExAllocatePool(PagedPool, LocalDest.Length + sizeof(WCHAR));
-                if(PathCopy != NULL)
-                {
-                  /* make a copy of the buffer to the temporary buffer */
-                  _SEH_TRY
-                  {
-                    RtlCopyMemory(PathCopy, StrSource, LocalDest.Length);
-                    PathCopy[LocalDest.Length / sizeof(WCHAR)] = L'\0';
-                  }
-                  _SEH_HANDLE
-                  {
-                    Status = _SEH_GetExceptionCode();
-                  }
-                  _SEH_END;
-
-                  /* detach from the process */
-                  if(Attached)
-                    KeDetachProcess();
-
-                  /* only copy the string back to the caller if we were able to
-                     copy it into the temporary buffer! */
-                  if(NT_SUCCESS(Status))
-                  {
-                    /* now let's copy the buffer back to the caller */
-                    _SEH_TRY
-                    {
-                      *DstPath = LocalDest;
-                      RtlCopyMemory(LocalDest.Buffer, PathCopy, LocalDest.Length + sizeof(WCHAR));
-                      if (ReturnLength)
-                      {
-                        *ReturnLength = sizeof(UNICODE_STRING) + LocalDest.Length + sizeof(WCHAR);
-                      }
-                    }
-                    _SEH_HANDLE
-                    {
-                      Status = _SEH_GetExceptionCode();
-                    }
-                    _SEH_END;
-                  }
-
-                  /* we're done with the copy operation, free the temporary kernel buffer */
-                  ExFreePool(PathCopy);
-
-                  /* we need to bail because we're already detached from the process */
-                  break;
-                }
-                else
-                {
-                  Status = STATUS_INSUFFICIENT_RESOURCES;
-                }
-              }
-            }
           }
-          
-          /* don't forget to detach from the process!!! */
-          if(Attached)
-            KeDetachProcess();
-        }
-        else
-        {
-          /* FIXME - what to do here? */
-          Status = STATUS_UNSUCCESSFUL;
-        }
-        break;
+          break;
       }
-      
+
       case ProcessCookie:
       {
         ULONG Cookie;
-        
+
         /* receive the process cookie, this is only allowed for the current
            process! */
 
@@ -571,16 +491,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,
@@ -592,7 +512,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
             Cookie = NewCookie;
           }
         }
-        
+
         _SEH_TRY
         {
           *(PULONG)ProcessInformation = Cookie;
@@ -606,7 +526,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
           Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-        
+
         break;
       }
 
@@ -632,7 +552,7 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
    {
      ObDereferenceObject(Process);
    }
-   
+
    return Status;
 }
 
@@ -649,24 +569,24 @@ 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:
@@ -680,7 +600,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
        Access = PROCESS_SET_INFORMATION;
        break;
    }
-   
+
    Status = ObReferenceObjectByHandle(ProcessHandle,
                                      Access,
                                      PsProcessType,
@@ -715,11 +635,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
            */
@@ -732,8 +652,8 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
           if(NT_SUCCESS(Status))
           {
             /* lock the process to be thread-safe! */
-            
-            Status = PsLockProcess(Process, FALSE);
+
+            Status = PsLockProcess((PROS_EPROCESS)Process, FALSE);
             if(NT_SUCCESS(Status))
             {
               /*
@@ -751,7 +671,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
                 ObDereferenceObject(ExceptionPort);
                 Status = STATUS_PORT_ALREADY_SET;
               }
-              PsUnlockProcess(Process);
+              PsUnlockProcess((PROS_EPROCESS)Process);
             }
             else
             {
@@ -801,14 +721,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 */
@@ -819,11 +739,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!
            */
@@ -835,13 +755,13 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             Status = STATUS_PRIVILEGE_NOT_HELD;
             break;
           }
-          
+
           /* FIXME - update the session id for the process token */
 
-          Status = PsLockProcess(Process, FALSE);
+          Status = PsLockProcess((PROS_EPROCESS)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)
@@ -865,12 +785,12 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
               KeDetachProcess();
             }
 
-            PsUnlockProcess(Process);
+            PsUnlockProcess((PROS_EPROCESS)Process);
           }
         }
         break;
       }
-      
+
       case ProcessPriorityClass:
       {
         PROCESS_PRIORITY_CLASS ppc;
@@ -884,14 +804,14 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
           Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-        
+
         if(NT_SUCCESS(Status))
         {
         }
-        
+
         break;
       }
-       
+
       case ProcessLdtInformation:
       case ProcessLdtSize:
       case ProcessIoPortHandlers:
@@ -923,7 +843,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
@@ -945,16 +865,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);
@@ -991,14 +911,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
                                );
                /*
@@ -1015,9 +935,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
                        )
@@ -1044,14 +964,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
                                        );
                        /*
@@ -1074,7 +994,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;
@@ -1091,9 +1011,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;
@@ -1120,7 +1040,7 @@ PiQuerySystemProcessInformation(PVOID Buffer,
         * Mark the end of the snapshot.
         */
        pInfoP->RelativeOffset = 0L;
-       /* OK */        
+       /* OK */
        return STATUS_SUCCESS;
 #endif
 }
@@ -1135,7 +1055,6 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
                        IN ULONG ThreadInformationLength)
 {
   PETHREAD Thread;
-  NTSTATUS Status;
   union
   {
      KPRIORITY Priority;
@@ -1144,8 +1063,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)
@@ -1162,20 +1085,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)
@@ -1188,19 +1134,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;
@@ -1209,9 +1167,9 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
             /* Shoult never occure if the data table is correct */
             KEBUGCHECK(0);
         }
+       ObDereferenceObject (Thread);
      }
-  ObDereferenceObject (Thread);
-
+  
   return Status;
 }
 
@@ -1226,7 +1184,6 @@ NtQueryInformationThread (IN      HANDLE          ThreadHandle,
                          OUT   PULONG          ReturnLength  OPTIONAL)
 {
    PETHREAD Thread;
-   NTSTATUS Status;
    union
    {
       THREAD_BASIC_INFORMATION TBI;
@@ -1235,8 +1192,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)
@@ -1253,6 +1214,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,
@@ -1268,17 +1253,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;
@@ -1311,23 +1296,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);