ReactOS 0.4.16-dev-981-g80eb313
ldrutils.c File Reference
#include <ntdll.h>
#include <debug.h>
Include dependency graph for ldrutils.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI LdrpAllocateUnicodeString (IN OUT PUNICODE_STRING StringOut, IN ULONG Length)
 
VOID NTAPI LdrpFreeUnicodeString (IN PUNICODE_STRING StringIn)
 
BOOLEAN NTAPI LdrpCallInitRoutine (IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context)
 
VOID NTAPI LdrpUpdateLoadCount3 (IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Flags, OUT PUNICODE_STRING UpdateString)
 
VOID NTAPI LdrpUpdateLoadCount2 (IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Flags)
 
VOID NTAPI LdrpCallTlsInitializers (IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Reason)
 
NTSTATUS NTAPI LdrpCodeAuthzCheckDllAllowed (IN PUNICODE_STRING FullName, IN HANDLE DllHandle)
 
NTSTATUS NTAPI LdrpCreateDllSection (IN PUNICODE_STRING FullName, IN HANDLE DllHandle, IN PULONG DllCharacteristics OPTIONAL, OUT PHANDLE SectionHandle)
 
BOOLEAN NTAPI LdrpResolveDllName (PWSTR DllPath, PWSTR DllName, PUNICODE_STRING FullDllName, PUNICODE_STRING BaseDllName)
 
PVOID NTAPI LdrpFetchAddressOfEntryPoint (IN PVOID ImageBase)
 
NTSTATUS NTAPI LdrpCheckForKnownDll (PWSTR DllName, PUNICODE_STRING FullDllName, PUNICODE_STRING BaseDllName, HANDLE *SectionHandle)
 
NTSTATUS NTAPI LdrpSetProtection (PVOID ViewBase, BOOLEAN Restore)
 
NTSTATUS NTAPI LdrpMapDll (IN PWSTR SearchPath OPTIONAL, IN PWSTR DllPath2, IN PWSTR DllName OPTIONAL, IN PULONG DllCharacteristics, IN BOOLEAN Static, IN BOOLEAN Redirect, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
 
PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry (IN PVOID BaseAddress)
 
VOID NTAPI LdrpInsertMemoryTableEntry (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
VOID NTAPI LdrpFinalizeAndDeallocateDataTableEntry (IN PLDR_DATA_TABLE_ENTRY Entry)
 
BOOLEAN NTAPI LdrpCheckForLoadedDllHandle (IN PVOID Base, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
 
NTSTATUS NTAPI LdrpResolveFullName (IN PUNICODE_STRING OriginalName, IN PUNICODE_STRING PathName, IN PUNICODE_STRING FullPathName, IN PUNICODE_STRING *ExpandedName)
 
NTSTATUS NTAPI LdrpSearchPath (IN PWCHAR *SearchPath, IN PWCHAR DllName, IN PUNICODE_STRING PathName, IN PUNICODE_STRING FullPathName, IN PUNICODE_STRING *ExpandedName)
 
BOOLEAN NTAPI LdrpCheckForLoadedDll (IN PWSTR DllPath, IN PUNICODE_STRING DllName, IN BOOLEAN Flag, IN BOOLEAN RedirectedDll, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
 
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)
 
NTSTATUS NTAPI LdrpLoadDll (IN BOOLEAN Redirected, IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress, IN BOOLEAN CallInit)
 
ULONG NTAPI LdrpClearLoadInProgress (VOID)
 
PVOID LdrpGetShimEngineFunction (PCSZ FunctionName)
 
VOID NTAPI LdrpGetShimEngineInterface ()
 
VOID NTAPI LdrpRunShimEngineInitRoutine (IN ULONG Reason)
 
VOID NTAPI LdrpLoadShimEngine (IN PWSTR ImageName, IN PUNICODE_STRING ProcessImage, IN PVOID pShimData)
 
VOID NTAPI LdrpUnloadShimEngine ()
 

Variables

PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache
 
PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache
 
BOOLEAN g_ShimsEnabled
 
PVOID g_pShimEngineModule
 
PVOID g_pfnSE_DllLoaded
 
PVOID g_pfnSE_DllUnloaded
 
PVOID g_pfnSE_InstallBeforeInit
 
PVOID g_pfnSE_InstallAfterInit
 
PVOID g_pfnSE_ProcessDying
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file ldrutils.c.

Function Documentation

◆ LdrpAllocateDataTableEntry()

PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry ( IN PVOID  BaseAddress)

Definition at line 1528 of file ldrutils.c.

1529{
1530 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
1531 PIMAGE_NT_HEADERS NtHeader;
1532
1533 /* Make sure the header is valid */
1534 NtHeader = RtlImageNtHeader(BaseAddress);
1535 DPRINT("LdrpAllocateDataTableEntry(%p), NtHeader %p\n", BaseAddress, NtHeader);
1536
1537 if (NtHeader)
1538 {
1539 /* Allocate an entry */
1540 LdrEntry = RtlAllocateHeap(LdrpHeap,
1542 sizeof(LDR_DATA_TABLE_ENTRY));
1543
1544 /* Make sure we got one */
1545 if (LdrEntry)
1546 {
1547 /* Set it up */
1548 LdrEntry->DllBase = BaseAddress;
1549 LdrEntry->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
1550 LdrEntry->TimeDateStamp = NtHeader->FileHeader.TimeDateStamp;
1551 LdrEntry->PatchInformation = NULL;
1552 }
1553 }
1554
1555 /* Return the entry */
1556 return LdrEntry;
1557}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
#define NULL
Definition: types.h:112
#define RtlImageNtHeader
Definition: compat.h:806
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
PVOID LdrpHeap
Definition: ldrinit.c:3
#define DPRINT
Definition: sndvol32.h:73
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
Definition: btrfs_drv.h:1876
ULONG SizeOfImage
Definition: ldrtypes.h:147
PVOID DllBase
Definition: btrfs_drv.h:1880
ULONG TimeDateStamp
Definition: btrfs_drv.h:1889
PVOID PatchInformation
Definition: ldrtypes.h:168

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

◆ LdrpAllocateUnicodeString()

NTSTATUS NTAPI LdrpAllocateUnicodeString ( IN OUT PUNICODE_STRING  StringOut,
IN ULONG  Length 
)

Definition at line 33 of file ldrutils.c.

35{
36 /* Sanity checks */
39
40 /* Assume failure */
41 StringOut->Length = 0;
42
43 /* Make sure it's not mis-aligned */
44 if (Length & 1)
45 {
46 /* Fail */
47 StringOut->Buffer = NULL;
48 StringOut->MaximumLength = 0;
50 }
51
52 /* Allocate the string*/
54 0,
55 Length + sizeof(WCHAR));
56 if (!StringOut->Buffer)
57 {
58 /* Fail */
59 StringOut->MaximumLength = 0;
60 return STATUS_NO_MEMORY;
61 }
62
63 /* Null-terminate it */
64 StringOut->Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
65
66 /* Check if this is a maximum-sized string */
68 {
69 /* It's not, so set the maximum length to be one char more */
70 StringOut->MaximumLength = (USHORT)Length + sizeof(UNICODE_NULL);
71 }
72 else
73 {
74 /* The length is already the maximum possible */
75 StringOut->MaximumLength = UNICODE_STRING_MAX_BYTES;
76 }
77
78 /* Return success */
79 return STATUS_SUCCESS;
80}
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define ASSERT(a)
Definition: mode.c:44
string StringOut(const string &String, bool forcePrint=true)
Definition: tools.cpp:96
#define UNICODE_NULL
#define UNICODE_STRING_MAX_BYTES
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by LdrpResolveFullName().

◆ LdrpCallInitRoutine()

BOOLEAN NTAPI LdrpCallInitRoutine ( IN PDLL_INIT_ROUTINE  EntryPoint,
IN PVOID  BaseAddress,
IN ULONG  Reason,
IN PVOID  Context 
)

Definition at line 100 of file ldrutils.c.

104{
105 /* Call the entry */
106 return EntryPoint(BaseAddress, Reason, Context);
107}
PVOID PVOID PWCHAR PVOID USHORT PULONG Reason
Definition: env.c:47

Referenced by AVrfpLoadAndInitializeProvider(), LdrpCallTlsInitializers(), LdrpInitializeThread(), LdrpRunInitializeRoutines(), LdrpRunShimEngineInitRoutine(), LdrShutdownProcess(), LdrShutdownThread(), and LdrUnloadDll().

◆ LdrpCallTlsInitializers()

VOID NTAPI LdrpCallTlsInitializers ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry,
IN ULONG  Reason 
)

Definition at line 447 of file ldrutils.c.

449{
450 PIMAGE_TLS_DIRECTORY TlsDirectory;
452 ULONG Size;
453
454 /* Get the TLS Directory */
455 TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
456 TRUE,
458 &Size);
459
460 /* Protect against invalid pointers */
462 {
463 /* Make sure it's valid */
464 if (TlsDirectory)
465 {
466 /* Get the array */
467 Array = (PIMAGE_TLS_CALLBACK *)TlsDirectory->AddressOfCallBacks;
468 if (Array)
469 {
470 /* Display debug */
471 if (ShowSnaps)
472 {
473 DPRINT1("LDR: Tls Callbacks Found. Imagebase %p Tls %p CallBacks %p\n",
474 LdrEntry->DllBase, TlsDirectory, Array);
475 }
476
477 /* Loop the array */
478 while (*Array)
479 {
480 /* Get the TLS Entrypoint */
481 Callback = *Array++;
482
483 /* Display debug */
484 if (ShowSnaps)
485 {
486 DPRINT1("LDR: Calling Tls Callback Imagebase %p Function %p\n",
487 LdrEntry->DllBase, Callback);
488 }
489
490 /* Call it */
492 LdrEntry->DllBase,
493 Reason,
494 NULL);
495 }
496 }
497 }
498 }
500 {
501 DPRINT1("LDR: Exception 0x%x during Tls Callback(%u) for %wZ\n",
502 _SEH2_GetExceptionCode(), Reason, &LdrEntry->BaseDllName);
503 }
504 _SEH2_END;
505}
#define DPRINT1
Definition: precomp.h:8
#define TRUE
Definition: types.h:120
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
BOOLEAN(NTAPI * PDLL_INIT_ROUTINE)(_In_ PVOID DllHandle, _In_ ULONG Reason, _In_opt_ PCONTEXT Context)
Definition: ldrtypes.h:271
BOOLEAN NTAPI LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context)
Definition: ldrutils.c:100
if(dx< 0)
Definition: linetemp.h:194
BOOLEAN ShowSnaps
Definition: ldrinit.c:79
VOID(NTAPI * PIMAGE_TLS_CALLBACK)(PVOID DllHandle, ULONG Reason, PVOID Reserved)
Definition: ntimage.h:531
#define IMAGE_DIRECTORY_ENTRY_TLS
Definition: pedump.c:268
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458

Referenced by LdrpInitializeThread(), LdrpRunInitializeRoutines(), LdrShutdownProcess(), and LdrShutdownThread().

◆ LdrpCheckForKnownDll()

NTSTATUS NTAPI LdrpCheckForKnownDll ( PWSTR  DllName,
PUNICODE_STRING  FullDllName,
PUNICODE_STRING  BaseDllName,
HANDLE SectionHandle 
)

Definition at line 788 of file ldrutils.c.

