- Implement ProcessQuotaLimits case for NtQueryInformationProcess. Based on Dmitry...
[reactos.git] / reactos / ntoskrnl / ps / query.c
index 4275d16..e00a0cd 100644 (file)
@@ -68,10 +68,13 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
     PPROCESS_BASIC_INFORMATION ProcessBasicInfo =
         (PPROCESS_BASIC_INFORMATION)ProcessInformation;
     PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation;
+    PPROCESS_PRIORITY_CLASS PsPriorityClass = (PPROCESS_PRIORITY_CLASS)ProcessInformation;
     ULONG HandleCount;
     PPROCESS_SESSION_INFORMATION SessionInfo =
         (PPROCESS_SESSION_INFORMATION)ProcessInformation;
     PVM_COUNTERS VmCounters = (PVM_COUNTERS)ProcessInformation;
+    PIO_COUNTERS IoCounters = (PIO_COUNTERS)ProcessInformation;
+    PQUOTA_LIMITS QuotaLimits = (PQUOTA_LIMITS)ProcessInformation;
     PROCESS_DEVICEMAP_INFORMATION DeviceMap;
     PUNICODE_STRING ImageName;
     ULONG Cookie;
@@ -89,19 +92,8 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
     if (!NT_SUCCESS(Status)) return Status;
 #endif
 
