- NDK 0.98, now with versionned headers. Too many changes to list, see the TinyKRNL...
[reactos.git] / reactos / ntoskrnl / ps / query.c
index cae8cae..be90e24 100644 (file)
@@ -143,13 +143,13 @@ NtQueryInformationProcess(IN  HANDLE ProcessHandle,
 
    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);
@@ -427,133 +427,53 @@ 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();
-
-          if(Attached)
-            KeAttachProcess(&Process->Pcb);
+          Section = (PROS_SECTION_OBJECT)Process->SectionObject;
 
-          _SEH_TRY
+          if (Section != NULL && Section->FileObject != NULL)
           {
-            ProcParams = Process->Peb->ProcessParameters;
-            ImagePathLen = ProcParams->ImagePathName.Length;
-          }
-          _SEH_HANDLE
-          {
-            Status = _SEH_GetExceptionCode();
+              /* 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_END;
 
-          if(NT_SUCCESS(Status))
+          if(ProcessInformationLength < sizeof(UNICODE_STRING) + ImagePathLen + sizeof(WCHAR))
           {
-            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 */
+          }
+          else
+          {
               _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:
@@ -654,12 +574,12 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
 
    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);
@@ -733,7 +653,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
           {
             /* 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
             {
@@ -838,7 +758,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
 
           /* FIXME - update the session id for the process token */
 
-          Status = PsLockProcess(Process, FALSE);
+          Status = PsLockProcess((PROS_EPROCESS)Process, FALSE);
           if(NT_SUCCESS(Status))
           {
             Process->Session = SessionInfo.SessionId;
@@ -865,7 +785,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
               KeDetachProcess();
             }
 
-            PsUnlockProcess(Process);
+            PsUnlockProcess((PROS_EPROCESS)Process);
           }
         }
         break;
@@ -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)
@@ -1194,7 +1140,19 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
             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:
@@ -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,
@@ -1276,7 +1261,7 @@ NtQueryInformationThread (IN      HANDLE          ThreadHandle,
         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:
@@ -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);