792{
794 HANDLE Section = NULL;
795 UNICODE_STRING DllNameUnic;
797 PCHAR p1;
798 PWCHAR p2;
799
800 /* Zero initialize provided parameters */
801 if (SectionHandle) *SectionHandle = 0;
802
803 if (FullDllName)
804 {
805 FullDllName->Length = 0;
806 FullDllName->MaximumLength = 0;
807 FullDllName->Buffer = NULL;
808 }
809
810 if (BaseDllName)
811 {
812 BaseDllName->Length = 0;
813 BaseDllName->MaximumLength = 0;
814 BaseDllName->Buffer = NULL;
815 }
816
817 /* If any of these three params are missing then fail */
818 if (!SectionHandle || !FullDllName || !BaseDllName)
820
821 /* Check the Loader Lock */
823
824 /* Upgrade DllName to a unicode string */
825 RtlInitUnicodeString(&DllNameUnic, DllName);
826
827 /* FIXME: Missing RtlComputePrivatizedDllName_U related functionality */
828
829 /* Get the activation context */
831 NULL,
832 ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
833 &DllNameUnic,
834 NULL);
835
836 /* Check if it's a SxS or not */
839 {
840 /* NOTE: Here it's beneficial to allocate one big unicode string
841 using LdrpAllocateUnicodeString instead of fragmenting the heap
842 with two allocations as it's done now. */
843
844 /* Set up BaseDllName */
845 BaseDllName->Length = DllNameUnic.Length;
846 BaseDllName->MaximumLength = DllNameUnic.MaximumLength;
847 BaseDllName->Buffer = RtlAllocateHeap(LdrpHeap,
848 0,
849 DllNameUnic.MaximumLength);
850 if (!BaseDllName->Buffer)
851 {
853 goto Failure;
854 }
855
856 /* Copy the contents there */
857 RtlMoveMemory(BaseDllName->Buffer, DllNameUnic.Buffer, DllNameUnic.MaximumLength);
858
859 /* Set up FullDllName */
860 FullDllName->Length = LdrpKnownDllPath.Length + BaseDllName->Length + sizeof(WCHAR);
861 FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
862 FullDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, FullDllName->MaximumLength);
863 if (!FullDllName->Buffer)
864 {
866 goto Failure;
867 }
868
870
871 /* Put a slash there */
873 p2 = (PWCHAR)p1;
874 *p2++ = (WCHAR)'\\';
875 p1 = (PCHAR)p2;
876
877 /* Set up DllNameUnic for a relative path */
878 DllNameUnic.Buffer = (PWSTR)p1;
879 DllNameUnic.Length = BaseDllName->Length;
880 DllNameUnic.MaximumLength = DllNameUnic.Length + sizeof(UNICODE_NULL);
881
882 /* Copy the contents */
883 RtlMoveMemory(p1, BaseDllName->Buffer, BaseDllName->MaximumLength);
884
885 /* There are all names, init attributes and open the section */
887 &DllNameUnic,
890 NULL);
891
892 Status = NtOpenSection(&Section,
895 if (!NT_SUCCESS(Status))
896 {
897 /* Clear status in case it was just not found */
899 goto Failure;
900 }
901
902 /* Pass section handle to the caller and return success */
903 *SectionHandle = Section;
904 return STATUS_SUCCESS;
905 }
906
907Failure:
908 /* Close section object if it was opened */
909 if (Section) NtClose(Section);
910
911 /* Free string resources */
912 if (BaseDllName->Buffer) RtlFreeHeap(LdrpHeap, 0, BaseDllName->Buffer);
913 if (FullDllName->Buffer) RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
914
915 /* Return status */
916 return Status;
917}
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3202
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define SECTION_MAP_READ
Definition: compat.h:139
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS WINAPI RtlFindActivationContextSectionString(ULONG, const GUID *, ULONG, const UNICODE_STRING *, PVOID)
Definition: actctx.c:5874
_In_ PCWSTR FullDllName
Definition: ldrtypes.h:264
#define PCHAR
Definition: match.c:90
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1290
#define SECTION_MAP_WRITE
Definition: nt_native.h:1288
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
UNICODE_STRING LdrpKnownDllPath
Definition: ldrinit.c:61
HANDLE LdrpKnownDllObjectDirectory
Definition: ldrinit.c:60
VOID NTAPI LdrpEnsureLoaderLockIsHeld(VOID)
Definition: ldrinit.c:408
#define STATUS_SXS_SECTION_NOT_FOUND
Definition: ntstatus.h:1382
#define STATUS_SXS_KEY_NOT_FOUND
Definition: ntstatus.h:1389
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
char * PCHAR
Definition: typedefs.h:51
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

Referenced by LdrpMapDll().

◆ LdrpCheckForLoadedDll()

BOOLEAN NTAPI LdrpCheckForLoadedDll ( IN PWSTR  DllPath,
IN PUNICODE_STRING  DllName,
IN BOOLEAN  Flag,
IN BOOLEAN  RedirectedDll,
OUT PLDR_DATA_TABLE_ENTRY LdrEntry 
)

Definition at line 1958 of file ldrutils.c.

1963{
1964 ULONG HashIndex;
1965 PLIST_ENTRY ListHead, ListEntry;
1966 PLDR_DATA_TABLE_ENTRY CurEntry;
1967 BOOLEAN FullPath = FALSE;
1968 PWCHAR wc;
1969 WCHAR NameBuf[266];
1970 UNICODE_STRING FullDllName, NtPathName;
1971 ULONG Length;
1974 HANDLE FileHandle, SectionHandle;
1976 PVOID ViewBase = NULL;
1977 SIZE_T ViewSize = 0;
1978 PIMAGE_NT_HEADERS NtHeader, NtHeader2;
1979 DPRINT("LdrpCheckForLoadedDll('%S' '%wZ' %u %u %p)\n", DllPath ? ((ULONG_PTR)DllPath == 1 ? L"" : DllPath) : L"", DllName, Flag, RedirectedDll, LdrEntry);
1980
1981 /* Check if a dll name was provided */
1982 if (!(DllName->Buffer) || !(DllName->Buffer[0])) return FALSE;
1983
1984 /* FIXME: Warning, "Flag" is used as magic instead of "Static" */
1985 /* FIXME: Warning, code does not support redirection at all */
1986
1987 /* Look in the hash table if flag was set */
1988lookinhash:
1989 if (Flag /* the second check is a hack */ && !RedirectedDll)
1990 {
1991 /* FIXME: if we get redirected dll it means that we also get a full path so we need to find its filename for the hash lookup */
1992
1993 /* Get hash index */
1994 HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]);
1995
1996 /* Traverse that list */
1997 ListHead = &LdrpHashTable[HashIndex];
1998 ListEntry = ListHead->Flink;
1999 while (ListEntry != ListHead)
2000 {
2001 /* Get the current entry */
2002 CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
2003
2004 /* Check base name of that module */
2005 if (RtlEqualUnicodeString(DllName, &CurEntry->BaseDllName, TRUE))
2006 {
2007 /* It matches, return it */
2008 *LdrEntry = CurEntry;
2009 return TRUE;
2010 }
2011
2012 /* Advance to the next entry */
2013 ListEntry = ListEntry->Flink;
2014 }
2015
2016 /* Module was not found, return failure */
2017 return FALSE;
2018 }
2019
2020 /* Check if this is a redirected DLL */
2021 if (RedirectedDll)
2022 {
2023 /* Redirected dlls already have a full path */
2024 FullPath = TRUE;
2025 FullDllName = *DllName;
2026 }
2027 else
2028 {
2029 /* Check if there is a full path in this DLL */
2030 wc = DllName->Buffer;
2031 while (*wc)
2032 {
2033 /* Check for a slash in the current position*/
2034 if ((*wc == L'\\') || (*wc == L'/'))
2035 {
2036 /* Found the slash, so dll name contains path */
2037 FullPath = TRUE;
2038
2039 /* Setup full dll name string */
2040 FullDllName.Buffer = NameBuf;
2041
2042 /* FIXME: This is from the Windows 2000 loader, not XP/2003, we should call LdrpSearchPath */
2044 DllName->Buffer,
2045 NULL,
2046 sizeof(NameBuf) - sizeof(UNICODE_NULL),
2047 FullDllName.Buffer,
2048 NULL);
2049
2050 /* Check if that was successful */
2051 if (!(Length) || (Length > (sizeof(NameBuf) - sizeof(UNICODE_NULL))))
2052 {
2053 if (ShowSnaps)
2054 {
2055 DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n",
2056 &DllName, Length);
2057 }
2058 }
2059
2060 /* Full dll name is found */
2061 FullDllName.Length = Length;
2062 FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL);
2063 break;
2064 }
2065
2066 wc++;
2067 }
2068 }
2069
2070 /* Go check the hash table */
2071 if (!FullPath)
2072 {
2073 Flag = TRUE;
2074 goto lookinhash;
2075 }
2076
2077 /* FIXME: Warning, activation context missing */
2078 DPRINT("Warning, activation context missing\n");
2079
2080 /* NOTE: From here on down, everything looks good */
2081
2082 /* Loop the module list */
2083 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
2084 ListEntry = ListHead->Flink;
2085 while (ListEntry != ListHead)
2086 {
2087 /* Get the current entry and advance to the next one */
2088 CurEntry = CONTAINING_RECORD(ListEntry,
2090 InLoadOrderLinks);
2091 ListEntry = ListEntry->Flink;
2092
2093 /* Check if it's being unloaded */
2094 if (!CurEntry->InMemoryOrderLinks.Flink) continue;
2095
2096 /* Check if name matches */
2098 &CurEntry->FullDllName,
2099 TRUE))
2100 {
2101 /* Found it */
2102 *LdrEntry = CurEntry;
2103 return TRUE;
2104 }
2105 }
2106
2107 /* Convert given path to NT path */
2109 &NtPathName,
2110 NULL,
2111 NULL))
2112 {
2113 /* Fail if conversion failed */
2114 return FALSE;
2115 }
2116
2117 /* Initialize object attributes and open it */
2119 &NtPathName,
2121 NULL,
2122 NULL);
2126 &Iosb,
2129
2130 /* Free NT path name */
2131 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
2132
2133 /* If opening the file failed - return failure */
2134 if (!NT_SUCCESS(Status)) return FALSE;
2135
2136 /* Create a section for this file */
2137 Status = NtCreateSection(&SectionHandle,
2141 NULL,
2142 NULL,
2144 SEC_COMMIT,
2145 FileHandle);
2146
2147 /* Close file handle */
2149
2150 /* If creating section failed - return failure */
2151 if (!NT_SUCCESS(Status)) return FALSE;
2152
2153 /* Map view of this section */
2154 Status = ZwMapViewOfSection(SectionHandle,
2156 &ViewBase,
2157 0,
2158 0,
2159 NULL,
2160 &ViewSize,
2161 ViewShare,
2162 0,
2163 PAGE_EXECUTE);
2164
2165 /* Close section handle */
2166 NtClose(SectionHandle);
2167
2168 /* If section mapping failed - return failure */
2169 if (!NT_SUCCESS(Status)) return FALSE;
2170
2171 /* Get pointer to the NT header of this section */
2172 Status = RtlImageNtHeaderEx(0, ViewBase, ViewSize, &NtHeader);
2173 if (!(NT_SUCCESS(Status)) || !(NtHeader))
2174 {
2175 /* Unmap the section and fail */
2177 return FALSE;
2178 }
2179
2180 /* Go through the list of modules again */
2181 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
2182 ListEntry = ListHead->Flink;
2183 while (ListEntry != ListHead)
2184 {
2185 /* Get the current entry and advance to the next one */
2186 CurEntry = CONTAINING_RECORD(ListEntry,
2188 InLoadOrderLinks);
2189 ListEntry = ListEntry->Flink;
2190
2191 /* Check if it's in the process of being unloaded */
2192 if (!CurEntry->InMemoryOrderLinks.Flink) continue;
2193
2194 /* The header is untrusted, use SEH */
2195 _SEH2_TRY
2196 {
2197 /* Check if timedate stamp and sizes match */
2198 if ((CurEntry->TimeDateStamp == NtHeader->FileHeader.TimeDateStamp) &&
2199 (CurEntry->SizeOfImage == NtHeader->OptionalHeader.SizeOfImage))
2200 {
2201 /* Time, date and size match. Let's compare their headers */
2202 NtHeader2 = RtlImageNtHeader(CurEntry->DllBase);
2203 if (RtlCompareMemory(NtHeader2, NtHeader, sizeof(IMAGE_NT_HEADERS)))
2204 {
2205 /* Headers match too! Finally ask the kernel to compare mapped files */
2206 Status = ZwAreMappedFilesTheSame(CurEntry->DllBase, ViewBase);
2207 if (NT_SUCCESS(Status))
2208 {
2209 /* This is our entry!, unmap and return success */
2210 *LdrEntry = CurEntry;
2212 _SEH2_YIELD(return TRUE;)
2213 }
2214 }
2215 }
2216 }
2218 {
2219 _SEH2_YIELD(break;)
2220 }
2221 _SEH2_END;
2222 }
2223
2224 /* Unmap the section and fail */
2226 return FALSE;
2227}
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3481
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:3074
#define NtCurrentPeb()
Definition: FLS.c:22
unsigned char BOOLEAN
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
NTSTATUS NTAPI RtlImageNtHeaderEx(_In_ ULONG Flags, _In_ PVOID Base, _In_ ULONG64 Size, _Out_ PIMAGE_NT_HEADERS *OutHeaders)
Definition: libsupp.c:32
#define FALSE
Definition: types.h:117
#define FILE_SHARE_READ
Definition: compat.h:136
return Iosb
Definition: create.c:4403
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
static const char const char * DllPath
Definition: image.c:34
NTSYSAPI NTSTATUS NTAPI ZwAreMappedFilesTheSame(_In_ PVOID File1MappedAsAnImage, _In_ PVOID File2MappedAsFile)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize 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 ULONG NTAPI RtlDosSearchPath_U(_In_ PCWSTR Path, _In_ PCWSTR FileName, _In_ PCWSTR Extension, _In_ ULONG BufferSize, _Out_ PWSTR Buffer, _Out_ PWSTR *PartName)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3953
#define SYNCHRONIZE
Definition: nt_native.h:61
#define PAGE_EXECUTE
Definition: nt_native.h:1306
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_EXECUTE
Definition: nt_native.h:642
@ ViewShare
Definition: nt_native.h:1278
UNICODE_STRING LdrpDefaultPath
Definition: ldrinit.c:63
#define LDR_GET_HASH_ENTRY(x)
Definition: ntdllp.h:12
LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]
Definition: ldrinit.c:59
#define L(x)
Definition: ntvdm.h:50
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:184
Definition: xml2sdb.h:80
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
LIST_ENTRY InMemoryOrderLinks
Definition: btrfs_drv.h:1878
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:149
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by LdrGetDllHandleEx(), LdrpLoadDll(), LdrpLoadImportModule(), and LdrpUpdateLoadCount3().

◆ LdrpCheckForLoadedDllHandle()

BOOLEAN NTAPI LdrpCheckForLoadedDllHandle ( IN PVOID  Base,
OUT PLDR_DATA_TABLE_ENTRY LdrEntry 
)

Definition at line 1600 of file ldrutils.c.

