ReactOS 0.4.17-dev-357-ga8f14ff
ldrapi.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NT User Mode Library
4 * FILE: dll/ntdll/ldr/ldrapi.c
5 * PURPOSE: PE Loader Public APIs
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * Aleksey Bragin (aleksey@reactos.org)
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include <ntdll.h>
13
14#define NDEBUG
15#include <debug.h>
16
17/* GLOBALS *******************************************************************/
18
25
26/* FUNCTIONS *****************************************************************/
27
32 IN PVOID IdPath,
33 IN ULONG IdPathLength,
34 IN PVOID OutDataEntry)
35{
38}
39
43{
46}
47
52 IN HANDLE DllHandle,
54{
57}
58
63 IN PVOID Unknown1,
64 IN PVOID Unknown2,
66{
69}
70
71VOID
75{
77}
78
82{
83 /* ReactOS does not support this */
84 return FALSE;
85}
86
90{
91 /* Generate a cookie */
92 return (((ULONG_PTR)NtCurrentTeb()->RealClientId.UniqueThread & 0xFFF) << 16) |
94}
95
96/*
97 * @implemented
98 */
100NTAPI
104{
106
107 DPRINT("LdrUnlockLoaderLock(%x %Ix)\n", Flags, Cookie);
108
109 /* Check for valid flags */
111 {
112 /* Flags are invalid, check how to fail */
114 {
115 /* The caller wants us to raise status */
117 }
118
119 /* A normal failure */
121 }
122
123 /* If we don't have a cookie, just return */
124 if (!Cookie) return STATUS_SUCCESS;
125
126 /* Validate the cookie */
127 if ((Cookie & 0xF0000000) ||
128 ((Cookie >> 16) ^ (HandleToUlong(NtCurrentTeb()->RealClientId.UniqueThread) & 0xFFF)))
129 {
130 DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n");
131
132 /* Invalid cookie, check how to fail */
134 {
135 /* The caller wants us to raise status */
137 }
138
139 /* A normal failure */
141 }
142
143 /* Ready to release the lock */
145 {
146 /* Do a direct leave */
148 }
149 else
150 {
151 /* Wrap this in SEH, since we're not supposed to raise */
153 {
154 /* Leave the lock */
156 }
158 {
159 /* We should use the LDR Filter instead */
161 }
162 _SEH2_END;
163 }
164
165 /* All done */
166 return Status;
167}
168
169/*
170 * @implemented
171 */
173NTAPI
178{
180 BOOLEAN InInit = LdrpInLdrInit;
181
182 DPRINT("LdrLockLoaderLock(%x %p %p)\n", Flags, Disposition, Cookie);
183
184 /* Zero out the outputs */
186 if (Cookie) *Cookie = 0;
187
188 /* Validate the flags */
191 {
192 /* Flags are invalid, check how to fail */
194 {
195 /* The caller wants us to raise status */
197 }
198
199 /* A normal failure */
201 }
202
203 /* Make sure we got a cookie */
204 if (!Cookie)
205 {
206 /* No cookie check how to fail */
208 {
209 /* The caller wants us to raise status */
211 }
212
213 /* A normal failure */
215 }
216
217 /* If the flag is set, make sure we have a valid pointer to use */
219 {
220 /* No pointer to return the data to */
222 {
223 /* The caller wants us to raise status */
225 }
226
227 /* Fail */
229 }
230
231 /* Return now if we are in the init phase */
232 if (InInit) return STATUS_SUCCESS;
233
234 /* Check what locking semantic to use */
236 {
237 /* Check if we should enter or simply try */
239 {
240 /* Do a try */
242 {
243 /* It's locked */
245 }
246 else
247 {
248 /* It worked */
251 }
252 }
253 else
254 {
255 /* Do a enter */
257
258 /* See if result was requested */
261 }
262 }
263 else
264 {
265 /* Wrap this in SEH, since we're not supposed to raise */
267 {
268 /* Check if we should enter or simply try */
270 {
271 /* Do a try */
273 {
274 /* It's locked */
276 }
277 else
278 {
279 /* It worked */
282 }
283 }
284 else
285 {
286 /* Do an enter */
288
289 /* See if result was requested */
292 }
293 }
295 {
296 /* We should use the LDR Filter instead */
298 }
299 _SEH2_END;
300 }
301
302 /* Return status */
303 return Status;
304}
305
306/*
307 * @implemented
308 */
310NTAPI
314 _In_opt_ PULONG DllCharacteristics,
315 _In_ PUNICODE_STRING DllName,
317{
320 BOOLEAN RedirectedDll = FALSE;
323 PUNICODE_STRING OldTldDll;
324 PTEB Teb = NtCurrentTeb();
325
326 /* Initialize the strings */
327 RtlInitEmptyUnicodeString(&StaticString, StringBuffer, sizeof(StringBuffer));
328 RtlInitEmptyUnicodeString(&DynamicString, NULL, 0);
329
331
332 /* Lock the loader lock */
334
335 /* Check if there's a TLD DLL being loaded */
336 OldTldDll = LdrpTopLevelDllBeingLoaded;
338 {
339
340 if (OldTldDll)
341 {
342 /* This is a recursive load, do something about it? */
344 {
345 /* Print out debug messages */
346 DPRINT1("[%p, %p] LDR: Recursive DLL Load\n",
349 DPRINT1("[%p, %p] Previous DLL being loaded \"%wZ\"\n",
352 OldTldDll);
353 DPRINT1("[%p, %p] DLL being requested \"%wZ\"\n",
356 DllName);
357
358 /* Was it initializing too? */
360 {
361 DPRINT1("[%p, %p] LDR: No DLL Initializer was running\n",
364 }
365 else
366 {
367 DPRINT1("[%p, %p] DLL whose initializer was currently running \"%wZ\"\n",
371 }
372 }
373 }
374
375 /* Set this one as the TLD DLL being loaded*/
377
378 /* Load the DLL */
379 Status = LdrpLoadDll(RedirectedDll,
381 DllCharacteristics,
382 DllName,
384 TRUE);
385 if (NT_SUCCESS(Status))
386 {
388 }
389 else if ((Status != STATUS_NO_SUCH_FILE) &&
393 {
396 "LDR: %s - failing because LdrpLoadDll(%wZ) returned status %x\n",
398 DllName,
399 Status);
400 }
401 }
403 {
404 /* Restore the old TLD DLL */
405 LdrpTopLevelDllBeingLoaded = OldTldDll;
406
407 /* Release the lock */
409 }
410 _SEH2_END;
411
412 /* Do we have a redirect string? */
415
416 /* Return */
417 return Status;
418}
419
420/*
421 * @implemented
422 */
424NTAPI
428{
429 PLIST_ENTRY ListHead, NextEntry;
430 PLDR_DATA_TABLE_ENTRY LdrEntry;
431 PIMAGE_NT_HEADERS NtHeader;
432 PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr;
433 ULONG_PTR DllBase, DllEnd;
434
435 DPRINT("LdrFindEntryForAddress(Address %p)\n", Address);
436
437 /* Nothing to do */
438 if (!Ldr) return STATUS_NO_MORE_ENTRIES;
439
440 /* Get the current entry */
441 LdrEntry = Ldr->EntryInProgress;
442 if (LdrEntry)
443 {
444 /* Get the NT Headers */
445 NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
446 if (NtHeader)
447 {
448 /* Get the Image Base */
449 DllBase = (ULONG_PTR)LdrEntry->DllBase;
450 DllEnd = DllBase + NtHeader->OptionalHeader.SizeOfImage;
451
452 /* Check if they match */
453 if (((ULONG_PTR)Address >= DllBase) &&
454 ((ULONG_PTR)Address < DllEnd))
455 {
456 /* Return it */
457 *Module = LdrEntry;
458 return STATUS_SUCCESS;
459 }
460 }
461 }
462
463 /* Loop the module list */
464 ListHead = &Ldr->InMemoryOrderModuleList;
465 NextEntry = ListHead->Flink;
466 while (NextEntry != ListHead)
467 {
468 /* Get the entry and NT Headers */
469 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
470 NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
471 if (NtHeader)
472 {
473 /* Get the Image Base */
474 DllBase = (ULONG_PTR)LdrEntry->DllBase;
475 DllEnd = DllBase + NtHeader->OptionalHeader.SizeOfImage;
476
477 /* Check if they match */
478 if (((ULONG_PTR)Address >= DllBase) &&
479 ((ULONG_PTR)Address < DllEnd))
480 {
481 /* Return it */
482 *Module = LdrEntry;
483 return STATUS_SUCCESS;
484 }
485
486 /* Next Entry */
487 NextEntry = NextEntry->Flink;
488 }
489 }
490
491 /* Nothing found */
494 "LDR: %s() exiting 0x%08lx\n",
498}
499
500/*
501 * @implemented
502 */
504NTAPI
508 _In_opt_ PULONG DllCharacteristics,
509 _In_ PUNICODE_STRING DllName,
510 _Out_opt_ PVOID *DllHandle)
511{
513 PLDR_DATA_TABLE_ENTRY LdrEntry;
514 UNICODE_STRING RedirectName, DynamicString, RawDllName;
515 PUNICODE_STRING pRedirectName, CompareName;
516 PWCHAR p1, p2, p3;
517 BOOLEAN Locked, RedirectedDll;
519 ULONG LoadFlag, Length;
520
521 /* Initialize the strings */
522 RtlInitEmptyUnicodeString(&DynamicString, NULL, 0);
523 RtlInitEmptyUnicodeString(&RawDllName, NULL, 0);
524 RedirectName = *DllName;
525 pRedirectName = &RedirectName;
526
527 /* Initialize state */
528 RedirectedDll = Locked = FALSE;
529 LdrEntry = NULL;
530 Cookie = 0;
531
532 /* Clear the handle */
533 if (DllHandle) *DllHandle = NULL;
534
535 /* Check for a valid flag combination */
537 (!DllHandle && !(Flags & LDR_GET_DLL_HANDLE_EX_PIN)))
538 {
539 DPRINT1("Flags are invalid or no DllHandle given\n");
541 goto Quickie;
542 }
543
544 /* If not initializing */
545 if (!LdrpInLdrInit)
546 {
547 /* Acquire the lock */
549 if (!NT_SUCCESS(Status)) goto Quickie;
550
551 /* Remember we own it */
552 Locked = TRUE;
553 }
554
556 pRedirectName, &LdrApiDefaultExtension, NULL, &DynamicString, &pRedirectName, &RedirectedDll);
557 if (!NT_SUCCESS(Status))
558 {
559 DPRINT1("LdrpApplyFileNameRedirection FAILED: (Status 0x%x)\n", Status);
560 goto Quickie;
561 }
562
563 /* Set default failure code */
565
566 /* Use the cache if we can */
568 {
569 /* Check if we were redirected */
570 if (RedirectedDll)
571 {
572 /* Check the flag */
574 {
575 goto DontCompare;
576 }
577
578 /* Use the right name */
580 }
581 else
582 {
583 /* Check the flag */
585 {
586 goto DontCompare;
587 }
588
589 /* Use the right name */
591 }
592
593 /* Check if the name matches */
594 if (RtlEqualUnicodeString(pRedirectName,
596 TRUE))
597 {
598 /* Skip the rest */
599 LdrEntry = LdrpGetModuleHandleCache;
600
601 /* Return success */
603 goto Quickie;
604 }
605 }
606
607DontCompare:
608 /* Find the name without the extension */
609 p1 = pRedirectName->Buffer;
610 p2 = NULL;
611 p3 = &p1[pRedirectName->Length / sizeof(WCHAR)];
612 while (p1 != p3)
613 {
614 if (*p1++ == L'.')
615 {
616 p2 = p1;
617 }
618 else if (*p1 == L'\\')
619 {
620 p2 = NULL;
621 }
622 }
623
624 /* Check if no extension was found or if we got a slash */
625 if (!(p2) || (*p2 == L'\\') || (*p2 == L'/'))
626 {
627 /* Check that we have space to add one */
628 Length = pRedirectName->Length +
631 {
632 /* No space to add the extension */
634 goto Quickie;
635 }
636
637 /* Setup the string */
638 RawDllName.MaximumLength = Length;
639 ASSERT(Length >= sizeof(UNICODE_NULL));
640 RawDllName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
641 0,
642 RawDllName.MaximumLength);
643 if (!RawDllName.Buffer)
644 {
646 goto Quickie;
647 }
648
649 /* Copy the string and add extension */
650 RtlCopyUnicodeString(&RawDllName, pRedirectName);
652 }
653 else
654 {
655 /* Check if there's something in the name */
656 Length = pRedirectName->Length;
657 if (Length)
658 {
659 /* Check and remove trailing period */
660 if (pRedirectName->Buffer[Length / sizeof(WCHAR) - sizeof(ANSI_NULL)] == '.')
661 {
662 /* Decrease the size */
663 pRedirectName->Length -= sizeof(WCHAR);
664 }
665 }
666
667 /* Setup the string */
668 RawDllName.MaximumLength = pRedirectName->Length + sizeof(WCHAR);
669 RawDllName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
670 0,
671 RawDllName.MaximumLength);
672 if (!RawDllName.Buffer)
673 {
675 goto Quickie;
676 }
677
678 /* Copy the string */
679 RtlCopyUnicodeString(&RawDllName, pRedirectName);
680 }
681
682 /* Display debug string */
683 if (ShowSnaps)
684 {
685 DPRINT1("LDR: LdrGetDllHandleEx, searching for %wZ from %ws\n",
686 &RawDllName,
687 DllPath ? ((ULONG_PTR)DllPath == 1 ? L"" : DllPath) : L"");
688 }
689
690 /* Do the lookup */
692 &RawDllName,
693 ((ULONG_PTR)DllPath == 1) ? TRUE : FALSE,
694 RedirectedDll,
695 &LdrEntry))
696 {
697 /* Update cached entry */
698 LdrpGetModuleHandleCache = LdrEntry;
699
700 /* Return success */
702 }
703 else
704 {
705 /* Make sure to NULL this */
706 LdrEntry = NULL;
707 }
708Quickie:
709 /* The success path must have a valid loader entry */
710 ASSERT((LdrEntry != NULL) == NT_SUCCESS(Status));
711
712 /* Check if we got an entry and success */
713 DPRINT("Got LdrEntry->BaseDllName %wZ\n", LdrEntry ? &LdrEntry->BaseDllName : NULL);
714 if ((LdrEntry) && (NT_SUCCESS(Status)))
715 {
716 /* Check if the DLL is locked */
717 if ((LdrEntry->LoadCount != 0xFFFF) &&
719 {
720 /* Check what to do with the load count */
722 {
723 /* Pin it */
724 LdrEntry->LoadCount = 0xFFFF;
725 LoadFlag = LDRP_UPDATE_PIN;
726 }
727 else
728 {
729 /* Increase the load count */
730 LdrEntry->LoadCount++;
731 LoadFlag = LDRP_UPDATE_REFCOUNT;
732 }
733
734 /* Update the load count now */
735 LdrpUpdateLoadCount2(LdrEntry, LoadFlag);
737 }
738
739 /* Check if the caller is requesting the handle */
740 if (DllHandle) *DllHandle = LdrEntry->DllBase;
741 }
742
743 /* Free string if needed */
745
746 /* Free the raw DLL Name if needed */
747 if (RawDllName.Buffer)
748 {
749 /* Free the heap-allocated buffer */
750 RtlFreeHeap(RtlGetProcessHeap(), 0, RawDllName.Buffer);
751 RawDllName.Buffer = NULL;
752 }
753
754 /* Release lock */
755 if (Locked)
756 {
758 Cookie);
759 }
760
761 /* Return */
762 return Status;
763}
764
765/*
766 * @implemented
767 */
769NTAPI
772 _In_opt_ PULONG DllCharacteristics,
773 _In_ PUNICODE_STRING DllName,
774 _Out_ PVOID *DllHandle)
775{
776 /* Call the newer API */
778 DllPath,
779 DllCharacteristics,
780 DllName,
781 DllHandle);
782}
783
784/*
785 * @implemented
786 */
788NTAPI
792 _In_opt_ _When_(Name == NULL, _In_range_(>, 0)) ULONG Ordinal,
793 _Out_ PVOID *ProcedureAddress)
794{
795 /* Call the internal routine and tell it to execute DllInit */
796 return LdrpGetProcedureAddress(BaseAddress, Name, Ordinal, ProcedureAddress, TRUE);
797}
798
800NTAPI
804 _In_opt_ _When_(Name == NULL, _In_range_(>, 0)) ULONG Ordinal,
805 _Out_ PVOID *ProcedureAddress,
807{
808 /* Call the internal routine and execute DllInit depending of flags */
810 return LdrpGetProcedureAddress(BaseAddress, Name, Ordinal, ProcedureAddress, ExecuteInit);
811}
812
813/*
814 * @implemented
815 */
817NTAPI
822 _Out_ PUSHORT ImageCharacteristics)
823{
825 PIMAGE_IMPORT_DESCRIPTOR ImportData;
826 PIMAGE_SECTION_HEADER LastSection = NULL;
828 PIMAGE_NT_HEADERS NtHeader;
829 HANDLE SectionHandle;
831 PVOID ViewBase;
832 BOOLEAN Result, NoActualCheck;
834 PVOID ImportName;
835 ULONG Size;
836 DPRINT("LdrVerifyImageMatchesChecksum() called\n");
837
838 /* If the handle has the magic KnownDll flag, skip actual checksums */
839 NoActualCheck = ((ULONG_PTR)FileHandle & 1);
840
841 /* Create the section */
842 Status = NtCreateSection(&SectionHandle,
844 NULL,
845 NULL,
848 FileHandle);
849 if (!NT_SUCCESS(Status))
850 {
851 DPRINT1 ("NtCreateSection() failed (Status 0x%x)\n", Status);
852 return Status;
853 }
854
855 /* Map the section */
856 ViewSize = 0;
857 ViewBase = NULL;
858 Status = NtMapViewOfSection(SectionHandle,
860 &ViewBase,
861 0,
862 0,
863 NULL,
864 &ViewSize,
865 ViewShare,
866 0,
868 if (!NT_SUCCESS(Status))
869 {
870 DPRINT1("NtMapViewOfSection() failed (Status 0x%x)\n", Status);
871 NtClose(SectionHandle);
872 return Status;
873 }
874
875 /* Get the file information */
881 if (!NT_SUCCESS(Status))
882 {
883 DPRINT1("NtMapViewOfSection() failed (Status 0x%x)\n", Status);
885 NtClose(SectionHandle);
886 return Status;
887 }
888
889 /* Protect with SEH */
891 {
892 /* Check if this is the KnownDll hack */
893 if (NoActualCheck)
894 {
895 /* Don't actually do it */
896 Result = TRUE;
897 }
898 else
899 {
900 /* Verify the checksum */
902 FileStandardInfo.EndOfFile.LowPart,
903 FileStandardInfo.EndOfFile.LowPart);
904 }
905
906 /* Check if a callback was supplied */
907 if ((Result) && (Callback))
908 {
909 /* Get the NT Header */
910 NtHeader = RtlImageNtHeader(ViewBase);
911
912 /* Check if caller requested this back */
913 if (ImageCharacteristics)
914 {
915 /* Return to caller */
916 *ImageCharacteristics = NtHeader->FileHeader.Characteristics;
917 }
918
919 /* Get the Import Directory Data */
920 ImportData = RtlImageDirectoryEntryToData(ViewBase,
921 FALSE,
923 &Size);
924
925 /* Make sure there is one */
926 if (ImportData)
927 {
928 /* Loop the imports */
929 while (ImportData->Name)
930 {
931 /* Get the name */
932 ImportName = RtlImageRvaToVa(NtHeader,
933 ViewBase,
934 ImportData->Name,
935 &LastSection);
936
937 /* Notify the callback */
938 Callback(CallbackContext, ImportName);
939 ImportData++;
940 }
941 }
942 }
943 }
945 {
946 /* Fail the request returning STATUS_IMAGE_CHECKSUM_MISMATCH */
947 Result = FALSE;
948 }
949 _SEH2_END;
950
951 /* Unmap file and close handle */
953 NtClose(SectionHandle);
954
955 /* Return status */
957}
958
960NTAPI
967{
968 PLIST_ENTRY ModuleListHead, InitListHead;
969 PLIST_ENTRY Entry, InitEntry;
970 PLDR_DATA_TABLE_ENTRY Module, InitModule;
973 ULONG UsedSize = FIELD_OFFSET(RTL_PROCESS_MODULES, Modules);
975 PCHAR p;
976
977 DPRINT("LdrQueryProcessModuleInformation() called\n");
978
979 /* Acquire loader lock */
981
983 {
984 /* Check if we were given enough space */
985 if (Size < UsedSize)
986 {
988 }
989 else
990 {
991 ModuleInformation->NumberOfModules = 0;
992 ModulePtr = &ModuleInformation->Modules[0];
994 }
995
996 /* Traverse the list of modules */
997 ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
999
1000 while (Entry != ModuleListHead)
1001 {
1002 Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1003
1004 DPRINT(" Module %wZ\n", &Module->FullDllName);
1005
1006 /* Increase the used size */
1007 UsedSize += sizeof(RTL_PROCESS_MODULE_INFORMATION);
1008
1009 if (UsedSize > Size)
1010 {
1012 }
1013 else
1014 {
1015 ModulePtr->ImageBase = Module->DllBase;
1016 ModulePtr->ImageSize = Module->SizeOfImage;
1017 ModulePtr->Flags = Module->Flags;
1018 ModulePtr->LoadCount = Module->LoadCount;
1019 ModulePtr->MappedBase = NULL;
1020 ModulePtr->InitOrderIndex = 0;
1021 ModulePtr->LoadOrderIndex = ModuleInformation->NumberOfModules;
1022
1023 /* Now get init order index by traversing init list */
1024 InitListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
1025 InitEntry = InitListHead->Flink;
1026
1027 while (InitEntry != InitListHead)
1028 {
1029 InitModule = CONTAINING_RECORD(InitEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1030
1031 /* Increase the index */
1032 ModulePtr->InitOrderIndex++;
1033
1034 /* Quit the loop if our module is found */
1035 if (InitModule == Module) break;
1036
1037 /* Advance to the next entry */
1038 InitEntry = InitEntry->Flink;
1039 }
1040
1041 /* Prepare ANSI string with the module's name */
1042 AnsiString.Length = 0;
1043 AnsiString.MaximumLength = sizeof(ModulePtr->FullPathName);
1044 AnsiString.Buffer = ModulePtr->FullPathName;
1046 &Module->FullDllName,
1047 FALSE);
1048
1049 /* Calculate OffsetToFileName field */
1050 p = strrchr(ModulePtr->FullPathName, '\\');
1051 if (p != NULL)
1052 ModulePtr->OffsetToFileName = p - ModulePtr->FullPathName + 1;
1053 else
1054 ModulePtr->OffsetToFileName = 0;
1055
1056 /* Advance to the next module in the output list */
1057 ModulePtr++;
1058
1059 /* Increase number of modules */
1060 if (ModuleInformation)
1061 ModuleInformation->NumberOfModules++;
1062 }
1063
1064 /* Go to the next entry in the modules list */
1065 Entry = Entry->Flink;
1066 }
1067
1068 /* Set returned size if it was provided */
1069 if (ReturnedSize)
1070 *ReturnedSize = UsedSize;
1071 }
1073 {
1074 /* Ignoring the exception */
1075 } _SEH2_END;
1076
1077 /* Release the lock */
1079
1080 DPRINT("LdrQueryProcessModuleInformation() done\n");
1081
1082 return Status;
1083}
1084
1085/*
1086 * @implemented
1087 */
1089NTAPI
1092 _In_ ULONG Size,
1094{
1095 /* Call Ex version of the API */
1096 return LdrQueryProcessModuleInformationEx(0, 0, ModuleInformation, Size, ReturnedSize);
1097}
1098
1099/*
1100 * @implemented
1101 */
1103NTAPI
1105 _Reserved_ ULONG ReservedFlag,
1108{
1109 PLIST_ENTRY ListHead, ListEntry;
1110 PLDR_DATA_TABLE_ENTRY LdrEntry;
1113 BOOLEAN Stop = FALSE;
1114
1115 /* Check parameters */
1116 if ((ReservedFlag) || !(EnumProc)) return STATUS_INVALID_PARAMETER;
1117
1118 /* Acquire the loader lock */
1120 if (!NT_SUCCESS(Status)) return Status;
1121
1122 /* Loop all the modules and call enum proc */
1123 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1124 ListEntry = ListHead->Flink;
1125 while (ListHead != ListEntry)
1126 {
1127 /* Get the entry */
1128 LdrEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1129
1130 /* Call the enumeration proc inside SEH */
1131 _SEH2_TRY
1132 {
1133 EnumProc(LdrEntry, Context, &Stop);
1134 }
1136 {
1137 /* Ignoring the exception */
1138 } _SEH2_END;
1139
1140 /* Break if we were asked to stop enumeration */
1141 if (Stop)
1142 {
1143 break;
1144 }
1145
1146 /* Advance to the next module */
1147 ListEntry = ListEntry->Flink;
1148 }
1149
1150 /* Release loader lock */
1153
1154 /* Reset any successful status to STATUS_SUCCESS,
1155 * but leave failure to the caller */
1156 if (NT_SUCCESS(Status))
1158
1159 /* Return any possible failure status */
1160 return Status;
1161}
1162
1163/*
1164 * @implemented
1165 */
1167NTAPI
1170{
1171 PLDR_DATA_TABLE_ENTRY LdrEntry;
1173 BOOLEAN LockHeld;
1175 DPRINT("LdrDisableThreadCalloutsForDll (BaseAddress %p)\n", BaseAddress);
1176
1177 /* Don't do it during shutdown */
1179
1180 /* Check if we should grab the lock */
1181 LockHeld = FALSE;
1182 if (!LdrpInLdrInit)
1183 {
1184 /* Grab the lock */
1186 if (!NT_SUCCESS(Status)) return Status;
1187 LockHeld = TRUE;
1188 }
1189
1190 /* Make sure the DLL is valid and get its entry */
1193 {
1194 /* Get if it has a TLS slot */
1195 if (!LdrEntry->TlsIndex)
1196 {
1197 /* It doesn't, so you're allowed to call this */
1198 LdrEntry->Flags |= LDRP_DONT_CALL_FOR_THREADS;
1200 }
1201 }
1202
1203 /* Check if the lock was held */
1204 if (LockHeld)
1205 {
1206 /* Release it */
1208 }
1209
1210 /* Return the status */
1211 return Status;
1212}
1213
1214/*
1215 * @implemented
1216 */
1218NTAPI
1222{
1223 PLDR_DATA_TABLE_ENTRY LdrEntry;
1227
1228 /* Check for invalid flags */
1229 if (Flags & ~(LDR_ADDREF_DLL_PIN))
1230 {
1231 /* Fail with invalid parameter status if so */
1233 goto quickie;
1234 }
1235
1236 /* Acquire the loader lock if not in init phase */
1237 if (!LdrpInLdrInit)
1238 {
1239 /* Acquire the lock */
1241 if (!NT_SUCCESS(Status)) goto quickie;
1242 Locked = TRUE;
1243 }
1244
1245 /* Get this module's data table entry */
1247 {
1248 if (!LdrEntry)
1249 {
1250 /* Shouldn't happen */
1252 goto quickie;
1253 }
1254
1255 /* If this is not a pinned module */
1256 if (LdrEntry->LoadCount != 0xFFFF)
1257 {
1258 /* Update its load count */
1260 {
1261 /* Pin it by setting load count to -1 */
1262 LdrEntry->LoadCount = 0xFFFF;
1264 }
1265 else
1266 {
1267 /* Increase its load count by one */
1268 LdrEntry->LoadCount++;
1270 }
1271
1272 /* Clear load in progress */
1274 }
1275 }
1276 else
1277 {
1278 /* There was an error getting this module's handle, return invalid param status */
1280 }
1281
1282quickie:
1283 /* Check for error case */
1284 if (!NT_SUCCESS(Status))
1285 {
1286 /* Print debug information */
1287 if ((ShowSnaps) || ((Status != STATUS_NO_SUCH_FILE) &&
1290 {
1291 DPRINT1("LDR: LdrAddRefDll(%p) 0x%08lx\n", BaseAddress, Status);
1292 }
1293 }
1294
1295 /* Release the lock if needed */
1297 return Status;
1298}
1299
1300/*
1301 * @implemented
1302 */
1304NTAPI
1307{
1309 PPEB Peb = NtCurrentPeb();
1310 PLDR_DATA_TABLE_ENTRY LdrEntry, CurrentEntry;
1311 PVOID EntryPoint;
1312 PLIST_ENTRY NextEntry;
1313 LIST_ENTRY UnloadList;
1314 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
1315 PVOID CorImageData;
1316 ULONG ComSectionSize;
1317
1318 /* Get the LDR Lock */
1320
1321 /* Increase the unload count */
1323
1324 /* Skip unload */
1325 if (LdrpShutdownInProgress) goto Quickie;
1326
1327 /* Make sure the DLL is valid and get its entry */
1329 {
1331 goto Quickie;
1332 }
1333
1334 /* Check the current Load Count */
1335 if (LdrEntry->LoadCount != 0xFFFF)
1336 {
1337 /* Decrease it */
1338 LdrEntry->LoadCount--;
1339
1340 /* If it's a dll */
1341 if (LdrEntry->Flags & LDRP_IMAGE_DLL)
1342 {
1343 /* Set up the Act Ctx */
1344 ActCtx.Size = sizeof(ActCtx);
1347
1348 /* Activate the ActCtx */
1349 RtlActivateActivationContextUnsafeFast(&ActCtx,
1350 LdrEntry->EntryPointActivationContext);
1351
1352 /* Update the load count */
1354
1355 /* Release the context */
1356 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1357 }
1358 }
1359 else
1360 {
1361 /* The DLL is locked */
1362 goto Quickie;
1363 }
1364
1365 /* Show debug message */
1366 if (ShowSnaps) DPRINT1("LDR: UNINIT LIST\n");
1367
1368 /* Check if this is our only unload and initialize the list if so */
1370
1371 /* Loop the modules to build the list */
1373 while (NextEntry != &Peb->Ldr->InInitializationOrderModuleList)
1374 {
1375 /* Get the entry */
1376 LdrEntry = CONTAINING_RECORD(NextEntry,
1378 InInitializationOrderLinks);
1379 NextEntry = NextEntry->Blink;
1380
1381 /* Remove flag */
1382 LdrEntry->Flags &= ~LDRP_UNLOAD_IN_PROGRESS;
1383
1384 /* If the load count is now 0 */
1385 if (!LdrEntry->LoadCount)
1386 {
1387 /* Show message */
1388 if (ShowSnaps)
1389 {
1390 DPRINT1("(%lu) [%ws] %ws (%lx) deinit %p\n",
1392 LdrEntry->BaseDllName.Buffer,
1393 LdrEntry->FullDllName.Buffer,
1394 (ULONG)LdrEntry->LoadCount,
1395 LdrEntry->EntryPoint);
1396 }
1397
1398 /* Call Shim Engine and notify */
1399 if (g_ShimsEnabled)
1400 {
1402 SE_DllUnloaded(LdrEntry);
1403 }
1404
1405 /* Unlink it */
1406 CurrentEntry = LdrEntry;
1408 RemoveEntryList(&CurrentEntry->InMemoryOrderLinks);
1409 RemoveEntryList(&CurrentEntry->HashLinks);
1410
1411 /* If there's more then one active unload */
1412 if (LdrpActiveUnloadCount > 1)
1413 {
1414 /* Flush the cached DLL handle and clear the list */
1416 CurrentEntry->InMemoryOrderLinks.Flink = NULL;
1417 }
1418
1419 /* Add the entry on the unload list */
1420 InsertTailList(&LdrpUnloadHead, &CurrentEntry->HashLinks);
1421 }
1422 }
1423
1424 /* Only call the entrypoints once */
1425 if (LdrpActiveUnloadCount > 1) goto Quickie;
1426
1427 /* Now loop the unload list and create our own */
1428 InitializeListHead(&UnloadList);
1429 CurrentEntry = NULL;
1430 NextEntry = LdrpUnloadHead.Flink;
1431 while (NextEntry != &LdrpUnloadHead)
1432 {
1433 /* Get the current entry */
1434 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
1435
1436 LdrpRecordUnloadEvent(LdrEntry);
1437
1438 /* Set the entry and clear it from the list */
1439 CurrentEntry = LdrEntry;
1441 CurrentEntry->InMemoryOrderLinks.Flink = NULL;
1442
1443 /* Move it from the global to the local list */
1444 RemoveEntryList(&CurrentEntry->HashLinks);
1445 InsertTailList(&UnloadList, &CurrentEntry->HashLinks);
1446
1447 /* Get the entrypoint */
1448 EntryPoint = LdrEntry->EntryPoint;
1449
1450 /* Check if we should call it */
1451 if ((EntryPoint) && (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED))
1452 {
1453 /* Show message */
1454 if (ShowSnaps)
1455 {
1456 DPRINT1("LDR: Calling deinit %p\n", EntryPoint);
1457 }
1458
1459 /* Set up the Act Ctx */
1460 ActCtx.Size = sizeof(ActCtx);
1463
1464 /* Activate the ActCtx */
1465 RtlActivateActivationContextUnsafeFast(&ActCtx,
1466 LdrEntry->EntryPointActivationContext);
1467
1468 /* Call the entrypoint */
1469 _SEH2_TRY
1470 {
1472 LdrEntry->DllBase,
1474 NULL);
1475 }
1477 {
1478 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_DETACH) for %wZ\n",
1479 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
1480 }
1481 _SEH2_END;
1482
1483 /* Release the context */
1484 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1485 }
1486
1487 /* Remove it from the list */
1488 RemoveEntryList(&CurrentEntry->InLoadOrderLinks);
1489 CurrentEntry = NULL;
1490 NextEntry = LdrpUnloadHead.Flink;
1491 }
1492
1493 /* Now loop our local list */
1494 NextEntry = UnloadList.Flink;
1495 while (NextEntry != &UnloadList)
1496 {
1497 /* Get the entry */
1498 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
1499 NextEntry = NextEntry->Flink;
1500 CurrentEntry = LdrEntry;
1501
1502 /* Notify Application Verifier */
1504 {
1505 AVrfDllUnloadNotification(LdrEntry);
1506 }
1507
1508 /* Show message */
1509 if (ShowSnaps)
1510 {
1511 DPRINT1("LDR: Unmapping [%ws]\n", LdrEntry->BaseDllName.Buffer);
1512 }
1513
1514#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
1515 /* Send shutdown notification */
1517#endif
1518
1519 /* Check if this is a .NET executable */
1520 CorImageData = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1521 TRUE,
1523 &ComSectionSize);
1524 if (CorImageData)
1525 {
1526 /* FIXME */
1527 DPRINT1(".NET Images are not supported yet\n");
1528 }
1529
1530 /* Check if we should unmap*/
1531 if (!(CurrentEntry->Flags & LDR_COR_OWNS_UNMAP))
1532 {
1533 /* Unmap the DLL */
1535 CurrentEntry->DllBase);
1537 }
1538
1539 /* Unload the alternate resource module, if any */
1541
1542 /* Check if a Hotpatch is active */
1543 if (LdrEntry->PatchInformation)
1544 {
1545 /* FIXME */
1546 DPRINT1("We don't support Hotpatching yet\n");
1547 }
1548
1549 /* Deallocate the Entry */
1551
1552 /* If this is the cached entry, invalidate it */
1553 if (LdrpGetModuleHandleCache == CurrentEntry)
1554 {
1556 }
1557 }
1558
1559Quickie:
1560 /* Decrease unload count */
1563
1564 /* Return to caller */
1565 return Status;
1566}
1567
1568/*
1569 * @implemented
1570 */
1571BOOLEAN
1572NTAPI
1574{
1575 /* Return the internal global */
1577}
1578
1579/*
1580 * @implemented
1581 */
1583NTAPI
1587 _In_ PUSHORT TypeOffset,
1588 _In_ LONG_PTR Delta)
1589{
1590 return LdrProcessRelocationBlockLongLong(Address, Count, TypeOffset, Delta);
1591}
1592
1593/*
1594 * @implemented
1595 */
1597NTAPI
1599 _In_ PVOID Module,
1601{
1602 /* Is MUI Support enabled? */
1604
1607}
1608
1609/*
1610 * @implemented
1611 */
1612BOOLEAN
1613NTAPI
1616{
1618
1619 /* Acquire the loader lock */
1621
1622 /* Check if there's any alternate resources loaded */
1624 {
1626 }
1627
1628 /* Release the loader lock */
1630
1631 /* All done */
1632 return TRUE;
1633}
1634
1635/*
1636 * @unimplemented
1637 */
1638BOOLEAN
1639NTAPI
1641{
1643 return FALSE;
1644}
1645
1646/*
1647 * @unimplemented
1648 * See https://web.archive.org/web/20231210142610/https://kernelmode.info/forum/viewtopic3973.html?t=991
1649 */
1651NTAPI
1656{
1659}
1660
1661BOOLEAN
1662NTAPI
1664{
1667 if (NT_SUCCESS(Status))
1668 {
1670 {
1673 }
1675 return TRUE;
1676 }
1677 return FALSE;
1678}
1679
1680/* EOF */
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3498
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3090
NTSTATUS NTAPI NtMapViewOfSection(_In_ HANDLE SectionHandle, _In_ HANDLE ProcessHandle, _Outptr_result_bytebuffer_(*ViewSize) _Pre_valid_ PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_opt_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG AllocationType, _In_ ULONG Win32Protect)
Definition: section.c:3271
#define NtCurrentPeb()
Definition: FLS.c:22
IN PUNICODE_STRING StaticString
IN PUNICODE_STRING IN PUNICODE_STRING DynamicString
ULONG ReturnedSize
static BOOL CALLBACK EnumProc(_In_ HWND hWnd, _In_ LPARAM lParam)
Definition: SetParent.c:53
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:240
#define VOID
Definition: acefi.h:82
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
static BOOL CompareName(LPCWSTR pszName1, LPCWSTR pszName2)
Definition: find.c:60
#define HandleToUlong(h)
Definition: basetsd.h:73
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD Unknown3
Definition: conport.c:37
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define DLL_PROCESS_DETACH
Definition: compat.h:130
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define RtlImageRvaToVa
Definition: compat.h:807
#define RtlImageNtHeader
Definition: compat.h:806
#define MAX_PATH
Definition: compat.h:34
PPEB Peb
Definition: dllmain.c:27
_ACRTIMP char *__cdecl strrchr(const char *, int)
Definition: string.c:3303
@ AnsiString
Definition: dnslib.h:19
@ DPFLTR_LDR_ID
Definition: dpfilter.h:113
#define L(x)
Definition: resources.c:13
#define __FUNCTION__
Definition: types.h:116
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2712
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
Status
Definition: gdiplustypes.h:24
GLfloat GLfloat p
Definition: glext.h:8902
@ Unknown
Definition: i8042prt.h:114
#define FLG_HEAP_ENABLE_TAIL_CHECK
Definition: pstypes.h:55
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define NtCurrentTeb
LIST_ENTRY * ModuleListHead
Definition: kdpacket.c:23
#define DbgPrintEx(cmpid, lvl, fmt,...)
Definition: kdinit.c:24
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
LONG LdrpLoaderLockAcquisitionCount
Definition: ldrapi.c:20
NTSTATUS NTAPI LdrGetDllHandle(_In_opt_ PWSTR DllPath, _In_opt_ PULONG DllCharacteristics, _In_ PUNICODE_STRING DllName, _Out_ PVOID *DllHandle)
Definition: ldrapi.c:770
NTSTATUS NTAPI LdrUnloadDll(_In_ PVOID BaseAddress)
Definition: ldrapi.c:1305
NTSTATUS NTAPI LdrAccessOutOfProcessResource(IN PVOID Unknown, IN PVOID Image, IN PVOID Unknown1, IN PVOID Unknown2, IN PVOID Unknown3)
Definition: ldrapi.c:61
NTSTATUS NTAPI LdrFindCreateProcessManifest(IN ULONG Flags, IN PVOID Image, IN PVOID IdPath, IN ULONG IdPathLength, IN PVOID OutDataEntry)
Definition: ldrapi.c:30
NTSTATUS NTAPI LdrQueryProcessModuleInformationEx(_In_opt_ ULONG ProcessId, _Reserved_ ULONG Reserved, _Out_writes_bytes_to_(Size, *ReturnedSize) PRTL_PROCESS_MODULES ModuleInformation, _In_ ULONG Size, _Out_opt_ PULONG ReturnedSize)
Definition: ldrapi.c:961
NTSTATUS NTAPI LdrLoadAlternateResourceModule(_In_ PVOID Module, _In_ PWSTR Buffer)
Definition: ldrapi.c:1598
NTSTATUS NTAPI LdrVerifyImageMatchesChecksum(_In_ HANDLE FileHandle, _In_ PLDR_CALLBACK Callback, _In_ PVOID CallbackContext, _Out_ PUSHORT ImageCharacteristics)
Definition: ldrapi.c:818
UNICODE_STRING LdrApiDefaultExtension
Definition: ldrapi.c:22
VOID NTAPI LdrSetDllManifestProber(_In_ PLDR_MANIFEST_PROBER_ROUTINE Routine)
Definition: ldrapi.c:73
NTSTATUS NTAPI LdrDisableThreadCalloutsForDll(_In_ PVOID BaseAddress)
Definition: ldrapi.c:1168
BOOLEAN NTAPI LdrInitShimEngineDynamic(IN PVOID BaseAddress)
Definition: ldrapi.c:1663
NTSTATUS NTAPI LdrUnlockLoaderLock(_In_ ULONG Flags, _In_opt_ ULONG_PTR Cookie)
Definition: ldrapi.c:101
PLDR_MANIFEST_PROBER_ROUTINE LdrpManifestProberRoutine
Definition: ldrpe.c:18
BOOLEAN LdrpBreakOnRecursiveDllLoads
Definition: ldrapi.c:21
NTSTATUS NTAPI LdrGetDllHandleEx(_In_ ULONG Flags, _In_opt_ PWSTR DllPath, _In_opt_ PULONG DllCharacteristics, _In_ PUNICODE_STRING DllName, _Out_opt_ PVOID *DllHandle)
Definition: ldrapi.c:505
PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlock(_In_ ULONG_PTR Address, _In_ ULONG Count, _In_ PUSHORT TypeOffset, _In_ LONG_PTR Delta)
Definition: ldrapi.c:1584
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(_In_opt_ PWSTR SearchPath, _In_opt_ PULONG DllCharacteristics, _In_ PUNICODE_STRING DllName, _Out_ PVOID *BaseAddress)
Definition: ldrapi.c:312
NTSTATUS NTAPI LdrGetProcedureAddressEx(_In_ PVOID BaseAddress, _In_opt_ _When_(Ordinal==0, _Notnull_) PANSI_STRING Name, _In_opt_ _When_(Name==NULL, _In_range_(>, 0)) ULONG Ordinal, _Out_ PVOID *ProcedureAddress, _In_ ULONG Flags)
Definition: ldrapi.c:801
LIST_ENTRY LdrpUnloadHead
Definition: ldrapi.c:19
NTSTATUS NTAPI LdrCreateOutOfProcessImage(IN ULONG Flags, IN HANDLE ProcessHandle, IN HANDLE DllHandle, IN PVOID Unknown3)
Definition: ldrapi.c:50
BOOLEAN NTAPI LdrFlushAlternateResourceModules(VOID)
Definition: ldrapi.c:1640
NTSTATUS NTAPI LdrQueryProcessModuleInformation(_Out_writes_bytes_to_(Size, *ReturnedSize) PRTL_PROCESS_MODULES ModuleInformation, _In_ ULONG Size, _Out_opt_ PULONG ReturnedSize)
Definition: ldrapi.c:1090
NTSTATUS NTAPI LdrDestroyOutOfProcessImage(IN PVOID Image)
Definition: ldrapi.c:42
NTSTATUS NTAPI LdrLockLoaderLock(_In_ ULONG Flags, _Out_opt_ PULONG Disposition, _Out_opt_ PULONG_PTR Cookie)
Definition: ldrapi.c:174
BOOLEAN LdrpShowRecursiveLoads
Definition: ldrapi.c:21
ULONG AlternateResourceModuleCount
Definition: ldrapi.c:23
NTSTATUS NTAPI LdrAddRefDll(_In_ ULONG Flags, _In_ PVOID BaseAddress)
Definition: ldrapi.c:1219
BOOLEAN NTAPI LdrUnloadAlternateResourceModule(_In_ PVOID BaseAddress)
Definition: ldrapi.c:1614
FORCEINLINE ULONG_PTR LdrpMakeCookie(VOID)
Definition: ldrapi.c:89
NTSTATUS NTAPI LdrFindEntryForAddress(_In_ PVOID Address, _Out_ PLDR_DATA_TABLE_ENTRY *Module)
Definition: ldrapi.c:425
NTSTATUS NTAPI LdrGetProcedureAddress(_In_ PVOID BaseAddress, _In_opt_ _When_(Ordinal==0, _Notnull_) PANSI_STRING Name, _In_opt_ _When_(Name==NULL, _In_range_(>, 0)) ULONG Ordinal, _Out_ PVOID *ProcedureAddress)
Definition: ldrapi.c:789
NTSTATUS NTAPI LdrEnumerateLoadedModules(_Reserved_ ULONG ReservedFlag, _In_ PLDR_ENUM_CALLBACK EnumProc, _In_opt_ PVOID Context)
Definition: ldrapi.c:1104
BOOLEAN NTAPI LdrAlternateResourcesEnabled(VOID)
Definition: ldrapi.c:81
NTSTATUS NTAPI LdrSetAppCompatDllRedirectionCallback(_In_ ULONG Flags, _In_ PLDR_APP_COMPAT_DLL_REDIRECTION_CALLBACK_FUNCTION CallbackFunction, _In_opt_ PVOID CallbackData)
Definition: ldrapi.c:1652
PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlockLongLong(_In_ ULONG_PTR Address, _In_ ULONG Count, _In_ PUSHORT TypeOffset, _In_ LONGLONG Delta)
#define LDR_GET_PROCEDURE_ADDRESS_DONT_RECORD_FORWARDER
Definition: ldrfuncs.h:101
BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum(_In_ PVOID BaseAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG FileLength)
#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED
Definition: ldrtypes.h:97
#define LDR_GET_DLL_HANDLE_EX_UNCHANGED_REFCOUNT
Definition: ldrtypes.h:91
#define LDR_DLL_NOTIFICATION_REASON_UNLOADED
Definition: ldrtypes.h:204
#define LDRP_REDIRECTED
Definition: ldrtypes.h:62
_In_opt_ PVOID _Out_ BOOLEAN * Stop
Definition: ldrtypes.h:258
#define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS
Definition: ldrtypes.h:80
#define LDR_ADDREF_DLL_PIN
Definition: ldrtypes.h:75
#define LDR_COR_OWNS_UNMAP
Definition: ldrtypes.h:57
#define LDR_GET_DLL_HANDLE_EX_PIN
Definition: ldrtypes.h:92
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:264
#define LDRP_DONT_CALL_FOR_THREADS
Definition: ldrtypes.h:52
#define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY
Definition: ldrtypes.h:81
#define LDR_LOCK_LOADER_LOCK_DISPOSITION_INVALID
Definition: ldrtypes.h:95
#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED
Definition: ldrtypes.h:96
LDR_MANIFEST_PROBER_ROUTINE * PLDR_MANIFEST_PROBER_ROUTINE
Definition: ldrtypes.h:265
#define LDRP_IMAGE_DLL
Definition: ldrtypes.h:39
#define LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS
Definition: ldrtypes.h:86
#define LDRP_PROCESS_ATTACH_CALLED
Definition: ldrtypes.h:53
LDR_ENUM_CALLBACK * PLDR_ENUM_CALLBACK
Definition: ldrtypes.h:259
VOID NTAPI LdrpGetShimEngineInterface()
Definition: ldrutils.c:2706
if(dx< 0)
Definition: linetemp.h:194
@ FileStandardInfo
Definition: minwinbase.h:305
#define ASSERT(a)
Definition: mode.c:44
static const char const char * DllPath
Definition: image.c:34
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
#define DPFLTR_WARNING_LEVEL
Definition: kdtypes.h:31
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
#define SEC_COMMIT
Definition: mmtypes.h:100
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI LOGICAL NTAPI RtlTryEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
struct _RTL_PROCESS_MODULE_INFORMATION RTL_PROCESS_MODULE_INFORMATION
#define RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER
Definition: rtltypes.h:101
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:209
#define _Out_opt_
Definition: no_sal2.h:214
#define _Notnull_
Definition: no_sal2.h:54
#define _Out_writes_bytes_to_(s, c)
Definition: no_sal2.h:190
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _Reserved_
Definition: no_sal2.h:504
#define _In_range_(l, h)
Definition: no_sal2.h:368
#define _When_(c, a)
Definition: no_sal2.h:38
int Count
Definition: noreturn.cpp:7
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1293
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define PAGE_EXECUTE
Definition: nt_native.h:1309
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define NtCurrentProcess()
Definition: nt_native.h:1660
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
@ ViewShare
Definition: nt_native.h:1281
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define UNICODE_NULL
#define UNICODE_STRING_MAX_BYTES
#define ANSI_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:100
BOOLEAN LdrpInLdrInit
Definition: ldrinit.c:30
NTSYSAPI NTSTATUS NTAPI LdrpApplyFileNameRedirection(_In_ PUNICODE_STRING OriginalName, _In_ PUNICODE_STRING Extension, _Inout_opt_ PUNICODE_STRING StaticString, _Inout_opt_ PUNICODE_STRING DynamicString, _Inout_ PUNICODE_STRING *NewName, _Inout_ PBOOLEAN RedirectedDll)
BOOLEAN LdrpShutdownInProgress
Definition: ldrinit.c:34
BOOLEAN NTAPI LdrpCheckForLoadedDllHandle(IN PVOID Base, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
Definition: ldrutils.c:1600
NTSTATUS NTAPI LdrpLoadDll(IN BOOLEAN Redirected, IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress, IN BOOLEAN CallInit)
Definition: ldrutils.c:2423
PVOID g_pShimEngineModule
Definition: ldrutils.c:22
VOID NTAPI LdrpUpdateLoadCount2(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Flags)
Definition: ldrutils.c:434
#define LDRP_UPDATE_DEREFCOUNT
Definition: ntdllp.h:16
PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer
Definition: ldrinit.c:43
ULONG LdrpActiveUnloadCount
Definition: ldrinit.c:82
VOID NTAPI LdrpFinalizeAndDeallocateDataTableEntry(IN PLDR_DATA_TABLE_ENTRY Entry)
Definition: ldrutils.c:1577
NTSTATUS(NTAPI * PLDR_APP_COMPAT_DLL_REDIRECTION_CALLBACK_FUNCTION)(_In_ ULONG Flags, _In_ PCWSTR DllName, _In_ PCWSTR DllPath OPTIONAL, _Inout_opt_ PULONG DllCharacteristics, _In_ PVOID CallbackData, _Outptr_ PWSTR *EffectiveDllPath)
Definition: ntdllp.h:34
PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache
Definition: ldrutils.c:19
NTSTATUS NTAPI LdrpGetProcedureAddress(_In_ PVOID BaseAddress, _In_opt_ _When_(Ordinal==0, _Notnull_) PANSI_STRING Name, _In_opt_ _When_(Name==NULL, _In_range_(>, 0)) ULONG Ordinal, _Out_ PVOID *ProcedureAddress, _In_ BOOLEAN ExecuteInit)
Definition: ldrutils.c:2231
BOOLEAN NTAPI LdrpCheckForLoadedDll(IN PWSTR DllPath, IN PUNICODE_STRING DllName, IN BOOLEAN Flag, IN BOOLEAN RedirectedDll, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
Definition: ldrutils.c:1958
BOOLEAN NTAPI LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context)
Definition: ldrutils.c:100
VOID NTAPI AVrfDllUnloadNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: verifier.c:332
BOOLEAN ShowSnaps
Definition: ldrinit.c:79
#define LDRP_UPDATE_PIN
Definition: ntdllp.h:17
VOID NTAPI LdrpSendDllNotifications(_In_ PLDR_DATA_TABLE_ENTRY DllEntry, _In_ ULONG NotificationReason)
Definition: ldrnotify.c:104
VOID NTAPI LdrpRecordUnloadEvent(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: trace.c:28
BOOLEAN g_ShimsEnabled
Definition: ldrutils.c:21
RTL_CRITICAL_SECTION LdrpLoaderLock
Definition: ldrinit.c:68
#define LDRP_UPDATE_REFCOUNT
Definition: ntdllp.h:15
PUNICODE_STRING LdrpTopLevelDllBeingLoaded
Definition: ldrinit.c:40
ULONG NTAPI LdrpClearLoadInProgress(VOID)
Definition: ldrutils.c:2658
PVOID g_pfnSE_DllUnloaded
Definition: ldrutils.c:24
PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache
Definition: ntdllp.h:59
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:559
#define STATUS_IMAGE_CHECKSUM_MISMATCH
Definition: ntstatus.h:799
#define STATUS_DLL_NOT_FOUND
Definition: ntstatus.h:639
#define STATUS_MUI_FILE_NOT_FOUND
Definition: ntstatus.h:1724
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:570
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:285
#define STATUS_DLL_INIT_FAILED
Definition: ntstatus.h:652
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:569
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:571
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:592
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
static WCHAR Address[46]
Definition: ping.c:68
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_FINALLY
Definition: pseh2_64.h:153
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
PVOID NTAPI RtlDecodeSystemPointer(IN PVOID Pointer)
Definition: process.c:439
Entry
Definition: section.c:5216
#define FileStandardInformation
Definition: propsheet.cpp:61
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID WINAPI SE_DllUnloaded(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:1498
#define DPRINT
Definition: sndvol32.h:73
_In_ PVOID Context
Definition: storport.h:2269
HANDLE UniqueThread
Definition: compat.h:826
HANDLE UniqueProcess
Definition: compat.h:825
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
Definition: btrfs_drv.h:1876
PACTIVATION_CONTEXT EntryPointActivationContext
Definition: ldrtypes.h:167
USHORT LoadCount
Definition: ntddk_ex.h:208
PVOID EntryPoint
Definition: ntddk_ex.h:203
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
ULONG SizeOfImage
Definition: ldrtypes.h:147
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:142
LIST_ENTRY InInitializationOrderLinks
Definition: ldrtypes.h:144
PVOID DllBase
Definition: btrfs_drv.h:1880
LIST_ENTRY InMemoryOrderLinks
Definition: btrfs_drv.h:1878
USHORT TlsIndex
Definition: ntddk_ex.h:209
ULONG Flags
Definition: ntddk_ex.h:207
LIST_ENTRY HashLinks
Definition: ldrtypes.h:155
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:149
PVOID PatchInformation
Definition: ldrtypes.h:168
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PVOID EntryInProgress
Definition: ldrtypes.h:127
LIST_ENTRY InInitializationOrderModuleList
Definition: ldrtypes.h:126
LIST_ENTRY InMemoryOrderModuleList
Definition: btrfs_drv.h:1895
PVOID LoaderLock
Definition: ntddk_ex.h:295
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1912
ULONG NtGlobalFlag
Definition: ntddk_ex.h:270
Definition: compat.h:836
CLIENT_ID ClientId
Definition: compat.h:839
CLIENT_ID RealClientId
Definition: compat.h:861
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
VOID(NTAPI * PLDR_CALLBACK)(PVOID CallbackContext, PCHAR Name)
Definition: umfuncs.h:217
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
#define FORCEINLINE
Definition: wdftypes.h:67
#define SearchPath
Definition: winbase.h:3621
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
NTSYSAPI BOOLEAN WINAPI RtlDllShutdownInProgress(void)
Definition: ldrapi.c:1573
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG _In_opt_ PEVENT_FILTER_DESCRIPTOR _Inout_opt_ PVOID CallbackContext
Definition: wmitypes.h:60
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14
_In_ PCALLBACK_FUNCTION CallbackFunction
Definition: exfuncs.h:1034