Use ASSERT() instead of assert().
[reactos.git] / reactos / lib / kernel32 / process / proc.c
index 9cf5c6d..7cc029c 100644 (file)
@@ -1,4 +1,5 @@
-/*
+/* $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
  * FILE:            lib/kernel32/proc/proc.c
  * UPDATE HISTORY:
  *                  Created 01/11/98
  */
-#define UNICODE
-#include <windows.h>
-#include <kernel32/proc.h>
-#include <kernel32/thread.h>
-#include <wstring.h>
-#include <string.h>
-#include <ddk/rtl.h>
-#include <ddk/li.h>
 
-extern NT_PEB *CurrentPeb;
-extern NT_PEB Peb;
+/* INCLUDES ****************************************************************/
+
+#include <k32.h>
+
+#define NDEBUG
+#include "../include/debug.h"
+
+
+/* GLOBALS *******************************************************************/
 
 WaitForInputIdleType  lpfnGlobalRegisterWaitForInputIdle;
 
-VOID RegisterWaitForInputIdle(WaitForInputIdleType  lpfnRegisterWaitForInputIdle);
+LPSTARTUPINFOA lpLocalStartupInfo = NULL;
 
-WINBOOL 
-STDCALL
-GetProcessId(HANDLE hProcess,  LPDWORD lpProcessId );
+VOID STDCALL
+RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
 
+/* FUNCTIONS ****************************************************************/
 
-NT_PEB *GetCurrentPeb(VOID)
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetProcessAffinityMask (HANDLE hProcess,
+                       LPDWORD lpProcessAffinityMask,
+                       LPDWORD lpSystemAffinityMask)
 {
-       if ( CurrentPeb != NULL )
-               return CurrentPeb;
-       else // hack to be able to return a process environment any time.
-               return &Peb;
+  PROCESS_BASIC_INFORMATION ProcessInfo;
+  NTSTATUS Status;
+
+  Status = NtQueryInformationProcess (hProcess,
+                                     ProcessBasicInformation,
+                                     (PVOID)&ProcessInfo,
+                                     sizeof(PROCESS_BASIC_INFORMATION),
+                                     NULL);
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus (Status);
+      return FALSE;
+    }
+
+  *lpProcessAffinityMask = (DWORD)ProcessInfo.AffinityMask;
+
+  /* FIXME */
+  *lpSystemAffinityMask  = 0x00000001;
+
+  return TRUE;
 }
 
-HANDLE STDCALL GetCurrentProcess(VOID)
-{
-       return (HANDLE)NtCurrentProcess();
-}
 
-HANDLE STDCALL GetCurrentThread(VOID)
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetProcessAffinityMask (HANDLE hProcess,
+                       DWORD dwProcessAffinityMask)
 {
-       return (HANDLE)NtCurrentThread();
+  NTSTATUS Status;
+
+  Status = NtSetInformationProcess (hProcess,
+                                   ProcessAffinityMask,
+                                   (PVOID)&dwProcessAffinityMask,
+                                   sizeof(DWORD));
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus (Status);
+      return FALSE;
+    }
+
+  return TRUE;
 }
 