1602{
1603 PLDR_DATA_TABLE_ENTRY Current;
1604 PLIST_ENTRY ListHead, Next;
1605
1606 /* Check the cache first */
1609 {
1610 /* We got lucky, return the cached entry */
1611 *LdrEntry = LdrpLoadedDllHandleCache;
1612 return TRUE;
1613 }
1614
1615 /* Time for a lookup */
1616 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1617 Next = ListHead->Flink;
1618 while (Next != ListHead)
1619 {
1620 /* Get the current entry */
1621 Current = CONTAINING_RECORD(Next,
1623 InLoadOrderLinks);
1624
1625 /* Make sure it's not unloading and check for a match */
1626 if ((Current->InMemoryOrderLinks.Flink) && (Base == Current->DllBase))
1627 {
1628 /* Save in cache */
1629 LdrpLoadedDllHandleCache = Current;
1630
1631 /* Return it */
1632 *LdrEntry = Current;
1633 return TRUE;
1634 }
1635
1636 /* Move to the next one */
1637 Next = Next->Flink;
1638 }
1639
1640 /* Nothing found */
1641 return FALSE;
1642}
PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache
Definition: ldrutils.c:19
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2478
STDMETHOD() Next(THIS_ ULONG celt, IAssociationElement *pElement, ULONG *pceltFetched) PURE

Referenced by LdrAddRefDll(), LdrDisableThreadCalloutsForDll(), LdrpGetProcedureAddress(), LdrpSnapThunk(), and LdrUnloadDll().

◆ LdrpClearLoadInProgress()

ULONG NTAPI LdrpClearLoadInProgress ( VOID  )

Definition at line 2649 of file ldrutils.c.

2650{
2651 PLIST_ENTRY ListHead, Entry;
2652 PLDR_DATA_TABLE_ENTRY LdrEntry;
2653 ULONG ModulesCount = 0;
2654
2655 /* Traverse the init list */
2656 ListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
2657 Entry = ListHead->Flink;
2658 while (Entry != ListHead)
2659 {
2660 /* Get the loader entry */
2661 LdrEntry = CONTAINING_RECORD(Entry,
2663 InInitializationOrderLinks);
2664
2665 /* Clear load in progress flag */
2666 LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
2667
2668 /* Check for modules with entry point count but not processed yet */
2669 if ((LdrEntry->EntryPoint) &&
2670 !(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
2671 {
2672 /* Increase counter */
2673 ModulesCount++;
2674 }
2675
2676 /* Advance to the next entry */
2677 Entry = Entry->Flink;
2678 }
2679
2680 /* Return final count */
2681 return ModulesCount;
2682}
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:48
base of all file and directory entries
Definition: entries.h:83
PVOID EntryPoint
Definition: ntddk_ex.h:203
ULONG Flags
Definition: ntddk_ex.h:207

Referenced by LdrAddRefDll(), LdrGetDllHandleEx(), LdrpLoadDll(), and LdrpRunInitializeRoutines().

◆ LdrpCodeAuthzCheckDllAllowed()

NTSTATUS NTAPI LdrpCodeAuthzCheckDllAllowed ( IN PUNICODE_STRING  FullName,
IN HANDLE  DllHandle 
)

Definition at line 509 of file ldrutils.c.

511{
512 /* Not implemented */
513 return STATUS_SUCCESS;
514}

Referenced by LdrpCreateDllSection().

◆ LdrpCreateDllSection()

NTSTATUS NTAPI LdrpCreateDllSection ( IN PUNICODE_STRING  FullName,
IN HANDLE  DllHandle,
IN PULONG DllCharacteristics  OPTIONAL,
OUT PHANDLE  SectionHandle 
)

Definition at line 518 of file ldrutils.c.

522{
527 ULONG_PTR HardErrorParameters[1];
529 SECTION_IMAGE_INFORMATION SectionImageInfo;
530
531 /* Check if we don't already have a handle */
532 if (!DllHandle)
533 {
534 /* Create the object attributes */
536 FullName,
538 NULL,
539 NULL);
540
541 /* Open the DLL */
548
549 /* Check if we failed */
550 if (!NT_SUCCESS(Status))
551 {
552 /* Attempt to open for execute only */
559
560 /* Check if this failed too */
561 if (!NT_SUCCESS(Status))
562 {
563 /* Show debug message */
564 if (ShowSnaps)
565 {
566 DPRINT1("LDR: LdrpCreateDllSection - NtOpenFile failed; status = %x\n",
567 Status);
568 }
569
570 /* Make sure to return an expected status code */
572 {
573 /* Callers expect this instead */
575 }
576
577 /* Return an empty section handle */
578 *SectionHandle = NULL;
579 return Status;
580 }
581 }
582 }
583 else
584 {
585 /* Use the handle we already have */
586 FileHandle = DllHandle;
587 }
588
589 /* Create a section for the DLL */
590 Status = NtCreateSection(SectionHandle,
593 NULL,
594 NULL,
596 SEC_IMAGE,
597 FileHandle);
598
599 /* If mapping failed, raise a hard error */
600 if (!NT_SUCCESS(Status))
601 {
602 /* Forget the handle */
603 *SectionHandle = NULL;
604
605 /* Give the DLL name */
606 HardErrorParameters[0] = (ULONG_PTR)FullName;
607
608 /* Raise the error */
610 1,
611 1,
612 HardErrorParameters,
613 OptionOk,
614 &Response);
615
616 /* Increment the error count */
618
619 goto Exit;
620 }
621
622 /* Check for Safer restrictions */
623 if (!DllCharacteristics ||
624 !(*DllCharacteristics & IMAGE_FILE_SYSTEM))
625 {
626 /* Make sure it's executable */
627 Status = ZwQuerySection(*SectionHandle,
629 &SectionImageInfo,
631 NULL);
632 if (NT_SUCCESS(Status))
633 {
634 /* Bypass the check for .NET images */
635 if (!(SectionImageInfo.LoaderFlags & IMAGE_LOADER_FLAGS_COMPLUS))
636 {
637 /* Check with Safer */
640 {
641 /* Show debug message */
642 if (ShowSnaps)
643 {
644 DPRINT1("LDR: Loading of (%wZ) blocked by Winsafer\n",
645 &FullName);
646 }
647
648 /* Failure case, close section handle */
649 NtClose(*SectionHandle);
650 *SectionHandle = NULL;
651 }
652 }
653 }
654 else
655 {
656 /* Failure case, close section handle */
657 NtClose(*SectionHandle);
658 *SectionHandle = NULL;
659 }
660 }
661
662Exit:
663 /* Close the file handle, we don't need it */
665
666 /* Return status */
667 return Status;
668}
#define ULONG_PTR
Definition: config.h:101
NTSTATUS NTAPI LdrpCodeAuthzCheckDllAllowed(IN PUNICODE_STRING FullName, IN HANDLE DllHandle)
Definition: ldrutils.c:509
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSYSAPI NTSTATUS NTAPI ZwRaiseHardError(_In_ NTSTATUS ErrorStatus, _In_ ULONG NumberOfParameters, _In_ ULONG UnicodeStringParameterMask, _In_ PULONG_PTR Parameters, _In_ ULONG ValidResponseOptions, _Out_ PULONG Response)
@ OptionOk
Definition: extypes.h:187
NTSYSAPI NTSTATUS NTAPI ZwQuerySection(_In_ HANDLE SectionHandle, _In_ SECTION_INFORMATION_CLASS SectionInformationClass, _Out_ PVOID SectionInformation, _In_ SIZE_T Length, _Out_opt_ PSIZE_T ResultLength)
#define SEC_IMAGE
Definition: mmtypes.h:97
@ SectionImageInformation
Definition: mmtypes.h:196
#define FILE_READ_DATA
Definition: nt_native.h:628
#define SECTION_QUERY
Definition: nt_native.h:1287
BOOLEAN LdrpInLdrInit
Definition: ldrinit.c:30
ULONG LdrpFatalHardErrorCount
Definition: ldrinit.c:81
#define IMAGE_LOADER_FLAGS_COMPLUS
Definition: ntdllp.h:20
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define STATUS_DLL_NOT_FOUND
Definition: ntstatus.h:545
#define IMAGE_FILE_SYSTEM
Definition: pedump.c:168
#define STATUS_NOT_FOUND
Definition: shellext.h:72
static void Exit(void)
Definition: sock.c:1330
Definition: ncftp.h:89
_In_ PSTRING FullName
Definition: rtlfuncs.h:1665

Referenced by LdrpMapDll().

◆ LdrpFetchAddressOfEntryPoint()

PVOID NTAPI LdrpFetchAddressOfEntryPoint ( IN PVOID  ImageBase)

Definition at line 767 of file ldrutils.c.

768{
769 PIMAGE_NT_HEADERS NtHeaders;
770 ULONG_PTR EntryPoint = 0;
771
772 /* Get entry point offset from NT headers */
773 NtHeaders = RtlImageNtHeader(ImageBase);
774 if (NtHeaders)
775 {
776 /* Add image base */
777 EntryPoint = NtHeaders->OptionalHeader.AddressOfEntryPoint;
778 if (EntryPoint) EntryPoint += (ULONG_PTR)ImageBase;
779 }
780
781 /* Return calculated pointer (or zero in case of failure) */
782 return (PVOID)EntryPoint;
783}

Referenced by LdrpMapDll().

◆ LdrpFinalizeAndDeallocateDataTableEntry()

VOID NTAPI LdrpFinalizeAndDeallocateDataTableEntry ( IN PLDR_DATA_TABLE_ENTRY  Entry)

Definition at line 1577 of file ldrutils.c.

1578{
1579 /* Sanity check */
1580 ASSERT(Entry != NULL);
1581
1582 /* Release the activation context if it exists and wasn't already released */
1583 if ((Entry->EntryPointActivationContext) &&
1584 (Entry->EntryPointActivationContext != INVALID_HANDLE_VALUE))
1585 {
1586 /* Mark it as invalid */
1587 RtlReleaseActivationContext(Entry->EntryPointActivationContext);
1588 Entry->EntryPointActivationContext = INVALID_HANDLE_VALUE;
1589 }
1590
1591 /* Release the full dll name string */
1592 if (Entry->FullDllName.Buffer) LdrpFreeUnicodeString(&Entry->FullDllName);
1593
1594 /* Finally free the entry's memory */
1596}
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
NTSYSAPI void WINAPI RtlReleaseActivationContext(HANDLE)
Definition: actctx.c:5384
VOID NTAPI LdrpFreeUnicodeString(IN PUNICODE_STRING StringIn)
Definition: ldrutils.c:84

Referenced by LdrUnloadDll().

◆ LdrpFreeUnicodeString()

VOID NTAPI LdrpFreeUnicodeString ( IN PUNICODE_STRING  StringIn)

Definition at line 84 of file ldrutils.c.

85{
86 ASSERT(StringIn != NULL);
87
88 /* If Buffer is not NULL - free it */
89 if (StringIn->Buffer)
90 {
91 RtlFreeHeap(LdrpHeap, 0, StringIn->Buffer);
92 }
93
94 /* Zero it out */
95 RtlInitEmptyUnicodeString(StringIn, NULL, 0);
96}

Referenced by LdrpFinalizeAndDeallocateDataTableEntry(), LdrpMapDll(), LdrpResolveDllName(), and LdrpResolveFullName().

◆ LdrpGetProcedureAddress()

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 at line 2231 of file ldrutils.c.

