ReactOS  0.4.13-dev-66-gc714b7f
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 
29 NTAPI
31  IN PVOID Image,
32  IN PVOID IdPath,
33  IN ULONG IdPathLength,
34  IN PVOID OutDataEntry)
35 {
38 }
39 
41 NTAPI
43 {
46 }
47 
49 NTAPI
52  IN HANDLE DllHandle,
54 {
57 }
58 
60 NTAPI
62  IN PVOID Image,
63  IN PVOID Unknown1,
64  IN PVOID Unknown2,
66 {
69 }
70 
71 VOID
72 NTAPI
75 {
76  LdrpManifestProberRoutine = Routine;
77 }
78 
79 BOOLEAN
80 NTAPI
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  */
100 NTAPI
103 {
105 
106  DPRINT("LdrUnlockLoaderLock(%x %x)\n", Flags, Cookie);
107 
108  /* Check for valid flags */
110  {
111  /* Flags are invalid, check how to fail */
113  {
114  /* The caller wants us to raise status */
116  }
117 
118  /* A normal failure */
120  }
121 
122  /* If we don't have a cookie, just return */
123  if (!Cookie) return STATUS_SUCCESS;
124 
125  /* Validate the cookie */
126  if ((Cookie & 0xF0000000) ||
127  ((Cookie >> 16) ^ (HandleToUlong(NtCurrentTeb()->RealClientId.UniqueThread) & 0xFFF)))
128  {
129  DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n");
130 
131  /* Invalid cookie, check how to fail */
133  {
134  /* The caller wants us to raise status */
136  }
137 
138  /* A normal failure */
140  }
141 
142  /* Ready to release the lock */
144  {
145  /* Do a direct leave */
147  }
148  else
149  {
150  /* Wrap this in SEH, since we're not supposed to raise */
151  _SEH2_TRY
152  {
153  /* Leave the lock */
155  }
157  {
158  /* We should use the LDR Filter instead */
160  }
161  _SEH2_END;
162  }
163 
164  /* All done */
165  return Status;
166 }
167 
168 /*
169  * @implemented
170  */
171 NTSTATUS
172 NTAPI
176 {
178  BOOLEAN InInit = LdrpInLdrInit;
179 
180  DPRINT("LdrLockLoaderLock(%x %p %p)\n", Flags, Disposition, Cookie);
181 
182  /* Zero out the outputs */
184  if (Cookie) *Cookie = 0;
185 
186  /* Validate the flags */
189  {
190  /* Flags are invalid, check how to fail */
192  {
193  /* The caller wants us to raise status */
195  }
196 
197  /* A normal failure */
199  }
200 
201  /* Make sure we got a cookie */
202  if (!Cookie)
203  {
204  /* No cookie check how to fail */
206  {
207  /* The caller wants us to raise status */
209  }
210 
211  /* A normal failure */
213  }
214 
215  /* If the flag is set, make sure we have a valid pointer to use */
217  {
218  /* No pointer to return the data to */
220  {
221  /* The caller wants us to raise status */
223  }
224 
225  /* Fail */
227  }
228 
229  /* Return now if we are in the init phase */
230  if (InInit) return STATUS_SUCCESS;
231 
232  /* Check what locking semantic to use */
234  {
235  /* Check if we should enter or simply try */
237  {
238  /* Do a try */
240  {
241  /* It's locked */
243  }
244  else
245  {
246  /* It worked */
248  *Cookie = LdrpMakeCookie();
249  }
250  }
251  else
252  {
253  /* Do a enter */
255 
256  /* See if result was requested */
258  *Cookie = LdrpMakeCookie();
259  }
260  }
261  else
262  {
263  /* Wrap this in SEH, since we're not supposed to raise */
264  _SEH2_TRY
265  {
266  /* Check if we should enter or simply try */
268  {
269  /* Do a try */
271  {
272  /* It's locked */
274  }
275  else
276  {
277  /* It worked */
279  *Cookie = LdrpMakeCookie();
280  }
281  }
282  else
283  {
284  /* Do an enter */
286 
287  /* See if result was requested */
289  *Cookie = LdrpMakeCookie();
290  }
291  }
293  {
294  /* We should use the LDR Filter instead */
296  }
297  _SEH2_END;
298  }
299 
300  /* Return status */
301  return Status;
302 }
303 
304 /*
305  * @implemented
306  */
307 NTSTATUS
308 NTAPI
311  IN PULONG DllCharacteristics OPTIONAL,
312  IN PUNICODE_STRING DllName,
314 {
316  UNICODE_STRING DllString1, DllString2;
317  BOOLEAN RedirectedDll = FALSE;
320  PUNICODE_STRING OldTldDll;
321  PTEB Teb = NtCurrentTeb();
322 
323  /* Initialize the strings */
324  RtlInitEmptyUnicodeString(&DllString1, StringBuffer, sizeof(StringBuffer));
325  RtlInitEmptyUnicodeString(&DllString2, NULL, 0);
326 
327  /* Check if the SxS Assemblies specify another file */
329  DllName,
331  &DllString1,
332  &DllString2,
333  &DllName,
334  NULL,
335  NULL,
336  NULL);
337 
338  /* Check success */
339  if (NT_SUCCESS(Status))
340  {
341  /* Let Ldrp know */
342  RedirectedDll = TRUE;
343  }
344  else if (Status != STATUS_SXS_KEY_NOT_FOUND)
345  {
346  /* Unrecoverable SxS failure; did we get a string? */
347  if (DllString2.Buffer) RtlFreeUnicodeString(&DllString2);
348  return Status;
349  }
350 
351  /* Lock the loader lock */
353 
354  /* Check if there's a TLD DLL being loaded */
355  OldTldDll = LdrpTopLevelDllBeingLoaded;
356  _SEH2_TRY
357  {
358 
359  if (OldTldDll)
360  {
361  /* This is a recursive load, do something about it? */
363  {
364  /* Print out debug messages */
365  DPRINT1("[%p, %p] LDR: Recursive DLL Load\n",
368  DPRINT1("[%p, %p] Previous DLL being loaded \"%wZ\"\n",
371  OldTldDll);
372  DPRINT1("[%p, %p] DLL being requested \"%wZ\"\n",
375  DllName);
376 
377  /* Was it initializing too? */
379  {
380  DPRINT1("[%p, %p] LDR: No DLL Initializer was running\n",
383  }
384  else
385  {
386  DPRINT1("[%p, %p] DLL whose initializer was currently running \"%wZ\"\n",
387  Teb->ClientId.UniqueProcess,
388  Teb->ClientId.UniqueThread,
390  }
391  }
392  }
393 
394  /* Set this one as the TLD DLL being loaded*/
395  LdrpTopLevelDllBeingLoaded = DllName;
396 
397  /* Load the DLL */
398  Status = LdrpLoadDll(RedirectedDll,
399  SearchPath,
400  DllCharacteristics,
401  DllName,
402  BaseAddress,
403  TRUE);
404  if (NT_SUCCESS(Status))
405  {
407  }
408  else if ((Status != STATUS_NO_SUCH_FILE) &&
412  {
415  "LDR: %s - failing because LdrpLoadDll(%wZ) returned status %x\n",
416  __FUNCTION__,
417  DllName,
418  Status);
419  }
420  }
422  {
423  /* Restore the old TLD DLL */
424  LdrpTopLevelDllBeingLoaded = OldTldDll;
425 
426  /* Release the lock */
428  }
429  _SEH2_END;
430 
431  /* Do we have a redirect string? */
432  if (DllString2.Buffer) RtlFreeUnicodeString(&DllString2);
433 
434  /* Return */
435  return Status;
436 }
437 
438 /*
439  * @implemented
440  */
441 NTSTATUS
442 NTAPI
444  PLDR_DATA_TABLE_ENTRY *Module)
445 {
446  PLIST_ENTRY ListHead, NextEntry;
447  PLDR_DATA_TABLE_ENTRY LdrEntry;
448  PIMAGE_NT_HEADERS NtHeader;
449  PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr;
450  ULONG_PTR DllBase, DllEnd;
451 
452  DPRINT("LdrFindEntryForAddress(Address %p)\n", Address);
453 
454  /* Nothing to do */
455  if (!Ldr) return STATUS_NO_MORE_ENTRIES;
456 
457  /* Get the current entry */
458  LdrEntry = Ldr->EntryInProgress;
459  if (LdrEntry)
460  {
461  /* Get the NT Headers */
462  NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
463  if (NtHeader)
464  {
465  /* Get the Image Base */
466  DllBase = (ULONG_PTR)LdrEntry->DllBase;
467  DllEnd = DllBase + NtHeader->OptionalHeader.SizeOfImage;
468 
469  /* Check if they match */
470  if (((ULONG_PTR)Address >= DllBase) &&
471  ((ULONG_PTR)Address < DllEnd))
472  {
473  /* Return it */
474  *Module = LdrEntry;
475  return STATUS_SUCCESS;
476  }
477  }
478  }
479 
480  /* Loop the module list */
481  ListHead = &Ldr->InMemoryOrderModuleList;
482  NextEntry = ListHead->Flink;
483  while (NextEntry != ListHead)
484  {
485  /* Get the entry and NT Headers */
486  LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
487  NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
488  if (NtHeader)
489  {
490  /* Get the Image Base */
491  DllBase = (ULONG_PTR)LdrEntry->DllBase;
492  DllEnd = DllBase + NtHeader->OptionalHeader.SizeOfImage;
493 
494  /* Check if they match */
495  if (((ULONG_PTR)Address >= DllBase) &&
496  ((ULONG_PTR)Address < DllEnd))
497  {
498  /* Return it */
499  *Module = LdrEntry;
500  return STATUS_SUCCESS;
501  }
502 
503  /* Next Entry */
504  NextEntry = NextEntry->Flink;
505  }
506  }
507 
508  /* Nothing found */
511  "LDR: %s() exiting 0x%08lx\n",
512  __FUNCTION__,
514  return STATUS_NO_MORE_ENTRIES;
515 }
516 
517 /*
518  * @implemented
519  */
520 NTSTATUS
521 NTAPI
524  IN PULONG DllCharacteristics OPTIONAL,
525  IN PUNICODE_STRING DllName,
526  OUT PVOID *DllHandle OPTIONAL)
527 {
529  PLDR_DATA_TABLE_ENTRY LdrEntry;
530  UNICODE_STRING RedirectName, DllString1, RawDllName;
531  PUNICODE_STRING pRedirectName, CompareName;
532  PWCHAR p1, p2, p3;
533  BOOLEAN Locked, RedirectedDll;
535  ULONG LoadFlag, Length;
536 
537  /* Initialize the strings */
538  RtlInitEmptyUnicodeString(&DllString1, NULL, 0);
539  RtlInitEmptyUnicodeString(&RawDllName, NULL, 0);
540  RedirectName = *DllName;
541  pRedirectName = &RedirectName;
542 
543  /* Initialize state */
544  RedirectedDll = Locked = FALSE;
545  LdrEntry = NULL;
546  Cookie = 0;
547 
548  /* Clear the handle */
549  if (DllHandle) *DllHandle = NULL;
550 
551  /* Check for a valid flag combination */
553  (!DllHandle && !(Flags & LDR_GET_DLL_HANDLE_EX_PIN)))
554  {
555  DPRINT1("Flags are invalid or no DllHandle given\n");
557  goto Quickie;
558  }
559 
560  /* If not initializing */
561  if (!LdrpInLdrInit)
562  {
563  /* Acquire the lock */
565  if (!NT_SUCCESS(Status)) goto Quickie;
566 
567  /* Remember we own it */
568  Locked = TRUE;
569  }
570 
571  /* Check if the SxS Assemblies specify another file */
573  pRedirectName,
575  NULL,
576  &DllString1,
577  &pRedirectName,
578  NULL,
579  NULL,
580  NULL);
581 
582  /* Check success */
583  if (NT_SUCCESS(Status))
584  {
585  /* Let Ldrp know */
586  RedirectedDll = TRUE;
587  }
588  else if (Status != STATUS_SXS_KEY_NOT_FOUND)
589  {
590  /* Unrecoverable SxS failure */
591  goto Quickie;
592  }
593  else
594  {
595  ASSERT(pRedirectName == &RedirectName);
596  }
597 
598  /* Set default failure code */
600 
601  /* Use the cache if we can */
603  {
604  /* Check if we were redirected */
605  if (RedirectedDll)
606  {
607  /* Check the flag */
609  {
610  goto DontCompare;
611  }
612 
613  /* Use the right name */
615  }
616  else
617  {
618  /* Check the flag */
620  {
621  goto DontCompare;
622  }
623 
624  /* Use the right name */
626  }
627 
628  /* Check if the name matches */
629  if (RtlEqualUnicodeString(pRedirectName,
630  CompareName,
631  TRUE))
632  {
633  /* Skip the rest */
634  LdrEntry = LdrpGetModuleHandleCache;
635 
636  /* Return success */
638  goto Quickie;
639  }
640  }
641 
642 DontCompare:
643  /* Find the name without the extension */
644  p1 = pRedirectName->Buffer;
645  p2 = NULL;
646  p3 = &p1[pRedirectName->Length / sizeof(WCHAR)];
647  while (p1 != p3)
648  {
649  if (*p1++ == L'.')
650  {
651  p2 = p1;
652  }
653  else if (*p1 == L'\\')
654  {
655  p2 = NULL;
656  }
657  }
658 
659  /* Check if no extension was found or if we got a slash */
660  if (!(p2) || (*p2 == L'\\') || (*p2 == L'/'))
661  {
662  /* Check that we have space to add one */
663  Length = pRedirectName->Length +
666  {
667  /* No space to add the extension */
669  goto Quickie;
670  }
671 
672  /* Setup the string */
673  RawDllName.MaximumLength = Length;
674  ASSERT(Length >= sizeof(UNICODE_NULL));
675  RawDllName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
676  0,
677  RawDllName.MaximumLength);
678  if (!RawDllName.Buffer)
679  {
681  goto Quickie;
682  }
683 
684  /* Copy the string and add extension */
685  RtlCopyUnicodeString(&RawDllName, pRedirectName);
687  }
688  else
689  {
690  /* Check if there's something in the name */
691  Length = pRedirectName->Length;
692  if (Length)
693  {
694  /* Check and remove trailing period */
695  if (pRedirectName->Buffer[Length / sizeof(WCHAR) - sizeof(ANSI_NULL)] == '.')
696  {
697  /* Decrease the size */
698  pRedirectName->Length -= sizeof(WCHAR);
699  }
700  }
701 
702  /* Setup the string */
703  RawDllName.MaximumLength = pRedirectName->Length + sizeof(WCHAR);
704  RawDllName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
705  0,
706  RawDllName.MaximumLength);
707  if (!RawDllName.Buffer)
708  {
710  goto Quickie;
711  }
712 
713  /* Copy the string */
714  RtlCopyUnicodeString(&RawDllName, pRedirectName);
715  }
716 
717  /* Display debug string */
718  if (ShowSnaps)
719  {
720  DPRINT1("LDR: LdrGetDllHandleEx, searching for %wZ from %ws\n",
721  &RawDllName,
722  DllPath ? ((ULONG_PTR)DllPath == 1 ? L"" : DllPath) : L"");
723  }
724 
725  /* Do the lookup */
727  &RawDllName,
728  ((ULONG_PTR)DllPath == 1) ? TRUE : FALSE,
729  RedirectedDll,
730  &LdrEntry))
731  {
732  /* Update cached entry */
733  LdrpGetModuleHandleCache = LdrEntry;
734 
735  /* Return success */
737  }
738  else
739  {
740  /* Make sure to NULL this */
741  LdrEntry = NULL;
742  }
743 Quickie:
744  /* The success path must have a valid loader entry */
745  ASSERT((LdrEntry != NULL) == NT_SUCCESS(Status));
746 
747  /* Check if we got an entry and success */
748  DPRINT("Got LdrEntry->BaseDllName %wZ\n", LdrEntry ? &LdrEntry->BaseDllName : NULL);
749  if ((LdrEntry) && (NT_SUCCESS(Status)))
750  {
751  /* Check if the DLL is locked */
752  if ((LdrEntry->LoadCount != 0xFFFF) &&
754  {
755  /* Check what to do with the load count */
757  {
758  /* Pin it */
759  LdrEntry->LoadCount = 0xFFFF;
760  LoadFlag = LDRP_UPDATE_PIN;
761  }
762  else
763  {
764  /* Increase the load count */
765  LdrEntry->LoadCount++;
766  LoadFlag = LDRP_UPDATE_REFCOUNT;
767  }
768 
769  /* Update the load count now */
770  LdrpUpdateLoadCount2(LdrEntry, LoadFlag);
772  }
773 
774  /* Check if the caller is requesting the handle */
775  if (DllHandle) *DllHandle = LdrEntry->DllBase;
776  }
777 
778  /* Free string if needed */
779  if (DllString1.Buffer) RtlFreeUnicodeString(&DllString1);
780 
781  /* Free the raw DLL Name if needed */
782  if (RawDllName.Buffer)
783  {
784  /* Free the heap-allocated buffer */
785  RtlFreeHeap(RtlGetProcessHeap(), 0, RawDllName.Buffer);
786  RawDllName.Buffer = NULL;
787  }
788 
789  /* Release lock */
790  if (Locked)
791  {
793  Cookie);
794  }
795 
796  /* Return */
797  return Status;
798 }
799 
800 /*
801  * @implemented
802  */
803 NTSTATUS
804 NTAPI
806  IN PULONG DllCharacteristics OPTIONAL,
807  IN PUNICODE_STRING DllName,
808  OUT PVOID *DllHandle)
809 {
810  /* Call the newer API */
812  DllPath,
813  DllCharacteristics,
814  DllName,
815  DllHandle);
816 }
817 
818 /*
819  * @implemented
820  */
821 NTSTATUS
822 NTAPI
825  IN ULONG Ordinal,
826  OUT PVOID *ProcedureAddress)
827 {
828  /* Call the internal routine and tell it to execute DllInit */
829  return LdrpGetProcedureAddress(BaseAddress, Name, Ordinal, ProcedureAddress, TRUE);
830 }
831 
832 /*
833  * @implemented
834  */
835 NTSTATUS
836 NTAPI
840  OUT PUSHORT ImageCharacteristics)
841 {
842  FILE_STANDARD_INFORMATION FileStandardInfo;
843  PIMAGE_IMPORT_DESCRIPTOR ImportData;
844  PIMAGE_SECTION_HEADER LastSection = NULL;
846  PIMAGE_NT_HEADERS NtHeader;
847  HANDLE SectionHandle;
849  PVOID ViewBase;
850  BOOLEAN Result, NoActualCheck;
852  PVOID ImportName;
853  ULONG Size;
854  DPRINT("LdrVerifyImageMatchesChecksum() called\n");
855 
856  /* If the handle has the magic KnownDll flag, skip actual checksums */
857  NoActualCheck = ((ULONG_PTR)FileHandle & 1);
858 
859  /* Create the section */
860  Status = NtCreateSection(&SectionHandle,
862  NULL,
863  NULL,
864  PAGE_EXECUTE,
865  SEC_COMMIT,
866  FileHandle);
867  if (!NT_SUCCESS(Status))
868  {
869  DPRINT1 ("NtCreateSection() failed (Status 0x%x)\n", Status);
870  return Status;
871  }
872 
873  /* Map the section */
874  ViewSize = 0;
875  ViewBase = NULL;
876  Status = NtMapViewOfSection(SectionHandle,
878  &ViewBase,
879  0,
880  0,
881  NULL,
882  &ViewSize,
883  ViewShare,
884  0,
885  PAGE_EXECUTE);
886  if (!NT_SUCCESS(Status))
887  {
888  DPRINT1("NtMapViewOfSection() failed (Status 0x%x)\n", Status);
889  NtClose(SectionHandle);
890  return Status;
891  }
892 
893  /* Get the file information */
895  &IoStatusBlock,
896  &FileStandardInfo,
899  if (!NT_SUCCESS(Status))
900  {
901  DPRINT1("NtMapViewOfSection() failed (Status 0x%x)\n", Status);
903  NtClose(SectionHandle);
904  return Status;
905  }
906 
907  /* Protect with SEH */
908  _SEH2_TRY
909  {
910  /* Check if this is the KnownDll hack */
911  if (NoActualCheck)
912  {
913  /* Don't actually do it */
914  Result = TRUE;
915  }
916  else
917  {
918  /* Verify the checksum */
920  FileStandardInfo.EndOfFile.LowPart,
921  FileStandardInfo.EndOfFile.LowPart);
922  }
923 
924  /* Check if a callback was supplied */
925  if ((Result) && (Callback))
926  {
927  /* Get the NT Header */
928  NtHeader = RtlImageNtHeader(ViewBase);
929 
930  /* Check if caller requested this back */
931  if (ImageCharacteristics)
932  {
933  /* Return to caller */
934  *ImageCharacteristics = NtHeader->FileHeader.Characteristics;
935  }
936 
937  /* Get the Import Directory Data */
938  ImportData = RtlImageDirectoryEntryToData(ViewBase,
939  FALSE,
941  &Size);
942 
943  /* Make sure there is one */
944  if (ImportData)
945  {
946  /* Loop the imports */
947  while (ImportData->Name)
948  {
949  /* Get the name */
950  ImportName = RtlImageRvaToVa(NtHeader,
951  ViewBase,
952  ImportData->Name,
953  &LastSection);
954 
955  /* Notify the callback */
956  Callback(CallbackContext, ImportName);
957  ImportData++;
958  }
959  }
960  }
961  }
963  {
964  /* Fail the request returning STATUS_IMAGE_CHECKSUM_MISMATCH */
965  Result = FALSE;
966  }
967  _SEH2_END;
968 
969  /* Unmap file and close handle */
971  NtClose(SectionHandle);
972 
973  /* Return status */
975 }
976 
977 NTSTATUS
978 NTAPI
980  IN ULONG Reserved,
981  OUT PRTL_PROCESS_MODULES ModuleInformation,
982  IN ULONG Size,
983  OUT PULONG ReturnedSize OPTIONAL)
984 {
985  PLIST_ENTRY ModuleListHead, InitListHead;
986  PLIST_ENTRY Entry, InitEntry;
987  PLDR_DATA_TABLE_ENTRY Module, InitModule;
990  ULONG UsedSize = sizeof(ULONG);
992  PCHAR p;
993 
994  DPRINT("LdrQueryProcessModuleInformation() called\n");
995 
996  /* Acquire loader lock */
997  RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
998 
999  _SEH2_TRY
1000  {
1001  /* Check if we were given enough space */
1002  if (Size < UsedSize)
1003  {
1005  }
1006  else
1007  {
1008  ModuleInformation->NumberOfModules = 0;
1009  ModulePtr = &ModuleInformation->Modules[0];
1011  }
1012 
1013  /* Traverse the list of modules */
1014  ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1016 
1017  while (Entry != ModuleListHead)
1018  {
1019  Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1020 
1021  DPRINT(" Module %wZ\n", &Module->FullDllName);
1022 
1023  /* Increase the used size */
1024  UsedSize += sizeof(RTL_PROCESS_MODULE_INFORMATION);
1025 
1026  if (UsedSize > Size)
1027  {
1029  }
1030  else
1031  {
1032  ModulePtr->ImageBase = Module->DllBase;
1033  ModulePtr->ImageSize = Module->SizeOfImage;
1034  ModulePtr->Flags = Module->Flags;
1035  ModulePtr->LoadCount = Module->LoadCount;
1036  ModulePtr->MappedBase = NULL;
1037  ModulePtr->InitOrderIndex = 0;
1038  ModulePtr->LoadOrderIndex = ModuleInformation->NumberOfModules;
1039 
1040  /* Now get init order index by traversing init list */
1041  InitListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
1042  InitEntry = InitListHead->Flink;
1043 
1044  while (InitEntry != InitListHead)
1045  {
1046  InitModule = CONTAINING_RECORD(InitEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1047 
1048  /* Increase the index */
1049  ModulePtr->InitOrderIndex++;
1050 
1051  /* Quit the loop if our module is found */
1052  if (InitModule == Module) break;
1053 
1054  /* Advance to the next entry */
1055  InitEntry = InitEntry->Flink;
1056  }
1057 
1058  /* Prepare ANSI string with the module's name */
1059  AnsiString.Length = 0;
1060  AnsiString.MaximumLength = sizeof(ModulePtr->FullPathName);
1061  AnsiString.Buffer = ModulePtr->FullPathName;
1063  &Module->FullDllName,
1064  FALSE);
1065 
1066  /* Calculate OffsetToFileName field */
1067  p = strrchr(ModulePtr->FullPathName, '\\');
1068  if (p != NULL)
1069  ModulePtr->OffsetToFileName = p - ModulePtr->FullPathName + 1;
1070  else
1071  ModulePtr->OffsetToFileName = 0;
1072 
1073  /* Advance to the next module in the output list */
1074  ModulePtr++;
1075 
1076  /* Increase number of modules */
1077  if (ModuleInformation)
1078  ModuleInformation->NumberOfModules++;
1079  }
1080 
1081  /* Go to the next entry in the modules list */
1082  Entry = Entry->Flink;
1083  }
1084 
1085  /* Set returned size if it was provided */
1086  if (ReturnedSize)
1087  *ReturnedSize = UsedSize;
1088  }
1090  {
1091  /* Ignoring the exception */
1092  } _SEH2_END;
1093 
1094  /* Release the lock */
1095  RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
1096 
1097  DPRINT("LdrQueryProcessModuleInformation() done\n");
1098 
1099  return Status;
1100 }
1101 
1102 /*
1103  * @implemented
1104  */
1105 NTSTATUS
1106 NTAPI
1108  IN ULONG Size,
1109  OUT PULONG ReturnedSize OPTIONAL)
1110 {
1111  /* Call Ex version of the API */
1112  return LdrQueryProcessModuleInformationEx(0, 0, ModuleInformation, Size, ReturnedSize);
1113 }
1114 
1115 /*
1116  * @implemented
1117  */
1118 NTSTATUS
1119 NTAPI
1122  IN PVOID Context)
1123 {
1124  PLIST_ENTRY ListHead, ListEntry;
1125  PLDR_DATA_TABLE_ENTRY LdrEntry;
1126  NTSTATUS Status;
1127  ULONG_PTR Cookie;
1128  BOOLEAN Stop = FALSE;
1129 
1130  /* Check parameters */
1131  if ((ReservedFlag) || !(EnumProc)) return STATUS_INVALID_PARAMETER;
1132 
1133  /* Acquire the loader lock */
1135  if (!NT_SUCCESS(Status)) return Status;
1136 
1137  /* Loop all the modules and call enum proc */
1138  ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1139  ListEntry = ListHead->Flink;
1140  while (ListHead != ListEntry)
1141  {
1142  /* Get the entry */
1143  LdrEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1144 
1145  /* Call the enumeration proc inside SEH */
1146  _SEH2_TRY
1147  {
1148  EnumProc(LdrEntry, Context, &Stop);
1149  }
1151  {
1152  /* Ignoring the exception */
1153  } _SEH2_END;
1154 
1155  /* Break if we were asked to stop enumeration */
1156  if (Stop)
1157  {
1158  /* Release loader lock */
1160 
1161  /* Reset any successful status to STATUS_SUCCESS, but leave
1162  failure to the caller */
1163  if (NT_SUCCESS(Status))
1165 
1166  /* Return any possible failure status */
1167  return Status;
1168  }
1169 
1170  /* Advance to the next module */
1171  ListEntry = ListEntry->Flink;
1172  }
1173 
1174  /* Release loader lock, it must succeed this time */
1177 
1178  /* Return success */
1179  return STATUS_SUCCESS;
1180 }
1181 
1182 /*
1183  * @implemented
1184  */
1185 NTSTATUS
1186 NTAPI
1188 {
1189  PLDR_DATA_TABLE_ENTRY LdrEntry;
1190  NTSTATUS Status;
1191  BOOLEAN LockHeld;
1192  ULONG_PTR Cookie;
1193  DPRINT("LdrDisableThreadCalloutsForDll (BaseAddress %p)\n", BaseAddress);
1194 
1195  /* Don't do it during shutdown */
1197 
1198  /* Check if we should grab the lock */
1199  LockHeld = FALSE;
1200  if (!LdrpInLdrInit)
1201  {
1202  /* Grab the lock */
1204  if (!NT_SUCCESS(Status)) return Status;
1205  LockHeld = TRUE;
1206  }
1207 
1208  /* Make sure the DLL is valid and get its entry */
1210  if (LdrpCheckForLoadedDllHandle(BaseAddress, &LdrEntry))
1211  {
1212  /* Get if it has a TLS slot */
1213  if (!LdrEntry->TlsIndex)
1214  {
1215  /* It doesn't, so you're allowed to call this */
1216  LdrEntry->Flags |= LDRP_DONT_CALL_FOR_THREADS;
1218  }
1219  }
1220 
1221  /* Check if the lock was held */
1222  if (LockHeld)
1223  {
1224  /* Release it */
1226  }
1227 
1228  /* Return the status */
1229  return Status;
1230 }
1231 
1232 /*
1233  * @implemented
1234  */
1235 NTSTATUS
1236 NTAPI
1239 {
1240  PLDR_DATA_TABLE_ENTRY LdrEntry;
1242  ULONG_PTR Cookie;
1243  BOOLEAN Locked = FALSE;
1244 
1245  /* Check for invalid flags */
1246  if (Flags & ~(LDR_ADDREF_DLL_PIN))
1247  {
1248  /* Fail with invalid parameter status if so */
1250  goto quickie;
1251  }
1252 
1253  /* Acquire the loader lock if not in init phase */
1254  if (!LdrpInLdrInit)
1255  {
1256  /* Acquire the lock */
1258  if (!NT_SUCCESS(Status)) goto quickie;
1259  Locked = TRUE;
1260  }
1261 
1262  /* Get this module's data table entry */
1263  if (LdrpCheckForLoadedDllHandle(BaseAddress, &LdrEntry))
1264  {
1265  if (!LdrEntry)
1266  {
1267  /* Shouldn't happen */
1269  goto quickie;
1270  }
1271 
1272  /* If this is not a pinned module */
1273  if (LdrEntry->LoadCount != 0xFFFF)
1274  {
1275  /* Update its load count */
1276  if (Flags & LDR_ADDREF_DLL_PIN)
1277  {
1278  /* Pin it by setting load count to -1 */
1279  LdrEntry->LoadCount = 0xFFFF;
1281  }
1282  else
1283  {
1284  /* Increase its load count by one */
1285  LdrEntry->LoadCount++;
1287  }
1288 
1289  /* Clear load in progress */
1291  }
1292  }
1293  else
1294  {
1295  /* There was an error getting this module's handle, return invalid param status */
1297  }
1298 
1299 quickie:
1300  /* Check for error case */
1301  if (!NT_SUCCESS(Status))
1302  {
1303  /* Print debug information */
1304  if ((ShowSnaps) || ((Status != STATUS_NO_SUCH_FILE) &&
1307  {
1308  DPRINT1("LDR: LdrAddRefDll(%p) 0x%08lx\n", BaseAddress, Status);
1309  }
1310  }
1311 
1312  /* Release the lock if needed */
1314  return Status;
1315 }
1316 
1317 /*
1318  * @implemented
1319  */
1320 NTSTATUS
1321 NTAPI
1323 {
1325  PPEB Peb = NtCurrentPeb();
1326  PLDR_DATA_TABLE_ENTRY LdrEntry, CurrentEntry;
1327  PVOID EntryPoint;
1328  PLIST_ENTRY NextEntry;
1329  LIST_ENTRY UnloadList;
1330  RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
1331  PVOID CorImageData;
1332  ULONG ComSectionSize;
1333 
1334  /* Get the LDR Lock */
1336 
1337  /* Increase the unload count */
1339 
1340  /* Skip unload */
1341  if (LdrpShutdownInProgress) goto Quickie;
1342 
1343  /* Make sure the DLL is valid and get its entry */
1344  if (!LdrpCheckForLoadedDllHandle(BaseAddress, &LdrEntry))
1345  {
1347  goto Quickie;
1348  }
1349 
1350  /* Check the current Load Count */
1351  if (LdrEntry->LoadCount != 0xFFFF)
1352  {
1353  /* Decrease it */
1354  LdrEntry->LoadCount--;
1355 
1356  /* If it's a dll */
1357  if (LdrEntry->Flags & LDRP_IMAGE_DLL)
1358  {
1359  /* Set up the Act Ctx */
1360  ActCtx.Size = sizeof(ActCtx);
1363 
1364  /* Activate the ActCtx */
1366  LdrEntry->EntryPointActivationContext);
1367 
1368  /* Update the load count */
1370 
1371  /* Release the context */
1373  }
1374  }
1375  else
1376  {
1377  /* The DLL is locked */
1378  goto Quickie;
1379  }
1380 
1381  /* Show debug message */
1382  if (ShowSnaps) DPRINT1("LDR: UNINIT LIST\n");
1383 
1384  /* Check if this is our only unload and initialize the list if so */
1386 
1387  /* Loop the modules to build the list */
1389  while (NextEntry != &Peb->Ldr->InInitializationOrderModuleList)
1390  {
1391  /* Get the entry */
1392  LdrEntry = CONTAINING_RECORD(NextEntry,
1394  InInitializationOrderLinks);
1395  NextEntry = NextEntry->Blink;
1396 
1397  /* Remove flag */
1398  LdrEntry->Flags &= ~LDRP_UNLOAD_IN_PROGRESS;
1399 
1400  /* If the load count is now 0 */
1401  if (!LdrEntry->LoadCount)
1402  {
1403  /* Show message */
1404  if (ShowSnaps)
1405  {
1406  DPRINT1("(%lu) [%ws] %ws (%lx) deinit %p\n",
1408  LdrEntry->BaseDllName.Buffer,
1409  LdrEntry->FullDllName.Buffer,
1410  (ULONG)LdrEntry->LoadCount,
1411  LdrEntry->EntryPoint);
1412  }
1413 
1414  /* Call Shim Engine and notify */
1415  if (g_ShimsEnabled)
1416  {
1418  SE_DllUnloaded(LdrEntry);
1419  }
1420 
1421  /* Unlink it */
1422  CurrentEntry = LdrEntry;
1424  RemoveEntryList(&CurrentEntry->InMemoryOrderLinks);
1425  RemoveEntryList(&CurrentEntry->HashLinks);
1426 
1427  /* If there's more then one active unload */
1428  if (LdrpActiveUnloadCount > 1)
1429  {
1430  /* Flush the cached DLL handle and clear the list */
1432  CurrentEntry->InMemoryOrderLinks.Flink = NULL;
1433  }
1434 
1435  /* Add the entry on the unload list */
1436  InsertTailList(&LdrpUnloadHead, &CurrentEntry->HashLinks);
1437  }
1438  }
1439 
1440  /* Only call the entrypoints once */
1441  if (LdrpActiveUnloadCount > 1) goto Quickie;
1442 
1443  /* Now loop the unload list and create our own */
1444  InitializeListHead(&UnloadList);
1445  CurrentEntry = NULL;
1446  NextEntry = LdrpUnloadHead.Flink;
1447  while (NextEntry != &LdrpUnloadHead)
1448  {
1449  /* Get the current entry */
1450  LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
1451 
1452  /* FIXME: Log the Unload Event */
1453  //LdrpRecordUnloadEvent(LdrEntry);
1454 
1455  /* Set the entry and clear it from the list */
1456  CurrentEntry = LdrEntry;
1458  CurrentEntry->InMemoryOrderLinks.Flink = NULL;
1459 
1460  /* Move it from the global to the local list */
1461  RemoveEntryList(&CurrentEntry->HashLinks);
1462  InsertTailList(&UnloadList, &CurrentEntry->HashLinks);
1463 
1464  /* Get the entrypoint */
1465  EntryPoint = LdrEntry->EntryPoint;
1466 
1467  /* Check if we should call it */
1468  if ((EntryPoint) && (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED))
1469  {
1470  /* Show message */
1471  if (ShowSnaps)
1472  {
1473  DPRINT1("LDR: Calling deinit %p\n", EntryPoint);
1474  }
1475 
1476  /* Set up the Act Ctx */
1477  ActCtx.Size = sizeof(ActCtx);
1480 
1481  /* Activate the ActCtx */
1483  LdrEntry->EntryPointActivationContext);
1484 
1485  /* Call the entrypoint */
1486  _SEH2_TRY
1487  {
1488  LdrpCallInitRoutine(LdrEntry->EntryPoint,
1489  LdrEntry->DllBase,
1491  NULL);
1492  }
1494  {
1495  DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_DETACH) for %wZ\n",
1496  _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
1497  }
1498  _SEH2_END;
1499 
1500  /* Release the context */
1502  }
1503 
1504  /* Remove it from the list */
1505  RemoveEntryList(&CurrentEntry->InLoadOrderLinks);
1506  CurrentEntry = NULL;
1507  NextEntry = LdrpUnloadHead.Flink;
1508  }
1509 
1510  /* Now loop our local list */
1511  NextEntry = UnloadList.Flink;
1512  while (NextEntry != &UnloadList)
1513  {
1514  /* Get the entry */
1515  LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
1516  NextEntry = NextEntry->Flink;
1517  CurrentEntry = LdrEntry;
1518 
1519  /* Notify Application Verifier */
1521  {
1522  AVrfDllUnloadNotification(LdrEntry);
1523  }
1524 
1525  /* Show message */
1526  if (ShowSnaps)
1527  {
1528  DPRINT1("LDR: Unmapping [%ws]\n", LdrEntry->BaseDllName.Buffer);
1529  }
1530 
1531  /* Check if this is a .NET executable */
1532  CorImageData = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1533  TRUE,
1535  &ComSectionSize);
1536  if (CorImageData)
1537  {
1538  /* FIXME */
1539  DPRINT1(".NET Images are not supported yet\n");
1540  }
1541 
1542  /* Check if we should unmap*/
1543  if (!(CurrentEntry->Flags & LDR_COR_OWNS_UNMAP))
1544  {
1545  /* Unmap the DLL */
1547  CurrentEntry->DllBase);
1549  }
1550 
1551  /* Unload the alternate resource module, if any */
1553 
1554  /* FIXME: Send shutdown notification */
1555  //LdrpSendDllNotifications(CurrentEntry, 2, LdrpShutdownInProgress);
1556 
1557  /* Check if a Hotpatch is active */
1558  if (LdrEntry->PatchInformation)
1559  {
1560  /* FIXME */
1561  DPRINT1("We don't support Hotpatching yet\n");
1562  }
1563 
1564  /* Deallocate the Entry */
1566 
1567  /* If this is the cached entry, invalidate it */
1568  if (LdrpGetModuleHandleCache == CurrentEntry)
1569  {
1571  }
1572  }
1573 
1574 Quickie:
1575  /* Decrease unload count */
1578 
1579  /* Return to caller */
1580  return Status;
1581 }
1582 
1583 /*
1584  * @implemented
1585  */
1586 BOOLEAN
1587 NTAPI
1589 {
1590  /* Return the internal global */
1591  return LdrpShutdownInProgress;
1592 }
1593 
1594 /*
1595  * @implemented
1596  */
1598 NTAPI
1600  IN ULONG Count,
1601  IN PUSHORT TypeOffset,
1602  IN LONG_PTR Delta)
1603 {
1604  return LdrProcessRelocationBlockLongLong(Address, Count, TypeOffset, Delta);
1605 }
1606 
1607 /* FIXME: Add to ntstatus.mc */
1608 #define STATUS_MUI_FILE_NOT_FOUND ((NTSTATUS)0xC00B0001L)
1609 
1610 /*
1611  * @implemented
1612  */
1613 NTSTATUS
1614 NTAPI
1616  IN PWSTR Buffer)
1617 {
1618  /* Is MUI Support enabled? */
1620 
1621  UNIMPLEMENTED;
1623 }
1624 
1625 /*
1626  * @implemented
1627  */
1628 BOOLEAN
1629 NTAPI
1631 {
1632  ULONG_PTR Cookie;
1633 
1634  /* Acquire the loader lock */
1636 
1637  /* Check if there's any alternate resources loaded */
1639  {
1640  UNIMPLEMENTED;
1641  }
1642 
1643  /* Release the loader lock */
1645 
1646  /* All done */
1647  return TRUE;
1648 }
1649 
1650 /*
1651  * @unimplemented
1652  */
1653 BOOLEAN
1654 NTAPI
1656 {
1657  UNIMPLEMENTED;
1658  return FALSE;
1659 }
1660 
1661 /* EOF */
ULONG AlternateResourceModuleCount
Definition: ldrapi.c:23
#define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS
Definition: ldrtypes.h:75
signed char * PCHAR
Definition: retypes.h:7
#define LDRP_UPDATE_PIN
Definition: ntdllp.h:17
NTSTATUS NTAPI LdrGetDllHandleEx(IN ULONG Flags, IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle OPTIONAL)
Definition: ldrapi.c:522
#define IN
Definition: typedefs.h:38
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
VOID NTAPI LdrpUpdateLoadCount2(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Flags)
Definition: ldrutils.c:460
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2697
BOOLEAN g_ShimsEnabled
Definition: ldrutils.c:21
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3780
#define TRUE
Definition: types.h:120
BOOLEAN LdrpBreakOnRecursiveDllLoads
Definition: ldrapi.c:21
FORCEINLINE ULONG_PTR LdrpMakeCookie(VOID)
Definition: ldrapi.c:89
NTSTATUS NTAPI LdrGetDllHandle(IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle)
Definition: ldrapi.c:805
PPEB Peb
Definition: dllmain.c:27
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD Unknown3
Definition: conport.c:35
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG _In_opt_ PEVENT_FILTER_DESCRIPTOR _Inout_opt_ PVOID CallbackContext
Definition: wmitypes.h:55
LIST_ENTRY InInitializationOrderModuleList
Definition: ldrtypes.h:121
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
VOID(NTAPI * PLDR_CALLBACK)(PVOID CallbackContext, PCHAR Name)
Definition: umfuncs.h:217
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
#define LDRP_DONT_CALL_FOR_THREADS
Definition: ldrtypes.h:47
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:3371
struct _Entry Entry
Definition: kefuncs.h:640
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
NTSTATUS NTAPI LdrUnlockLoaderLock(IN ULONG Flags, IN ULONG Cookie OPTIONAL)
Definition: ldrapi.c:101
USHORT MaximumLength
Definition: env_spec_w32.h:370
PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache
Definition: ldrutils.c:19
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define LDRP_REDIRECTED
Definition: ldrtypes.h:57
uint16_t * PWSTR
Definition: typedefs.h:54
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
#define LDR_COR_OWNS_UNMAP
Definition: ldrtypes.h:52
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489
#define FLG_HEAP_ENABLE_TAIL_CHECK
Definition: pstypes.h:60
NTSTATUS NTAPI LdrAddRefDll(IN ULONG Flags, IN PVOID BaseAddress)
Definition: ldrapi.c:1237
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN ShowSnaps
Definition: ldrinit.c:81
#define RtlImageRvaToVa
Definition: compat.h:458
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
#define HandleToUlong(h)
Definition: basetsd.h:79
NTSTATUS NTAPI LdrDestroyOutOfProcessImage(IN PVOID Image)
Definition: ldrapi.c:42
LIST_ENTRY InMemoryOrderModuleList
Definition: btrfs_drv.h:1820
NTSTATUS NTAPI LdrLockLoaderLock(IN ULONG Flags, OUT PULONG Disposition OPTIONAL, OUT PULONG_PTR Cookie OPTIONAL)
Definition: ldrapi.c:173
ULONG SizeOfImage
Definition: ldrtypes.h:142
NTSYSAPI ULONG __cdecl DbgPrintEx(_In_ ULONG ComponentId, _In_ ULONG Level, _In_z_ _Printf_format_string_ PCSTR Format,...)
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
BOOLEAN NTAPI LdrFlushAlternateResourceModules(VOID)
Definition: ldrapi.c:1655
#define STATUS_SXS_KEY_NOT_FOUND
Definition: ntstatus.h:1170
#define LDR_LOCK_LOADER_LOCK_DISPOSITION_INVALID
Definition: ldrtypes.h:90
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
uint16_t * PWCHAR
Definition: typedefs.h:54
#define InsertTailList(ListHead, Entry)
HANDLE UniqueProcess
Definition: compat.h:474
#define UNICODE_STRING_MAX_BYTES
NTSTATUS NTAPI LdrVerifyImageMatchesChecksum(IN HANDLE FileHandle, IN PLDR_CALLBACK Callback, IN PVOID CallbackContext, OUT PUSHORT ImageCharacteristics)
Definition: ldrapi.c:837
ULONG LdrpActiveUnloadCount
Definition: ldrinit.c:84
BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum(_In_ PVOID BaseAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG FileLength)
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#define DPFLTR_WARNING_LEVEL
Definition: kdtypes.h:31
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED
Definition: ldrtypes.h:92
#define SearchPath
Definition: winbase.h:3714
_In_ PVOID _Out_ BOOLEAN * Stop
Definition: ldrtypes.h:240
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
PVOID g_pfnSE_DllUnloaded
Definition: ldrutils.c:24
CLIENT_ID ClientId
Definition: compat.h:488
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
PVOID DllBase
Definition: btrfs_drv.h:1805
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
ULONG NtGlobalFlag
Definition: ntddk_ex.h:270
#define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY
Definition: ldrtypes.h:76
LDR_MANIFEST_PROBER_ROUTINE * PLDR_MANIFEST_PROBER_ROUTINE
Definition: ldrtypes.h:247
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:1974
HANDLE FileHandle
Definition: stats.c:38
NTSTATUS NTAPI LdrCreateOutOfProcessImage(IN ULONG Flags, IN HANDLE ProcessHandle, IN HANDLE DllHandle, IN PVOID Unknown3)
Definition: ldrapi.c:50
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
USHORT TlsIndex
Definition: ntddk_ex.h:209
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:463
#define SEC_COMMIT
Definition: mmtypes.h:99
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
#define ANSI_NULL
long LONG
Definition: pedump.c:60
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:260
PVOID EntryPoint
Definition: ntddk_ex.h:203
PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlockLongLong(_In_ ULONG_PTR Address, _In_ ULONG Count, _In_ PUSHORT TypeOffset, _In_ LONGLONG Delta)
PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer
Definition: ldrinit.c:43
#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED
Definition: ldrtypes.h:91
NTSTATUS NTAPI NtMapViewOfSection(IN HANDLE SectionHandle, IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3552
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSTATUS NTAPI LdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress)
Definition: ldrapi.c:823
NTSTATUS NTAPI LdrFindCreateProcessManifest(IN ULONG Flags, IN PVOID Image, IN PVOID IdPath, IN ULONG IdPathLength, IN PVOID OutDataEntry)
Definition: ldrapi.c:30
unsigned char BOOLEAN
#define STATUS_MUI_FILE_NOT_FOUND
Definition: ldrapi.c:1608
PVOID EntryInProgress
Definition: ldrtypes.h:122
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:462
#define FORCEINLINE
Definition: ntbasedef.h:221
_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:426
#define PAGE_EXECUTE
Definition: nt_native.h:1306
#define LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS
Definition: ldrtypes.h:81
PVOID NTAPI RtlDecodeSystemPointer(IN PVOID Pointer)
Definition: process.c:439
void DPRINT(...)
Definition: polytest.cpp:61
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define LDRP_UPDATE_DEREFCOUNT
Definition: ntdllp.h:16
Definition: bufpool.h:45
#define RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER
Definition: rtltypes.h:101
LDR_ENUM_CALLBACK * PLDR_ENUM_CALLBACK
Definition: ldrtypes.h:241
VOID NTAPI AVrfDllUnloadNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: verifier.c:328
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSTATUS NTAPI LdrAccessOutOfProcessResource(IN PVOID Unknown, IN PVOID Image, IN PVOID Unknown1, IN PVOID Unknown2, IN PVOID Unknown3)
Definition: ldrapi.c:61
void * PVOID
Definition: retypes.h:9
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
BOOLEAN NTAPI RtlDllShutdownInProgress(VOID)
Definition: ldrapi.c:1588
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:484
#define LDR_GET_DLL_HANDLE_EX_PIN
Definition: ldrtypes.h:87
#define DLL_PROCESS_DETACH
Definition: compat.h:119
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define STATUS_IMAGE_CHECKSUM_MISMATCH
Definition: ntstatus.h:663
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:224
VOID NTAPI LdrpFinalizeAndDeallocateDataTableEntry(IN PLDR_DATA_TABLE_ENTRY Entry)
Definition: ldrutils.c:1593
PVOID PatchInformation
Definition: ldrtypes.h:163
BOOLEAN NTAPI LdrUnloadAlternateResourceModule(IN PVOID BaseAddress)
Definition: ldrapi.c:1630
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
VOID WINAPI SE_DllUnloaded(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:1414
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:13
#define MAX_PATH
Definition: compat.h:26
CLIENT_ID RealClientId
Definition: compat.h:510
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame)
Definition: actctx.c:5934
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSTATUS NTAPI LdrpGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress, IN BOOLEAN ExecuteInit)
Definition: ldrutils.c:2247
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:246
static BOOL CompareName(LPCWSTR pszName1, LPCWSTR pszName2)
Definition: find.c:72
NTSTATUS NTAPI LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation, IN ULONG Size, OUT PULONG ReturnedSize OPTIONAL)
Definition: ldrapi.c:1107
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
HANDLE UniqueThread
Definition: compat.h:475
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _RTL_PROCESS_MODULE_INFORMATION RTL_PROCESS_MODULE_INFORMATION
ULONG NTAPI LdrpClearLoadInProgress(VOID)
Definition: ldrutils.c:2658
PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache
Definition: ldrutils.c:19
VOID NTAPI LdrSetDllManifestProber(_In_ PLDR_MANIFEST_PROBER_ROUTINE Routine)
Definition: ldrapi.c:73
#define LDRP_UNLOAD_IN_PROGRESS
Definition: ldrtypes.h:42
static const WCHAR L[]
Definition: oid.c:1250
#define RtlImageDirectoryEntryToData
Definition: compat.h:460
LIST_ENTRY HashLinks
Definition: ldrtypes.h:150
#define VOID
Definition: acefi.h:82
PLDR_MANIFEST_PROBER_ROUTINE LdrpManifestProberRoutine
Definition: ldrpe.c:18
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:461
NTSYSAPI NTSTATUS NTAPI RtlDosApplyFileIsolationRedirection_Ustr(IN ULONG Flags, IN PUNICODE_STRING OriginalName, IN PUNICODE_STRING Extension, IN OUT PUNICODE_STRING StaticString, IN OUT PUNICODE_STRING DynamicString, IN OUT PUNICODE_STRING *NewName, IN PULONG NewFlags, IN PSIZE_T FileNameSize, IN PSIZE_T RequiredLength)
Definition: libsupp.c:778
Definition: btrfs_drv.h:1801
ULONG LowPart
Definition: typedefs.h:104
PUNICODE_STRING LdrpTopLevelDllBeingLoaded
Definition: ldrinit.c:40
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(IN PWSTR SearchPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress)
Definition: ldrapi.c:310
LONG LdrpLoaderLockAcquisitionCount
Definition: ldrapi.c:20
UNICODE_STRING LdrApiDefaultExtension
Definition: ldrapi.c:22
Definition: typedefs.h:117
NTSTATUS NTAPI LdrEnumerateLoadedModules(IN BOOLEAN ReservedFlag, IN PLDR_ENUM_CALLBACK EnumProc, IN PVOID Context)
Definition: ldrapi.c:1120
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
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:2424
PVOID LoaderLock
Definition: ntddk_ex.h:295
Status
Definition: gdiplustypes.h:24
BOOLEAN LdrpShowRecursiveLoads
Definition: ldrapi.c:21
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:137
NTSTATUS NTAPI LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress)
Definition: ldrapi.c:1187
#define _In_
Definition: no_sal2.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define STATUS_DLL_INIT_FAILED
Definition: ntstatus.h:544
Definition: compat.h:484
NTSTATUS NTAPI LdrUnloadDll(IN PVOID BaseAddress)
Definition: ldrapi.c:1322
_SEH2_END
Definition: create.c:4424
BOOLEAN LdrpShutdownInProgress
Definition: ldrinit.c:34
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define NtCurrentPeb()
Definition: FLS.c:19
NTSTATUS NTAPI LdrLoadAlternateResourceModule(IN PVOID Module, IN PWSTR Buffer)
Definition: ldrapi.c:1615
#define STATUS_DLL_NOT_FOUND
Definition: ntstatus.h:531
LIST_ENTRY InMemoryOrderLinks
Definition: btrfs_drv.h:1803
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1837
static const char const char * DllPath
Definition: image.c:34
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
static ULONG Delta
Definition: xboxvideo.c:28
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1807
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:144
_SEH2_FINALLY
Definition: create.c:4395
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
PACTIVATION_CONTEXT EntryPointActivationContext
Definition: ldrtypes.h:162
NTSTATUS NTAPI LdrQueryProcessModuleInformationEx(IN ULONG ProcessId, IN ULONG Reserved, OUT PRTL_PROCESS_MODULES ModuleInformation, IN ULONG Size, OUT PULONG ReturnedSize OPTIONAL)
Definition: ldrapi.c:979
#define LDRP_UPDATE_REFCOUNT
Definition: ntdllp.h:15
#define DPRINT1
Definition: precomp.h:8
#define FileStandardInformation
Definition: propsheet.cpp:61
#define RtlImageNtHeader
Definition: compat.h:457
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame, IN PVOID Context)
Definition: actctx.c:5857
#define LDRP_IMAGE_DLL
Definition: ldrtypes.h:39
#define OUT
Definition: typedefs.h:39
#define LDR_GET_DLL_HANDLE_EX_UNCHANGED_REFCOUNT
Definition: ldrtypes.h:86
BOOLEAN NTAPI LdrpCheckForLoadedDllHandle(IN PVOID Base, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
Definition: ldrutils.c:1616
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
#define LDR_ADDREF_DLL_PIN
Definition: ldrtypes.h:70
ULONG Flags
Definition: ntddk_ex.h:207
RTL_CRITICAL_SECTION LdrpLoaderLock
Definition: ldrinit.c:70
unsigned int ULONG
Definition: retypes.h:1
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1290
static BOOL CALLBACK EnumProc(_In_ HWND hWnd, _In_ LPARAM lParam)
Definition: SetParent.c:53
BOOLEAN NTAPI LdrAlternateResourcesEnabled(VOID)
Definition: ldrapi.c:81
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:63
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
BOOLEAN LdrpInLdrInit
Definition: ldrinit.c:30
GLfloat GLfloat p
Definition: glext.h:8902
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlock(IN ULONG_PTR Address, IN ULONG Count, IN PUSHORT TypeOffset, IN LONG_PTR Delta)
Definition: ldrapi.c:1599
return STATUS_SUCCESS
Definition: btrfs.c:2725
#define __FUNCTION__
Definition: types.h:112
LPFNPSPCALLBACK Callback
Definition: desk.c:111
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
NTSYSAPI BOOLEAN NTAPI RtlTryEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define LDRP_PROCESS_ATTACH_CALLED
Definition: ldrtypes.h:48
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
NTSTATUS NTAPI LdrFindEntryForAddress(PVOID Address, PLDR_DATA_TABLE_ENTRY *Module)
Definition: ldrapi.c:443
LIST_ENTRY * ModuleListHead
Definition: kdpacket.c:23
unsigned short * PUSHORT
Definition: retypes.h:2
LIST_ENTRY InInitializationOrderLinks
Definition: ldrtypes.h:139
base of all file and directory entries
Definition: entries.h:82
USHORT LoadCount
Definition: ntddk_ex.h:208
BOOLEAN NTAPI LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context)
Definition: ldrutils.c:100
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
LIST_ENTRY LdrpUnloadHead
Definition: ldrapi.c:19
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68