*** empty log message ***
[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 extern HANDLE __ProcessHeap;
29
30
31 /* FUNCTIONS *****************************************************************/
32
33 NTSTATUS LdrMapNTDllForProcess(HANDLE ProcessHandle,
34 PHANDLE PtrNTDllSectionHandle)
35 {
36 ULONG InitialViewSize;
37 NTSTATUS Status;
38 HANDLE NTDllSectionHandle;
39 PVOID ImageBase;
40 PIMAGE_NT_HEADERS NTHeaders;
41 PIMAGE_DOS_HEADER PEDosHeader;
42
43 DPRINT("LdrMapNTDllForProcess(ProcessHandle %x)\n",ProcessHandle);
44
45 PEDosHeader = (PIMAGE_DOS_HEADER)LdrDllListHead.BaseAddress;
46 NTHeaders = (PIMAGE_NT_HEADERS)(LdrDllListHead.BaseAddress +
47 PEDosHeader->e_lfanew);
48
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,
55 ProcessHandle,
56 (PVOID *)&ImageBase,
57 0,
58 InitialViewSize,
59 NULL,
60 &InitialViewSize,
61 0,
62 MEM_COMMIT,
63 PAGE_READWRITE);
64 LdrMapSections(ProcessHandle,
65 ImageBase,
66 NTDllSectionHandle,
67 NTHeaders);
68 *PtrNTDllSectionHandle = NTDllSectionHandle;
69 return(STATUS_SUCCESS);
70 }
71
72 /* LdrStartup
73 * FUNCTION:
74 * Handles Process Startup Activities.
75 * ARGUMENTS:
76 * DWORD ImageBase The base address of the process image
77 */
78 VOID LdrStartup(HANDLE SectionHandle,
79 DWORD ImageBase,
80 HANDLE NTDllSectionHandle)
81 {
82 PEPFUNC EntryPoint;
83 PIMAGE_DOS_HEADER PEDosHeader;
84 NTSTATUS Status;
85 PIMAGE_NT_HEADERS NTHeaders;
86
87 dprintf("LdrStartup(ImageBase %x, SectionHandle %x, "
88 "NTDllSectionHandle %x)\n",ImageBase,
89 SectionHandle, NTDllSectionHandle);
90
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);
98
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)
104 {
105 DPRINT("Image has bad header\n");
106 ZwTerminateProcess(NULL,STATUS_UNSUCCESSFUL);
107 }
108
109 NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + PEDosHeader->e_lfanew);
110 __ProcessHeap = RtlCreateHeap(0,
111 (PVOID)HEAP_BASE,
112 NTHeaders->OptionalHeader.SizeOfHeapCommit,
113 NTHeaders->OptionalHeader.SizeOfHeapReserve,
114 NULL,
115 NULL);
116 EntryPoint = LdrPEStartup((PVOID)ImageBase, SectionHandle);
117
118 if (EntryPoint == NULL)
119 {
120 dprintf("Failed to initialize image\n");
121 ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
122 }
123
124 dprintf("Transferring control to image at %x\n",EntryPoint);
125 Status = EntryPoint();
126 ZwTerminateProcess(NtCurrentProcess(),Status);
127 }