-DWORD 
-STDCALL
-GetCurrentProcessId(VOID)
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetProcessShutdownParameters (LPDWORD lpdwLevel,
+                             LPDWORD lpdwFlags)
 {
-       
-       return (DWORD)(GetTeb()->Cid).UniqueProcess;
-       
-       
+  CSRSS_API_REQUEST CsrRequest;
+  CSRSS_API_REPLY CsrReply;
+  NTSTATUS Status;
+
+  CsrRequest.Type = CSRSS_GET_SHUTDOWN_PARAMETERS;
+  Status = CsrClientCallServer(&CsrRequest,
+                              &CsrReply,
+                              sizeof(CSRSS_API_REQUEST),
+                              sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
+    {
+      SetLastErrorByStatus (Status);
+      return(FALSE);
+    }
+
+  *lpdwLevel = CsrReply.Data.GetShutdownParametersReply.Level;
+  *lpdwFlags = CsrReply.Data.GetShutdownParametersReply.Flags;
+
+  return(TRUE);
 }
 
-unsigned char CommandLineA[MAX_PATH];
 
-LPSTR
-STDCALL
-GetCommandLineA(
-               VOID
-               )
-{
-       WCHAR *CommandLineW;
-       ULONG i = 0;
-       
-       CommandLineW = GetCommandLineW();
-       while ((CommandLineW[i])!=0 && i < MAX_PATH)
-       {
-               CommandLineA[i] = (unsigned char)CommandLineW[i];
-               i++;
-       }
-       CommandLineA[i] = 0;
-       return CommandLineA;
-}
-LPWSTR
-STDCALL
-GetCommandLineW(
-               VOID
-               )
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetProcessShutdownParameters (DWORD dwLevel,
+                             DWORD dwFlags)
 {
-       return GetCurrentPeb()->StartupInfo->CommandLine;
+  CSRSS_API_REQUEST CsrRequest;
+  CSRSS_API_REPLY CsrReply;
+  NTSTATUS Status;
+
+  CsrRequest.Data.SetShutdownParametersRequest.Level = dwLevel;
+  CsrRequest.Data.SetShutdownParametersRequest.Flags = dwFlags;
+
+  CsrRequest.Type = CSRSS_SET_SHUTDOWN_PARAMETERS;
+  Status = CsrClientCallServer(&CsrRequest,
+                              &CsrReply,
+                              sizeof(CSRSS_API_REQUEST),
+                              sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
+    {
+      SetLastErrorByStatus (Status);
+      return(FALSE);
+    }
+
+  return(TRUE);
 }
 
 
-WINBOOL 
-STDCALL
-GetExitCodeProcess(
-    HANDLE hProcess,   
-    LPDWORD lpExitCode 
-   )
-{
-       NTSTATUS errCode;
-       PROCESS_BASIC_INFORMATION ProcessBasic;
-       ULONG BytesWritten;
-
-       errCode = NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasic,sizeof(PROCESS_BASIC_INFORMATION),&BytesWritten);
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
-       memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
-       return TRUE;
-       
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetProcessWorkingSetSize (HANDLE hProcess,
+                         PSIZE_T lpMinimumWorkingSetSize,
+                         PSIZE_T lpMaximumWorkingSetSize)
+{
+  QUOTA_LIMITS QuotaLimits;
+  NTSTATUS Status;
+
+  Status = NtQueryInformationProcess(hProcess,
+                                    ProcessQuotaLimits,
+                                    &QuotaLimits,
+                                    sizeof(QUOTA_LIMITS),
+                                    NULL);
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return(FALSE);
+    }
+
+  *lpMinimumWorkingSetSize = QuotaLimits.MinimumWorkingSetSize;
+  *lpMaximumWorkingSetSize = QuotaLimits.MaximumWorkingSetSize;
+
+  return(TRUE);
 }
 
-WINBOOL 
-STDCALL
-GetProcessId(
-    HANDLE hProcess,   
-    LPDWORD lpProcessId 
-   )
-{
-       NTSTATUS errCode;
-       PROCESS_BASIC_INFORMATION ProcessBasic;
-       ULONG BytesWritten;
-
-       errCode = NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasic,sizeof(PROCESS_BASIC_INFORMATION),&BytesWritten);
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
-       memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD));
-       return TRUE;
-       
-}
 
-WINBOOL
-STDCALL
-CreateProcessA(
-    LPCSTR lpApplicationName,
-    LPSTR lpCommandLine,
-    LPSECURITY_ATTRIBUTES lpProcessAttributes,
-    LPSECURITY_ATTRIBUTES lpThreadAttributes,
-    WINBOOL bInheritHandles,
-    DWORD dwCreationFlags,
-    LPVOID lpEnvironment,
-    LPCSTR lpCurrentDirectory,
-    LPSTARTUPINFO lpStartupInfo,
-    LPPROCESS_INFORMATION lpProcessInformation
-    )
-{
-       WCHAR ApplicationNameW[MAX_PATH];
-       WCHAR CommandLineW[MAX_PATH];
-       WCHAR CurrentDirectoryW[MAX_PATH];
-       
-       
-       ULONG i;
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetProcessWorkingSetSize(HANDLE hProcess,
+                        SIZE_T dwMinimumWorkingSetSize,
+                        SIZE_T dwMaximumWorkingSetSize)
+{
+  QUOTA_LIMITS QuotaLimits;
+  NTSTATUS Status;
   
-       i = 0;
-       while ((*lpApplicationName)!=0 && i < MAX_PATH)
-       {
-               ApplicationNameW[i] = *lpApplicationName;
-               lpApplicationName++;
-               i++;
-       }
-       ApplicationNameW[i] = 0;
-
-
-       i = 0;
-       while ((*lpCommandLine)!=0 && i < MAX_PATH)
-       {
-               CommandLineW[i] = *lpCommandLine;
-               lpCommandLine++;
-               i++;
-       }
-       CommandLineW[i] = 0;
-
-       i = 0;
-       while ((*lpCurrentDirectory)!=0 && i < MAX_PATH)
-       {
-               CurrentDirectoryW[i] = *lpCurrentDirectory;
-               lpCurrentDirectory++;
-               i++;
-       }
-       CurrentDirectoryW[i] = 0;
-       
-       return CreateProcessW(ApplicationNameW,CommandLineW, lpProcessAttributes,lpThreadAttributes,
-               bInheritHandles,dwCreationFlags,lpEnvironment,CurrentDirectoryW,lpStartupInfo,
-               lpProcessInformation);
-               
-               
-}
-
-
-WINBOOL
-STDCALL
-CreateProcessW(
-    LPCWSTR lpApplicationName,
-    LPWSTR lpCommandLine,
-    LPSECURITY_ATTRIBUTES lpProcessAttributes,
-    LPSECURITY_ATTRIBUTES lpThreadAttributes,
-    WINBOOL bInheritHandles,
-    DWORD dwCreationFlags,
-    LPVOID lpEnvironment,
-    LPCWSTR lpCurrentDirectory,
-    LPSTARTUPINFO lpStartupInfo,
-    LPPROCESS_INFORMATION lpProcessInformation
-    )
-{
-       HANDLE hFile, hSection, hProcess, hThread;
-       KPRIORITY PriorityClass;
-       OBJECT_ATTRIBUTES ObjectAttributes;
-       IO_STATUS_BLOCK IoStatusBlock;
-       BOOLEAN CreateSuspended;
-       
-       NTSTATUS errCode;
-
-       UNICODE_STRING ApplicationNameString;
-       
-
-
-       LPTHREAD_START_ROUTINE  lpStartAddress = NULL;
-       LPVOID  lpParameter = NULL;
-       
-       hFile = NULL;
-
-       ApplicationNameString.Length = lstrlenW(lpApplicationName)*sizeof(WCHAR);
-   
-       ApplicationNameString.Buffer = (WCHAR *)lpApplicationName;
-       ApplicationNameString.MaximumLength = ApplicationNameString.Length;
-
-
-       ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
-       ObjectAttributes.RootDirectory = NULL;
-       
-       
+  QuotaLimits.MinimumWorkingSetSize = dwMinimumWorkingSetSize;
+  QuotaLimits.MaximumWorkingSetSize = dwMaximumWorkingSetSize;
+
+  Status = NtSetInformationProcess(hProcess,
+                                  ProcessQuotaLimits,
+                                  &QuotaLimits,
+                                  sizeof(QUOTA_LIMITS));
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return(FALSE);
+    }
+
+  return(TRUE);
+}
 
