diff --git a/reactos/include/ntos/rtl.h b/reactos/include/ntos/rtl.h index 6623ea51f6a..81034eefa8b 100755 --- a/reactos/include/ntos/rtl.h +++ b/reactos/include/ntos/rtl.h @@ -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 ( diff --git a/reactos/lib/ntdll/makefile b/reactos/lib/ntdll/makefile index 5286ac590e8..559c5224afd 100644 --- a/reactos/lib/ntdll/makefile +++ b/reactos/lib/ntdll/makefile @@ -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 diff --git a/reactos/lib/ntdll/rtl/process.c b/reactos/lib/ntdll/rtl/process.c index 760696fc352..04cac8dc09a 100644 --- a/reactos/lib/ntdll/rtl/process.c +++ b/reactos/lib/ntdll/rtl/process.c @@ -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); } diff --git a/reactos/lib/ntdll/rtl/teb.c b/reactos/lib/ntdll/rtl/teb.c index dc0c67ab19b..7aafca57e89 100644 --- a/reactos/lib/ntdll/rtl/teb.c +++ b/reactos/lib/ntdll/rtl/teb.c @@ -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 */ diff --git a/reactos/lib/rtl/makefile b/reactos/lib/rtl/makefile index 2a0f381d0c0..6987763c93e 100644 --- a/reactos/lib/rtl/makefile +++ b/reactos/lib/rtl/makefile @@ -20,6 +20,8 @@ TARGET_OBJECTS = \ acl.o \ ppb.o \ bit.o \ + thread.o \ + process.o \ bitmap.o \ bootdata.o \ compress.o \ diff --git a/reactos/lib/rtl/process.c b/reactos/lib/rtl/process.c new file mode 100644 index 00000000000..33b058c151e --- /dev/null +++ b/reactos/lib/rtl/process.c @@ -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 +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +/* 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 */ diff --git a/reactos/lib/ntdll/rtl/thread.c b/reactos/lib/rtl/thread.c similarity index 99% rename from reactos/lib/ntdll/rtl/thread.c rename to reactos/lib/rtl/thread.c index f92aacaab83..50780f010c8 100644 --- a/reactos/lib/ntdll/rtl/thread.c +++ b/reactos/lib/rtl/thread.c @@ -18,7 +18,6 @@ /* INCLUDES *****************************************************************/ -#define NTOS_MODE_USER #include #define NDEBUG diff --git a/reactos/ntoskrnl/ldr/init.c b/reactos/ntoskrnl/ldr/init.c index 7b0d5352fb7..aaddd443b46 100644 --- a/reactos/ntoskrnl/ldr/init.c +++ b/reactos/ntoskrnl/ldr/init.c @@ -11,540 +11,152 @@ /* INCLUDES *****************************************************************/ + #include + #define NDEBUG #include -/* 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 */ diff --git a/reactos/subsys/csrss/init.c b/reactos/subsys/csrss/init.c index a694ab7c40e..e8c0076da1f 100644 --- a/reactos/subsys/csrss/init.c +++ b/reactos/subsys/csrss/init.c @@ -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; } diff --git a/reactos/subsys/smss/smapiexec.c b/reactos/subsys/smss/smapiexec.c index f961c917c0e..7efc800b110 100644 --- a/reactos/subsys/smss/smapiexec.c +++ b/reactos/subsys/smss/smapiexec.c @@ -91,7 +91,7 @@ SmCreateUserProcess (LPWSTR ImagePath, return Status; } - NtResumeThread(pProcessInfo->ThreadHandle, NULL); + ZwResumeThread(pProcessInfo->ThreadHandle, NULL); /* Wait for process termination */