ReactOS 0.4.15-dev-8039-g69ebfd6
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 1523 of file ldrutils.c.

1524{
1525 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
1526 PIMAGE_NT_HEADERS NtHeader;
1527
1528 /* Make sure the header is valid */
1529 NtHeader = RtlImageNtHeader(BaseAddress);
1530 DPRINT("LdrpAllocateDataTableEntry(%p), NtHeader %p\n", BaseAddress, NtHeader);
1531
1532 if (NtHeader)
1533 {
1534 /* Allocate an entry */
1535 LdrEntry = RtlAllocateHeap(LdrpHeap,
1537 sizeof(LDR_DATA_TABLE_ENTRY));
1538
1539 /* Make sure we got one */
1540 if (LdrEntry)
1541 {
1542 /* Set it up */
1543 LdrEntry->DllBase = BaseAddress;
1544 LdrEntry->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
1545 LdrEntry->TimeDateStamp = NtHeader->FileHeader.TimeDateStamp;
1546 LdrEntry->PatchInformation = NULL;
1547 }
1548 }
1549
1550 /* Return the entry */
1551 return LdrEntry;
1552}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
#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:59
#define DPRINT
Definition: sndvol32.h:71
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:143
PVOID DllBase
Definition: btrfs_drv.h:1880
ULONG TimeDateStamp
Definition: btrfs_drv.h:1889
PVOID PatchInformation
Definition: ldrtypes.h:164

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 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
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
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 _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOLEAN(NTAPI * PDLL_INIT_ROUTINE)(_In_ PVOID DllHandle, _In_ ULONG Reason, _In_opt_ PCONTEXT Context)
Definition: ldrtypes.h:254
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:81
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:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
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:3569
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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:5863
_In_ PCWSTR FullDllName
Definition: ldrtypes.h:247
#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:63
HANDLE LdrpKnownDllObjectDirectory
Definition: ldrinit.c:62
VOID NTAPI LdrpEnsureLoaderLockIsHeld(VOID)
Definition: ldrinit.c:409
#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 1953 of file ldrutils.c.

1958{
1959 ULONG HashIndex;
1960 PLIST_ENTRY ListHead, ListEntry;
1961 PLDR_DATA_TABLE_ENTRY CurEntry;
1962 BOOLEAN FullPath = FALSE;
1963 PWCHAR wc;
1964 WCHAR NameBuf[266];
1965 UNICODE_STRING FullDllName, NtPathName;
1966 ULONG Length;
1969 HANDLE FileHandle, SectionHandle;
1971 PVOID ViewBase = NULL;
1972 SIZE_T ViewSize = 0;
1973 PIMAGE_NT_HEADERS NtHeader, NtHeader2;
1974 DPRINT("LdrpCheckForLoadedDll('%S' '%wZ' %u %u %p)\n", DllPath ? ((ULONG_PTR)DllPath == 1 ? L"" : DllPath) : L"", DllName, Flag, RedirectedDll, LdrEntry);
1975
1976 /* Check if a dll name was provided */
1977 if (!(DllName->Buffer) || !(DllName->Buffer[0])) return FALSE;
1978
1979 /* FIXME: Warning, "Flag" is used as magic instead of "Static" */
1980 /* FIXME: Warning, code does not support redirection at all */
1981
1982 /* Look in the hash table if flag was set */
1983lookinhash:
1984 if (Flag /* the second check is a hack */ && !RedirectedDll)
1985 {
1986 /* 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 */
1987
1988 /* Get hash index */
1989 HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]);
1990
1991 /* Traverse that list */
1992 ListHead = &LdrpHashTable[HashIndex];
1993 ListEntry = ListHead->Flink;
1994 while (ListEntry != ListHead)
1995 {
1996 /* Get the current entry */
1997 CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
1998
1999 /* Check base name of that module */
2000 if (RtlEqualUnicodeString(DllName, &CurEntry->BaseDllName, TRUE))
2001 {
2002 /* It matches, return it */
2003 *LdrEntry = CurEntry;
2004 return TRUE;
2005 }
2006
2007 /* Advance to the next entry */
2008 ListEntry = ListEntry->Flink;
2009 }
2010
2011 /* Module was not found, return failure */
2012 return FALSE;
2013 }
2014
2015 /* Check if this is a redirected DLL */
2016 if (RedirectedDll)
2017 {
2018 /* Redirected dlls already have a full path */
2019 FullPath = TRUE;
2020 FullDllName = *DllName;
2021 }
2022 else
2023 {
2024 /* Check if there is a full path in this DLL */
2025 wc = DllName->Buffer;
2026 while (*wc)
2027 {
2028 /* Check for a slash in the current position*/
2029 if ((*wc == L'\\') || (*wc == L'/'))
2030 {
2031 /* Found the slash, so dll name contains path */
2032 FullPath = TRUE;
2033
2034 /* Setup full dll name string */
2035 FullDllName.Buffer = NameBuf;
2036
2037 /* FIXME: This is from the Windows 2000 loader, not XP/2003, we should call LdrpSearchPath */
2039 DllName->Buffer,
2040 NULL,
2041 sizeof(NameBuf) - sizeof(UNICODE_NULL),
2042 FullDllName.Buffer,
2043 NULL);
2044
2045 /* Check if that was successful */
2046 if (!(Length) || (Length > (sizeof(NameBuf) - sizeof(UNICODE_NULL))))
2047 {
2048 if (ShowSnaps)
2049 {
2050 DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n",
2051 &DllName, Length);
2052 }
2053 }
2054
2055 /* Full dll name is found */
2056 FullDllName.Length = Length;
2057 FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL);
2058 break;
2059 }
2060
2061 wc++;
2062 }
2063 }
2064
2065 /* Go check the hash table */
2066 if (!FullPath)
2067 {
2068 Flag = TRUE;
2069 goto lookinhash;
2070 }
2071
2072 /* FIXME: Warning, activation context missing */
2073 DPRINT("Warning, activation context missing\n");
2074
2075 /* NOTE: From here on down, everything looks good */
2076
2077 /* Loop the module list */
2078 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
2079 ListEntry = ListHead->Flink;
2080 while (ListEntry != ListHead)
2081 {
2082 /* Get the current entry and advance to the next one */
2083 CurEntry = CONTAINING_RECORD(ListEntry,
2085 InLoadOrderLinks);
2086 ListEntry = ListEntry->Flink;
2087
2088 /* Check if it's being unloaded */
2089 if (!CurEntry->InMemoryOrderLinks.Flink) continue;
2090
2091 /* Check if name matches */
2093 &CurEntry->FullDllName,
2094 TRUE))
2095 {
2096 /* Found it */
2097 *LdrEntry = CurEntry;
2098 return TRUE;
2099 }
2100 }
2101
2102 /* Convert given path to NT path */
2104 &NtPathName,
2105 NULL,
2106 NULL))
2107 {
2108 /* Fail if conversion failed */
2109 return FALSE;
2110 }
2111
2112 /* Initialize object attributes and open it */
2114 &NtPathName,
2116 NULL,
2117 NULL);
2121 &Iosb,
2124
2125 /* Free NT path name */
2126 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
2127
2128 /* If opening the file failed - return failure */
2129 if (!NT_SUCCESS(Status)) return FALSE;
2130
2131 /* Create a section for this file */
2132 Status = NtCreateSection(&SectionHandle,
2136 NULL,
2137 NULL,
2139 SEC_COMMIT,
2140 FileHandle);
2141
2142 /* Close file handle */
2144
2145 /* If creating section failed - return failure */
2146 if (!NT_SUCCESS(Status)) return FALSE;
2147
2148 /* Map view of this section */
2149 Status = ZwMapViewOfSection(SectionHandle,
2151 &ViewBase,
2152 0,
2153 0,
2154 NULL,
2155 &ViewSize,
2156 ViewShare,
2157 0,
2158 PAGE_EXECUTE);
2159
2160 /* Close section handle */
2161 NtClose(SectionHandle);
2162
2163 /* If section mapping failed - return failure */
2164 if (!NT_SUCCESS(Status)) return FALSE;
2165
2166 /* Get pointer to the NT header of this section */
2167 Status = RtlImageNtHeaderEx(0, ViewBase, ViewSize, &NtHeader);
2168 if (!(NT_SUCCESS(Status)) || !(NtHeader))
2169 {
2170 /* Unmap the section and fail */
2172 return FALSE;
2173 }
2174
2175 /* Go through the list of modules again */
2176 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
2177 ListEntry = ListHead->Flink;
2178 while (ListEntry != ListHead)
2179 {
2180 /* Get the current entry and advance to the next one */
2181 CurEntry = CONTAINING_RECORD(ListEntry,
2183 InLoadOrderLinks);
2184 ListEntry = ListEntry->Flink;
2185
2186 /* Check if it's in the process of being unloaded */
2187 if (!CurEntry->InMemoryOrderLinks.Flink) continue;
2188
2189 /* The header is untrusted, use SEH */
2190 _SEH2_TRY
2191 {
2192 /* Check if timedate stamp and sizes match */
2193 if ((CurEntry->TimeDateStamp == NtHeader->FileHeader.TimeDateStamp) &&
2194 (CurEntry->SizeOfImage == NtHeader->OptionalHeader.SizeOfImage))
2195 {
2196 /* Time, date and size match. Let's compare their headers */
2197 NtHeader2 = RtlImageNtHeader(CurEntry->DllBase);
2198 if (RtlCompareMemory(NtHeader2, NtHeader, sizeof(IMAGE_NT_HEADERS)))
2199 {
2200 /* Headers match too! Finally ask the kernel to compare mapped files */
2201 Status = ZwAreMappedFilesTheSame(CurEntry->DllBase, ViewBase);
2202 if (NT_SUCCESS(Status))
2203 {
2204 /* This is our entry!, unmap and return success */
2205 *LdrEntry = CurEntry;
2207 _SEH2_YIELD(return TRUE;)
2208 }
2209 }
2210 }
2211 }
2213 {
2214 _SEH2_YIELD(break;)
2215 }
2216 _SEH2_END;
2217 }
2218
2219 /* Unmap the section and fail */
2221 return FALSE;
2222}
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3848
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:3441
#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:4402
#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:3952
#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:65
#define LDR_GET_HASH_ENTRY(x)
Definition: ntdllp.h:12
LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]
Definition: ldrinit.c:60
#define L(x)
Definition: ntvdm.h:50
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
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:145
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 1595 of file ldrutils.c.

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

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

◆ LdrpClearLoadInProgress()

ULONG NTAPI LdrpClearLoadInProgress ( VOID  )

Definition at line 2644 of file ldrutils.c.