-       if ( lpProcessAttributes != NULL ) {
-               if ( lpProcessAttributes->bInheritHandle ) 
-                       ObjectAttributes.Attributes = OBJ_INHERIT;
-               else
-                       ObjectAttributes.Attributes = 0;
-               ObjectAttributes.SecurityDescriptor = lpProcessAttributes->lpSecurityDescriptor;
-       }
-       ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
-
-       errCode = NtOpenFile(&hFile,(SYNCHRONIZE|FILE_EXECUTE), &ObjectAttributes,
-               &IoStatusBlock,(FILE_SHARE_DELETE|FILE_SHARE_READ),(FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE));
-       
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
 
-       errCode = NtCreateSection(&hSection,SECTION_ALL_ACCESS,NULL,NULL,PAGE_EXECUTE,SEC_IMAGE,hFile);
-       NtClose(hFile);
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetProcessTimes(HANDLE hProcess,
+               LPFILETIME lpCreationTime,
+               LPFILETIME lpExitTime,
+               LPFILETIME lpKernelTime,
+               LPFILETIME lpUserTime)
+{
+  KERNEL_USER_TIMES Kut;
+  NTSTATUS Status;
 
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
-               
-       
-       if ( lpProcessAttributes != NULL ) {
-               if ( lpProcessAttributes->bInheritHandle ) 
-                       ObjectAttributes.Attributes = OBJ_INHERIT;
-               else
-                       ObjectAttributes.Attributes = 0;
-               ObjectAttributes.SecurityDescriptor = lpProcessAttributes->lpSecurityDescriptor;
-       }
+  Status = NtQueryInformationProcess(hProcess,
+                                    ProcessTimes,
+                                    &Kut,
+                                    sizeof(Kut),
+                                    NULL);
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return(FALSE);
+    }
 
-       errCode = NtCreateProcess(&hProcess,PROCESS_ALL_ACCESS, &ObjectAttributes,NtCurrentProcess(),bInheritHandles,hSection,NULL,NULL);
-       NtClose(hSection);
+  lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
+  lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
 
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
+  lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
+  lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
 
-       PriorityClass = NORMAL_PRIORITY_CLASS;  
-       NtSetInformationProcess(hProcess,ProcessBasePriority,&PriorityClass,sizeof(KPRIORITY));
+  lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
+  lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
 
-       if ( ( dwCreationFlags & CREATE_SUSPENDED  ) ==  CREATE_SUSPENDED)
-               CreateSuspended = TRUE;
-       else
-               CreateSuspended = FALSE;
+  lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
+  lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
 
-       hThread =  CreateRemoteThread(
-               hProcess,       
-               lpThreadAttributes,
-               4096, // 1 page ??      
-               lpStartAddress, 
-               lpParameter,    
-               CREATE_SUSPENDED,
-               &lpProcessInformation->dwThreadId
-       );
+  return(TRUE);
+}
 
 
-       if ( hThread == NULL )
-               return FALSE;
+/*
+ * @implemented
+ */
+HANDLE STDCALL
+GetCurrentProcess(VOID)
+{
+  return((HANDLE)NtCurrentProcess());
+}
 
