-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
Modified: trunk/reactos/include/ntos/rtl.h
Modified: trunk/reactos/lib/ntdll/makefile
Modified: trunk/reactos/lib/ntdll/rtl/process.c
Modified: trunk/reactos/lib/ntdll/rtl/teb.c
Deleted: trunk/reactos/lib/ntdll/rtl/thread.c
Modified: trunk/reactos/lib/rtl/makefile
Added: trunk/reactos/lib/rtl/process.c
Added: trunk/reactos/lib/rtl/thread.c
Modified: trunk/reactos/ntoskrnl/ldr/init.c
Modified: trunk/reactos/subsys/csrss/init.c
Modified: trunk/reactos/subsys/smss/smapiexec.c

Modified: trunk/reactos/include/ntos/rtl.h
--- trunk/reactos/include/ntos/rtl.h	2005-04-02 00:11:50 UTC (rev 14429)
+++ trunk/reactos/include/ntos/rtl.h	2005-04-02 00:18:46 UTC (rev 14430)
@@ -379,6 +379,21 @@
 
 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 (
 	PUNICODE_STRING	Destination,
 	PCWSTR		Source

Modified: trunk/reactos/lib/ntdll/makefile
--- trunk/reactos/lib/ntdll/makefile	2005-04-02 00:11:50 UTC (rev 14429)
+++ trunk/reactos/lib/ntdll/makefile	2005-04-02 00:18:46 UTC (rev 14430)
@@ -23,7 +23,7 @@
   -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/rangelist.o \
 	rtl/resource.o \
 	rtl/teb.o \
-	rtl/thread.o \
 	rtl/timerqueue.o \
 	rtl/libsupp.o
 

Modified: trunk/reactos/lib/ntdll/rtl/process.c
--- trunk/reactos/lib/ntdll/rtl/process.c	2005-04-02 00:11:50 UTC (rev 14429)
+++ trunk/reactos/lib/ntdll/rtl/process.c	2005-04-02 00:18:46 UTC (rev 14430)
@@ -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 @@
     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)
+/*
+ * @implemented
+ */
+VOID STDCALL
+RtlAcquirePebLock(VOID)
 {
-   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);
+   PPEB Peb = NtCurrentPeb ();
+   Peb->FastPebLockRoutine (Peb->FastPebLock);
 }
 
+
 /*
  * @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
+RtlReleasePebLock(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;
-
-   /*
-    * 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);
+   PPEB Peb = NtCurrentPeb ();
+   Peb->FastPebUnlockRoutine (Peb->FastPebLock);
 }
 
 

Modified: trunk/reactos/lib/ntdll/rtl/teb.c
--- trunk/reactos/lib/ntdll/rtl/teb.c	2005-04-02 00:11:50 UTC (rev 14429)
+++ trunk/reactos/lib/ntdll/rtl/teb.c	2005-04-02 00:18:46 UTC (rev 14430)
@@ -14,25 +14,5 @@
 _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 */

Deleted: trunk/reactos/lib/ntdll/rtl/thread.c
--- trunk/reactos/lib/ntdll/rtl/thread.c	2005-04-02 00:11:50 UTC (rev 14429)
+++ trunk/reactos/lib/ntdll/rtl/thread.c	2005-04-02 00:18:46 UTC (rev 14430)
@@ -1,115 +0,0 @@
-/*
- * COPYRIGHT:         See COPYING in the top level directory
- * PROJECT:           ReactOS kernel
- * PURPOSE:           Rtl user thread functions
- * FILE:              lib/ntdll/rtl/thread.c
- * PROGRAMER:         Eric Kohl
- * REVISION HISTORY:
- *                    09/07/99: Created
- *                    09/10/99: Cleanup and full stack support.
- *                    25/04/03: Near rewrite. Made code more readable, replaced
- *                              INITIAL_TEB with USER_STACK, added support for
- *                              fixed-size stacks
- *                    28/04/03: Moved all code to a new statically linked
- *                              library (ROSRTL) so it can be shared with
- *                              kernel32.dll without exporting non-standard
- *                              functions from ntdll.dll
- */
-
-/* INCLUDES *****************************************************************/
-
-#define NTOS_MODE_USER
-#include <ntos.h>
-
-#define NDEBUG
-#include <ntdll/ntdll.h>
-
-/* FUNCTIONS ***************************************************************/
-
-/*
- @implemented
-*/
-NTSTATUS STDCALL RtlCreateUserThread
-(
- HANDLE ProcessHandle,
- PSECURITY_DESCRIPTOR SecurityDescriptor,
- BOOLEAN CreateSuspended,
- LONG StackZeroBits,
- PULONG StackReserve,
- PULONG StackCommit,
- PTHREAD_START_ROUTINE StartAddress,
- PVOID Parameter,
- PHANDLE ThreadHandle,
- PCLIENT_ID ClientId
-)
-{
- OBJECT_ATTRIBUTES oaThreadAttribs;
- 
- InitializeObjectAttributes
- (
-  &oaThreadAttribs,
-  NULL,
-  0,
-  NULL,
-  SecurityDescriptor
- );
- 
- return RtlRosCreateUserThread
- (
-  ProcessHandle,
-  &oaThreadAttribs,
-  CreateSuspended,
-  StackZeroBits,
-  StackReserve,
-  StackCommit,
-  StartAddress,
-  ThreadHandle,
-  ClientId,
-  1,
-  (ULONG_PTR *)&Parameter
- );
-}
-
-/*
- @implemented
-*/
-NTSTATUS STDCALL
-RtlInitializeContext(
-  IN HANDLE ProcessHandle,
-  OUT PCONTEXT ThreadContext,
-  IN PVOID ThreadStartParam  OPTIONAL,
-  IN PTHREAD_START_ROUTINE ThreadStartAddress,
-  IN PINITIAL_TEB InitialTeb)
-{
- return RtlRosInitializeContext
- (
-  ProcessHandle,
-  ThreadContext,
-  ThreadStartAddress,
-  InitialTeb,
-  1,
-  (ULONG_PTR *)&ThreadStartParam
- );
-}
-
-/*
- @implemented
-*/
-NTSTATUS STDCALL RtlFreeUserThreadStack
-(
- HANDLE ProcessHandle,
- HANDLE ThreadHandle
-)
-{
- return RtlRosFreeUserThreadStack(ProcessHandle, ThreadHandle);
-}
-
-/*
- @implemented
-*/
-NTSTATUS STDCALL RtlExitUserThread(NTSTATUS Status)
-{
- RtlRosExitUserThread(Status);
-}
-
-/* EOF */

Modified: trunk/reactos/lib/rtl/makefile
--- trunk/reactos/lib/rtl/makefile	2005-04-02 00:11:50 UTC (rev 14429)
+++ trunk/reactos/lib/rtl/makefile	2005-04-02 00:18:46 UTC (rev 14430)
@@ -20,6 +20,8 @@
 	acl.o \
 	ppb.o \
 	bit.o \
+	thread.o \
+	process.o \
 	bitmap.o \
 	bootdata.o \
 	compress.o \

Copied: trunk/reactos/lib/rtl/process.c (from rev 14394, trunk/reactos/lib/ntdll/rtl/process.c)
--- trunk/reactos/lib/ntdll/rtl/process.c	2005-03-31 19:54:03 UTC (rev 14394)
+++ trunk/reactos/lib/rtl/process.c	2005-04-02 00:18:46 UTC (rev 14430)
@@ -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 */

Copied: trunk/reactos/lib/rtl/thread.c (from rev 14394, trunk/reactos/lib/ntdll/rtl/thread.c)
--- trunk/reactos/lib/ntdll/rtl/thread.c	2005-03-31 19:54:03 UTC (rev 14394)
+++ trunk/reactos/lib/rtl/thread.c	2005-04-02 00:18:46 UTC (rev 14430)
@@ -0,0 +1,114 @@
+/*
+ * COPYRIGHT:         See COPYING in the top level directory
+ * PROJECT:           ReactOS kernel
+ * PURPOSE:           Rtl user thread functions
+ * FILE:              lib/ntdll/rtl/thread.c
+ * PROGRAMER:         Eric Kohl
+ * REVISION HISTORY:
+ *                    09/07/99: Created
+ *                    09/10/99: Cleanup and full stack support.
+ *                    25/04/03: Near rewrite. Made code more readable, replaced
+ *                              INITIAL_TEB with USER_STACK, added support for
+ *                              fixed-size stacks
+ *                    28/04/03: Moved all code to a new statically linked
+ *                              library (ROSRTL) so it can be shared with
+ *                              kernel32.dll without exporting non-standard
+ *                              functions from ntdll.dll
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntos.h>
+
+#define NDEBUG
+#include <ntdll/ntdll.h>
+
+/* FUNCTIONS ***************************************************************/
+
+/*
+ @implemented
+*/
+NTSTATUS STDCALL RtlCreateUserThread
+(
+ HANDLE ProcessHandle,
+ PSECURITY_DESCRIPTOR SecurityDescriptor,
+ BOOLEAN CreateSuspended,
+ LONG StackZeroBits,
+ PULONG StackReserve,
+ PULONG StackCommit,
+ PTHREAD_START_ROUTINE StartAddress,
+ PVOID Parameter,
+ PHANDLE ThreadHandle,
+ PCLIENT_ID ClientId
+)
+{
+ OBJECT_ATTRIBUTES oaThreadAttribs;
+ 
+ InitializeObjectAttributes
+ (
+  &oaThreadAttribs,
+  NULL,
+  0,
+  NULL,
+  SecurityDescriptor
+ );
+ 
+ return RtlRosCreateUserThread
+ (
+  ProcessHandle,
+  &oaThreadAttribs,
+  CreateSuspended,
+  StackZeroBits,
+  StackReserve,
+  StackCommit,
+  StartAddress,
+  ThreadHandle,
+  ClientId,
+  1,
+  (ULONG_PTR *)&Parameter
+ );
+}
+
+/*
+ @implemented
+*/
+NTSTATUS STDCALL
+RtlInitializeContext(
+  IN HANDLE ProcessHandle,
+  OUT PCONTEXT ThreadContext,
+  IN PVOID ThreadStartParam  OPTIONAL,
+  IN PTHREAD_START_ROUTINE ThreadStartAddress,
+  IN PINITIAL_TEB InitialTeb)
+{
+ return RtlRosInitializeContext
+ (
+  ProcessHandle,
+  ThreadContext,
+  ThreadStartAddress,
+  InitialTeb,
+  1,
+  (ULONG_PTR *)&ThreadStartParam
+ );
+}
+
+/*
+ @implemented
+*/
+NTSTATUS STDCALL RtlFreeUserThreadStack
+(
+ HANDLE ProcessHandle,
+ HANDLE ThreadHandle
+)
+{
+ return RtlRosFreeUserThreadStack(ProcessHandle, ThreadHandle);
+}
+
+/*
+ @implemented
+*/
+NTSTATUS STDCALL RtlExitUserThread(NTSTATUS Status)
+{
+ RtlRosExitUserThread(Status);
+}
+
+/* EOF */

Modified: trunk/reactos/ntoskrnl/ldr/init.c
--- trunk/reactos/ntoskrnl/ldr/init.c	2005-04-02 00:11:50 UTC (rev 14429)
+++ trunk/reactos/ntoskrnl/ldr/init.c	2005-04-02 00:18:46 UTC (rev 14430)
@@ -11,540 +11,152 @@
 
 /* INCLUDES *****************************************************************/
 
+
 #include <ntoskrnl.h>
+
 #define NDEBUG
 #include <internal/debug.h>
 
 
-/* MACROS ******************************************************************/
-
-#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)
+/* 
[truncated at 1000 lines; 660 more skipped]