2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: lib/ntdll/ldr/utils.c
5 * PURPOSE: Process startup for PE executables
6 * PROGRAMMERS: Jean Michault
7 * Rex Jolliff (rex@lvcablemodem.com)
13 * - Handle loading flags correctly
14 * - Handle errors correctly (unload dll's)
15 * - Implement a faster way to find modules (hash table)
19 /* INCLUDES *****************************************************************/
25 #define LDRP_PROCESS_CREATION_TIME 0xffff
26 #define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))
28 /* GLOBALS *******************************************************************/
31 #define TRACE_LDR(...) if (RtlGetNtGlobalFlags() & FLG_SHOW_LDR_SNAPS) { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(__VA_ARGS__); }
34 static BOOLEAN LdrpDllShutdownInProgress
= FALSE
;
35 static HANDLE LdrpKnownDllsDirHandle
= NULL
;
36 static UNICODE_STRING LdrpKnownDllPath
= {0, 0, NULL
};
37 static PLDR_DATA_TABLE_ENTRY LdrpLastModule
= NULL
;
38 extern PLDR_DATA_TABLE_ENTRY ExeModule
;
40 /* PROTOTYPES ****************************************************************/
42 static NTSTATUS
LdrFindEntryForName(PUNICODE_STRING Name
, PLDR_DATA_TABLE_ENTRY
*Module
, BOOLEAN Ref
);
43 static PVOID
LdrFixupForward(PCHAR ForwardName
);
44 static PVOID
LdrGetExportByName(PVOID BaseAddress
, PUCHAR SymbolName
, USHORT Hint
);
45 static NTSTATUS
LdrpLoadModule(IN PWSTR SearchPath OPTIONAL
,
47 IN PUNICODE_STRING Name
,
48 OUT PLDR_DATA_TABLE_ENTRY
*Module
,
49 OUT PVOID
*BaseAddress OPTIONAL
);
50 static NTSTATUS
LdrpAttachProcess(VOID
);
51 static VOID
LdrpDetachProcess(BOOLEAN UnloadAll
);
52 static NTSTATUS
LdrpUnloadModule(PLDR_DATA_TABLE_ENTRY Module
, BOOLEAN Unload
);
54 NTSTATUS
find_actctx_dll( LPCWSTR libname
, WCHAR
*fulldosname
);
55 NTSTATUS
create_module_activation_context( LDR_DATA_TABLE_ENTRY
*module
);
57 /* FUNCTIONS *****************************************************************/
60 LdrMappedAsDataFile(PVOID
*BaseAddress
)
62 if (0 != ((DWORD_PTR
) *BaseAddress
& (PAGE_SIZE
- 1)))
64 *BaseAddress
= (PVOID
)((DWORD_PTR
)*BaseAddress
& ~((DWORD_PTR
) PAGE_SIZE
- 1));
71 static __inline LONG
LdrpDecrementLoadCount(PLDR_DATA_TABLE_ENTRY Module
, BOOLEAN Locked
)
76 RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock
);
78 LoadCount
= Module
->LoadCount
;
79 if (Module
->LoadCount
> 0 && Module
->LoadCount
!= LDRP_PROCESS_CREATION_TIME
)
85 RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock
);
90 static __inline LONG
LdrpIncrementLoadCount(PLDR_DATA_TABLE_ENTRY Module
, BOOLEAN Locked
)
95 RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock
);
97 LoadCount
= Module
->LoadCount
;
98 if (Module
->LoadCount
!= LDRP_PROCESS_CREATION_TIME
)
104 RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock
);
110 LdrpQueryAppPaths(IN PCWSTR ImageName
)
112 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo
;
113 OBJECT_ATTRIBUTES ObjectAttributes
;
114 WCHAR SearchPathBuffer
[5*MAX_PATH
];
115 UNICODE_STRING ValueNameString
;
116 UNICODE_STRING KeyName
;
117 WCHAR NameBuffer
[MAX_PATH
];
125 _snwprintf(NameBuffer
,
126 sizeof(NameBuffer
) / sizeof(WCHAR
),
127 L
"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s",
130 RtlInitUnicodeString(&KeyName
, NameBuffer
);
132 InitializeObjectAttributes(&ObjectAttributes
,
134 OBJ_CASE_INSENSITIVE
,
138 Status
= NtOpenKey(&KeyHandle
,
141 if (!NT_SUCCESS(Status
))
143 DPRINT ("NtOpenKey() failed (Status %lx)\n", Status
);
147 KeyInfoSize
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + 256 * sizeof(WCHAR
);
149 KeyInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, KeyInfoSize
);
152 DPRINT("RtlAllocateHeap() failed\n");
157 RtlInitUnicodeString(&ValueNameString
,
160 Status
= NtQueryValueKey(KeyHandle
,
162 KeyValuePartialInformation
,
167 if (!NT_SUCCESS(Status
))
170 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo
);
174 RtlCopyMemory(SearchPathBuffer
,
176 KeyInfo
->DataLength
);
178 /* Free KeyInfo memory, we won't need it anymore */
179 RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo
);
181 /* Close the key handle */
184 /* get application running path */
185 wcscat(SearchPathBuffer
, L
";");
186 wcscat(SearchPathBuffer
, NtCurrentPeb()->ProcessParameters
->ImagePathName
.Buffer
); // FIXME: Don't rely on it being NULL-terminated!!!
188 /* Remove trailing backslash */
189 Backslash
= wcsrchr(SearchPathBuffer
, L
'\\');
190 if (Backslash
) Backslash
= L
'\0';
192 wcscat(SearchPathBuffer
, L
";");
194 wcscat(SearchPathBuffer
, SharedUserData
->NtSystemRoot
);
195 wcscat(SearchPathBuffer
, L
"\\system32;");
196 wcscat(SearchPathBuffer
, SharedUserData
->NtSystemRoot
);
197 wcscat(SearchPathBuffer
, L
";.");
199 /* Copy it to the heap allocd memory */
200 Path
= RtlAllocateHeap(RtlGetProcessHeap(),
202 (wcslen(SearchPathBuffer
) + 1) * sizeof(WCHAR
));
206 DPRINT1("RtlAllocateHeap() failed\n");
210 wcscpy(Path
, SearchPathBuffer
);
218 OBJECT_ATTRIBUTES ObjectAttributes
;
219 UNICODE_STRING LinkTarget
;
225 DPRINT("LdrpInitLoader() called for %wZ\n", &ExeModule
->BaseDllName
);
227 /* Get handle to the 'KnownDlls' directory */
228 RtlInitUnicodeString(&Name
,
230 InitializeObjectAttributes(&ObjectAttributes
,
232 OBJ_CASE_INSENSITIVE
,
235 Status
= NtOpenDirectoryObject(&LdrpKnownDllsDirHandle
,
236 DIRECTORY_QUERY
| DIRECTORY_TRAVERSE
,
238 if (!NT_SUCCESS(Status
))
240 DPRINT("NtOpenDirectoryObject() failed (Status %lx)\n", Status
);
241 LdrpKnownDllsDirHandle
= NULL
;
245 /* Allocate target name string */
246 LinkTarget
.Length
= 0;
247 LinkTarget
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
248 LinkTarget
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
250 MAX_PATH
* sizeof(WCHAR
));
251 if (LinkTarget
.Buffer
== NULL
)
253 NtClose(LdrpKnownDllsDirHandle
);
254 LdrpKnownDllsDirHandle
= NULL
;
258 RtlInitUnicodeString(&Name
,
260 InitializeObjectAttributes(&ObjectAttributes
,
262 OBJ_CASE_INSENSITIVE
,
263 LdrpKnownDllsDirHandle
,
265 Status
= NtOpenSymbolicLinkObject(&LinkHandle
,
266 SYMBOLIC_LINK_ALL_ACCESS
,
268 if (!NT_SUCCESS(Status
))
270 RtlFreeUnicodeString(&LinkTarget
);
271 NtClose(LdrpKnownDllsDirHandle
);
272 LdrpKnownDllsDirHandle
= NULL
;
276 Status
= NtQuerySymbolicLinkObject(LinkHandle
,
280 if (!NT_SUCCESS(Status
))
282 RtlFreeUnicodeString(&LinkTarget
);
283 NtClose(LdrpKnownDllsDirHandle
);
284 LdrpKnownDllsDirHandle
= NULL
;
287 RtlCreateUnicodeString(&LdrpKnownDllPath
,
290 RtlFreeUnicodeString(&LinkTarget
);
292 DPRINT("LdrpInitLoader() done\n");
296 /***************************************************************************
301 * Adjusts the name of a dll to a fully qualified name.
304 * FullDllName: Pointer to caller supplied storage for the fully
305 * qualified dll name.
306 * DllName: Pointer to the dll name.
307 * BaseName: TRUE: Only the file name is passed to FullDllName
308 * FALSE: The full path is preserved in FullDllName
316 * A given path is not affected by the adjustment, but the file
318 * ntdll --> ntdll.dll
320 * ntdll.xyz --> ntdll.xyz
323 LdrAdjustDllName (PUNICODE_STRING FullDllName
,
324 PUNICODE_STRING DllName
,
327 WCHAR Buffer
[MAX_PATH
];
332 Length
= DllName
->Length
/ sizeof(WCHAR
);
336 /* get the base dll name */
337 Pointer
= DllName
->Buffer
+ Length
;
344 while (Pointer
>= DllName
->Buffer
&& *Pointer
!= L
'\\' && *Pointer
!= L
'/');
347 Length
= Extension
- Pointer
;
348 memmove (Buffer
, Pointer
, Length
* sizeof(WCHAR
));
349 Buffer
[Length
] = L
'\0';
353 /* get the full dll name */
354 memmove (Buffer
, DllName
->Buffer
, DllName
->Length
);
355 Buffer
[DllName
->Length
/ sizeof(WCHAR
)] = L
'\0';
358 /* Build the DLL's absolute name */
359 Extension
= wcsrchr (Buffer
, L
'.');
360 if ((Extension
!= NULL
) && (*Extension
== L
'.'))
362 /* with extension - remove dot if it's the last character */
363 if (Buffer
[Length
- 1] == L
'.')
369 /* name without extension - assume that it is .dll */
370 memmove (Buffer
+ Length
, L
".dll", 10);
373 RtlCreateUnicodeString(FullDllName
, Buffer
);
376 PLDR_DATA_TABLE_ENTRY
377 LdrAddModuleEntry(PVOID ImageBase
,
378 PIMAGE_NT_HEADERS NTHeaders
,
381 PLDR_DATA_TABLE_ENTRY Module
;
383 Module
= RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof (LDR_DATA_TABLE_ENTRY
));
385 memset(Module
, 0, sizeof(LDR_DATA_TABLE_ENTRY
));
386 Module
->DllBase
= (PVOID
)ImageBase
;
387 Module
->EntryPoint
= (PVOID
)NTHeaders
->OptionalHeader
.AddressOfEntryPoint
;
388 if (Module
->EntryPoint
!= 0)
389 Module
->EntryPoint
= (PVOID
)((ULONG_PTR
)Module
->EntryPoint
+ (ULONG_PTR
)Module
->DllBase
);
390 Module
->SizeOfImage
= LdrpGetResidentSize(NTHeaders
);
391 if (NtCurrentPeb()->Ldr
->Initialized
== TRUE
)
393 /* loading while app is running */
394 Module
->LoadCount
= 1;
399 * loading while app is initializing
400 * dll must not be unloaded
402 Module
->LoadCount
= LDRP_PROCESS_CREATION_TIME
;
406 Module
->TlsIndex
= -1;
407 Module
->CheckSum
= NTHeaders
->OptionalHeader
.CheckSum
;
408 Module
->TimeDateStamp
= NTHeaders
->FileHeader
.TimeDateStamp
;
410 RtlCreateUnicodeString (&Module
->FullDllName
,
412 RtlCreateUnicodeString (&Module
->BaseDllName
,
413 wcsrchr(FullDosName
, L
'\\') + 1);
414 DPRINT ("BaseDllName %wZ\n", &Module
->BaseDllName
);
416 RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock
);
417 InsertTailList(&NtCurrentPeb()->Ldr
->InLoadOrderModuleList
,
418 &Module
->InLoadOrderLinks
);
419 RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock
);
426 LdrpMapKnownDll(IN PUNICODE_STRING DllName
,
427 OUT PUNICODE_STRING FullDosName
,
428 OUT PHANDLE SectionHandle
)
430 OBJECT_ATTRIBUTES ObjectAttributes
;
433 DPRINT("LdrpMapKnownDll() called\n");
435 if (LdrpKnownDllsDirHandle
== NULL
)
437 DPRINT("Invalid 'KnownDlls' directory\n");
438 return STATUS_UNSUCCESSFUL
;
441 DPRINT("LdrpKnownDllPath '%wZ'\n", &LdrpKnownDllPath
);
443 InitializeObjectAttributes(&ObjectAttributes
,
445 OBJ_CASE_INSENSITIVE
,
446 LdrpKnownDllsDirHandle
,
448 Status
= NtOpenSection(SectionHandle
,
449 SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
,
451 if (!NT_SUCCESS(Status
))
453 DPRINT("NtOpenSection() failed for '%wZ' (Status 0x%08lx)\n", DllName
, Status
);
457 FullDosName
->Length
= LdrpKnownDllPath
.Length
+ DllName
->Length
+ sizeof(WCHAR
);
458 FullDosName
->MaximumLength
= FullDosName
->Length
+ sizeof(WCHAR
);
459 FullDosName
->Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
461 FullDosName
->MaximumLength
);
462 if (FullDosName
->Buffer
== NULL
)
464 FullDosName
->Length
= 0;
465 FullDosName
->MaximumLength
= 0;
466 return STATUS_SUCCESS
;
469 wcscpy(FullDosName
->Buffer
, LdrpKnownDllPath
.Buffer
);
470 wcscat(FullDosName
->Buffer
, L
"\\");
471 wcscat(FullDosName
->Buffer
, DllName
->Buffer
);
473 DPRINT("FullDosName '%wZ'\n", FullDosName
);
475 DPRINT("LdrpMapKnownDll() done\n");
477 return STATUS_SUCCESS
;
482 LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL
,
483 IN PUNICODE_STRING DllName
,
484 OUT PUNICODE_STRING FullDosName
,
485 IN BOOLEAN MapAsDataFile
,
486 OUT PHANDLE SectionHandle
)
488 WCHAR
*SearchPathBuffer
= NULL
;
489 WCHAR
*ImagePathNameBufferPtr
= NULL
;
490 WCHAR DosName
[MAX_PATH
];
491 UNICODE_STRING FullNtFileName
;
492 UNICODE_STRING PathEnvironmentVar_U
;
493 UNICODE_STRING PathName_U
;
494 OBJECT_ATTRIBUTES FileObjectAttributes
;
496 char BlockBuffer
[1024];
497 PIMAGE_DOS_HEADER DosHeader
;
498 PIMAGE_NT_HEADERS NTHeaders
;
499 IO_STATUS_BLOCK IoStatusBlock
;
504 DPRINT("LdrpMapDllImageFile() called\n");
506 if (SearchPath
== NULL
)
508 /* get application running path */
509 ImagePathNameBufferPtr
= NtCurrentPeb()->ProcessParameters
->ImagePathName
.Buffer
;
511 /* Length of ImagePathName */
512 ImagePathLen
= wcslen(ImagePathNameBufferPtr
);
514 /* Subtract application name leaveing only the directory length */
515 while (ImagePathLen
&& ImagePathNameBufferPtr
[ImagePathLen
- 1] != L
'\\')
518 /* Length of directory + semicolon */
519 len
= ImagePathLen
+ 1;
521 /* Length of SystemRoot + "//system32" + semicolon*/
522 len
+= wcslen(SharedUserData
->NtSystemRoot
) + 10;
523 /* Length of SystemRoot + semicolon */
524 len
+= wcslen(SharedUserData
->NtSystemRoot
) + 1;
526 RtlInitUnicodeString (&PathName_U
, L
"PATH");
527 PathEnvironmentVar_U
.Length
= 0;
528 PathEnvironmentVar_U
.MaximumLength
= 0;
529 PathEnvironmentVar_U
.Buffer
= NULL
;
531 /* Get the path environment variable */
532 Status
= RtlQueryEnvironmentVariable_U(NULL
, &PathName_U
, &PathEnvironmentVar_U
);
534 /* Check that valid information was returned */
535 if ((Status
== STATUS_BUFFER_TOO_SMALL
) && (PathEnvironmentVar_U
.Length
> 0))
537 /* Allocate memory for the path env var */
538 PathEnvironmentVar_U
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, PathEnvironmentVar_U
.Length
+ sizeof(WCHAR
));
539 if (!PathEnvironmentVar_U
.Buffer
)
541 DPRINT1("Fatal! Out of Memory!!\n");
542 return STATUS_NO_MEMORY
;
544 PathEnvironmentVar_U
.MaximumLength
= PathEnvironmentVar_U
.Length
+ sizeof(WCHAR
);
547 Status
= RtlQueryEnvironmentVariable_U(NULL
, &PathName_U
, &PathEnvironmentVar_U
);
549 if (!NT_SUCCESS(Status
))
551 DPRINT1("Unable to get path environment string!\n");
554 /* Length of path evn var + semicolon */
555 len
+= (PathEnvironmentVar_U
.Length
/ sizeof(WCHAR
)) + 1;
558 /* Allocate the size needed to hold all the above paths + period */
559 SearchPathBuffer
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, (len
+ 2) * sizeof(WCHAR
));
560 if (!SearchPathBuffer
)
562 DPRINT1("Fatal! Out of Memory!!\n");
563 return STATUS_NO_MEMORY
;
566 wcsncpy(SearchPathBuffer
, ImagePathNameBufferPtr
, ImagePathLen
);
567 wcscat (SearchPathBuffer
, L
";");
568 wcscat (SearchPathBuffer
, SharedUserData
->NtSystemRoot
);
569 wcscat (SearchPathBuffer
, L
"\\system32;");
570 wcscat (SearchPathBuffer
, SharedUserData
->NtSystemRoot
);
571 wcscat (SearchPathBuffer
, L
";");
573 if (PathEnvironmentVar_U
.Buffer
)
575 wcscat (SearchPathBuffer
, PathEnvironmentVar_U
.Buffer
);
576 wcscat (SearchPathBuffer
, L
";");
577 RtlFreeHeap(RtlGetProcessHeap(), 0, PathEnvironmentVar_U
.Buffer
);
579 wcscat (SearchPathBuffer
, L
".");
581 SearchPath
= SearchPathBuffer
;
584 if (RtlDosSearchPath_U (SearchPath
,
591 /* try to find active context dll */
592 Status
= find_actctx_dll(DllName
->Buffer
, DosName
);
593 if(Status
== STATUS_SUCCESS
)
594 DPRINT("found %S for %S\n", DosName
,DllName
->Buffer
);
596 return STATUS_DLL_NOT_FOUND
;
599 if (!RtlDosPathNameToNtPathName_U (DosName
,
604 DPRINT("Dll %wZ not found!\n", DllName
);
605 return STATUS_DLL_NOT_FOUND
;
608 DPRINT("FullNtFileName %wZ\n", &FullNtFileName
);
610 InitializeObjectAttributes(&FileObjectAttributes
,
616 DPRINT("Opening dll \"%wZ\"\n", &FullNtFileName
);
618 Status
= NtOpenFile(&FileHandle
,
619 GENERIC_READ
|SYNCHRONIZE
,
620 &FileObjectAttributes
,
623 FILE_SYNCHRONOUS_IO_NONALERT
);
624 if (!NT_SUCCESS(Status
))
626 DPRINT1("Dll open of %wZ failed: Status = 0x%08lx\n",
627 &FullNtFileName
, Status
);
628 RtlFreeHeap (RtlGetProcessHeap (),
630 FullNtFileName
.Buffer
);
633 RtlFreeHeap (RtlGetProcessHeap (),
635 FullNtFileName
.Buffer
);
640 Status
= NtReadFile(FileHandle
,
649 if (!NT_SUCCESS(Status
))
651 DPRINT("Dll header read failed: Status = 0x%08lx\n", Status
);
657 * Overlay DOS and NT headers structures to the
658 * buffer with DLL's header raw data.
660 DosHeader
= (PIMAGE_DOS_HEADER
) BlockBuffer
;
661 NTHeaders
= (PIMAGE_NT_HEADERS
) (BlockBuffer
+ DosHeader
->e_lfanew
);
663 * Check it is a PE image file.
665 if ((DosHeader
->e_magic
!= IMAGE_DOS_SIGNATURE
)
666 || (DosHeader
->e_lfanew
== 0L)
667 || (*(PULONG
)(NTHeaders
) != IMAGE_NT_SIGNATURE
))
669 DPRINT("NTDLL format invalid\n");
672 return STATUS_UNSUCCESSFUL
;
677 * Create a section for dll.
679 Status
= NtCreateSection(SectionHandle
,
684 MapAsDataFile
? SEC_COMMIT
: SEC_IMAGE
,
688 if (!NT_SUCCESS(Status
))
690 DPRINT("NTDLL create section failed: Status = 0x%08lx\n", Status
);
694 RtlCreateUnicodeString(FullDosName
,
702 /***************************************************************************
719 LdrLoadDll (IN PWSTR SearchPath OPTIONAL
,
720 IN PULONG LoadFlags OPTIONAL
,
721 IN PUNICODE_STRING Name
,
722 OUT PVOID
*BaseAddress
/* also known as HMODULE*, and PHANDLE 'DllHandle' */)
725 PLDR_DATA_TABLE_ENTRY Module
;
727 PPEB Peb
= NtCurrentPeb();
729 TRACE_LDR("LdrLoadDll loading %wZ%S%S with flags %d\n",
731 SearchPath
? L
" from " : L
"",
732 SearchPath
? SearchPath
: L
"",
733 LoadFlags
? *LoadFlags
: 0);
735 Status
= LdrpLoadModule(SearchPath
, LoadFlags
? *LoadFlags
: 0, Name
, &Module
, BaseAddress
);
737 if (NT_SUCCESS(Status
) &&
738 (!LoadFlags
|| 0 == (*LoadFlags
& LOAD_LIBRARY_AS_DATAFILE
)))
740 if (!create_module_activation_context( Module
))
742 RtlActivateActivationContext(0, Module
->EntryPointActivationContext
, &cookie
);
745 if (!(Module
->Flags
& LDRP_PROCESS_ATTACH_CALLED
))
747 RtlEnterCriticalSection(Peb
->LoaderLock
);
748 Status
= LdrpAttachProcess();
749 RtlLeaveCriticalSection(Peb
->LoaderLock
);
751 if (Module
->EntryPointActivationContext
) RtlDeactivateActivationContext(0, cookie
);
754 if ((!Module
) && (NT_SUCCESS(Status
)))
757 *BaseAddress
= NT_SUCCESS(Status
) ? Module
->DllBase
: NULL
;
763 /***************************************************************************
765 * LdrFindEntryForAddress
780 LdrFindEntryForAddress(PVOID Address
,
781 PLDR_DATA_TABLE_ENTRY
*Module
)
783 PLIST_ENTRY ModuleListHead
;
785 PLDR_DATA_TABLE_ENTRY ModulePtr
;
787 DPRINT("LdrFindEntryForAddress(Address %p)\n", Address
);
789 if (NtCurrentPeb()->Ldr
== NULL
)
790 return(STATUS_NO_MORE_ENTRIES
);
792 RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock
);
793 ModuleListHead
= &NtCurrentPeb()->Ldr
->InLoadOrderModuleList
;
794 Entry
= ModuleListHead
->Flink
;
795 if (Entry
== ModuleListHead
)
797 RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock
);
798 return(STATUS_NO_MORE_ENTRIES
);
801 while (Entry
!= ModuleListHead
)
803 ModulePtr
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
805 DPRINT("Scanning %wZ at %p\n", &ModulePtr
->BaseDllName
, ModulePtr
->DllBase
);
807 if ((Address
>= ModulePtr
->DllBase
) &&
808 ((ULONG_PTR
)Address
<= ((ULONG_PTR
)ModulePtr
->DllBase
+ ModulePtr
->SizeOfImage
)))
811 RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock
);
812 return(STATUS_SUCCESS
);
815 Entry
= Entry
->Flink
;
818 DPRINT("Failed to find module entry.\n");
820 RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock
);
821 return(STATUS_NO_MORE_ENTRIES
);
825 /***************************************************************************
827 * LdrFindEntryForName
841 LdrFindEntryForName(PUNICODE_STRING Name
,
842 PLDR_DATA_TABLE_ENTRY
*Module
,
845 PLIST_ENTRY ModuleListHead
;
847 PLDR_DATA_TABLE_ENTRY ModulePtr
;
848 BOOLEAN ContainsPath
;
849 UNICODE_STRING AdjustedName
;
851 DPRINT("LdrFindEntryForName(Name %wZ)\n", Name
);
853 if (NtCurrentPeb()->Ldr
== NULL
)
854 return(STATUS_NO_MORE_ENTRIES
);
856 RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock
);
857 ModuleListHead
= &NtCurrentPeb()->Ldr
->InLoadOrderModuleList
;
858 Entry
= ModuleListHead
->Flink
;
859 if (Entry
== ModuleListHead
)
861 RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock
);
862 return(STATUS_NO_MORE_ENTRIES
);
865 // NULL is the current process
869 RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock
);
870 return(STATUS_SUCCESS
);
873 ContainsPath
= (Name
->Length
>= 2 * sizeof(WCHAR
) && L
':' == Name
->Buffer
[1]);
874 LdrAdjustDllName (&AdjustedName
, Name
, !ContainsPath
);
878 if ((!ContainsPath
&&
879 0 == RtlCompareUnicodeString(&LdrpLastModule
->BaseDllName
, &AdjustedName
, TRUE
)) ||
881 0 == RtlCompareUnicodeString(&LdrpLastModule
->FullDllName
, &AdjustedName
, TRUE
)))
883 *Module
= LdrpLastModule
;
884 if (Ref
&& (*Module
)->LoadCount
!= LDRP_PROCESS_CREATION_TIME
)
886 (*Module
)->LoadCount
++;
888 RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock
);
889 RtlFreeUnicodeString(&AdjustedName
);
890 return(STATUS_SUCCESS
);
893 while (Entry
!= ModuleListHead
)
895 ModulePtr
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
897 DPRINT("Scanning %wZ %wZ\n", &ModulePtr
->BaseDllName
, &AdjustedName
);
899 if ((!ContainsPath
&&
900 0 == RtlCompareUnicodeString(&ModulePtr
->BaseDllName
, &AdjustedName
, TRUE
)) ||
902 0 == RtlCompareUnicodeString(&ModulePtr
->FullDllName
, &AdjustedName
, TRUE
)))
904 *Module
= LdrpLastModule
= ModulePtr
;
905 if (Ref
&& ModulePtr
->LoadCount
!= LDRP_PROCESS_CREATION_TIME
)
907 ModulePtr
->LoadCount
++;
909 RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock
);
910 RtlFreeUnicodeString(&AdjustedName
);
911 return(STATUS_SUCCESS
);
914 Entry
= Entry
->Flink
;
917 DPRINT("Failed to find dll %wZ\n", Name
);
918 RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock
);
919 RtlFreeUnicodeString(&AdjustedName
);
920 return(STATUS_NO_MORE_ENTRIES
);
923 /**********************************************************************
939 LdrFixupForward(PCHAR ForwardName
)
941 CHAR NameBuffer
[128];
942 UNICODE_STRING DllName
;
945 PLDR_DATA_TABLE_ENTRY Module
;
948 strcpy(NameBuffer
, ForwardName
);
949 p
= strchr(NameBuffer
, '.');
954 DPRINT("Dll: %s Function: %s\n", NameBuffer
, p
+1);
955 RtlCreateUnicodeStringFromAsciiz (&DllName
,
958 Status
= LdrFindEntryForName (&DllName
, &Module
, FALSE
);
960 * The caller (or the image) is responsible for loading of the dll, where the function is forwarded.
962 if (!NT_SUCCESS(Status
))
964 Status
= LdrLoadDll(NULL
, NULL
, &DllName
, &BaseAddress
);
965 if (NT_SUCCESS(Status
))
967 Status
= LdrFindEntryForName (&DllName
, &Module
, FALSE
);
970 RtlFreeUnicodeString (&DllName
);
971 if (!NT_SUCCESS(Status
))
973 DPRINT1("LdrFixupForward: failed to load %s\n", NameBuffer
);
977 DPRINT("BaseAddress: %p\n", Module
->DllBase
);
979 return LdrGetExportByName(Module
->DllBase
, (PUCHAR
)(p
+1), -1);
986 /**********************************************************************
988 * LdrGetExportByOrdinal
1002 LdrGetExportByOrdinal (
1007 PIMAGE_EXPORT_DIRECTORY ExportDir
;
1008 ULONG ExportDirSize
;
1009 PDWORD
* ExFunctions
;
1012 ExportDir
= (PIMAGE_EXPORT_DIRECTORY
)
1013 RtlImageDirectoryEntryToData (BaseAddress
,
1015 IMAGE_DIRECTORY_ENTRY_EXPORT
,
1019 ExFunctions
= (PDWORD
*)RVA(BaseAddress
, ExportDir
->AddressOfFunctions
);
1020 DPRINT("LdrGetExportByOrdinal(Ordinal %lu) = %p\n",
1021 Ordinal
, RVA(BaseAddress
, ExFunctions
[Ordinal
- ExportDir
->Base
]));
1023 Function
= (0 != ExFunctions
[Ordinal
- ExportDir
->Base
]
1024 ? RVA(BaseAddress
, ExFunctions
[Ordinal
- ExportDir
->Base
] )
1027 if (((ULONG
)Function
>= (ULONG
)ExportDir
) &&
1028 ((ULONG
)Function
< (ULONG
)ExportDir
+ (ULONG
)ExportDirSize
))
1030 DPRINT("Forward: %s\n", (PCHAR
)Function
);
1031 Function
= LdrFixupForward((PCHAR
)Function
);
1038 /**********************************************************************
1040 * LdrGetExportByName
1051 * AddressOfNames and AddressOfNameOrdinals are paralell tables,
1052 * both with NumberOfNames entries.
1056 LdrGetExportByName(PVOID BaseAddress
,
1060 PIMAGE_EXPORT_DIRECTORY ExportDir
;
1061 PDWORD
*ExFunctions
;
1068 ULONG ExportDirSize
;
1070 DPRINT("LdrGetExportByName %p %s %hu\n", BaseAddress
, SymbolName
, Hint
);
1072 ExportDir
= (PIMAGE_EXPORT_DIRECTORY
)
1073 RtlImageDirectoryEntryToData(BaseAddress
,
1075 IMAGE_DIRECTORY_ENTRY_EXPORT
,
1077 if (ExportDir
== NULL
)
1079 DPRINT1("LdrGetExportByName(): no export directory, "
1080 "can't lookup %s/%hu!\n", SymbolName
, Hint
);
1085 //The symbol names may be missing entirely
1086 if (ExportDir
->AddressOfNames
== 0)
1088 DPRINT("LdrGetExportByName(): symbol names missing entirely\n");
1093 * Get header pointers
1095 ExNames
= (PDWORD
*)RVA(BaseAddress
, ExportDir
->AddressOfNames
);
1096 ExOrdinals
= (USHORT
*)RVA(BaseAddress
, ExportDir
->AddressOfNameOrdinals
);
1097 ExFunctions
= (PDWORD
*)RVA(BaseAddress
, ExportDir
->AddressOfFunctions
);
1100 * Check the hint first
1102 if (Hint
< ExportDir
->NumberOfNames
)
1104 ExName
= RVA(BaseAddress
, ExNames
[Hint
]);
1105 if (strcmp(ExName
, (PCHAR
)SymbolName
) == 0)
1107 Ordinal
= ExOrdinals
[Hint
];
1108 Function
= RVA(BaseAddress
, ExFunctions
[Ordinal
]);
1109 if (((ULONG
)Function
>= (ULONG
)ExportDir
) &&
1110 ((ULONG
)Function
< (ULONG
)ExportDir
+ (ULONG
)ExportDirSize
))
1112 DPRINT("Forward: %s\n", (PCHAR
)Function
);
1113 Function
= LdrFixupForward((PCHAR
)Function
);
1114 if (Function
== NULL
)
1116 DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName
);
1120 if (Function
!= NULL
)
1129 maxn
= ExportDir
->NumberOfNames
- 1;
1130 while (minn
<= maxn
)
1135 mid
= (minn
+ maxn
) / 2;
1137 ExName
= RVA(BaseAddress
, ExNames
[mid
]);
1138 res
= strcmp(ExName
, (PCHAR
)SymbolName
);
1141 Ordinal
= ExOrdinals
[mid
];
1142 Function
= RVA(BaseAddress
, ExFunctions
[Ordinal
]);
1143 if (((ULONG
)Function
>= (ULONG
)ExportDir
) &&
1144 ((ULONG
)Function
< (ULONG
)ExportDir
+ (ULONG
)ExportDirSize
))
1146 DPRINT("Forward: %s\n", (PCHAR
)Function
);
1147 Function
= LdrFixupForward((PCHAR
)Function
);
1148 if (Function
== NULL
)
1150 DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName
);
1154 if (Function
!= NULL
)
1157 else if (minn
== maxn
)
1159 DPRINT("LdrGetExportByName(): binary search failed\n");
1172 DPRINT("LdrGetExportByName(): failed to find %s\n",SymbolName
);
1177 /**********************************************************************
1179 * LdrPerformRelocations
1182 * Relocate a DLL's memory image.
1194 LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders
,
1197 PIMAGE_DATA_DIRECTORY RelocationDDir
;
1198 PIMAGE_BASE_RELOCATION RelocationDir
, RelocationEnd
;
1199 ULONG Count
, ProtectSize
, OldProtect
, OldProtect2
;
1200 PVOID Page
, ProtectPage
, ProtectPage2
;
1205 if (NTHeaders
->FileHeader
.Characteristics
& IMAGE_FILE_RELOCS_STRIPPED
)
1207 return STATUS_SUCCESS
;
1211 &NTHeaders
->OptionalHeader
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_BASERELOC
];
1213 if (RelocationDDir
->VirtualAddress
== 0 || RelocationDDir
->Size
== 0)
1215 return STATUS_SUCCESS
;
1218 ProtectSize
= PAGE_SIZE
;
1219 Delta
= (ULONG_PTR
)ImageBase
- NTHeaders
->OptionalHeader
.ImageBase
;
1220 RelocationDir
= (PIMAGE_BASE_RELOCATION
)((ULONG_PTR
)ImageBase
+
1221 RelocationDDir
->VirtualAddress
);
1222 RelocationEnd
= (PIMAGE_BASE_RELOCATION
)((ULONG_PTR
)ImageBase
+
1223 RelocationDDir
->VirtualAddress
+ RelocationDDir
->Size
);
1225 while (RelocationDir
< RelocationEnd
&&
1226 RelocationDir
->SizeOfBlock
> 0)
1228 Count
= (RelocationDir
->SizeOfBlock
- sizeof(IMAGE_BASE_RELOCATION
)) /
1230 Page
= (PVOID
)((ULONG_PTR
)ImageBase
+ (ULONG_PTR
)RelocationDir
->VirtualAddress
);
1231 TypeOffset
= (PUSHORT
)(RelocationDir
+ 1);
1233 /* Unprotect the page(s) we're about to relocate. */
1235 Status
= NtProtectVirtualMemory(NtCurrentProcess(),
1240 if (!NT_SUCCESS(Status
))
1242 DPRINT1("Failed to unprotect relocation target.\n");
1246 if (RelocationDir
->VirtualAddress
+ PAGE_SIZE
<
1247 NTHeaders
->OptionalHeader
.SizeOfImage
)
1249 ProtectPage2
= (PVOID
)((ULONG_PTR
)ProtectPage
+ PAGE_SIZE
);
1250 Status
= NtProtectVirtualMemory(NtCurrentProcess(),
1255 if (!NT_SUCCESS(Status
))
1257 DPRINT1("Failed to unprotect relocation target (2).\n");
1258 NtProtectVirtualMemory(NtCurrentProcess(),
1268 ProtectPage2
= NULL
;
1271 RelocationDir
= LdrProcessRelocationBlock((ULONG_PTR
)Page
,
1275 if (RelocationDir
== NULL
)
1276 return STATUS_UNSUCCESSFUL
;
1278 /* Restore old page protection. */
1279 NtProtectVirtualMemory(NtCurrentProcess(),
1285 if (ProtectPage2
!= NULL
)
1287 NtProtectVirtualMemory(NtCurrentProcess(),
1295 return STATUS_SUCCESS
;
1299 LdrpGetOrLoadModule(PWCHAR SearchPath
,
1301 PLDR_DATA_TABLE_ENTRY
* Module
,
1304 ANSI_STRING AnsiDllName
;
1305 UNICODE_STRING DllName
;
1308 DPRINT("LdrpGetOrLoadModule() called for %s\n", Name
);
1310 RtlInitAnsiString(&AnsiDllName
, Name
);
1311 Status
= RtlAnsiStringToUnicodeString(&DllName
, &AnsiDllName
, TRUE
);
1312 if (!NT_SUCCESS(Status
))
1317 Status
= LdrFindEntryForName (&DllName
, Module
, Load
);
1318 if (Load
&& !NT_SUCCESS(Status
))
1320 Status
= LdrpLoadModule(SearchPath
,
1325 if (NT_SUCCESS(Status
))
1327 Status
= LdrFindEntryForName (&DllName
, Module
, FALSE
);
1329 if (!NT_SUCCESS(Status
))
1331 ULONG ErrorResponse
;
1332 ULONG_PTR ErrorParameter
= (ULONG_PTR
)&AnsiDllName
;
1334 DPRINT1("failed to load %wZ\n", &DllName
);
1336 NtRaiseHardError(STATUS_DLL_NOT_FOUND
,
1344 RtlFreeUnicodeString (&DllName
);
1349 RtlpRaiseImportNotFound(CHAR
*FuncName
, ULONG Ordinal
, PUNICODE_STRING DllName
)
1351 ULONG ErrorResponse
;
1352 ULONG_PTR ErrorParameters
[2];
1353 ANSI_STRING ProcNameAnsi
;
1354 UNICODE_STRING ProcName
;
1359 _snprintf(Buffer
, 8, "# %ld", Ordinal
);
1363 RtlInitAnsiString(&ProcNameAnsi
, FuncName
);
1364 RtlAnsiStringToUnicodeString(&ProcName
, &ProcNameAnsi
, TRUE
);
1365 ErrorParameters
[0] = (ULONG_PTR
)&ProcName
;
1366 ErrorParameters
[1] = (ULONG_PTR
)DllName
;
1367 NtRaiseHardError(STATUS_ENTRYPOINT_NOT_FOUND
,
1373 RtlFreeUnicodeString(&ProcName
);
1377 LdrpProcessImportDirectoryEntry(PLDR_DATA_TABLE_ENTRY Module
,
1378 PLDR_DATA_TABLE_ENTRY ImportedModule
,
1379 PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory
)
1382 PVOID
* ImportAddressList
;
1383 PULONG FunctionNameList
;
1389 if (ImportModuleDirectory
== NULL
|| ImportModuleDirectory
->Name
== 0)
1391 return STATUS_UNSUCCESSFUL
;
1394 /* Get the import address list. */
1395 ImportAddressList
= (PVOID
*)((ULONG_PTR
)Module
->DllBase
+
1396 (ULONG_PTR
)ImportModuleDirectory
->FirstThunk
);
1398 /* Get the list of functions to import. */
1399 if (ImportModuleDirectory
->OriginalFirstThunk
!= 0)
1401 FunctionNameList
= (PULONG
)((ULONG_PTR
)Module
->DllBase
+
1402 (ULONG_PTR
)ImportModuleDirectory
->OriginalFirstThunk
);
1406 FunctionNameList
= (PULONG
)((ULONG_PTR
)Module
->DllBase
+
1407 (ULONG_PTR
)ImportModuleDirectory
->FirstThunk
);
1410 /* Get the size of IAT. */
1412 while (FunctionNameList
[IATSize
] != 0L)
1417 /* No need to fixup anything if IAT is empty */
1418 if (IATSize
== 0) return STATUS_SUCCESS
;
1420 /* Unprotect the region we are about to write into. */
1421 IATBase
= (PVOID
)ImportAddressList
;
1422 IATSize
*= sizeof(PVOID
*);
1423 Status
= NtProtectVirtualMemory(NtCurrentProcess(),
1428 if (!NT_SUCCESS(Status
))
1430 DPRINT1("Failed to unprotect IAT.\n");
1434 /* Walk through function list and fixup addresses. */
1435 while (*FunctionNameList
!= 0L)
1437 if ((*FunctionNameList
) & 0x80000000)
1439 Ordinal
= (*FunctionNameList
) & 0x7fffffff;
1440 *ImportAddressList
= LdrGetExportByOrdinal(ImportedModule
->DllBase
,
1442 if ((*ImportAddressList
) == NULL
)
1444 DPRINT1("Failed to import #%ld from %wZ\n",
1445 Ordinal
, &ImportedModule
->FullDllName
);
1446 RtlpRaiseImportNotFound(NULL
, Ordinal
, &ImportedModule
->FullDllName
);
1447 return STATUS_ENTRYPOINT_NOT_FOUND
;
1452 IMAGE_IMPORT_BY_NAME
*pe_name
;
1453 pe_name
= RVA(Module
->DllBase
, *FunctionNameList
);
1454 *ImportAddressList
= LdrGetExportByName(ImportedModule
->DllBase
,
1457 if ((*ImportAddressList
) == NULL
)
1459 DPRINT1("Failed to import %s from %wZ\n",
1460 pe_name
->Name
, &ImportedModule
->FullDllName
);
1461 RtlpRaiseImportNotFound((CHAR
*)pe_name
->Name
,
1463 &ImportedModule
->FullDllName
);
1464 return STATUS_ENTRYPOINT_NOT_FOUND
;
1467 ImportAddressList
++;
1471 /* Protect the region we are about to write into. */
1472 Status
= NtProtectVirtualMemory(NtCurrentProcess(),
1477 if (!NT_SUCCESS(Status
))
1479 DPRINT1("Failed to protect IAT.\n");
1483 return STATUS_SUCCESS
;
1487 LdrpProcessImportDirectory(
1488 PLDR_DATA_TABLE_ENTRY Module
,
1489 PLDR_DATA_TABLE_ENTRY ImportedModule
,
1493 PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory
;
1497 DPRINT("LdrpProcessImportDirectory(%p '%wZ', '%s')\n",
1498 Module
, &Module
->BaseDllName
, ImportedName
);
1501 ImportModuleDirectory
= (PIMAGE_IMPORT_DESCRIPTOR
)
1502 RtlImageDirectoryEntryToData(Module
->DllBase
,
1504 IMAGE_DIRECTORY_ENTRY_IMPORT
,
1506 if (ImportModuleDirectory
== NULL
)
1508 return STATUS_UNSUCCESSFUL
;
1511 while (ImportModuleDirectory
->Name
)
1513 Name
= (PCHAR
)Module
->DllBase
+ ImportModuleDirectory
->Name
;
1514 if (0 == _stricmp(Name
, ImportedName
))
1516 Status
= LdrpProcessImportDirectoryEntry(Module
,
1518 ImportModuleDirectory
);
1519 if (!NT_SUCCESS(Status
))
1524 ImportModuleDirectory
++;
1528 return STATUS_SUCCESS
;
1533 LdrpAdjustImportDirectory(PLDR_DATA_TABLE_ENTRY Module
,
1534 PLDR_DATA_TABLE_ENTRY ImportedModule
,
1537 PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory
;
1539 PVOID
* ImportAddressList
;
1542 PULONG FunctionNameList
;
1547 PIMAGE_NT_HEADERS NTHeaders
;
1551 DPRINT("LdrpAdjustImportDirectory(Module %p '%wZ', %p '%wZ', '%s')\n",
1552 Module
, &Module
->BaseDllName
, ImportedModule
, &ImportedModule
->BaseDllName
, ImportedName
);
1554 ImportModuleDirectory
= (PIMAGE_IMPORT_DESCRIPTOR
)
1555 RtlImageDirectoryEntryToData(Module
->DllBase
,
1557 IMAGE_DIRECTORY_ENTRY_IMPORT
,
1559 if (ImportModuleDirectory
== NULL
)
1561 return STATUS_UNSUCCESSFUL
;
1564 while (ImportModuleDirectory
->Name
)
1566 Name
= (PCHAR
)Module
->DllBase
+ ImportModuleDirectory
->Name
;
1567 if (0 == _stricmp(Name
, (PCHAR
)ImportedName
))
1570 /* Get the import address list. */
1571 ImportAddressList
= (PVOID
*)((ULONG_PTR
)Module
->DllBase
+
1572 (ULONG_PTR
)ImportModuleDirectory
->FirstThunk
);
1574 /* Get the list of functions to import. */
1575 if (ImportModuleDirectory
->OriginalFirstThunk
!= 0)
1577 FunctionNameList
= (PULONG
)((ULONG_PTR
)Module
->DllBase
+
1578 (ULONG_PTR
)ImportModuleDirectory
->OriginalFirstThunk
);
1582 FunctionNameList
= (PULONG
)((ULONG_PTR
)Module
->DllBase
+
1583 (ULONG_PTR
)ImportModuleDirectory
->FirstThunk
);
1586 /* Get the size of IAT. */
1588 while (FunctionNameList
[IATSize
] != 0L)
1593 /* Unprotect the region we are about to write into. */
1594 IATBase
= (PVOID
)ImportAddressList
;
1595 IATSize
*= sizeof(PVOID
*);
1596 Status
= NtProtectVirtualMemory(NtCurrentProcess(),
1601 if (!NT_SUCCESS(Status
))
1603 DPRINT1("Failed to unprotect IAT.\n");
1607 NTHeaders
= RtlImageNtHeader (ImportedModule
->DllBase
);
1608 Start
= (PVOID
)NTHeaders
->OptionalHeader
.ImageBase
;
1609 End
= (PVOID
)((ULONG_PTR
)Start
+ ImportedModule
->SizeOfImage
);
1610 Offset
= (ULONG
)((ULONG_PTR
)ImportedModule
->DllBase
- (ULONG_PTR
)Start
);
1612 /* Walk through function list and fixup addresses. */
1613 while (*FunctionNameList
!= 0L)
1615 if (*ImportAddressList
>= Start
&& *ImportAddressList
< End
)
1617 (*ImportAddressList
) = (PVOID
)((ULONG_PTR
)(*ImportAddressList
) + Offset
);
1619 ImportAddressList
++;
1623 /* Protect the region we are about to write into. */
1624 Status
= NtProtectVirtualMemory(NtCurrentProcess(),
1629 if (!NT_SUCCESS(Status
))
1631 DPRINT1("Failed to protect IAT.\n");
1635 ImportModuleDirectory
++;
1637 return STATUS_SUCCESS
;
1641 /**********************************************************************
1646 * Compute the entry point for every symbol the DLL imports
1647 * from other modules.
1659 LdrFixupImports(IN PWSTR SearchPath OPTIONAL
,
1660 IN PLDR_DATA_TABLE_ENTRY Module
)
1662 PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory
;
1663 PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectoryCurrent
;
1664 PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptor
;
1665 PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptorCurrent
;
1666 PIMAGE_TLS_DIRECTORY TlsDirectory
;
1668 NTSTATUS Status
= STATUS_SUCCESS
;
1669 PLDR_DATA_TABLE_ENTRY ImportedModule
;
1675 DPRINT("LdrFixupImports(SearchPath %S, Module %p)\n", SearchPath
, Module
);
1677 /* Check for tls data */
1678 TlsDirectory
= (PIMAGE_TLS_DIRECTORY
)
1679 RtlImageDirectoryEntryToData(Module
->DllBase
,
1681 IMAGE_DIRECTORY_ENTRY_TLS
,
1685 TlsSize
= TlsDirectory
->EndAddressOfRawData
1686 - TlsDirectory
->StartAddressOfRawData
1687 + TlsDirectory
->SizeOfZeroFill
;
1689 if (TlsSize
> 0 && NtCurrentPeb()->Ldr
->Initialized
)
1691 TRACE_LDR("Trying to dynamically load %wZ which contains a TLS directory\n",
1692 &Module
->BaseDllName
);
1693 TlsDirectory
= NULL
;
1697 if (!create_module_activation_context( Module
))
1699 if (Module
->EntryPointActivationContext
== NULL
)
1701 DPRINT("EntryPointActivationContext has not be allocated\n");
1702 DPRINT("Module->DllBaseName %wZ\n", Module
->BaseDllName
);
1704 RtlActivateActivationContext( 0, Module
->EntryPointActivationContext
, &cookie
);
1708 * Process each import module.
1710 ImportModuleDirectory
= (PIMAGE_IMPORT_DESCRIPTOR
)
1711 RtlImageDirectoryEntryToData(Module
->DllBase
,
1713 IMAGE_DIRECTORY_ENTRY_IMPORT
,
1716 BoundImportDescriptor
= (PIMAGE_BOUND_IMPORT_DESCRIPTOR
)
1717 RtlImageDirectoryEntryToData(Module
->DllBase
,
1719 IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
,
1722 if (BoundImportDescriptor
!= NULL
&& ImportModuleDirectory
== NULL
)
1724 DPRINT1("%wZ has only a bound import directory\n", &Module
->BaseDllName
);
1725 return STATUS_UNSUCCESSFUL
;
1727 if (BoundImportDescriptor
)
1729 DPRINT("BoundImportDescriptor %p\n", BoundImportDescriptor
);
1731 BoundImportDescriptorCurrent
= BoundImportDescriptor
;
1732 while (BoundImportDescriptorCurrent
->OffsetModuleName
)
1734 ImportedName
= (PCHAR
)BoundImportDescriptor
+
1735 BoundImportDescriptorCurrent
->OffsetModuleName
;
1736 TRACE_LDR("%wZ bound to %s\n", &Module
->BaseDllName
, ImportedName
);
1737 Status
= LdrpGetOrLoadModule(SearchPath
, ImportedName
, &ImportedModule
, TRUE
);
1738 if (!NT_SUCCESS(Status
))
1740 DPRINT1("failed to load %s\n", ImportedName
);
1743 if (Module
== ImportedModule
)
1745 LdrpDecrementLoadCount(Module
, FALSE
);
1747 if (ImportedModule
->TimeDateStamp
!= BoundImportDescriptorCurrent
->TimeDateStamp
)
1749 TRACE_LDR("%wZ has stale binding to %wZ\n",
1750 &Module
->BaseDllName
, &ImportedModule
->BaseDllName
);
1751 Status
= LdrpProcessImportDirectory(Module
, ImportedModule
, ImportedName
);
1752 if (!NT_SUCCESS(Status
))
1754 DPRINT1("failed to import %s\n", ImportedName
);
1760 BOOLEAN WrongForwarder
;
1761 WrongForwarder
= FALSE
;
1762 if (ImportedModule
->Flags
& LDRP_IMAGE_NOT_AT_BASE
)
1764 TRACE_LDR("%wZ has stale binding to %s\n",
1765 &Module
->BaseDllName
, ImportedName
);
1769 TRACE_LDR("%wZ has correct binding to %wZ\n",
1770 &Module
->BaseDllName
, &ImportedModule
->BaseDllName
);
1772 if (BoundImportDescriptorCurrent
->NumberOfModuleForwarderRefs
)
1774 PIMAGE_BOUND_FORWARDER_REF BoundForwarderRef
;
1776 PLDR_DATA_TABLE_ENTRY ForwarderModule
;
1777 PCHAR ForwarderName
;
1779 BoundForwarderRef
= (PIMAGE_BOUND_FORWARDER_REF
)(BoundImportDescriptorCurrent
+ 1);
1781 i
< BoundImportDescriptorCurrent
->NumberOfModuleForwarderRefs
;
1782 i
++, BoundForwarderRef
++)
1784 ForwarderName
= (PCHAR
)BoundImportDescriptor
+
1785 BoundForwarderRef
->OffsetModuleName
;
1786 TRACE_LDR("%wZ bound to %s via forwardes from %s\n",
1787 &Module
->BaseDllName
, ForwarderName
, ImportedName
);
1788 Status
= LdrpGetOrLoadModule(SearchPath
, ForwarderName
, &ForwarderModule
, TRUE
);
1789 if (!NT_SUCCESS(Status
))
1791 DPRINT1("failed to load %s\n", ForwarderName
);
1794 if (Module
== ImportedModule
)
1796 LdrpDecrementLoadCount(Module
, FALSE
);
1798 if (ForwarderModule
->TimeDateStamp
!= BoundForwarderRef
->TimeDateStamp
||
1799 ForwarderModule
->Flags
& LDRP_IMAGE_NOT_AT_BASE
)
1801 TRACE_LDR("%wZ has stale binding to %s\n",
1802 &Module
->BaseDllName
, ForwarderName
);
1803 WrongForwarder
= TRUE
;
1807 TRACE_LDR("%wZ has correct binding to %s\n",
1808 &Module
->BaseDllName
, ForwarderName
);
1812 if (WrongForwarder
||
1813 ImportedModule
->Flags
& LDRP_IMAGE_NOT_AT_BASE
)
1815 Status
= LdrpProcessImportDirectory(Module
, ImportedModule
, ImportedName
);
1816 if (!NT_SUCCESS(Status
))
1818 DPRINT1("failed to import %s\n", ImportedName
);
1822 else if (ImportedModule
->Flags
& LDRP_IMAGE_NOT_AT_BASE
)
1824 TRACE_LDR("Adjust imports for %s from %wZ\n",
1825 ImportedName
, &Module
->BaseDllName
);
1826 Status
= LdrpAdjustImportDirectory(Module
, ImportedModule
, ImportedName
);
1827 if (!NT_SUCCESS(Status
))
1829 DPRINT1("failed to adjust import entries for %s\n", ImportedName
);
1833 else if (WrongForwarder
)
1837 * Update only forwarders
1839 TRACE_LDR("Stale BIND %s from %wZ\n",
1840 ImportedName
, &Module
->BaseDllName
);
1841 Status
= LdrpProcessImportDirectory(Module
, ImportedModule
, ImportedName
);
1842 if (!NT_SUCCESS(Status
))
1844 DPRINT1("faild to import %s\n", ImportedName
);
1853 BoundImportDescriptorCurrent
+= BoundImportDescriptorCurrent
->NumberOfModuleForwarderRefs
+ 1;
1856 else if (ImportModuleDirectory
)
1858 DPRINT("ImportModuleDirectory %p\n", ImportModuleDirectory
);
1860 ImportModuleDirectoryCurrent
= ImportModuleDirectory
;
1861 while (ImportModuleDirectoryCurrent
->Name
)
1863 ImportedName
= (PCHAR
)Module
->DllBase
+ ImportModuleDirectoryCurrent
->Name
;
1864 TRACE_LDR("%wZ imports functions from %s\n", &Module
->BaseDllName
, ImportedName
);
1866 if (SearchPath
== NULL
)
1868 ModulePath
= LdrpQueryAppPaths(Module
->BaseDllName
.Buffer
);
1870 Status
= LdrpGetOrLoadModule(ModulePath
, ImportedName
, &ImportedModule
, TRUE
);
1871 if (ModulePath
!= NULL
) RtlFreeHeap(RtlGetProcessHeap(), 0, ModulePath
);
1872 if (NT_SUCCESS(Status
)) goto Success
;
1875 Status
= LdrpGetOrLoadModule(SearchPath
, ImportedName
, &ImportedModule
, TRUE
);
1876 if (!NT_SUCCESS(Status
))
1878 DPRINT1("failed to load %s\n", ImportedName
);
1882 if (Module
== ImportedModule
)
1884 LdrpDecrementLoadCount(Module
, FALSE
);
1887 TRACE_LDR("Initializing imports for %wZ from %s\n",
1888 &Module
->BaseDllName
, ImportedName
);
1889 Status
= LdrpProcessImportDirectoryEntry(Module
, ImportedModule
, ImportModuleDirectoryCurrent
);
1890 if (!NT_SUCCESS(Status
))
1892 DPRINT1("failed to import %s\n", ImportedName
);
1895 ImportModuleDirectoryCurrent
++;
1898 if (!NT_SUCCESS(Status
))
1900 NTSTATUS errorStatus
= Status
;
1902 while (ImportModuleDirectoryCurrent
>= ImportModuleDirectory
)
1904 ImportedName
= (PCHAR
)Module
->DllBase
+ ImportModuleDirectoryCurrent
->Name
;
1906 Status
= LdrpGetOrLoadModule(NULL
, ImportedName
, &ImportedModule
, FALSE
);
1907 if (NT_SUCCESS(Status
) && Module
!= ImportedModule
)
1909 Status
= LdrpUnloadModule(ImportedModule
, FALSE
);
1910 if (!NT_SUCCESS(Status
)) DPRINT1("unable to unload %s\n", ImportedName
);
1912 ImportModuleDirectoryCurrent
--;
1918 if (Module
->EntryPointActivationContext
) RtlDeactivateActivationContext( 0, cookie
);
1920 return STATUS_SUCCESS
;
1924 /**********************************************************************
1929 * 1. Relocate, if needed the EXE.
1930 * 2. Fixup any imported symbol.
1931 * 3. Compute the EXE's entry point.
1935 * Address at which the EXE's image
1939 * Handle of the section that contains
1943 * NULL on error; otherwise the entry point
1944 * to call for initializing the DLL.
1949 * 04.01.2004 hb Previous this function was used for all images (dll + exe).
1950 * Currently the function is only used for the exe.
1952 PEPFUNC
LdrPEStartup (PVOID ImageBase
,
1953 HANDLE SectionHandle
,
1954 PLDR_DATA_TABLE_ENTRY
* Module
,
1958 PEPFUNC EntryPoint
= NULL
;
1959 PIMAGE_DOS_HEADER DosHeader
;
1960 PIMAGE_NT_HEADERS NTHeaders
;
1961 PLDR_DATA_TABLE_ENTRY tmpModule
;
1962 PVOID ActivationContextStack
;
1964 DPRINT("LdrPEStartup(ImageBase %p SectionHandle %p)\n",
1965 ImageBase
, SectionHandle
);
1968 * Overlay DOS and WNT headers structures
1969 * to the DLL's image.
1971 DosHeader
= (PIMAGE_DOS_HEADER
) ImageBase
;
1972 NTHeaders
= (PIMAGE_NT_HEADERS
) ((ULONG_PTR
)ImageBase
+ DosHeader
->e_lfanew
);
1975 * If the base address is different from the
1976 * one the DLL is actually loaded, perform any
1979 if (ImageBase
!= (PVOID
)NTHeaders
->OptionalHeader
.ImageBase
)
1981 DPRINT("LDR: Performing relocations\n");
1982 Status
= LdrPerformRelocations(NTHeaders
, ImageBase
);
1983 if (!NT_SUCCESS(Status
))
1985 DPRINT1("LdrPerformRelocations() failed\n");
1992 *Module
= LdrAddModuleEntry(ImageBase
, NTHeaders
, FullDosName
);
1993 (*Module
)->SectionPointer
= SectionHandle
;
1997 Module
= &tmpModule
;
1998 Status
= LdrFindEntryForAddress(ImageBase
, Module
);
1999 if (!NT_SUCCESS(Status
))
2005 if (ImageBase
!= (PVOID
) NTHeaders
->OptionalHeader
.ImageBase
)
2007 (*Module
)->Flags
|= LDRP_IMAGE_NOT_AT_BASE
;
2010 /* Allocate memory for the ActivationContextStack */
2011 /* FIXME: Verify RtlAllocateActivationContextStack behavior */
2012 Status
= RtlAllocateActivationContextStack(&ActivationContextStack
);
2013 if (NT_SUCCESS(Status
))
2015 DPRINT("ActivationContextStack %x\n",ActivationContextStack
);
2016 DPRINT("ActiveFrame %x\n", ((PACTIVATION_CONTEXT_STACK
)ActivationContextStack
)->ActiveFrame
);
2017 NtCurrentTeb()->ActivationContextStackPointer
= ActivationContextStack
;
2018 NtCurrentTeb()->ActivationContextStackPointer
->ActiveFrame
= NULL
;
2021 DPRINT1("Warning: Unable to allocate ActivationContextStack\n");
2024 * If the DLL's imports symbols from other
2025 * modules, fixup the imported calls entry points.
2027 DPRINT("About to fixup imports\n");
2028 Status
= LdrFixupImports(NULL
, *Module
);
2029 if (!NT_SUCCESS(Status
))
2031 DPRINT1("LdrFixupImports() failed for %wZ\n", &(*Module
)->BaseDllName
);
2034 DPRINT("Fixup done\n");
2035 RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock
);
2036 Status
= LdrpInitializeTls();
2037 if (NT_SUCCESS(Status
))
2039 Status
= LdrpAttachProcess();
2041 if (NT_SUCCESS(Status
))
2043 LdrpTlsCallback((*Module
)->DllBase
, DLL_PROCESS_ATTACH
);
2047 RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock
);
2048 if (!NT_SUCCESS(Status
))
2054 * Compute the DLL's entry point's address.
2056 DPRINT("ImageBase = %p\n", ImageBase
);
2057 DPRINT("AddressOfEntryPoint = 0x%lx\n",(ULONG
)NTHeaders
->OptionalHeader
.AddressOfEntryPoint
);
2058 if (NTHeaders
->OptionalHeader
.AddressOfEntryPoint
!= 0)
2060 EntryPoint
= (PEPFUNC
) ((ULONG_PTR
)ImageBase
2061 + NTHeaders
->OptionalHeader
.AddressOfEntryPoint
);
2063 DPRINT("LdrPEStartup() = %p\n",EntryPoint
);
2068 LdrpLoadModule(IN PWSTR SearchPath OPTIONAL
,
2070 IN PUNICODE_STRING Name
,
2071 PLDR_DATA_TABLE_ENTRY
*Module
,
2072 PVOID
*BaseAddress OPTIONAL
)
2074 UNICODE_STRING AdjustedName
;
2075 UNICODE_STRING FullDosName
;
2077 PLDR_DATA_TABLE_ENTRY tmpModule
;
2078 HANDLE SectionHandle
;
2081 PIMAGE_NT_HEADERS NtHeaders
;
2082 BOOLEAN MappedAsDataFile
;
2083 PVOID ArbitraryUserPointer
;
2087 Module
= &tmpModule
;
2089 /* adjust the full dll name */
2090 LdrAdjustDllName(&AdjustedName
, Name
, FALSE
);
2092 DPRINT("%wZ\n", &AdjustedName
);
2094 MappedAsDataFile
= FALSE
;
2095 /* Test if dll is already loaded */
2096 Status
= LdrFindEntryForName(&AdjustedName
, Module
, TRUE
);
2097 if (NT_SUCCESS(Status
))
2099 RtlFreeUnicodeString(&AdjustedName
);
2100 if (NULL
!= BaseAddress
)
2102 *BaseAddress
= (*Module
)->DllBase
;
2107 /* Open or create dll image section */
2108 Status
= LdrpMapKnownDll(&AdjustedName
, &FullDosName
, &SectionHandle
);
2109 if (!NT_SUCCESS(Status
))
2111 MappedAsDataFile
= (0 != (LoadFlags
& LOAD_LIBRARY_AS_DATAFILE
));
2112 Status
= LdrpMapDllImageFile(SearchPath
, &AdjustedName
, &FullDosName
,
2113 MappedAsDataFile
, &SectionHandle
);
2115 if (!NT_SUCCESS(Status
))
2117 DPRINT1("Failed to create or open dll section of '%wZ' (Status %lx)\n",
2118 &AdjustedName
, Status
);
2119 RtlFreeUnicodeString(&AdjustedName
);
2122 RtlFreeUnicodeString(&AdjustedName
);
2123 /* Map the dll into the process */
2126 ArbitraryUserPointer
= NtCurrentTeb()->NtTib
.ArbitraryUserPointer
;
2127 NtCurrentTeb()->NtTib
.ArbitraryUserPointer
= FullDosName
.Buffer
;
2128 Status
= NtMapViewOfSection(SectionHandle
,
2138 NtCurrentTeb()->NtTib
.ArbitraryUserPointer
= ArbitraryUserPointer
;
2139 if (!NT_SUCCESS(Status
))
2141 DPRINT1("map view of section failed (Status 0x%08lx)\n", Status
);
2142 RtlFreeUnicodeString(&FullDosName
);
2143 NtClose(SectionHandle
);
2146 if (NULL
!= BaseAddress
)
2148 *BaseAddress
= ImageBase
;
2150 if (!MappedAsDataFile
)
2152 /* Get and check the NT headers */
2153 NtHeaders
= RtlImageNtHeader(ImageBase
);
2154 if (NtHeaders
== NULL
)
2156 DPRINT1("RtlImageNtHeaders() failed\n");
2157 NtUnmapViewOfSection (NtCurrentProcess (), ImageBase
);
2158 NtClose (SectionHandle
);
2159 RtlFreeUnicodeString(&FullDosName
);
2160 return STATUS_UNSUCCESSFUL
;
2163 DPRINT("Mapped %wZ at %x\n", &FullDosName
, ImageBase
);
2164 if (MappedAsDataFile
)
2166 ASSERT(NULL
!= BaseAddress
);
2167 if (NULL
!= BaseAddress
)
2169 *BaseAddress
= (PVOID
) ((char *) *BaseAddress
+ 1);
2172 RtlFreeUnicodeString(&FullDosName
);
2173 NtClose(SectionHandle
);
2174 return STATUS_SUCCESS
;
2176 /* If the base address is different from the
2177 * one the DLL is actually loaded, perform any
2179 if (ImageBase
!= (PVOID
) NtHeaders
->OptionalHeader
.ImageBase
)
2181 DPRINT1("Relocating (%lx -> %p) %wZ\n",
2182 NtHeaders
->OptionalHeader
.ImageBase
, ImageBase
, &FullDosName
);
2183 Status
= LdrPerformRelocations(NtHeaders
, ImageBase
);
2184 if (!NT_SUCCESS(Status
))
2186 DPRINT1("LdrPerformRelocations() failed\n");
2187 NtUnmapViewOfSection (NtCurrentProcess (), ImageBase
);
2188 NtClose (SectionHandle
);
2189 RtlFreeUnicodeString(&FullDosName
);
2190 return STATUS_UNSUCCESSFUL
;
2193 *Module
= LdrAddModuleEntry(ImageBase
, NtHeaders
, FullDosName
.Buffer
);
2194 (*Module
)->SectionPointer
= SectionHandle
;
2195 if (ImageBase
!= (PVOID
) NtHeaders
->OptionalHeader
.ImageBase
)
2197 (*Module
)->Flags
|= LDRP_IMAGE_NOT_AT_BASE
;
2199 if (NtHeaders
->FileHeader
.Characteristics
& IMAGE_FILE_DLL
)
2201 (*Module
)->Flags
|= LDRP_IMAGE_DLL
;
2203 /* fixup the imported calls entry points */
2204 Status
= LdrFixupImports(SearchPath
, *Module
);
2205 if (!NT_SUCCESS(Status
))
2207 DPRINT1("LdrFixupImports failed for %wZ, status=%x\n", &(*Module
)->BaseDllName
, Status
);
2208 NtUnmapViewOfSection (NtCurrentProcess (), ImageBase
);
2209 NtClose (SectionHandle
);
2210 RtlFreeUnicodeString (&FullDosName
);
2211 RtlFreeUnicodeString (&(*Module
)->FullDllName
);
2212 RtlFreeUnicodeString (&(*Module
)->BaseDllName
);
2213 RemoveEntryList (&(*Module
)->InLoadOrderLinks
);
2217 RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock
);
2218 InsertTailList(&NtCurrentPeb()->Ldr
->InInitializationOrderModuleList
,
2219 &(*Module
)->InInitializationOrderModuleList
);
2220 RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock
);
2222 return STATUS_SUCCESS
;
2226 LdrpUnloadModule(PLDR_DATA_TABLE_ENTRY Module
,
2229 PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory
;
2230 PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptor
;
2231 PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptorCurrent
;
2233 PLDR_DATA_TABLE_ENTRY ImportedModule
;
2234 NTSTATUS Status
= 0;
2240 RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock
);
2243 LoadCount
= LdrpDecrementLoadCount(Module
, Unload
);
2245 TRACE_LDR("Unload %wZ, LoadCount %d\n", &Module
->BaseDllName
, LoadCount
);
2249 /* ?????????????????? */
2251 else if (!(Module
->Flags
& LDRP_STATIC_LINK
) && LoadCount
== 1)
2253 BoundImportDescriptor
= (PIMAGE_BOUND_IMPORT_DESCRIPTOR
)
2254 RtlImageDirectoryEntryToData(Module
->DllBase
,
2256 IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
,
2258 if (BoundImportDescriptor
)
2260 /* dereferencing all imported modules, use the bound import descriptor */
2261 BoundImportDescriptorCurrent
= BoundImportDescriptor
;
2262 while (BoundImportDescriptorCurrent
->OffsetModuleName
)
2264 ImportedName
= (PCHAR
)BoundImportDescriptor
+ BoundImportDescriptorCurrent
->OffsetModuleName
;
2265 TRACE_LDR("%wZ trys to unload %s\n", &Module
->BaseDllName
, ImportedName
);
2266 Status
= LdrpGetOrLoadModule(NULL
, ImportedName
, &ImportedModule
, FALSE
);
2267 if (!NT_SUCCESS(Status
))
2269 DPRINT1("unable to found imported modul %s\n", ImportedName
);
2273 if (Module
!= ImportedModule
)
2275 Status
= LdrpUnloadModule(ImportedModule
, FALSE
);
2276 if (!NT_SUCCESS(Status
))
2278 DPRINT1("unable to unload %s\n", ImportedName
);
2282 BoundImportDescriptorCurrent
++;
2287 ImportModuleDirectory
= (PIMAGE_IMPORT_DESCRIPTOR
)
2288 RtlImageDirectoryEntryToData(Module
->DllBase
,
2290 IMAGE_DIRECTORY_ENTRY_IMPORT
,
2292 if (ImportModuleDirectory
)
2294 /* dereferencing all imported modules, use the import descriptor */
2295 while (ImportModuleDirectory
->Name
)
2297 ImportedName
= (PCHAR
)Module
->DllBase
+ ImportModuleDirectory
->Name
;
2298 TRACE_LDR("%wZ trys to unload %s\n", &Module
->BaseDllName
, ImportedName
);
2299 Status
= LdrpGetOrLoadModule(NULL
, ImportedName
, &ImportedModule
, FALSE
);
2300 if (!NT_SUCCESS(Status
))
2302 DPRINT1("unable to found imported modul %s\n", ImportedName
);
2306 if (Module
!= ImportedModule
)
2308 Status
= LdrpUnloadModule(ImportedModule
, FALSE
);
2309 if (!NT_SUCCESS(Status
))
2311 DPRINT1("unable to unload %s\n", ImportedName
);
2315 ImportModuleDirectory
++;
2323 if (!(Module
->Flags
& LDRP_STATIC_LINK
))
2325 LdrpDetachProcess(FALSE
);
2328 RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock
);
2330 return STATUS_SUCCESS
;
2338 LdrUnloadDll (IN PVOID BaseAddress
)
2340 PLDR_DATA_TABLE_ENTRY Module
;
2343 if (BaseAddress
== NULL
)
2344 return STATUS_SUCCESS
;
2346 if (LdrMappedAsDataFile(&BaseAddress
))
2348 Status
= NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
2352 Status
= LdrFindEntryForAddress(BaseAddress
, &Module
);
2353 if (NT_SUCCESS(Status
))
2355 TRACE_LDR("LdrUnloadDll, , unloading %wZ\n", &Module
->BaseDllName
);
2356 Status
= LdrpUnloadModule(Module
, TRUE
);
2367 LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress
)
2369 PLIST_ENTRY ModuleListHead
;
2371 PLDR_DATA_TABLE_ENTRY Module
;
2374 DPRINT("LdrDisableThreadCalloutsForDll (BaseAddress %p)\n", BaseAddress
);
2376 Status
= STATUS_DLL_NOT_FOUND
;
2377 RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock
);
2378 ModuleListHead
= &NtCurrentPeb()->Ldr
->InLoadOrderModuleList
;
2379 Entry
= ModuleListHead
->Flink
;
2380 while (Entry
!= ModuleListHead
)
2382 Module
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
2384 DPRINT("BaseDllName %wZ BaseAddress %p\n", &Module
->BaseDllName
, Module
->DllBase
);
2386 if (Module
->DllBase
== BaseAddress
)
2388 if (Module
->TlsIndex
== 0xFFFF)
2390 Module
->Flags
|= LDRP_DONT_CALL_FOR_THREADS
;
2391 Status
= STATUS_SUCCESS
;
2395 Entry
= Entry
->Flink
;
2397 RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock
);
2405 LdrGetDllHandle(IN PWSTR DllPath OPTIONAL
,
2406 IN PULONG DllCharacteristics
,
2407 IN PUNICODE_STRING DllName
,
2408 OUT PVOID
*DllHandle
)
2410 PLDR_DATA_TABLE_ENTRY Module
;
2413 TRACE_LDR("LdrGetDllHandle, searching for %wZ from %S\n",
2414 DllName
, DllPath
? DllPath
: L
"");
2416 /* NULL is the current executable */
2417 if (DllName
== NULL
)
2419 *DllHandle
= ExeModule
->DllBase
;
2420 DPRINT("BaseAddress 0x%lx\n", *DllHandle
);
2421 return STATUS_SUCCESS
;
2424 Status
= LdrFindEntryForName(DllName
, &Module
, FALSE
);
2425 if (NT_SUCCESS(Status
))
2427 *DllHandle
= Module
->DllBase
;
2428 return STATUS_SUCCESS
;
2431 DPRINT("Failed to find dll %wZ\n", DllName
);
2433 return STATUS_DLL_NOT_FOUND
;
2440 LdrAddRefDll(IN ULONG Flags
,
2441 IN PVOID BaseAddress
)
2443 PLIST_ENTRY ModuleListHead
;
2445 PLDR_DATA_TABLE_ENTRY Module
;
2448 if (Flags
& ~(LDR_PIN_MODULE
))
2450 return STATUS_INVALID_PARAMETER
;
2453 Status
= STATUS_DLL_NOT_FOUND
;
2454 RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock
);
2455 ModuleListHead
= &NtCurrentPeb()->Ldr
->InLoadOrderModuleList
;
2456 Entry
= ModuleListHead
->Flink
;
2457 while (Entry
!= ModuleListHead
)
2459 Module
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
2461 if (Module
->DllBase
== BaseAddress
)
2463 if (Flags
& LDR_PIN_MODULE
)
2465 Module
->Flags
|= LDRP_STATIC_LINK
;
2469 LdrpIncrementLoadCount(Module
,
2472 Status
= STATUS_SUCCESS
;
2475 Entry
= Entry
->Flink
;
2477 RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock
);
2485 LdrGetProcedureAddress (IN PVOID BaseAddress
,
2486 IN PANSI_STRING Name
,
2488 OUT PVOID
*ProcedureAddress
)
2490 NTSTATUS Status
= STATUS_PROCEDURE_NOT_FOUND
;
2491 if (Name
&& Name
->Length
)
2493 TRACE_LDR("LdrGetProcedureAddress by NAME - %Z\n", Name
);
2497 TRACE_LDR("LdrGetProcedureAddress by ORDINAL - %d\n", Ordinal
);
2500 DPRINT("LdrGetProcedureAddress (BaseAddress %p Name %Z Ordinal %lu ProcedureAddress %p)\n",
2501 BaseAddress
, Name
, Ordinal
, ProcedureAddress
);
2505 if (Name
&& Name
->Length
)
2508 *ProcedureAddress
= LdrGetExportByName(BaseAddress
, (PUCHAR
)Name
->Buffer
, 0xffff);
2509 if (*ProcedureAddress
!= NULL
)
2511 Status
= STATUS_SUCCESS
;
2513 DPRINT("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name
);
2518 Ordinal
&= 0x0000FFFF;
2519 *ProcedureAddress
= LdrGetExportByOrdinal(BaseAddress
, (WORD
)Ordinal
);
2520 if (*ProcedureAddress
)
2522 Status
= STATUS_SUCCESS
;
2524 DPRINT("LdrGetProcedureAddress: Can't resolve symbol @%lu\n", Ordinal
);
2527 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2529 Status
= STATUS_DLL_NOT_FOUND
;
2536 /**********************************************************************
2541 * Unload dll's which are no longer referenced from others dll's
2552 * The loader lock must be held on enty.
2555 LdrpDetachProcess(BOOLEAN UnloadAll
)
2557 PLIST_ENTRY ModuleListHead
;
2559 PLDR_DATA_TABLE_ENTRY Module
;
2560 static ULONG CallingCount
= 0;
2562 DPRINT("LdrpDetachProcess() called for %wZ\n",
2563 &ExeModule
->BaseDllName
);
2566 LdrpDllShutdownInProgress
= TRUE
;
2570 ModuleListHead
= &NtCurrentPeb()->Ldr
->InInitializationOrderModuleList
;
2571 Entry
= ModuleListHead
->Blink
;
2572 while (Entry
!= ModuleListHead
)
2574 Module
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InInitializationOrderModuleList
);
2575 if (((UnloadAll
&& Module
->LoadCount
== LDRP_PROCESS_CREATION_TIME
) || Module
->LoadCount
== 0) &&
2576 Module
->Flags
& LDRP_ENTRY_PROCESSED
&&
2577 !(Module
->Flags
& LDRP_UNLOAD_IN_PROGRESS
))
2579 Module
->Flags
|= LDRP_UNLOAD_IN_PROGRESS
;
2580 if (Module
== LdrpLastModule
)
2582 LdrpLastModule
= NULL
;
2584 if (Module
->Flags
& LDRP_PROCESS_ATTACH_CALLED
)
2586 TRACE_LDR("Unload %wZ - Calling entry point at %x\n",
2587 &Module
->BaseDllName
, Module
->EntryPoint
);
2589 /* Check if it has TLS */
2590 if (Module
->TlsIndex
)
2593 LdrpTlsCallback(Module
->DllBase
, DLL_PROCESS_ATTACH
);
2596 if ((Module
->Flags
& LDRP_IMAGE_DLL
) && Module
->EntryPoint
)
2598 LdrpCallDllEntry(Module
->EntryPoint
,
2601 (PVOID
)(Module
->LoadCount
== LDRP_PROCESS_CREATION_TIME
? 1 : 0));
2606 TRACE_LDR("Unload %wZ\n", &Module
->BaseDllName
);
2608 Entry
= ModuleListHead
->Blink
;
2612 Entry
= Entry
->Blink
;
2616 if (CallingCount
== 1)
2618 Entry
= ModuleListHead
->Blink
;
2619 while (Entry
!= ModuleListHead
)
2621 Module
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InInitializationOrderModuleList
);
2622 Entry
= Entry
->Blink
;
2623 if (Module
->Flags
& LDRP_UNLOAD_IN_PROGRESS
&&
2624 ((UnloadAll
&& Module
->LoadCount
!= LDRP_PROCESS_CREATION_TIME
) || Module
->LoadCount
== 0))
2626 /* remove the module entry from the list */
2627 RemoveEntryList (&Module
->InLoadOrderLinks
);
2628 RemoveEntryList (&Module
->InInitializationOrderModuleList
);
2630 NtUnmapViewOfSection (NtCurrentProcess (), Module
->DllBase
);
2631 NtClose (Module
->SectionPointer
);
2633 TRACE_LDR("%wZ unloaded\n", &Module
->BaseDllName
);
2635 RtlFreeUnicodeString (&Module
->FullDllName
);
2636 RtlFreeUnicodeString (&Module
->BaseDllName
);
2638 RtlFreeHeap (RtlGetProcessHeap (), 0, Module
);
2643 DPRINT("LdrpDetachProcess() done\n");
2646 /**********************************************************************
2651 * Initialize all dll's which are prepered for loading
2662 * The loader lock must be held on entry.
2666 LdrpAttachProcess(VOID
)
2668 PLIST_ENTRY ModuleListHead
;
2670 PLDR_DATA_TABLE_ENTRY Module
;
2672 NTSTATUS Status
= STATUS_SUCCESS
;
2674 DPRINT("LdrpAttachProcess() called for %wZ\n",
2675 &ExeModule
->BaseDllName
);
2677 ModuleListHead
= &NtCurrentPeb()->Ldr
->InInitializationOrderModuleList
;
2678 Entry
= ModuleListHead
->Flink
;
2679 while (Entry
!= ModuleListHead
)
2681 Module
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InInitializationOrderModuleList
);
2682 if (!(Module
->Flags
& (LDRP_LOAD_IN_PROGRESS
|LDRP_UNLOAD_IN_PROGRESS
|LDRP_ENTRY_PROCESSED
)))
2684 Module
->Flags
|= LDRP_LOAD_IN_PROGRESS
;
2685 TRACE_LDR("%wZ loaded - Calling init routine at %x for process attaching\n",
2686 &Module
->BaseDllName
, Module
->EntryPoint
);
2688 /* Check if it has TLS */
2689 if (Module
->TlsIndex
&& FALSE
/*Context*/)
2692 LdrpTlsCallback(Module
->DllBase
, DLL_PROCESS_ATTACH
);
2695 if ((Module
->Flags
& LDRP_IMAGE_DLL
) && Module
->EntryPoint
)
2696 Result
= LdrpCallDllEntry(Module
->EntryPoint
, Module
->DllBase
, DLL_PROCESS_ATTACH
, (PVOID
)(Module
->LoadCount
== LDRP_PROCESS_CREATION_TIME
? 1 : 0));
2702 Status
= STATUS_DLL_INIT_FAILED
;
2705 if (Module
->Flags
& LDRP_IMAGE_DLL
&& Module
->EntryPoint
!= 0)
2707 Module
->Flags
|= LDRP_PROCESS_ATTACH_CALLED
|LDRP_ENTRY_PROCESSED
;
2711 Module
->Flags
|= LDRP_ENTRY_PROCESSED
;
2713 Module
->Flags
&= ~LDRP_LOAD_IN_PROGRESS
;
2715 Entry
= Entry
->Flink
;
2718 DPRINT("LdrpAttachProcess() done\n");
2727 RtlDllShutdownInProgress (VOID
)
2729 return LdrpDllShutdownInProgress
;
2736 LdrShutdownProcess (VOID
)
2738 LdrpDetachProcess(TRUE
);
2739 return STATUS_SUCCESS
;
2747 LdrpAttachThread (VOID
)
2749 PLIST_ENTRY ModuleListHead
;
2751 PLDR_DATA_TABLE_ENTRY Module
;
2754 DPRINT("LdrpAttachThread() called for %wZ\n",
2755 &ExeModule
->BaseDllName
);
2757 RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock
);
2759 Status
= LdrpAllocateTls();
2761 if (NT_SUCCESS(Status
))
2763 ModuleListHead
= &NtCurrentPeb()->Ldr
->InInitializationOrderModuleList
;
2764 Entry
= ModuleListHead
->Flink
;
2766 while (Entry
!= ModuleListHead
)
2768 Module
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InInitializationOrderModuleList
);
2769 if (Module
->Flags
& LDRP_PROCESS_ATTACH_CALLED
&&
2770 !(Module
->Flags
& LDRP_DONT_CALL_FOR_THREADS
) &&
2771 !(Module
->Flags
& LDRP_UNLOAD_IN_PROGRESS
))
2773 TRACE_LDR("%wZ - Calling entry point at %x for thread attaching\n",
2774 &Module
->BaseDllName
, Module
->EntryPoint
);
2776 /* Check if it has TLS */
2777 if (Module
->TlsIndex
)
2780 LdrpTlsCallback(Module
->DllBase
, DLL_THREAD_ATTACH
);
2783 if ((Module
->Flags
& LDRP_IMAGE_DLL
) && Module
->EntryPoint
)
2784 LdrpCallDllEntry(Module
->EntryPoint
, Module
->DllBase
, DLL_THREAD_ATTACH
, NULL
);
2786 Entry
= Entry
->Flink
;
2789 Entry
= NtCurrentPeb()->Ldr
->InLoadOrderModuleList
.Flink
;
2790 Module
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
2791 LdrpTlsCallback(Module
->DllBase
, DLL_THREAD_ATTACH
);
2794 RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock
);
2796 DPRINT("LdrpAttachThread() done\n");
2806 LdrShutdownThread (VOID
)
2808 PLIST_ENTRY ModuleListHead
;
2810 PLDR_DATA_TABLE_ENTRY Module
;
2812 DPRINT("LdrShutdownThread() called for %wZ\n",
2813 &ExeModule
->BaseDllName
);
2815 RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock
);
2817 ModuleListHead
= &NtCurrentPeb()->Ldr
->InInitializationOrderModuleList
;
2818 Entry
= ModuleListHead
->Blink
;
2819 while (Entry
!= ModuleListHead
)
2821 Module
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InInitializationOrderModuleList
);
2823 if (Module
->Flags
& LDRP_PROCESS_ATTACH_CALLED
&&
2824 !(Module
->Flags
& LDRP_DONT_CALL_FOR_THREADS
) &&
2825 !(Module
->Flags
& LDRP_UNLOAD_IN_PROGRESS
))
2827 TRACE_LDR("%wZ - Calling entry point at %x for thread detaching\n",
2828 &Module
->BaseDllName
, Module
->EntryPoint
);
2829 /* Check if it has TLS */
2830 if (Module
->TlsIndex
)
2833 LdrpTlsCallback(Module
->DllBase
, DLL_THREAD_DETACH
);
2836 if ((Module
->Flags
& LDRP_IMAGE_DLL
) && Module
->EntryPoint
)
2837 LdrpCallDllEntry(Module
->EntryPoint
, Module
->DllBase
, DLL_THREAD_DETACH
, NULL
);
2839 Entry
= Entry
->Blink
;
2844 RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock
);
2846 DPRINT("LdrShutdownThread() done\n");
2848 return STATUS_SUCCESS
;
2852 /***************************************************************************
2854 * LdrQueryProcessModuleInformation
2869 LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation OPTIONAL
,
2870 IN ULONG Size OPTIONAL
,
2871 OUT PULONG ReturnedSize
)
2873 PLIST_ENTRY ModuleListHead
;
2875 PLDR_DATA_TABLE_ENTRY Module
;
2876 PRTL_PROCESS_MODULE_INFORMATION ModulePtr
= NULL
;
2877 NTSTATUS Status
= STATUS_SUCCESS
;
2878 ULONG UsedSize
= sizeof(ULONG
);
2879 ANSI_STRING AnsiString
;
2882 DPRINT("LdrQueryProcessModuleInformation() called\n");
2883 // FIXME: This code is ultra-duplicated. see lib\rtl\dbgbuffer.c
2884 RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock
);
2886 if (ModuleInformation
== NULL
|| Size
== 0)
2888 Status
= STATUS_INFO_LENGTH_MISMATCH
;
2892 ModuleInformation
->NumberOfModules
= 0;
2893 ModulePtr
= &ModuleInformation
->Modules
[0];
2894 Status
= STATUS_SUCCESS
;
2897 ModuleListHead
= &NtCurrentPeb()->Ldr
->InLoadOrderModuleList
;
2898 Entry
= ModuleListHead
->Flink
;
2900 while (Entry
!= ModuleListHead
)
2902 Module
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
2904 DPRINT(" Module %wZ\n",
2905 &Module
->FullDllName
);
2907 if (UsedSize
> Size
)
2909 Status
= STATUS_INFO_LENGTH_MISMATCH
;
2911 else if (ModuleInformation
!= NULL
)
2913 ModulePtr
->Section
= 0;
2914 ModulePtr
->MappedBase
= NULL
; // FIXME: ??
2915 ModulePtr
->ImageBase
= Module
->DllBase
;
2916 ModulePtr
->ImageSize
= Module
->SizeOfImage
;
2917 ModulePtr
->Flags
= Module
->Flags
;
2918 ModulePtr
->LoadOrderIndex
= 0; // FIXME: ??
2919 ModulePtr
->InitOrderIndex
= 0; // FIXME: ??
2920 ModulePtr
->LoadCount
= Module
->LoadCount
;
2922 AnsiString
.Length
= 0;
2923 AnsiString
.MaximumLength
= 256;
2924 AnsiString
.Buffer
= ModulePtr
->FullPathName
;
2925 RtlUnicodeStringToAnsiString(&AnsiString
,
2926 &Module
->FullDllName
,
2929 p
= strrchr(ModulePtr
->FullPathName
, '\\');
2931 ModulePtr
->OffsetToFileName
= p
- ModulePtr
->FullPathName
+ 1;
2933 ModulePtr
->OffsetToFileName
= 0;
2936 ModuleInformation
->NumberOfModules
++;
2938 UsedSize
+= sizeof(RTL_PROCESS_MODULE_INFORMATION
);
2940 Entry
= Entry
->Flink
;
2943 RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock
);
2945 if (ReturnedSize
!= 0)
2946 *ReturnedSize
= UsedSize
;
2948 DPRINT("LdrQueryProcessModuleInformation() done\n");
2955 LdrpCheckImageChecksum (IN PVOID BaseAddress
,
2958 PIMAGE_NT_HEADERS Header
;
2965 Header
= RtlImageNtHeader (BaseAddress
);
2969 HeaderSum
= Header
->OptionalHeader
.CheckSum
;
2974 Ptr
= (PUSHORT
) BaseAddress
;
2975 for (i
= 0; i
< ImageSize
/ sizeof (USHORT
); i
++)
2978 if (HIWORD(Sum
) != 0)
2980 Sum
= LOWORD(Sum
) + HIWORD(Sum
);
2987 Sum
+= (ULONG
)*((PUCHAR
)Ptr
);
2988 if (HIWORD(Sum
) != 0)
2990 Sum
= LOWORD(Sum
) + HIWORD(Sum
);
2994 CalcSum
= (USHORT
)(LOWORD(Sum
) + HIWORD(Sum
));
2996 /* Subtract image checksum from calculated checksum. */
2997 /* fix low word of checksum */
2998 if (LOWORD(CalcSum
) >= LOWORD(HeaderSum
))
3000 CalcSum
-= LOWORD(HeaderSum
);
3004 CalcSum
= ((LOWORD(CalcSum
) - LOWORD(HeaderSum
)) & 0xFFFF) - 1;
3007 /* fix high word of checksum */
3008 if (LOWORD(CalcSum
) >= HIWORD(HeaderSum
))
3010 CalcSum
-= HIWORD(HeaderSum
);
3014 CalcSum
= ((LOWORD(CalcSum
) - HIWORD(HeaderSum
)) & 0xFFFF) - 1;
3017 /* add file length */
3018 CalcSum
+= ImageSize
;
3020 return (BOOLEAN
)(CalcSum
== HeaderSum
);
3024 * Compute size of an image as it is actually present in virt memory
3025 * (i.e. excluding NEVER_LOAD sections)
3028 LdrpGetResidentSize(PIMAGE_NT_HEADERS NTHeaders
)
3030 PIMAGE_SECTION_HEADER SectionHeader
;
3031 unsigned SectionIndex
;
3034 SectionHeader
= (PIMAGE_SECTION_HEADER
)((char *) &NTHeaders
->OptionalHeader
3035 + NTHeaders
->FileHeader
.SizeOfOptionalHeader
);
3037 for (SectionIndex
= 0;
3038 SectionIndex
< NTHeaders
->FileHeader
.NumberOfSections
;
3041 if (0 == (SectionHeader
->Characteristics
& IMAGE_SCN_LNK_REMOVE
)
3042 && ResidentSize
< SectionHeader
->VirtualAddress
+ SectionHeader
->Misc
.VirtualSize
)
3044 ResidentSize
= SectionHeader
->VirtualAddress
+ SectionHeader
->Misc
.VirtualSize
;
3049 return ResidentSize
;
3053 /***************************************************************************
3055 * LdrVerifyImageMatchesChecksum
3070 LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle
,
3071 IN PLDR_CALLBACK Callback
,
3072 IN PVOID CallbackContext
,
3073 OUT PUSHORT ImageCharacterstics
)
3075 FILE_STANDARD_INFORMATION FileInfo
;
3076 IO_STATUS_BLOCK IoStatusBlock
;
3077 HANDLE SectionHandle
;
3083 DPRINT ("LdrVerifyImageMatchesChecksum() called\n");
3085 Status
= NtCreateSection (&SectionHandle
,
3092 if (!NT_SUCCESS(Status
))
3094 DPRINT1 ("NtCreateSection() failed (Status %lx)\n", Status
);
3100 Status
= NtMapViewOfSection (SectionHandle
,
3101 NtCurrentProcess (),
3110 if (!NT_SUCCESS(Status
))
3112 DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status
);
3113 NtClose (SectionHandle
);
3117 Status
= NtQueryInformationFile(FileHandle
,
3120 sizeof (FILE_STANDARD_INFORMATION
),
3121 FileStandardInformation
);
3122 if (!NT_SUCCESS(Status
))
3124 DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status
);
3125 NtUnmapViewOfSection (NtCurrentProcess(),
3127 NtClose (SectionHandle
);
3131 Result
= LdrpCheckImageChecksum(BaseAddress
,
3132 FileInfo
.EndOfFile
.u
.LowPart
);
3133 if (Result
== FALSE
)
3135 Status
= STATUS_IMAGE_CHECKSUM_MISMATCH
;
3138 NtUnmapViewOfSection (NtCurrentProcess(),
3141 NtClose(SectionHandle
);
3146 PIMAGE_BASE_RELOCATION
3148 LdrProcessRelocationBlock(
3149 IN ULONG_PTR Address
,
3151 IN PUSHORT TypeOffset
,
3154 return LdrProcessRelocationBlockLongLong(Address
, Count
, TypeOffset
, Delta
);
3159 LdrUnloadAlternateResourceModule(IN PVOID BaseAddress
)