-       
-       
-       lpProcessInformation->hProcess = hProcess;
-       lpProcessInformation->hThread = hThread;
 
-       
+/*
+ * @implemented
+ */
+HANDLE STDCALL
+GetCurrentThread(VOID)
+{
+  return((HANDLE)NtCurrentThread());
+}
 
-       
-       GetProcessId(hProcess,&lpProcessInformation->dwProcessId);
 
-       
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetCurrentProcessId(VOID)
+{
+  return((DWORD)GetTeb()->Cid.UniqueProcess);
+}
 
-       return TRUE;
-                               
-       
- }
 
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetExitCodeProcess(HANDLE hProcess,
+                  LPDWORD lpExitCode)
+{
+  PROCESS_BASIC_INFORMATION ProcessBasic;
+  NTSTATUS Status;
+
+  Status = NtQueryInformationProcess(hProcess,
+                                    ProcessBasicInformation,
+                                    &ProcessBasic,
+                                    sizeof(PROCESS_BASIC_INFORMATION),
+                                    NULL);
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return(FALSE);
+     }
+
+  memcpy(lpExitCode, &ProcessBasic.ExitStatus, sizeof(DWORD));
+
+  return(TRUE);
+}
 
 
-HANDLE
+/*
+ * @implemented
+ */
+DWORD
 STDCALL
-OpenProcess(
-           DWORD dwDesiredAccess,
-           WINBOOL bInheritHandle,
-           DWORD dwProcessId
-           )
-{
-
-
-       NTSTATUS errCode;
-       HANDLE ProcessHandle;
-       OBJECT_ATTRIBUTES ObjectAttributes;
-       CLIENT_ID ClientId ;
-
-       ClientId.UniqueProcess = (HANDLE)dwProcessId;
-       ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
-       ObjectAttributes.RootDirectory = (HANDLE)NULL;
-       ObjectAttributes.SecurityDescriptor = NULL;
-       ObjectAttributes.SecurityQualityOfService = NULL;
-       
-       if ( bInheritHandle == TRUE )
-               ObjectAttributes.Attributes = OBJ_INHERIT;
-       else
-               ObjectAttributes.Attributes = 0;
-
-       errCode = NtOpenProcess ( &ProcessHandle, dwDesiredAccess, &ObjectAttributes, &ClientId);
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return NULL;
-       }
-       return ProcessHandle;
+GetProcessId(HANDLE Process)
+{
+  PROCESS_BASIC_INFORMATION ProcessBasic;
+  NTSTATUS Status;
+
+  Status = NtQueryInformationProcess(Process,
+                                    ProcessBasicInformation,
+                                    &ProcessBasic,
+                                    sizeof(PROCESS_BASIC_INFORMATION),
+                                    NULL);
+  if (!NT_SUCCESS(Status))
+  {
+    SetLastErrorByStatus(Status);
+    return 0;
+  }
+
+  return ProcessBasic.UniqueProcessId;
 }
 
 