2237{
2239 UCHAR ImportBuffer[64]; // 128 since NT6.2
2240 PLDR_DATA_TABLE_ENTRY LdrEntry;
2241 IMAGE_THUNK_DATA Thunk;
2242 PVOID ImageBase;
2243 PIMAGE_IMPORT_BY_NAME ImportName = NULL;
2244 PIMAGE_EXPORT_DIRECTORY ExportDir;
2245 ULONG ExportDirSize, Length;
2247
2248 /* Show debug message */
2249 if (ShowSnaps) DPRINT1("LDR: LdrGetProcedureAddress by ");
2250
2251 /* Check if we got a name */
2252 if (Name)
2253 {
2254 /* Show debug message */
2255 if (ShowSnaps) DbgPrint("NAME - %s\n", Name->Buffer);
2256
2257 /* Make sure it's not too long */
2258 Length = Name->Length +
2259 sizeof(CHAR) +
2262 {
2263 /* Won't have enough space to add the hint */
2264 return STATUS_NAME_TOO_LONG;
2265 }
2266
2267 /* Check if our buffer is large enough */
2268 if (Length > sizeof(ImportBuffer))
2269 {
2270 /* Allocate from heap, plus 2 bytes for the Hint */
2271 ImportName = RtlAllocateHeap(RtlGetProcessHeap(),
2272 0,
2273 Length);
2274 if (!ImportName)
2275 {
2276 /* Return STATUS_INSUFFICIENT_RESOURCES since NT6.2 */
2278 }
2279 }
2280 else
2281 {
2282 /* Use our internal buffer */
2283 ImportName = (PIMAGE_IMPORT_BY_NAME)ImportBuffer;
2284 }
2285
2286 /* Clear the hint */
2287 ImportName->Hint = 0;
2288
2289 /* Copy the name and null-terminate it */
2290 RtlCopyMemory(ImportName->Name, Name->Buffer, Name->Length);
2291 ImportName->Name[Name->Length] = ANSI_NULL;
2292
2293 /* Clear the high bit */
2294 ImageBase = ImportName;
2295 Thunk.u1.AddressOfData = 0;
2296 }
2297 else
2298 {
2299 /* Do it by ordinal */
2300 ImageBase = NULL;
2301
2302 /* Show debug message */
2303 if (ShowSnaps) DbgPrint("ORDINAL - %lx\n", Ordinal);
2304
2305 /* Make sure an ordinal was given */
2306 if (!Ordinal)
2307 {
2308 /* No ordinal */
2309 DPRINT1("No ordinal and no name\n");
2311 }
2312
2313 /* Set the original flag in the thunk */
2314 Thunk.u1.Ordinal = Ordinal | IMAGE_ORDINAL_FLAG;
2315 }
2316
2317 /* Acquire lock unless we are initting */
2319
2320 _SEH2_TRY
2321 {
2322 /* Try to find the loaded DLL */
2324 {
2325 /* Invalid base */
2326 DPRINT1("Invalid base address %p\n", BaseAddress);
2328 _SEH2_YIELD(goto Quickie;)
2329 }
2330
2331 /* Get the pointer to the export directory */
2332 ExportDir = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
2333 TRUE,
2335 &ExportDirSize);
2336
2337 if (!ExportDir)
2338 {
2339 DPRINT1("Image %wZ has no exports, but were trying to get procedure %Z. BaseAddress asked 0x%p, got entry BA 0x%p\n",
2340 &LdrEntry->BaseDllName, Name, BaseAddress, LdrEntry->DllBase);
2342 _SEH2_YIELD(goto Quickie;)
2343 }
2344
2345 /* Now get the thunk */
2346 Status = LdrpSnapThunk(LdrEntry->DllBase,
2347 ImageBase,
2348 &Thunk,
2349 &Thunk,
2350 ExportDir,
2351 ExportDirSize,
2352 FALSE,
2353 NULL);
2354
2355 /* Finally, see if we're supposed to run the init routines */
2356 if ((NT_SUCCESS(Status)) && (ExecuteInit))
2357 {
2358 /*
2359 * It's possible a forwarded entry had us load the DLL. In that case,
2360 * then we will call its DllMain. Use the last loaded DLL for this.
2361 */
2362 Entry = NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Blink;
2363 LdrEntry = CONTAINING_RECORD(Entry,
2365 InInitializationOrderLinks);
2366
2367 /* Make sure we didn't process it yet*/
2368 if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
2369 {
2370 /* Call the init routine */
2371 _SEH2_TRY
2372 {
2374 }
2376 {
2377 /* Get the exception code */
2379 }
2380 _SEH2_END;
2381 }
2382 }
2383
2384 /* Make sure we're OK till here */
2385 if (NT_SUCCESS(Status))
2386 {
2387 /* Return the address */
2388 *ProcedureAddress = (PVOID)Thunk.u1.Function;
2389 }
2390 }
2392 {
2393 /* Just ignore exceptions */
2394 }
2395 _SEH2_END;
2396
2397Quickie:
2398 /* Cleanup */
2399 if (ImportName && (ImportName != (PIMAGE_IMPORT_BY_NAME)ImportBuffer))
2400 {
2401 /* We allocated from heap, free it */
2402 RtlFreeHeap(RtlGetProcessHeap(), 0, ImportName);
2403 }
2404
2405 /* Release the CS if we entered it */
2407
2408 /* We're done */
2409 return Status;
2410}
#define CHAR(Char)
LPWSTR Name
Definition: desk.c:124
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
#define DbgPrint
Definition: hal.h:12
BOOLEAN NTAPI LdrpCheckForLoadedDllHandle(IN PVOID Base, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
Definition: ldrutils.c:1600
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define ANSI_NULL
NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
Definition: ldrinit.c:648
RTL_CRITICAL_SECTION LdrpLoaderLock
Definition: ldrinit.c:68
NTSTATUS NTAPI LdrpSnapThunk(IN PVOID ExportBase, IN PVOID ImportBase, IN PIMAGE_THUNK_DATA OriginalThunk, IN OUT PIMAGE_THUNK_DATA Thunk, IN PIMAGE_EXPORT_DIRECTORY ExportEntry, IN ULONG ExportSize, IN BOOLEAN Static, IN LPSTR DllName)
Definition: ldrpe.c:937
#define STATUS_PROCEDURE_NOT_FOUND
Definition: ntstatus.h:358
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
#define IMAGE_ORDINAL_FLAG
Definition: pedump.c:336
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
union _IMAGE_THUNK_DATA32::@2218 u1
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by AvrfpResolveThunks(), LdrGetProcedureAddress(), LdrpGetShimEngineFunction(), and LdrpSnapThunk().

◆ LdrpGetShimEngineFunction()

PVOID LdrpGetShimEngineFunction ( PCSZ  FunctionName)

Definition at line 2684 of file ldrutils.c.

2685{
2688 PVOID Address;
2690 /* Skip Dll init */
2692 return NT_SUCCESS(Status) ? Address : NULL;
2693}
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char * FunctionName
Definition: acpixf.h:1279
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
PVOID g_pShimEngineModule
Definition: ldrutils.c:22
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
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
static WCHAR Address[46]
Definition: ping.c:68

Referenced by LdrpGetShimEngineInterface().

◆ LdrpGetShimEngineInterface()

VOID NTAPI LdrpGetShimEngineInterface ( )

Definition at line 2697 of file ldrutils.c.

2698{
2701 PVOID SE_InstallBeforeInit = LdrpGetShimEngineFunction("SE_InstallBeforeInit");
2702 PVOID SE_InstallAfterInit = LdrpGetShimEngineFunction("SE_InstallAfterInit");
2703 PVOID SE_ProcessDying = LdrpGetShimEngineFunction("SE_ProcessDying");
2704
2706 {
2713 }
2714 else
2715 {
2717 }
2718}
VOID NTAPI LdrpUnloadShimEngine()
Definition: ldrutils.c:2782
PVOID g_pfnSE_InstallBeforeInit
Definition: ldrutils.c:25
PVOID g_pfnSE_InstallAfterInit
Definition: ldrutils.c:26
PVOID g_pfnSE_ProcessDying
Definition: ldrutils.c:27
BOOLEAN g_ShimsEnabled
Definition: ldrutils.c:21
PVOID LdrpGetShimEngineFunction(PCSZ FunctionName)
Definition: ldrutils.c:2684
PVOID g_pfnSE_DllUnloaded
Definition: ldrutils.c:24
PVOID g_pfnSE_DllLoaded
Definition: ldrutils.c:23
PVOID NTAPI RtlEncodeSystemPointer(IN PVOID Pointer)
Definition: process.c:429
VOID NTAPI SE_InstallAfterInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1436
VOID NTAPI SE_InstallBeforeInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1417
VOID NTAPI SE_ProcessDying(VOID)
Definition: shimeng.c:1441
VOID WINAPI SE_DllLoaded(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:1447
VOID WINAPI SE_DllUnloaded(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:1465

Referenced by LdrInitShimEngineDynamic(), and LdrpLoadShimEngine().

◆ LdrpInsertMemoryTableEntry()

VOID NTAPI LdrpInsertMemoryTableEntry ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 1561 of file ldrutils.c.

1562{
1563 PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr;
1564 ULONG i;
1565
1566 /* Insert into hash table */
1567 i = LDR_GET_HASH_ENTRY(LdrEntry->BaseDllName.Buffer[0]);
1568 InsertTailList(&LdrpHashTable[i], &LdrEntry->HashLinks);
1569
1570 /* Insert into other lists */
1571 InsertTailList(&PebData->InLoadOrderModuleList, &LdrEntry->InLoadOrderLinks);
1572 InsertTailList(&PebData->InMemoryOrderModuleList, &LdrEntry->InMemoryOrderLinks);
1573}
#define InsertTailList(ListHead, Entry)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LIST_ENTRY InMemoryOrderModuleList
Definition: btrfs_drv.h:1895
LIST_ENTRY InLoadOrderModuleList
Definition: ldrtypes.h:124

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

◆ LdrpLoadDll()

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 at line 2414 of file ldrutils.c.

2420{
2421 PPEB Peb = NtCurrentPeb();
2423 const WCHAR *p;
2424 BOOLEAN GotExtension;
2425 WCHAR c;
2426 WCHAR NameBuffer[MAX_PATH + 6];
2427 UNICODE_STRING RawDllName;
2428 PLDR_DATA_TABLE_ENTRY LdrEntry;
2429 BOOLEAN InInit = LdrpInLdrInit;
2430
2431 /* Save the Raw DLL Name */
2432 if (DllName->Length >= sizeof(NameBuffer)) return STATUS_NAME_TOO_LONG;
2433 RtlInitEmptyUnicodeString(&RawDllName, NameBuffer, sizeof(NameBuffer));
2434 RtlCopyUnicodeString(&RawDllName, DllName);
2435
2436 /* Find the extension, if present */
2437 /* NOTE: Access violation is expected here in some cases (Buffer[-1]) */
2438 p = DllName->Buffer + DllName->Length / sizeof(WCHAR) - 1;
2439 GotExtension = FALSE;
2440 while (p >= DllName->Buffer)
2441 {
2442 c = *p--;
2443 if (c == L'.')
2444 {
2445 GotExtension = TRUE;
2446 break;
2447 }
2448 else if (c == L'\\')
2449 {
2450 break;
2451 }
2452 }
2453
2454 /* If no extension was found, add the default extension */
2455 if (!GotExtension)
2456 {
2457 /* Check that we have space to add one */
2458 if ((DllName->Length + LdrApiDefaultExtension.Length + sizeof(UNICODE_NULL)) >=
2459 sizeof(NameBuffer))
2460 {
2461 /* No space to add the extension */
2464 "LDR: %s - Dll name missing extension; with extension "
2465 "added the name is too long\n"
2466 " DllName: (@ %p) \"%wZ\"\n"
2467 " DllName->Length: %u\n",
2469 DllName,
2470 DllName,
2471 DllName->Length);
2472 return STATUS_NAME_TOO_LONG;
2473 }
2474
2475 /* Add it. Needs to be null terminated, thus the length check above */
2478 }
2479
2480 /* Check for init flag and acquire lock */
2482
2483 _SEH2_TRY
2484 {
2485 /* Show debug message */
2486 if (ShowSnaps)
2487 {
2488 DPRINT1("LDR: LdrLoadDll, loading %wZ from %ws\n",
2489 &RawDllName,
2490 DllPath ? DllPath : L"");
2491 }
2492
2493 /* Check if the DLL is already loaded */
2495 &RawDllName,
2496 FALSE,
2497 Redirected,
2498 &LdrEntry))
2499 {
2500 /* Map it */
2502 DllPath,
2503 NameBuffer,
2504 DllCharacteristics,
2505 FALSE,
2506 Redirected,
2507 &LdrEntry);
2508 if (!NT_SUCCESS(Status))
2510
2511 /* FIXME: Need to mark the DLL range for the stack DB */
2512 //RtlpStkMarkDllRange(LdrEntry);
2513
2514 /* Check if IMAGE_FILE_EXECUTABLE_IMAGE was provided */
2515 if ((DllCharacteristics) &&
2516 (*DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
2517 {
2518 /* This is not a DLL, so remove such data */
2519 LdrEntry->EntryPoint = NULL;
2520 LdrEntry->Flags &= ~LDRP_IMAGE_DLL;
2521 }
2522
2523 /* Make sure it's a DLL */
2524 if (LdrEntry->Flags & LDRP_IMAGE_DLL)
2525 {
2526 /* Check if this is a .NET Image */
2527 if (!(LdrEntry->Flags & LDRP_COR_IMAGE))
2528 {
2529 /* Walk the Import Descriptor */
2531 }
2532
2533 /* Update load count, unless it's locked */
2534 if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
2536
2537 /* Check if we failed */
2538 if (!NT_SUCCESS(Status))
2539 {
2540 /* Clear entrypoint, and insert into list */
2541 LdrEntry->EntryPoint = NULL;
2543 &LdrEntry->InInitializationOrderLinks);
2544
2545 /* Cancel the load */
2547
2548 /* Unload the DLL */
2549 if (ShowSnaps)
2550 {
2551 DbgPrint("LDR: Unloading %wZ due to error %x walking "
2552 "import descriptors\n",
2553 DllName,
2554 Status);
2555 }
2556 LdrUnloadDll(LdrEntry->DllBase);
2557
2558 /* Return the error */
2560 }
2561 }
2562 else if (LdrEntry->LoadCount != 0xFFFF)
2563 {
2564 /* Increase load count */
2565 LdrEntry->LoadCount++;
2566 }
2567
2568 /* Insert it into the list */
2570 &LdrEntry->InInitializationOrderLinks);
2571
2572 /* If we have to run the entrypoint, make sure the DB is ready */
2573 if (CallInit && LdrpLdrDatabaseIsSetup)
2574 {
2575 /* Notify Shim Engine */
2576 if (g_ShimsEnabled)
2577 {
2579 SE_DllLoaded(LdrEntry);
2580 }
2581
2582 /* Run the init routine */
2584 if (!NT_SUCCESS(Status))
2585 {
2586 /* Failed, unload the DLL */
2587 if (ShowSnaps)
2588 {
2589 DbgPrint("LDR: Unloading %wZ because either its init "
2590 "routine or one of its static imports failed; "
2591 "status = 0x%08lx\n",
2592 DllName,
2593 Status);
2594 }
2595 LdrUnloadDll(LdrEntry->DllBase);
2596 }
2597 }
2598 else
2599 {
2600 /* The DB isn't ready, which means we were loaded because of a forwarder */
2602 }
2603 }
2604 else
2605 {
2606 /* We were already loaded. Are we a DLL? */
2607 if ((LdrEntry->Flags & LDRP_IMAGE_DLL) && (LdrEntry->LoadCount != 0xFFFF))
2608 {
2609 /* Increase load count */
2610 LdrEntry->LoadCount++;
2612
2613 /* Clear the load in progress */
2615 }
2616 else
2617 {
2618 /* Not a DLL, just increase the load count */
2619 if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
2620 }
2621 }
2622
2623 }
2625 {
2626 /* Release the lock */
2628 }
2629 _SEH2_END;
2630
2631 /* Check for success */
2632 if (NT_SUCCESS(Status))
2633 {
2634 /* Return the base address */
2635 *BaseAddress = LdrEntry->DllBase;
2636 }
2637 else
2638 {
2639 /* Nothing found */
2640 *BaseAddress = NULL;
2641 }
2642
2643 /* Return status */
2644 return Status;
2645}
#define VOID
Definition: acefi.h:82
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
struct _LDR_DATA_TABLE_ENTRY * PLDR_DATA_TABLE_ENTRY
#define MAX_PATH
Definition: compat.h:34
PPEB Peb
Definition: dllmain.c:27
@ DPFLTR_LDR_ID
Definition: dpfilter.h:113
#define __FUNCTION__
Definition: types.h:116
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
#define DbgPrintEx(cmpid, lvl, fmt,...)
Definition: kdinit.c:24
#define c
Definition: ke_i.h:80
NTSTATUS NTAPI LdrUnloadDll(_In_ PVOID BaseAddress)
Definition: ldrapi.c:1291
#define LDRP_COR_IMAGE
Definition: ldrtypes.h:56
#define LDRP_IMAGE_DLL
Definition: ldrtypes.h:39
NTSTATUS NTAPI LdrpMapDll(IN PWSTR SearchPath OPTIONAL, IN PWSTR DllPath2, IN PWSTR DllName OPTIONAL, IN PULONG DllCharacteristics, IN BOOLEAN Static, IN BOOLEAN Redirect, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
Definition: ldrutils.c:997
VOID NTAPI LdrpUpdateLoadCount2(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Flags)
Definition: ldrutils.c:434
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
ULONG NTAPI LdrpClearLoadInProgress(VOID)
Definition: ldrutils.c:2649
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSTATUS NTAPI LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrpe.c:670
UNICODE_STRING LdrApiDefaultExtension
Definition: ldrapi.c:22
BOOLEAN LdrpLdrDatabaseIsSetup
Definition: ldrinit.c:33
#define LDRP_UPDATE_REFCOUNT
Definition: ntdllp.h:15
#define IMAGE_FILE_EXECUTABLE_IMAGE
Definition: pedump.c:160
#define _SEH2_FINALLY
Definition: pseh2_64.h:130
#define _SEH2_LEAVE
Definition: pseh2_64.h:183
PVOID NTAPI RtlDecodeSystemPointer(IN PVOID Pointer)
Definition: process.c:439
USHORT LoadCount
Definition: ntddk_ex.h:208
LIST_ENTRY InInitializationOrderLinks
Definition: ldrtypes.h:144
LIST_ENTRY InInitializationOrderModuleList
Definition: ldrtypes.h:126
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1912
#define NTAPI
Definition: typedefs.h:36

Referenced by LdrLoadDll(), LdrpLoadShimEngine(), and LdrpSnapThunk().

◆ LdrpLoadShimEngine()

VOID NTAPI LdrpLoadShimEngine ( IN PWSTR  ImageName,
IN PUNICODE_STRING  ProcessImage,
IN PVOID  pShimData 
)

Definition at line 2757 of file ldrutils.c.

2758{
2759 UNICODE_STRING ShimLibraryName;
2760 PVOID ShimLibrary;
2762 RtlInitUnicodeString(&ShimLibraryName, ImageName);
2763 /* We should NOT pass CallInit = TRUE!
2764 If we do this, other init routines will be called before we get a chance to shim stuff.. */
2765 Status = LdrpLoadDll(FALSE, NULL, NULL, &ShimLibraryName, &ShimLibrary, FALSE);
2766 if (NT_SUCCESS(Status))
2767 {
2768 g_pShimEngineModule = ShimLibrary;
2771 if (g_ShimsEnabled)
2772 {
2775 SE_InstallBeforeInit(ProcessImage, pShimData);
2776 }
2777 }
2778}
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
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:2414
VOID NTAPI LdrpRunShimEngineInitRoutine(IN ULONG Reason)
Definition: ldrutils.c:2722
VOID NTAPI LdrpGetShimEngineInterface()
Definition: ldrutils.c:2697
static const char * ImageName
Definition: image.c:34

Referenced by LdrpInitializeProcess().

◆ LdrpMapDll()

NTSTATUS NTAPI LdrpMapDll ( IN PWSTR SearchPath  OPTIONAL,
IN PWSTR  DllPath2,
IN PWSTR DllName  OPTIONAL,
IN PULONG  DllCharacteristics,
IN BOOLEAN  Static,
IN BOOLEAN  Redirect,
OUT PLDR_DATA_TABLE_ENTRY DataTableEntry 
)

Definition at line 997 of file ldrutils.c.

1004{
1005 PTEB Teb = NtCurrentTeb();
1006 PPEB Peb = NtCurrentPeb();
1007 PWCHAR p1 = DllName;
1008 WCHAR TempChar;
1009 BOOLEAN KnownDll = FALSE;
1010 UNICODE_STRING FullDllName, BaseDllName;
1011 HANDLE SectionHandle = NULL, DllHandle = 0;
1012 UNICODE_STRING NtPathDllName;
1013 ULONG_PTR HardErrorParameters[2];
1014 UNICODE_STRING HardErrorDllName, HardErrorDllPath;
1016 SIZE_T ViewSize = 0;
1017 PVOID ViewBase = NULL;
1018 PVOID ArbitraryUserPointer;
1019 PIMAGE_NT_HEADERS NtHeaders;
1020 NTSTATUS HardErrorStatus, Status;
1021 BOOLEAN OverlapDllFound = FALSE;
1022 ULONG_PTR ImageBase, ImageEnd;
1023 PLIST_ENTRY ListHead, NextEntry;
1024 PLDR_DATA_TABLE_ENTRY CandidateEntry, LdrEntry;
1025 ULONG_PTR CandidateBase, CandidateEnd;
1026 UNICODE_STRING OverlapDll;
1027 BOOLEAN RelocatableDll = TRUE;
1028 UNICODE_STRING IllegalDll;
1029 PVOID RelocData;
1030 ULONG RelocDataSize = 0;
1031
1032 // FIXME: AppCompat stuff is missing
1033
1034 if (ShowSnaps)
1035 {
1036 DPRINT1("LDR: LdrpMapDll: Image Name %ws, Search Path %ws\n",
1037 DllName,
1038 SearchPath ? SearchPath : L"");
1039 }
1040
1041 /* Check if we have a known dll directory */
1042 if (LdrpKnownDllObjectDirectory && Redirect == FALSE)
1043 {
1044 /* Check if the path is full */
1045 while (*p1)
1046 {
1047 TempChar = *p1++;
1048 if (TempChar == '\\' || TempChar == '/' )
1049 {
1050 /* Complete path, don't do Known Dll lookup */
1051 goto SkipCheck;
1052 }
1053 }
1054
1055 /* Try to find a Known DLL */
1056 Status = LdrpCheckForKnownDll(DllName,
1057 &FullDllName,
1058 &BaseDllName,
1059 &SectionHandle);
1060
1062 {
1063 /* Failure */
1066 "LDR: %s - call to LdrpCheckForKnownDll(\"%ws\", ...) failed with status %x\n",
1068 DllName,
1069 Status);
1070
1071 return Status;
1072 }
1073 }
1074
1075SkipCheck:
1076
1077 /* Check if the Known DLL Check returned something */
1078 if (!SectionHandle)
1079 {
1080 /* It didn't, so try to resolve the name now */
1082 DllName,
1083 &FullDllName,
1084 &BaseDllName))
1085 {
1086 /* Got a name, display a message */
1087 if (ShowSnaps)
1088 {
1089 DPRINT1("LDR: Loading (%s) %wZ\n",
1090 Static ? "STATIC" : "DYNAMIC",
1091 &FullDllName);
1092 }
1093
1094 /* Convert to NT Name */
1096 &NtPathDllName,
1097 NULL,
1098 NULL))
1099 {
1100 /* Path was invalid */
1102 }
1103
1104 /* Create a section for this dLL */
1105 Status = LdrpCreateDllSection(&NtPathDllName,
1106 DllHandle,
1107 DllCharacteristics,
1108 &SectionHandle);
1109
1110 /* Free the NT Name */
1111 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathDllName.Buffer);
1112
1113 /* If we failed */
1114 if (!NT_SUCCESS(Status))
1115 {
1116 /* Free the name strings and return */
1118 LdrpFreeUnicodeString(&BaseDllName);
1119 return Status;
1120 }
1121 }
1122 else
1123 {
1124 /* We couldn't resolve the name, is this a static load? */
1125 if (Static)
1126 {
1127 /*
1128 * This is BAD! Static loads are CRITICAL. Bugcheck!
1129 * Initialize the strings for the error
1130 */
1131 RtlInitUnicodeString(&HardErrorDllName, DllName);
1132 RtlInitUnicodeString(&HardErrorDllPath,
1133 DllPath2 ? DllPath2 : LdrpDefaultPath.Buffer);
1134
1135 /* Set them as error parameters */
1136 HardErrorParameters[0] = (ULONG_PTR)&HardErrorDllName;
1137 HardErrorParameters[1] = (ULONG_PTR)&HardErrorDllPath;
1138
1139 /* Raise the hard error */
1141 2,
1142 0x00000003,
1143 HardErrorParameters,
1144 OptionOk,
1145 &Response);
1146
1147 /* We're back, where we initializing? */
1149 }
1150
1151 /* Return failure */
1152 return STATUS_DLL_NOT_FOUND;
1153 }
1154 }
1155 else
1156 {
1157 /* We have a section handle, so this is a known dll */
1158 KnownDll = TRUE;
1159 }
1160
1161 /* Stuff the image name in the TIB, for the debugger */
1162 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
1164
1165 /* Map the DLL */
1166 ViewBase = NULL;
1167 ViewSize = 0;
1168 Status = NtMapViewOfSection(SectionHandle,
1170 &ViewBase,
1171 0,
1172 0,
1173 NULL,
1174 &ViewSize,
1175 ViewShare,
1176 0,
1178
1179 /* Restore */
1180 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
1181
1182 /* Fail if we couldn't map it */
1183 if (!NT_SUCCESS(Status))
1184 {
1185 /* Close and return */
1186 NtClose(SectionHandle);
1187 return Status;
1188 }
1189
1190 /* Get the NT Header */
1191 if (!(NtHeaders = RtlImageNtHeader(ViewBase)))
1192 {
1193 /* Invalid image, unmap, close handle and fail */
1195 NtClose(SectionHandle);
1197 }
1198
1199 // FIXME: .NET support is missing
1200
1201 /* Allocate an entry */
1202 if (!(LdrEntry = LdrpAllocateDataTableEntry(ViewBase)))
1203 {
1204 /* Invalid image, unmap, close handle and fail */
1206 NtClose(SectionHandle);
1207 return STATUS_NO_MEMORY;
1208 }
1209
1210 /* Setup the entry */
1211 LdrEntry->Flags = Static ? LDRP_STATIC_LINK : 0;
1212 if (Redirect) LdrEntry->Flags |= LDRP_REDIRECTED;
1213 LdrEntry->LoadCount = 0;
1214 LdrEntry->FullDllName = FullDllName;
1215 LdrEntry->BaseDllName = BaseDllName;
1216 LdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(LdrEntry->DllBase);
1217
1218 /* Show debug message */
1219 if (ShowSnaps)
1220 {
1221 DPRINT1("LDR: LdrpMapDll: Full Name %wZ, Base Name %wZ\n",
1222 &FullDllName,
1223 &BaseDllName);
1224 }
1225
1226 /* Insert this entry */
1228
1229#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
1231#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
1232 LdrEntry->Flags |= LDRP_LOAD_NOTIFICATIONS_SENT; /* LdrEntry->LoadNotificationsSent = TRUE; */
1233#endif
1234#endif
1235
1236 /* Check for invalid CPU Image */
1238 {
1239 /* Load our header */
1241
1242 /* Assume defaults if we don't have to run the Hard Error path */
1243 HardErrorStatus = STATUS_SUCCESS;
1245
1246 /* Are we an NT 3.0 image? [Do these still exist? LOL -- IAI] */
1248 {
1249 /* Reset the entrypoint, save our Dll Name */
1250 LdrEntry->EntryPoint = 0;
1251 HardErrorParameters[0] = (ULONG_PTR)&FullDllName;
1252
1253 /* Raise the error */
1255 1,
1256 1,
1257 HardErrorParameters,
1259 &Response);
1260 }
1261
1262 /* Check if the user pressed cancel */
1263 if (NT_SUCCESS(HardErrorStatus) && Response == ResponseCancel)
1264 {
1265 /* Remove the DLL from the lists */
1268 RemoveEntryList(&LdrEntry->HashLinks);
1269
1270 /* Remove the LDR Entry */
1271 RtlFreeHeap(LdrpHeap, 0, LdrEntry );
1272
1273 /* Unmap and close section */
1275 NtClose(SectionHandle);
1276
1277 /* Did we do a hard error? */
1279 {
1280 /* Yup, so increase fatal error count if we are initializing */
1282 }
1283
1284 /* Return failure */
1286 }
1287 }
1288 else
1289 {
1290 /* The image was valid. Is it a DLL? */
1291 if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
1292 {
1293 /* Set the DLL Flag */
1294 LdrEntry->Flags |= LDRP_IMAGE_DLL;
1295 }
1296
1297 /* If we're not a DLL, clear the entrypoint */
1298 if (!(LdrEntry->Flags & LDRP_IMAGE_DLL))
1299 {
1300 LdrEntry->EntryPoint = 0;
1301 }
1302 }
1303
1304 /* Return it for the caller */
1305 *DataTableEntry = LdrEntry;
1306
1307 /* Check if we loaded somewhere else */
1309 {
1310 /* Write the flag */
1311 LdrEntry->Flags |= LDRP_IMAGE_NOT_AT_BASE;
1312
1313 /* Find our region */
1314 ImageBase = (ULONG_PTR)NtHeaders->OptionalHeader.ImageBase;
1315 ImageEnd = ImageBase + ViewSize;
1316
1317 DPRINT("LDR: LdrpMapDll Relocating Image Name %ws (%p-%p -> %p)\n", DllName, (PVOID)ImageBase, (PVOID)ImageEnd, ViewBase);
1318
1319 /* Scan all the modules */
1320 ListHead = &Peb->Ldr->InLoadOrderModuleList;
1321 NextEntry = ListHead->Flink;
1322 while (NextEntry != ListHead)
1323 {
1324 /* Get the entry */
1325 CandidateEntry = CONTAINING_RECORD(NextEntry,
1327 InLoadOrderLinks);
1328 NextEntry = NextEntry->Flink;
1329
1330 /* Get the entry's bounds */
1331 CandidateBase = (ULONG_PTR)CandidateEntry->DllBase;
1332 CandidateEnd = CandidateBase + CandidateEntry->SizeOfImage;
1333
1334 /* Make sure this entry isn't unloading */
1335 if (!CandidateEntry->InMemoryOrderLinks.Flink) continue;
1336
1337 /* Check if our regions are colliding */
1338 if ((ImageBase >= CandidateBase && ImageBase <= CandidateEnd) ||
1339 (ImageEnd >= CandidateBase && ImageEnd <= CandidateEnd) ||
1340 (CandidateBase >= ImageBase && CandidateBase <= ImageEnd))
1341 {
1342 /* Found who is overlapping */
1343 OverlapDllFound = TRUE;
1344 OverlapDll = CandidateEntry->FullDllName;
1345 break;
1346 }
1347 }
1348
1349 /* Check if we found the DLL overlapping with us */
1350 if (!OverlapDllFound)
1351 {
1352 /* It's not another DLL, it's memory already here */
1353 RtlInitUnicodeString(&OverlapDll, L"Dynamically Allocated Memory");
1354 }
1355
1356 DPRINT("Overlapping DLL: %wZ\n", &OverlapDll);
1357
1358 /* Are we dealing with a DLL? */
1359 if (LdrEntry->Flags & LDRP_IMAGE_DLL)
1360 {
1361 /* Check if relocs were stripped */
1363 {
1364 /* Get the relocation data */
1365 RelocData = RtlImageDirectoryEntryToData(ViewBase,
1366 TRUE,
1368 &RelocDataSize);
1369
1370 /* Does the DLL not have any? */
1371 if (!RelocData && !RelocDataSize)
1372 {
1373 /* We'll allow this and simply continue */
1374 goto NoRelocNeeded;
1375 }
1376 }
1377
1378 /* See if this is an Illegal DLL - IE: user32 and kernel32 */
1379 RtlInitUnicodeString(&IllegalDll,L"user32.dll");
1380 if (RtlEqualUnicodeString(&BaseDllName, &IllegalDll, TRUE))
1381 {
1382 /* Can't relocate user32 */
1383 RelocatableDll = FALSE;
1384 }
1385 else
1386 {
1387 RtlInitUnicodeString(&IllegalDll, L"kernel32.dll");
1388 if (RtlEqualUnicodeString(&BaseDllName, &IllegalDll, TRUE))
1389 {
1390 /* Can't relocate kernel32 */
1391 RelocatableDll = FALSE;
1392 }
1393 }
1394
1395 /* Known DLLs are not allowed to be relocated */
1396 if (KnownDll && !RelocatableDll)
1397 {
1398 /* Setup for hard error */
1399 HardErrorParameters[0] = (ULONG_PTR)&IllegalDll;
1400 HardErrorParameters[1] = (ULONG_PTR)&OverlapDll;
1401
1402 DPRINT1("Illegal DLL relocation! %wZ overlaps %wZ\n", &OverlapDll, &IllegalDll);
1403
1404 /* Raise the error */
1406 2,
1407 3,
1408 HardErrorParameters,
1409 OptionOk,
1410 &Response);
1411
1412 /* If initializing, increase the error count */
1414
1415 /* Don't do relocation */
1417 goto FailRelocate;
1418 }
1419
1420 /* Change the protection to prepare for relocation */
1421 Status = LdrpSetProtection(ViewBase, FALSE);
1422
1423 /* Make sure we changed the protection */
1424 if (NT_SUCCESS(Status))
1425 {
1426 /* Do the relocation */
1429
1430 if (NT_SUCCESS(Status))
1431 {
1432 /* Stuff the image name in the TIB, for the debugger */
1433 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
1435#if 0
1436 /* Map the DLL */
1437 Status = NtMapViewOfSection(SectionHandle,
1439 &ViewBase,
1440 0,
1441 0,
1442 NULL,
1443 &ViewSize,
1444 ViewShare,
1445 0,
1447#endif
1448 /* Restore */
1449 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
1450
1451 /* Return the protection */
1452 Status = LdrpSetProtection(ViewBase, TRUE);
1453 }
1454 }
1455FailRelocate:
1456 /* Handle any kind of failure */
1457 if (!NT_SUCCESS(Status))
1458 {
1459 /* Remove it from the lists */
1462 RemoveEntryList(&LdrEntry->HashLinks);
1463
1464 /* Unmap it, clear the entry */
1466 LdrEntry = NULL;
1467 }
1468
1469 /* Show debug message */
1470 if (ShowSnaps)
1471 {
1472 DPRINT1("LDR: Fixups %successfully re-applied @ %p\n",
1473 NT_SUCCESS(Status) ? "s" : "uns", ViewBase);
1474 }
1475 }
1476 else
1477 {
1478NoRelocNeeded:
1479 /* Not a DLL, or no relocation needed */
1481
1482 /* Stuff the image name in the TIB, for the debugger */
1483 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
1485#if 0
1486 /* Map the DLL */
1487 Status = NtMapViewOfSection(SectionHandle,
1489 &ViewBase,
1490 0,
1491 0,
1492 NULL,
1493 &ViewSize,
1494 ViewShare,
1495 0,
1497#endif
1498 /* Restore */
1499 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
1500
1501 /* Show debug message */
1502 if (ShowSnaps)
1503 {
1504 DPRINT1("LDR: Fixups won't be re-applied to non-Dll @ %p\n", ViewBase);
1505 }
1506 }
1507 }
1508
1509 // FIXME: LdrpCheckCorImage() is missing
1510
1511 /* Check if this is an SMP Machine and a DLL */
1512 if ((LdrpNumberOfProcessors > 1) &&
1513 (LdrEntry && (LdrEntry->Flags & LDRP_IMAGE_DLL)))
1514 {
1515 /* Validate the image for MP */
1516 LdrpValidateImageForMp(LdrEntry);
1517 }
1518
1519 // FIXME: LdrpCorUnloadImage() is missing
1520
1521 /* Close section and return status */
1522 NtClose(SectionHandle);
1523 return Status;
1524}
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:3255
PIMAGE_NT_HEADERS WINAPI ImageNtHeader(_In_ PVOID)
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
NTSTATUS NTAPI NtRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN ULONG ValidResponseOptions, OUT PULONG Response)
Definition: harderr.c:551
#define NtCurrentTeb
#define LDRP_REDIRECTED
Definition: ldrtypes.h:62
#define LDR_DLL_NOTIFICATION_REASON_LOADED
Definition: ldrtypes.h:203
#define LDRP_LOAD_NOTIFICATIONS_SENT
Definition: ldrtypes.h:43
#define LDRP_IMAGE_NOT_AT_BASE
Definition: ldrtypes.h:55
#define LDRP_STATIC_LINK
Definition: ldrtypes.h:38
BOOLEAN NTAPI LdrpResolveDllName(PWSTR DllPath, PWSTR DllName, PUNICODE_STRING FullDllName, PUNICODE_STRING BaseDllName)
Definition: ldrutils.c:673
PVOID NTAPI LdrpFetchAddressOfEntryPoint(IN PVOID ImageBase)
Definition: ldrutils.c:767
NTSTATUS NTAPI LdrpCheckForKnownDll(PWSTR DllName, PUNICODE_STRING FullDllName, PUNICODE_STRING BaseDllName, HANDLE *SectionHandle)
Definition: ldrutils.c:788
VOID NTAPI LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrutils.c:1561
NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase, BOOLEAN Restore)
Definition: ldrutils.c:921
PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
Definition: ldrutils.c:1528
NTSTATUS NTAPI LdrpCreateDllSection(IN PUNICODE_STRING FullName, IN HANDLE DllHandle, IN PULONG DllCharacteristics OPTIONAL, OUT PHANDLE SectionHandle)
Definition: ldrutils.c:518
@ OptionOkCancel
Definition: extypes.h:188
@ ResponseCancel
Definition: extypes.h:202
ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID BaseAddress, _In_ LONGLONG AdditionalBias, _In_opt_ PCSTR LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
Definition: image.c:474
#define PAGE_READWRITE
Definition: nt_native.h:1304
ULONG LdrpNumberOfProcessors
Definition: ldrinit.c:55
VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
Definition: ldrinit.c:1546
VOID NTAPI LdrpSendDllNotifications(_In_ PLDR_DATA_TABLE_ENTRY DllEntry, _In_ ULONG NotificationReason)
Definition: ldrnotify.c:104
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH
Definition: ntstatus.h:128
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:295
#define STATUS_ILLEGAL_DLL_RELOCATION
Definition: ntstatus.h:742
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#define STATUS_IMAGE_NOT_AT_BASE
Definition: ntstatus.h:117
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define IMAGE_FILE_DLL
Definition: pedump.c:169
#define IMAGE_FILE_RELOCS_STRIPPED
Definition: pedump.c:159
Definition: window.h:585
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:142
LIST_ENTRY HashLinks
Definition: ldrtypes.h:155
PVOID ArbitraryUserPointer
Definition: compat.h:719
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
Definition: compat.h:836
NT_TIB NtTib
Definition: ntddk_ex.h:332
#define LL
Definition: tui.h:166
#define SearchPath
Definition: winbase.h:3931

