Added experimental paging out code (wouldn't activate until the system is
[reactos.git] / reactos / lib / ntdll / ldr / startup.c
1 /* $Id: startup.c,v 1.26 2000/07/06 14:34:49 dwelch Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: lib/ntdll/ldr/startup.c
6 * PURPOSE: Process startup for PE executables
7 * PROGRAMMERS: Jean Michault
8 * Rex Jolliff (rex@lvcablemodem.com)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <reactos/config.h>
14 #include <ddk/ntddk.h>
15 #include <windows.h>
16 #include <ntdll/ldr.h>
17 #include <ntdll/rtl.h>
18 #include <csrss/csrss.h>
19 #include <ntdll/csr.h>
20
21 #define NDEBUG
22 #include <ntdll/ntdll.h>
23
24
25 VOID RtlpInitProcessHeaps (PPEB Peb);
26
27 /* GLOBALS *******************************************************************/
28
29 DLL LdrDllListHead;
30 extern unsigned int _image_base__;
31
32 CRITICAL_SECTION PebLock;
33
34 ULONG NtGlobalFlag = 0;
35
36
37 /* FUNCTIONS *****************************************************************/
38
39 VOID LdrStartup(VOID)
40 {
41 PEPFUNC EntryPoint;
42 PIMAGE_DOS_HEADER PEDosHeader;
43 NTSTATUS Status;
44 PIMAGE_NT_HEADERS NTHeaders;
45 PVOID ImageBase;
46 PPEB Peb;
47
48 DPRINT("LdrStartup()\n");
49
50 LdrDllListHead.BaseAddress = (PVOID)&_image_base__;
51 LdrDllListHead.Prev = &LdrDllListHead;
52 LdrDllListHead.Next = &LdrDllListHead;
53 LdrDllListHead.SectionHandle = NULL;
54 PEDosHeader = (PIMAGE_DOS_HEADER)LdrDllListHead.BaseAddress;
55 LdrDllListHead.Headers = (PIMAGE_NT_HEADERS)(LdrDllListHead.BaseAddress +
56 PEDosHeader->e_lfanew);
57
58 Peb = (PPEB)(PEB_BASE);
59 DPRINT("Peb %x\n", Peb);
60 ImageBase = Peb->ImageBaseAddress;
61 DPRINT("ImageBase %x\n", ImageBase);
62 if (ImageBase <= (PVOID)0x1000)
63 {
64 DPRINT("ImageBase is null\n");
65 ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL);
66 }
67
68 NtGlobalFlag = Peb->NtGlobalFlag;
69
70 /* If MZ header exists */
71 PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
72 DPRINT("PEDosHeader %x\n", PEDosHeader);
73 if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
74 PEDosHeader->e_lfanew == 0L ||
75 *(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_PE_MAGIC)
76 {
77 DbgPrint("Image has bad header\n");
78 ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL);
79 }
80
81 /* normalize process parameters */
82 RtlNormalizeProcessParams (Peb->ProcessParameters);
83
84 #if 0
85 /* initialize NLS data */
86 RtlInitNlsTables (Peb->AnsiCodePageData,
87 Peb->OemCodePageData,
88 Peb->UnicodeCaseTableData,
89 &TranslationTable);
90 RtlResetRtlTranslations (&TranslationTable);
91 #endif
92
93 NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + PEDosHeader->e_lfanew);
94
95 /* create process heap */
96 Peb->ProcessHeap = RtlCreateHeap(0,
97 (PVOID)HEAP_BASE,
98 NTHeaders->OptionalHeader.SizeOfHeapCommit,
99 NTHeaders->OptionalHeader.SizeOfHeapReserve,
100 NULL,
101 NULL);
102 if (Peb->ProcessHeap == 0)
103 {
104 DbgPrint("Failed to create process heap\n");
105 ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
106 }
107
108 /* initialize process heaps support */
109 RtlpInitProcessHeaps (Peb);
110
111 /* initalize peb lock support */
112 RtlInitializeCriticalSection (&PebLock);
113 Peb->FastPebLock = &PebLock;
114 Peb->FastPebLockRoutine = RtlEnterCriticalSection;
115 Peb->FastPebUnlockRoutine = RtlLeaveCriticalSection;
116
117 EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL);
118 if (EntryPoint == NULL)
119 {
120 DbgPrint("Failed to initialize image\n");
121 ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
122 }
123
124 DbgPrint("Transferring control to image at %x\n",EntryPoint);
125 Status = EntryPoint(Peb);
126 ZwTerminateProcess(NtCurrentProcess(),Status);
127 }
128
129 /* EOF */