+/*
+ * @implemented
+ */
+HANDLE STDCALL
+OpenProcess(DWORD dwDesiredAccess,
+           BOOL bInheritHandle,
+           DWORD dwProcessId)
+{
+   NTSTATUS errCode;
+   HANDLE ProcessHandle;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   CLIENT_ID ClientId;
+   
+   ClientId.UniqueProcess = (HANDLE)dwProcessId;
+   ClientId.UniqueThread = INVALID_HANDLE_VALUE;
+   
+   ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
+   ObjectAttributes.RootDirectory = (HANDLE)NULL;
+   ObjectAttributes.SecurityDescriptor = NULL;
+   ObjectAttributes.SecurityQualityOfService = NULL;
+   ObjectAttributes.ObjectName = NULL;
+   
+   if (bInheritHandle == TRUE)
+     ObjectAttributes.Attributes = OBJ_INHERIT;
+   else
+     ObjectAttributes.Attributes = 0;
+   
+   errCode = NtOpenProcess(&ProcessHandle,
+                          dwDesiredAccess,
+                          &ObjectAttributes,
+                          &ClientId);
+   if (!NT_SUCCESS(errCode))
+     {
+       SetLastErrorByStatus (errCode);
+       return NULL;
+     }
+   return ProcessHandle;
+}
 
 
+/*
+ * @implemented
+ */
+UINT STDCALL
+WinExec(LPCSTR lpCmdLine,
+       UINT uCmdShow)
+{
+   STARTUPINFOA StartupInfo;
+   PROCESS_INFORMATION  ProcessInformation;
+   DWORD dosErr;
+
+   RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
+   StartupInfo.cb = sizeof(STARTUPINFOA);
+   StartupInfo.wShowWindow = uCmdShow;
+   StartupInfo.dwFlags = 0;
+
+   if (! CreateProcessA(NULL,
+                       (PVOID)lpCmdLine,
+                       NULL,
+                       NULL,
+                       FALSE,
+                       0,
+                       NULL,
+                       NULL,
+                       &StartupInfo,
+                       &ProcessInformation))
+     {
+       dosErr = GetLastError();
+       return dosErr < 32 ? dosErr : ERROR_BAD_FORMAT;
+     }
+   if (NULL != lpfnGlobalRegisterWaitForInputIdle)
+     {
+       lpfnGlobalRegisterWaitForInputIdle (
+         ProcessInformation.hProcess,
+          10000
+       );
+     }
+   NtClose(ProcessInformation.hProcess);
+   NtClose(ProcessInformation.hThread);
 
+   return 33; /* Something bigger than 31 means success. */
+}
 
 
+/*
+ * @implemented
+ */
+VOID STDCALL
+RegisterWaitForInputIdle (
+       WaitForInputIdleType    lpfnRegisterWaitForInputIdle
+       )
+{
+       lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
+       return;
+}
 
 
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+WaitForInputIdle (
+       HANDLE  hProcess,
+       DWORD   dwMilliseconds
+       )
+{
+       return 0;
+}
 
 
+/*
+ * @implemented
+ */
+VOID STDCALL
+Sleep(DWORD dwMilliseconds)
+{
+  SleepEx(dwMilliseconds, FALSE);
+  return;
+}
 
 
-UINT   WinExec ( LPCSTR  lpCmdLine,    UINT  uCmdShow  )
+/*
+ * @implemented
+ */
+DWORD STDCALL
+SleepEx(DWORD dwMilliseconds,
+       BOOL bAlertable)
 {
-       STARTUPINFO StartupInfo;
-       PROCESS_INFORMATION  ProcessInformation;        
+  TIME Interval;
+  NTSTATUS errCode;
+  
+  if (dwMilliseconds != INFINITE)
+    {
+      /*
+       * System time units are 100 nanoseconds (a nanosecond is a billionth of
+       * a second).
+       */
+      Interval.QuadPart = -((ULONGLONG)dwMilliseconds * 10000);
+    }  
+  else
+    {
+      /* Approximately 292000 years hence */
+      Interval.QuadPart = -0x7FFFFFFFFFFFFFFFLL;
+    }
+
+  errCode = NtDelayExecution (bAlertable, &Interval);
+  if (!NT_SUCCESS(errCode))
+    {
+      SetLastErrorByStatus (errCode);
+      return -1;
+    }
+  return 0;
+}
 
-       HINSTANCE hInst;
-       DWORD dosErr;
 