Referenced by LdrpLoadDll(), and LdrpLoadImportModule().

◆ LdrpResolveDllName()

BOOLEAN NTAPI LdrpResolveDllName ( PWSTR  DllPath,
PWSTR  DllName,
PUNICODE_STRING  FullDllName,
PUNICODE_STRING  BaseDllName 
)

Definition at line 673 of file ldrutils.c.

677{
678 PWCHAR NameBuffer, p1, p2 = 0;
680 ULONG BufSize = 500;
681
682 /* Allocate space for full DLL name */
684 if (!FullDllName->Buffer) return FALSE;
685
687 DllName,
688 NULL,
689 BufSize,
690 FullDllName->Buffer,
691 &BaseDllName->Buffer);
692
693 if (!Length || Length > BufSize)
694 {
695 if (ShowSnaps)
696 {
697 DPRINT1("LDR: LdrResolveDllName - Unable to find ");
698 DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer);
699 }
700
702 return FALSE;
703 }
704
705 /* Construct full DLL name */
706 FullDllName->Length = Length;
707 FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
708
709 /* Allocate a new buffer */
710 NameBuffer = RtlAllocateHeap(LdrpHeap, 0, FullDllName->MaximumLength);
711 if (!NameBuffer)
712 {
713 RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
714 return FALSE;
715 }
716
717 /* Copy over the contents from the previous one and free it */
718 RtlCopyMemory(NameBuffer, FullDllName->Buffer, FullDllName->MaximumLength);
719 RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
720 FullDllName->Buffer = NameBuffer;
721
722 /* Find last backslash */
723 p1 = FullDllName->Buffer;
724 while (*p1)
725 {
726 if (*p1++ == L'\\')
727 {
728 p2 = p1;
729 }
730 }
731
732 /* If found, set p1 to it, otherwise p1 points to the beginning of DllName */
733 if (p2)
734 p1 = p2;
735 else
736 p1 = DllName;
737
738 p2 = p1;
739
740 /* Calculate remaining length */
741 while (*p1) ++p1;
742
743 /* Construct base DLL name */
744 BaseDllName->Length = (ULONG_PTR)p1 - (ULONG_PTR)p2;
745 BaseDllName->MaximumLength = BaseDllName->Length + sizeof(UNICODE_NULL);
746 BaseDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, BaseDllName->MaximumLength);
747
748 if (!BaseDllName->Buffer)
749 {
750 RtlFreeHeap(LdrpHeap, 0, NameBuffer);
751 return FALSE;
752 }
753
754 /* Copy base dll name to the new buffer */
755 RtlMoveMemory(BaseDllName->Buffer,
756 p2,
757 BaseDllName->Length);
758
759 /* Null-terminate the string */
760 BaseDllName->Buffer[BaseDllName->Length / sizeof(WCHAR)] = 0;
761
762 return TRUE;
763}
#define BufSize
Definition: FsRtlTunnel.c:28

