Use ASSERT() instead of assert().
[reactos.git] / reactos / lib / kernel32 / process / proc.c
index 7f48126..7cc029c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: proc.c,v 1.51 2003/01/22 02:24:10 ekohl Exp $
+/* $Id: proc.c,v 1.72 2004/11/05 12:26:55 ekohl Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
 
 #include <k32.h>
 
-
 #define NDEBUG
-#include <kernel32/kernel32.h>
+#include "../include/debug.h"
 
 
 /* GLOBALS *******************************************************************/
 
 WaitForInputIdleType  lpfnGlobalRegisterWaitForInputIdle;
 
-LPSTARTUPINFO lpLocalStartupInfo = NULL;
+LPSTARTUPINFOA lpLocalStartupInfo = NULL;
 
 VOID STDCALL
 RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
 
-WINBOOL STDCALL
-GetProcessId (HANDLE hProcess, LPDWORD lpProcessId);
-
-
 /* FUNCTIONS ****************************************************************/
 
-WINBOOL STDCALL
-GetProcessAffinityMask(HANDLE hProcess,
-                      LPDWORD lpProcessAffinityMask,
-                      LPDWORD lpSystemAffinityMask)
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetProcessAffinityMask (HANDLE hProcess,
+                       LPDWORD lpProcessAffinityMask,
+                       LPDWORD lpSystemAffinityMask)
 {
-  if ((NULL == lpProcessAffinityMask)
-      || (NULL == lpSystemAffinityMask))
+  PROCESS_BASIC_INFORMATION ProcessInfo;
+  NTSTATUS Status;
+
+  Status = NtQueryInformationProcess (hProcess,
+                                     ProcessBasicInformation,
+                                     (PVOID)&ProcessInfo,
+                                     sizeof(PROCESS_BASIC_INFORMATION),
+                                     NULL);
+  if (!NT_SUCCESS(Status))
     {
-      SetLastError(ERROR_BAD_ARGUMENTS);
-      return(FALSE);
+      SetLastErrorByStatus (Status);
+      return FALSE;
     }
 
-  /* FIXME: check hProcess is actually a process */
-  /* FIXME: query the kernel process object */
-  *lpProcessAffinityMask = 0x00000001;
+  *lpProcessAffinityMask = (DWORD)ProcessInfo.AffinityMask;
+
+  /* FIXME */
   *lpSystemAffinityMask  = 0x00000001;
 
-  return(TRUE);
+  return TRUE;
 }
 
 
+/*
+ * @implemented
+ */
 BOOL STDCALL
-SetProcessAffinityMask(HANDLE hProcess,
-                      DWORD dwProcessAffinityMask)
+SetProcessAffinityMask (HANDLE hProcess,
+                       DWORD dwProcessAffinityMask)
 {
-  return(FALSE);
+  NTSTATUS Status;
+
+  Status = NtSetInformationProcess (hProcess,
+                                   ProcessAffinityMask,
+                                   (PVOID)&dwProcessAffinityMask,
+                                   sizeof(DWORD));
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus (Status);
+      return FALSE;
+    }
+
+  return TRUE;
 }
 
 
-WINBOOL STDCALL
-GetProcessShutdownParameters(LPDWORD lpdwLevel,
-                            LPDWORD lpdwFlags)
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetProcessShutdownParameters (LPDWORD lpdwLevel,
+                             LPDWORD lpdwFlags)
 {
   CSRSS_API_REQUEST CsrRequest;
   CSRSS_API_REPLY CsrReply;
@@ -77,7 +100,7 @@ GetProcessShutdownParameters(LPDWORD lpdwLevel,
                               sizeof(CSRSS_API_REPLY));
   if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
     {
-      SetLastError(Status);
+      SetLastErrorByStatus (Status);
       return(FALSE);
     }
 
@@ -88,9 +111,12 @@ GetProcessShutdownParameters(LPDWORD lpdwLevel,
 }
 
 
-WINBOOL STDCALL
-SetProcessShutdownParameters(DWORD dwLevel,
-                            DWORD dwFlags)
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetProcessShutdownParameters (DWORD dwLevel,
+                             DWORD dwFlags)
 {
   CSRSS_API_REQUEST CsrRequest;
   CSRSS_API_REPLY CsrReply;
@@ -106,7 +132,7 @@ SetProcessShutdownParameters(DWORD dwLevel,
                               sizeof(CSRSS_API_REPLY));
   if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
     {
-      SetLastError(Status);
+      SetLastErrorByStatus (Status);
       return(FALSE);
     }
 
@@ -114,10 +140,13 @@ SetProcessShutdownParameters(DWORD dwLevel,
 }
 
 
-WINBOOL STDCALL
-GetProcessWorkingSetSize(HANDLE hProcess,
-                        LPDWORD lpMinimumWorkingSetSize,
-                        LPDWORD lpMaximumWorkingSetSize)
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetProcessWorkingSetSize (HANDLE hProcess,
+                         PSIZE_T lpMinimumWorkingSetSize,
+                         PSIZE_T lpMaximumWorkingSetSize)
 {
   QUOTA_LIMITS QuotaLimits;
   NTSTATUS Status;
@@ -133,24 +162,45 @@ GetProcessWorkingSetSize(HANDLE hProcess,
       return(FALSE);
     }
 
-  *lpMinimumWorkingSetSize = (DWORD)QuotaLimits.MinimumWorkingSetSize;
-  *lpMaximumWorkingSetSize = (DWORD)QuotaLimits.MaximumWorkingSetSize;
+  *lpMinimumWorkingSetSize = QuotaLimits.MinimumWorkingSetSize;
+  *lpMaximumWorkingSetSize = QuotaLimits.MaximumWorkingSetSize;
 
   return(TRUE);
 }
 
 
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
 SetProcessWorkingSetSize(HANDLE hProcess,
-                        DWORD dwMinimumWorkingSetSize,
-                        DWORD dwMaximumWorkingSetSize)
+                        SIZE_T dwMinimumWorkingSetSize,
+                        SIZE_T dwMaximumWorkingSetSize)
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return(FALSE);
+  QUOTA_LIMITS QuotaLimits;
+  NTSTATUS Status;
+  
+  QuotaLimits.MinimumWorkingSetSize = dwMinimumWorkingSetSize;
+  QuotaLimits.MaximumWorkingSetSize = dwMaximumWorkingSetSize;
+
+  Status = NtSetInformationProcess(hProcess,
+                                  ProcessQuotaLimits,
+                                  &QuotaLimits,
+                                  sizeof(QUOTA_LIMITS));
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return(FALSE);
+    }
+
+  return(TRUE);
 }
 
 
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
 GetProcessTimes(HANDLE hProcess,
                LPFILETIME lpCreationTime,
                LPFILETIME lpExitTime,
@@ -187,6 +237,9 @@ GetProcessTimes(HANDLE hProcess,
 }
 
 
+/*
+ * @implemented
+ */
 HANDLE STDCALL
 GetCurrentProcess(VOID)
 {
@@ -194,6 +247,9 @@ GetCurrentProcess(VOID)
 }
 
 
+/*
+ * @implemented
+ */
 HANDLE STDCALL
 GetCurrentThread(VOID)
 {
@@ -201,6 +257,9 @@ GetCurrentThread(VOID)
 }
 
 
+/*
+ * @implemented
+ */
 DWORD STDCALL
 GetCurrentProcessId(VOID)
 {
@@ -208,19 +267,21 @@ GetCurrentProcessId(VOID)
 }
 
 
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
 GetExitCodeProcess(HANDLE hProcess,
                   LPDWORD lpExitCode)
 {
   PROCESS_BASIC_INFORMATION ProcessBasic;
-  ULONG BytesWritten;
   NTSTATUS Status;
 
   Status = NtQueryInformationProcess(hProcess,
                                     ProcessBasicInformation,
                                     &ProcessBasic,
                                     sizeof(PROCESS_BASIC_INFORMATION),
-                                    &BytesWritten);
+                                    NULL);
   if (!NT_SUCCESS(Status))
     {
       SetLastErrorByStatus(Status);
@@ -233,40 +294,43 @@ GetExitCodeProcess(HANDLE hProcess,
 }
 
 
-WINBOOL STDCALL
-GetProcessId(HANDLE hProcess,
-            LPDWORD lpProcessId)
+/*
+ * @implemented
+ */
+DWORD
+STDCALL
+GetProcessId(HANDLE Process)
 {
   PROCESS_BASIC_INFORMATION ProcessBasic;
-  ULONG BytesWritten;
   NTSTATUS Status;
 
-  Status = NtQueryInformationProcess(hProcess,
+  Status = NtQueryInformationProcess(Process,
                                     ProcessBasicInformation,
                                     &ProcessBasic,
                                     sizeof(PROCESS_BASIC_INFORMATION),
-                                    &BytesWritten);
+                                    NULL);
   if (!NT_SUCCESS(Status))
-    {
-      SetLastErrorByStatus(Status);
-      return(FALSE);
-    }
+  {
+    SetLastErrorByStatus(Status);
+    return 0;
+  }
 
-  memcpy(lpProcessId, &ProcessBasic.UniqueProcessId, sizeof(DWORD));
-
-  return(TRUE);
+  return ProcessBasic.UniqueProcessId;
 }
 
 
+/*
+ * @implemented
+ */
 HANDLE STDCALL
 OpenProcess(DWORD dwDesiredAccess,
-           WINBOOL bInheritHandle,
+           BOOL bInheritHandle,
            DWORD dwProcessId)
 {
    NTSTATUS errCode;
    HANDLE ProcessHandle;
    OBJECT_ATTRIBUTES ObjectAttributes;
-   CLIENT_ID ClientId ;
+   CLIENT_ID ClientId;
    
    ClientId.UniqueProcess = (HANDLE)dwProcessId;
    ClientId.UniqueThread = INVALID_HANDLE_VALUE;
@@ -295,47 +359,53 @@ OpenProcess(DWORD dwDesiredAccess,
 }
 
 
+/*
+ * @implemented
+ */
 UINT STDCALL
 WinExec(LPCSTR lpCmdLine,
        UINT uCmdShow)
 {
    STARTUPINFOA StartupInfo;
    PROCESS_INFORMATION  ProcessInformation;
-   HINSTANCE hInst;
    DWORD dosErr;
 
+   RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
    StartupInfo.cb = sizeof(STARTUPINFOA);
    StartupInfo.wShowWindow = uCmdShow;
    StartupInfo.dwFlags = 0;
 
-   hInst = (HINSTANCE)CreateProcessA(NULL,
-                                    (PVOID)lpCmdLine,
-                                    NULL,
-                                    NULL,
-                                    FALSE,
-                                    0,
-                                    NULL,
-                                    NULL,
-                                    &StartupInfo,
-                                    &ProcessInformation);
-   if ( hInst == NULL )
+   if (! CreateProcessA(NULL,
+                       (PVOID)lpCmdLine,
+                       NULL,
+                       NULL,
+                       FALSE,
+                       0,
+                       NULL,
+                       NULL,
+                       &StartupInfo,
+                       &ProcessInformation))
      {
        dosErr = GetLastError();
-       return dosErr;
+       return dosErr < 32 ? dosErr : ERROR_BAD_FORMAT;
      }
    if (NULL != lpfnGlobalRegisterWaitForInputIdle)
-   {
-     lpfnGlobalRegisterWaitForInputIdle (
-       ProcessInformation.hProcess,
-       10000
+     {
+       lpfnGlobalRegisterWaitForInputIdle (
+         ProcessInformation.hProcess,
+          10000
        );
-   }
-   NtClose (ProcessInformation.hProcess);
-   NtClose (ProcessInformation.hThread);
-   return 0;   
+     }
+   NtClose(ProcessInformation.hProcess);
+   NtClose(ProcessInformation.hThread);
+
+   return 33; /* Something bigger than 31 means success. */
 }
 
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 RegisterWaitForInputIdle (
        WaitForInputIdleType    lpfnRegisterWaitForInputIdle
@@ -346,6 +416,9 @@ RegisterWaitForInputIdle (
 }
 
 
+/*
+ * @unimplemented
+ */
 DWORD STDCALL
 WaitForInputIdle (
        HANDLE  hProcess,
@@ -356,6 +429,9 @@ WaitForInputIdle (
 }
 
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 Sleep(DWORD dwMilliseconds)
 {
@@ -364,6 +440,9 @@ Sleep(DWORD dwMilliseconds)
 }
 
 
+/*
+ * @implemented
+ */
 DWORD STDCALL
 SleepEx(DWORD dwMilliseconds,
        BOOL bAlertable)
@@ -377,13 +456,12 @@ SleepEx(DWORD dwMilliseconds,
        * System time units are 100 nanoseconds (a nanosecond is a billionth of
        * a second).
        */
-      Interval.QuadPart = dwMilliseconds;
-      Interval.QuadPart = -(Interval.QuadPart * 10000);
+      Interval.QuadPart = -((ULONGLONG)dwMilliseconds * 10000);
     }  
   else
     {
       /* Approximately 292000 years hence */
-      Interval.QuadPart = -0x7FFFFFFFFFFFFFFF;
+      Interval.QuadPart = -0x7FFFFFFFFFFFFFFFLL;
     }
 
   errCode = NtDelayExecution (bAlertable, &Interval);
@@ -396,6 +474,9 @@ SleepEx(DWORD dwMilliseconds,
 }
 
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
 {
@@ -431,6 +512,9 @@ GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
 }
 
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
 {
@@ -500,6 +584,9 @@ GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
 }
 
 
+/*
+ * @implemented
+ */
 BOOL STDCALL
 FlushInstructionCache (HANDLE  hProcess,
                       LPCVOID  lpBaseAddress,
@@ -519,6 +606,9 @@ FlushInstructionCache (HANDLE       hProcess,
 }
 
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 ExitProcess(UINT uExitCode)
 {
@@ -537,17 +627,23 @@ ExitProcess(UINT uExitCode)
                               sizeof(CSRSS_API_REPLY));
   if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
     {
-      DbgPrint("Failed to tell csrss about terminating process. "
-              "Expect trouble.\n");
+      DPRINT("Failed to tell csrss about terminating process\n");
     }
   
   
   NtTerminateProcess (NtCurrentProcess (),
                      uExitCode);
+
+  /* should never get here */
+  ASSERT(0);
+  while(1);
 }
 
 
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
 TerminateProcess (HANDLE       hProcess,
                  UINT  uExitCode)
 {
@@ -563,6 +659,9 @@ TerminateProcess (HANDLE    hProcess,
 }
 
 
+/*
+ * @unimplemented
+ */
 VOID STDCALL
 FatalAppExitA (UINT    uAction,
               LPCSTR   lpMessageText)
@@ -582,6 +681,9 @@ FatalAppExitA (UINT uAction,
 }
 
 
+/*
+ * @unimplemented
+ */
 VOID STDCALL
 FatalAppExitW(UINT uAction,
              LPCWSTR lpMessageText)
@@ -590,6 +692,9 @@ FatalAppExitW(UINT uAction,
 }
 
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 FatalExit (int ExitCode)
 {
@@ -597,107 +702,122 @@ FatalExit (int ExitCode)
 }
 
 
+/*
+ * @implemented
+ */
 DWORD STDCALL
-GetPriorityClass (HANDLE       hProcess)
-{
-  HANDLE               hProcessTmp;
-  DWORD                CsrPriorityClass = 0; // This tells CSRSS we want to GET it!
-  NTSTATUS     Status;
-       
-  Status = 
-    NtDuplicateObject (GetCurrentProcess(),
-                      hProcess,
-                      GetCurrentProcess(),
-                      &hProcessTmp,
-                      (PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
-                      FALSE,
-                      0);
-  if (!NT_SUCCESS(Status))
-    {
-      SetLastErrorByStatus (Status);
-      return (0); /* ERROR */
-    }
-  /* Ask CSRSS to set it */
-  CsrSetPriorityClass (hProcessTmp, &CsrPriorityClass);
-  NtClose (hProcessTmp);
-  /* Translate CSR->W32 priorities */
-  switch (CsrPriorityClass)
+GetPriorityClass (HANDLE hProcess)
+{
+  NTSTATUS Status;
+  PROCESS_PRIORITY_CLASS PriorityClass;
+  
+  Status = NtQueryInformationProcess(hProcess,
+                                     ProcessPriorityClass,
+                                     &PriorityClass,
+                                     sizeof(PROCESS_PRIORITY_CLASS),
+                                     NULL);
+  if(NT_SUCCESS(Status))
+  {
+    switch(PriorityClass.PriorityClass)
     {
-    case CSR_PRIORITY_CLASS_NORMAL:
-      return (NORMAL_PRIORITY_CLASS);  /* 32 */
-    case CSR_PRIORITY_CLASS_IDLE:
-      return (IDLE_PRIORITY_CLASS);    /* 64 */
-    case CSR_PRIORITY_CLASS_HIGH:
-      return (HIGH_PRIORITY_CLASS);    /* 128 */
-    case CSR_PRIORITY_CLASS_REALTIME:
-      return (REALTIME_PRIORITY_CLASS);        /* 256 */
+      case PROCESS_PRIORITY_CLASS_IDLE:
+        return IDLE_PRIORITY_CLASS;
+
+      case PROCESS_PRIORITY_CLASS_BELOW_NORMAL:
+        return BELOW_NORMAL_PRIORITY_CLASS;
+
+      case PROCESS_PRIORITY_CLASS_NORMAL:
+        return NORMAL_PRIORITY_CLASS;
+
+      case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL:
+        return ABOVE_NORMAL_PRIORITY_CLASS;
+
+      case PROCESS_PRIORITY_CLASS_HIGH:
+        return HIGH_PRIORITY_CLASS;
+
+      case PROCESS_PRIORITY_CLASS_REALTIME:
+        return REALTIME_PRIORITY_CLASS;
+
+      default:
+        return NORMAL_PRIORITY_CLASS;
     }
-  SetLastError (ERROR_ACCESS_DENIED);
-  return (0); /* ERROR */
+  }
+  
+  SetLastErrorByStatus(Status);
+  return FALSE;
 }
 
 
-
-WINBOOL STDCALL
-SetPriorityClass (HANDLE       hProcess,
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetPriorityClass (HANDLE hProcess,
                  DWORD dwPriorityClass)
 {
-  HANDLE               hProcessTmp;
-  DWORD                CsrPriorityClass;
-  NTSTATUS     Status;
+  NTSTATUS Status;
+  PROCESS_PRIORITY_CLASS PriorityClass;
   
-  switch (dwPriorityClass)
-    {
-    case NORMAL_PRIORITY_CLASS:        /* 32 */
-      CsrPriorityClass = CSR_PRIORITY_CLASS_NORMAL;
+  switch(dwPriorityClass)
+  {
+    case IDLE_PRIORITY_CLASS:
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE;
+      break;
+
+    case BELOW_NORMAL_PRIORITY_CLASS:
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
       break;
-    case IDLE_PRIORITY_CLASS:  /* 64 */
-      CsrPriorityClass = CSR_PRIORITY_CLASS_IDLE;
+
+    case NORMAL_PRIORITY_CLASS:
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
       break;
-    case HIGH_PRIORITY_CLASS:  /* 128 */
-      CsrPriorityClass = CSR_PRIORITY_CLASS_HIGH;
+
+    case ABOVE_NORMAL_PRIORITY_CLASS:
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
       break;
-    case REALTIME_PRIORITY_CLASS:      /* 256 */
-      CsrPriorityClass = CSR_PRIORITY_CLASS_REALTIME;
+
+    case HIGH_PRIORITY_CLASS:
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH;
       break;
+
+    case REALTIME_PRIORITY_CLASS:
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME;
+      break;
+
     default:
-      SetLastError (ERROR_INVALID_PARAMETER);
-      return (FALSE);
-    }
-  Status = 
-    NtDuplicateObject (GetCurrentProcess(),
-                      hProcess,
-                      GetCurrentProcess(),
-                      &hProcessTmp,
-                      (PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
-                      FALSE,
-                      0);
-  if (!NT_SUCCESS(Status))
-    {
-      SetLastErrorByStatus (Status);
-      return (FALSE); /* ERROR */
-    }
-  /* Ask CSRSS to set it */
-  Status = CsrSetPriorityClass (hProcessTmp, &CsrPriorityClass);
-  NtClose (hProcessTmp);
-  if (!NT_SUCCESS(Status))
-    {
-      SetLastErrorByStatus (Status);
-      return (FALSE);
-    }
-  return (TRUE);
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return FALSE;
+  }
+  
+  PriorityClass.Foreground = FALSE;
+
+  Status = NtSetInformationProcess(hProcess,
+                                   ProcessPriorityClass,
+                                   &PriorityClass,
+                                   sizeof(PROCESS_PRIORITY_CLASS));
+
+  if(!NT_SUCCESS(Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+  
+  return TRUE;
 }
 
 
+/*
+ * @implemented
+ */
 DWORD STDCALL
-GetProcessVersion (DWORD       ProcessId)
+GetProcessVersion (DWORD ProcessId)
 {
   DWORD                        Version = 0;
   PIMAGE_NT_HEADERS    NtHeader = NULL;
   PVOID                        BaseAddress = NULL;
 
   /* Caller's */
-  if (0 == ProcessId)
+  if (0 == ProcessId || GetCurrentProcessId() == ProcessId)
     {
       BaseAddress = (PVOID) NtCurrentPeb()->ImageBaseAddress;
       NtHeader = RtlImageNtHeader (BaseAddress);
@@ -716,4 +836,109 @@ GetProcessVersion (DWORD  ProcessId)
   return (Version);
 }
 
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetProcessIoCounters(
+  HANDLE hProcess,
+  PIO_COUNTERS lpIoCounters)
+{
+  NTSTATUS Status;
+
+  Status = NtQueryInformationProcess(hProcess,
+                                    ProcessIoCounters,
+                                    lpIoCounters,
+                                    sizeof(IO_COUNTERS),
+                                    NULL);
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return(FALSE);
+    }
+  
+  return TRUE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetProcessPriorityBoost(HANDLE hProcess,
+                        PBOOL pDisablePriorityBoost)
+{
+  NTSTATUS Status;
+  BOOL PriorityBoost;
+
+  Status = NtQueryInformationProcess(hProcess,
+                                    ProcessPriorityBoost,
+                                    &PriorityBoost,
+                                    sizeof(BOOL),
+                                    NULL);
+  if (NT_SUCCESS(Status))
+    {
+      *pDisablePriorityBoost = PriorityBoost;
+      return TRUE;
+    }
+
+  SetLastErrorByStatus(Status);
+  return FALSE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+SetProcessPriorityBoost(HANDLE hProcess,
+                        BOOL bDisablePriorityBoost)
+{
+  NTSTATUS Status;
+  BOOL PriorityBoost = (bDisablePriorityBoost ? TRUE : FALSE); /* prevent setting values other than 1 and 0 */
+
+  Status = NtSetInformationProcess(hProcess,
+                                  ProcessPriorityBoost,
+                                  &PriorityBoost,
+                                  sizeof(BOOL));
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetProcessHandleCount(HANDLE hProcess,
+                      PDWORD pdwHandleCount)
+{
+    ULONG phc;
+    NTSTATUS Status;
+
+    Status = NtQueryInformationProcess(hProcess,
+                                       ProcessHandleCount,
+                                       &phc,
+                                       sizeof(ULONG),
+                                       NULL);
+    if(NT_SUCCESS(Status))
+    {
+      *pdwHandleCount = phc;
+      return TRUE;
+    }
+
+    SetLastErrorByStatus(Status);
+    return FALSE;
+}
+
 /* EOF */