-    /* Check if this isn't the cookie class */
-    if(ProcessInformationClass != ProcessCookie)
-    {
-        /* Reference the process */
-        Status = ObReferenceObjectByHandle(ProcessHandle,
-                                           PROCESS_QUERY_INFORMATION,
-                                           PsProcessType,
-                                           PreviousMode,
-                                           (PVOID*)&Process,
-                                           NULL);
-        if (!NT_SUCCESS(Status)) return Status;
-    }
-    else if(ProcessHandle != NtCurrentProcess())
+    if((ProcessInformationClass == ProcessCookie) &&
+        (ProcessHandle != NtCurrentProcess()))
     {
         /*
          * Retreiving the process cookie is only allowed for the calling process
@@ -125,6 +117,16 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
+
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
             /* Protect writes with SEH */
             _SEH2_TRY
             {
@@ -145,10 +147,75 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             break;
 
-        /* Quote limits and I/O Counters: not implemented */
+        /* Process quota limits */
         case ProcessQuotaLimits:
+
+            Length = sizeof(QUOTA_LIMITS);
+            if (ProcessInformationLength != Length)
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
+            /* Indicate success */
+            Status = STATUS_SUCCESS;
+
+            _SEH2_TRY
+            {
+                /* Set max/min working set sizes */
+                QuotaLimits->MaximumWorkingSetSize =
+                        Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT;
+                QuotaLimits->MinimumWorkingSetSize =
+                        Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT;
+
+                /* Set default time limits */
+                QuotaLimits->TimeLimit.LowPart = (ULONG)-1;
+                QuotaLimits->TimeLimit.HighPart = (ULONG)-1;
+
+                /* Is quota block a default one? */
+                if (Process->QuotaBlock == &PspDefaultQuotaBlock)
+                {
+                    /* Set default pools and pagefile limits */
+                    QuotaLimits->PagedPoolLimit = (SIZE_T)-1;
+                    QuotaLimits->NonPagedPoolLimit = (SIZE_T)-1;
+                    QuotaLimits->PagefileLimit = (SIZE_T)-1;
+                }
+                else
+                {
+                    /* Get limits from non-default quota block */
+                    QuotaLimits->PagedPoolLimit =
+                        Process->QuotaBlock->QuotaEntry[PagedPool].Limit;
+                    QuotaLimits->NonPagedPoolLimit =
+                        Process->QuotaBlock->QuotaEntry[NonPagedPool].Limit;
+                    QuotaLimits->PagefileLimit =
+                        Process->QuotaBlock->QuotaEntry[2].Limit;
+                }
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                /* Get exception code */
+                Status = _SEH2_GetExceptionCode();
+            }
+            _SEH2_END;
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
+            break;
+
         case ProcessIoCounters:
 
             Length = sizeof(IO_COUNTERS);
@@ -158,7 +225,35 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 break;
             }
 
-            Status = STATUS_NOT_IMPLEMENTED;
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
+            _SEH2_TRY
+            {
+                IoCounters->ReadOperationCount = Process->ReadOperationCount.QuadPart;
+                IoCounters->ReadTransferCount = Process->ReadTransferCount.QuadPart;
+                IoCounters->WriteOperationCount = Process->WriteOperationCount.QuadPart;
+                IoCounters->WriteTransferCount = Process->WriteTransferCount.QuadPart;
+                IoCounters->OtherOperationCount = Process->OtherOperationCount.QuadPart;
+                IoCounters->OtherTransferCount = Process->OtherTransferCount.QuadPart;
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                /* Ignore exception */
+            }
+            _SEH2_END;
+
+            /* Set status to success in any case */
+            Status = STATUS_SUCCESS;
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             break;
 
         /* Timing */
@@ -173,6 +268,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 break;
             }
 
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
             /* Protect writes with SEH */
             _SEH2_TRY
             {
@@ -190,6 +294,9 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             break;
 
         /* Process Debug Port */
@@ -203,6 +310,16 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
+
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
             /* Protect write with SEH */
             _SEH2_TRY
             {
@@ -216,12 +333,29 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             break;
 
         /* LDT, WS and VDM Information: not implemented */
         case ProcessLdtInformation:
         case ProcessWorkingSetWatch:
         case ProcessWx86Information:
+
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
+            DPRINT1("Not implemented: %lx\n", ProcessInformationClass);
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             Status = STATUS_NOT_IMPLEMENTED;
             break;
 
@@ -236,6 +370,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 break;
             }
 
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
             /* Count the number of handles this process has */
             HandleCount = ObGetProcessHandleCount(Process);
 
@@ -251,6 +394,9 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             break;
 
         /* Session ID for the process */
@@ -264,6 +410,16 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
+
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
             /* Enter SEH for write safety */
             _SEH2_TRY
             {
@@ -276,6 +432,9 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             break;
 
         /* WOW64: Not implemented */
@@ -295,6 +454,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 break;
             }
 
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
             /* Enter SEH for write safety */
             _SEH2_TRY
             {
@@ -318,6 +486,9 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             break;
 
         /* Hard Error Processing Mode */
@@ -331,6 +502,16 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
+
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
             /* Enter SEH for writing back data */
             _SEH2_TRY
             {
@@ -344,6 +525,9 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             break;
 
         /* Priority Boosting status */
@@ -357,6 +541,16 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
+
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
             /* Enter SEH for writing back data */
             _SEH2_TRY
             {
@@ -370,6 +564,9 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             break;
 
         /* DOS Device Map */
@@ -383,6 +580,16 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
+
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
             /* Query the device map information */
             ObQueryDeviceMapInformation(Process, &DeviceMap);
 
@@ -397,24 +604,38 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             break;
 
         /* Priority class */
         case ProcessPriorityClass:
 
             /* Set the return length*/
-            Length = sizeof(USHORT);
+            Length = sizeof(PROCESS_PRIORITY_CLASS);
 
             if (ProcessInformationLength != Length)
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
+
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
             /* Enter SEH for writing back data */
             _SEH2_TRY
             {
                 /* Return current priority class */
-                *(PUSHORT)ProcessInformation = Process->PriorityClass;
+                PsPriorityClass->PriorityClass = Process->PriorityClass;
+                PsPriorityClass->Foreground = FALSE;
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
@@ -422,10 +643,22 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
+
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             break;
 
         case ProcessImageFileName:
 
+            /* Reference the process */
+            Status = ObReferenceObjectByHandle(ProcessHandle,
+                                               PROCESS_QUERY_INFORMATION,
+                                               PsProcessType,
+                                               PreviousMode,
+                                               (PVOID*)&Process,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
             /* Get the image path */
             Status = SeLocateProcessImageName(Process, &ImageName);
             if (NT_SUCCESS(Status))
@@ -465,6 +698,8 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 /* Free the image path */
                 ExFreePool(ImageName);
             }
+            /* Dereference the process */
+            ObDereferenceObject(Process);
             break;
 
         /* Per-process security cookie */
@@ -521,6 +756,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         case ProcessAffinityMask:
         case ProcessForegroundInformation:
         default:
+            DPRINT1("Unsupported or unimplemented: %lx\n", ProcessInformationClass);
             Status = STATUS_INVALID_INFO_CLASS;
     }
 
@@ -537,8 +773,6 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
     }
     _SEH2_END;
 
-    /* If we referenced the process, dereference it */
-    if(ProcessInformationClass != ProcessCookie) ObDereferenceObject(Process);
     return Status;
 }
 
@@ -559,6 +793,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
     HANDLE PortHandle = NULL;
     HANDLE TokenHandle = NULL;
     PROCESS_SESSION_INFORMATION SessionInfo = {0};
+    PROCESS_PRIORITY_CLASS PriorityClass = {0};
     PVOID ExceptionPort;
     PAGED_CODE();
 
@@ -598,16 +833,16 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
     /* Check what kind of information class this is */
     switch (ProcessInformationClass)
     {
-        /* Quotas and priorities: not implemented */
-        case ProcessQuotaLimits:
-        case ProcessBasePriority:
-        case ProcessRaisePriority:
-            Status = STATUS_NOT_IMPLEMENTED;
-            break;
-
         /* Error/Exception Port */
         case ProcessExceptionPort:
 
+            /* Check buffer length */
+            if (ProcessInformationLength != sizeof(HANDLE))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
             /* Use SEH for capture */
             _SEH2_TRY
             {
@@ -645,6 +880,13 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
         /* Security Token */
         case ProcessAccessToken:
 
+            /* Check buffer length */
+            if (ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
             /* Use SEH for capture */
             _SEH2_TRY
             {
@@ -667,6 +909,13 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
         /* Hard error processing */
         case ProcessDefaultHardErrorMode:
 
+            /* Check buffer length */
+            if (ProcessInformationLength != sizeof(ULONG))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
             /* Enter SEH for direct buffer read */
             _SEH2_TRY
             {
@@ -685,6 +934,13 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
         /* Session ID */
         case ProcessSessionInformation:
 
+            /* Check buffer length */
+            if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
             /* Enter SEH for capture */
             _SEH2_TRY
             {
@@ -744,11 +1000,59 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             //PsUnlockProcess(Process);
             break;
 
-        /* Priority class: HACK! */
         case ProcessPriorityClass:
+
+            /* Check buffer length */
+            if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
+            /* Enter SEH for capture */
+            _SEH2_TRY
+            {
+                /* Capture the caller's buffer */
+                PriorityClass = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
+            }
+            _SEH2_END;
+            if (!NT_SUCCESS(Status)) break;
+
+            /* Check for invalid PriorityClass value */
+            if (PriorityClass.PriorityClass > PROCESS_PRIORITY_CLASS_ABOVE_NORMAL)
+            {
+                Status = STATUS_INVALID_PARAMETER;
+                break;
+            }
+
+            /* TODO: Check privileges */
+
+            /* Check if we have a job */
+            if (Process->Job)
+            {
+                DPRINT1("Jobs not yet supported\n");
+            }
+
+            /* Set process priority class */
+            Process->PriorityClass = PriorityClass.PriorityClass;
+
+            /* Set process priority mode (foreground or background) */
+            PsSetProcessPriorityByClass(Process,
+                                        !PriorityClass.Foreground ? PsProcessPriorityBackground :
+                                        PsProcessPriorityForeground);
+
+            Status = STATUS_SUCCESS;
             break;
 
         /* We currently don't implement any of these */
+        case ProcessQuotaLimits:
+        case ProcessBasePriority:
+        case ProcessRaisePriority:
         case ProcessLdtInformation:
         case ProcessLdtSize:
         case ProcessIoPortHandlers:
@@ -756,6 +1060,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
         case ProcessUserModeIOPL:
         case ProcessEnableAlignmentFaultFixup:
         case ProcessAffinityMask:
+            DPRINT1("Not implemented: %lx\n", ProcessInformationClass);
             Status = STATUS_NOT_IMPLEMENTED;
             break;
 
@@ -769,6 +1074,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
         case ProcessWow64Information:
         case ProcessDebugPort:
         default:
+            DPRINT1("Unsupported or unimplemented: %lx\n", ProcessInformationClass);
             Status = STATUS_INVALID_INFO_CLASS;
     }
 
@@ -838,6 +1144,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
         /* Thread priority */
         case ThreadPriority:
 
+            /* Check buffer length */
+            if (ThreadInformationLength != sizeof(KPRIORITY))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
             /* Use SEH for capture */
             _SEH2_TRY
             {
@@ -867,6 +1180,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
 
         case ThreadBasePriority:
 
+            /* Check buffer length */
+            if (ThreadInformationLength != sizeof(LONG))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
             /* Use SEH for capture */
             _SEH2_TRY
             {
@@ -906,6 +1226,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
 
         case ThreadAffinityMask:
 
+            /* Check buffer length */
+            if (ThreadInformationLength != sizeof(ULONG_PTR))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
             /* Use SEH for capture */
             _SEH2_TRY
             {
@@ -967,6 +1294,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
 
         case ThreadImpersonationToken:
 
+            /* Check buffer length */
+            if (ThreadInformationLength != sizeof(HANDLE))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
             /* Use SEH for capture */
             _SEH2_TRY
             {
@@ -987,6 +1321,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
 
         case ThreadQuerySetWin32StartAddress:
 
+            /* Check buffer length */
+            if (ThreadInformationLength != sizeof(ULONG_PTR))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
             /* Use SEH for capture */
             _SEH2_TRY
             {
@@ -1007,6 +1348,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
 
         case ThreadIdealProcessor:
 
+            /* Check buffer length */
+            if (ThreadInformationLength != sizeof(ULONG_PTR))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
             /* Use SEH for capture */
             _SEH2_TRY
             {
@@ -1048,6 +1396,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
 
         case ThreadPriorityBoost:
 
+            /* Check buffer length */
+            if (ThreadInformationLength != sizeof(ULONG_PTR))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
             /* Use SEH for capture */
             _SEH2_TRY
             {
@@ -1068,6 +1423,13 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
 
         case ThreadZeroTlsCell:
 
+            /* Check buffer length */
+            if (ThreadInformationLength != sizeof(ULONG_PTR))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
             /* Use SEH for capture */
             _SEH2_TRY
             {
@@ -1170,17 +1532,27 @@ NtQueryInformationThread(IN HANDLE ThreadHandle,
     KIRQL OldIrql;
     PAGED_CODE();
 
-    /* Verify Information Class validity */
-#if 0
-    Status = DefaultQueryInfoBufferCheck(ThreadInformationClass,
-                                         PsThreadInfoClass,
-                                         RTL_NUMBER_OF(PsThreadInfoClass),
-                                         ThreadInformation,
-                                         ThreadInformationLength,
-                                         ReturnLength,
-                                         PreviousMode);
-    if (!NT_SUCCESS(Status)) return Status;
-#endif
+    if (PreviousMode != KernelMode)
+    {
+        _SEH2_TRY
+        {
+            ProbeForWrite(ThreadInformation,
+                          ThreadInformationLength,
+                          sizeof(ULONG));
+
+            if (ReturnLength)
+            {
+                ProbeForWriteUlong(ReturnLength);
+            }
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            Status = _SEH2_GetExceptionCode();
+        }
+        _SEH2_END;
+
+        if (!NT_SUCCESS(Status)) return Status;
+    }
 
     /* Check what class this is */
     Access = THREAD_QUERY_INFORMATION;
@@ -1363,6 +1735,33 @@ NtQueryInformationThread(IN HANDLE ThreadHandle,
             KeLowerIrql(OldIrql);
             break;
 
+        case ThreadDescriptorTableEntry:
+            DPRINT1("NtQueryInformationThread(): case ThreadDescriptorTableEntry not implemented!\n");
+            Status = STATUS_NOT_IMPLEMENTED;
+            break;
+
+        case ThreadPriorityBoost:
+
+            /* Set the return length*/
+            Length = sizeof(ULONG);
+
+            if (ThreadInformationLength != Length)
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
+            _SEH2_TRY
+            {
+                *(PULONG)ThreadInformation = Thread->Tcb.DisableBoost ? 1 : 0;
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                Status = _SEH2_GetExceptionCode();
+            }
+            _SEH2_END;
+            break;
+
         /* Anything else */
         default: