mirror of
https://github.com/reactos/reactos.git
synced 2025-06-15 07:38:30 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
495
sdk/lib/rtl/process.c
Normal file
495
sdk/lib/rtl/process.c
Normal file
|
@ -0,0 +1,495 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/rtl/process.c
|
||||
* PURPOSE: Process functions
|
||||
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
||||
* Ariadne (ariadne@xs4all.nl)
|
||||
* Eric Kohl
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <rtl.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* INTERNAL FUNCTIONS *******************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlpMapFile(PUNICODE_STRING ImageFileName,
|
||||
ULONG Attributes,
|
||||
PHANDLE Section)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
NTSTATUS Status;
|
||||
HANDLE hFile = NULL;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
/* Open the Image File */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
ImageFileName,
|
||||
Attributes & (OBJ_CASE_INSENSITIVE | OBJ_INHERIT),
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwOpenFile(&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(Status))
|
||||
{
|
||||
DPRINT1("Failed to read image file from disk, Status = 0x%08X\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Now create a section for this image */
|
||||
Status = ZwCreateSection(Section,
|
||||
SECTION_ALL_ACCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_EXECUTE,
|
||||
SEC_IMAGE,
|
||||
hFile);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to create section for image file, Status = 0x%08X\n", Status);
|
||||
}
|
||||
|
||||
ZwClose(hFile);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlpInitEnvironment(HANDLE ProcessHandle,
|
||||
PPEB Peb,
|
||||
PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PVOID BaseAddress = NULL;
|
||||
SIZE_T EnviroSize;
|
||||
SIZE_T Size;
|
||||
PWCHAR Environment = NULL;
|
||||
DPRINT("RtlpInitEnvironment(ProcessHandle: %p, Peb: %p Params: %p)\n",
|
||||
ProcessHandle, Peb, ProcessParameters);
|
||||
|
||||
/* Give the caller 1MB if he requested it */
|
||||
if (ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB)
|
||||
{
|
||||
/* Give 1MB starting at 0x4 */
|
||||
BaseAddress = (PVOID)4;
|
||||
EnviroSize = (1024 * 1024) - 256;
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||
&BaseAddress,
|
||||
0,
|
||||
&EnviroSize,
|
||||
MEM_RESERVE,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to reserve 1MB of space \n");
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the end of the Enviroment Block */
|
||||
if ((Environment = (PWCHAR)ProcessParameters->Environment))
|
||||
{
|
||||
while (*Environment++) while (*Environment++);
|
||||
|
||||
/* Calculate the size of the block */
|
||||
EnviroSize = (ULONG)((ULONG_PTR)Environment -
|
||||
(ULONG_PTR)ProcessParameters->Environment);
|
||||
|
||||
/* Allocate and Initialize new Environment Block */
|
||||
Size = EnviroSize;
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||
&BaseAddress,
|
||||
0,
|
||||
&Size,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to allocate Environment Block\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Write the Environment Block */
|
||||
ZwWriteVirtualMemory(ProcessHandle,
|
||||
BaseAddress,
|
||||
ProcessParameters->Environment,
|
||||
EnviroSize,
|
||||
NULL);
|
||||
|
||||
/* Save pointer */
|
||||
ProcessParameters->Environment = BaseAddress;
|
||||
}
|
||||
|
||||
/* Now allocate space for the Parameter Block */
|
||||
BaseAddress = NULL;
|
||||
Size = ProcessParameters->MaximumLength;
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||
&BaseAddress,
|
||||
0,
|
||||
&Size,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to allocate Parameter Block\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Write the Parameter Block */
|
||||
Status = ZwWriteVirtualMemory(ProcessHandle,
|
||||
BaseAddress,
|
||||
ProcessParameters,
|
||||
ProcessParameters->Length,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to write the Parameter Block\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Write pointer to Parameter Block */
|
||||
Status = ZwWriteVirtualMemory(ProcessHandle,
|
||||
&Peb->ProcessParameters,
|
||||
&BaseAddress,
|
||||
sizeof(BaseAddress),
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to write pointer to Parameter Block\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*
|
||||
* Creates a process and its initial thread.
|
||||
*
|
||||
* NOTES:
|
||||
* - The first thread is created suspended, so it needs a manual resume!!!
|
||||
* - If ParentProcess is NULL, current process is used
|
||||
* - ProcessParameters must be normalized
|
||||
* - Attributes are object attribute flags used when opening the ImageFileName.
|
||||
* Valid flags are OBJ_INHERIT and OBJ_CASE_INSENSITIVE.
|
||||
*
|
||||
* -Gunnar
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName,
|
||||
IN ULONG Attributes,
|
||||
IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
|
||||
IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL,
|
||||
IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
|
||||
IN HANDLE ParentProcess OPTIONAL,
|
||||
IN BOOLEAN InheritHandles,
|
||||
IN HANDLE DebugPort OPTIONAL,
|
||||
IN HANDLE ExceptionPort OPTIONAL,
|
||||
OUT PRTL_USER_PROCESS_INFORMATION ProcessInfo)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE hSection;
|
||||
PROCESS_BASIC_INFORMATION ProcessBasicInfo;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING DebugString = RTL_CONSTANT_STRING(L"\\WindowsSS");
|
||||
DPRINT("RtlCreateUserProcess: %wZ\n", ImageFileName);
|
||||
|
||||
/* Map and Load the File */
|
||||
Status = RtlpMapFile(ImageFileName,
|
||||
Attributes,
|
||||
&hSection);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Could not map process image\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Clean out the current directory handle if we won't use it */
|
||||
if (!InheritHandles) ProcessParameters->CurrentDirectory.Handle = NULL;
|
||||
|
||||
/* Use us as parent if none other specified */
|
||||
if (!ParentProcess) ParentProcess = NtCurrentProcess();
|
||||
|
||||
/* Initialize the Object Attributes */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
ProcessSecurityDescriptor);
|
||||
|
||||
/*
|
||||
* If FLG_ENABLE_CSRDEBUG is used, then CSRSS is created under the
|
||||
* watch of WindowsSS
|
||||
*/
|
||||
if ((RtlGetNtGlobalFlags() & FLG_ENABLE_CSRDEBUG) &&
|
||||
(wcsstr(ImageFileName->Buffer, L"csrss")))
|
||||
{
|
||||
ObjectAttributes.ObjectName = &DebugString;
|
||||
}
|
||||
|
||||
/* Create Kernel Process Object */
|
||||
Status = ZwCreateProcess(&ProcessInfo->ProcessHandle,
|
||||
PROCESS_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
ParentProcess,
|
||||
InheritHandles,
|
||||
hSection,
|
||||
DebugPort,
|
||||
ExceptionPort);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Could not create Kernel Process Object\n");
|
||||
ZwClose(hSection);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get some information on the image */
|
||||
Status = ZwQuerySection(hSection,
|
||||
SectionImageInformation,
|
||||
&ProcessInfo->ImageInformation,
|
||||
sizeof(SECTION_IMAGE_INFORMATION),
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Could not query Section Info\n");
|
||||
ZwClose(ProcessInfo->ProcessHandle);
|
||||
ZwClose(hSection);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get some information about the process */
|
||||
Status = ZwQueryInformationProcess(ProcessInfo->ProcessHandle,
|
||||
ProcessBasicInformation,
|
||||
&ProcessBasicInfo,
|
||||
sizeof(ProcessBasicInfo),
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Could not query Process Info\n");
|
||||
ZwClose(ProcessInfo->ProcessHandle);
|
||||
ZwClose(hSection);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Duplicate the standard handles */
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_TRY
|
||||
{
|
||||
if (ProcessParameters->StandardInput)
|
||||
{
|
||||
Status = ZwDuplicateObject(ParentProcess,
|
||||
ProcessParameters->StandardInput,
|
||||
ProcessInfo->ProcessHandle,
|
||||
&ProcessParameters->StandardInput,
|
||||
0,
|
||||
0,
|
||||
DUPLICATE_SAME_ACCESS |
|
||||
DUPLICATE_SAME_ATTRIBUTES);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ProcessParameters->StandardOutput)
|
||||
{
|
||||
Status = ZwDuplicateObject(ParentProcess,
|
||||
ProcessParameters->StandardOutput,
|
||||
ProcessInfo->ProcessHandle,
|
||||
&ProcessParameters->StandardOutput,
|
||||
0,
|
||||
0,
|
||||
DUPLICATE_SAME_ACCESS |
|
||||
DUPLICATE_SAME_ATTRIBUTES);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ProcessParameters->StandardError)
|
||||
{
|
||||
Status = ZwDuplicateObject(ParentProcess,
|
||||
ProcessParameters->StandardError,
|
||||
ProcessInfo->ProcessHandle,
|
||||
&ProcessParameters->StandardError,
|
||||
0,
|
||||
0,
|
||||
DUPLICATE_SAME_ACCESS |
|
||||
DUPLICATE_SAME_ATTRIBUTES);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ZwClose(ProcessInfo->ProcessHandle);
|
||||
ZwClose(hSection);
|
||||
}
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
/* Create Process Environment */
|
||||
Status = RtlpInitEnvironment(ProcessInfo->ProcessHandle,
|
||||
ProcessBasicInfo.PebBaseAddress,
|
||||
ProcessParameters);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Could not Create Process Environment\n");
|
||||
ZwClose(ProcessInfo->ProcessHandle);
|
||||
ZwClose(hSection);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Create the first Thread */
|
||||
Status = RtlCreateUserThread(ProcessInfo->ProcessHandle,
|
||||
ThreadSecurityDescriptor,
|
||||
TRUE,
|
||||
ProcessInfo->ImageInformation.ZeroBits,
|
||||
ProcessInfo->ImageInformation.MaximumStackSize,
|
||||
ProcessInfo->ImageInformation.CommittedStackSize,
|
||||
ProcessInfo->ImageInformation.TransferAddress,
|
||||
ProcessBasicInfo.PebBaseAddress,
|
||||
&ProcessInfo->ThreadHandle,
|
||||
&ProcessInfo->ClientId);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Could not Create Thread\n");
|
||||
ZwClose(ProcessInfo->ProcessHandle);
|
||||
ZwClose(hSection); /* Don't try to optimize this on top! */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Close the Section Handle and return */
|
||||
ZwClose(hSection);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PVOID
|
||||
NTAPI
|
||||
RtlEncodePointer(IN PVOID Pointer)
|
||||
{
|
||||
ULONG Cookie;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = ZwQueryInformationProcess(NtCurrentProcess(),
|
||||
ProcessCookie,
|
||||
&Cookie,
|
||||
sizeof(Cookie),
|
||||
NULL);
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to receive the process cookie! Status: 0x%lx\n", Status);
|
||||
return Pointer;
|
||||
}
|
||||
|
||||
return (PVOID)((ULONG_PTR)Pointer ^ Cookie);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PVOID
|
||||
NTAPI
|
||||
RtlDecodePointer(IN PVOID Pointer)
|
||||
{
|
||||
return RtlEncodePointer(Pointer);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PVOID
|
||||
NTAPI
|
||||
RtlEncodeSystemPointer(IN PVOID Pointer)
|
||||
{
|
||||
return (PVOID)((ULONG_PTR)Pointer ^ SharedUserData->Cookie);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PVOID
|
||||
NTAPI
|
||||
RtlDecodeSystemPointer(IN PVOID Pointer)
|
||||
{
|
||||
return RtlEncodeSystemPointer(Pointer);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*
|
||||
* NOTES:
|
||||
* Implementation based on the documentation from:
|
||||
* http://www.geoffchappell.com/studies/windows/win32/ntdll/api/rtl/peb/setprocessiscritical.htm
|
||||
*/
|
||||
NTSTATUS
|
||||
__cdecl
|
||||
RtlSetProcessIsCritical(IN BOOLEAN NewValue,
|
||||
OUT PBOOLEAN OldValue OPTIONAL,
|
||||
IN BOOLEAN NeedBreaks)
|
||||
{
|
||||
ULONG BreakOnTermination;
|
||||
|
||||
/* Initialize to FALSE */
|
||||
if (OldValue) *OldValue = FALSE;
|
||||
|
||||
/* Fail, if the critical breaks flag is required but is not set */
|
||||
if ((NeedBreaks) &&
|
||||
!(NtCurrentPeb()->NtGlobalFlag & FLG_ENABLE_SYSTEM_CRIT_BREAKS))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Check if the caller wants the old value */
|
||||
if (OldValue)
|
||||
{
|
||||
/* Query and return the old break on termination flag for the process */
|
||||
ZwQueryInformationProcess(NtCurrentProcess(),
|
||||
ProcessBreakOnTermination,
|
||||
&BreakOnTermination,
|
||||
sizeof(ULONG),
|
||||
NULL);
|
||||
*OldValue = (BOOLEAN)BreakOnTermination;
|
||||
}
|
||||
|
||||
/* Set the break on termination flag for the process */
|
||||
BreakOnTermination = NewValue;
|
||||
return ZwSetInformationProcess(NtCurrentProcess(),
|
||||
ProcessBreakOnTermination,
|
||||
&BreakOnTermination,
|
||||
sizeof(ULONG));
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
RtlGetCurrentProcessorNumber(VOID)
|
||||
{
|
||||
/* Forward to kernel */
|
||||
return NtGetCurrentProcessorNumber();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue