2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/ntdll/rtl/process.c
5 * PURPOSE: Process functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
11 /* INCLUDES ****************************************************************/
13 #define WIN32_NO_PEHDR
14 #include <ddk/ntddk.h>
18 #include <internal/i386/segment.h>
19 #include <ntdll/ldr.h>
20 #include <internal/teb.h>
21 #include <ntdll/base.h>
24 #include <ntdll/ntdll.h>
26 /* FUNCTIONS ****************************************************************/
29 #define STACK_TOP (0xb0000000)
32 RtlpCreateFirstThread(HANDLE ProcessHandle
,
33 PSECURITY_DESCRIPTOR SecurityDescriptor
,
35 LPTHREAD_START_ROUTINE lpStartAddress
,
37 DWORD dwCreationFlags
,
40 HANDLE NTDllSectionHandle
,
46 OBJECT_ATTRIBUTES ObjectAttributes
;
48 CONTEXT ThreadContext
;
49 INITIAL_TEB InitialTeb
;
50 BOOLEAN CreateSuspended
= FALSE
;
53 HANDLE DupNTDllSectionHandle
, DupSectionHandle
;
55 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
56 ObjectAttributes
.RootDirectory
= NULL
;
57 ObjectAttributes
.ObjectName
= NULL
;
58 ObjectAttributes
.Attributes
= 0;
59 // ObjectAttributes.Attributes = OBJ_INHERIT;
60 ObjectAttributes
.SecurityDescriptor
= SecurityDescriptor
;
61 ObjectAttributes
.SecurityQualityOfService
= NULL
;
63 if ((dwCreationFlags
& CREATE_SUSPENDED
) == CREATE_SUSPENDED
)
64 CreateSuspended
= TRUE
;
66 CreateSuspended
= FALSE
;
70 BaseAddress
= (PVOID
)(STACK_TOP
- dwStackSize
);
71 Status
= NtAllocateVirtualMemory(ProcessHandle
,
77 if (!NT_SUCCESS(Status
))
83 memset(&ThreadContext
,0,sizeof(CONTEXT
));
84 ThreadContext
.Eip
= (ULONG
)lpStartAddress
;
85 ThreadContext
.SegGs
= USER_DS
;
86 ThreadContext
.SegFs
= USER_DS
;
87 ThreadContext
.SegEs
= USER_DS
;
88 ThreadContext
.SegDs
= USER_DS
;
89 ThreadContext
.SegCs
= USER_CS
;
90 ThreadContext
.SegSs
= USER_DS
;
91 ThreadContext
.Esp
= STACK_TOP
- 16;
92 ThreadContext
.EFlags
= (1<<1) + (1<<9);
94 DPRINT("ThreadContext.Eip %x\n",ThreadContext
.Eip
);
96 NtDuplicateObject(NtCurrentProcess(),
102 DUPLICATE_SAME_ACCESS
);
103 NtDuplicateObject(NtCurrentProcess(),
106 &DupNTDllSectionHandle
,
109 DUPLICATE_SAME_ACCESS
);
111 NtWriteVirtualMemory(ProcessHandle
,
112 (PVOID
)(STACK_TOP
- 4),
113 &DupNTDllSectionHandle
,
114 sizeof(DupNTDllSectionHandle
),
116 NtWriteVirtualMemory(ProcessHandle
,
117 (PVOID
)(STACK_TOP
- 8),
121 NtWriteVirtualMemory(ProcessHandle
,
122 (PVOID
)(STACK_TOP
- 12),
124 sizeof(DupSectionHandle
),
128 Status
= NtCreateThread(&ThreadHandle
,
136 if ( lpThreadId
!= NULL
)
137 memcpy(lpThreadId
, &ClientId
.UniqueThread
,sizeof(ULONG
));
144 RtlpMapFile(PUNICODE_STRING ApplicationName
,
145 PIMAGE_NT_HEADERS Headers
,
146 PIMAGE_DOS_HEADER DosHeader
,
150 IO_STATUS_BLOCK IoStatusBlock
;
151 LARGE_INTEGER FileOffset
;
152 OBJECT_ATTRIBUTES ObjectAttributes
;
153 PSECURITY_DESCRIPTOR SecurityDescriptor
= NULL
;
160 DPRINT("ApplicationName %w\n", ApplicationName
->Buffer
);
162 InitializeObjectAttributes(&ObjectAttributes
,
164 OBJ_CASE_INSENSITIVE
,
169 * Try to open the executable
172 Status
= NtOpenFile(&hFile
,
173 SYNCHRONIZE
|FILE_EXECUTE
|FILE_READ_DATA
,
176 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
177 FILE_SYNCHRONOUS_IO_NONALERT
|FILE_NON_DIRECTORY_FILE
);
179 if (!NT_SUCCESS(Status
))
182 Status
= NtReadFile(hFile
,
188 sizeof(IMAGE_DOS_HEADER
),
191 if (!NT_SUCCESS(Status
))
194 FileOffset
.u
.LowPart
= DosHeader
->e_lfanew
;
195 FileOffset
.u
.HighPart
= 0;
197 Status
= NtReadFile(hFile
,
203 sizeof(IMAGE_NT_HEADERS
),
206 if (!NT_SUCCESS(Status
))
209 Status
= NtCreateSection(Section
,
218 if (!NT_SUCCESS(Status
))
221 return STATUS_SUCCESS
;
226 RtlpCreatePeb(HANDLE ProcessHandle
, PUNICODE_STRING CommandLine
)
233 PVOID StartupInfoBase
;
234 ULONG StartupInfoSize
;
235 PROCESSINFOW StartupInfo
;
237 PebBase
= (PVOID
)PEB_BASE
;
239 Status
= NtAllocateVirtualMemory(ProcessHandle
,
245 if (!NT_SUCCESS(Status
))
248 memset(&Peb
, 0, sizeof(Peb
));
249 Peb
.StartupInfo
= (PPROCESSINFOW
)PEB_STARTUPINFO
;
251 NtWriteVirtualMemory(ProcessHandle
,
257 StartupInfoBase
= (PVOID
)PEB_STARTUPINFO
;
258 StartupInfoSize
= 0x1000;
259 Status
= NtAllocateVirtualMemory(ProcessHandle
,
265 if (!NT_SUCCESS(Status
))
268 memset(&StartupInfo
, 0, sizeof(StartupInfo
));
269 wcscpy(StartupInfo
.CommandLine
, CommandLine
->Buffer
);
271 DPRINT("StartupInfoSize %x\n",StartupInfoSize
);
272 NtWriteVirtualMemory(ProcessHandle
,
273 (PVOID
)PEB_STARTUPINFO
,
278 return STATUS_SUCCESS
;
283 RtlCreateUserProcess(PUNICODE_STRING ApplicationName
,
284 PSECURITY_DESCRIPTOR ProcessSd
,
285 PSECURITY_DESCRIPTOR ThreadSd
,
286 WINBOOL bInheritHandles
,
287 DWORD dwCreationFlags
,
288 // LPVOID lpEnvironment,
289 // LPCWSTR lpCurrentDirectory,
290 // LPSTARTUPINFO lpStartupInfo,
292 PHANDLE ProcessHandle
,
293 PHANDLE ThreadHandle
)
295 HANDLE hSection
, hProcess
, hThread
;
297 LPTHREAD_START_ROUTINE lpStartAddress
= NULL
;
298 LPVOID lpParameter
= NULL
;
299 WCHAR TempCommandLine
[256];
301 LARGE_INTEGER SectionOffset
;
302 IMAGE_NT_HEADERS Headers
;
303 IMAGE_DOS_HEADER DosHeader
;
305 ULONG InitialViewSize
;
306 PROCESS_BASIC_INFORMATION ProcessBasicInfo
;
307 CLIENT_ID LocalClientId
;
310 DPRINT("RtlCreateUserProcess(ApplicationName '%w')\n",
311 ApplicationName
->Buffer
);
313 Status
= RtlpMapFile(ApplicationName
,
318 Status
= NtCreateProcess(&hProcess
,
327 NtQueryInformationProcess(hProcess
,
328 ProcessBasicInformation
,
330 sizeof(ProcessBasicInfo
),
332 DPRINT("ProcessBasicInfo.UniqueProcessId %d\n",
333 ProcessBasicInfo
.UniqueProcessId
);
334 LocalClientId
.UniqueProcess
= ProcessBasicInfo
.UniqueProcessId
;
337 * Map NT DLL into the process
339 Status
= LdrMapNTDllForProcess(hProcess
,
342 InitialViewSize
= DosHeader
.e_lfanew
+ sizeof(IMAGE_NT_HEADERS
)
343 + sizeof(IMAGE_SECTION_HEADER
) * Headers
.FileHeader
.NumberOfSections
;
345 BaseAddress
= (PVOID
)Headers
.OptionalHeader
.ImageBase
;
346 SectionOffset
.QuadPart
= 0;
347 Status
= NtMapViewOfSection(hSection
,
357 if (!NT_SUCCESS(Status
))
363 DPRINT("Creating peb\n");
364 RtlpCreatePeb(hProcess
, ApplicationName
);
366 DPRINT("Creating thread for process\n");
367 lpStartAddress
= (LPTHREAD_START_ROUTINE
)
368 ((PIMAGE_OPTIONAL_HEADER
)OPTHDROFFSET(NTDLL_BASE
))->
369 AddressOfEntryPoint
+
370 ((PIMAGE_OPTIONAL_HEADER
)OPTHDROFFSET(NTDLL_BASE
))->ImageBase
;
371 hThread
= RtlpCreateFirstThread(hProcess
,
373 Headers
.OptionalHeader
.SizeOfStackReserve
,
377 &LocalClientId
.UniqueThread
,
381 (PVOID
)Headers
.OptionalHeader
.ImageBase
);
383 if ( hThread
== NULL
)
388 ClientId
->UniqueProcess
= LocalClientId
.UniqueProcess
;
389 ClientId
->UniqueThread
= LocalClientId
.UniqueThread
;
393 *ProcessHandle
= hProcess
;
396 *ThreadHandle
= hThread
;
398 return STATUS_SUCCESS
;