2645{
2646 PLIST_ENTRY ListHead, Entry;
2647 PLDR_DATA_TABLE_ENTRY LdrEntry;
2648 ULONG ModulesCount = 0;
2649
2650 /* Traverse the init list */
2651 ListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
2652 Entry = ListHead->Flink;
2653 while (Entry != ListHead)
2654 {
2655 /* Get the loader entry */
2656 LdrEntry = CONTAINING_RECORD(Entry,
2658 InInitializationOrderLinks);
2659
2660 /* Clear load in progress flag */
2661 LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
2662
2663 /* Check for modules with entry point count but not processed yet */
2664 if ((LdrEntry->EntryPoint) &&
2665 !(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
2666 {
2667 /* Increase counter */
2668 ModulesCount++;
2669 }
2670
2671 /* Advance to the next entry */
2672 Entry = Entry->Flink;
2673 }
2674
2675 /* Return final count */
2676 return ModulesCount;
2677}
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:44
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:83
#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:1648

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 1572 of file ldrutils.c.

1573{
1574 /* Sanity check */
1575 ASSERT(Entry != NULL);
1576
1577 /* Release the activation context if it exists and wasn't already released */
1578 if ((Entry->EntryPointActivationContext) &&
1579 (Entry->EntryPointActivationContext != INVALID_HANDLE_VALUE))
1580 {
1581 /* Mark it as invalid */
1582 RtlReleaseActivationContext(Entry->EntryPointActivationContext);
1583 Entry->EntryPointActivationContext = INVALID_HANDLE_VALUE;
1584 }
1585
1586 /* Release the full dll name string */
1587 if (Entry->FullDllName.Buffer) LdrpFreeUnicodeString(&Entry->FullDllName);
1588
1589 /* Finally free the entry's memory */
1591}
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
NTSYSAPI void WINAPI RtlReleaseActivationContext(HANDLE)
Definition: actctx.c:5373
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 2226 of file ldrutils.c.

2232{
2234 UCHAR ImportBuffer[64]; // 128 since NT6.2
2235 PLDR_DATA_TABLE_ENTRY LdrEntry;
2236 IMAGE_THUNK_DATA Thunk;
2237 PVOID ImageBase;
2238 PIMAGE_IMPORT_BY_NAME ImportName = NULL;
2239 PIMAGE_EXPORT_DIRECTORY ExportDir;
2240 ULONG ExportDirSize, Length;
2242
2243 /* Show debug message */
2244 if (ShowSnaps) DPRINT1("LDR: LdrGetProcedureAddress by ");
2245
2246 /* Check if we got a name */
2247 if (Name)
2248 {
2249 /* Show debug message */
2250 if (ShowSnaps) DbgPrint("NAME - %s\n", Name->Buffer);
2251
2252 /* Make sure it's not too long */
2253 Length = Name->Length +
2254 sizeof(CHAR) +
2257 {
2258 /* Won't have enough space to add the hint */
2259 return STATUS_NAME_TOO_LONG;
2260 }
2261
2262 /* Check if our buffer is large enough */
2263 if (Length > sizeof(ImportBuffer))
2264 {
2265 /* Allocate from heap, plus 2 bytes for the Hint */
2266 ImportName = RtlAllocateHeap(RtlGetProcessHeap(),
2267 0,
2268 Length);
2269 if (!ImportName)
2270 {
2271 /* Return STATUS_INSUFFICIENT_RESOURCES since NT6.2 */
2273 }
2274 }
2275 else
2276 {
2277 /* Use our internal buffer */
2278 ImportName = (PIMAGE_IMPORT_BY_NAME)ImportBuffer;
2279 }
2280
2281 /* Clear the hint */
2282 ImportName->Hint = 0;
2283
2284 /* Copy the name and null-terminate it */
2285 RtlCopyMemory(ImportName->Name, Name->Buffer, Name->Length);
2286 ImportName->Name[Name->Length] = ANSI_NULL;
2287
2288 /* Clear the high bit */
2289 ImageBase = ImportName;
2290 Thunk.u1.AddressOfData = 0;
2291 }
2292 else
2293 {
2294 /* Do it by ordinal */
2295 ImageBase = NULL;
2296
2297 /* Show debug message */
2298 if (ShowSnaps) DbgPrint("ORDINAL - %lx\n", Ordinal);
2299
2300 /* Make sure an ordinal was given */
2301 if (!Ordinal)
2302 {
2303 /* No ordinal */
2304 DPRINT1("No ordinal and no name\n");
2306 }
2307
2308 /* Set the original flag in the thunk */
2309 Thunk.u1.Ordinal = Ordinal | IMAGE_ORDINAL_FLAG;
2310 }
2311
2312 /* Acquire lock unless we are initting */
2314
2315 _SEH2_TRY
2316 {
2317 /* Try to find the loaded DLL */
2319 {
2320 /* Invalid base */
2321 DPRINT1("Invalid base address %p\n", BaseAddress);
2323 _SEH2_YIELD(goto Quickie;)
2324 }
2325
2326 /* Get the pointer to the export directory */
2327 ExportDir = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
2328 TRUE,
2330 &ExportDirSize);
2331
2332 if (!ExportDir)
2333 {
2334 DPRINT1("Image %wZ has no exports, but were trying to get procedure %Z. BaseAddress asked 0x%p, got entry BA 0x%p\n",
2335 &LdrEntry->BaseDllName, Name, BaseAddress, LdrEntry->DllBase);
2337 _SEH2_YIELD(goto Quickie;)
2338 }
2339
2340 /* Now get the thunk */
2341 Status = LdrpSnapThunk(LdrEntry->DllBase,
2342 ImageBase,
2343 &Thunk,
2344 &Thunk,
2345 ExportDir,
2346 ExportDirSize,
2347 FALSE,
2348 NULL);
2349
2350 /* Finally, see if we're supposed to run the init routines */
2351 if ((NT_SUCCESS(Status)) && (ExecuteInit))
2352 {
2353 /*
2354 * It's possible a forwarded entry had us load the DLL. In that case,
2355 * then we will call its DllMain. Use the last loaded DLL for this.
2356 */
2357 Entry = NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Blink;
2358 LdrEntry = CONTAINING_RECORD(Entry,
2360 InInitializationOrderLinks);
2361
2362 /* Make sure we didn't process it yet*/
2363 if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
2364 {
2365 /* Call the init routine */
2366 _SEH2_TRY
2367 {
2369 }
2371 {
2372 /* Get the exception code */
2374 }
2375 _SEH2_END;
2376 }
2377 }
2378
2379 /* Make sure we're OK till here */
2380 if (NT_SUCCESS(Status))
2381 {
2382 /* Return the address */
2383 *ProcedureAddress = (PVOID)Thunk.u1.Function;
2384 }
2385 }
2387 {
2388 /* Just ignore exceptions */
2389 }
2390 _SEH2_END;
2391
2392Quickie:
2393 /* Cleanup */
2394 if (ImportName && (ImportName != (PIMAGE_IMPORT_BY_NAME)ImportBuffer))
2395 {
2396 /* We allocated from heap, free it */
2397 RtlFreeHeap(RtlGetProcessHeap(), 0, ImportName);
2398 }
2399
2400 /* Release the CS if we entered it */
2402
2403 /* We're done */
2404 return Status;
2405}
#define CHAR(Char)
#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:1595
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:641
RTL_CRITICAL_SECTION LdrpLoaderLock
Definition: ldrinit.c:70
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::@2136 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 2679 of file ldrutils.c.

2680{
2683 PVOID Address;
2685 /* Skip Dll init */
2687 return NT_SUCCESS(Status) ? Address : NULL;
2688}
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:2226
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 2692 of file ldrutils.c.

2693{
2696 PVOID SE_InstallBeforeInit = LdrpGetShimEngineFunction("SE_InstallBeforeInit");
2697 PVOID SE_InstallAfterInit = LdrpGetShimEngineFunction("SE_InstallAfterInit");
2698 PVOID SE_ProcessDying = LdrpGetShimEngineFunction("SE_ProcessDying");
2699
2701 {
2708 }
2709 else
2710 {
2712 }
2713}
VOID NTAPI LdrpUnloadShimEngine()
Definition: ldrutils.c:2777
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:2679
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 1556 of file ldrutils.c.

1557{
1558 PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr;
1559 ULONG i;
1560
1561 /* Insert into hash table */
1562 i = LDR_GET_HASH_ENTRY(LdrEntry->BaseDllName.Buffer[0]);
1563 InsertTailList(&LdrpHashTable[i], &LdrEntry->HashLinks);
1564
1565 /* Insert into other lists */
1566 InsertTailList(&PebData->InLoadOrderModuleList, &LdrEntry->InLoadOrderLinks);
1567 InsertTailList(&PebData->InMemoryOrderModuleList, &LdrEntry->InMemoryOrderLinks);
1568}
#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:120

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 2409 of file ldrutils.c.

2415{
2416 PPEB Peb = NtCurrentPeb();
2418 const WCHAR *p;
2419 BOOLEAN GotExtension;
2420 WCHAR c;
2421 WCHAR NameBuffer[MAX_PATH + 6];
2422 UNICODE_STRING RawDllName;
2423 PLDR_DATA_TABLE_ENTRY LdrEntry;
2424 BOOLEAN InInit = LdrpInLdrInit;
2425
2426 /* Save the Raw DLL Name */
2427 if (DllName->Length >= sizeof(NameBuffer)) return STATUS_NAME_TOO_LONG;
2428 RtlInitEmptyUnicodeString(&RawDllName, NameBuffer, sizeof(NameBuffer));
2429 RtlCopyUnicodeString(&RawDllName, DllName);
2430
2431 /* Find the extension, if present */
2432 /* NOTE: Access violation is expected here in some cases (Buffer[-1]) */
2433 p = DllName->Buffer + DllName->Length / sizeof(WCHAR) - 1;
2434 GotExtension = FALSE;
2435 while (p >= DllName->Buffer)
2436 {
2437 c = *p--;
2438 if (c == L'.')
2439 {
2440 GotExtension = TRUE;
2441 break;
2442 }
2443 else if (c == L'\\')
2444 {
2445 break;
2446 }
2447 }
2448
2449 /* If no extension was found, add the default extension */
2450 if (!GotExtension)
2451 {
2452 /* Check that we have space to add one */
2453 if ((DllName->Length + LdrApiDefaultExtension.Length + sizeof(UNICODE_NULL)) >=
2454 sizeof(NameBuffer))
2455 {
2456 /* No space to add the extension */
2459 "LDR: %s - Dll name missing extension; with extension "
2460 "added the name is too long\n"
2461 " DllName: (@ %p) \"%wZ\"\n"
2462 " DllName->Length: %u\n",
2464 DllName,
2465 DllName,
2466 DllName->Length);
2467 return STATUS_NAME_TOO_LONG;
2468 }
2469
2470 /* Add it. Needs to be null terminated, thus the length check above */
2473 }
2474
2475 /* Check for init flag and acquire lock */
2477
2478 _SEH2_TRY
2479 {
2480 /* Show debug message */
2481 if (ShowSnaps)
2482 {
2483 DPRINT1("LDR: LdrLoadDll, loading %wZ from %ws\n",
2484 &RawDllName,
2485 DllPath ? DllPath : L"");
2486 }
2487
2488 /* Check if the DLL is already loaded */
2490 &RawDllName,
2491 FALSE,
2492 Redirected,
2493 &LdrEntry))
2494 {
2495 /* Map it */
2497 DllPath,
2498 NameBuffer,
2499 DllCharacteristics,
2500 FALSE,
2501 Redirected,
2502 &LdrEntry);
2503 if (!NT_SUCCESS(Status))
2505
2506 /* FIXME: Need to mark the DLL range for the stack DB */
2507 //RtlpStkMarkDllRange(LdrEntry);
2508
2509 /* Check if IMAGE_FILE_EXECUTABLE_IMAGE was provided */
2510 if ((DllCharacteristics) &&
2511 (*DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
2512 {
2513 /* This is not a DLL, so remove such data */
2514 LdrEntry->EntryPoint = NULL;
2515 LdrEntry->Flags &= ~LDRP_IMAGE_DLL;
2516 }
2517
2518 /* Make sure it's a DLL */
2519 if (LdrEntry->Flags & LDRP_IMAGE_DLL)
2520 {
2521 /* Check if this is a .NET Image */
2522 if (!(LdrEntry->Flags & LDRP_COR_IMAGE))
2523 {
2524 /* Walk the Import Descriptor */
2526 }
2527
2528 /* Update load count, unless it's locked */
2529 if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
2531
2532 /* Check if we failed */
2533 if (!NT_SUCCESS(Status))
2534 {
2535 /* Clear entrypoint, and insert into list */
2536 LdrEntry->EntryPoint = NULL;
2538 &LdrEntry->InInitializationOrderLinks);
2539
2540 /* Cancel the load */
2542
2543 /* Unload the DLL */
2544 if (ShowSnaps)
2545 {
2546 DbgPrint("LDR: Unloading %wZ due to error %x walking "
2547 "import descriptors\n",
2548 DllName,
2549 Status);
2550 }
2551 LdrUnloadDll(LdrEntry->DllBase);
2552
2553 /* Return the error */
2555 }
2556 }
2557 else if (LdrEntry->LoadCount != 0xFFFF)
2558 {
2559 /* Increase load count */
2560 LdrEntry->LoadCount++;
2561 }
2562
2563 /* Insert it into the list */
2565 &LdrEntry->InInitializationOrderLinks);
2566
2567 /* If we have to run the entrypoint, make sure the DB is ready */
2568 if (CallInit && LdrpLdrDatabaseIsSetup)
2569 {
2570 /* Notify Shim Engine */
2571 if (g_ShimsEnabled)
2572 {
2574 SE_DllLoaded(LdrEntry);
2575 }
2576
2577 /* Run the init routine */
2579 if (!NT_SUCCESS(Status))
2580 {
2581 /* Failed, unload the DLL */
2582 if (ShowSnaps)
2583 {
2584 DbgPrint("LDR: Unloading %wZ because either its init "
2585 "routine or one of its static imports failed; "
2586 "status = 0x%08lx\n",
2587 DllName,
2588 Status);
2589 }
2590 LdrUnloadDll(LdrEntry->DllBase);
2591 }
2592 }
2593 else
2594 {
2595 /* The DB isn't ready, which means we were loaded because of a forwarder */
2597 }
2598 }
2599 else
2600 {
2601 /* We were already loaded. Are we a DLL? */
2602 if ((LdrEntry->Flags & LDRP_IMAGE_DLL) && (LdrEntry->LoadCount != 0xFFFF))
2603 {
2604 /* Increase load count */
2605 LdrEntry->LoadCount++;
2607
2608 /* Clear the load in progress */
2610 }
2611 else
2612 {
2613 /* Not a DLL, just increase the load count */
2614 if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
2615 }
2616 }
2617
2618 }
2620 {
2621 /* Release the lock */
2623 }
2624 _SEH2_END;
2625
2626 /* Check for success */
2627 if (NT_SUCCESS(Status))
2628 {
2629 /* Return the base address */
2630 *BaseAddress = LdrEntry->DllBase;
2631 }
2632 else
2633 {
2634 /* Nothing found */
2635 *BaseAddress = NULL;
2636 }
2637
2638 /* Return status */
2639 return Status;
2640}
#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
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_LEAVE
Definition: filesup.c:20
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
#define c
Definition: ke_i.h:80
NTSTATUS NTAPI LdrUnloadDll(_In_ PVOID BaseAddress)
Definition: ldrapi.c:1291
#define LDRP_COR_IMAGE
Definition: ldrtypes.h:52
#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:1953
ULONG NTAPI LdrpClearLoadInProgress(VOID)
Definition: ldrutils.c:2644
NTSYSAPI ULONG __cdecl DbgPrintEx(_In_ ULONG ComponentId, _In_ ULONG Level, _In_z_ _Printf_format_string_ PCSTR Format,...)
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
PVOID NTAPI RtlDecodeSystemPointer(IN PVOID Pointer)
Definition: process.c:439
USHORT LoadCount
Definition: ntddk_ex.h:208
LIST_ENTRY InInitializationOrderLinks
Definition: ldrtypes.h:140
LIST_ENTRY InInitializationOrderModuleList
Definition: ldrtypes.h:122
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 2752 of file ldrutils.c.

2753{
2754 UNICODE_STRING ShimLibraryName;
2755 PVOID ShimLibrary;
2757 RtlInitUnicodeString(&ShimLibraryName, ImageName);
2758 /* We should NOT pass CallInit = TRUE!
2759 If we do this, other init routines will be called before we get a chance to shim stuff.. */
2760 Status = LdrpLoadDll(FALSE, NULL, NULL, &ShimLibraryName, &ShimLibrary, FALSE);
2761 if (NT_SUCCESS(Status))
2762 {
2763 g_pShimEngineModule = ShimLibrary;
2766 if (g_ShimsEnabled)
2767 {
2770 SE_InstallBeforeInit(ProcessImage, pShimData);
2771 }
2772 }
2773}
#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:2409
VOID NTAPI LdrpRunShimEngineInitRoutine(IN ULONG Reason)
Definition: ldrutils.c:2717
VOID NTAPI LdrpGetShimEngineInterface()
Definition: ldrutils.c:2692
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 // LdrpSendDllNotifications(LdrEntry, TRUE, Status == STATUS_IMAGE_NOT_AT_BASE)
1230
1231 /* Check for invalid CPU Image */
1233 {
1234 /* Load our header */
1236
1237 /* Assume defaults if we don't have to run the Hard Error path */
1238 HardErrorStatus = STATUS_SUCCESS;
1240
1241 /* Are we an NT 3.0 image? [Do these still exist? LOL -- IAI] */
1243 {
1244 /* Reset the entrypoint, save our Dll Name */
1245 LdrEntry->EntryPoint = 0;
1246 HardErrorParameters[0] = (ULONG_PTR)&FullDllName;
1247
1248 /* Raise the error */
1250 1,
1251 1,
1252 HardErrorParameters,
1254 &Response);
1255 }
1256
1257 /* Check if the user pressed cancel */
1258 if (NT_SUCCESS(HardErrorStatus) && Response == ResponseCancel)
1259 {
1260 /* Remove the DLL from the lists */
1263 RemoveEntryList(&LdrEntry->HashLinks);
1264
1265 /* Remove the LDR Entry */
1266 RtlFreeHeap(LdrpHeap, 0, LdrEntry );
1267
1268 /* Unmap and close section */
1270 NtClose(SectionHandle);
1271
1272 /* Did we do a hard error? */
1274 {
1275 /* Yup, so increase fatal error count if we are initializing */
1277 }
1278
1279 /* Return failure */
1281 }
1282 }
1283 else
1284 {
1285 /* The image was valid. Is it a DLL? */
1286 if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
1287 {
1288 /* Set the DLL Flag */
1289 LdrEntry->Flags |= LDRP_IMAGE_DLL;
1290 }
1291
1292 /* If we're not a DLL, clear the entrypoint */
1293 if (!(LdrEntry->Flags & LDRP_IMAGE_DLL))
1294 {
1295 LdrEntry->EntryPoint = 0;
1296 }
1297 }
1298
1299 /* Return it for the caller */
1300 *DataTableEntry = LdrEntry;
1301
1302 /* Check if we loaded somewhere else */
1304 {
1305 /* Write the flag */
1306 LdrEntry->Flags |= LDRP_IMAGE_NOT_AT_BASE;
1307
1308 /* Find our region */
1309 ImageBase = (ULONG_PTR)NtHeaders->OptionalHeader.ImageBase;
1310 ImageEnd = ImageBase + ViewSize;
1311
1312 DPRINT("LDR: LdrpMapDll Relocating Image Name %ws (%p-%p -> %p)\n", DllName, (PVOID)ImageBase, (PVOID)ImageEnd, ViewBase);
1313
1314 /* Scan all the modules */
1315 ListHead = &Peb->Ldr->InLoadOrderModuleList;
1316 NextEntry = ListHead->Flink;
1317 while (NextEntry != ListHead)
1318 {
1319 /* Get the entry */
1320 CandidateEntry = CONTAINING_RECORD(NextEntry,
1322 InLoadOrderLinks);
1323 NextEntry = NextEntry->Flink;
1324
1325 /* Get the entry's bounds */
1326 CandidateBase = (ULONG_PTR)CandidateEntry->DllBase;
1327 CandidateEnd = CandidateBase + CandidateEntry->SizeOfImage;
1328
1329 /* Make sure this entry isn't unloading */
1330 if (!CandidateEntry->InMemoryOrderLinks.Flink) continue;
1331
1332 /* Check if our regions are colliding */
1333 if ((ImageBase >= CandidateBase && ImageBase <= CandidateEnd) ||
1334 (ImageEnd >= CandidateBase && ImageEnd <= CandidateEnd) ||
1335 (CandidateBase >= ImageBase && CandidateBase <= ImageEnd))
1336 {
1337 /* Found who is overlapping */
1338 OverlapDllFound = TRUE;
1339 OverlapDll = CandidateEntry->FullDllName;
1340 break;
1341 }
1342 }
1343
1344 /* Check if we found the DLL overlapping with us */
1345 if (!OverlapDllFound)
1346 {
1347 /* It's not another DLL, it's memory already here */
1348 RtlInitUnicodeString(&OverlapDll, L"Dynamically Allocated Memory");
1349 }
1350
1351 DPRINT("Overlapping DLL: %wZ\n", &OverlapDll);
1352
1353 /* Are we dealing with a DLL? */
1354 if (LdrEntry->Flags & LDRP_IMAGE_DLL)
1355 {
1356 /* Check if relocs were stripped */
1358 {
1359 /* Get the relocation data */
1360 RelocData = RtlImageDirectoryEntryToData(ViewBase,
1361 TRUE,
1363 &RelocDataSize);
1364
1365 /* Does the DLL not have any? */
1366 if (!RelocData && !RelocDataSize)
1367 {
1368 /* We'll allow this and simply continue */
1369 goto NoRelocNeeded;
1370 }
1371 }
1372
1373 /* See if this is an Illegal DLL - IE: user32 and kernel32 */
1374 RtlInitUnicodeString(&IllegalDll,L"user32.dll");
1375 if (RtlEqualUnicodeString(&BaseDllName, &IllegalDll, TRUE))
1376 {
1377 /* Can't relocate user32 */
1378 RelocatableDll = FALSE;
1379 }
1380 else
1381 {
1382 RtlInitUnicodeString(&IllegalDll, L"kernel32.dll");
1383 if (RtlEqualUnicodeString(&BaseDllName, &IllegalDll, TRUE))
1384 {
1385 /* Can't relocate kernel32 */
1386 RelocatableDll = FALSE;
1387 }
1388 }
1389
1390 /* Known DLLs are not allowed to be relocated */
1391 if (KnownDll && !RelocatableDll)
1392 {
1393 /* Setup for hard error */
1394 HardErrorParameters[0] = (ULONG_PTR)&IllegalDll;
1395 HardErrorParameters[1] = (ULONG_PTR)&OverlapDll;
1396
1397 DPRINT1("Illegal DLL relocation! %wZ overlaps %wZ\n", &OverlapDll, &IllegalDll);
1398
1399 /* Raise the error */
1401 2,
1402 3,
1403 HardErrorParameters,
1404 OptionOk,
1405 &Response);
1406
1407 /* If initializing, increase the error count */
1409
1410 /* Don't do relocation */
1412 goto FailRelocate;
1413 }
1414
1415 /* Change the protection to prepare for relocation */
1416 Status = LdrpSetProtection(ViewBase, FALSE);
1417
1418 /* Make sure we changed the protection */
1419 if (NT_SUCCESS(Status))
1420 {
1421 /* Do the relocation */
1424
1425 if (NT_SUCCESS(Status))
1426 {
1427 /* Stuff the image name in the TIB, for the debugger */
1428 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
1430#if 0
1431 /* Map the DLL */
1432 Status = NtMapViewOfSection(SectionHandle,
1434 &ViewBase,
1435 0,
1436 0,
1437 NULL,
1438 &ViewSize,
1439 ViewShare,
1440 0,
1442#endif
1443 /* Restore */
1444 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
1445
1446 /* Return the protection */
1447 Status = LdrpSetProtection(ViewBase, TRUE);
1448 }
1449 }
1450FailRelocate:
1451 /* Handle any kind of failure */
1452 if (!NT_SUCCESS(Status))
1453 {
1454 /* Remove it from the lists */
1457 RemoveEntryList(&LdrEntry->HashLinks);
1458
1459 /* Unmap it, clear the entry */
1461 LdrEntry = NULL;
1462 }
1463
1464 /* Show debug message */
1465 if (ShowSnaps)
1466 {
1467 DPRINT1("LDR: Fixups %successfully re-applied @ %p\n",
1468 NT_SUCCESS(Status) ? "s" : "uns", ViewBase);
1469 }
1470 }
1471 else
1472 {
1473NoRelocNeeded:
1474 /* Not a DLL, or no relocation needed */
1476
1477 /* Stuff the image name in the TIB, for the debugger */
1478 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
1480#if 0
1481 /* Map the DLL */
1482 Status = NtMapViewOfSection(SectionHandle,
1484 &ViewBase,
1485 0,
1486 0,
1487 NULL,
1488 &ViewSize,
1489 ViewShare,
1490 0,
1492#endif
1493 /* Restore */
1494 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
1495
1496 /* Show debug message */
1497 if (ShowSnaps)
1498 {
1499 DPRINT1("LDR: Fixups won't be re-applied to non-Dll @ %p\n", ViewBase);
1500 }
1501 }
1502 }
1503
1504 // FIXME: LdrpCheckCorImage() is missing
1505
1506 /* Check if this is an SMP Machine and a DLL */
1507 if ((LdrpNumberOfProcessors > 1) &&
1508 (LdrEntry && (LdrEntry->Flags & LDRP_IMAGE_DLL)))
1509 {
1510 /* Validate the image for MP */
1511 LdrpValidateImageForMp(LdrEntry);
1512 }
1513
1514 // FIXME: LdrpCorUnloadImage() is missing
1515
1516 /* Close section and return status */
1517 NtClose(SectionHandle);
1518 return Status;
1519}
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:3622
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:58
#define LDRP_IMAGE_NOT_AT_BASE
Definition: ldrtypes.h:51
#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:1556
NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase, BOOLEAN Restore)
Definition: ldrutils.c:921
PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
Definition: ldrutils.c:1523
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:1539
#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:138
LIST_ENTRY HashLinks
Definition: ldrtypes.h:151
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:167
#define SearchPath
Definition: winbase.h:3900

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 1641 of file ldrutils.c.

1645{
1647// RTL_PATH_TYPE PathType;
1648// BOOLEAN InvalidName;
1649 ULONG Length;
1650
1651 /* Display debug output if snaps are on */
1652 if (ShowSnaps)
1653 {
1656 "LDR: %s - Expanding full name of %wZ\n",
1658 OriginalName);
1659 }
1660
1661 /* FIXME: Lock the PEB */
1662 //RtlEnterCriticalSection(&FastPebLock);
1663#if 0
1664 /* Get the path name */
1665 Length = RtlGetFullPathName_Ustr(OriginalName,
1666 PathName->Length,
1667 PathName->Buffer,
1668 NULL,
1669 &InvalidName,
1670 &PathType);
1671#else
1672 Length = 0;
1673#endif
1675 {
1676 /* Fail */
1678 goto Quickie;
1679 }
1680
1681 /* Check if the length hasn't changed */
1682 if (Length <= PathName->Length)
1683 {
1684 /* Return the same thing */
1685 *ExpandedName = PathName;
1686 PathName->Length = (USHORT)Length;
1687 goto Quickie;
1688 }
1689
1690 /* Sanity check */
1691 ASSERT(Length >= sizeof(WCHAR));
1692
1693 /* Allocate a string */
1694 Status = LdrpAllocateUnicodeString(FullPathName, Length - sizeof(WCHAR));
1695 if (!NT_SUCCESS(Status)) goto Quickie;
1696
1697 /* Now get the full path again */
1698#if 0
1699 Length = RtlGetFullPathName_Ustr(OriginalName,
1700 FullPathName->Length,
1701 FullPathName->Buffer,
1702 NULL,
1703 &InvalidName,
1704 &PathType);
1705#else
1706 Length = 0;
1707#endif
1708 if (!(Length) || (Length > FullPathName->Length))
1709 {
1710 /* Fail */
1711 LdrpFreeUnicodeString(FullPathName);
1713 }
1714 else
1715 {
1716 /* Return the expanded name */
1717 *ExpandedName = FullPathName;
1718 FullPathName->Length = (USHORT)Length;
1719 }
1720
1721Quickie:
1722 /* FIXME: Unlock the PEB */
1723 //RtlLeaveCriticalSection(&FastPebLock);
1724
1725 /* Display debug output if snaps are on */
1726 if (ShowSnaps)
1727 {
1728 /* Check which output to use -- failure or success */
1729 if (NT_SUCCESS(Status))
1730 {
1733 "LDR: %s - Expanded to %wZ\n",
1735 *ExpandedName);
1736 }
1737 else
1738 {
1741 "LDR: %s - Failed to expand %wZ; 0x%08x\n",
1743 OriginalName,
1744 Status);
1745 }
1746 }
1747
1748 /* If we failed, return NULL */
1749 if (!NT_SUCCESS(Status)) *ExpandedName = NULL;
1750
1751 /* Return status */
1752 return Status;
1753}
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 2717 of file ldrutils.c.

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

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 1757 of file ldrutils.c.