+/*
+ * @implemented
+ */
+VOID STDCALL
+GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
+{
+  PRTL_USER_PROCESS_PARAMETERS Params;
+
+  if (lpStartupInfo == NULL)
+    {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return;
+    }
+
+  Params = NtCurrentPeb()->ProcessParameters;
+
+  lpStartupInfo->cb = sizeof(STARTUPINFOW);
+  lpStartupInfo->lpDesktop = Params->DesktopInfo.Buffer;
+  lpStartupInfo->lpTitle = Params->WindowTitle.Buffer;
+  lpStartupInfo->dwX = Params->dwX;
+  lpStartupInfo->dwY = Params->dwY;
+  lpStartupInfo->dwXSize = Params->dwXSize;
+  lpStartupInfo->dwYSize = Params->dwYSize;
+  lpStartupInfo->dwXCountChars = Params->dwXCountChars;
+  lpStartupInfo->dwYCountChars = Params->dwYCountChars;
+  lpStartupInfo->dwFillAttribute = Params->dwFillAttribute;
+  lpStartupInfo->dwFlags = Params->dwFlags;
+  lpStartupInfo->wShowWindow = Params->wShowWindow;
+  lpStartupInfo->lpReserved = Params->ShellInfo.Buffer;
+  lpStartupInfo->cbReserved2 = Params->RuntimeInfo.Length;
+  lpStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeInfo.Buffer;
+
+  lpStartupInfo->hStdInput = Params->hStdInput;
+  lpStartupInfo->hStdOutput = Params->hStdOutput;
+  lpStartupInfo->hStdError = Params->hStdError;
+}
 
 
-       StartupInfo.cb = sizeof(STARTUPINFO);
-       StartupInfo.wShowWindow = uCmdShow ;
-       StartupInfo.dwFlags = 0;
+/*
+ * @implemented
+ */
+VOID STDCALL
+GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
+{
+  PRTL_USER_PROCESS_PARAMETERS Params;
+  ANSI_STRING AnsiString;
 
-       hInst = (HINSTANCE)CreateProcessA(NULL,(PVOID)lpCmdLine,NULL,NULL,FALSE,0,NULL,NULL,&StartupInfo, &ProcessInformation);
-       if ( hInst == NULL ) {
-               dosErr = GetLastError();
-               return dosErr;
-       }
-       if ( lpfnGlobalRegisterWaitForInputIdle != NULL )
-               lpfnGlobalRegisterWaitForInputIdle(ProcessInformation.hProcess,10000);
-       NtClose(ProcessInformation.hProcess);
-       NtClose(ProcessInformation.hThread);
-       return 0;
-       
+  if (lpStartupInfo == NULL)
+    {
+       SetLastError(ERROR_INVALID_PARAMETER);
+       return;
+    }
+
+  Params = NtCurrentPeb ()->ProcessParameters;
+
+  RtlAcquirePebLock ();
+
+  if (lpLocalStartupInfo == NULL)
+    {
+       /* create new local startup info (ansi) */
+       lpLocalStartupInfo = RtlAllocateHeap (RtlGetProcessHeap (),
+                                             0,
+                                             sizeof(STARTUPINFOA));
+
+       lpLocalStartupInfo->cb = sizeof(STARTUPINFOA);
+
+       /* copy window title string */
+       RtlUnicodeStringToAnsiString (&AnsiString,
+                                     &Params->WindowTitle,
+                                     TRUE);
+       lpLocalStartupInfo->lpTitle = AnsiString.Buffer;
+
+       /* copy desktop info string */
+       RtlUnicodeStringToAnsiString (&AnsiString,
+                                     &Params->DesktopInfo,
+                                     TRUE);
+       lpLocalStartupInfo->lpDesktop = AnsiString.Buffer;
+
+       /* copy shell info string */
+       RtlUnicodeStringToAnsiString (&AnsiString,
+                                     &Params->ShellInfo,
+                                     TRUE);
+       lpLocalStartupInfo->lpReserved = AnsiString.Buffer;
+
+       lpLocalStartupInfo->dwX = Params->dwX;
+       lpLocalStartupInfo->dwY = Params->dwY;
+       lpLocalStartupInfo->dwXSize = Params->dwXSize;
+       lpLocalStartupInfo->dwYSize = Params->dwYSize;
+       lpLocalStartupInfo->dwXCountChars = Params->dwXCountChars;
+       lpLocalStartupInfo->dwYCountChars = Params->dwYCountChars;
+       lpLocalStartupInfo->dwFillAttribute = Params->dwFillAttribute;
+       lpLocalStartupInfo->dwFlags = Params->dwFlags;
+       lpLocalStartupInfo->wShowWindow = Params->wShowWindow;
+       lpLocalStartupInfo->cbReserved2 = Params->RuntimeInfo.Length;
+       lpLocalStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeInfo.Buffer;
+
+       lpLocalStartupInfo->hStdInput = Params->hStdInput;
+       lpLocalStartupInfo->hStdOutput = Params->hStdOutput;
+       lpLocalStartupInfo->hStdError = Params->hStdError;
+     }
+
+   RtlReleasePebLock ();
+
+   /* copy local startup info data to external startup info */
+   memcpy (lpStartupInfo,
+           lpLocalStartupInfo,
+           sizeof(STARTUPINFOA));
 }
 
 
-
-VOID RegisterWaitForInputIdle(WaitForInputIdleType  lpfnRegisterWaitForInputIdle)
+/*
+ * @implemented
+ */
+BOOL STDCALL
+FlushInstructionCache (HANDLE  hProcess,
+                      LPCVOID  lpBaseAddress,
+                      DWORD    dwSize)
 {
-       lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle; 
-       return;
+  NTSTATUS Status;
+  
+  Status = NtFlushInstructionCache(hProcess,
+                                  (PVOID)lpBaseAddress,
+                                  dwSize);
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return FALSE;
+    }
+  return TRUE;
 }
 
-DWORD 
-STDCALL
-WaitForInputIdle(
-    HANDLE hProcess,   
-    DWORD dwMilliseconds       
-   )
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+ExitProcess(UINT uExitCode)
 {
-       return 0;
+  CSRSS_API_REQUEST CsrRequest;
+  CSRSS_API_REPLY CsrReply;
+  NTSTATUS Status;
+  
+  /* unload all dll's */
+  LdrShutdownProcess ();
+
+  /* notify csrss of process termination */
+  CsrRequest.Type = CSRSS_TERMINATE_PROCESS;
+  Status = CsrClientCallServer(&CsrRequest, 
+                              &CsrReply,
+                              sizeof(CSRSS_API_REQUEST),
+                              sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
+    {
+      DPRINT("Failed to tell csrss about terminating process\n");
+    }
+  
+  
+  NtTerminateProcess (NtCurrentProcess (),
+                     uExitCode);
+
+  /* should never get here */
+  ASSERT(0);
+  while(1);
 }
 
-VOID 
-STDCALL
-Sleep(
-    DWORD dwMilliseconds       
-   )
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+TerminateProcess (HANDLE       hProcess,
+                 UINT  uExitCode)
 {
-       SleepEx(dwMilliseconds,FALSE);
-       return;
+  NTSTATUS Status;
+
+  Status = NtTerminateProcess (hProcess, uExitCode);
+  if (NT_SUCCESS(Status))
+    {
+      return TRUE;
+    }
+  SetLastErrorByStatus (Status);
+  return FALSE;
 }
 
-DWORD 
-STDCALL
-SleepEx(
-    DWORD dwMilliseconds,      
-    BOOL bAlertable    
-   )
-{
-       TIME Interval;
-       NTSTATUS errCode;       
-       SET_LARGE_INTEGER_LOW_PART(Interval,dwMilliseconds*1000);
-
-       errCode = NtDelayExecution(bAlertable,&Interval);
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return -1;
-       }
-       return 0;
-}
 
