Added ZwQueryFileInformation
[reactos.git] / reactos / ntoskrnl / ldr / loader.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ldr/loader.c
5 * PURPOSE: Loaders for PE executables
6 * PROGRAMMER: David Welch (welch@mcmail.com)
7 * UPDATE HISTORY:
8 * Created 22/05/98
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <internal/kernel.h>
14 #include <internal/linkage.h>
15 #include <ddk/ntddk.h>
16
17 #include <internal/debug.h>
18 #include "pe.h"
19
20 /* FUNCTIONS *****************************************************************/
21
22 NTSTATUS LdrProcessImage(HANDLE SectionHandle, PVOID BaseAddress)
23 {
24 PIMAGE_DOS_HEADER dos_hdr = (PIMAGE_DOS_HEADER)BaseAddress;
25 PIMAGE_NT_HEADERS hdr = (PIMAGE_NT_HEADERS)(BaseAddress
26 + dos_hdr->e_lfanew);
27 PIMAGE_SECTION_HEADER sections = (PIMAGE_SECTION_HEADER)(BaseAddress
28 + dos_hdr->e_lfanew + sizeof(IMAGE_NT_HEADERS));
29
30 // FIXME: Check image signature
31 // FIXME: Check architechture
32 // FIXME: Build/Load image sections
33 // FIXME: resolve imports
34 // FIXME: do fixups
35
36 }
37
38 NTSTATUS LdrLoadDriver(PUNICODE_STRING FileName)
39 /*
40 * FUNCTION: Loads a PE executable into the kernel
41 * ARGUMENTS:
42 * FileName = Driver to load
43 * RETURNS: Status
44 */
45 {
46 NTSTATUS Status;
47 HANDLE FileHandle;
48 HANDLE SectionHandle;
49 ANSI_STRING AnsiFileName;
50 UNICODE_STRING UnicodeFileName;
51 OBJECT_ATTRIBUTES FileAttributes;
52 PVOID BaseAddress;
53
54 // Open the image file or die
55 RtlInitAnsiString(&AnsiFileName, FileName);
56 RtlAnsiStringToUnicodeString(&UnicodeFileName, &AnsiFileName, TRUE);
57 InitializeObjectAttributes(&FileAttributes,
58 &UnicodeFileName,
59 0,
60 NULL,
61 NULL);
62 FileHandle = ZwFileOpen(&FileHandle, 0, &FileAttributes, NULL, 0, 0);
63 if (!NT_SUCCESS(Status))
64 {
65 return Status;
66 }
67 RtlFreeUnicodeString(&UnicodeFileName);
68
69 // Map the image into a section or die
70 Status = ZwCreateSection(&SectionHandle,
71 SECTION_MAP_READ,
72 NULL,
73 NULL,
74 PAGE_READONLY,
75 SEC_IMAGE,
76 FileHandle);
77 if (!NT_SUCCESS(Status))
78 {
79 return Status;
80 }
81
82 // FIXME: get the base address of the section
83
84 ZwCloseFile(FileHandle);
85
86 return LdrProcessImage(SectionHandle, BaseAddress);
87 }
88
89 /*
90 * FUNCTION: Loads a PE executable into the specified process
91 * ARGUMENTS:
92 * Filename = File to load
93 * ProcessHandle = handle
94 * RETURNS: Status
95 */
96
97 NTSTATUS
98 LdrLoadImage(PUNICODE_STRING Filename, HANDLE ProcessHandle)
99 {
100 char BlockBuffer[512];
101 NTSTATUS Status;
102 HANDLE FileHandle;
103 OBJECT_ATTRIBUTES FileObjectAttributes;
104 PIMAGE_DOS_HEADER PEDosHeader;
105 PIMAGE_NT_HEADERS PEHeader;
106
107 HANDLE SectionHandle;
108 PVOID BaseAddress;
109
110 /* Open the image file */
111 InitializeObjectAttributes(&FileObjectAttributes,
112 &Filename,
113 0,
114 NULL,
115 NULL);
116 Status = ZwFileOpen(&FileHandle, 0, &FileObjectAttributes, NULL, 0, 0);
117 if (!NT_SUCCESS(Status))
118 {
119 return Status;
120 }
121
122 /* Read first block of image to determine type */
123 Status = ZwReadFile(FileHandle, 0, 0, 0, 0, BlockBuffer, 512, 0, 0);
124 if (!NT_SUCCESS(Status))
125 {
126 ZwClose(FileHandle);
127 return Status;
128 }
129
130 /* If MZ header exists */
131 PEDosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
132 if (PEDosHeader->e_magic == 0x54AD)
133 {
134 /* FIXME: if PE header exists */
135 /* FIXME: load PE image */
136 /* FIXME: else */
137 /* FIXME: load MZ image */
138 }
139 else /* Assume bin format and load */
140 /* FIXME: could check for a.out, ELF, COFF, etc. images here... */
141 {
142 Status = ZwCreateSection(&SectionHandle,
143 SECTION_ALL_ACCESS,
144 NULL,
145 NULL,
146 PAGE_READWRITE,
147 MEM_COMMIT,
148 FileHandle);
149 ZwClose(FileHandle);
150 if (!NT_SUCCESS(Status))
151 {
152 return Status;
153 }
154
155 BaseAddress = (PVOID)0x10000;
156 SectionOffset.HighPart = 0;
157 SectionOffset.LowPart = 0;
158
159 /* FIXME: get the size of the file */
160 Size = 0x8000;
161
162 ZwMapViewOfSection(SectionHandle,
163 ProcessHandle,
164 &BaseAddress,
165 0,
166 0x8000,
167 &SectionOffset,
168 &Size,
169 0,
170 MEM_COMMIT,
171 PAGE_READWRITE);
172
173 memset(&Context,0,sizeof(CONTEXT));
174
175 Context.SegSs = USER_DS;
176 Context.Esp = 0x2000;
177 Context.EFlags = 0x202;
178 Context.SegCs = USER_CS;
179 Context.Eip = 0x10000;
180 Context.SegDs = USER_DS;
181 Context.SegEs = USER_DS;
182 Context.SegFs = USER_DS;
183 Context.SegGs = USER_DS;
184
185 BaseAddress = 0x1000;
186 StackSize = 0x1000;
187 ZwAllocateVirtualMemory(ProcessHandle,
188 &BaseAddress,
189 0,
190 &StackSize,
191 MEM_COMMIT,
192 PAGE_READWRITE);
193 ZwCreateThread(&ThreadHandle,
194 THREAD_ALL_ACCESS,
195 NULL,
196 ShellHandle,
197 NULL,
198 &Context,
199 NULL,
200 FALSE);
201 }
202
203 /* FIXME: should DLLs be named sections? */
204 /* FIXME: get current process and associate with section */
205
206 // Map the image into a section or die
207 Status = ZwCreateSection(&SectionHandle,
208 SECTION_MAP_READ,
209 NULL,
210 NULL,
211 PAGE_READONLY,
212 SEC_IMAGE,
213 FileHandle);
214 if (!NT_SUCCESS(Status))
215 {
216 return Status;
217 }
218
219 // FIXME: get the base address of the section
220
221 ZwCloseFile(FileHandle);
222
223 // FIXME: initialize process context for image
224
225 return LdrProcessImage(SectionHandle, BaseAddress);
226 }
227