Began improvements to memory managment, changed method of
[reactos.git] / reactos / lib / ntdll / ldr / startup.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: lib/ntdll/ldr/startup.c
5 * PURPOSE: Process startup for PE executables
6 * PROGRAMMERS: Jean Michault
7 * Rex Jolliff (rex@lvcablemodem.com)
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #define WIN32_NO_PEHDR
13 #include <windows.h>
14 #include <ddk/ntddk.h>
15 #include <pe.h>
16 #include <string.h>
17 #include <wchar.h>
18 #include <ntdll/ldr.h>
19 #include <ntdll/rtl.h>
20
21 #define NDEBUG
22 #include <ntdll/ntdll.h>
23
24 /* GLOBALS *******************************************************************/
25
26 DLL LdrDllListHead;
27 extern unsigned int _image_base__;
28
29 /* FUNCTIONS *****************************************************************/
30
31 NTSTATUS LdrMapNTDllForProcess(HANDLE ProcessHandle,
32 PHANDLE PtrNTDllSectionHandle)
33 {
34 ULONG InitialViewSize;
35 NTSTATUS Status;
36 HANDLE NTDllSectionHandle;
37 PVOID ImageBase;
38 PIMAGE_NT_HEADERS NTHeaders;
39 PIMAGE_DOS_HEADER PEDosHeader;
40
41 DPRINT("LdrMapNTDllForProcess(ProcessHandle %x)\n",ProcessHandle);
42
43 PEDosHeader = (PIMAGE_DOS_HEADER)LdrDllListHead.BaseAddress;
44 NTHeaders = (PIMAGE_NT_HEADERS)(LdrDllListHead.BaseAddress +
45 PEDosHeader->e_lfanew);
46
47 NTDllSectionHandle = LdrDllListHead.SectionHandle;
48 InitialViewSize = PEDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
49 + sizeof(IMAGE_SECTION_HEADER) * NTHeaders->FileHeader.NumberOfSections;
50 ImageBase = LdrDllListHead.BaseAddress;
51 DPRINT("Mapping at %x\n",ImageBase);
52 Status = ZwMapViewOfSection(NTDllSectionHandle,
53 ProcessHandle,
54 (PVOID *)&ImageBase,
55 0,
56 InitialViewSize,
57 NULL,
58 &InitialViewSize,
59 0,
60 MEM_COMMIT,
61 PAGE_READWRITE);
62 LdrMapSections(ProcessHandle,
63 ImageBase,
64 NTDllSectionHandle,
65 NTHeaders);
66 *PtrNTDllSectionHandle = NTDllSectionHandle;
67 return(STATUS_SUCCESS);
68 }
69
70 /* LdrStartup
71 * FUNCTION:
72 * Handles Process Startup Activities.
73 * ARGUMENTS:
74 * DWORD ImageBase The base address of the process image
75 */
76 VOID LdrStartup(HANDLE SectionHandle,
77 DWORD ImageBase,
78 HANDLE NTDllSectionHandle)
79 {
80 PEPFUNC EntryPoint;
81 PIMAGE_DOS_HEADER PEDosHeader;
82 NTSTATUS Status;
83 PIMAGE_NT_HEADERS NTHeaders;
84
85 dprintf("LdrStartup(ImageBase %x, SectionHandle %x, "
86 "NTDllSectionHandle %x)\n",ImageBase,
87 SectionHandle, NTDllSectionHandle);
88
89 LdrDllListHead.BaseAddress = (PVOID)&_image_base__;
90 LdrDllListHead.Prev = &LdrDllListHead;
91 LdrDllListHead.Next = &LdrDllListHead;
92 LdrDllListHead.SectionHandle = NTDllSectionHandle;
93 PEDosHeader = (PIMAGE_DOS_HEADER)LdrDllListHead.BaseAddress;
94 LdrDllListHead.Headers = (PIMAGE_NT_HEADERS)(LdrDllListHead.BaseAddress +
95 PEDosHeader->e_lfanew);
96
97 /* If MZ header exists */
98 PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
99 if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
100 PEDosHeader->e_lfanew == 0L ||
101 *(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_PE_MAGIC)
102 {
103 DPRINT("Image has bad header\n");
104 ZwTerminateProcess(NULL,STATUS_UNSUCCESSFUL);
105 }
106
107 NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + PEDosHeader->e_lfanew);
108 __RtlInitHeap((PVOID)HEAP_BASE,
109 NTHeaders->OptionalHeader.SizeOfHeapCommit,
110 NTHeaders->OptionalHeader.SizeOfHeapReserve);
111 EntryPoint = LdrPEStartup((PVOID)ImageBase, SectionHandle);
112
113 if (EntryPoint == NULL)
114 {
115 DPRINT("Failed to initialize image\n");
116 ZwTerminateProcess(NULL,STATUS_UNSUCCESSFUL);
117 }
118
119 DPRINT("Transferring control to image at %x\n",EntryPoint);
120 Status = EntryPoint();
121 ZwTerminateProcess(NtCurrentProcess(),Status);
122 }