+/*
+ * @unimplemented
+ */
+VOID STDCALL
+FatalAppExitA (UINT    uAction,
+              LPCSTR   lpMessageText)
+{
+  UNICODE_STRING MessageTextU;
+  ANSI_STRING MessageText;
+  
+  RtlInitAnsiString (&MessageText, (LPSTR) lpMessageText);
 
+  RtlAnsiStringToUnicodeString (&MessageTextU,
+                               &MessageText,
+                               TRUE);
 
+  FatalAppExitW (uAction, MessageTextU.Buffer);
 
+  RtlFreeUnicodeString (&MessageTextU);
+}
 
-VOID
-STDCALL
-GetStartupInfoW(
-    LPSTARTUPINFO  lpStartupInfo       
-   )
+
+/*
+ * @unimplemented
+ */
+VOID STDCALL
+FatalAppExitW(UINT uAction,
+             LPCWSTR lpMessageText)
+{
+  return;
+}
+
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+FatalExit (int ExitCode)
 {
-       NT_PEB *pPeb = GetCurrentPeb();
+  ExitProcess(ExitCode);
+}
 
-       if (lpStartupInfo == NULL ) {
-               SetLastError(ERROR_INVALID_PARAMETER);
-               return;
-       }
 
-       lpStartupInfo->cb = sizeof(STARTUPINFO);
-       lstrcpyW(lpStartupInfo->lpDesktop, pPeb->StartupInfo->Desktop); 
-       lstrcpyW(lpStartupInfo->lpTitle, pPeb->StartupInfo->Title);
-       lpStartupInfo->dwX = pPeb->StartupInfo->dwX; 
-       lpStartupInfo->dwY = pPeb->StartupInfo->dwY; 
-       lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize; 
-       lpStartupInfo->dwYSize = pPeb->StartupInfo->dwYSize; 
-       lpStartupInfo->dwXCountChars = pPeb->StartupInfo->dwXCountChars; 
-       lpStartupInfo->dwYCountChars = pPeb->StartupInfo->dwYCountChars; 
-       lpStartupInfo->dwFillAttribute = pPeb->StartupInfo->dwFillAttribute; 
-       lpStartupInfo->dwFlags = pPeb->StartupInfo->dwFlags; 
-       lpStartupInfo->wShowWindow = pPeb->StartupInfo->wShowWindow; 
-       //lpStartupInfo->cbReserved2 = pPeb->StartupInfo->cbReserved; 
-       //lpStartupInfo->lpReserved = pPeb->StartupInfo->lpReserved1; 
-       //lpStartupInfo->lpReserved2 = pPeb->StartupInfo->lpReserved2; 
-       
-       lpStartupInfo->hStdInput = pPeb->StartupInfo->hStdInput; 
-       lpStartupInfo->hStdOutput = pPeb->StartupInfo->hStdOutput; 
-       lpStartupInfo->hStdError = pPeb->StartupInfo->hStdError; 
-       
-       
-       
-       return;
+/*
+ * @implemented
+ */
+DWORD STDCALL
+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 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;
+    }
+  }
   
