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__
;
28 extern HANDLE __ProcessHeap
;
31 /* FUNCTIONS *****************************************************************/
33 NTSTATUS
LdrMapNTDllForProcess(HANDLE ProcessHandle
,
34 PHANDLE PtrNTDllSectionHandle
)
36 ULONG InitialViewSize
;
38 HANDLE NTDllSectionHandle
;
40 PIMAGE_NT_HEADERS NTHeaders
;
41 PIMAGE_DOS_HEADER PEDosHeader
;
43 DPRINT("LdrMapNTDllForProcess(ProcessHandle %x)\n",ProcessHandle
);
45 PEDosHeader
= (PIMAGE_DOS_HEADER
)LdrDllListHead
.BaseAddress
;
46 NTHeaders
= (PIMAGE_NT_HEADERS
)(LdrDllListHead
.BaseAddress
+
47 PEDosHeader
->e_lfanew
);
49 NTDllSectionHandle
= LdrDllListHead
.SectionHandle
;
50 InitialViewSize
= PEDosHeader
->e_lfanew
+ sizeof(IMAGE_NT_HEADERS
)
51 + sizeof(IMAGE_SECTION_HEADER
) * NTHeaders
->FileHeader
.NumberOfSections
;
52 ImageBase
= LdrDllListHead
.BaseAddress
;
53 DPRINT("Mapping at %x\n",ImageBase
);
54 Status
= ZwMapViewOfSection(NTDllSectionHandle
,
64 LdrMapSections(ProcessHandle
,
68 *PtrNTDllSectionHandle
= NTDllSectionHandle
;
69 return(STATUS_SUCCESS
);
74 * Handles Process Startup Activities.
76 * DWORD ImageBase The base address of the process image
78 VOID
LdrStartup(HANDLE SectionHandle
,
80 HANDLE NTDllSectionHandle
)
83 PIMAGE_DOS_HEADER PEDosHeader
;
85 PIMAGE_NT_HEADERS NTHeaders
;
87 dprintf("LdrStartup(ImageBase %x, SectionHandle %x, "
88 "NTDllSectionHandle %x)\n",ImageBase
,
89 SectionHandle
, NTDllSectionHandle
);
91 LdrDllListHead
.BaseAddress
= (PVOID
)&_image_base__
;
92 LdrDllListHead
.Prev
= &LdrDllListHead
;
93 LdrDllListHead
.Next
= &LdrDllListHead
;
94 LdrDllListHead
.SectionHandle
= NTDllSectionHandle
;
95 PEDosHeader
= (PIMAGE_DOS_HEADER
)LdrDllListHead
.BaseAddress
;
96 LdrDllListHead
.Headers
= (PIMAGE_NT_HEADERS
)(LdrDllListHead
.BaseAddress
+
97 PEDosHeader
->e_lfanew
);
99 /* If MZ header exists */
100 PEDosHeader
= (PIMAGE_DOS_HEADER
) ImageBase
;
101 if (PEDosHeader
->e_magic
!= IMAGE_DOS_MAGIC
||
102 PEDosHeader
->e_lfanew
== 0L ||
103 *(PULONG
)((PUCHAR
)ImageBase
+ PEDosHeader
->e_lfanew
) != IMAGE_PE_MAGIC
)
105 DPRINT("Image has bad header\n");
106 ZwTerminateProcess(NULL
,STATUS_UNSUCCESSFUL
);
109 NTHeaders
= (PIMAGE_NT_HEADERS
)(ImageBase
+ PEDosHeader
->e_lfanew
);
110 __ProcessHeap
= RtlCreateHeap(0,
112 NTHeaders
->OptionalHeader
.SizeOfHeapCommit
,
113 NTHeaders
->OptionalHeader
.SizeOfHeapReserve
,
116 EntryPoint
= LdrPEStartup((PVOID
)ImageBase
, SectionHandle
);
118 if (EntryPoint
== NULL
)
120 dprintf("Failed to initialize image\n");
121 ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL
);
124 dprintf("Transferring control to image at %x\n",EntryPoint
);
125 Status
= EntryPoint();
126 ZwTerminateProcess(NtCurrentProcess(),Status
);