2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ldr/sysdll.c
5 * PURPOSE: Loaders for PE executables
6 * PROGRAMMERS: Jean Michault
7 * Rex Jolliff (rex@lvcablemodem.com)
10 * Skywing 09/11/2003 Added support for KiRaiseUserExceptionDispatcher
13 /* INCLUDES *****************************************************************/
17 #include <internal/debug.h>
19 /* GLOBALS *******************************************************************/
21 static PVOID SystemDllEntryPoint
= NULL
;
22 static PVOID SystemDllApcDispatcher
= NULL
;
23 static PVOID SystemDllCallbackDispatcher
= NULL
;
24 static PVOID SystemDllExceptionDispatcher
= NULL
;
25 static PVOID SystemDllRaiseExceptionDispatcher
= NULL
;
27 /* FUNCTIONS *****************************************************************/
29 PVOID
LdrpGetSystemDllExceptionDispatcher(VOID
)
31 return(SystemDllExceptionDispatcher
);
34 PVOID
LdrpGetSystemDllCallbackDispatcher(VOID
)
36 return(SystemDllCallbackDispatcher
);
39 PVOID
LdrpGetSystemDllEntryPoint(VOID
)
41 return(SystemDllEntryPoint
);
44 PVOID
LdrpGetSystemDllApcDispatcher(VOID
)
46 return(SystemDllApcDispatcher
);
49 PVOID
LdrpGetSystemDllRaiseExceptionDispatcher(VOID
)
51 return(SystemDllRaiseExceptionDispatcher
);
54 NTSTATUS
LdrpMapSystemDll(HANDLE ProcessHandle
,
55 PVOID
* LdrStartupAddr
)
57 * FUNCTION: LdrpMapSystemDll maps the system dll into the specified process
58 * address space and returns its startup address.
61 * Points to the process to map the system dll into
64 * Receives the startup address of the system dll on function
70 CHAR BlockBuffer
[1024];
74 OBJECT_ATTRIBUTES FileObjectAttributes
;
76 HANDLE NTDllSectionHandle
;
77 UNICODE_STRING DllPathname
= ROS_STRING_INITIALIZER(L
"\\SystemRoot\\system32\\ntdll.dll");
78 PIMAGE_DOS_HEADER DosHeader
;
79 PIMAGE_NT_HEADERS NTHeaders
;
81 ANSI_STRING ProcedureName
;
86 * Locate and open NTDLL to determine ImageBase
89 InitializeObjectAttributes(&FileObjectAttributes
,
94 DPRINT("Opening NTDLL\n");
95 Status
= ZwOpenFile(&FileHandle
,
97 &FileObjectAttributes
,
100 FILE_SYNCHRONOUS_IO_NONALERT
);
101 if (!NT_SUCCESS(Status
))
103 DbgPrint("NTDLL open failed (Status %x)\n", Status
);
106 Status
= ZwReadFile(FileHandle
,
115 if (!NT_SUCCESS(Status
) || Iosb
.Information
!= sizeof(BlockBuffer
))
117 DbgPrint("NTDLL header read failed (Status %x)\n", Status
);
123 * FIXME: this will fail if the NT headers are
124 * more than 1024 bytes from start.
126 DosHeader
= (PIMAGE_DOS_HEADER
) BlockBuffer
;
127 NTHeaders
= (PIMAGE_NT_HEADERS
) (BlockBuffer
+ DosHeader
->e_lfanew
);
128 if ((DosHeader
->e_magic
!= IMAGE_DOS_MAGIC
)
129 || (DosHeader
->e_lfanew
== 0L)
130 || (*(PULONG
) NTHeaders
!= IMAGE_PE_MAGIC
))
132 DbgPrint("NTDLL format invalid\n");
134 return(STATUS_UNSUCCESSFUL
);
136 ImageBase
= NTHeaders
->OptionalHeader
.ImageBase
;
137 ImageSize
= NTHeaders
->OptionalHeader
.SizeOfImage
;
140 * Create a section for NTDLL
142 DPRINT("Creating section\n");
143 Status
= ZwCreateSection(&NTDllSectionHandle
,
148 SEC_IMAGE
| SEC_COMMIT
,
150 if (!NT_SUCCESS(Status
))
152 DbgPrint("NTDLL create section failed (Status %x)\n", Status
);
159 * Map the NTDLL into the process
163 Status
= ZwMapViewOfSection(NTDllSectionHandle
,
173 if (!NT_SUCCESS(Status
))
175 DbgPrint("NTDLL map view of secion failed (Status %x)", Status
);
176 ZwClose(NTDllSectionHandle
);
180 DPRINT("Referencing process\n");
181 Status
= ObReferenceObjectByHandle(ProcessHandle
,
187 if (!NT_SUCCESS(Status
))
189 DbgPrint("ObReferenceObjectByProcess() failed (Status %x)\n", Status
);
193 DPRINT("Attaching to Process\n");
194 KeAttachProcess(Process
);
197 * retrieve ntdll's startup address
199 if (SystemDllEntryPoint
== NULL
)
201 RtlInitAnsiString (&ProcedureName
,
202 "LdrInitializeThunk");
203 Status
= LdrGetProcedureAddress ((PVOID
)ImageBase
,
206 &SystemDllEntryPoint
);
207 if (!NT_SUCCESS(Status
))
209 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status
);
211 ObDereferenceObject(Process
);
212 ZwClose(NTDllSectionHandle
);
215 *LdrStartupAddr
= SystemDllEntryPoint
;
219 * Retrieve the offset of the APC dispatcher from NTDLL
221 if (SystemDllApcDispatcher
== NULL
)
223 RtlInitAnsiString (&ProcedureName
,
224 "KiUserApcDispatcher");
225 Status
= LdrGetProcedureAddress ((PVOID
)ImageBase
,
228 &SystemDllApcDispatcher
);
229 if (!NT_SUCCESS(Status
))
231 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status
);
233 ObDereferenceObject(Process
);
234 ZwClose(NTDllSectionHandle
);
240 * Retrieve the offset of the exception dispatcher from NTDLL
242 if (SystemDllExceptionDispatcher
== NULL
)
244 RtlInitAnsiString (&ProcedureName
,
245 "KiUserExceptionDispatcher");
246 Status
= LdrGetProcedureAddress ((PVOID
)ImageBase
,
249 &SystemDllExceptionDispatcher
);
250 if (!NT_SUCCESS(Status
))
252 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status
);
254 ObDereferenceObject(Process
);
255 ZwClose(NTDllSectionHandle
);
261 * Retrieve the offset of the callback dispatcher from NTDLL
263 if (SystemDllCallbackDispatcher
== NULL
)
265 RtlInitAnsiString (&ProcedureName
,
266 "KiUserCallbackDispatcher");
267 Status
= LdrGetProcedureAddress ((PVOID
)ImageBase
,
270 &SystemDllCallbackDispatcher
);
271 if (!NT_SUCCESS(Status
))
273 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status
);
275 ObDereferenceObject(Process
);
276 ZwClose(NTDllSectionHandle
);
282 * Retrieve the offset of the raise exception dispatcher from NTDLL
284 if (SystemDllRaiseExceptionDispatcher
== NULL
)
286 RtlInitAnsiString (&ProcedureName
,
287 "KiRaiseUserExceptionDispatcher");
288 Status
= LdrGetProcedureAddress ((PVOID
)ImageBase
,
291 &SystemDllRaiseExceptionDispatcher
);
292 if (!NT_SUCCESS(Status
))
294 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status
);
296 ObDereferenceObject(Process
);
297 ZwClose(NTDllSectionHandle
);
303 ObDereferenceObject(Process
);
305 ZwClose(NTDllSectionHandle
);
307 return(STATUS_SUCCESS
);