-/*
+/* $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
/* INCLUDES ****************************************************************/
-#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>
-#include <internal/i386/segment.h>
+#include <k32.h>
#define NDEBUG
-#include <kernel32/kernel32.h>
+#include "../include/debug.h"
-/* GLOBALS *****************************************************************/
-static NT_PEB CurrentPeb;
-static PROCESSINFOW ProcessInfo;
+/* GLOBALS *******************************************************************/
WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
-VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
+LPSTARTUPINFOA lpLocalStartupInfo = NULL;
-/* FUNCTIONS ****************************************************************/
+VOID STDCALL
+RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
-WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId);
+/* FUNCTIONS ****************************************************************/
-VOID InitializePeb(PWSTR CommandLine)
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetProcessAffinityMask (HANDLE hProcess,
+ LPDWORD lpProcessAffinityMask,
+ LPDWORD lpSystemAffinityMask)
{
- DPRINT("InitializePeb(CommandLine %x)\n",CommandLine);
-// DPRINT("ProcessInfo.CommandLine %x\n",ProcessInfo.CommandLine);
-// wcscpy(ProcessInfo.CommandLine, CommandLine);
- CurrentPeb.StartupInfo = &ProcessInfo;
+ 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;
}
-NT_PEB *GetCurrentPeb(VOID)
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetProcessAffinityMask (HANDLE hProcess,
+ DWORD dwProcessAffinityMask)
{
- return(&CurrentPeb);
+ NTSTATUS Status;
+
+ Status = NtSetInformationProcess (hProcess,
+ ProcessAffinityMask,
+ (PVOID)&dwProcessAffinityMask,
+ sizeof(DWORD));
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus (Status);
+ return FALSE;
+ }
+
+ return TRUE;
}
-HANDLE STDCALL GetCurrentProcess(VOID)
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetProcessShutdownParameters (LPDWORD lpdwLevel,
+ LPDWORD lpdwFlags)
{
- return (HANDLE)NtCurrentProcess();
+ 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);
}
-HANDLE STDCALL GetCurrentThread(VOID)
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetProcessShutdownParameters (DWORD dwLevel,
+ DWORD dwFlags)
{
- return (HANDLE)NtCurrentThread();
+ 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);
}
-DWORD STDCALL GetCurrentProcessId(VOID)
-{
- return (DWORD)(GetTeb()->Cid).UniqueProcess;
-}
-WINBOOL STDCALL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode )
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetProcessWorkingSetSize (HANDLE hProcess,
+ PSIZE_T lpMinimumWorkingSetSize,
+ PSIZE_T lpMaximumWorkingSetSize)
{
- 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;
+ 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 )
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetProcessWorkingSetSize(HANDLE hProcess,
+ SIZE_T dwMinimumWorkingSetSize,
+ SIZE_T dwMaximumWorkingSetSize)
{
- 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;
+ 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);
}
-PWSTR InternalAnsiToUnicode(PWSTR Out, LPCSTR In, ULONG MaxLength)
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetProcessTimes(HANDLE hProcess,
+ LPFILETIME lpCreationTime,
+ LPFILETIME lpExitTime,
+ LPFILETIME lpKernelTime,
+ LPFILETIME lpUserTime)
{
- ULONG i;
-
- if (In == NULL)
- {
- return(NULL);
- }
- else
- {
- i = 0;
- while ((*In)!=0 && i < MaxLength)
- {
- Out[i] = *In;
- In++;
- i++;
- }
- Out[i] = 0;
- return(Out);
- }
+ KERNEL_USER_TIMES Kut;
+ NTSTATUS Status;
+
+ Status = NtQueryInformationProcess(hProcess,
+ ProcessTimes,
+ &Kut,
+ sizeof(Kut),
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return(FALSE);
+ }
+
+ lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
+ lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
+
+ lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
+ lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
+
+ lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
+ lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
+
+ lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
+ lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
+
+ 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)
-/*
- * FUNCTION: The CreateProcess function creates a new process and its
- * primary thread. The new process executes the specified executable file
- * ARGUMENTS:
- *
- * lpApplicationName = Pointer to name of executable module
- * lpCommandLine = Pointer to command line string
- * lpProcessAttributes = Process security attributes
- * lpThreadAttributes = Thread security attributes
- * bInheritHandles = Handle inheritance flag
- * dwCreationFlags = Creation flags
- * lpEnvironment = Pointer to new environment block
- * lpCurrentDirectory = Pointer to current directory name
- * lpStartupInfo = Pointer to startup info
- * lpProcessInformation = Pointer to process information
- */
-{
- WCHAR ApplicationNameW[MAX_PATH];
- WCHAR CommandLineW[MAX_PATH];
- WCHAR CurrentDirectoryW[MAX_PATH];
- PWSTR PApplicationNameW;
- PWSTR PCommandLineW;
- PWSTR PCurrentDirectoryW;
- ULONG i;
-
- DPRINT("CreateProcessA\n");
-
- PApplicationNameW = InternalAnsiToUnicode(ApplicationNameW,
- lpApplicationName,
- MAX_PATH);
- PCommandLineW = InternalAnsiToUnicode(CommandLineW,
- lpCommandLine,
- MAX_PATH);
- PCurrentDirectoryW = InternalAnsiToUnicode(CurrentDirectoryW,
- lpCurrentDirectory,
- MAX_PATH);
- return CreateProcessW(PApplicationNameW,
- PCommandLineW,
- lpProcessAttributes,
- lpThreadAttributes,
- bInheritHandles,
- dwCreationFlags,
- lpEnvironment,
- PCurrentDirectoryW,
- lpStartupInfo,
- lpProcessInformation);
-}
-
-HANDLE STDCALL CreateFirstThread(HANDLE hProcess,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- DWORD dwStackSize,
- LPTHREAD_START_ROUTINE lpStartAddress,
- LPVOID lpParameter,
- DWORD dwCreationFlags,
- LPDWORD lpThreadId,
- PWSTR lpCommandLine)
-{
- NTSTATUS errCode;
- HANDLE ThreadHandle;
- OBJECT_ATTRIBUTES ObjectAttributes;
- CLIENT_ID ClientId;
- CONTEXT ThreadContext;
- INITIAL_TEB InitialTeb;
- BOOLEAN CreateSuspended = FALSE;
- ULONG BaseAddress;
- ULONG BytesWritten;
- ULONG Temp;
- ULONG CommandLineLen;
-
- if (lpCommandLine == NULL)
- {
- lpCommandLine = "";
- CommandLineLen = 1;
- }
- else
- {
- CommandLineLen = wcslen(lpCommandLine) + 1;
- }
- CommandLineLen = CommandLineLen * sizeof(WCHAR);
- CommandLineLen = (CommandLineLen & (~0x3)) + 4;
- DPRINT("CommandLineLen %d\n",CommandLineLen);
-
-
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
- ObjectAttributes.RootDirectory = NULL;
- ObjectAttributes.ObjectName = NULL;
- ObjectAttributes.Attributes = 0;
- if ( lpThreadAttributes != NULL ) {
- if ( lpThreadAttributes->bInheritHandle )
- ObjectAttributes.Attributes = OBJ_INHERIT;
- ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
- }
- ObjectAttributes.SecurityQualityOfService = NULL;
-
- if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED )
- CreateSuspended = TRUE;
- else
- CreateSuspended = FALSE;
-
- BaseAddress = 0;
- ZwAllocateVirtualMemory(hProcess,
- &BaseAddress,
- 0,
- &dwStackSize,
- MEM_COMMIT,
- PAGE_READWRITE);
-
- memset(&ThreadContext,0,sizeof(CONTEXT));
- ThreadContext.Eip = lpStartAddress;
- ThreadContext.SegGs = USER_DS;
- ThreadContext.SegFs = USER_DS;
- ThreadContext.SegEs = USER_DS;
- ThreadContext.SegDs = USER_DS;
- ThreadContext.SegCs = USER_CS;
- ThreadContext.SegSs = USER_DS;
- ThreadContext.Esp = BaseAddress + dwStackSize - CommandLineLen - 8;
- ThreadContext.EFlags = (1<<1) + (1<<9);
-
- NtWriteVirtualMemory(hProcess,
- BaseAddress + dwStackSize - CommandLineLen,
- lpCommandLine,
- CommandLineLen,
- &BytesWritten);
- Temp = BaseAddress + dwStackSize - CommandLineLen;
- NtWriteVirtualMemory(hProcess,
- BaseAddress + dwStackSize - CommandLineLen - 4,
- &Temp,
- sizeof(Temp),
- &BytesWritten);
-
- errCode = NtCreateThread(&ThreadHandle,
- THREAD_ALL_ACCESS,
- &ObjectAttributes,
- hProcess,
- &ClientId,
- &ThreadContext,
- &InitialTeb,
- CreateSuspended);
- if ( lpThreadId != NULL )
- memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
-
- return ThreadHandle;
+/*
+ * @implemented
+ */
+HANDLE STDCALL
+GetCurrentProcess(VOID)
+{
+ return((HANDLE)NtCurrentProcess());
}
-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)
+/*
+ * @implemented
+ */
+HANDLE STDCALL
+GetCurrentThread(VOID)
{
- 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;
- PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
- WCHAR TempApplicationName[256];
- WCHAR TempFileName[256];
- WCHAR TempDirectoryName[256];
- WCHAR TempCommandLine[256];
- ULONG i;
- ULONG BaseAddress;
- ULONG Size;
- LARGE_INTEGER SectionOffset;
-
- DPRINT("CreateProcessW(lpApplicationName '%w', lpCommandLine '%w')\n",
- lpApplicationName,lpCommandLine);
-
- wcscpy(TempCommandLine, lpCommandLine);
-
- hFile = NULL;
-
- /*
- * Find the application name
- */
- TempApplicationName[0] = '\\';
- TempApplicationName[1] = '?';
- TempApplicationName[2] = '?';
- TempApplicationName[3] = '\\';
- TempApplicationName[4] = 0;
-
- DPRINT("TempApplicationName '%w'\n",TempApplicationName);
-
- if (lpApplicationName != NULL)
- {
- wcscpy(TempFileName, lpApplicationName);
-
- DPRINT("TempFileName '%w'\n",TempFileName);
- }
- else
- {
- wcscpy(TempFileName, lpCommandLine);
-
- DPRINT("TempFileName '%w'\n",TempFileName);
-
- for (i=0; TempFileName[i]!=' ' && TempFileName[i] != 0; i++);
- TempFileName[i]=0;
-
- }
- if (TempFileName[1] != ':')
- {
- GetCurrentDirectoryW(MAX_PATH,TempDirectoryName);
- wcscat(TempApplicationName,TempDirectoryName);
- }
- wcscat(TempApplicationName,TempFileName);
-
- RtlInitUnicodeString(&ApplicationNameString, TempApplicationName);
-
- DPRINT("ApplicationName %w\n",ApplicationNameString.Buffer);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &ApplicationNameString,
- OBJ_CASE_INSENSITIVE,
- NULL,
- SecurityDescriptor);
-
- /*
- * Try to open the executable
- */
-
- errCode = NtOpenFile(&hFile,
- SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
- &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;
- }
+ return((HANDLE)NtCurrentThread());
+}
- errCode = NtCreateSection(&hSection,
- SECTION_ALL_ACCESS,
- NULL,
- NULL,
- PAGE_EXECUTE,
- SEC_IMAGE,
- hFile);
- NtClose(hFile);
- if ( !NT_SUCCESS(errCode) )
- {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
- }
-
- errCode = NtCreateProcess(&hProcess,
- PROCESS_ALL_ACCESS,
- NULL,
- NtCurrentProcess(),
- bInheritHandles,
- NULL,
- NULL,
- NULL);
-
- BaseAddress = (PVOID)0x10000;
- LARGE_INTEGER_QUAD_PART(SectionOffset) = 0;
- Size = 0x10000;
- NtMapViewOfSection(hSection,
- hProcess,
- &BaseAddress,
- 0,
- Size,
- &SectionOffset,
- &Size,
- 0,
- MEM_COMMIT,
- PAGE_READWRITE);
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetCurrentProcessId(VOID)
+{
+ return((DWORD)GetTeb()->Cid.UniqueProcess);
+}
-
- NtClose(hSection);
- if ( !NT_SUCCESS(errCode) )
- {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
+/*
+ * @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);
}
-
-#if 0
- PriorityClass = NORMAL_PRIORITY_CLASS;
- NtSetInformationProcess(hProcess,
- ProcessBasePriority,
- &PriorityClass,
- sizeof(KPRIORITY));
-#endif
-
- DPRINT("Creating thread for process\n");
- lpStartAddress = BaseAddress;
- hThread = CreateFirstThread(hProcess,
- lpThreadAttributes,
- 16384, // 3 page ??
- lpStartAddress,
- lpParameter,
- dwCreationFlags,
- &lpProcessInformation->dwThreadId,
- TempCommandLine);
-
- if ( hThread == NULL )
- return FALSE;
-
- lpProcessInformation->hProcess = hProcess;
- lpProcessInformation->hThread = hThread;
- GetProcessId(hProcess,&lpProcessInformation->dwProcessId);
+ memcpy(lpExitCode, &ProcessBasic.ExitStatus, sizeof(DWORD));
- return TRUE;
+ return(TRUE);
}
+/*
+ * @implemented
+ */
+DWORD
+STDCALL
+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;
+}
+
-HANDLE STDCALL OpenProcess(DWORD dwDesiredAccess,
- WINBOOL bInheritHandle,
- DWORD dwProcessId)
+/*
+ * @implemented
+ */
+HANDLE STDCALL
+OpenProcess(DWORD dwDesiredAccess,
+ 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;
+
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = (HANDLE)NULL;
ObjectAttributes.SecurityDescriptor = NULL;
ObjectAttributes.SecurityQualityOfService = NULL;
+ ObjectAttributes.ObjectName = NULL;
- if ( bInheritHandle == TRUE )
+ if (bInheritHandle == TRUE)
ObjectAttributes.Attributes = OBJ_INHERIT;
else
ObjectAttributes.Attributes = 0;
- errCode = NtOpenProcess(&ProcessHandle,
- dwDesiredAccess,
- &ObjectAttributes,
+ errCode = NtOpenProcess(&ProcessHandle,
+ dwDesiredAccess,
+ &ObjectAttributes,
&ClientId);
- if (!NT_SUCCESS(errCode))
+ if (!NT_SUCCESS(errCode))
{
- SetLastError(RtlNtStatusToDosError(errCode));
+ SetLastErrorByStatus (errCode);
return NULL;
}
return ProcessHandle;
}
-
-
-
-
-
-
-
-
-
-
-
-UINT WinExec (LPCSTR lpCmdLine, UINT uCmdShow)
+/*
+ * @implemented
+ */
+UINT STDCALL
+WinExec(LPCSTR lpCmdLine,
+ UINT uCmdShow)
{
- STARTUPINFO StartupInfo;
- PROCESS_INFORMATION ProcessInformation;
- HINSTANCE hInst;
+ STARTUPINFOA StartupInfo;
+ PROCESS_INFORMATION ProcessInformation;
DWORD dosErr;
- StartupInfo.cb = sizeof(STARTUPINFO);
- StartupInfo.wShowWindow = uCmdShow ;
+ 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
+ );
}
- if ( lpfnGlobalRegisterWaitForInputIdle != NULL )
- lpfnGlobalRegisterWaitForInputIdle(ProcessInformation.hProcess,10000);
NtClose(ProcessInformation.hProcess);
NtClose(ProcessInformation.hThread);
- return 0;
-}
+ return 33; /* Something bigger than 31 means success. */
+}
-VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle)
+/*
+ * @implemented
+ */
+VOID STDCALL
+RegisterWaitForInputIdle (
+ WaitForInputIdleType lpfnRegisterWaitForInputIdle
+ )
{
- lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
+ lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
return;
}
-DWORD STDCALL WaitForInputIdle(HANDLE hProcess,
- DWORD dwMilliseconds)
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+WaitForInputIdle (
+ HANDLE hProcess,
+ DWORD dwMilliseconds
+ )
{
- return 0;
+ return 0;
}
-VOID
-STDCALL
-Sleep(
- DWORD dwMilliseconds
- )
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+Sleep(DWORD dwMilliseconds)
+{
+ SleepEx(dwMilliseconds, FALSE);
+ return;
+}
+
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+SleepEx(DWORD dwMilliseconds,
+ BOOL bAlertable)
{
- SleepEx(dwMilliseconds,FALSE);
+ 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;
+}
+
+
+/*
+ * @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;
+}
+
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
+{
+ PRTL_USER_PROCESS_PARAMETERS Params;
+ ANSI_STRING AnsiString;
+
+ 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));
}
-DWORD
-STDCALL
-SleepEx(
- DWORD dwMilliseconds,
- BOOL bAlertable
- )
-{
- TIME Interval;
- NTSTATUS errCode;
-
- Interval.LowPart = dwMilliseconds * 1000;
- Interval.HighPart = 0;
- errCode = NtDelayExecution(bAlertable,&Interval);
- if ( !NT_SUCCESS(errCode) ) {
- SetLastError(RtlNtStatusToDosError(errCode));
- return -1;
- }
- return 0;
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+FlushInstructionCache (HANDLE hProcess,
+ LPCVOID lpBaseAddress,
+ DWORD dwSize)
+{
+ NTSTATUS Status;
+
+ Status = NtFlushInstructionCache(hProcess,
+ (PVOID)lpBaseAddress,
+ dwSize);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+ return TRUE;
}
+/*
+ * @implemented
+ */
+VOID STDCALL
+ExitProcess(UINT uExitCode)
+{
+ 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
-GetStartupInfoW(
- LPSTARTUPINFO lpStartupInfo
- )
+/*
+ * @implemented
+ */
+BOOL STDCALL
+TerminateProcess (HANDLE hProcess,
+ UINT uExitCode)
{
- NT_PEB *pPeb = GetCurrentPeb();
+ NTSTATUS Status;
+
+ Status = NtTerminateProcess (hProcess, uExitCode);
+ if (NT_SUCCESS(Status))
+ {
+ return TRUE;
+ }
+ SetLastErrorByStatus (Status);
+ return FALSE;
+}
- 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;
+/*
+ * @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
-GetStartupInfoA(
- LPSTARTUPINFO lpStartupInfo
- )
-{
- NT_PEB *pPeb = GetCurrentPeb();
- ULONG i = 0;
- if (lpStartupInfo == NULL ) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return;
- }
+/*
+ * @unimplemented
+ */
+VOID STDCALL
+FatalAppExitW(UINT uAction,
+ LPCWSTR lpMessageText)
+{
+ return;
+}
+
-
- lpStartupInfo->cb = sizeof(STARTUPINFO);
- i = 0;
+/*
+ * @implemented
+ */
+VOID STDCALL
+FatalExit (int ExitCode)
+{
+ ExitProcess(ExitCode);
+}
+
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetPriorityClass (HANDLE hProcess)
+{
+ NTSTATUS Status;
+ PROCESS_PRIORITY_CLASS PriorityClass;
- 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;
+ 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;
}
-BOOL
-STDCALL
-FlushInstructionCache(
+
+/*
+ * @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;
+}
- HANDLE hProcess,
- LPCVOID lpBaseAddress,
- DWORD dwSize
- )
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetProcessVersion (DWORD ProcessId)
{
- NTSTATUS errCode;
- errCode = NtFlushInstructionCache(hProcess,(PVOID)lpBaseAddress,dwSize);
- if ( !NT_SUCCESS(errCode) ) {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
+ 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);
}
- return TRUE;
+ }
+ else /* other process */
+ {
+ /* FIXME: open the other process */
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ }
+ return (Version);
}
-VOID STDCALL ExitProcess(UINT uExitCode)
-{
- NtTerminateProcess(NtCurrentProcess() ,uExitCode);
+
+/*
+ * @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;
}
-VOID
+
+/*
+ * @implemented
+ */
+BOOL
STDCALL
-FatalAppExitA(
- UINT uAction,
- LPCSTR lpMessageText
- )
+GetProcessPriorityBoost(HANDLE hProcess,
+ PBOOL pDisablePriorityBoost)
{
- 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);
+ 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 FatalAppExitW(UINT uAction, LPCWSTR lpMessageText)
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+SetProcessPriorityBoost(HANDLE hProcess,
+ BOOL bDisablePriorityBoost)
{
- return;
+ 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 */