ReactOS 0.4.15-dev-7924-g5949c20
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 1549 of file ldrutils.c.

1550{
1551 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
1552 PIMAGE_NT_HEADERS NtHeader;
1553
1554 /* Make sure the header is valid */
1555 NtHeader = RtlImageNtHeader(BaseAddress);
1556 DPRINT("LdrpAllocateDataTableEntry(%p), NtHeader %p\n", BaseAddress, NtHeader);
1557
1558 if (NtHeader)
1559 {
1560 /* Allocate an entry */
1561 LdrEntry = RtlAllocateHeap(LdrpHeap,
1563 sizeof(LDR_DATA_TABLE_ENTRY));
1564
1565 /* Make sure we got one */
1566 if (LdrEntry)
1567 {
1568 /* Set it up */
1569 LdrEntry->DllBase = BaseAddress;
1570 LdrEntry->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
1571 LdrEntry->TimeDateStamp = NtHeader->FileHeader.TimeDateStamp;
1572 LdrEntry->PatchInformation = NULL;
1573 }
1574 }
1575
1576 /* Return the entry */
1577 return LdrEntry;
1578}
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 473 of file ldrutils.c.

475{
476 PIMAGE_TLS_DIRECTORY TlsDirectory;
478 ULONG Size;
479
480 /* Get the TLS Directory */
481 TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
482 TRUE,
484 &Size);
485
486 /* Protect against invalid pointers */
488 {
489 /* Make sure it's valid */
490 if (TlsDirectory)
491 {
492 /* Get the array */
493 Array = (PIMAGE_TLS_CALLBACK *)TlsDirectory->AddressOfCallBacks;
494 if (Array)
495 {
496 /* Display debug */
497 if (ShowSnaps)
498 {
499 DPRINT1("LDR: Tls Callbacks Found. Imagebase %p Tls %p CallBacks %p\n",
500 LdrEntry->DllBase, TlsDirectory, Array);
501 }
502
503 /* Loop the array */
504 while (*Array)
505 {
506 /* Get the TLS Entrypoint */
507 Callback = *Array++;
508
509 /* Display debug */
510 if (ShowSnaps)
511 {
512 DPRINT1("LDR: Calling Tls Callback Imagebase %p Function %p\n",
513 LdrEntry->DllBase, Callback);
514 }
515
516 /* Call it */
518 LdrEntry->DllBase,
519 Reason,
520 NULL);
521 }
522 }
523 }
524 }
526 {
527 DPRINT1("LDR: Exception 0x%x during Tls Callback(%u) for %wZ\n",
528 _SEH2_GetExceptionCode(), Reason, &LdrEntry->BaseDllName);
529 }
530 _SEH2_END;
531}
#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 814 of file ldrutils.c.

818{
820 HANDLE Section = NULL;
821 UNICODE_STRING DllNameUnic;
823 PCHAR p1;
824 PWCHAR p2;
825
826 /* Zero initialize provided parameters */
827 if (SectionHandle) *SectionHandle = 0;
828
829 if (FullDllName)
830 {
831 FullDllName->Length = 0;
832 FullDllName->MaximumLength = 0;
833 FullDllName->Buffer = NULL;
834 }
835
836 if (BaseDllName)
837 {
838 BaseDllName->Length = 0;
839 BaseDllName->MaximumLength = 0;
840 BaseDllName->Buffer = NULL;
841 }
842
843 /* If any of these three params are missing then fail */
844 if (!SectionHandle || !FullDllName || !BaseDllName)
846
847 /* Check the Loader Lock */
849
850 /* Upgrade DllName to a unicode string */
851 RtlInitUnicodeString(&DllNameUnic, DllName);
852
853 /* FIXME: Missing RtlComputePrivatizedDllName_U related functionality */
854
855 /* Get the activation context */
857 NULL,
858 ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
859 &DllNameUnic,
860 NULL);
861
862 /* Check if it's a SxS or not */
865 {
866 /* NOTE: Here it's beneficial to allocate one big unicode string
867 using LdrpAllocateUnicodeString instead of fragmenting the heap
868 with two allocations as it's done now. */
869
870 /* Set up BaseDllName */
871 BaseDllName->Length = DllNameUnic.Length;
872 BaseDllName->MaximumLength = DllNameUnic.MaximumLength;
873 BaseDllName->Buffer = RtlAllocateHeap(LdrpHeap,
874 0,
875 DllNameUnic.MaximumLength);
876 if (!BaseDllName->Buffer)
877 {
879 goto Failure;
880 }
881
882 /* Copy the contents there */
883 RtlMoveMemory(BaseDllName->Buffer, DllNameUnic.Buffer, DllNameUnic.MaximumLength);
884
885 /* Set up FullDllName */
886 FullDllName->Length = LdrpKnownDllPath.Length + BaseDllName->Length + sizeof(WCHAR);
887 FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
888 FullDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, FullDllName->MaximumLength);
889 if (!FullDllName->Buffer)
890 {
892 goto Failure;
893 }
894
896
897 /* Put a slash there */
899 p2 = (PWCHAR)p1;
900 *p2++ = (WCHAR)'\\';
901 p1 = (PCHAR)p2;
902
903 /* Set up DllNameUnic for a relative path */
904 DllNameUnic.Buffer = (PWSTR)p1;
905 DllNameUnic.Length = BaseDllName->Length;
906 DllNameUnic.MaximumLength = DllNameUnic.Length + sizeof(UNICODE_NULL);
907
908 /* Copy the contents */
909 RtlMoveMemory(p1, BaseDllName->Buffer, BaseDllName->MaximumLength);
910
911 /* There are all names, init attributes and open the section */
913 &DllNameUnic,
916 NULL);
917
918 Status = NtOpenSection(&Section,
921 if (!NT_SUCCESS(Status))
922 {
923 /* Clear status in case it was just not found */
925 goto Failure;
926 }
927
928 /* Pass section handle to the caller and return success */
929 *SectionHandle = Section;
930 return STATUS_SUCCESS;
931 }
932
933Failure:
934 /* Close section object if it was opened */
935 if (Section) NtClose(Section);
936
937 /* Free string resources */
938 if (BaseDllName->Buffer) RtlFreeHeap(LdrpHeap, 0, BaseDllName->Buffer);
939 if (FullDllName->Buffer) RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
940
941 /* Return status */
942 return Status;
943}
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:5815
_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 1979 of file ldrutils.c.

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

1623{
1624 PLDR_DATA_TABLE_ENTRY Current;
1625 PLIST_ENTRY ListHead, Next;
1626
1627 /* Check the cache first */
1630 {
1631 /* We got lucky, return the cached entry */
1632 *LdrEntry = LdrpLoadedDllHandleCache;
1633 return TRUE;
1634 }
1635
1636 /* Time for a lookup */
1637 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1638 Next = ListHead->Flink;
1639 while (Next != ListHead)
1640 {
1641 /* Get the current entry */
1642 Current = CONTAINING_RECORD(Next,
1644 InLoadOrderLinks);
1645
1646 /* Make sure it's not unloading and check for a match */
1647 if ((Current->InMemoryOrderLinks.Flink) && (Base == Current->DllBase))
1648 {
1649 /* Save in cache */
1650 LdrpLoadedDllHandleCache = Current;
1651
1652 /* Return it */
1653 *LdrEntry = Current;
1654 return TRUE;
1655 }
1656
1657 /* Move to the next one */
1658 Next = Next->Flink;
1659 }
1660
1661 /* Nothing found */
1662 return FALSE;
1663}
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 2670 of file ldrutils.c.