+  SetLastErrorByStatus(Status);
+  return FALSE;
+}
 
 
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetPriorityClass (HANDLE hProcess,
+                 DWORD dwPriorityClass)
+{
+  NTSTATUS Status;
+  PROCESS_PRIORITY_CLASS PriorityClass;
+  
+  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 NORMAL_PRIORITY_CLASS:
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
+      break;
+
+    case ABOVE_NORMAL_PRIORITY_CLASS:
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
+      break;
+
+    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;
+  }
+  
+  PriorityClass.Foreground = FALSE;
+
+  Status = NtSetInformationProcess(hProcess,
+                                   ProcessPriorityClass,
+                                   &PriorityClass,
+                                   sizeof(PROCESS_PRIORITY_CLASS));
+
+  if(!NT_SUCCESS(Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+  
+  return TRUE;
 }
 
 
-VOID
-STDCALL
-GetStartupInfoA(
-    LPSTARTUPINFO  lpStartupInfo       
-   )
-{
-       NT_PEB *pPeb = GetCurrentPeb();
-       ULONG i = 0;
-       if (lpStartupInfo == NULL ) {
-               SetLastError(ERROR_INVALID_PARAMETER);
-               return;
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetProcessVersion (DWORD ProcessId)
+{
+  DWORD                        Version = 0;
+  PIMAGE_NT_HEADERS    NtHeader = NULL;
+  PVOID                        BaseAddress = NULL;
+
+  /* Caller's */
+  if (0 == ProcessId || GetCurrentProcessId() == ProcessId)
+    {
+      BaseAddress = (PVOID) NtCurrentPeb()->ImageBaseAddress;
+      NtHeader = RtlImageNtHeader (BaseAddress);
+      if (NULL != NtHeader)
+       {
+         Version =
+           (NtHeader->OptionalHeader.MajorOperatingSystemVersion << 16) | 
+           (NtHeader->OptionalHeader.MinorOperatingSystemVersion);
        }
-
-       
-       lpStartupInfo->cb = sizeof(STARTUPINFO);
-       i = 0;
-  
-       while ((pPeb->StartupInfo->Desktop[i])!=0 && i < MAX_PATH)
-       {
-               lpStartupInfo->lpDesktop[i] = (unsigned char)pPeb->StartupInfo->Desktop[i];
-               i++;
-       }
-       lpStartupInfo->lpDesktop[i] = 0;
-       
-        i = 0;
-       while ((pPeb->StartupInfo->Title[i])!=0 && i < MAX_PATH)
-       {
-               lpStartupInfo->lpTitle[i] = (unsigned char)pPeb->StartupInfo->Title[i];
-               i++;
-       }
-       lpStartupInfo->lpTitle[i] = 0;
-
-       lpStartupInfo->dwX = pPeb->StartupInfo->dwX; 
-       lpStartupInfo->dwY = pPeb->StartupInfo->dwY; 
-       lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize; 
-       lpStartupInfo->dwYSize = pPeb->StartupInfo->dwYSize; 
-       lpStartupInfo->dwXCountChars = pPeb->StartupInfo->dwXCountChars; 
-       lpStartupInfo->dwYCountChars = pPeb->StartupInfo->dwYCountChars; 
-       lpStartupInfo->dwFillAttribute = pPeb->StartupInfo->dwFillAttribute; 
-       lpStartupInfo->dwFlags = pPeb->StartupInfo->dwFlags; 
-       lpStartupInfo->wShowWindow = pPeb->StartupInfo->wShowWindow; 
-       //lpStartupInfo->cbReserved2 = pPeb->StartupInfo->cbReserved; 
-       //lpStartupInfo->lpReserved = pPeb->StartupInfo->lpReserved1; 
-       //lpStartupInfo->lpReserved2 = pPeb->StartupInfo->lpReserved2; 
-       
-       lpStartupInfo->hStdInput = pPeb->StartupInfo->hStdInput; 
-       lpStartupInfo->hStdOutput = pPeb->StartupInfo->hStdOutput; 
-       lpStartupInfo->hStdError = pPeb->StartupInfo->hStdError; 
-       
-       return;
+    }
+  else /* other process */
+    {
+      /* FIXME: open the other process */
+      SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    }
+  return (Version);
 }
 
-BOOL 
+
+/*
+ * @implemented
+ */
+BOOL
 STDCALL
-FlushInstructionCache(
+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;
+}
+
 
-    HANDLE  hProcess,  
-    LPCVOID  lpBaseAddress,    
-    DWORD  dwSize      
-   )
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetProcessPriorityBoost(HANDLE hProcess,
+                        PBOOL pDisablePriorityBoost)
 {
-       NTSTATUS errCode;
-       errCode = NtFlushInstructionCache(hProcess,(PVOID)lpBaseAddress,dwSize);
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
-       return TRUE;
+  NTSTATUS Status;
+  BOOL PriorityBoost;
+
+  Status = NtQueryInformationProcess(hProcess,
+                                    ProcessPriorityBoost,
+                                    &PriorityBoost,
+                                    sizeof(BOOL),
+                                    NULL);
+  if (NT_SUCCESS(Status))
+    {
+      *pDisablePriorityBoost = PriorityBoost;
+      return TRUE;
+    }
+
+  SetLastErrorByStatus(Status);
+  return FALSE;
 }
 
-VOID
-STDCALL
-ExitProcess(
-           UINT uExitCode
-           ) 
-{
-       
-       NtTerminateProcess(
-               NtCurrentProcess() ,
-               uExitCode
-       );
-       
 
+/*
+ * @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;
 }
 
-VOID
-STDCALL
-FatalAppExitA(
-             UINT uAction,
-             LPCSTR lpMessageText
-             )
-{
-       WCHAR MessageTextW[MAX_PATH];
-       UINT i;
-       i = 0;
-       while ((*lpMessageText)!=0 && i < 35)
-       {
-               MessageTextW[i] = *lpMessageText;
-               lpMessageText++;
-               i++;
-       }
-       MessageTextW[i] = 0;
-       
-       return FatalAppExitW(uAction,MessageTextW);
-}
-
-
-       
-VOID
+
+/*
+ * @implemented
+ */
+BOOL
 STDCALL
-FatalAppExitW(
-    UINT uAction,
-    LPCWSTR lpMessageText
-    )
+GetProcessHandleCount(HANDLE hProcess,
+                      PDWORD pdwHandleCount)
 {
-       return; 
+    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 */