Referenced by LdrpMapDll().

◆ LdrpResolveFullName()

NTSTATUS NTAPI LdrpResolveFullName ( IN PUNICODE_STRING  OriginalName,
IN PUNICODE_STRING  PathName,
IN PUNICODE_STRING  FullPathName,
IN PUNICODE_STRING ExpandedName 
)

Definition at line 1646 of file ldrutils.c.

1650{
1652// RTL_PATH_TYPE PathType;
1653// BOOLEAN InvalidName;
1654 ULONG Length;
1655
1656 /* Display debug output if snaps are on */
1657 if (ShowSnaps)
1658 {
1661 "LDR: %s - Expanding full name of %wZ\n",
1663 OriginalName);
1664 }
1665
1666 /* FIXME: Lock the PEB */
1667 //RtlEnterCriticalSection(&FastPebLock);
1668#if 0
1669 /* Get the path name */
1670 Length = RtlGetFullPathName_Ustr(OriginalName,
1671 PathName->Length,
1672 PathName->Buffer,
1673 NULL,
1674 &InvalidName,
1675 &PathType);
1676#else
1677 Length = 0;
1678#endif
1680 {
1681 /* Fail */
1683 goto Quickie;
1684 }
1685
1686 /* Check if the length hasn't changed */
1687 if (Length <= PathName->Length)
1688 {
1689 /* Return the same thing */
1690 *ExpandedName = PathName;
1691 PathName->Length = (USHORT)Length;
1692 goto Quickie;
1693 }
1694
1695 /* Sanity check */
1696 ASSERT(Length >= sizeof(WCHAR));
1697
1698 /* Allocate a string */
1699 Status = LdrpAllocateUnicodeString(FullPathName, Length - sizeof(WCHAR));
1700 if (!NT_SUCCESS(Status)) goto Quickie;
1701
1702 /* Now get the full path again */
1703#if 0
1704 Length = RtlGetFullPathName_Ustr(OriginalName,
1705 FullPathName->Length,
1706 FullPathName->Buffer,
1707 NULL,
1708 &InvalidName,
1709 &PathType);
1710#else
1711 Length = 0;
1712#endif
1713 if (!(Length) || (Length > FullPathName->Length))
1714 {
1715 /* Fail */
1716 LdrpFreeUnicodeString(FullPathName);
1718 }
1719 else
1720 {
1721 /* Return the expanded name */
1722 *ExpandedName = FullPathName;
1723 FullPathName->Length = (USHORT)Length;
1724 }
1725
1726Quickie:
1727 /* FIXME: Unlock the PEB */
1728 //RtlLeaveCriticalSection(&FastPebLock);
1729
1730 /* Display debug output if snaps are on */
1731 if (ShowSnaps)
1732 {
1733 /* Check which output to use -- failure or success */
1734 if (NT_SUCCESS(Status))
1735 {
1738 "LDR: %s - Expanded to %wZ\n",
1740 *ExpandedName);
1741 }
1742 else
1743 {
1746 "LDR: %s - Failed to expand %wZ; 0x%08x\n",
1748 OriginalName,
1749 Status);
1750 }
1751 }
1752
1753 /* If we failed, return NULL */
1754 if (!NT_SUCCESS(Status)) *ExpandedName = NULL;
1755
1756 /* Return status */
1757 return Status;
1758}
static IN ULONG IN PWSTR OUT PCWSTR OUT PBOOLEAN OUT PATH_TYPE_AND_UNKNOWN * PathType
static IN ULONG IN PWSTR OUT PCWSTR OUT PBOOLEAN InvalidName
NTSTATUS NTAPI LdrpAllocateUnicodeString(IN OUT PUNICODE_STRING StringOut, IN ULONG Length)
Definition: ldrutils.c:33
ULONG NTAPI RtlGetFullPathName_Ustr(_In_ PUNICODE_STRING FileName, _In_ ULONG Size, _Out_z_bytecap_(Size) PWSTR Buffer, _Out_opt_ PCWSTR *ShortName, _Out_opt_ PBOOLEAN InvalidName, _Out_ RTL_PATH_TYPE *PathType)
Definition: path.c:734