2671{
2672 PLIST_ENTRY ListHead, Entry;
2673 PLDR_DATA_TABLE_ENTRY LdrEntry;
2674 ULONG ModulesCount = 0;
2675
2676 /* Traverse the init list */
2677 ListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
2678 Entry = ListHead->Flink;
2679 while (Entry != ListHead)
2680 {
2681 /* Get the loader entry */
2682 LdrEntry = CONTAINING_RECORD(Entry,
2684 InInitializationOrderLinks);
2685
2686 /* Clear load in progress flag */
2687 LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
2688
2689 /* Check for modules with entry point count but not processed yet */
2690 if ((LdrEntry->EntryPoint) &&
2691 !(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
2692 {
2693 /* Increase counter */
2694 ModulesCount++;
2695 }
2696
2697 /* Advance to the next entry */
2698 Entry = Entry->Flink;
2699 }
2700
2701 /* Return final count */
2702 return ModulesCount;
2703}
#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 535 of file ldrutils.c.

537{
538 /* Not implemented */
539 return STATUS_SUCCESS;
540}

Referenced by LdrpCreateDllSection().

◆ LdrpCreateDllSection()

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

Definition at line 544 of file ldrutils.c.

548{
553 ULONG_PTR HardErrorParameters[1];
555 SECTION_IMAGE_INFORMATION SectionImageInfo;
556
557 /* Check if we don't already have a handle */
558 if (!DllHandle)
559 {
560 /* Create the object attributes */
562 FullName,
564 NULL,
565 NULL);
566
567 /* Open the DLL */
574
575 /* Check if we failed */
576 if (!NT_SUCCESS(Status))
577 {
578 /* Attempt to open for execute only */
585
586 /* Check if this failed too */
587 if (!NT_SUCCESS(Status))
588 {
589 /* Show debug message */
590 if (ShowSnaps)
591 {
592 DPRINT1("LDR: LdrpCreateDllSection - NtOpenFile failed; status = %x\n",
593 Status);
594 }
595
596 /* Make sure to return an expected status code */
598 {
599 /* Callers expect this instead */
601 }
602
603 /* Return an empty section handle */
604 *SectionHandle = NULL;
605 return Status;
606 }
607 }
608 }
609 else
610 {
611 /* Use the handle we already have */
612 FileHandle = DllHandle;
613 }
614
615 /* Create a section for the DLL */
616 Status = NtCreateSection(SectionHandle,
619 NULL,
620 NULL,
622 SEC_IMAGE,
623 FileHandle);
624
625 /* If mapping failed, raise a hard error */
626 if (!NT_SUCCESS(Status))
627 {
628 /* Forget the handle */
629 *SectionHandle = NULL;
630
631 /* Give the DLL name */
632 HardErrorParameters[0] = (ULONG_PTR)FullName;
633
634 /* Raise the error */
636 1,
637 1,
638 HardErrorParameters,
639 OptionOk,
640 &Response);
641
642 /* Increment the error count */
644
645 goto Exit;
646 }
647
648 /* Check for Safer restrictions */
649 if (!DllCharacteristics ||
650 !(*DllCharacteristics & IMAGE_FILE_SYSTEM))
651 {
652 /* Make sure it's executable */
653 Status = ZwQuerySection(*SectionHandle,
655 &SectionImageInfo,
657 NULL);
658 if (NT_SUCCESS(Status))
659 {
660 /* Bypass the check for .NET images */
661 if (!(SectionImageInfo.LoaderFlags & IMAGE_LOADER_FLAGS_COMPLUS))
662 {
663 /* Check with Safer */
666 {
667 /* Show debug message */
668 if (ShowSnaps)
669 {
670 DPRINT1("LDR: Loading of (%wZ) blocked by Winsafer\n",
671 &FullName);
672 }
673
674 /* Failure case, close section handle */
675 NtClose(*SectionHandle);
676 *SectionHandle = NULL;
677 }
678 }
679 }
680 else
681 {
682 /* Failure case, close section handle */
683 NtClose(*SectionHandle);
684 *SectionHandle = NULL;
685 }
686 }
687
688Exit:
689 /* Close the file handle, we don't need it */
691
692 /* Return status */
693 return Status;
694}
#define ULONG_PTR
Definition: config.h:101
NTSTATUS NTAPI LdrpCodeAuthzCheckDllAllowed(IN PUNICODE_STRING FullName, IN HANDLE DllHandle)
Definition: ldrutils.c:535
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 793 of file ldrutils.c.

794{
795 PIMAGE_NT_HEADERS NtHeaders;
796 ULONG_PTR EntryPoint = 0;
797
798 /* Get entry point offset from NT headers */
799 NtHeaders = RtlImageNtHeader(ImageBase);
800 if (NtHeaders)
801 {
802 /* Add image base */
803 EntryPoint = NtHeaders->OptionalHeader.AddressOfEntryPoint;
804 if (EntryPoint) EntryPoint += (ULONG_PTR)ImageBase;
805 }
806
807 /* Return calculated pointer (or zero in case of failure) */
808 return (PVOID)EntryPoint;
809}

Referenced by LdrpMapDll().

◆ LdrpFinalizeAndDeallocateDataTableEntry()

VOID NTAPI LdrpFinalizeAndDeallocateDataTableEntry ( IN PLDR_DATA_TABLE_ENTRY  Entry)

Definition at line 1598 of file ldrutils.c.

1599{
1600 /* Sanity check */
1601 ASSERT(Entry != NULL);
1602
1603 /* Release the activation context if it exists and wasn't already released */
1604 if ((Entry->EntryPointActivationContext) &&
1605 (Entry->EntryPointActivationContext != INVALID_HANDLE_VALUE))
1606 {
1607 /* Mark it as invalid */
1608 RtlReleaseActivationContext(Entry->EntryPointActivationContext);
1609 Entry->EntryPointActivationContext = INVALID_HANDLE_VALUE;
1610 }
1611
1612 /* Release the full dll name string */
1613 if (Entry->FullDllName.Buffer) LdrpFreeUnicodeString(&Entry->FullDllName);
1614
1615 /* Finally free the entry's memory */
1617}
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
NTSYSAPI void WINAPI RtlReleaseActivationContext(HANDLE)
Definition: actctx.c:5344
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 2252 of file ldrutils.c.

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

2706{
2709 PVOID Address;
2711 /* Skip Dll init */
2713 return NT_SUCCESS(Status) ? Address : NULL;
2714}
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:2252
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 2718 of file ldrutils.c.

2719{
2722 PVOID SE_InstallBeforeInit = LdrpGetShimEngineFunction("SE_InstallBeforeInit");
2723 PVOID SE_InstallAfterInit = LdrpGetShimEngineFunction("SE_InstallAfterInit");
2724 PVOID SE_ProcessDying = LdrpGetShimEngineFunction("SE_ProcessDying");
2725
2727 {
2734 }
2735 else
2736 {
2738 }
2739}
VOID NTAPI LdrpUnloadShimEngine()
Definition: ldrutils.c:2803
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:2705
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 1582 of file ldrutils.c.

1583{
1584 PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr;
1585 ULONG i;
1586
1587 /* Insert into hash table */
1588 i = LDR_GET_HASH_ENTRY(LdrEntry->BaseDllName.Buffer[0]);
1589 InsertTailList(&LdrpHashTable[i], &LdrEntry->HashLinks);
1590
1591 /* Insert into other lists */
1592 InsertTailList(&PebData->InLoadOrderModuleList, &LdrEntry->InLoadOrderLinks);
1593 InsertTailList(&PebData->InMemoryOrderModuleList, &LdrEntry->InMemoryOrderLinks);
1594}
#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 2435 of file ldrutils.c.

