mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
-move rtl thread/process stuff from ntdll to rtl and make ntoskrnl\ldr\init.c use those
-fix RtlCreateUserProcess to create the thread suspended and update all users of RtlCreateUserProcess to manually resume the thread svn path=/trunk/; revision=14430
This commit is contained in:
parent
c8e0c8df83
commit
95daa63b61
10 changed files with 469 additions and 814 deletions
|
@ -377,6 +377,21 @@ RemoveTailList(
|
|||
|
||||
#define RtlEqualMemory(Destination,Source,Length) (!memcmp((Destination), (Source), (Length)))
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlCreateUserThread (
|
||||
IN HANDLE ProcessHandle,
|
||||
IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||
IN BOOLEAN CreateSuspended,
|
||||
IN LONG StackZeroBits,
|
||||
IN OUT PULONG StackReserve,
|
||||
IN OUT PULONG StackCommit,
|
||||
IN PTHREAD_START_ROUTINE StartAddress,
|
||||
IN PVOID Parameter,
|
||||
IN OUT PHANDLE ThreadHandle,
|
||||
IN OUT PCLIENT_ID ClientId
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlAppendUnicodeToString (
|
||||
|
|
|
@ -23,7 +23,7 @@ TARGET_LFLAGS = -Wl,--file-alignment,0x1000 \
|
|||
-Wl,--section-alignment,0x1000 \
|
||||
-nostartfiles -nostdlib
|
||||
|
||||
TARGET_SDKLIBS = rosrtl.a rtl.a string.a
|
||||
TARGET_SDKLIBS = rtl.a rosrtl.a string.a
|
||||
|
||||
TARGET_GCCLIBS = gcc
|
||||
|
||||
|
@ -81,7 +81,6 @@ RTL_OBJECTS = \
|
|||
rtl/rangelist.o \
|
||||
rtl/resource.o \
|
||||
rtl/teb.o \
|
||||
rtl/thread.o \
|
||||
rtl/timerqueue.o \
|
||||
rtl/libsupp.o
|
||||
|
||||
|
|
|
@ -23,30 +23,6 @@
|
|||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static NTSTATUS RtlpCreateFirstThread
|
||||
(
|
||||
HANDLE ProcessHandle,
|
||||
ULONG StackReserve,
|
||||
ULONG StackCommit,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
PCLIENT_ID ClientId,
|
||||
PHANDLE ThreadHandle
|
||||
)
|
||||
{
|
||||
return RtlCreateUserThread
|
||||
(
|
||||
ProcessHandle,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
&StackReserve,
|
||||
&StackCommit,
|
||||
lpStartAddress,
|
||||
(PVOID)PEB_BASE,
|
||||
ThreadHandle,
|
||||
ClientId
|
||||
);
|
||||
}
|
||||
|
||||
PPEB
|
||||
STDCALL
|
||||
|
@ -55,273 +31,26 @@ RtlpCurrentPeb(VOID)
|
|||
return NtCurrentPeb();
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
RtlpMapFile(PUNICODE_STRING ImageFileName,
|
||||
PRTL_USER_PROCESS_PARAMETERS Ppb,
|
||||
ULONG Attributes,
|
||||
PHANDLE Section)
|
||||
{
|
||||
HANDLE hFile;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
hFile = NULL;
|
||||
|
||||
RtlDeNormalizeProcessParams (Ppb);
|
||||
|
||||
// DbgPrint("ImagePathName %x\n", Ppb->ImagePathName.Buffer);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
ImageFileName,
|
||||
Attributes & (OBJ_CASE_INSENSITIVE | OBJ_INHERIT),
|
||||
NULL,
|
||||
SecurityDescriptor);
|
||||
|
||||
RtlNormalizeProcessParams (Ppb);
|
||||
|
||||
/*
|
||||
* Try to open the executable
|
||||
*/
|
||||
|
||||
Status = 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(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
Status = NtCreateSection(Section,
|
||||
SECTION_ALL_ACCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_EXECUTE,
|
||||
SEC_IMAGE,
|
||||
hFile);
|
||||
NtClose(hFile);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
static NTSTATUS KlInitPeb (HANDLE ProcessHandle,
|
||||
PRTL_USER_PROCESS_PARAMETERS Ppb,
|
||||
PVOID* ImageBaseAddress)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PVOID PpbBase;
|
||||
ULONG PpbSize;
|
||||
ULONG BytesWritten;
|
||||
ULONG Offset;
|
||||
PVOID EnvPtr = NULL;
|
||||
ULONG EnvSize = 0;
|
||||
|
||||
/* create the Environment */
|
||||
if (Ppb->Environment != NULL)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION MemInfo;
|
||||
|
||||
Status = NtQueryVirtualMemory (NtCurrentProcess (),
|
||||
Ppb->Environment,
|
||||
MemoryBasicInformation,
|
||||
&MemInfo,
|
||||
sizeof(MEMORY_BASIC_INFORMATION),
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
EnvSize = MemInfo.RegionSize;
|
||||
}
|
||||
DPRINT("EnvironmentSize %ld\n", EnvSize);
|
||||
|
||||
/* allocate and initialize new environment block */
|
||||
if (EnvSize != 0)
|
||||
{
|
||||
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||
&EnvPtr,
|
||||
0,
|
||||
&EnvSize,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
NtWriteVirtualMemory(ProcessHandle,
|
||||
EnvPtr,
|
||||
Ppb->Environment,
|
||||
EnvSize,
|
||||
&BytesWritten);
|
||||
}
|
||||
DPRINT("EnvironmentPointer %p\n", EnvPtr);
|
||||
|
||||
/* create the PPB */
|
||||
PpbBase = NULL;
|
||||
PpbSize = Ppb->AllocationSize;
|
||||
|
||||
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||
&PpbBase,
|
||||
0,
|
||||
&PpbSize,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
DPRINT("Ppb->MaximumLength %x\n", Ppb->AllocationSize);
|
||||
|
||||
/* write process parameters block*/
|
||||
RtlDeNormalizeProcessParams (Ppb);
|
||||
NtWriteVirtualMemory(ProcessHandle,
|
||||
PpbBase,
|
||||
Ppb,
|
||||
Ppb->AllocationSize,
|
||||
|
||||
&BytesWritten);
|
||||
RtlNormalizeProcessParams (Ppb);
|
||||
|
||||
/* write pointer to environment */
|
||||
Offset = FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment);
|
||||
NtWriteVirtualMemory(ProcessHandle,
|
||||
(PVOID)(PpbBase + Offset),
|
||||
&EnvPtr,
|
||||
sizeof(EnvPtr),
|
||||
&BytesWritten);
|
||||
|
||||
/* write pointer to process parameter block */
|
||||
Offset = FIELD_OFFSET(PEB, ProcessParameters);
|
||||
NtWriteVirtualMemory(ProcessHandle,
|
||||
(PVOID)(PEB_BASE + Offset),
|
||||
&PpbBase,
|
||||
sizeof(PpbBase),
|
||||
&BytesWritten);
|
||||
|
||||
/* Read image base address. */
|
||||
Offset = FIELD_OFFSET(PEB, ImageBaseAddress);
|
||||
NtReadVirtualMemory(ProcessHandle,
|
||||
(PVOID)(PEB_BASE + Offset),
|
||||
ImageBaseAddress,
|
||||
sizeof(PVOID),
|
||||
&BytesWritten);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS STDCALL
|
||||
RtlCreateUserProcess(PUNICODE_STRING ImageFileName,
|
||||
ULONG Attributes,
|
||||
PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
|
||||
PSECURITY_DESCRIPTOR ProcessSecurityDescriptor,
|
||||
PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
|
||||
HANDLE ParentProcess,
|
||||
BOOLEAN CurrentDirectory,
|
||||
HANDLE DebugPort,
|
||||
HANDLE ExceptionPort,
|
||||
PRTL_PROCESS_INFO ProcessInfo)
|
||||
VOID STDCALL
|
||||
RtlAcquirePebLock(VOID)
|
||||
{
|
||||
HANDLE hSection;
|
||||
NTSTATUS Status;
|
||||
PROCESS_BASIC_INFORMATION ProcessBasicInfo;
|
||||
ULONG retlen;
|
||||
SECTION_IMAGE_INFORMATION Sii;
|
||||
ULONG ResultLength;
|
||||
PVOID ImageBaseAddress;
|
||||
|
||||
DPRINT("RtlCreateUserProcess\n");
|
||||
|
||||
Status = RtlpMapFile(ImageFileName,
|
||||
ProcessParameters,
|
||||
Attributes,
|
||||
&hSection);
|
||||
if( !NT_SUCCESS( Status ) )
|
||||
return Status;
|
||||
PPEB Peb = NtCurrentPeb ();
|
||||
Peb->FastPebLockRoutine (Peb->FastPebLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new process
|
||||
*/
|
||||
if (ParentProcess == NULL)
|
||||
ParentProcess = NtCurrentProcess();
|
||||
|
||||
Status = NtCreateProcess(&(ProcessInfo->ProcessHandle),
|
||||
PROCESS_ALL_ACCESS,
|
||||
NULL,
|
||||
ParentProcess,
|
||||
CurrentDirectory,
|
||||
hSection,
|
||||
DebugPort,
|
||||
ExceptionPort);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
NtClose(hSection);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get some information about the process
|
||||
*/
|
||||
NtQueryInformationProcess(ProcessInfo->ProcessHandle,
|
||||
ProcessBasicInformation,
|
||||
&ProcessBasicInfo,
|
||||
sizeof(ProcessBasicInfo),
|
||||
&retlen);
|
||||
DPRINT("ProcessBasicInfo.UniqueProcessId %d\n",
|
||||
ProcessBasicInfo.UniqueProcessId);
|
||||
ProcessInfo->ClientId.UniqueProcess = (HANDLE)ProcessBasicInfo.UniqueProcessId;
|
||||
|
||||
/*
|
||||
* Create Process Environment Block
|
||||
*/
|
||||
DPRINT("Creating peb\n");
|
||||
KlInitPeb(ProcessInfo->ProcessHandle,
|
||||
ProcessParameters,
|
||||
&ImageBaseAddress);
|
||||
|
||||
Status = NtQuerySection(hSection,
|
||||
SectionImageInformation,
|
||||
&Sii,
|
||||
sizeof(Sii),
|
||||
&ResultLength);
|
||||
if (!NT_SUCCESS(Status) || ResultLength != sizeof(Sii))
|
||||
{
|
||||
DPRINT("Failed to get section image information.\n");
|
||||
NtClose(hSection);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
DPRINT("Creating thread for process\n");
|
||||
Status = RtlpCreateFirstThread(ProcessInfo->ProcessHandle,
|
||||
Sii.StackReserve,
|
||||
Sii.StackCommit,
|
||||
ImageBaseAddress + (ULONG)Sii.EntryPoint,
|
||||
&ProcessInfo->ClientId,
|
||||
&ProcessInfo->ThreadHandle);
|
||||
|
||||
NtClose(hSection);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Failed to create thread\n");
|
||||
return(Status);
|
||||
}
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID STDCALL
|
||||
RtlReleasePebLock(VOID)
|
||||
{
|
||||
PPEB Peb = NtCurrentPeb ();
|
||||
Peb->FastPebUnlockRoutine (Peb->FastPebLock);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,25 +14,5 @@ PTEB STDCALL
|
|||
_NtCurrentTeb() { return NtCurrentTeb(); }
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID STDCALL
|
||||
RtlAcquirePebLock(VOID)
|
||||
{
|
||||
PPEB Peb = NtCurrentPeb ();
|
||||
Peb->FastPebLockRoutine (Peb->FastPebLock);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID STDCALL
|
||||
RtlReleasePebLock(VOID)
|
||||
{
|
||||
PPEB Peb = NtCurrentPeb ();
|
||||
Peb->FastPebUnlockRoutine (Peb->FastPebLock);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -20,6 +20,8 @@ TARGET_OBJECTS = \
|
|||
acl.o \
|
||||
ppb.o \
|
||||
bit.o \
|
||||
thread.o \
|
||||
process.o \
|
||||
bitmap.o \
|
||||
bootdata.o \
|
||||
compress.o \
|
||||
|
|
318
reactos/lib/rtl/process.c
Normal file
318
reactos/lib/rtl/process.c
Normal file
|
@ -0,0 +1,318 @@
|
|||
/* $Id$
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/ntdll/rtl/process.c
|
||||
* PURPOSE: Process functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <windows.h>
|
||||
#include <napi/i386/segment.h>
|
||||
#include <ntdll/ldr.h>
|
||||
#include <ntdll/base.h>
|
||||
#include <ntdll/rtl.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <ntdll/ntdll.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
RtlpMapFile(PUNICODE_STRING ImageFileName,
|
||||
PRTL_USER_PROCESS_PARAMETERS Ppb,
|
||||
ULONG Attributes,
|
||||
PHANDLE Section)
|
||||
{
|
||||
HANDLE hFile;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
hFile = NULL;
|
||||
|
||||
RtlDeNormalizeProcessParams (Ppb);
|
||||
|
||||
// DbgPrint("ImagePathName %x\n", Ppb->ImagePathName.Buffer);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
ImageFileName,
|
||||
Attributes & (OBJ_CASE_INSENSITIVE | OBJ_INHERIT),
|
||||
NULL,
|
||||
SecurityDescriptor);
|
||||
|
||||
RtlNormalizeProcessParams (Ppb);
|
||||
|
||||
/*
|
||||
* Try to open the executable
|
||||
*/
|
||||
|
||||
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))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
Status = ZwCreateSection(Section,
|
||||
SECTION_ALL_ACCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_EXECUTE,
|
||||
SEC_IMAGE,
|
||||
hFile);
|
||||
ZwClose(hFile);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
static NTSTATUS KlInitPeb (HANDLE ProcessHandle,
|
||||
PRTL_USER_PROCESS_PARAMETERS Ppb,
|
||||
PVOID* ImageBaseAddress)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PVOID PpbBase;
|
||||
ULONG PpbSize;
|
||||
ULONG BytesWritten;
|
||||
ULONG Offset;
|
||||
PVOID EnvPtr = NULL;
|
||||
ULONG EnvSize = 0;
|
||||
|
||||
/* create the Environment */
|
||||
if (Ppb->Environment != NULL)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION MemInfo;
|
||||
|
||||
Status = ZwQueryVirtualMemory (NtCurrentProcess (),
|
||||
Ppb->Environment,
|
||||
MemoryBasicInformation,
|
||||
&MemInfo,
|
||||
sizeof(MEMORY_BASIC_INFORMATION),
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
EnvSize = MemInfo.RegionSize;
|
||||
}
|
||||
DPRINT("EnvironmentSize %ld\n", EnvSize);
|
||||
|
||||
/* allocate and initialize new environment block */
|
||||
if (EnvSize != 0)
|
||||
{
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||
&EnvPtr,
|
||||
0,
|
||||
&EnvSize,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
ZwWriteVirtualMemory(ProcessHandle,
|
||||
EnvPtr,
|
||||
Ppb->Environment,
|
||||
EnvSize,
|
||||
&BytesWritten);
|
||||
}
|
||||
DPRINT("EnvironmentPointer %p\n", EnvPtr);
|
||||
|
||||
/* create the PPB */
|
||||
PpbBase = NULL;
|
||||
PpbSize = Ppb->AllocationSize;
|
||||
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||
&PpbBase,
|
||||
0,
|
||||
&PpbSize,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
DPRINT("Ppb->MaximumLength %x\n", Ppb->AllocationSize);
|
||||
|
||||
/* write process parameters block*/
|
||||
RtlDeNormalizeProcessParams (Ppb);
|
||||
ZwWriteVirtualMemory(ProcessHandle,
|
||||
PpbBase,
|
||||
Ppb,
|
||||
Ppb->AllocationSize,
|
||||
|
||||
&BytesWritten);
|
||||
RtlNormalizeProcessParams (Ppb);
|
||||
|
||||
/* write pointer to environment */
|
||||
Offset = FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment);
|
||||
ZwWriteVirtualMemory(ProcessHandle,
|
||||
(PVOID)(PpbBase + Offset),
|
||||
&EnvPtr,
|
||||
sizeof(EnvPtr),
|
||||
&BytesWritten);
|
||||
|
||||
/* write pointer to process parameter block */
|
||||
Offset = FIELD_OFFSET(PEB, ProcessParameters);
|
||||
ZwWriteVirtualMemory(ProcessHandle,
|
||||
(PVOID)(PEB_BASE + Offset),
|
||||
&PpbBase,
|
||||
sizeof(PpbBase),
|
||||
&BytesWritten);
|
||||
|
||||
/* Read image base address. */
|
||||
Offset = FIELD_OFFSET(PEB, ImageBaseAddress);
|
||||
ZwReadVirtualMemory(ProcessHandle,
|
||||
(PVOID)(PEB_BASE + Offset),
|
||||
ImageBaseAddress,
|
||||
sizeof(PVOID),
|
||||
&BytesWritten);
|
||||
|
||||
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 STDCALL
|
||||
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_PROCESS_INFO ProcessInfo
|
||||
)
|
||||
{
|
||||
HANDLE hSection;
|
||||
NTSTATUS Status;
|
||||
PROCESS_BASIC_INFORMATION ProcessBasicInfo;
|
||||
ULONG retlen;
|
||||
SECTION_IMAGE_INFORMATION Sii;
|
||||
ULONG ResultLength;
|
||||
PVOID ImageBaseAddress;
|
||||
|
||||
DPRINT("RtlCreateUserProcess\n");
|
||||
|
||||
Status = RtlpMapFile(ImageFileName,
|
||||
ProcessParameters,
|
||||
Attributes,
|
||||
&hSection);
|
||||
if( !NT_SUCCESS( Status ) )
|
||||
return Status;
|
||||
|
||||
/*
|
||||
* Create a new process
|
||||
*/
|
||||
if (ParentProcess == NULL)
|
||||
ParentProcess = NtCurrentProcess();
|
||||
|
||||
Status = ZwCreateProcess(&(ProcessInfo->ProcessHandle),
|
||||
PROCESS_ALL_ACCESS,
|
||||
NULL,
|
||||
ParentProcess,
|
||||
InheritHandles,
|
||||
hSection,
|
||||
DebugPort,
|
||||
ExceptionPort);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ZwClose(hSection);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get some information about the process
|
||||
*/
|
||||
ZwQueryInformationProcess(ProcessInfo->ProcessHandle,
|
||||
ProcessBasicInformation,
|
||||
&ProcessBasicInfo,
|
||||
sizeof(ProcessBasicInfo),
|
||||
&retlen);
|
||||
DPRINT("ProcessBasicInfo.UniqueProcessId %d\n",
|
||||
ProcessBasicInfo.UniqueProcessId);
|
||||
ProcessInfo->ClientId.UniqueProcess = (HANDLE)ProcessBasicInfo.UniqueProcessId;
|
||||
|
||||
/*
|
||||
* Create Process Environment Block
|
||||
*/
|
||||
DPRINT("Creating peb\n");
|
||||
KlInitPeb(ProcessInfo->ProcessHandle,
|
||||
ProcessParameters,
|
||||
&ImageBaseAddress);
|
||||
|
||||
Status = ZwQuerySection(hSection,
|
||||
SectionImageInformation,
|
||||
&Sii,
|
||||
sizeof(Sii),
|
||||
&ResultLength);
|
||||
if (!NT_SUCCESS(Status) || ResultLength != sizeof(Sii))
|
||||
{
|
||||
DPRINT("Failed to get section image information.\n");
|
||||
ZwClose(hSection);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
DPRINT("Creating thread for process\n");
|
||||
Status = RtlCreateUserThread(
|
||||
ProcessInfo->ProcessHandle,
|
||||
NULL,
|
||||
TRUE, /* CreateSuspended? */
|
||||
0,
|
||||
&Sii.StackReserve,
|
||||
&Sii.StackCommit,
|
||||
ImageBaseAddress + (ULONG)Sii.EntryPoint,
|
||||
(PVOID)PEB_BASE,
|
||||
&ProcessInfo->ThreadHandle,
|
||||
&ProcessInfo->ClientId
|
||||
);
|
||||
|
||||
ZwClose(hSection);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Failed to create thread\n");
|
||||
return(Status);
|
||||
}
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* EOF */
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#define NTOS_MODE_USER
|
||||
#include <ntos.h>
|
||||
|
||||
#define NDEBUG
|
|
@ -11,540 +11,152 @@
|
|||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
|
||||
/* MACROS ******************************************************************/
|
||||
/*
|
||||
* HACK! No matter what i did, i couldnt get it working when i put these into ntos\rtl.h
|
||||
* (got redefinition problems, since ntdll\rtl.h somehow include ntos\rtl.h).
|
||||
* We need to merge ntos\rtl.h and ntdll\rtl.h to get this working. -Gunnar
|
||||
*/
|
||||
typedef struct _RTL_PROCESS_INFO
|
||||
{
|
||||
ULONG Size;
|
||||
HANDLE ProcessHandle;
|
||||
HANDLE ThreadHandle;
|
||||
CLIENT_ID ClientId;
|
||||
SECTION_IMAGE_INFORMATION ImageInfo;
|
||||
} RTL_PROCESS_INFO, *PRTL_PROCESS_INFO;
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlCreateUserProcess (
|
||||
IN PUNICODE_STRING ImageFileName,
|
||||
IN ULONG Attributes,
|
||||
IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
|
||||
IN PSECURITY_DESCRIPTOR ProcessSecutityDescriptor OPTIONAL,
|
||||
IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
|
||||
IN HANDLE ParentProcess OPTIONAL,
|
||||
IN BOOLEAN CurrentDirectory,
|
||||
IN HANDLE DebugPort OPTIONAL,
|
||||
IN HANDLE ExceptionPort OPTIONAL,
|
||||
OUT PRTL_PROCESS_INFO ProcessInfo
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlCreateProcessParameters (
|
||||
OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
|
||||
IN PUNICODE_STRING ImagePathName OPTIONAL,
|
||||
IN PUNICODE_STRING DllPath OPTIONAL,
|
||||
IN PUNICODE_STRING CurrentDirectory OPTIONAL,
|
||||
IN PUNICODE_STRING CommandLine OPTIONAL,
|
||||
IN PWSTR Environment OPTIONAL,
|
||||
IN PUNICODE_STRING WindowTitle OPTIONAL,
|
||||
IN PUNICODE_STRING DesktopInfo OPTIONAL,
|
||||
IN PUNICODE_STRING ShellInfo OPTIONAL,
|
||||
IN PUNICODE_STRING RuntimeInfo OPTIONAL
|
||||
);
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlDestroyProcessParameters (
|
||||
IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters
|
||||
);
|
||||
|
||||
#define DENORMALIZE(x,addr) {if(x) x=(VOID*)((ULONG)(x)-(ULONG)(addr));}
|
||||
#define ALIGN(x,align) (((ULONG)(x)+(align)-1UL)&(~((align)-1UL)))
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static NTSTATUS
|
||||
LdrpMapProcessImage(PHANDLE SectionHandle,
|
||||
PUNICODE_STRING ImagePath)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HANDLE FileHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Open image file */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
ImagePath,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
DPRINT("Opening image file %S\n", ObjectAttributes.ObjectName->Buffer);
|
||||
Status = NtOpenFile(&FileHandle,
|
||||
FILE_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
0,
|
||||
FILE_SYNCHRONOUS_IO_ALERT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Create a section for the image */
|
||||
DPRINT("Creating section\n");
|
||||
Status = NtCreateSection(SectionHandle,
|
||||
SECTION_ALL_ACCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_READWRITE,
|
||||
SEC_COMMIT | SEC_IMAGE,
|
||||
FileHandle);
|
||||
NtClose(FileHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtCreateSection() failed (Status %lx)\n", Status);
|
||||
}
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
LdrpCreateProcessEnvironment(HANDLE ProcessHandle,
|
||||
PUNICODE_STRING ImagePath,
|
||||
PVOID* ImageBaseAddress)
|
||||
{
|
||||
PRTL_USER_PROCESS_PARAMETERS LocalPpb;
|
||||
PRTL_USER_PROCESS_PARAMETERS ProcessPpb;
|
||||
ULONG BytesWritten;
|
||||
ULONG Offset;
|
||||
ULONG Size;
|
||||
ULONG RegionSize;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Calculate the PPB size */
|
||||
Size = sizeof(RTL_USER_PROCESS_PARAMETERS);
|
||||
Size += ALIGN(ImagePath->Length + sizeof(WCHAR), sizeof(ULONG));
|
||||
RegionSize = ROUND_UP(Size, PAGE_SIZE);
|
||||
DPRINT("Size %lu RegionSize %lu\n", Size, RegionSize);
|
||||
|
||||
/* Allocate the local PPB */
|
||||
LocalPpb = NULL;
|
||||
Status = NtAllocateVirtualMemory(NtCurrentProcess(),
|
||||
(PVOID*)&LocalPpb,
|
||||
0,
|
||||
&RegionSize,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
DPRINT("LocalPpb %p AllocationSize %lu\n", LocalPpb, RegionSize);
|
||||
|
||||
/* Initialize the local PPB */
|
||||
RtlZeroMemory(LocalPpb,
|
||||
RegionSize);
|
||||
LocalPpb->AllocationSize = RegionSize;
|
||||
LocalPpb->Size = Size;
|
||||
LocalPpb->ImagePathName.Length = ImagePath->Length;
|
||||
LocalPpb->ImagePathName.MaximumLength = ImagePath->Length + sizeof(WCHAR);
|
||||
LocalPpb->ImagePathName.Buffer = (PWCHAR)(LocalPpb + 1);
|
||||
|
||||
/* Copy image path */
|
||||
RtlCopyMemory(LocalPpb->ImagePathName.Buffer,
|
||||
ImagePath->Buffer,
|
||||
ImagePath->Length);
|
||||
LocalPpb->ImagePathName.Buffer[ImagePath->Length / sizeof(WCHAR)] = L'\0';
|
||||
|
||||
/* Denormalize the process parameter block */
|
||||
DENORMALIZE(LocalPpb->ImagePathName.Buffer, LocalPpb);
|
||||
LocalPpb->Flags &= ~PPF_NORMALIZED;
|
||||
|
||||
/* Create the process PPB */
|
||||
ProcessPpb = NULL;
|
||||
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||
(PVOID*)&ProcessPpb,
|
||||
0,
|
||||
&RegionSize,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
|
||||
|
||||
/* Release the local PPB */
|
||||
RegionSize = 0;
|
||||
NtFreeVirtualMemory(NtCurrentProcess(),
|
||||
(PVOID*)&LocalPpb,
|
||||
&RegionSize,
|
||||
MEM_RELEASE);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Copy local PPB into the process PPB */
|
||||
NtWriteVirtualMemory(ProcessHandle,
|
||||
ProcessPpb,
|
||||
LocalPpb,
|
||||
LocalPpb->AllocationSize,
|
||||
&BytesWritten);
|
||||
|
||||
/* Update pointer to process PPB in the process PEB */
|
||||
Offset = FIELD_OFFSET(PEB, ProcessParameters);
|
||||
NtWriteVirtualMemory(ProcessHandle,
|
||||
(PVOID)(PEB_BASE + Offset),
|
||||
&ProcessPpb,
|
||||
sizeof(ProcessPpb),
|
||||
&BytesWritten);
|
||||
|
||||
/* Release local PPB */
|
||||
RegionSize = 0;
|
||||
NtFreeVirtualMemory(NtCurrentProcess(),
|
||||
(PVOID*)&LocalPpb,
|
||||
&RegionSize,
|
||||
MEM_RELEASE);
|
||||
|
||||
/* Read image base address. */
|
||||
Offset = FIELD_OFFSET(PEB, ImageBaseAddress);
|
||||
NtReadVirtualMemory(ProcessHandle,
|
||||
(PVOID)(PEB_BASE + Offset),
|
||||
ImageBaseAddress,
|
||||
sizeof(PVOID),
|
||||
&BytesWritten);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
FIXME: this sucks. Sucks sucks sucks. This code was duplicated, if you can
|
||||
believe it, in four different places - excluding this, and twice in the two
|
||||
DLLs that contained it (kernel32.dll and ntdll.dll). As much as I'd like to
|
||||
rip the whole RTL out of ntdll.dll and ntoskrnl.exe and into its own static
|
||||
library, ntoskrnl.exe is built separatedly from the rest of ReactOS, coming
|
||||
with its own linker scripts and specifications, and, save for changes and fixes
|
||||
to make it at least compile, I'm not going to touch any of it. If you feel
|
||||
brave enough, you're welcome [KJK::Hyperion]
|
||||
*/
|
||||
static NTSTATUS LdrpCreateStack
|
||||
(
|
||||
HANDLE ProcessHandle,
|
||||
PINITIAL_TEB InitialTeb,
|
||||
PULONG_PTR StackReserve,
|
||||
PULONG_PTR StackCommit
|
||||
)
|
||||
{
|
||||
PVOID pStackLowest = NULL;
|
||||
ULONG_PTR nSize = 0;
|
||||
NTSTATUS nErrCode;
|
||||
|
||||
if(StackReserve == NULL || StackCommit == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* FIXME: no SEH, no guard pages */
|
||||
*StackCommit = *StackReserve;
|
||||
|
||||
InitialTeb->StackBase = NULL;
|
||||
InitialTeb->StackLimit = NULL;
|
||||
InitialTeb->StackCommit = NULL;
|
||||
InitialTeb->StackCommitMax = NULL;
|
||||
InitialTeb->StackReserved = NULL;
|
||||
|
||||
/* FIXME: this code assumes a stack growing downwards */
|
||||
/* fixed stack */
|
||||
if(*StackCommit == *StackReserve)
|
||||
{
|
||||
DPRINT("Fixed stack\n");
|
||||
|
||||
InitialTeb->StackLimit = NULL;
|
||||
|
||||
/* allocate the stack */
|
||||
nErrCode = NtAllocateVirtualMemory
|
||||
(
|
||||
ProcessHandle,
|
||||
&(InitialTeb->StackLimit),
|
||||
0,
|
||||
StackReserve,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE
|
||||
);
|
||||
|
||||
/* failure */
|
||||
if(!NT_SUCCESS(nErrCode)) return nErrCode;
|
||||
|
||||
/* store the highest (first) address of the stack */
|
||||
InitialTeb->StackBase =
|
||||
(PUCHAR)(InitialTeb->StackLimit) + *StackReserve;
|
||||
}
|
||||
/* expandable stack */
|
||||
else
|
||||
{
|
||||
ULONG_PTR nGuardSize = PAGE_SIZE;
|
||||
PVOID pGuardBase;
|
||||
|
||||
DPRINT("Expandable stack\n");
|
||||
|
||||
InitialTeb->StackLimit = NULL;
|
||||
InitialTeb->StackBase = NULL;
|
||||
InitialTeb->StackReserved = NULL;
|
||||
|
||||
/* reserve the stack */
|
||||
nErrCode = NtAllocateVirtualMemory
|
||||
(
|
||||
ProcessHandle,
|
||||
&(InitialTeb->StackReserved),
|
||||
0,
|
||||
StackReserve,
|
||||
MEM_RESERVE,
|
||||
PAGE_READWRITE
|
||||
);
|
||||
|
||||
/* failure */
|
||||
if(!NT_SUCCESS(nErrCode)) return nErrCode;
|
||||
|
||||
DPRINT("Reserved %08X bytes\n", *StackReserve);
|
||||
|
||||
/* expandable stack base - the highest address of the stack */
|
||||
InitialTeb->StackCommit =
|
||||
(PUCHAR)(InitialTeb->StackReserved) + *StackReserve;
|
||||
|
||||
/* expandable stack limit - the lowest committed address of the stack */
|
||||
InitialTeb->StackCommitMax =
|
||||
(PUCHAR)(InitialTeb->StackCommit) - *StackCommit;
|
||||
|
||||
DPRINT("Stack commit %p\n", InitialTeb->StackCommit);
|
||||
DPRINT("Stack commit max %p\n", InitialTeb->StackCommitMax);
|
||||
|
||||
/* commit as much stack as requested */
|
||||
nErrCode = NtAllocateVirtualMemory
|
||||
(
|
||||
ProcessHandle,
|
||||
&(InitialTeb->StackCommitMax),
|
||||
0,
|
||||
StackCommit,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE
|
||||
);
|
||||
|
||||
/* failure */
|
||||
if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
|
||||
|
||||
DPRINT("Stack commit max %p\n", InitialTeb->StackCommitMax);
|
||||
|
||||
pGuardBase = (PUCHAR)(InitialTeb->StackCommitMax) - PAGE_SIZE;
|
||||
|
||||
DPRINT("Guard base %p\n", InitialTeb->StackCommit);
|
||||
|
||||
/* set up the guard page */
|
||||
nErrCode = NtAllocateVirtualMemory
|
||||
(
|
||||
ProcessHandle,
|
||||
&pGuardBase,
|
||||
0,
|
||||
&nGuardSize,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE | PAGE_GUARD
|
||||
);
|
||||
|
||||
/* failure */
|
||||
if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
|
||||
|
||||
DPRINT("Guard base %p\n", InitialTeb->StackCommit);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
/* cleanup in case of failure */
|
||||
l_Cleanup:
|
||||
if(InitialTeb->StackLimit)
|
||||
pStackLowest = InitialTeb->StackLimit;
|
||||
else if(InitialTeb->StackReserved)
|
||||
pStackLowest = InitialTeb->StackReserved;
|
||||
|
||||
/* free the stack, if it was allocated */
|
||||
if(pStackLowest != NULL)
|
||||
NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE);
|
||||
|
||||
return nErrCode;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS INIT_FUNCTION
|
||||
INIT_FUNCTION
|
||||
NTSTATUS
|
||||
LdrLoadInitialProcess(PHANDLE ProcessHandle,
|
||||
PHANDLE ThreadHandle)
|
||||
{
|
||||
SECTION_IMAGE_INFORMATION Sii;
|
||||
UNICODE_STRING ImagePath;
|
||||
HANDLE SectionHandle;
|
||||
CONTEXT Context;
|
||||
INITIAL_TEB InitialTeb;
|
||||
ULONG_PTR nStackReserve = 0;
|
||||
ULONG_PTR nStackCommit = 0;
|
||||
PVOID pStackLowest;
|
||||
PVOID pStackBase;
|
||||
ULONG ResultLength;
|
||||
PVOID ImageBaseAddress;
|
||||
ULONG InitialStack[5];
|
||||
HANDLE SystemProcessHandle;
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING ImagePath;
|
||||
HANDLE SystemProcessHandle;
|
||||
NTSTATUS Status;
|
||||
PRTL_USER_PROCESS_PARAMETERS Params=NULL;
|
||||
RTL_PROCESS_INFO Info;
|
||||
|
||||
/* Get the absolute path to smss.exe. */
|
||||
RtlRosInitUnicodeStringFromLiteral(&ImagePath,
|
||||
L"\\SystemRoot\\system32\\smss.exe");
|
||||
/* Get the absolute path to smss.exe. */
|
||||
RtlRosInitUnicodeStringFromLiteral(&ImagePath,
|
||||
L"\\SystemRoot\\system32\\smss.exe");
|
||||
|
||||
/* Map process image */
|
||||
Status = LdrpMapProcessImage(&SectionHandle,
|
||||
&ImagePath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("LdrpMapImage() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Get information about the process image. */
|
||||
Status = NtQuerySection(SectionHandle,
|
||||
SectionImageInformation,
|
||||
&Sii,
|
||||
sizeof(Sii),
|
||||
&ResultLength);
|
||||
if (!NT_SUCCESS(Status) || ResultLength != sizeof(Sii))
|
||||
{
|
||||
DPRINT("ZwQuerySection failed (Status %X)\n", Status);
|
||||
NtClose(ProcessHandle);
|
||||
NtClose(SectionHandle);
|
||||
return(Status);
|
||||
}
|
||||
Status = ObCreateHandle(
|
||||
PsGetCurrentProcess(),
|
||||
PsInitialSystemProcess,
|
||||
PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION,
|
||||
FALSE,
|
||||
&SystemProcessHandle
|
||||
);
|
||||
|
||||
Status = ObCreateHandle(PsGetCurrentProcess(),
|
||||
PsInitialSystemProcess,
|
||||
PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION,
|
||||
FALSE,
|
||||
&SystemProcessHandle);
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to create a handle for the system process!\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
Status = RtlCreateProcessParameters(
|
||||
&Params,
|
||||
&ImagePath,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to create a handle for the system process!\n");
|
||||
DPRINT1("Failed to create ppb!\n");
|
||||
ZwClose(SystemProcessHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
DPRINT("Creating process\n");
|
||||
Status = NtCreateProcess(ProcessHandle,
|
||||
PROCESS_ALL_ACCESS,
|
||||
NULL,
|
||||
SystemProcessHandle,
|
||||
FALSE,
|
||||
SectionHandle,
|
||||
NULL,
|
||||
NULL);
|
||||
NtClose(SectionHandle);
|
||||
NtClose(SystemProcessHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtCreateProcess() failed (Status %lx)\n", Status);
|
||||
DPRINT("Creating process\n");
|
||||
|
||||
Status = RtlCreateUserProcess(
|
||||
&ImagePath,
|
||||
OBJ_CASE_INSENSITIVE, //Valid are OBJ_INHERIT and OBJ_CASE_INSENSITIVE.
|
||||
Params,
|
||||
NULL,
|
||||
NULL,
|
||||
SystemProcessHandle,
|
||||
FALSE,
|
||||
NULL,
|
||||
NULL,
|
||||
&Info
|
||||
);
|
||||
|
||||
ZwClose(SystemProcessHandle);
|
||||
RtlDestroyProcessParameters(Params);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtCreateProcess() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create process environment */
|
||||
DPRINT("Creating the process environment\n");
|
||||
Status = LdrpCreateProcessEnvironment(*ProcessHandle,
|
||||
&ImagePath,
|
||||
&ImageBaseAddress);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("LdrpCreateProcessEnvironment() failed (Status %lx)\n", Status);
|
||||
NtClose(*ProcessHandle);
|
||||
return(Status);
|
||||
}
|
||||
DPRINT("ImageBaseAddress: %p\n", ImageBaseAddress);
|
||||
ZwResumeThread(Info.ThreadHandle, NULL);
|
||||
|
||||
*ProcessHandle = Info.ProcessHandle;
|
||||
*ThreadHandle= Info.ThreadHandle;
|
||||
|
||||
/* Calculate initial stack sizes */
|
||||
if (Sii.StackReserve > 0x100000)
|
||||
nStackReserve = Sii.StackReserve;
|
||||
else
|
||||
nStackReserve = 0x100000; /* 1MByte */
|
||||
DPRINT("Process created successfully\n");
|
||||
|
||||
/* FIXME */
|
||||
#if 0
|
||||
if (Sii.StackCommit > PAGE_SIZE)
|
||||
nStackCommit = Sii.StackCommit;
|
||||
else
|
||||
nStackCommit = PAGE_SIZE;
|
||||
#endif
|
||||
nStackCommit = nStackReserve - PAGE_SIZE;
|
||||
|
||||
DPRINT("StackReserve 0x%lX StackCommit 0x%lX\n",
|
||||
nStackReserve, nStackCommit);
|
||||
|
||||
|
||||
/* Create the process stack */
|
||||
Status = LdrpCreateStack
|
||||
(
|
||||
*ProcessHandle,
|
||||
&InitialTeb,
|
||||
&nStackReserve,
|
||||
&nStackCommit
|
||||
);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Failed to write initial stack.\n");
|
||||
NtClose(ProcessHandle);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
if(InitialTeb.StackBase && InitialTeb.StackLimit)
|
||||
{
|
||||
pStackBase = InitialTeb.StackBase;
|
||||
pStackLowest = InitialTeb.StackLimit;
|
||||
}
|
||||
else
|
||||
{
|
||||
pStackBase = InitialTeb.StackCommit;
|
||||
pStackLowest = InitialTeb.StackReserved;
|
||||
}
|
||||
|
||||
DPRINT("pStackBase = %p\n", pStackBase);
|
||||
DPRINT("pStackLowest = %p\n", pStackLowest);
|
||||
|
||||
/*
|
||||
* Initialize context to point to LdrStartup
|
||||
*/
|
||||
#if defined(_M_IX86)
|
||||
memset(&Context,0,sizeof(CONTEXT));
|
||||
Context.ContextFlags = CONTEXT_FULL;
|
||||
Context.FloatSave.ControlWord = 0xffff037f;
|
||||
Context.FloatSave.StatusWord = 0xffff0000;
|
||||
Context.FloatSave.TagWord = 0xffffffff;
|
||||
Context.FloatSave.DataSelector = 0xffff0000;
|
||||
Context.Eip = (ULONG_PTR)((char*)ImageBaseAddress + (ULONG_PTR)Sii.EntryPoint);
|
||||
Context.SegCs = USER_CS;
|
||||
Context.SegDs = USER_DS;
|
||||
Context.SegEs = USER_DS;
|
||||
Context.SegFs = TEB_SELECTOR;
|
||||
Context.SegGs = USER_DS;
|
||||
Context.SegSs = USER_DS;
|
||||
Context.EFlags = 0x202;
|
||||
Context.Esp = (ULONG_PTR)pStackBase - 20;
|
||||
#else
|
||||
#error Unsupported architecture
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Write in the initial stack.
|
||||
*/
|
||||
InitialStack[0] = 0;
|
||||
InitialStack[1] = PEB_BASE;
|
||||
Status = NtWriteVirtualMemory(*ProcessHandle,
|
||||
(PVOID)Context.Esp,
|
||||
InitialStack,
|
||||
sizeof(InitialStack),
|
||||
&ResultLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ULONG_PTR nSize = 0;
|
||||
|
||||
DPRINT("Failed to write initial stack.\n");
|
||||
|
||||
NtFreeVirtualMemory(*ProcessHandle,
|
||||
pStackLowest,
|
||||
&nSize,
|
||||
MEM_RELEASE);
|
||||
NtClose(*ProcessHandle);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Create initial thread */
|
||||
DPRINT("Creating thread for initial process\n");
|
||||
Status = NtCreateThread(ThreadHandle,
|
||||
THREAD_ALL_ACCESS,
|
||||
NULL,
|
||||
*ProcessHandle,
|
||||
NULL,
|
||||
&Context,
|
||||
&InitialTeb,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ULONG_PTR nSize = 0;
|
||||
|
||||
DPRINT("NtCreateThread() failed (Status %lx)\n", Status);
|
||||
|
||||
NtFreeVirtualMemory(*ProcessHandle,
|
||||
pStackLowest,
|
||||
&nSize,
|
||||
MEM_RELEASE);
|
||||
|
||||
NtClose(*ProcessHandle);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
DPRINT("Process created successfully\n");
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -480,9 +480,10 @@ CsrpRunWinlogon (ULONG argc, PWSTR* argv)
|
|||
RtlDestroyProcessParameters (ProcessParameters);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
|
||||
DPRINT1("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
|
||||
__FUNCTION__, Status);
|
||||
}
|
||||
ZwResumeThread(ProcessInfo.ThreadHandle, NULL);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ SmCreateUserProcess (LPWSTR ImagePath,
|
|||
return Status;
|
||||
}
|
||||
|
||||
NtResumeThread(pProcessInfo->ThreadHandle, NULL);
|
||||
ZwResumeThread(pProcessInfo->ThreadHandle, NULL);
|
||||
|
||||
|
||||
/* Wait for process termination */
|
||||
|
|
Loading…
Reference in a new issue