Referenced by LdrpSearchPath().

◆ LdrpRunShimEngineInitRoutine()

VOID NTAPI LdrpRunShimEngineInitRoutine ( IN ULONG  Reason)

Definition at line 2722 of file ldrutils.c.

2723{
2724 PLIST_ENTRY ListHead, Next;
2725 PLDR_DATA_TABLE_ENTRY LdrEntry;
2726
2727 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
2728 Next = ListHead->Flink;
2729 while (Next != ListHead)
2730 {
2731 LdrEntry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
2732
2733 if (g_pShimEngineModule == LdrEntry->DllBase)
2734 {
2735 if (LdrEntry->EntryPoint)
2736 {
2737 _SEH2_TRY
2738 {
2739 LdrpCallInitRoutine(LdrEntry->EntryPoint, LdrEntry->DllBase, Reason, NULL);
2740 }
2742 {
2743 DPRINT1("WARNING: Exception 0x%x during LdrpRunShimEngineInitRoutine(%u)\n",
2745 }
2746 _SEH2_END;
2747 }
2748 return;
2749 }
2750
2751 Next = Next->Flink;
2752 }
2753}

Referenced by LdrpLoadShimEngine(), and LdrpUnloadShimEngine().

◆ LdrpSearchPath()

NTSTATUS NTAPI LdrpSearchPath ( IN PWCHAR SearchPath,
IN PWCHAR  DllName,
IN PUNICODE_STRING  PathName,
IN PUNICODE_STRING  FullPathName,
IN PUNICODE_STRING ExpandedName 
)

Definition at line 1762 of file ldrutils.c.

1767{
1769 PWCHAR ActualSearchPath = *SearchPath;
1772 PWCHAR Buffer, BufEnd = NULL;
1773 ULONG Length = 0;
1774 WCHAR p;
1775 //PWCHAR pp;
1776
1777 /* Check if we don't have a search path */
1778 if (!ActualSearchPath) *SearchPath = LdrpDefaultPath.Buffer;
1779
1780 /* Display debug output if snaps are on */
1781 if (ShowSnaps)
1782 {
1785 "LDR: %s - Looking for %ws in %ws\n",
1787 DllName,
1788 *SearchPath);
1789 }
1790
1791 /* Check if we're dealing with a relative path */
1793 {
1794 /* Good, we're not. Create the name string */
1796 if (!NT_SUCCESS(Status)) goto Quickie;
1797
1798 /* Make sure it exists */
1799 #if 0
1801 {
1802 /* It doesn't, fail */
1804 goto Quickie;
1805 }
1806 #endif
1807
1808 /* Resolve the full name */
1810 PathName,
1811 FullPathName,
1812 ExpandedName);
1813 goto Quickie;
1814 }
1815
1816 /* FIXME: Handle relative case semicolon-lookup here */
1817
1818 /* Calculate length */
1819 Length += (ULONG)wcslen(DllName) + 1;
1821 {
1822 /* Too long, fail */
1824 goto Quickie;
1825 }
1826
1827 /* Allocate buffer */
1828 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
1829 if (!Buffer)
1830 {
1831 /* Fail */
1833 goto Quickie;
1834 }
1835
1836 /* FIXME: Setup TestName here */
1838 BufEnd = Buffer;
1839
1840 /* Start loop */
1841 do
1842 {
1843 /* Get character */
1844 p = *ActualSearchPath;
1845 if (!(p) || (p == ';'))
1846 {
1847 /* FIXME: We don't have a character, or is a semicolon.*/
1848
1849 /* Display debug output if snaps are on */
1850 if (ShowSnaps)
1851 {
1854 "LDR: %s - Looking for %ws\n",
1856 Buffer);
1857 }
1858
1859 /* Sanity check */
1860 TestName.Length = (USHORT)ALIGN_DOWN((BufEnd - Buffer), WCHAR);
1861#if 0
1862 ASSERT(TestName.Length < TestName.MaximumLength);
1863#endif
1864
1865 /* Check if the file exists */
1866 #if 0
1868 #endif
1869 {
1870 /* It does. Reallocate the buffer */
1871 TestName.MaximumLength = (USHORT)ALIGN_DOWN((BufEnd - Buffer), WCHAR) + sizeof(WCHAR);
1872 TestName.Buffer = RtlReAllocateHeap(RtlGetProcessHeap(),
1873 0,
1874 Buffer,
1875 TestName.MaximumLength);
1876 if (!TestName.Buffer)
1877 {
1878 /* Keep the old one */
1879 TestName.Buffer = Buffer;
1880 }
1881 else
1882 {
1883 /* Update buffer */
1884 Buffer = TestName.Buffer;
1885 }
1886
1887 /* Make sure we have a buffer at least */
1888 ASSERT(TestName.Buffer);
1889
1890 /* Resolve the name */
1891 *SearchPath = ActualSearchPath++;
1893 PathName,
1894 FullPathName,
1895 ExpandedName);
1896 break;
1897 }
1898
1899 /* Update buffer end */
1900 BufEnd = Buffer;
1901
1902 /* Update string position */
1903 //pp = ActualSearchPath++;
1904 }
1905 else
1906 {
1907 /* Otherwise, write the character */
1908 *BufEnd = p;
1909 BufEnd++;
1910 }
1911
1912 /* Check if the string is empty, meaning we're done */
1913 if (!(*ActualSearchPath)) TryAgain = TRUE;
1914
1915 /* Advance in the string */
1916 ActualSearchPath++;
1917 } while (!TryAgain);
1918
1919 /* Check if we had a buffer and free it */
1920 if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
1921
1922Quickie:
1923 /* Check if we got here through failure */
1924 if (!NT_SUCCESS(Status)) *ExpandedName = NULL;
1925
1926 /* Display debug output if snaps are on */
1927 if (ShowSnaps)
1928 {
1929 /* Check which output to use -- failure or success */
1930 if (NT_SUCCESS(Status))
1931 {
1934 "LDR: %s - Returning %wZ\n",
1936 *ExpandedName);
1937 }
1938 else
1939 {
1942 "LDR: %s - Unable to locate %ws in %ws: 0x%08x\n",
1944 DllName,
1945 ActualSearchPath,
1946 Status);
1947 }
1948 }
1949
1950 /* Return status */
1951 return Status;
1952}
@ TryAgain
Definition: bl.h:896
Definition: bufpool.h:45
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2686
NTSYSAPI NTSTATUS WINAPI RtlInitUnicodeStringEx(PUNICODE_STRING, PCWSTR)
NTSTATUS NTAPI LdrpResolveFullName(IN PUNICODE_STRING OriginalName, IN PUNICODE_STRING PathName, IN PUNICODE_STRING FullPathName, IN PUNICODE_STRING *ExpandedName)
Definition: ldrutils.c:1646
WCHAR TestName[MAX_PATH]
Definition: main.cpp:13
NTSYSAPI RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_U(_In_ PCWSTR Path)
@ RtlPathTypeRelative
Definition: rtltypes.h:470
#define UNICODE_STRING_MAX_CHARS
BOOLEAN NTAPI RtlDoesFileExists_UstrEx(IN PCUNICODE_STRING FileName, IN BOOLEAN SucceedIfBusy)
Definition: path.c:1430
#define ALIGN_DOWN(size, type)
Definition: umtypes.h:88

◆ LdrpSetProtection()

NTSTATUS NTAPI LdrpSetProtection ( PVOID  ViewBase,
BOOLEAN  Restore 
)

Definition at line 921 of file ldrutils.c.

923{
924 PIMAGE_NT_HEADERS NtHeaders;
925 PIMAGE_SECTION_HEADER Section;
927 PVOID SectionBase;
928 SIZE_T SectionSize;
929 ULONG NewProtection, OldProtection, i;
930
931 /* Get the NT headers */
932 NtHeaders = RtlImageNtHeader(ViewBase);
933 if (!NtHeaders) return STATUS_INVALID_IMAGE_FORMAT;
934
935 /* Compute address of the first section header */
936 Section = IMAGE_FIRST_SECTION(NtHeaders);
937
938 /* Go through all sections */
939 for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
940 {
941 /* Check for read-only non-zero section */
942 if ((Section->SizeOfRawData) &&
944 {
945 /* Check if we are setting or restoring protection */
946 if (Restore)
947 {
948 /* Set it to either EXECUTE or READONLY */
950 {
951 NewProtection = PAGE_EXECUTE;
952 }
953 else
954 {
955 NewProtection = PAGE_READONLY;
956 }
957
958 /* Add PAGE_NOCACHE if needed */
960 {
961 NewProtection |= PAGE_NOCACHE;
962 }
963 }
964 else
965 {
966 /* Enable write access */
967 NewProtection = PAGE_READWRITE;
968 }
969
970 /* Get the section VA */
971 SectionBase = (PVOID)((ULONG_PTR)ViewBase + Section->VirtualAddress);
972 SectionSize = Section->SizeOfRawData;
973 if (SectionSize)
974 {
975 /* Set protection */
977 &SectionBase,
978 &SectionSize,
979 NewProtection,
980 &OldProtection);
981 if (!NT_SUCCESS(Status)) return Status;
982 }
983 }
984
985 /* Move to the next section */
986 Section++;
987 }
988
989 /* Flush instruction cache if necessary */
991 return STATUS_SUCCESS;
992}
#define PAGE_READONLY
Definition: compat.h:138
NTSYSAPI NTSTATUS NTAPI ZwFlushInstructionCache(_In_ HANDLE ProcessHandle, _In_ PVOID BaseAddress, _In_ ULONG NumberOfBytesToFlush)
NTSYSAPI NTSTATUS NTAPI ZwProtectVirtualMemory(_In_ HANDLE ProcessHandle, _In_ PVOID *BaseAddress, _In_ SIZE_T *NumberOfBytesToProtect, _In_ ULONG NewAccessProtection, _Out_ PULONG OldAccessProtection)
#define PAGE_NOCACHE
Definition: nt_native.h:1311
#define IMAGE_SCN_MEM_NOT_CACHED
Definition: ntimage.h:236
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
#define IMAGE_SCN_MEM_EXECUTE
Definition: ntimage.h:239
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