2441{
2442 PPEB Peb = NtCurrentPeb();
2444 const WCHAR *p;
2445 BOOLEAN GotExtension;
2446 WCHAR c;
2447 WCHAR NameBuffer[MAX_PATH + 6];
2448 UNICODE_STRING RawDllName;
2449 PLDR_DATA_TABLE_ENTRY LdrEntry;
2450 BOOLEAN InInit = LdrpInLdrInit;
2451
2452 /* Save the Raw DLL Name */
2453 if (DllName->Length >= sizeof(NameBuffer)) return STATUS_NAME_TOO_LONG;
2454 RtlInitEmptyUnicodeString(&RawDllName, NameBuffer, sizeof(NameBuffer));
2455 RtlCopyUnicodeString(&RawDllName, DllName);
2456
2457 /* Find the extension, if present */
2458 /* NOTE: Access violation is expected here in some cases (Buffer[-1]) */
2459 p = DllName->Buffer + DllName->Length / sizeof(WCHAR) - 1;
2460 GotExtension = FALSE;
2461 while (p >= DllName->Buffer)
2462 {
2463 c = *p--;
2464 if (c == L'.')
2465 {
2466 GotExtension = TRUE;
2467 break;
2468 }
2469 else if (c == L'\\')
2470 {
2471 break;
2472 }
2473 }
2474
2475 /* If no extension was found, add the default extension */
2476 if (!GotExtension)
2477 {
2478 /* Check that we have space to add one */
2479 if ((DllName->Length + LdrApiDefaultExtension.Length + sizeof(UNICODE_NULL)) >=
2480 sizeof(NameBuffer))
2481 {
2482 /* No space to add the extension */
2485 "LDR: %s - Dll name missing extension; with extension "
2486 "added the name is too long\n"
2487 " DllName: (@ %p) \"%wZ\"\n"
2488 " DllName->Length: %u\n",
2490 DllName,
2491 DllName,
2492 DllName->Length);
2493 return STATUS_NAME_TOO_LONG;
2494 }
2495
2496 /* Add it. Needs to be null terminated, thus the length check above */
2499 }
2500
2501 /* Check for init flag and acquire lock */
2503
2504 _SEH2_TRY
2505 {
2506 /* Show debug message */
2507 if (ShowSnaps)
2508 {
2509 DPRINT1("LDR: LdrLoadDll, loading %wZ from %ws\n",
2510 &RawDllName,
2511 DllPath ? DllPath : L"");
2512 }
2513
2514 /* Check if the DLL is already loaded */
2516 &RawDllName,
2517 FALSE,
2518 Redirected,
2519 &LdrEntry))
2520 {
2521 /* Map it */
2523 DllPath,
2524 NameBuffer,
2525 DllCharacteristics,
2526 FALSE,
2527 Redirected,
2528 &LdrEntry);
2529 if (!NT_SUCCESS(Status))
2531
2532 /* FIXME: Need to mark the DLL range for the stack DB */
2533 //RtlpStkMarkDllRange(LdrEntry);
2534
2535 /* Check if IMAGE_FILE_EXECUTABLE_IMAGE was provided */
2536 if ((DllCharacteristics) &&
2537 (*DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
2538 {
2539 /* This is not a DLL, so remove such data */
2540 LdrEntry->EntryPoint = NULL;
2541 LdrEntry->Flags &= ~LDRP_IMAGE_DLL;
2542 }
2543
2544 /* Make sure it's a DLL */
2545 if (LdrEntry->Flags & LDRP_IMAGE_DLL)
2546 {
2547 /* Check if this is a .NET Image */
2548 if (!(LdrEntry->Flags & LDRP_COR_IMAGE))
2549 {
2550 /* Walk the Import Descriptor */
2552 }
2553
2554 /* Update load count, unless it's locked */
2555 if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
2557
2558 /* Check if we failed */
2559 if (!NT_SUCCESS(Status))
2560 {
2561 /* Clear entrypoint, and insert into list */
2562 LdrEntry->EntryPoint = NULL;
2564 &LdrEntry->InInitializationOrderLinks);
2565
2566 /* Cancel the load */
2568
2569 /* Unload the DLL */
2570 if (ShowSnaps)
2571 {
2572 DbgPrint("LDR: Unloading %wZ due to error %x walking "
2573 "import descriptors\n",
2574 DllName,
2575 Status);
2576 }
2577 LdrUnloadDll(LdrEntry->DllBase);
2578
2579 /* Return the error */
2581 }
2582 }
2583 else if (LdrEntry->LoadCount != 0xFFFF)
2584 {
2585 /* Increase load count */
2586 LdrEntry->LoadCount++;
2587 }
2588
2589 /* Insert it into the list */
2591 &LdrEntry->InInitializationOrderLinks);
2592
2593 /* If we have to run the entrypoint, make sure the DB is ready */
2594 if (CallInit && LdrpLdrDatabaseIsSetup)
2595 {
2596 /* Notify Shim Engine */
2597 if (g_ShimsEnabled)
2598 {
2600 SE_DllLoaded(LdrEntry);
2601 }
2602
2603 /* Run the init routine */
2605 if (!NT_SUCCESS(Status))
2606 {
2607 /* Failed, unload the DLL */
2608 if (ShowSnaps)
2609 {
2610 DbgPrint("LDR: Unloading %wZ because either its init "
2611 "routine or one of its static imports failed; "
2612 "status = 0x%08lx\n",
2613 DllName,
2614 Status);
2615 }
2616 LdrUnloadDll(LdrEntry->DllBase);
2617 }
2618 }
2619 else
2620 {
2621 /* The DB isn't ready, which means we were loaded because of a forwarder */
2623 }
2624 }
2625 else
2626 {
2627 /* We were already loaded. Are we a DLL? */
2628 if ((LdrEntry->Flags & LDRP_IMAGE_DLL) && (LdrEntry->LoadCount != 0xFFFF))
2629 {
2630 /* Increase load count */
2631 LdrEntry->LoadCount++;
2633
2634 /* Clear the load in progress */
2636 }
2637 else
2638 {
2639 /* Not a DLL, just increase the load count */
2640 if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
2641 }
2642 }
2643
2644 }
2646 {
2647 /* Release the lock */
2649 }
2650 _SEH2_END;
2651
2652 /* Check for success */
2653 if (NT_SUCCESS(Status))
2654 {
2655 /* Return the base address */
2656 *BaseAddress = LdrEntry->DllBase;
2657 }
2658 else
2659 {
2660 /* Nothing found */
2661 *BaseAddress = NULL;
2662 }
2663
2664 /* Return status */
2665 return Status;
2666}
#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:1331
#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:1023
VOID NTAPI LdrpUpdateLoadCount2(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Flags)
Definition: ldrutils.c:460
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:1979
ULONG NTAPI LdrpClearLoadInProgress(VOID)
Definition: ldrutils.c:2670
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 2778 of file ldrutils.c.

2779{
2780 UNICODE_STRING ShimLibraryName;
2781 PVOID ShimLibrary;
2783 RtlInitUnicodeString(&ShimLibraryName, ImageName);
2784 /* We should NOT pass CallInit = TRUE!
2785 If we do this, other init routines will be called before we get a chance to shim stuff.. */
2786 Status = LdrpLoadDll(FALSE, NULL, NULL, &ShimLibraryName, &ShimLibrary, FALSE);
2787 if (NT_SUCCESS(Status))
2788 {
2789 g_pShimEngineModule = ShimLibrary;
2792 if (g_ShimsEnabled)
2793 {
2796 SE_InstallBeforeInit(ProcessImage, pShimData);
2797 }
2798 }
2799}
#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:2435
VOID NTAPI LdrpRunShimEngineInitRoutine(IN ULONG Reason)
Definition: ldrutils.c:2743
VOID NTAPI LdrpGetShimEngineInterface()
Definition: ldrutils.c:2718
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 1023 of file ldrutils.c.

1030{
1031 PTEB Teb = NtCurrentTeb();
1032 PPEB Peb = NtCurrentPeb();
1033 PWCHAR p1 = DllName;
1034 WCHAR TempChar;
1035 BOOLEAN KnownDll = FALSE;
1036 UNICODE_STRING FullDllName, BaseDllName;
1037 HANDLE SectionHandle = NULL, DllHandle = 0;
1038 UNICODE_STRING NtPathDllName;
1039 ULONG_PTR HardErrorParameters[2];
1040 UNICODE_STRING HardErrorDllName, HardErrorDllPath;
1042 SIZE_T ViewSize = 0;
1043 PVOID ViewBase = NULL;
1044 PVOID ArbitraryUserPointer;
1045 PIMAGE_NT_HEADERS NtHeaders;
1046 NTSTATUS HardErrorStatus, Status;
1047 BOOLEAN OverlapDllFound = FALSE;
1048 ULONG_PTR ImageBase, ImageEnd;
1049 PLIST_ENTRY ListHead, NextEntry;
1050 PLDR_DATA_TABLE_ENTRY CandidateEntry, LdrEntry;
1051 ULONG_PTR CandidateBase, CandidateEnd;
1052 UNICODE_STRING OverlapDll;
1053 BOOLEAN RelocatableDll = TRUE;
1054 UNICODE_STRING IllegalDll;
1055 PVOID RelocData;
1056 ULONG RelocDataSize = 0;
1057
1058 // FIXME: AppCompat stuff is missing
1059
1060 if (ShowSnaps)
1061 {
1062 DPRINT1("LDR: LdrpMapDll: Image Name %ws, Search Path %ws\n",
1063 DllName,
1064 SearchPath ? SearchPath : L"");
1065 }
1066
1067 /* Check if we have a known dll directory */
1068 if (LdrpKnownDllObjectDirectory && Redirect == FALSE)
1069 {
1070 /* Check if the path is full */
1071 while (*p1)
1072 {
1073 TempChar = *p1++;
1074 if (TempChar == '\\' || TempChar == '/' )
1075 {
1076 /* Complete path, don't do Known Dll lookup */
1077 goto SkipCheck;
1078 }
1079 }
1080
1081 /* Try to find a Known DLL */
1082 Status = LdrpCheckForKnownDll(DllName,
1083 &FullDllName,
1084 &BaseDllName,
1085 &SectionHandle);
1086
1088 {
1089 /* Failure */
1092 "LDR: %s - call to LdrpCheckForKnownDll(\"%ws\", ...) failed with status %x\n",
1094 DllName,
1095 Status);
1096
1097 return Status;
1098 }
1099 }
1100
1101SkipCheck:
1102
1103 /* Check if the Known DLL Check returned something */
1104 if (!SectionHandle)
1105 {
1106 /* It didn't, so try to resolve the name now */
1108 DllName,
1109 &FullDllName,
1110 &BaseDllName))
1111 {
1112 /* Got a name, display a message */
1113 if (ShowSnaps)
1114 {
1115 DPRINT1("LDR: Loading (%s) %wZ\n",
1116 Static ? "STATIC" : "DYNAMIC",
1117 &FullDllName);
1118 }
1119
1120 /* Convert to NT Name */
1122 &NtPathDllName,
1123 NULL,
1124 NULL))
1125 {
1126 /* Path was invalid */
1128 }
1129
1130 /* Create a section for this dLL */
1131 Status = LdrpCreateDllSection(&NtPathDllName,
1132 DllHandle,
1133 DllCharacteristics,
1134 &SectionHandle);
1135
1136 /* Free the NT Name */
1137 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathDllName.Buffer);
1138
1139 /* If we failed */
1140 if (!NT_SUCCESS(Status))
1141 {
1142 /* Free the name strings and return */
1144 LdrpFreeUnicodeString(&BaseDllName);
1145 return Status;
1146 }
1147 }
1148 else
1149 {
1150 /* We couldn't resolve the name, is this a static load? */
1151 if (Static)
1152 {
1153 /*
1154 * This is BAD! Static loads are CRITICAL. Bugcheck!
1155 * Initialize the strings for the error
1156 */
1157 RtlInitUnicodeString(&HardErrorDllName, DllName);
1158 RtlInitUnicodeString(&HardErrorDllPath,
1159 DllPath2 ? DllPath2 : LdrpDefaultPath.Buffer);
1160
1161 /* Set them as error parameters */
1162 HardErrorParameters[0] = (ULONG_PTR)&HardErrorDllName;
1163 HardErrorParameters[1] = (ULONG_PTR)&HardErrorDllPath;
1164
1165 /* Raise the hard error */
1167 2,
1168 0x00000003,
1169 HardErrorParameters,
1170 OptionOk,
1171 &Response);
1172
1173 /* We're back, where we initializing? */
1175 }
1176
1177 /* Return failure */
1178 return STATUS_DLL_NOT_FOUND;
1179 }
1180 }
1181 else
1182 {
1183 /* We have a section handle, so this is a known dll */
1184 KnownDll = TRUE;
1185 }
1186
1187 /* Stuff the image name in the TIB, for the debugger */
1188 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
1190
1191 /* Map the DLL */
1192 ViewBase = NULL;
1193 ViewSize = 0;
1194 Status = NtMapViewOfSection(SectionHandle,
1196 &ViewBase,
1197 0,
1198 0,
1199 NULL,
1200 &ViewSize,
1201 ViewShare,
1202 0,
1204
1205 /* Restore */
1206 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
1207
1208 /* Fail if we couldn't map it */
1209 if (!NT_SUCCESS(Status))
1210 {
1211 /* Close and return */
1212 NtClose(SectionHandle);
1213 return Status;
1214 }
1215
1216 /* Get the NT Header */
1217 if (!(NtHeaders = RtlImageNtHeader(ViewBase)))
1218 {
1219 /* Invalid image, unmap, close handle and fail */
1221 NtClose(SectionHandle);
1223 }
1224
1225 // FIXME: .NET support is missing
1226
1227 /* Allocate an entry */
1228 if (!(LdrEntry = LdrpAllocateDataTableEntry(ViewBase)))
1229 {
1230 /* Invalid image, unmap, close handle and fail */
1232 NtClose(SectionHandle);
1233 return STATUS_NO_MEMORY;
1234 }
1235
1236 /* Setup the entry */
1237 LdrEntry->Flags = Static ? LDRP_STATIC_LINK : 0;
1238 if (Redirect) LdrEntry->Flags |= LDRP_REDIRECTED;
1239 LdrEntry->LoadCount = 0;
1240 LdrEntry->FullDllName = FullDllName;
1241 LdrEntry->BaseDllName = BaseDllName;
1242 LdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(LdrEntry->DllBase);
1243
1244 /* Show debug message */
1245 if (ShowSnaps)
1246 {
1247 DPRINT1("LDR: LdrpMapDll: Full Name %wZ, Base Name %wZ\n",
1248 &FullDllName,
1249 &BaseDllName);
1250 }
1251
1252 /* Insert this entry */
1254
1255 // LdrpSendDllNotifications(LdrEntry, TRUE, Status == STATUS_IMAGE_NOT_AT_BASE)
1256
1257 /* Check for invalid CPU Image */
1259 {
1260 /* Load our header */
1262
1263 /* Assume defaults if we don't have to run the Hard Error path */
1264 HardErrorStatus = STATUS_SUCCESS;
1266
1267 /* Are we an NT 3.0 image? [Do these still exist? LOL -- IAI] */
1269 {
1270 /* Reset the entrypoint, save our Dll Name */
1271 LdrEntry->EntryPoint = 0;
1272 HardErrorParameters[0] = (ULONG_PTR)&FullDllName;
1273
1274 /* Raise the error */
1276 1,
1277 1,
1278 HardErrorParameters,
1280 &Response);
1281 }
1282
1283 /* Check if the user pressed cancel */
1284 if (NT_SUCCESS(HardErrorStatus) && Response == ResponseCancel)
1285 {
1286 /* Remove the DLL from the lists */
1289 RemoveEntryList(&LdrEntry->HashLinks);
1290
1291 /* Remove the LDR Entry */
1292 RtlFreeHeap(LdrpHeap, 0, LdrEntry );
1293
1294 /* Unmap and close section */
1296 NtClose(SectionHandle);
1297
1298 /* Did we do a hard error? */
1300 {
1301 /* Yup, so increase fatal error count if we are initializing */
1303 }
1304
1305 /* Return failure */
1307 }
1308 }
1309 else
1310 {
1311 /* The image was valid. Is it a DLL? */
1312 if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
1313 {
1314 /* Set the DLL Flag */
1315 LdrEntry->Flags |= LDRP_IMAGE_DLL;
1316 }
1317
1318 /* If we're not a DLL, clear the entrypoint */
1319 if (!(LdrEntry->Flags & LDRP_IMAGE_DLL))
1320 {
1321 LdrEntry->EntryPoint = 0;
1322 }
1323 }
1324
1325 /* Return it for the caller */
1326 *DataTableEntry = LdrEntry;
1327
1328 /* Check if we loaded somewhere else */
1330 {
1331 /* Write the flag */
1332 LdrEntry->Flags |= LDRP_IMAGE_NOT_AT_BASE;
1333
1334 /* Find our region */
1335 ImageBase = (ULONG_PTR)NtHeaders->OptionalHeader.ImageBase;
1336 ImageEnd = ImageBase + ViewSize;
1337
1338 DPRINT("LDR: LdrpMapDll Relocating Image Name %ws (%p-%p -> %p)\n", DllName, (PVOID)ImageBase, (PVOID)ImageEnd, ViewBase);
1339
1340 /* Scan all the modules */
1341 ListHead = &Peb->Ldr->InLoadOrderModuleList;
1342 NextEntry = ListHead->Flink;
1343 while (NextEntry != ListHead)
1344 {
1345 /* Get the entry */
1346 CandidateEntry = CONTAINING_RECORD(NextEntry,
1348 InLoadOrderLinks);
1349 NextEntry = NextEntry->Flink;
1350
1351 /* Get the entry's bounds */
1352 CandidateBase = (ULONG_PTR)CandidateEntry->DllBase;
1353 CandidateEnd = CandidateBase + CandidateEntry->SizeOfImage;
1354
1355 /* Make sure this entry isn't unloading */
1356 if (!CandidateEntry->InMemoryOrderLinks.Flink) continue;
1357
1358 /* Check if our regions are colliding */
1359 if ((ImageBase >= CandidateBase && ImageBase <= CandidateEnd) ||
1360 (ImageEnd >= CandidateBase && ImageEnd <= CandidateEnd) ||
1361 (CandidateBase >= ImageBase && CandidateBase <= ImageEnd))
1362 {
1363 /* Found who is overlapping */
1364 OverlapDllFound = TRUE;
1365 OverlapDll = CandidateEntry->FullDllName;
1366 break;
1367 }
1368 }
1369
1370 /* Check if we found the DLL overlapping with us */
1371 if (!OverlapDllFound)
1372 {
1373 /* It's not another DLL, it's memory already here */
1374 RtlInitUnicodeString(&OverlapDll, L"Dynamically Allocated Memory");
1375 }
1376
1377 DPRINT("Overlapping DLL: %wZ\n", &OverlapDll);
1378
1379 /* Are we dealing with a DLL? */
1380 if (LdrEntry->Flags & LDRP_IMAGE_DLL)
1381 {
1382 /* Check if relocs were stripped */
1384 {
1385 /* Get the relocation data */
1386 RelocData = RtlImageDirectoryEntryToData(ViewBase,
1387 TRUE,
1389 &RelocDataSize);
1390
1391 /* Does the DLL not have any? */
1392 if (!RelocData && !RelocDataSize)
1393 {
1394 /* We'll allow this and simply continue */
1395 goto NoRelocNeeded;
1396 }
1397 }
1398
1399 /* See if this is an Illegal DLL - IE: user32 and kernel32 */
1400 RtlInitUnicodeString(&IllegalDll,L"user32.dll");
1401 if (RtlEqualUnicodeString(&BaseDllName, &IllegalDll, TRUE))
1402 {
1403 /* Can't relocate user32 */
1404 RelocatableDll = FALSE;
1405 }
1406 else
1407 {
1408 RtlInitUnicodeString(&IllegalDll, L"kernel32.dll");
1409 if (RtlEqualUnicodeString(&BaseDllName, &IllegalDll, TRUE))
1410 {
1411 /* Can't relocate kernel32 */
1412 RelocatableDll = FALSE;
1413 }
1414 }
1415
1416 /* Known DLLs are not allowed to be relocated */
1417 if (KnownDll && !RelocatableDll)
1418 {
1419 /* Setup for hard error */
1420 HardErrorParameters[0] = (ULONG_PTR)&IllegalDll;
1421 HardErrorParameters[1] = (ULONG_PTR)&OverlapDll;
1422
1423 DPRINT1("Illegal DLL relocation! %wZ overlaps %wZ\n", &OverlapDll, &IllegalDll);
1424
1425 /* Raise the error */
1427 2,
1428 3,
1429 HardErrorParameters,
1430 OptionOk,
1431 &Response);
1432
1433 /* If initializing, increase the error count */
1435
1436 /* Don't do relocation */
1438 goto FailRelocate;
1439 }
1440
1441 /* Change the protection to prepare for relocation */
1442 Status = LdrpSetProtection(ViewBase, FALSE);
1443
1444 /* Make sure we changed the protection */
1445 if (NT_SUCCESS(Status))
1446 {
1447 /* Do the relocation */
1450
1451 if (NT_SUCCESS(Status))
1452 {
1453 /* Stuff the image name in the TIB, for the debugger */
1454 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
1456#if 0
1457 /* Map the DLL */
1458 Status = NtMapViewOfSection(SectionHandle,
1460 &ViewBase,
1461 0,
1462 0,
1463 NULL,
1464 &ViewSize,
1465 ViewShare,
1466 0,
1468#endif
1469 /* Restore */
1470 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
1471
1472 /* Return the protection */
1473 Status = LdrpSetProtection(ViewBase, TRUE);
1474 }
1475 }
1476FailRelocate:
1477 /* Handle any kind of failure */
1478 if (!NT_SUCCESS(Status))
1479 {
1480 /* Remove it from the lists */
1483 RemoveEntryList(&LdrEntry->HashLinks);
1484
1485 /* Unmap it, clear the entry */
1487 LdrEntry = NULL;
1488 }
1489
1490 /* Show debug message */
1491 if (ShowSnaps)
1492 {
1493 DPRINT1("LDR: Fixups %successfully re-applied @ %p\n",
1494 NT_SUCCESS(Status) ? "s" : "uns", ViewBase);
1495 }
1496 }
1497 else
1498 {
1499NoRelocNeeded:
1500 /* Not a DLL, or no relocation needed */
1502
1503 /* Stuff the image name in the TIB, for the debugger */
1504 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
1506#if 0
1507 /* Map the DLL */
1508 Status = NtMapViewOfSection(SectionHandle,
1510 &ViewBase,
1511 0,
1512 0,
1513 NULL,
1514 &ViewSize,
1515 ViewShare,
1516 0,
1518#endif
1519 /* Restore */
1520 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
1521
1522 /* Show debug message */
1523 if (ShowSnaps)
1524 {
1525 DPRINT1("LDR: Fixups won't be re-applied to non-Dll @ %p\n", ViewBase);
1526 }
1527 }
1528 }
1529
1530 // FIXME: LdrpCheckCorImage() is missing
1531
1532 /* Check if this is an SMP Machine and a DLL */
1533 if ((LdrpNumberOfProcessors > 1) &&
1534 (LdrEntry && (LdrEntry->Flags & LDRP_IMAGE_DLL)))
1535 {
1536 /* Validate the image for MP */
1537 LdrpValidateImageForMp(LdrEntry);
1538 }
1539
1540 // FIXME: LdrpCorUnloadImage() is missing
1541
1542 /* Close section and return status */
1543 NtClose(SectionHandle);
1544 return Status;
1545}
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:699
PVOID NTAPI LdrpFetchAddressOfEntryPoint(IN PVOID ImageBase)
Definition: ldrutils.c:793
NTSTATUS NTAPI LdrpCheckForKnownDll(PWSTR DllName, PUNICODE_STRING FullDllName, PUNICODE_STRING BaseDllName, HANDLE *SectionHandle)
Definition: ldrutils.c:814
VOID NTAPI LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrutils.c:1582
NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase, BOOLEAN Restore)
Definition: ldrutils.c:947
PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
Definition: ldrutils.c:1549
NTSTATUS NTAPI LdrpCreateDllSection(IN PUNICODE_STRING FullName, IN HANDLE DllHandle, IN PULONG DllCharacteristics OPTIONAL, OUT PHANDLE SectionHandle)
Definition: ldrutils.c:544
@ 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 699 of file ldrutils.c.

703{
704 PWCHAR NameBuffer, p1, p2 = 0;
706 ULONG BufSize = 500;
707
708 /* Allocate space for full DLL name */
710 if (!FullDllName->Buffer) return FALSE;
711
713 DllName,
714 NULL,
715 BufSize,
716 FullDllName->Buffer,
717 &BaseDllName->Buffer);
718
719 if (!Length || Length > BufSize)
720 {
721 if (ShowSnaps)
722 {
723 DPRINT1("LDR: LdrResolveDllName - Unable to find ");
724 DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer);
725 }
726
728 return FALSE;
729 }
730
731 /* Construct full DLL name */
732 FullDllName->Length = Length;
733 FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
734
735 /* Allocate a new buffer */
736 NameBuffer = RtlAllocateHeap(LdrpHeap, 0, FullDllName->MaximumLength);
737 if (!NameBuffer)
738 {
739 RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
740 return FALSE;
741 }
742
743 /* Copy over the contents from the previous one and free it */
744 RtlCopyMemory(NameBuffer, FullDllName->Buffer, FullDllName->MaximumLength);
745 RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
746 FullDllName->Buffer = NameBuffer;
747
748 /* Find last backslash */
749 p1 = FullDllName->Buffer;
750 while (*p1)
751 {
752 if (*p1++ == L'\\')
753 {
754 p2 = p1;
755 }
756 }
757
758 /* If found, set p1 to it, otherwise p1 points to the beginning of DllName */
759 if (p2)
760 p1 = p2;
761 else
762 p1 = DllName;
763
764 p2 = p1;
765
766 /* Calculate remaining length */
767 while (*p1) ++p1;
768
769 /* Construct base DLL name */
770 BaseDllName->Length = (ULONG_PTR)p1 - (ULONG_PTR)p2;
771 BaseDllName->MaximumLength = BaseDllName->Length + sizeof(UNICODE_NULL);
772 BaseDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, BaseDllName->MaximumLength);
773
774 if (!BaseDllName->Buffer)
775 {
776 RtlFreeHeap(LdrpHeap, 0, NameBuffer);
777 return FALSE;
778 }
779
780 /* Copy base dll name to the new buffer */
781 RtlMoveMemory(BaseDllName->Buffer,
782 p2,
783 BaseDllName->Length);
784
785 /* Null-terminate the string */
786 BaseDllName->Buffer[BaseDllName->Length / sizeof(WCHAR)] = 0;
787
788 return TRUE;
789}
#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 1667 of file ldrutils.c.

1671{
1673// RTL_PATH_TYPE PathType;
1674// BOOLEAN InvalidName;
1675 ULONG Length;
1676
1677 /* Display debug output if snaps are on */
1678 if (ShowSnaps)
1679 {
1682 "LDR: %s - Expanding full name of %wZ\n",
1684 OriginalName);
1685 }
1686
1687 /* FIXME: Lock the PEB */
1688 //RtlEnterCriticalSection(&FastPebLock);
1689#if 0
1690 /* Get the path name */
1691 Length = RtlGetFullPathName_Ustr(OriginalName,
1692 PathName->Length,
1693 PathName->Buffer,
1694 NULL,
1695 &InvalidName,
1696 &PathType);
1697#else
1698 Length = 0;
1699#endif
1701 {
1702 /* Fail */
1704 goto Quickie;
1705 }
1706
1707 /* Check if the length hasn't changed */
1708 if (Length <= PathName->Length)
1709 {
1710 /* Return the same thing */
1711 *ExpandedName = PathName;
1712 PathName->Length = (USHORT)Length;
1713 goto Quickie;
1714 }
1715
1716 /* Sanity check */
1717 ASSERT(Length >= sizeof(WCHAR));
1718
1719 /* Allocate a string */
1720 Status = LdrpAllocateUnicodeString(FullPathName, Length - sizeof(WCHAR));
1721 if (!NT_SUCCESS(Status)) goto Quickie;
1722
1723 /* Now get the full path again */
1724#if 0
1725 Length = RtlGetFullPathName_Ustr(OriginalName,
1726 FullPathName->Length,
1727 FullPathName->Buffer,
1728 NULL,
1729 &InvalidName,
1730 &PathType);
1731#else
1732 Length = 0;
1733#endif
1734 if (!(Length) || (Length > FullPathName->Length))
1735 {
1736 /* Fail */
1737 LdrpFreeUnicodeString(FullPathName);
1739 }
1740 else
1741 {
1742 /* Return the expanded name */
1743 *ExpandedName = FullPathName;
1744 FullPathName->Length = (USHORT)Length;
1745 }
1746
1747Quickie:
1748 /* FIXME: Unlock the PEB */
1749 //RtlLeaveCriticalSection(&FastPebLock);
1750
1751 /* Display debug output if snaps are on */
1752 if (ShowSnaps)
1753 {
1754 /* Check which output to use -- failure or success */
1755 if (NT_SUCCESS(Status))
1756 {
1759 "LDR: %s - Expanded to %wZ\n",
1761 *ExpandedName);
1762 }
1763 else
1764 {
1767 "LDR: %s - Failed to expand %wZ; 0x%08x\n",
1769 OriginalName,
1770 Status);
1771 }
1772 }
1773
1774 /* If we failed, return NULL */
1775 if (!NT_SUCCESS(Status)) *ExpandedName = NULL;
1776
1777 /* Return status */
1778 return Status;
1779}
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 2743 of file ldrutils.c.

2744{
2745 PLIST_ENTRY ListHead, Next;
2746 PLDR_DATA_TABLE_ENTRY LdrEntry;
2747
2748 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
2749 Next = ListHead->Flink;
2750 while (Next != ListHead)
2751 {
2752 LdrEntry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
2753
2754 if (g_pShimEngineModule == LdrEntry->DllBase)
2755 {
2756 if (LdrEntry->EntryPoint)
2757 {
2758 _SEH2_TRY
2759 {
2760 LdrpCallInitRoutine(LdrEntry->EntryPoint, LdrEntry->DllBase, Reason, NULL);
2761 }
2763 {
2764 DPRINT1("WARNING: Exception 0x%x during LdrpRunShimEngineInitRoutine(%u)\n",
2766 }
2767 _SEH2_END;
2768 }
2769 return;
2770 }
2771
2772 Next = Next->Flink;
2773 }
2774}

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

1788{
1790 PWCHAR ActualSearchPath = *SearchPath;
1791 UNICODE_STRING TestName;
1793 PWCHAR Buffer, BufEnd = NULL;
1794 ULONG Length = 0;
1795 WCHAR p;
1796 //PWCHAR pp;
1797
1798 /* Check if we don't have a search path */
1799 if (!ActualSearchPath) *SearchPath = LdrpDefaultPath.Buffer;
1800
1801 /* Display debug output if snaps are on */
1802 if (ShowSnaps)
1803 {
1806 "LDR: %s - Looking for %ws in %ws\n",
1808 DllName,
1809 *SearchPath);
1810 }
1811
1812 /* Check if we're dealing with a relative path */
1814 {
1815 /* Good, we're not. Create the name string */
1816 Status = RtlInitUnicodeStringEx(&TestName, DllName);
1817 if (!NT_SUCCESS(Status)) goto Quickie;
1818
1819 /* Make sure it exists */
1820 #if 0
1821 if (!RtlDoesFileExists_UstrEx(&TestName, TRUE))
1822 {
1823 /* It doesn't, fail */
1825 goto Quickie;
1826 }
1827 #endif
1828
1829 /* Resolve the full name */
1830 Status = LdrpResolveFullName(&TestName,
1831 PathName,
1832 FullPathName,
1833 ExpandedName);
1834 goto Quickie;
1835 }
1836
1837 /* FIXME: Handle relative case semicolon-lookup here */
1838
1839 /* Calculate length */
1840 Length += (ULONG)wcslen(DllName) + 1;
1842 {
1843 /* Too long, fail */
1845 goto Quickie;
1846 }
1847
1848 /* Allocate buffer */
1849 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
1850 if (!Buffer)
1851 {
1852 /* Fail */
1854 goto Quickie;
1855 }
1856
1857 /* FIXME: Setup TestName here */
1859 BufEnd = Buffer;
1860
1861 /* Start loop */
1862 do
1863 {
1864 /* Get character */
1865 p = *ActualSearchPath;
1866 if (!(p) || (p == ';'))
1867 {
1868 /* FIXME: We don't have a character, or is a semicolon.*/
1869
1870 /* Display debug output if snaps are on */
1871 if (ShowSnaps)
1872 {
1875 "LDR: %s - Looking for %ws\n",
1877 Buffer);
1878 }
1879
1880 /* Sanity check */
1881 TestName.Length = (USHORT)ALIGN_DOWN((BufEnd - Buffer), WCHAR);
1882#if 0
1883 ASSERT(TestName.Length < TestName.MaximumLength);
1884#endif
1885
1886 /* Check if the file exists */
1887 #if 0
1888 if (RtlDoesFileExists_UstrEx(&TestName, FALSE))
1889 #endif
1890 {
1891 /* It does. Reallocate the buffer */
1892 TestName.MaximumLength = (USHORT)ALIGN_DOWN((BufEnd - Buffer), WCHAR) + sizeof(WCHAR);
1893 TestName.Buffer = RtlReAllocateHeap(RtlGetProcessHeap(),
1894 0,
1895 Buffer,
1896 TestName.MaximumLength);
1897 if (!TestName.Buffer)
1898 {
1899 /* Keep the old one */
1900 TestName.Buffer = Buffer;
1901 }
1902 else
1903 {
1904 /* Update buffer */
1905 Buffer = TestName.Buffer;
1906 }
1907
1908 /* Make sure we have a buffer at least */
1909 ASSERT(TestName.Buffer);
1910
1911 /* Resolve the name */
1912 *SearchPath = ActualSearchPath++;
1913 Status = LdrpResolveFullName(&TestName,
1914 PathName,
1915 FullPathName,
1916 ExpandedName);
1917 break;
1918 }
1919
1920 /* Update buffer end */
1921 BufEnd = Buffer;
1922
1923 /* Update string position */
1924 //pp = ActualSearchPath++;
1925 }
1926 else
1927 {
1928 /* Otherwise, write the character */
1929 *BufEnd = p;
1930 BufEnd++;
1931 }
1932
1933 /* Check if the string is empty, meaning we're done */
1934 if (!(*ActualSearchPath)) TryAgain = TRUE;
1935
1936 /* Advance in the string */
1937 ActualSearchPath++;
1938 } while (!TryAgain);
1939
1940 /* Check if we had a buffer and free it */
1941 if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
1942
1943Quickie:
1944 /* Check if we got here through failure */
1945 if (!NT_SUCCESS(Status)) *ExpandedName = NULL;
1946
1947 /* Display debug output if snaps are on */
1948 if (ShowSnaps)
1949 {
1950 /* Check which output to use -- failure or success */
1951 if (NT_SUCCESS(Status))
1952 {
1955 "LDR: %s - Returning %wZ\n",
1957 *ExpandedName);
1958 }
1959 else
1960 {
1963 "LDR: %s - Unable to locate %ws in %ws: 0x%08x\n",
1965 DllName,
1966 ActualSearchPath,
1967 Status);
1968 }
1969 }
1970
1971 /* Return status */
1972 return Status;
1973}
@ 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:1667
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 947 of file ldrutils.c.

949{
950 PIMAGE_NT_HEADERS NtHeaders;
951 PIMAGE_SECTION_HEADER Section;
953 PVOID SectionBase;
954 SIZE_T SectionSize;
955 ULONG NewProtection, OldProtection, i;
956
957 /* Get the NT headers */
958 NtHeaders = RtlImageNtHeader(ViewBase);
959 if (!NtHeaders) return STATUS_INVALID_IMAGE_FORMAT;
960
961 /* Compute address of the first section header */
962 Section = IMAGE_FIRST_SECTION(NtHeaders);
963
964 /* Go through all sections */
965 for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
966 {
967 /* Check for read-only non-zero section */
968 if ((Section->SizeOfRawData) &&
970 {
971 /* Check if we are setting or restoring protection */
972 if (Restore)
973 {
974 /* Set it to either EXECUTE or READONLY */
976 {
977 NewProtection = PAGE_EXECUTE;
978 }
979 else
980 {
981 NewProtection = PAGE_READONLY;
982 }
983
984 /* Add PAGE_NOCACHE if needed */
986 {
987 NewProtection |= PAGE_NOCACHE;
988 }
989 }
990 else
991 {
992 /* Enable write access */
993 NewProtection = PAGE_READWRITE;
994 }
995
996 /* Get the section VA */
997 SectionBase = (PVOID)((ULONG_PTR)ViewBase + Section->VirtualAddress);
998 SectionSize = Section->SizeOfRawData;
999 if (SectionSize)
1000 {
1001 /* Set protection */
1003 &SectionBase,
1004 &SectionSize,
1005 NewProtection,
1006 &OldProtection);
1007 if (!NT_SUCCESS(Status)) return Status;
1008 }
1009 }
1010
1011 /* Move to the next section */
1012 Section++;
1013 }
1014
1015 /* Flush instruction cache if necessary */
1016 if (Restore) ZwFlushInstructionCache(NtCurrentProcess(), NULL, 0);
1017 return STATUS_SUCCESS;
1018}
#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 2803 of file ldrutils.c.

2804{
2805 /* Make sure we do not call into the shim engine anymore */
2810}
#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 460 of file ldrutils.c.

462{
464 UNICODE_STRING UpdateString;
465
466 /* Setup the string and call the extended API */
467 RtlInitEmptyUnicodeString(&UpdateString, Buffer, sizeof(Buffer));
468 LdrpUpdateLoadCount3(LdrEntry, Flags, &UpdateString);
469}
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 */
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,
193 UpdateString,
194 NULL,
195 &RedirectedImportName,
196 NULL,
197 NULL,
198 NULL);
199
200 /* Check success */
201 if (NT_SUCCESS(Status))
202 {
203 /* Let Ldrp know */
204 if (ShowSnaps)
205 {
206 DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
207 }
208
209 RedirectedDll = TRUE;
210 }
211
212 if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND)
213 {
215 RedirectedImportName,
216 TRUE,
217 RedirectedDll,
218 &Entry))
219 {
220 if (Entry->LoadCount != 0xFFFF)
221 {
222 /* Perform the required action */
223 switch (Flags)
224 {
226 Entry->LoadCount++;
227 break;
229 Entry->LoadCount--;
230 break;
231 case LDRP_UPDATE_PIN:
232 Entry->LoadCount = 0xFFFF;
233 break;
234 }
235
236 /* Show snaps */
237 if (ShowSnaps)
238 {
239 DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
240 }
241 }
242
243 /* Recurse into this entry */
244 LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
245 }
246 else if (RedirectedDll)
247 {
248 DPRINT1("LDR: LdrpCheckForLoadedDll failed for redirected dll %wZ\n", RedirectedImportName);
249 }
250 }
251 else
252 {
253 /* Unrecoverable SxS failure */
254 DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed with status %x for dll %wZ\n", Status, ImportNameUnic);
255 }
256
257 }
258
259 /* Go through forwarders */
260 NewImportForwarder = (PIMAGE_BOUND_FORWARDER_REF)(BoundEntry + 1);
261 for (i = 0; i < BoundEntry->NumberOfModuleForwarderRefs; i++)
262 {
263 ImportName = (LPSTR)FirstEntry + NewImportForwarder->OffsetModuleName;
264
265 RtlInitAnsiString(&ImportNameAnsi, ImportName);
266 Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
267 if (NT_SUCCESS(Status))
268 {
269 RedirectedDll = FALSE;
270 RedirectedImportName = ImportNameUnic;
271
272 /* Check if the SxS Assemblies specify another file */
274 ImportNameUnic,
276 UpdateString,
277 NULL,
278 &RedirectedImportName,
279 NULL,
280 NULL,
281 NULL);
282 /* Check success */
283 if (NT_SUCCESS(Status))
284 {
285 if (ShowSnaps)
286 {
287 DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
288 }
289 /* Let Ldrp know */
290 RedirectedDll = TRUE;
291 }
292
293 if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND)
294 {
296 RedirectedImportName,
297 TRUE,
298 RedirectedDll,
299 &Entry))
300 {
301 if (Entry->LoadCount != 0xFFFF)
302 {
303 /* Perform the required action */
304 switch (Flags)
305 {
307 Entry->LoadCount++;
308 break;
310 Entry->LoadCount--;
311 break;
312 case LDRP_UPDATE_PIN:
313 Entry->LoadCount = 0xFFFF;
314 break;
315 }
316
317 /* Show snaps */
318 if (ShowSnaps)
319 {
320 DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
321 }
322 }
323
324 /* Recurse into this entry */
325 LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
326 }
327 else if (RedirectedDll)
328 {
329 DPRINT1("LDR: LdrpCheckForLoadedDll failed with status %x for redirected dll %wZ\n", Status, RedirectedImportName);
330 }
331 }
332 else
333 {
334 /* Unrecoverable SxS failure */
335 DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed with status %x for dll %wZ\n", Status, ImportNameUnic);
336 }
337
338 }
339
340 NewImportForwarder++;
341 }
342
343 BoundEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewImportForwarder;
344 }
345
346 /* We're done */
347 goto done;
348 }
349
350 /* Check oldstyle import descriptor */
351 ImportEntry = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(LdrEntry->DllBase,
352 TRUE,
354 &ImportSize);
355 if (ImportEntry)
356 {
357 /* There is old one, so go through its entries */
358 while (ImportEntry->Name && ImportEntry->FirstThunk)
359 {
360 FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->FirstThunk);
361
362 /* Skip this entry if needed */
363 if (!FirstThunk->u1.Function)
364 {
365 ImportEntry++;
366 continue;
367 }
368
369 ImportName = (PSZ)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->Name);
370
371 RtlInitAnsiString(&ImportNameAnsi, ImportName);
372 Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
373 if (NT_SUCCESS(Status))
374 {
375 RedirectedDll = FALSE;
376 RedirectedImportName = ImportNameUnic;
377
378 /* Check if the SxS Assemblies specify another file */
380 ImportNameUnic,
382 UpdateString,
383 NULL,
384 &RedirectedImportName,
385 NULL,
386 NULL,
387 NULL);
388 /* Check success */
389 if (NT_SUCCESS(Status))
390 {
391 if (ShowSnaps)
392 {
393 DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
394 }
395
396 /* Let Ldrp know */
397 RedirectedDll = TRUE;
398 }
399
400 if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND)
401 {
403 RedirectedImportName,
404 TRUE,
405 RedirectedDll,
406 &Entry))
407 {
408 if (Entry->LoadCount != 0xFFFF)
409 {
410 /* Perform the required action */
411 switch (Flags)
412 {
414 Entry->LoadCount++;
415 break;
417 Entry->LoadCount--;
418 break;
419 case LDRP_UPDATE_PIN:
420 Entry->LoadCount = 0xFFFF;
421 break;
422 }
423
424 /* Show snaps */
425 if (ShowSnaps)
426 {
427 DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
428 }
429 }
430
431 /* Recurse */
432 LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
433 }
434 else if (RedirectedDll)
435 {
436 DPRINT1("LDR: LdrpCheckForLoadedDll failed for redirected dll %wZ\n", RedirectedImportName);
437 }
438
439 }
440 else
441 {
442 /* Unrecoverable SxS failure */
443 DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed for dll %wZ\n", ImportNameUnic);
444 }
445
446 }
447
448 /* Go to the next entry */
449 ImportEntry++;
450 }
451 }
452
453done:
454 /* Release the context */
456}
NTSYSAPI NTSTATUS NTAPI RtlDosApplyFileIsolationRedirection_Ustr(IN ULONG Flags, IN PUNICODE_STRING OriginalName, IN PUNICODE_STRING Extension, IN OUT PUNICODE_STRING StaticString, IN OUT PUNICODE_STRING DynamicString, IN OUT PUNICODE_STRING *NewName, IN PULONG NewFlags, IN PSIZE_T FileNameSize, IN PSIZE_T RequiredLength)
Definition: libsupp.c:818
#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)
#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
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame, IN PVOID Context)
Definition: actctx.c:5934
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame)
Definition: actctx.c:6011
#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().