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)
10 /* INCLUDES *****************************************************************/
12 #define WIN32_NO_PEHDR
14 #include <ddk/ntddk.h>
18 #include <ntdll/ldr.h>
19 #include <ntdll/rtl.h>
22 #include <ntdll/ntdll.h>
24 /* GLOBALS *******************************************************************/
27 extern unsigned int _image_base__
;
29 /* FUNCTIONS *****************************************************************/
31 NTSTATUS
LdrMapNTDllForProcess(HANDLE ProcessHandle
,
32 PHANDLE PtrNTDllSectionHandle
)
34 ULONG InitialViewSize
;
36 HANDLE NTDllSectionHandle
;
38 PIMAGE_NT_HEADERS NTHeaders
;
39 PIMAGE_DOS_HEADER PEDosHeader
;
41 DPRINT("LdrMapNTDllForProcess(ProcessHandle %x)\n",ProcessHandle
);
43 PEDosHeader
= (PIMAGE_DOS_HEADER
)LdrDllListHead
.BaseAddress
;
44 NTHeaders
= (PIMAGE_NT_HEADERS
)(LdrDllListHead
.BaseAddress
+
45 PEDosHeader
->e_lfanew
);
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
,
62 LdrMapSections(ProcessHandle
,
66 *PtrNTDllSectionHandle
= NTDllSectionHandle
;
67 return(STATUS_SUCCESS
);
72 * Handles Process Startup Activities.
74 * DWORD ImageBase The base address of the process image
76 VOID
LdrStartup(HANDLE SectionHandle
,
78 HANDLE NTDllSectionHandle
)
81 PIMAGE_DOS_HEADER PEDosHeader
;
83 PIMAGE_NT_HEADERS NTHeaders
;
85 dprintf("LdrStartup(ImageBase %x, SectionHandle %x, "
86 "NTDllSectionHandle %x)\n",ImageBase
,
87 SectionHandle
, NTDllSectionHandle
);
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
);
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
)
103 DPRINT("Image has bad header\n");
104 ZwTerminateProcess(NULL
,STATUS_UNSUCCESSFUL
);
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
);
113 if (EntryPoint
== NULL
)
115 DPRINT("Failed to initialize image\n");
116 ZwTerminateProcess(NULL
,STATUS_UNSUCCESSFUL
);
119 DPRINT("Transferring control to image at %x\n",EntryPoint
);
120 Status
= EntryPoint();
121 ZwTerminateProcess(NtCurrentProcess(),Status
);