◆ LdrpUnloadShimEngine()

VOID NTAPI LdrpUnloadShimEngine ( )

Definition at line 2782 of file ldrutils.c.

2783{
2784 /* Make sure we do not call into the shim engine anymore */
2789}
#define DLL_PROCESS_DETACH
Definition: compat.h:130

Referenced by LdrpGetShimEngineInterface().

◆ LdrpUpdateLoadCount2()

VOID NTAPI LdrpUpdateLoadCount2 ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry,
IN ULONG  Flags 
)

Definition at line 434 of file ldrutils.c.

436{
438 UNICODE_STRING UpdateString;
439
440 /* Setup the string and call the extended API */
441 RtlInitEmptyUnicodeString(&UpdateString, Buffer, sizeof(Buffer));
442 LdrpUpdateLoadCount3(LdrEntry, Flags, &UpdateString);
443}
VOID NTAPI LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Flags, OUT PUNICODE_STRING UpdateString)
Definition: ldrutils.c:112
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by LdrAddRefDll(), LdrGetDllHandleEx(), LdrpLoadDll(), and LdrUnloadDll().

◆ LdrpUpdateLoadCount3()

VOID NTAPI LdrpUpdateLoadCount3 ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry,
IN ULONG  Flags,
OUT PUNICODE_STRING  UpdateString 
)

Definition at line 112 of file ldrutils.c.

115{
116 PIMAGE_BOUND_FORWARDER_REF NewImportForwarder;
119 PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
120 PIMAGE_THUNK_DATA FirstThunk;
122 PUNICODE_STRING ImportNameUnic, RedirectedImportName;
123 ANSI_STRING ImportNameAnsi;
124 LPSTR ImportName;
125 ULONG ImportSize;
127 ULONG i;
128 BOOLEAN RedirectedDll;
129 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
130
131 /* Set up the Act Ctx */
132 ActCtx.Size = sizeof(ActCtx);
135
136 /* Activate the ActCtx */
137 RtlActivateActivationContextUnsafeFast(&ActCtx,
138 LdrEntry->EntryPointActivationContext);
139
140 /* Check the action we need to perform */
142 {
143 /* Make sure entry is not being loaded already */
144 if (LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS)
145 goto done;
146
147 LdrEntry->Flags |= LDRP_LOAD_IN_PROGRESS;
148 }
149 else if (Flags == LDRP_UPDATE_DEREFCOUNT)
150 {
151 /* Make sure the entry is not being unloaded already */
152 if (LdrEntry->Flags & LDRP_UNLOAD_IN_PROGRESS)
153 goto done;
154
155 LdrEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS;
156 }
157
158 /* Go through all bound DLLs and dereference them */
159 ImportNameUnic = &NtCurrentTeb()->StaticUnicodeString;
160
161 /* Try to get the new import entry */
162 FirstEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
163 TRUE,
165 &ImportSize);
166
167 if (FirstEntry)
168 {
169 /* Set entry flags if refing/derefing */
171 LdrEntry->Flags |= LDRP_LOAD_IN_PROGRESS;
172 else if (Flags == LDRP_UPDATE_DEREFCOUNT)
173 LdrEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS;
174
175 BoundEntry = FirstEntry;
176 while (BoundEntry->OffsetModuleName)
177 {
178 /* Get pointer to the current import name */
179 ImportName = (LPSTR)FirstEntry + BoundEntry->OffsetModuleName;
180
181 RtlInitAnsiString(&ImportNameAnsi, ImportName);
182 Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
183
184 if (NT_SUCCESS(Status))
185 {
186 RedirectedDll = FALSE;
187 RedirectedImportName = ImportNameUnic;
188
189 /* Check if the SxS Assemblies specify another file */
191 ImportNameUnic, &LdrApiDefaultExtension, UpdateString, NULL, &RedirectedImportName,
192 &RedirectedDll);
193
194 /* Check success */
195 if (NT_SUCCESS(Status) && RedirectedDll)
196 {
197 if (ShowSnaps)
198 {
199 DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
200 }
201 }
202
203 if (NT_SUCCESS(Status))
204 {
206 RedirectedImportName,
207 TRUE,
208 RedirectedDll,
209 &Entry))
210 {
211 if (Entry->LoadCount != 0xFFFF)
212 {
213 /* Perform the required action */
214 switch (Flags)
215 {
217 Entry->LoadCount++;
218 break;
220 Entry->LoadCount--;
221 break;
222 case LDRP_UPDATE_PIN:
223 Entry->LoadCount = 0xFFFF;
224 break;
225 }
226
227 /* Show snaps */
228 if (ShowSnaps)
229 {
230 DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
231 }
232 }
233
234 /* Recurse into this entry */
235 LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
236 }
237 else if (RedirectedDll)
238 {
239 DPRINT1("LDR: LdrpCheckForLoadedDll failed for redirected dll %wZ\n", RedirectedImportName);
240 }
241 }
242 else
243 {
244 /* Unrecoverable SxS failure */
245 DPRINT1("LDR: LdrpApplyFileNameRedirection failed with status %x for dll %wZ\n", Status, ImportNameUnic);
246 }
247
248 }
249
250 /* Go through forwarders */
251 NewImportForwarder = (PIMAGE_BOUND_FORWARDER_REF)(BoundEntry + 1);
252 for (i = 0; i < BoundEntry->NumberOfModuleForwarderRefs; i++)
253 {
254 ImportName = (LPSTR)FirstEntry + NewImportForwarder->OffsetModuleName;
255
256 RtlInitAnsiString(&ImportNameAnsi, ImportName);
257 Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
258 if (NT_SUCCESS(Status))
259 {
260 RedirectedDll = FALSE;
261 RedirectedImportName = ImportNameUnic;
262
263 /* Check if the SxS Assemblies specify another file */
265 ImportNameUnic, &LdrApiDefaultExtension, UpdateString, NULL, &RedirectedImportName,
266 &RedirectedDll);
267
268 /* Check success */
269 if (NT_SUCCESS(Status) && RedirectedDll)
270 {
271 if (ShowSnaps)
272 {
273 DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
274 }
275 }
276
277 if (NT_SUCCESS(Status))
278 {
280 RedirectedImportName,
281 TRUE,
282 RedirectedDll,
283 &Entry))
284 {
285 if (Entry->LoadCount != 0xFFFF)
286 {
287 /* Perform the required action */
288 switch (Flags)
289 {
291 Entry->LoadCount++;
292 break;
294 Entry->LoadCount--;
295 break;
296 case LDRP_UPDATE_PIN:
297 Entry->LoadCount = 0xFFFF;
298 break;
299 }
300
301 /* Show snaps */
302 if (ShowSnaps)
303 {
304 DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
305 }
306 }
307
308 /* Recurse into this entry */
309 LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
310 }
311 else if (RedirectedDll)
312 {
313 DPRINT1("LDR: LdrpCheckForLoadedDll failed with status %x for redirected dll %wZ\n", Status, RedirectedImportName);
314 }
315 }
316 else
317 {
318 /* Unrecoverable SxS failure */
319 DPRINT1("LDR: LdrpApplyFileNameRedirection failed with status %x for dll %wZ\n", Status, ImportNameUnic);
320 }
321
322 }
323
324 NewImportForwarder++;
325 }
326
327 BoundEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewImportForwarder;
328 }
329
330 /* We're done */
331 goto done;
332 }
333
334 /* Check oldstyle import descriptor */
335 ImportEntry = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(LdrEntry->DllBase,
336 TRUE,
338 &ImportSize);
339 if (ImportEntry)
340 {
341 /* There is old one, so go through its entries */
342 while (ImportEntry->Name && ImportEntry->FirstThunk)
343 {
344 FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->FirstThunk);
345
346 /* Skip this entry if needed */
347 if (!FirstThunk->u1.Function)
348 {
349 ImportEntry++;
350 continue;
351 }
352
353 ImportName = (PSZ)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->Name);
354
355 RtlInitAnsiString(&ImportNameAnsi, ImportName);
356 Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
357 if (NT_SUCCESS(Status))
358 {
359 RedirectedDll = FALSE;
360 RedirectedImportName = ImportNameUnic;
361
362 /* Check if the SxS Assemblies specify another file */
364 ImportNameUnic, &LdrApiDefaultExtension, UpdateString, NULL, &RedirectedImportName, &RedirectedDll);
365
366 /* Check success */
367 if (NT_SUCCESS(Status) && RedirectedDll)
368 {
369 if (ShowSnaps)
370 {
371 DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
372 }
373 }
374
375 if (NT_SUCCESS(Status))
376 {
378 RedirectedImportName,
379 TRUE,
380 RedirectedDll,
381 &Entry))
382 {
383 if (Entry->LoadCount != 0xFFFF)
384 {
385 /* Perform the required action */
386 switch (Flags)
387 {
389 Entry->LoadCount++;
390 break;
392 Entry->LoadCount--;
393 break;
394 case LDRP_UPDATE_PIN:
395 Entry->LoadCount = 0xFFFF;
396 break;
397 }
398
399 /* Show snaps */
400 if (ShowSnaps)
401 {
402 DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
403 }
404 }
405
406 /* Recurse */
407 LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
408 }
409 else if (RedirectedDll)
410 {
411 DPRINT1("LDR: LdrpCheckForLoadedDll failed for redirected dll %wZ\n", RedirectedImportName);
412 }
413
414 }
415 else
416 {
417 /* Unrecoverable SxS failure */
418 DPRINT1("LDR: LdrpApplyFileNameRedirection failed for dll %wZ\n", ImportNameUnic);
419 }
420 }
421
422 /* Go to the next entry */
423 ImportEntry++;
424 }
425 }
426
427done:
428 /* Release the context */
429 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
430}
#define LDRP_UNLOAD_IN_PROGRESS
Definition: ldrtypes.h:47
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:264
#define LDRP_LOAD_IN_PROGRESS
Definition: ldrtypes.h:46
#define RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER
Definition: rtltypes.h:101
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
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)
#define LDRP_UPDATE_DEREFCOUNT
Definition: ntdllp.h:16
#define LDRP_UPDATE_PIN
Definition: ntdllp.h:17
struct _IMAGE_IMPORT_DESCRIPTOR * PIMAGE_IMPORT_DESCRIPTOR
PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA
Definition: ntimage.h:566
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
Definition: pedump.c:270
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
char * PSZ
Definition: windef.h:57
struct _IMAGE_BOUND_FORWARDER_REF * PIMAGE_BOUND_FORWARDER_REF
struct _IMAGE_BOUND_IMPORT_DESCRIPTOR * PIMAGE_BOUND_IMPORT_DESCRIPTOR
char * LPSTR
Definition: xmlstorage.h:182

Referenced by LdrpUpdateLoadCount2(), and LdrpUpdateLoadCount3().

Variable Documentation

◆ g_pfnSE_DllLoaded

PVOID g_pfnSE_DllLoaded

Definition at line 23 of file ldrutils.c.

Referenced by LdrpGetShimEngineInterface(), and LdrpLoadDll().

◆ g_pfnSE_DllUnloaded

PVOID g_pfnSE_DllUnloaded

Definition at line 24 of file ldrutils.c.

Referenced by LdrpGetShimEngineInterface(), and LdrUnloadDll().

◆ g_pfnSE_InstallAfterInit

PVOID g_pfnSE_InstallAfterInit

Definition at line 26 of file ldrutils.c.

Referenced by LdrpGetShimEngineInterface(), and LdrpInitializeProcess().

◆ g_pfnSE_InstallBeforeInit

PVOID g_pfnSE_InstallBeforeInit

Definition at line 25 of file ldrutils.c.

Referenced by LdrpGetShimEngineInterface(), and LdrpLoadShimEngine().

◆ g_pfnSE_ProcessDying

PVOID g_pfnSE_ProcessDying

Definition at line 27 of file ldrutils.c.

Referenced by LdrpGetShimEngineInterface(), and LdrShutdownProcess().

◆ g_pShimEngineModule

◆ g_ShimsEnabled

◆ LdrpGetModuleHandleCache

PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache

Definition at line 19 of file ldrutils.c.

Referenced by LdrGetDllHandleEx(), and LdrUnloadDll().

◆ LdrpLoadedDllHandleCache

PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache

Definition at line 19 of file ldrutils.c.

Referenced by LdrpCheckForLoadedDllHandle().