2004-08-29 14:46:02 +00:00
|
|
|
/* $Id: proc.c,v 1.64 2004/08/29 14:46:02 weiden Exp $
|
1999-08-29 06:59:11 +00:00
|
|
|
*
|
1998-12-04 18:28:13 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS system libraries
|
|
|
|
* FILE: lib/kernel32/proc/proc.c
|
|
|
|
* PURPOSE: Process functions
|
|
|
|
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
|
|
|
* UPDATE HISTORY:
|
|
|
|
* Created 01/11/98
|
1996-01-23 01:02:17 +00:00
|
|
|
*/
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
/* INCLUDES ****************************************************************/
|
|
|
|
|
2003-01-15 21:24:36 +00:00
|
|
|
#include <k32.h>
|
2002-09-08 10:23:54 +00:00
|
|
|
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-01-16 21:03:00 +00:00
|
|
|
#define NDEBUG
|
2004-01-23 21:16:04 +00:00
|
|
|
#include "../include/debug.h"
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2000-01-26 10:07:30 +00:00
|
|
|
|
1999-05-29 00:15:17 +00:00
|
|
|
/* GLOBALS *******************************************************************/
|
1999-01-01 22:03:17 +00:00
|
|
|
|
1998-12-04 18:28:13 +00:00
|
|
|
WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
|
1996-01-23 01:02:17 +00:00
|
|
|
|
2003-08-05 15:41:03 +00:00
|
|
|
LPSTARTUPINFOA lpLocalStartupInfo = NULL;
|
2000-02-19 19:37:13 +00:00
|
|
|
|
2001-03-13 16:25:55 +00:00
|
|
|
VOID STDCALL
|
2003-01-22 02:24:36 +00:00
|
|
|
RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
|
1996-01-23 01:02:17 +00:00
|
|
|
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL STDCALL
|
2003-08-28 19:37:00 +00:00
|
|
|
InternalGetProcessId (HANDLE hProcess, LPDWORD lpProcessId);
|
2000-02-19 19:37:13 +00:00
|
|
|
|
1996-01-23 01:02:17 +00:00
|
|
|
|
2003-01-22 02:24:36 +00:00
|
|
|
/* FUNCTIONS ****************************************************************/
|
1999-04-14 00:52:19 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-03-06 15:05:29 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
GetProcessAffinityMask (HANDLE hProcess,
|
|
|
|
LPDWORD lpProcessAffinityMask,
|
|
|
|
LPDWORD lpSystemAffinityMask)
|
2001-03-31 01:17:30 +00:00
|
|
|
{
|
2003-03-06 15:05:29 +00:00
|
|
|
PROCESS_BASIC_INFORMATION ProcessInfo;
|
|
|
|
ULONG BytesWritten;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = NtQueryInformationProcess (hProcess,
|
|
|
|
ProcessBasicInformation,
|
|
|
|
(PVOID)&ProcessInfo,
|
|
|
|
sizeof(PROCESS_BASIC_INFORMATION),
|
|
|
|
&BytesWritten);
|
|
|
|
if (!NT_SUCCESS(Status))
|
2002-10-20 16:40:12 +00:00
|
|
|
{
|
2003-03-06 15:05:29 +00:00
|
|
|
SetLastError (Status);
|
|
|
|
return FALSE;
|
2002-10-20 16:40:12 +00:00
|
|
|
}
|
|
|
|
|
2003-03-06 15:05:29 +00:00
|
|
|
*lpProcessAffinityMask = (DWORD)ProcessInfo.AffinityMask;
|
|
|
|
|
|
|
|
/* FIXME */
|
2002-10-20 16:40:12 +00:00
|
|
|
*lpSystemAffinityMask = 0x00000001;
|
|
|
|
|
2003-03-06 15:05:29 +00:00
|
|
|
return TRUE;
|
2001-03-31 01:17:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-01-22 02:24:36 +00:00
|
|
|
BOOL STDCALL
|
2003-03-06 15:05:29 +00:00
|
|
|
SetProcessAffinityMask (HANDLE hProcess,
|
|
|
|
DWORD dwProcessAffinityMask)
|
2003-01-22 02:24:36 +00:00
|
|
|
{
|
2003-03-06 15:05:29 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = NtSetInformationProcess (hProcess,
|
|
|
|
ProcessAffinityMask,
|
|
|
|
(PVOID)&dwProcessAffinityMask,
|
|
|
|
sizeof(DWORD));
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastError (Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
2003-01-22 02:24:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL STDCALL
|
2003-03-06 15:05:29 +00:00
|
|
|
GetProcessShutdownParameters (LPDWORD lpdwLevel,
|
|
|
|
LPDWORD lpdwFlags)
|
2001-03-31 01:17:30 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
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))
|
|
|
|
{
|
|
|
|
SetLastError(Status);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
*lpdwLevel = CsrReply.Data.GetShutdownParametersReply.Level;
|
|
|
|
*lpdwFlags = CsrReply.Data.GetShutdownParametersReply.Flags;
|
|
|
|
|
|
|
|
return(TRUE);
|
2001-03-31 01:17:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL STDCALL
|
2003-03-06 15:05:29 +00:00
|
|
|
SetProcessShutdownParameters (DWORD dwLevel,
|
|
|
|
DWORD dwFlags)
|
2001-03-31 01:17:30 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
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))
|
|
|
|
{
|
|
|
|
SetLastError(Status);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(TRUE);
|
2001-03-31 01:17:30 +00:00
|
|
|
}
|
|
|
|
|
2002-10-20 16:40:12 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL STDCALL
|
2003-03-06 15:05:29 +00:00
|
|
|
GetProcessWorkingSetSize (HANDLE hProcess,
|
|
|
|
LPDWORD lpMinimumWorkingSetSize,
|
|
|
|
LPDWORD lpMaximumWorkingSetSize)
|
2001-03-31 01:17:30 +00:00
|
|
|
{
|
2003-01-22 02:24:36 +00:00
|
|
|
QUOTA_LIMITS QuotaLimits;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = NtQueryInformationProcess(hProcess,
|
|
|
|
ProcessQuotaLimits,
|
|
|
|
&QuotaLimits,
|
|
|
|
sizeof(QUOTA_LIMITS),
|
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastErrorByStatus(Status);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
*lpMinimumWorkingSetSize = (DWORD)QuotaLimits.MinimumWorkingSetSize;
|
|
|
|
*lpMaximumWorkingSetSize = (DWORD)QuotaLimits.MaximumWorkingSetSize;
|
|
|
|
|
|
|
|
return(TRUE);
|
2001-03-31 01:17:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL STDCALL
|
2002-10-20 16:40:12 +00:00
|
|
|
SetProcessWorkingSetSize(HANDLE hProcess,
|
|
|
|
DWORD dwMinimumWorkingSetSize,
|
|
|
|
DWORD dwMaximumWorkingSetSize)
|
2001-03-31 01:17:30 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return(FALSE);
|
2001-03-31 01:17:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL STDCALL
|
2002-10-20 16:40:12 +00:00
|
|
|
GetProcessTimes(HANDLE hProcess,
|
|
|
|
LPFILETIME lpCreationTime,
|
|
|
|
LPFILETIME lpExitTime,
|
|
|
|
LPFILETIME lpKernelTime,
|
|
|
|
LPFILETIME lpUserTime)
|
1999-04-14 00:52:19 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
KERNEL_USER_TIMES Kut;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = NtQueryInformationProcess(hProcess,
|
|
|
|
ProcessTimes,
|
|
|
|
&Kut,
|
|
|
|
sizeof(Kut),
|
|
|
|
NULL);
|
2001-03-13 16:25:55 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
SetLastErrorByStatus(Status);
|
|
|
|
return(FALSE);
|
2001-03-13 16:25:55 +00:00
|
|
|
}
|
2002-10-20 16:40:12 +00:00
|
|
|
|
2003-01-22 02:24:36 +00:00
|
|
|
lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
|
2001-03-13 16:25:55 +00:00
|
|
|
lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
|
2002-10-20 16:40:12 +00:00
|
|
|
|
2001-03-13 16:25:55 +00:00
|
|
|
lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
|
|
|
|
lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
|
2002-10-20 16:40:12 +00:00
|
|
|
|
2001-03-13 16:25:55 +00:00
|
|
|
lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
|
|
|
|
lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
|
2002-10-20 16:40:12 +00:00
|
|
|
|
2001-03-13 16:25:55 +00:00
|
|
|
lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
|
|
|
|
lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
|
2002-10-20 16:40:12 +00:00
|
|
|
|
|
|
|
return(TRUE);
|
1999-04-14 00:52:19 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2002-10-20 16:40:12 +00:00
|
|
|
HANDLE STDCALL
|
|
|
|
GetCurrentProcess(VOID)
|
1996-01-23 01:02:17 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
return((HANDLE)NtCurrentProcess());
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2002-10-20 16:40:12 +00:00
|
|
|
HANDLE STDCALL
|
|
|
|
GetCurrentThread(VOID)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
return((HANDLE)NtCurrentThread());
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2002-10-20 16:40:12 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
GetCurrentProcessId(VOID)
|
1999-10-13 22:35:55 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
return((DWORD)GetTeb()->Cid.UniqueProcess);
|
1996-01-23 01:02:17 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL STDCALL
|
2002-10-20 16:40:12 +00:00
|
|
|
GetExitCodeProcess(HANDLE hProcess,
|
|
|
|
LPDWORD lpExitCode)
|
1999-01-16 02:11:45 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
PROCESS_BASIC_INFORMATION ProcessBasic;
|
|
|
|
ULONG BytesWritten;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = NtQueryInformationProcess(hProcess,
|
|
|
|
ProcessBasicInformation,
|
|
|
|
&ProcessBasic,
|
|
|
|
sizeof(PROCESS_BASIC_INFORMATION),
|
|
|
|
&BytesWritten);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastErrorByStatus(Status);
|
|
|
|
return(FALSE);
|
1999-01-16 21:03:00 +00:00
|
|
|
}
|
2002-10-20 16:40:12 +00:00
|
|
|
|
|
|
|
memcpy(lpExitCode, &ProcessBasic.ExitStatus, sizeof(DWORD));
|
|
|
|
|
|
|
|
return(TRUE);
|
1996-01-23 01:02:17 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL STDCALL
|
2003-08-28 19:37:00 +00:00
|
|
|
InternalGetProcessId(HANDLE hProcess,
|
2002-10-20 16:40:12 +00:00
|
|
|
LPDWORD lpProcessId)
|
1996-01-23 01:02:17 +00:00
|
|
|
{
|
2003-01-22 02:24:36 +00:00
|
|
|
PROCESS_BASIC_INFORMATION ProcessBasic;
|
|
|
|
ULONG BytesWritten;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = NtQueryInformationProcess(hProcess,
|
|
|
|
ProcessBasicInformation,
|
|
|
|
&ProcessBasic,
|
|
|
|
sizeof(PROCESS_BASIC_INFORMATION),
|
|
|
|
&BytesWritten);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastErrorByStatus(Status);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(lpProcessId, &ProcessBasic.UniqueProcessId, sizeof(DWORD));
|
|
|
|
|
|
|
|
return(TRUE);
|
1996-01-23 01:02:17 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2004-03-14 11:11:17 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
DWORD
|
|
|
|
STDCALL
|
|
|
|
GetProcessId(HANDLE Process)
|
|
|
|
{
|
|
|
|
DWORD ProcessId;
|
|
|
|
|
|
|
|
if(!InternalGetProcessId(Process, &ProcessId))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return ProcessId;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2002-10-20 16:40:12 +00:00
|
|
|
HANDLE STDCALL
|
|
|
|
OpenProcess(DWORD dwDesiredAccess,
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL bInheritHandle,
|
2002-10-20 16:40:12 +00:00
|
|
|
DWORD dwProcessId)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
1999-01-16 21:03:00 +00:00
|
|
|
NTSTATUS errCode;
|
|
|
|
HANDLE ProcessHandle;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
CLIENT_ID ClientId ;
|
|
|
|
|
|
|
|
ClientId.UniqueProcess = (HANDLE)dwProcessId;
|
1999-06-09 15:50:16 +00:00
|
|
|
ClientId.UniqueThread = INVALID_HANDLE_VALUE;
|
|
|
|
|
1999-01-16 21:03:00 +00:00
|
|
|
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
|
|
|
ObjectAttributes.RootDirectory = (HANDLE)NULL;
|
|
|
|
ObjectAttributes.SecurityDescriptor = NULL;
|
|
|
|
ObjectAttributes.SecurityQualityOfService = NULL;
|
1999-06-09 15:50:16 +00:00
|
|
|
ObjectAttributes.ObjectName = NULL;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-06-09 15:50:16 +00:00
|
|
|
if (bInheritHandle == TRUE)
|
1999-01-16 21:03:00 +00:00
|
|
|
ObjectAttributes.Attributes = OBJ_INHERIT;
|
|
|
|
else
|
|
|
|
ObjectAttributes.Attributes = 0;
|
|
|
|
|
2000-02-19 19:37:13 +00:00
|
|
|
errCode = NtOpenProcess(&ProcessHandle,
|
|
|
|
dwDesiredAccess,
|
|
|
|
&ObjectAttributes,
|
1999-01-16 21:03:00 +00:00
|
|
|
&ClientId);
|
2000-02-19 19:37:13 +00:00
|
|
|
if (!NT_SUCCESS(errCode))
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
2000-04-25 23:22:57 +00:00
|
|
|
SetLastErrorByStatus (errCode);
|
1999-01-16 21:03:00 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return ProcessHandle;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2002-10-20 16:40:12 +00:00
|
|
|
UINT STDCALL
|
|
|
|
WinExec(LPCSTR lpCmdLine,
|
|
|
|
UINT uCmdShow)
|
1996-01-23 01:02:17 +00:00
|
|
|
{
|
1999-10-13 22:35:55 +00:00
|
|
|
STARTUPINFOA StartupInfo;
|
|
|
|
PROCESS_INFORMATION ProcessInformation;
|
1999-01-16 21:03:00 +00:00
|
|
|
DWORD dosErr;
|
2000-02-19 19:37:13 +00:00
|
|
|
|
2004-05-29 15:10:28 +00:00
|
|
|
RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
|
1999-10-13 22:35:55 +00:00
|
|
|
StartupInfo.cb = sizeof(STARTUPINFOA);
|
|
|
|
StartupInfo.wShowWindow = uCmdShow;
|
1999-01-16 21:03:00 +00:00
|
|
|
StartupInfo.dwFlags = 0;
|
1999-10-13 22:35:55 +00:00
|
|
|
|
2004-07-02 12:18:04 +00:00
|
|
|
if (! CreateProcessA(NULL,
|
|
|
|
(PVOID)lpCmdLine,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
FALSE,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&StartupInfo,
|
|
|
|
&ProcessInformation))
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
|
|
|
dosErr = GetLastError();
|
2004-07-02 12:18:04 +00:00
|
|
|
return dosErr < 32 ? dosErr : ERROR_BAD_FORMAT;
|
1999-01-16 21:03:00 +00:00
|
|
|
}
|
2000-04-25 23:22:57 +00:00
|
|
|
if (NULL != lpfnGlobalRegisterWaitForInputIdle)
|
2004-07-02 12:18:04 +00:00
|
|
|
{
|
|
|
|
lpfnGlobalRegisterWaitForInputIdle (
|
|
|
|
ProcessInformation.hProcess,
|
|
|
|
10000
|
2000-04-25 23:22:57 +00:00
|
|
|
);
|
2004-07-02 12:18:04 +00:00
|
|
|
}
|
|
|
|
NtClose(ProcessInformation.hProcess);
|
|
|
|
NtClose(ProcessInformation.hThread);
|
|
|
|
|
|
|
|
return 33; /* Something bigger than 31 means success. */
|
1996-01-23 01:02:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2002-10-20 16:40:12 +00:00
|
|
|
VOID STDCALL
|
1999-08-29 06:59:11 +00:00
|
|
|
RegisterWaitForInputIdle (
|
|
|
|
WaitForInputIdleType lpfnRegisterWaitForInputIdle
|
|
|
|
)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2000-03-16 01:14:58 +00:00
|
|
|
lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
|
1999-08-29 06:59:11 +00:00
|
|
|
return;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2002-10-20 16:40:12 +00:00
|
|
|
DWORD STDCALL
|
1999-08-29 06:59:11 +00:00
|
|
|
WaitForInputIdle (
|
2000-03-16 01:14:58 +00:00
|
|
|
HANDLE hProcess,
|
1999-08-29 06:59:11 +00:00
|
|
|
DWORD dwMilliseconds
|
|
|
|
)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
1999-08-29 06:59:11 +00:00
|
|
|
return 0;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2002-10-20 16:40:12 +00:00
|
|
|
VOID STDCALL
|
|
|
|
Sleep(DWORD dwMilliseconds)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
SleepEx(dwMilliseconds, FALSE);
|
|
|
|
return;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
2000-03-16 01:14:58 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2001-02-06 00:11:20 +00:00
|
|
|
DWORD STDCALL
|
2002-10-20 16:40:12 +00:00
|
|
|
SleepEx(DWORD dwMilliseconds,
|
|
|
|
BOOL bAlertable)
|
1996-01-23 01:02:17 +00:00
|
|
|
{
|
2001-02-06 00:11:20 +00:00
|
|
|
TIME Interval;
|
|
|
|
NTSTATUS errCode;
|
|
|
|
|
|
|
|
if (dwMilliseconds != INFINITE)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* System time units are 100 nanoseconds (a nanosecond is a billionth of
|
|
|
|
* a second).
|
|
|
|
*/
|
2003-09-21 14:02:30 +00:00
|
|
|
Interval.QuadPart = -((ULONGLONG)dwMilliseconds * 10000);
|
2001-02-06 00:11:20 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Approximately 292000 years hence */
|
2003-09-21 14:02:30 +00:00
|
|
|
Interval.QuadPart = -0x7FFFFFFFFFFFFFFFLL;
|
2001-02-06 00:11:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
errCode = NtDelayExecution (bAlertable, &Interval);
|
|
|
|
if (!NT_SUCCESS(errCode))
|
|
|
|
{
|
|
|
|
SetLastErrorByStatus (errCode);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
1996-01-23 01:02:17 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2000-12-28 20:38:28 +00:00
|
|
|
VOID STDCALL
|
|
|
|
GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
|
1996-01-23 01:02:17 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
PRTL_USER_PROCESS_PARAMETERS Params;
|
1999-10-13 22:35:55 +00:00
|
|
|
|
2002-10-20 16:40:12 +00:00
|
|
|
if (lpStartupInfo == NULL)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return;
|
|
|
|
}
|
1999-10-13 22:35:55 +00:00
|
|
|
|
2002-10-20 16:40:12 +00:00
|
|
|
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;
|
1996-01-23 01:02:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2000-12-28 20:38:28 +00:00
|
|
|
VOID STDCALL
|
|
|
|
GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
PRTL_USER_PROCESS_PARAMETERS Params;
|
|
|
|
ANSI_STRING AnsiString;
|
1999-10-13 22:35:55 +00:00
|
|
|
|
2002-10-20 16:40:12 +00:00
|
|
|
if (lpStartupInfo == NULL)
|
|
|
|
{
|
1999-04-10 12:08:24 +00:00
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
1998-12-04 18:28:13 +00:00
|
|
|
return;
|
2002-10-20 16:40:12 +00:00
|
|
|
}
|
1999-10-13 22:35:55 +00:00
|
|
|
|
2002-10-20 16:40:12 +00:00
|
|
|
Params = NtCurrentPeb ()->ProcessParameters;
|
1999-10-13 22:35:55 +00:00
|
|
|
|
2002-10-20 16:40:12 +00:00
|
|
|
RtlAcquirePebLock ();
|
2000-02-19 19:37:13 +00:00
|
|
|
|
2002-10-20 16:40:12 +00:00
|
|
|
if (lpLocalStartupInfo == NULL)
|
|
|
|
{
|
2000-02-19 19:37:13 +00:00
|
|
|
/* 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;
|
|
|
|
|
2002-10-20 16:40:12 +00:00
|
|
|
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;
|
2000-12-28 20:38:28 +00:00
|
|
|
lpLocalStartupInfo->cbReserved2 = Params->RuntimeInfo.Length;
|
|
|
|
lpLocalStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeInfo.Buffer;
|
2000-02-19 19:37:13 +00:00
|
|
|
|
2002-10-20 16:40:12 +00:00
|
|
|
lpLocalStartupInfo->hStdInput = Params->hStdInput;
|
|
|
|
lpLocalStartupInfo->hStdOutput = Params->hStdOutput;
|
|
|
|
lpLocalStartupInfo->hStdError = Params->hStdError;
|
1999-04-10 12:08:24 +00:00
|
|
|
}
|
2000-02-19 19:37:13 +00:00
|
|
|
|
|
|
|
RtlReleasePebLock ();
|
|
|
|
|
|
|
|
/* copy local startup info data to external startup info */
|
|
|
|
memcpy (lpStartupInfo,
|
|
|
|
lpLocalStartupInfo,
|
|
|
|
sizeof(STARTUPINFOA));
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2002-08-26 11:24:29 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
FlushInstructionCache (HANDLE hProcess,
|
|
|
|
LPCVOID lpBaseAddress,
|
|
|
|
DWORD dwSize)
|
1996-01-23 01:02:17 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
NTSTATUS Status;
|
2002-08-26 11:24:29 +00:00
|
|
|
|
2002-10-20 16:40:12 +00:00
|
|
|
Status = NtFlushInstructionCache(hProcess,
|
|
|
|
(PVOID)lpBaseAddress,
|
|
|
|
dwSize);
|
|
|
|
if (!NT_SUCCESS(Status))
|
2002-08-26 11:24:29 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
SetLastErrorByStatus(Status);
|
2002-08-26 11:24:29 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2002-08-26 11:24:29 +00:00
|
|
|
VOID STDCALL
|
2002-10-20 16:40:12 +00:00
|
|
|
ExitProcess(UINT uExitCode)
|
1999-05-11 15:28:11 +00:00
|
|
|
{
|
2002-08-26 11:24:29 +00:00
|
|
|
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))
|
|
|
|
{
|
|
|
|
DbgPrint("Failed to tell csrss about terminating process. "
|
|
|
|
"Expect trouble.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NtTerminateProcess (NtCurrentProcess (),
|
|
|
|
uExitCode);
|
My biggest commit so far (everything compiles and apparently runs fine):
- replaced DWORD with ULONG in a couple of places
- replaced some ULONGs with LONGs in the KD GDB stub
- replaced INITIAL_TEB with USER_STACK, as per Nebbet's book, to support both fixed size and expandable stacks
- added InterlockedExchangePointer
- added the ASM_BREAKPOINT macro as the architecture-dependent assembler code to raise a breakpoint exception
- corrected definitions of INT, LONG, DWORD, UINT, ULONG and ULONG32
- corrected IoSetCancelRoutine to use InterlockedExchangePointer
- corrected definition of NtCurrentTeb and NtCurrentPeb
- corrected DbgBreakPoint and DbgUserBreakPoint not to set up a stack frame (temporary fix with inline assembler - why doesn't GCC understand __declspec(naked)?)
- corrected various calls to Interlocked* functions to cast OUT operands to LONG *
- corrected various printf format strings
- corrected DbgUiIssueRemoteBreakin to use the smallest possible stack (this is what started everything)
- removed a DPRINT that accessed pageable memory at non-PASSIVE_LEVEL IRQL
- beautified CreateProcessA (another temporary fix - all the new functions will be isolated in the upcoming stand-alone RTL)
- prefixed LdrInitializeThunk with a nop that can be overwritten with a breakpoint for debugging purposes (temporary debugging aid until we have user-mode debugger support). Will add support for this to the breakin utility soon
- thread creation code rewritten from scratch (some glitches documented inline, but works fine)
- thread creation code now duplicated just twice, as opposed to five times (temporary fix - three new, non standard functions have been exported from NTDLL.DLL, will fix later)
svn path=/trunk/; revision=4595
2003-04-26 23:13:33 +00:00
|
|
|
|
|
|
|
/* should never get here */
|
|
|
|
assert(0);
|
|
|
|
while(1);
|
1999-05-11 15:28:11 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL STDCALL
|
2002-08-26 11:24:29 +00:00
|
|
|
TerminateProcess (HANDLE hProcess,
|
|
|
|
UINT uExitCode)
|
1999-05-11 15:28:11 +00:00
|
|
|
{
|
2002-10-20 16:40:12 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = NtTerminateProcess (hProcess, uExitCode);
|
2002-08-26 11:24:29 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
2001-08-15 20:35:39 +00:00
|
|
|
{
|
2002-08-26 11:24:29 +00:00
|
|
|
return TRUE;
|
2001-08-15 20:35:39 +00:00
|
|
|
}
|
2002-08-26 11:24:29 +00:00
|
|
|
SetLastErrorByStatus (Status);
|
|
|
|
return FALSE;
|
1996-01-23 01:02:17 +00:00
|
|
|
}
|
1998-10-05 04:01:30 +00:00
|
|
|
|
2000-03-16 01:14:58 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2002-08-26 11:24:29 +00:00
|
|
|
VOID STDCALL
|
|
|
|
FatalAppExitA (UINT uAction,
|
|
|
|
LPCSTR lpMessageText)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2002-08-26 11:24:29 +00:00
|
|
|
UNICODE_STRING MessageTextU;
|
|
|
|
ANSI_STRING MessageText;
|
|
|
|
|
|
|
|
RtlInitAnsiString (&MessageText, (LPSTR) lpMessageText);
|
2000-03-16 01:14:58 +00:00
|
|
|
|
2002-08-26 11:24:29 +00:00
|
|
|
RtlAnsiStringToUnicodeString (&MessageTextU,
|
|
|
|
&MessageText,
|
|
|
|
TRUE);
|
2000-03-16 01:14:58 +00:00
|
|
|
|
2002-08-26 11:24:29 +00:00
|
|
|
FatalAppExitW (uAction, MessageTextU.Buffer);
|
1999-10-13 22:35:55 +00:00
|
|
|
|
2002-08-26 11:24:29 +00:00
|
|
|
RtlFreeUnicodeString (&MessageTextU);
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2002-08-26 11:24:29 +00:00
|
|
|
VOID STDCALL
|
2002-10-20 16:40:12 +00:00
|
|
|
FatalAppExitW(UINT uAction,
|
|
|
|
LPCWSTR lpMessageText)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2002-08-26 11:24:29 +00:00
|
|
|
return;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
1999-08-29 06:59:11 +00:00
|
|
|
|
2000-04-25 23:22:57 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2002-08-26 11:24:29 +00:00
|
|
|
VOID STDCALL
|
|
|
|
FatalExit (int ExitCode)
|
2000-09-05 13:53:27 +00:00
|
|
|
{
|
2002-08-26 11:24:29 +00:00
|
|
|
ExitProcess(ExitCode);
|
2000-09-05 13:53:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2002-08-26 11:24:29 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
GetPriorityClass (HANDLE hProcess)
|
2000-04-25 23:22:57 +00:00
|
|
|
{
|
2002-08-26 11:24:29 +00:00
|
|
|
HANDLE hProcessTmp;
|
|
|
|
DWORD CsrPriorityClass = 0; // This tells CSRSS we want to GET it!
|
|
|
|
NTSTATUS Status;
|
2000-04-25 23:22:57 +00:00
|
|
|
|
2002-08-26 11:24:29 +00:00
|
|
|
Status =
|
|
|
|
NtDuplicateObject (GetCurrentProcess(),
|
|
|
|
hProcess,
|
|
|
|
GetCurrentProcess(),
|
|
|
|
&hProcessTmp,
|
|
|
|
(PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
|
2002-09-08 10:23:54 +00:00
|
|
|
FALSE,
|
2002-08-26 11:24:29 +00:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
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 */
|
|
|
|
}
|
|
|
|
SetLastError (ERROR_ACCESS_DENIED);
|
|
|
|
return (0); /* ERROR */
|
2000-04-25 23:22:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL STDCALL
|
2002-08-26 11:24:29 +00:00
|
|
|
SetPriorityClass (HANDLE hProcess,
|
|
|
|
DWORD dwPriorityClass)
|
2000-04-25 23:22:57 +00:00
|
|
|
{
|
2002-09-08 10:23:54 +00:00
|
|
|
HANDLE hProcessTmp;
|
2002-08-26 11:24:29 +00:00
|
|
|
DWORD CsrPriorityClass;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
switch (dwPriorityClass)
|
|
|
|
{
|
|
|
|
case NORMAL_PRIORITY_CLASS: /* 32 */
|
|
|
|
CsrPriorityClass = CSR_PRIORITY_CLASS_NORMAL;
|
|
|
|
break;
|
|
|
|
case IDLE_PRIORITY_CLASS: /* 64 */
|
|
|
|
CsrPriorityClass = CSR_PRIORITY_CLASS_IDLE;
|
|
|
|
break;
|
|
|
|
case HIGH_PRIORITY_CLASS: /* 128 */
|
|
|
|
CsrPriorityClass = CSR_PRIORITY_CLASS_HIGH;
|
|
|
|
break;
|
|
|
|
case REALTIME_PRIORITY_CLASS: /* 256 */
|
|
|
|
CsrPriorityClass = CSR_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);
|
2000-04-25 23:22:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2002-08-26 11:24:29 +00:00
|
|
|
DWORD STDCALL
|
2003-03-06 15:05:29 +00:00
|
|
|
GetProcessVersion (DWORD ProcessId)
|
2001-02-10 22:01:50 +00:00
|
|
|
{
|
2002-08-26 11:24:29 +00:00
|
|
|
DWORD Version = 0;
|
|
|
|
PIMAGE_NT_HEADERS NtHeader = NULL;
|
|
|
|
PVOID BaseAddress = NULL;
|
2001-02-10 22:01:50 +00:00
|
|
|
|
2002-08-26 11:24:29 +00:00
|
|
|
/* Caller's */
|
2003-03-06 15:05:29 +00:00
|
|
|
if (0 == ProcessId || GetCurrentProcessId() == ProcessId)
|
2002-08-26 11:24:29 +00:00
|
|
|
{
|
|
|
|
BaseAddress = (PVOID) NtCurrentPeb()->ImageBaseAddress;
|
|
|
|
NtHeader = RtlImageNtHeader (BaseAddress);
|
|
|
|
if (NULL != NtHeader)
|
2001-02-10 22:01:50 +00:00
|
|
|
{
|
2002-08-26 11:24:29 +00:00
|
|
|
Version =
|
|
|
|
(NtHeader->OptionalHeader.MajorOperatingSystemVersion << 16) |
|
|
|
|
(NtHeader->OptionalHeader.MinorOperatingSystemVersion);
|
2001-02-10 22:01:50 +00:00
|
|
|
}
|
2002-08-26 11:24:29 +00:00
|
|
|
}
|
|
|
|
else /* other process */
|
|
|
|
{
|
|
|
|
/* FIXME: open the other process */
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
}
|
|
|
|
return (Version);
|
2001-02-10 22:01:50 +00:00
|
|
|
}
|
|
|
|
|
2004-03-14 18:16:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @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;
|
|
|
|
}
|
|
|
|
|
2004-08-29 14:46:02 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @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;
|
|
|
|
}
|
|
|
|
|
1999-08-29 06:59:11 +00:00
|
|
|
/* EOF */
|