1762{
1764 PWCHAR ActualSearchPath = *SearchPath;
1765 UNICODE_STRING TestName;
1767 PWCHAR Buffer, BufEnd = NULL;
1768 ULONG Length = 0;
1769 WCHAR p;
1770 //PWCHAR pp;
1771
1772 /* Check if we don't have a search path */
1773 if (!ActualSearchPath) *SearchPath = LdrpDefaultPath.Buffer;
1774
1775 /* Display debug output if snaps are on */
1776 if (ShowSnaps)
1777 {
1780 "LDR: %s - Looking for %ws in %ws\n",
1782 DllName,
1783 *SearchPath);
1784 }
1785
1786 /* Check if we're dealing with a relative path */
1788 {
1789 /* Good, we're not. Create the name string */
1790 Status = RtlInitUnicodeStringEx(&TestName, DllName);
1791 if (!NT_SUCCESS(Status)) goto Quickie;
1792
1793 /* Make sure it exists */
1794 #if 0
1795 if (!RtlDoesFileExists_UstrEx(&TestName, TRUE))
1796 {
1797 /* It doesn't, fail */
1799 goto Quickie;
1800 }
1801 #endif
1802
1803 /* Resolve the full name */
1804 Status = LdrpResolveFullName(&TestName,
1805 PathName,
1806 FullPathName,
1807 ExpandedName);
1808 goto Quickie;
1809 }
1810
1811 /* FIXME: Handle relative case semicolon-lookup here */
1812
1813 /* Calculate length */
1814 Length += (ULONG)wcslen(DllName) + 1;
1816 {
1817 /* Too long, fail */
1819 goto Quickie;
1820 }
1821
1822 /* Allocate buffer */
1823 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
1824 if (!Buffer)
1825 {
1826 /* Fail */
1828 goto Quickie;
1829 }
1830
1831 /* FIXME: Setup TestName here */
1833 BufEnd = Buffer;
1834
1835 /* Start loop */
1836 do
1837 {
1838 /* Get character */
1839 p = *ActualSearchPath;
1840 if (!(p) || (p == ';'))
1841 {
1842 /* FIXME: We don't have a character, or is a semicolon.*/
1843
1844 /* Display debug output if snaps are on */
1845 if (ShowSnaps)
1846 {
1849 "LDR: %s - Looking for %ws\n",
1851 Buffer);
1852 }
1853
1854 /* Sanity check */
1855 TestName.Length = (USHORT)ALIGN_DOWN((BufEnd - Buffer), WCHAR);
1856#if 0
1857 ASSERT(TestName.Length < TestName.MaximumLength);
1858#endif
1859
1860 /* Check if the file exists */
1861 #if 0
1862 if (RtlDoesFileExists_UstrEx(&TestName, FALSE))
1863 #endif
1864 {
1865 /* It does. Reallocate the buffer */
1866 TestName.MaximumLength = (USHORT)ALIGN_DOWN((BufEnd - Buffer), WCHAR) + sizeof(WCHAR);
1867 TestName.Buffer = RtlReAllocateHeap(RtlGetProcessHeap(),
1868 0,
1869 Buffer,
1870 TestName.MaximumLength);
1871 if (!TestName.Buffer)
1872 {
1873 /* Keep the old one */
1874 TestName.Buffer = Buffer;
1875 }
1876 else
1877 {
1878 /* Update buffer */
1879 Buffer = TestName.Buffer;
1880 }
1881
1882 /* Make sure we have a buffer at least */
1883 ASSERT(TestName.Buffer);
1884
1885 /* Resolve the name */
1886 *SearchPath = ActualSearchPath++;
1887 Status = LdrpResolveFullName(&TestName,
1888 PathName,
1889 FullPathName,
1890 ExpandedName);
1891 break;
1892 }
1893
1894 /* Update buffer end */
1895 BufEnd = Buffer;
1896
1897 /* Update string position */
1898 //pp = ActualSearchPath++;
1899 }
1900 else
1901 {
1902 /* Otherwise, write the character */
1903 *BufEnd = p;
1904 BufEnd++;
1905 }
1906
1907 /* Check if the string is empty, meaning we're done */
1908 if (!(*ActualSearchPath)) TryAgain = TRUE;
1909
1910 /* Advance in the string */
1911 ActualSearchPath++;
1912 } while (!TryAgain);
1913
1914 /* Check if we had a buffer and free it */
1915 if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
1916
1917Quickie:
1918 /* Check if we got here through failure */
1919 if (!NT_SUCCESS(Status)) *ExpandedName = NULL;
1920
1921 /* Display debug output if snaps are on */
1922 if (ShowSnaps)
1923 {
1924 /* Check which output to use -- failure or success */
1925 if (NT_SUCCESS(Status))
1926 {
1929 "LDR: %s - Returning %wZ\n",
1931 *ExpandedName);
1932 }
1933 else
1934 {
1937 "LDR: %s - Unable to locate %ws in %ws: 0x%08x\n",
1939 DllName,
1940 ActualSearchPath,
1941 Status);
1942 }
1943 }
1944
1945 /* Return status */
1946 return Status;
1947}
@ 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:2667
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:1641
NTSYSAPI RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_U(_In_ PCWSTR Path)
@ RtlPathTypeRelative
Definition: rtltypes.h:476
#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 2777 of file ldrutils.c.

2778{
2779 /* Make sure we do not call into the shim engine anymore */
2784}
#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:43
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:247
#define LDRP_LOAD_IN_PROGRESS
Definition: ldrtypes.h:42
#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().