ReactOS 0.4.16-dev-752-g47bae01
ntdllp.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _LDRP_TLS_DATA
 

Macros

#define LDR_HASH_TABLE_ENTRIES   32
 
#define LDR_GET_HASH_ENTRY(x)   (RtlUpcaseUnicodeChar((x)) & (LDR_HASH_TABLE_ENTRIES - 1))
 
#define LDRP_UPDATE_REFCOUNT   0x01
 
#define LDRP_UPDATE_DEREFCOUNT   0x02
 
#define LDRP_UPDATE_PIN   0x03
 
#define IMAGE_LOADER_FLAGS_COMPLUS   0x00000001
 
#define IMAGE_LOADER_FLAGS_SYSTEM_GLOBAL   0x01000000
 
#define DPH_FLAG_DLL_NOTIFY   0x40
 

Typedefs

typedef struct _LDRP_TLS_DATA LDRP_TLS_DATA
 
typedef struct _LDRP_TLS_DATAPLDRP_TLS_DATA
 
typedef NTSTATUS(NTAPIPLDR_APP_COMPAT_DLL_REDIRECTION_CALLBACK_FUNCTION) (_In_ ULONG Flags, _In_ PCWSTR DllName, _In_ PCWSTR DllPath OPTIONAL, _Inout_opt_ PULONG DllCharacteristics, _In_ PVOID CallbackData, _Outptr_ PWSTR *EffectiveDllPath)
 
typedef NTSTATUS(NTAPIPEPFUNC) (PPEB)
 

Functions

NTSTATUS NTAPI LdrpRunInitializeRoutines (IN PCONTEXT Context OPTIONAL)
 
VOID NTAPI LdrpInitializeThread (IN PCONTEXT Context)
 
NTSTATUS NTAPI LdrpInitializeTls (VOID)
 
NTSTATUS NTAPI LdrpAllocateTls (VOID)
 
VOID NTAPI LdrpFreeTls (VOID)
 
VOID NTAPI LdrpCallTlsInitializers (IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Reason)
 
BOOLEAN NTAPI LdrpCallInitRoutine (IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context)
 
NTSTATUS NTAPI LdrpInitializeProcess (IN PCONTEXT Context, IN PVOID SystemArgument1)
 
VOID NTAPI LdrpInitFailure (NTSTATUS Status)
 
VOID NTAPI LdrpValidateImageForMp (IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
 
VOID NTAPI LdrpEnsureLoaderLockIsHeld (VOID)
 
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)
 
NTSTATUS NTAPI LdrpWalkImportDescriptor (IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSYSAPI NTSTATUS NTAPI LdrpApplyFileNameRedirection (_In_ PUNICODE_STRING OriginalName, _In_ PUNICODE_STRING Extension, _Inout_opt_ PUNICODE_STRING StaticString, _Inout_opt_ PUNICODE_STRING DynamicString, _Inout_ PUNICODE_STRING *NewName, _Inout_ PBOOLEAN RedirectedDll)
 
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)
 
PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry (IN PVOID BaseAddress)
 
VOID NTAPI LdrpInsertMemoryTableEntry (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSTATUS NTAPI LdrpLoadDll (IN BOOLEAN Redirected, IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress, IN BOOLEAN CallInit)
 
VOID NTAPI LdrpUpdateLoadCount2 (IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Flags)
 
ULONG NTAPI LdrpClearLoadInProgress (VOID)
 
NTSTATUS NTAPI LdrpSetProtection (PVOID ViewBase, BOOLEAN Restore)
 
BOOLEAN NTAPI LdrpCheckForLoadedDllHandle (IN PVOID Base, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
 
BOOLEAN NTAPI LdrpCheckForLoadedDll (IN PWSTR DllPath, IN PUNICODE_STRING DllName, IN BOOLEAN Flag, IN BOOLEAN RedirectedDll, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
 
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)
 
PVOID NTAPI LdrpFetchAddressOfEntryPoint (PVOID ImageBase)
 
VOID NTAPI LdrpFreeUnicodeString (PUNICODE_STRING String)
 
VOID NTAPI LdrpRecordUnloadEvent (_In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
 
VOID NTAPI LdrpGetShimEngineInterface (VOID)
 
VOID NTAPI LdrpLoadShimEngine (IN PWSTR ImageName, IN PUNICODE_STRING ProcessImage, IN PVOID pShimData)
 
VOID NTAPI LdrpUnloadShimEngine (VOID)
 
NTSTATUS NTAPI LdrpInitializeApplicationVerifierPackage (IN HANDLE KeyHandle, IN PPEB Peb, IN BOOLEAN SystemWide, IN BOOLEAN ReadAdvancedOptions)
 
NTSTATUS NTAPI AVrfInitializeVerifier (VOID)
 
VOID NTAPI AVrfDllLoadNotification (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
VOID NTAPI AVrfDllUnloadNotification (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
VOID NTAPI AVrfPageHeapDllNotification (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSTATUS LdrMapSections (HANDLE ProcessHandle, PVOID ImageBase, HANDLE SectionHandle, PIMAGE_NT_HEADERS NTHeaders)
 
NTSTATUS LdrMapNTDllForProcess (HANDLE ProcessHandle, PHANDLE NTDllSectionHandle)
 
ULONG LdrpGetResidentSize (PIMAGE_NT_HEADERS NTHeaders)
 
NTSTATUS NTAPI LdrpLoadImportModule (IN PWSTR DllPath OPTIONAL, IN LPSTR ImportName, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry, OUT PBOOLEAN Existing)
 
VOID NTAPI LdrpFinalizeAndDeallocateDataTableEntry (IN PLDR_DATA_TABLE_ENTRY Entry)
 
BOOLEAN NTAPI RtlDoesFileExists_UStr (IN PUNICODE_STRING FileName)
 
VOID NTAPI RtlpInitializeKeyedEvent (VOID)
 
VOID NTAPI RtlpInitializeThreadPooling (VOID)
 

Variables

RTL_CRITICAL_SECTION LdrpLoaderLock
 
BOOLEAN LdrpInLdrInit
 
PVOID LdrpHeap
 
LIST_ENTRY LdrpHashTable [LDR_HASH_TABLE_ENTRIES]
 
BOOLEAN ShowSnaps
 
UNICODE_STRING LdrpDefaultPath
 
HANDLE LdrpKnownDllObjectDirectory
 
ULONG LdrpNumberOfProcessors
 
ULONG LdrpFatalHardErrorCount
 
PUNICODE_STRING LdrpTopLevelDllBeingLoaded
 
PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer
 
UNICODE_STRING LdrApiDefaultExtension
 
BOOLEAN LdrpLdrDatabaseIsSetup
 
ULONG LdrpActiveUnloadCount
 
BOOLEAN LdrpShutdownInProgress
 
UNICODE_STRING LdrpKnownDllPath
 
PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache
 
PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache
 
BOOLEAN RtlpPageHeapEnabled
 
ULONG RtlpDphGlobalFlags
 
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

◆ DPH_FLAG_DLL_NOTIFY

#define DPH_FLAG_DLL_NOTIFY   0x40

Definition at line 24 of file ntdllp.h.

◆ IMAGE_LOADER_FLAGS_COMPLUS

#define IMAGE_LOADER_FLAGS_COMPLUS   0x00000001

Definition at line 20 of file ntdllp.h.

◆ IMAGE_LOADER_FLAGS_SYSTEM_GLOBAL

#define IMAGE_LOADER_FLAGS_SYSTEM_GLOBAL   0x01000000

Definition at line 21 of file ntdllp.h.

◆ LDR_GET_HASH_ENTRY

#define LDR_GET_HASH_ENTRY (   x)    (RtlUpcaseUnicodeChar((x)) & (LDR_HASH_TABLE_ENTRIES - 1))

Definition at line 12 of file ntdllp.h.

◆ LDR_HASH_TABLE_ENTRIES

#define LDR_HASH_TABLE_ENTRIES   32

Definition at line 11 of file ntdllp.h.

◆ LDRP_UPDATE_DEREFCOUNT

#define LDRP_UPDATE_DEREFCOUNT   0x02

Definition at line 16 of file ntdllp.h.

◆ LDRP_UPDATE_PIN

#define LDRP_UPDATE_PIN   0x03

Definition at line 17 of file ntdllp.h.

◆ LDRP_UPDATE_REFCOUNT

#define LDRP_UPDATE_REFCOUNT   0x01

Definition at line 15 of file ntdllp.h.

Typedef Documentation

◆ LDRP_TLS_DATA

◆ PEPFUNC

typedef NTSTATUS(NTAPI * PEPFUNC) (PPEB)

Definition at line 211 of file ntdllp.h.

◆ PLDR_APP_COMPAT_DLL_REDIRECTION_CALLBACK_FUNCTION

typedef NTSTATUS(NTAPI * PLDR_APP_COMPAT_DLL_REDIRECTION_CALLBACK_FUNCTION) (_In_ ULONG Flags, _In_ PCWSTR DllName, _In_ PCWSTR DllPath OPTIONAL, _Inout_opt_ PULONG DllCharacteristics, _In_ PVOID CallbackData, _Outptr_ PWSTR *EffectiveDllPath)

Definition at line 33 of file ntdllp.h.

◆ PLDRP_TLS_DATA

Function Documentation

◆ AVrfDllLoadNotification()

VOID NTAPI AVrfDllLoadNotification ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 294 of file verifier.c.

295{
297
299 return;
300
302 if (!AVrfpIsVerifierProviderDll(LdrEntry->DllBase))
303 {
304 AvrfpResolveThunks(LdrEntry);
305
307 {
309 RTL_VERIFIER_DLL_LOAD_CALLBACK ProviderDllLoadCallback;
310
312
313 ProviderDllLoadCallback = Provider->ProviderDllLoadCallback;
314 if (ProviderDllLoadCallback)
315 {
316 ProviderDllLoadCallback(LdrEntry->BaseDllName.Buffer,
317 LdrEntry->DllBase,
318 LdrEntry->SizeOfImage,
319 LdrEntry);
320 }
321 }
322 }
324}
#define NtCurrentPeb()
Definition: FLS.c:22
#define FLG_APPLICATION_VERIFIER
Definition: pstypes.h:64
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
LIST_ENTRY AVrfpVerifierProvidersList
Definition: verifier.c:22
RTL_CRITICAL_SECTION AVrfpVerifierLock
Definition: verifier.c:21
BOOLEAN AVrfpIsVerifierProviderDll(PVOID BaseAddress)
Definition: verifier.c:103
VOID AvrfpResolveThunks(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: verifier.c:235
ULONG NtGlobalFlag
Definition: init.c:54
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
VOID(NTAPI * RTL_VERIFIER_DLL_LOAD_CALLBACK)(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved)
Definition: verifier.h:6

Referenced by LdrpWalkImportDescriptor().

◆ AVrfDllUnloadNotification()

VOID NTAPI AVrfDllUnloadNotification ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 328 of file verifier.c.

329{
331
333 return;
334
336 if (!AVrfpIsVerifierProviderDll(LdrEntry->DllBase))
337 {
339 {
341 RTL_VERIFIER_DLL_UNLOAD_CALLBACK ProviderDllUnloadCallback;
342
344
345 ProviderDllUnloadCallback = Provider->ProviderDllUnloadCallback;
346 if (ProviderDllUnloadCallback)
347 {
348 ProviderDllUnloadCallback(LdrEntry->BaseDllName.Buffer,
349 LdrEntry->DllBase,
350 LdrEntry->SizeOfImage,
351 LdrEntry);
352 }
353 }
354 }
356}
VOID(NTAPI * RTL_VERIFIER_DLL_UNLOAD_CALLBACK)(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved)
Definition: verifier.h:7

Referenced by LdrUnloadDll().

◆ AVrfInitializeVerifier()

NTSTATUS NTAPI AVrfInitializeVerifier ( VOID  )

Definition at line 612 of file verifier.c.

613{
617 WCHAR* Ptr, *Next;
618
621
622 if (!NT_SUCCESS(Status))
623 return Status;
624
625 DbgPrint("AVRF: %wZ: pid 0x%X: flags 0x%X: application verifier enabled\n",
627
628 Provider = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VERIFIER_PROVIDER));
629 if (!Provider)
630 return STATUS_NO_MEMORY;
631
632 RtlInitUnicodeString(&Provider->DllName, L"verifier.dll");
634
636
637 do
638 {
639 while (*Next == L' ' || *Next == L'\t')
640 Next++;
641
642 Ptr = Next;
643
644 while (*Next != ' ' && *Next != '\t' && *Next)
645 Next++;
646
647 if (*Next)
648 *(Next++) = '\0';
649 else
650 Next = NULL;
651
652 if (*Ptr)
653 {
654 Provider = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VERIFIER_PROVIDER));
655 if (!Provider)
656 return STATUS_NO_MEMORY;
659 }
660 } while (Next);
661
664 {
666 Entry = Entry->Flink;
667
669 if (!NT_SUCCESS(Status))
670 {
671 RemoveEntryList(&Provider->ListEntry);
672 RtlFreeHeap(RtlGetProcessHeap(), 0, Provider);
673 }
674 }
675
676 if (!NT_SUCCESS(Status))
677 {
678 DbgPrint("AVRF: %wZ: pid 0x%X: application verifier will be disabled due to an initialization error.\n",
680 NtCurrentPeb()->NtGlobalFlag &= ~FLG_APPLICATION_VERIFIER;
681 }
682
683 return Status;
684}
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
Status
Definition: gdiplustypes.h:25
#define DbgPrint
Definition: hal.h:12
#define NtCurrentTeb
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
ULONG AVrfpVerifierFlags
Definition: verifier.c:17
PLDR_DATA_TABLE_ENTRY LdrpImageEntry
Definition: ldrinit.c:39
WCHAR AVrfpVerifierDllsString[256]
Definition: verifier.c:18
NTSTATUS NTAPI AVrfpLoadAndInitializeProvider(PVERIFIER_PROVIDER Provider)
Definition: verifier.c:485
#define L(x)
Definition: ntvdm.h:50
STDMETHOD() Next(THIS_ ULONG celt, IAssociationElement *pElement, ULONG *pceltFetched) PURE
HANDLE UniqueProcess
Definition: compat.h:825
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by LdrpInitializeProcess().

◆ AVrfPageHeapDllNotification()

VOID NTAPI AVrfPageHeapDllNotification ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 361 of file verifier.c.

362{
363 /* Check if page heap dll notification is turned on */
365 return;
366
367 /* We don't support this flag currently */
369}
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
ULONG RtlpDphGlobalFlags
Definition: heappage.c:108
#define DPH_FLAG_DLL_NOTIFY
Definition: ntdllp.h:24

Referenced by LdrpWalkImportDescriptor().

◆ LdrMapNTDllForProcess()

NTSTATUS LdrMapNTDllForProcess ( HANDLE  ProcessHandle,
PHANDLE  NTDllSectionHandle 
)

◆ LdrMapSections()

NTSTATUS LdrMapSections ( HANDLE  ProcessHandle,
PVOID  ImageBase,
HANDLE  SectionHandle,
PIMAGE_NT_HEADERS  NTHeaders 
)

◆ LdrpAllocateDataTableEntry()

PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry ( IN PVOID  BaseAddress)

Definition at line 1523 of file ldrutils.c.

1524{
1525 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
1526 PIMAGE_NT_HEADERS NtHeader;
1527
1528 /* Make sure the header is valid */
1529 NtHeader = RtlImageNtHeader(BaseAddress);
1530 DPRINT("LdrpAllocateDataTableEntry(%p), NtHeader %p\n", BaseAddress, NtHeader);
1531
1532 if (NtHeader)
1533 {
1534 /* Allocate an entry */
1535 LdrEntry = RtlAllocateHeap(LdrpHeap,
1537 sizeof(LDR_DATA_TABLE_ENTRY));
1538
1539 /* Make sure we got one */
1540 if (LdrEntry)
1541 {
1542 /* Set it up */
1543 LdrEntry->DllBase = BaseAddress;
1544 LdrEntry->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
1545 LdrEntry->TimeDateStamp = NtHeader->FileHeader.TimeDateStamp;
1546 LdrEntry->PatchInformation = NULL;
1547 }
1548 }
1549
1550 /* Return the entry */
1551 return LdrEntry;
1552}
#define RtlImageNtHeader
Definition: compat.h:806
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
PVOID LdrpHeap
Definition: ldrinit.c:59
#define DPRINT
Definition: sndvol32.h:73
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
Definition: btrfs_drv.h:1876
ULONG SizeOfImage
Definition: ldrtypes.h: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().

◆ LdrpAllocateTls()

NTSTATUS NTAPI LdrpAllocateTls ( VOID  )

Definition at line 1329 of file ldrinit.c.

1330{
1331 PTEB Teb = NtCurrentTeb();
1332 PLIST_ENTRY NextEntry, ListHead;
1333 PLDRP_TLS_DATA TlsData;
1334 SIZE_T TlsDataSize;
1335 PVOID *TlsVector;
1336
1337 /* Check if we have any entries */
1339 return STATUS_SUCCESS;
1340
1341 /* Allocate the vector array */
1342 TlsVector = RtlAllocateHeap(RtlGetProcessHeap(),
1343 0,
1344 LdrpNumberOfTlsEntries * sizeof(PVOID));
1345 if (!TlsVector) return STATUS_NO_MEMORY;
1346 Teb->ThreadLocalStoragePointer = TlsVector;
1347
1348 /* Loop the TLS Array */
1349 ListHead = &LdrpTlsList;
1350 NextEntry = ListHead->Flink;
1351 while (NextEntry != ListHead)
1352 {
1353 /* Get the entry */
1354 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1355 NextEntry = NextEntry->Flink;
1356
1357 /* Allocate this vector */
1358 TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
1360 TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
1361 0,
1362 TlsDataSize);
1363 if (!TlsVector[TlsData->TlsDirectory.Characteristics])
1364 {
1365 /* Out of memory */
1366 return STATUS_NO_MEMORY;
1367 }
1368
1369 /* Show debug message */
1370 if (ShowSnaps)
1371 {
1372 DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
1373 TlsVector,
1375 &TlsVector[TlsData->TlsDirectory.Characteristics],
1377 TlsVector[TlsData->TlsDirectory.Characteristics]);
1378 }
1379
1380 /* Copy the data */
1381 RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics],
1383 TlsDataSize);
1384 }
1385
1386 /* Done */
1387 return STATUS_SUCCESS;
1388}
#define DPRINT1
Definition: precomp.h:8
ULONG LdrpNumberOfTlsEntries
Definition: ldrinit.c:54
LIST_ENTRY LdrpTlsList
Definition: ldrinit.c:53
BOOLEAN ShowSnaps
Definition: ldrinit.c:81
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG StartAddressOfRawData
Definition: ntimage.h:546
IMAGE_TLS_DIRECTORY TlsDirectory
Definition: ntdllp.h:29
Definition: compat.h:836
PVOID ThreadLocalStoragePointer
Definition: compat.h:841
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by LdrpInitializeThread(), and LdrpInitializeTls().

◆ LdrpApplyFileNameRedirection()

NTSYSAPI NTSTATUS NTAPI LdrpApplyFileNameRedirection ( _In_ PUNICODE_STRING  OriginalName,
_In_ PUNICODE_STRING  Extension,
_Inout_opt_ PUNICODE_STRING  StaticString,
_Inout_opt_ PUNICODE_STRING  DynamicString,
_Inout_ PUNICODE_STRING NewName,
_Inout_ PBOOLEAN  RedirectedDll 
)

◆ LdrpCallInitRoutine()

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

Definition at line 100 of file ldrutils.c.

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

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

◆ LdrpCallTlsInitializers()

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

Definition at line 447 of file ldrutils.c.

449{
450 PIMAGE_TLS_DIRECTORY TlsDirectory;
452 ULONG Size;
453
454 /* Get the TLS Directory */
455 TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
456 TRUE,
458 &Size);
459
460 /* Protect against invalid pointers */
462 {
463 /* Make sure it's valid */
464 if (TlsDirectory)
465 {
466 /* Get the array */
467 Array = (PIMAGE_TLS_CALLBACK *)TlsDirectory->AddressOfCallBacks;
468 if (Array)
469 {
470 /* Display debug */
471 if (ShowSnaps)
472 {
473 DPRINT1("LDR: Tls Callbacks Found. Imagebase %p Tls %p CallBacks %p\n",
474 LdrEntry->DllBase, TlsDirectory, Array);
475 }
476
477 /* Loop the array */
478 while (*Array)
479 {
480 /* Get the TLS Entrypoint */
481 Callback = *Array++;
482
483 /* Display debug */
484 if (ShowSnaps)
485 {
486 DPRINT1("LDR: Calling Tls Callback Imagebase %p Function %p\n",
487 LdrEntry->DllBase, Callback);
488 }
489
490 /* Call it */
492 LdrEntry->DllBase,
493 Reason,
494 NULL);
495 }
496 }
497 }
498 }
500 {
501 DPRINT1("LDR: Exception 0x%x during Tls Callback(%u) for %wZ\n",
502 _SEH2_GetExceptionCode(), Reason, &LdrEntry->BaseDllName);
503 }
504 _SEH2_END;
505}
#define TRUE
Definition: types.h:120
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
BOOLEAN(NTAPI * PDLL_INIT_ROUTINE)(_In_ PVOID DllHandle, _In_ ULONG Reason, _In_opt_ PCONTEXT Context)
Definition: ldrtypes.h: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:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
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().

◆ LdrpCheckForLoadedDll()

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

Definition at line 1953 of file ldrutils.c.

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

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

◆ LdrpCheckForLoadedDllHandle()

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

Definition at line 1595 of file ldrutils.c.

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

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

◆ LdrpClearLoadInProgress()

ULONG NTAPI LdrpClearLoadInProgress ( VOID  )

Definition at line 2644 of file ldrutils.c.

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

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

◆ LdrpEnsureLoaderLockIsHeld()

VOID NTAPI LdrpEnsureLoaderLockIsHeld ( VOID  )

Definition at line 409 of file ldrinit.c.

410{
411 // Ignored atm
412}

Referenced by LdrpCheckForKnownDll(), and LdrpRunInitializeRoutines().

◆ LdrpFetchAddressOfEntryPoint()

PVOID NTAPI LdrpFetchAddressOfEntryPoint ( PVOID  ImageBase)

◆ LdrpFinalizeAndDeallocateDataTableEntry()

VOID NTAPI LdrpFinalizeAndDeallocateDataTableEntry ( IN PLDR_DATA_TABLE_ENTRY  Entry)

Definition at line 1572 of file ldrutils.c.

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

Referenced by LdrUnloadDll().

◆ LdrpFreeTls()

VOID NTAPI LdrpFreeTls ( VOID  )

Definition at line 1392 of file ldrinit.c.

1393{
1394 PLIST_ENTRY ListHead, NextEntry;
1395 PLDRP_TLS_DATA TlsData;
1396 PVOID *TlsVector;
1397 PTEB Teb = NtCurrentTeb();
1398
1399 /* Get a pointer to the vector array */
1400 TlsVector = Teb->ThreadLocalStoragePointer;
1401 if (!TlsVector) return;
1402
1403 /* Loop through it */
1404 ListHead = &LdrpTlsList;
1405 NextEntry = ListHead->Flink;
1406 while (NextEntry != ListHead)
1407 {
1408 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1409 NextEntry = NextEntry->Flink;
1410
1411 /* Free each entry */
1412 if (TlsVector[TlsData->TlsDirectory.Characteristics])
1413 {
1414 RtlFreeHeap(RtlGetProcessHeap(),
1415 0,
1416 TlsVector[TlsData->TlsDirectory.Characteristics]);
1417 }
1418 }
1419
1420 /* Free the array itself */
1421 RtlFreeHeap(RtlGetProcessHeap(),
1422 0,
1423 TlsVector);
1424}

Referenced by LdrShutdownThread().

◆ LdrpFreeUnicodeString()

VOID NTAPI LdrpFreeUnicodeString ( PUNICODE_STRING  String)

◆ LdrpGetProcedureAddress()

NTSTATUS NTAPI LdrpGetProcedureAddress ( _In_ PVOID  BaseAddress,
_In_opt_ _When_(Ordinal==0, _Notnull_) PANSI_STRING  Name,
_In_opt_ _When_(Name==NULL, _In_range_(>, 0)) ULONG  Ordinal,
_Out_ PVOID ProcedureAddress,
_In_ BOOLEAN  ExecuteInit 
)

Definition at line 2226 of file ldrutils.c.

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

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

◆ LdrpGetResidentSize()

ULONG LdrpGetResidentSize ( PIMAGE_NT_HEADERS  NTHeaders)

◆ LdrpGetShimEngineInterface()

VOID NTAPI LdrpGetShimEngineInterface ( VOID  )

◆ LdrpInitFailure()

VOID NTAPI LdrpInitFailure ( NTSTATUS  Status)

Definition at line 2554 of file ldrinit.c.

2555{
2557 PPEB Peb = NtCurrentPeb();
2558
2559 /* Print a debug message */
2560 DPRINT1("LDR: Process initialization failure for %wZ; NTSTATUS = %08lx\n",
2562
2563 /* Raise a hard error */
2565 {
2567 }
2568}
PPEB Peb
Definition: dllmain.c:27
ULONG LdrpFatalHardErrorCount
Definition: ldrinit.c:83
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
#define STATUS_APP_INIT_FAILURE
Definition: ntstatus.h:561
Definition: ncftp.h:89
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1913
UNICODE_STRING ImagePathName
Definition: btrfs_drv.h:1901
uint32_t * PULONG_PTR
Definition: typedefs.h:65

Referenced by LdrpInit(), and LdrpInitializeProcess().

◆ LdrpInitializeApplicationVerifierPackage()

NTSTATUS NTAPI LdrpInitializeApplicationVerifierPackage ( IN HANDLE  KeyHandle,
IN PPEB  Peb,
IN BOOLEAN  SystemWide,
IN BOOLEAN  ReadAdvancedOptions 
)

◆ LdrpInitializeProcess()

NTSTATUS NTAPI LdrpInitializeProcess ( IN PCONTEXT  Context,
IN PVOID  SystemArgument1 
)

Definition at line 1767 of file ldrinit.c.

1769{
1770 RTL_HEAP_PARAMETERS HeapParameters;
1771 ULONG ComSectionSize;
1772 ANSI_STRING BaseProcessInitPostImportName = RTL_CONSTANT_STRING("BaseProcessInitPostImport");
1773 ANSI_STRING BaseQueryModuleDataName = RTL_CONSTANT_STRING("BaseQueryModuleData");
1774 PVOID OldShimData;
1776 //UNICODE_STRING LocalFileName, FullImageName;
1777 HANDLE SymLinkHandle;
1778 //ULONG DebugHeapOnly;
1779 UNICODE_STRING CommandLine, NtSystemRoot, ImagePathName, FullPath, ImageFileName, KnownDllString;
1780 PPEB Peb = NtCurrentPeb();
1781 BOOLEAN IsDotNetImage = FALSE;
1782 BOOLEAN FreeCurDir = FALSE;
1783 //HANDLE CompatKey;
1784 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
1785 //LPWSTR ImagePathBuffer;
1786 ULONG ConfigSize;
1788 HANDLE OptionsKey;
1789 ULONG HeapFlags;
1790 PIMAGE_NT_HEADERS NtHeader;
1791 LPWSTR NtDllName = NULL;
1792 NTSTATUS Status, ImportStatus;
1793 NLSTABLEINFO NlsTable;
1795 PTEB Teb = NtCurrentTeb();
1796 PLIST_ENTRY ListHead;
1797 PLIST_ENTRY NextEntry;
1798 ULONG i;
1799 PWSTR ImagePath;
1800 ULONG DebugProcessHeapOnly = 0;
1801 PLDR_DATA_TABLE_ENTRY NtLdrEntry;
1802 PWCHAR Current;
1803 ULONG ExecuteOptions = 0;
1804 PVOID ViewBase;
1805
1806 /* Set a NULL SEH Filter */
1808
1809 /* Get the image path */
1811
1812 /* Check if it's not normalized */
1814 {
1815 /* Normalize it*/
1816 ImagePath = (PWSTR)((ULONG_PTR)ImagePath + (ULONG_PTR)Peb->ProcessParameters);
1817 }
1818
1819 /* Create a unicode string for the Image Path */
1821 ImagePathName.MaximumLength = ImagePathName.Length + sizeof(WCHAR);
1822 ImagePathName.Buffer = ImagePath;
1823
1824 /* Get the NT Headers */
1826
1827 /* Get the execution options */
1828 Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &OptionsKey);
1829
1830 /* Check if this is a .NET executable */
1832 TRUE,
1834 &ComSectionSize))
1835 {
1836 /* Remember this for later */
1837 IsDotNetImage = TRUE;
1838 }
1839
1840 /* Save the NTDLL Base address */
1842
1843 /* If this is a Native Image */
1845 {
1846 /* Then do DLL Validation */
1848 }
1849
1850 /* Save the old Shim Data */
1851 OldShimData = Peb->pShimData;
1852
1853 /* ReactOS specific: do not clear it. (Windows starts doing the same in later versions) */
1854 //Peb->pShimData = NULL;
1855
1856 /* Save the number of processors and CS timeout */
1859
1860 /* Normalize the parameters */
1861 ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
1862 if (ProcessParameters)
1863 {
1864 /* Save the Image and Command Line Names */
1865 ImageFileName = ProcessParameters->ImagePathName;
1866 CommandLine = ProcessParameters->CommandLine;
1867 }
1868 else
1869 {
1870 /* It failed, initialize empty strings */
1871 RtlInitUnicodeString(&ImageFileName, NULL);
1872 RtlInitUnicodeString(&CommandLine, NULL);
1873 }
1874
1875 /* Initialize NLS data */
1879 &NlsTable);
1880
1881 /* Reset NLS Translations */
1882 RtlResetRtlTranslations(&NlsTable);
1883
1884 /* Get the Image Config Directory */
1886 TRUE,
1888 &ConfigSize);
1889
1890 /* Setup the Heap Parameters */
1891 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
1892 HeapFlags = HEAP_GROWABLE;
1893 HeapParameters.Length = sizeof(HeapParameters);
1894
1895 /* Check if we have Configuration Data */
1896#define VALID_CONFIG_FIELD(Name) (ConfigSize >= RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, Name))
1897 /* The 'original' load config ends after SecurityCookie */
1898 if ((LoadConfig) && ConfigSize && (VALID_CONFIG_FIELD(SecurityCookie) || ConfigSize == LoadConfig->Size))
1899 {
1900 if (ConfigSize != sizeof(IMAGE_LOAD_CONFIG_DIRECTORY))
1901 DPRINT1("WARN: Accepting different LOAD_CONFIG size!\n");
1902 else
1903 DPRINT1("Applying LOAD_CONFIG\n");
1904
1905 if (VALID_CONFIG_FIELD(GlobalFlagsSet) && LoadConfig->GlobalFlagsSet)
1906 Peb->NtGlobalFlag |= LoadConfig->GlobalFlagsSet;
1907
1908 if (VALID_CONFIG_FIELD(GlobalFlagsClear) && LoadConfig->GlobalFlagsClear)
1909 Peb->NtGlobalFlag &= ~LoadConfig->GlobalFlagsClear;
1910
1911 /* Convert the default CS timeout from milliseconds to 100ns units */
1912 if (VALID_CONFIG_FIELD(CriticalSectionDefaultTimeout) && LoadConfig->CriticalSectionDefaultTimeout)
1913 RtlpTimeout.QuadPart = Int32x32To64(LoadConfig->CriticalSectionDefaultTimeout, -10000);
1914
1915 if (VALID_CONFIG_FIELD(DeCommitFreeBlockThreshold) && LoadConfig->DeCommitFreeBlockThreshold)
1916 HeapParameters.DeCommitFreeBlockThreshold = LoadConfig->DeCommitFreeBlockThreshold;
1917
1918 if (VALID_CONFIG_FIELD(DeCommitTotalFreeThreshold) && LoadConfig->DeCommitTotalFreeThreshold)
1919 HeapParameters.DeCommitTotalFreeThreshold = LoadConfig->DeCommitTotalFreeThreshold;
1920
1921 if (VALID_CONFIG_FIELD(MaximumAllocationSize) && LoadConfig->MaximumAllocationSize)
1922 HeapParameters.MaximumAllocationSize = LoadConfig->MaximumAllocationSize;
1923
1924 if (VALID_CONFIG_FIELD(VirtualMemoryThreshold) && LoadConfig->VirtualMemoryThreshold)
1925 HeapParameters.VirtualMemoryThreshold = LoadConfig->VirtualMemoryThreshold;
1926
1927 if (VALID_CONFIG_FIELD(ProcessHeapFlags) && LoadConfig->ProcessHeapFlags)
1928 HeapFlags = LoadConfig->ProcessHeapFlags;
1929 }
1930#undef VALID_CONFIG_FIELD
1931
1932 /* Check for custom affinity mask */
1934 {
1935 /* Set it */
1939 sizeof(Peb->ImageProcessAffinityMask));
1940 }
1941
1942 /* Check if verbose debugging (ShowSnaps) was requested */
1944
1945 /* Start verbose debugging messages right now if they were requested */
1946 if (ShowSnaps)
1947 {
1948 DPRINT1("LDR: PID: 0x%p started - '%wZ'\n",
1950 &CommandLine);
1951 }
1952
1953 /* If the CS timeout is longer than 1 hour, disable it */
1954 if (RtlpTimeout.QuadPart < Int32x32To64(3600, -10000000))
1956
1957 /* Initialize Critical Section Data */
1959
1960 /* Initialize VEH Call lists */
1962
1963 /* Set TLS/FLS Bitmap data */
1967
1968 /* Initialize FLS Bitmap */
1972 RtlSetBit(&FlsBitMap, 0);
1974
1975 /* Initialize TLS Bitmap */
1979 RtlSetBit(&TlsBitMap, 0);
1984
1985 /* Initialize the Hash Table */
1986 for (i = 0; i < LDR_HASH_TABLE_ENTRIES; i++)
1987 {
1989 }
1990
1991 /* Initialize the Loader Lock */
1992 // FIXME: What's the point of initing it manually, if two lines lower
1993 // a call to RtlInitializeCriticalSection() is being made anyway?
1994 //InsertTailList(&RtlCriticalSectionList, &LdrpLoaderLock.DebugInfo->ProcessLocksList);
1995 //LdrpLoaderLock.DebugInfo->CriticalSection = &LdrpLoaderLock;
1998
1999 /* Check if User Stack Trace Database support was requested */
2001 {
2002 DPRINT1("We don't support user stack trace databases yet\n");
2003 }
2004
2005 /* Setup Fast PEB Lock */
2008 //Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
2009 //Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
2010
2011 /* Setup Callout Lock and Notification list */
2012 //RtlInitializeCriticalSection(&RtlpCalloutEntryLock);
2014
2015 /* For old executables, use 16-byte aligned heap */
2016 if ((NtHeader->OptionalHeader.MajorSubsystemVersion <= 3) &&
2017 (NtHeader->OptionalHeader.MinorSubsystemVersion < 51))
2018 {
2019 HeapFlags |= HEAP_CREATE_ALIGN_16;
2020 }
2021
2022 /* Setup the Heap */
2024 Peb->ProcessHeap = RtlCreateHeap(HeapFlags,
2025 NULL,
2028 NULL,
2029 &HeapParameters);
2030
2031 if (!Peb->ProcessHeap)
2032 {
2033 DPRINT1("Failed to create process heap\n");
2034 return STATUS_NO_MEMORY;
2035 }
2036
2037 /* Allocate an Activation Context Stack */
2038 Status = RtlAllocateActivationContextStack(&Teb->ActivationContextStackPointer);
2039 if (!NT_SUCCESS(Status)) return Status;
2040
2041 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
2042 HeapFlags = HEAP_GROWABLE | HEAP_CLASS_1;
2043 HeapParameters.Length = sizeof(HeapParameters);
2044 LdrpHeap = RtlCreateHeap(HeapFlags, 0, 0x10000, 0x6000, 0, &HeapParameters);
2045 if (!LdrpHeap)
2046 {
2047 DPRINT1("Failed to create loader private heap\n");
2048 return STATUS_NO_MEMORY;
2049 }
2050
2051 /* Check for Debug Heap */
2052 if (OptionsKey)
2053 {
2054 /* Query the setting */
2056 L"DebugProcessHeapOnly",
2057 REG_DWORD,
2058 &DebugProcessHeapOnly,
2059 sizeof(ULONG),
2060 NULL);
2061
2062 if (NT_SUCCESS(Status))
2063 {
2064 /* Reset DPH if requested */
2065 if (RtlpPageHeapEnabled && DebugProcessHeapOnly)
2066 {
2067 RtlpDphGlobalFlags &= ~DPH_FLAG_DLL_NOTIFY;
2069 }
2070 }
2071 }
2072
2073 /* Build the NTDLL Path */
2074 FullPath.Buffer = StringBuffer;
2075 FullPath.Length = 0;
2076 FullPath.MaximumLength = sizeof(StringBuffer);
2079 RtlAppendUnicodeToString(&FullPath, L"\\System32\\");
2080
2081 /* Open the Known DLLs directory */
2082 RtlInitUnicodeString(&KnownDllString, L"\\KnownDlls");
2084 &KnownDllString,
2086 NULL,
2087 NULL);
2091
2092 /* Check if it exists */
2093 if (NT_SUCCESS(Status))
2094 {
2095 /* Open the Known DLLs Path */
2096 RtlInitUnicodeString(&KnownDllString, L"KnownDllPath");
2098 &KnownDllString,
2101 NULL);
2102 Status = NtOpenSymbolicLinkObject(&SymLinkHandle,
2105 if (NT_SUCCESS(Status))
2106 {
2107 /* Query the path */
2111 Status = ZwQuerySymbolicLinkObject(SymLinkHandle, &LdrpKnownDllPath, NULL);
2112 NtClose(SymLinkHandle);
2113 if (!NT_SUCCESS(Status))
2114 {
2115 DPRINT1("LDR: %s - failed call to ZwQuerySymbolicLinkObject with status %x\n", "", Status);
2116 return Status;
2117 }
2118 }
2119 }
2120
2121 /* Check if we failed */
2122 if (!NT_SUCCESS(Status))
2123 {
2124 /* Assume System32 */
2127 LdrpKnownDllPath.Length -= sizeof(WCHAR);
2128 }
2129
2130 /* If we have process parameters, get the default path and current path */
2131 if (ProcessParameters)
2132 {
2133 /* Check if we have a Dll Path */
2134 if (ProcessParameters->DllPath.Length)
2135 {
2136 /* Get the path */
2137 LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath;
2138 }
2139 else
2140 {
2141 /* We need a valid path */
2142 DPRINT1("No valid DllPath was given!\n");
2144 }
2145
2146 /* Set the current directory */
2147 CurrentDirectory = ProcessParameters->CurrentDirectory.DosPath;
2148
2149 /* Check if it's empty or invalid */
2150 if ((!CurrentDirectory.Buffer) ||
2151 (CurrentDirectory.Buffer[0] == UNICODE_NULL) ||
2152 (!CurrentDirectory.Length))
2153 {
2154 /* Allocate space for the buffer */
2156 0,
2157 3 * sizeof(WCHAR) +
2158 sizeof(UNICODE_NULL));
2159 if (!CurrentDirectory.Buffer)
2160 {
2161 DPRINT1("LDR: LdrpInitializeProcess - unable to allocate current working directory buffer\n");
2162 // FIXME: And what?
2163 }
2164
2165 /* Copy the drive of the system root */
2167 SharedUserData->NtSystemRoot,
2168 3 * sizeof(WCHAR));
2169 CurrentDirectory.Buffer[3] = UNICODE_NULL;
2170 CurrentDirectory.Length = 3 * sizeof(WCHAR);
2171 CurrentDirectory.MaximumLength = CurrentDirectory.Length + sizeof(WCHAR);
2172
2173 FreeCurDir = TRUE;
2174 DPRINT("Using dynamically allocd curdir\n");
2175 }
2176 else
2177 {
2178 /* Use the local buffer */
2179 DPRINT("Using local system root\n");
2180 }
2181 }
2182
2183 /* Setup Loader Data */
2184 Peb->Ldr = &PebLdr;
2188 PebLdr.Length = sizeof(PEB_LDR_DATA);
2190
2191 /* Allocate a data entry for the Image */
2193
2194 /* Set it up */
2198 LdrpImageEntry->FullDllName = ImageFileName;
2199
2200 if (IsDotNetImage)
2202 else
2203 LdrpImageEntry->Flags = 0;
2204
2205 /* Check if the name is empty */
2206 if (!ImageFileName.Buffer[0])
2207 {
2208 /* Use the same Base name */
2210 }
2211 else
2212 {
2213 /* Find the last slash */
2214 Current = ImageFileName.Buffer;
2215 while (*Current)
2216 {
2217 if (*Current++ == '\\')
2218 {
2219 /* Set this path */
2220 NtDllName = Current;
2221 }
2222 }
2223
2224 /* Did we find anything? */
2225 if (!NtDllName)
2226 {
2227 /* Use the same Base name */
2229 }
2230 else
2231 {
2232 /* Setup the name */
2233 LdrpImageEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName);
2236 (ImageFileName.Length - LdrpImageEntry->BaseDllName.Length));
2237 }
2238 }
2239
2240 /* Processing done, insert it */
2243
2244 /* Now add an entry for NTDLL */
2246 NtLdrEntry->Flags = LDRP_IMAGE_DLL;
2247 NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase);
2248 NtLdrEntry->LoadCount = -1;
2249 NtLdrEntry->EntryPointActivationContext = 0;
2250
2251 NtLdrEntry->FullDllName.Length = FullPath.Length;
2252 NtLdrEntry->FullDllName.MaximumLength = FullPath.MaximumLength;
2253 NtLdrEntry->FullDllName.Buffer = StringBuffer;
2255
2256 NtLdrEntry->BaseDllName.Length = NtDllString.Length;
2258 NtLdrEntry->BaseDllName.Buffer = NtDllString.Buffer;
2259
2260 /* Processing done, insert it */
2261 LdrpNtDllDataTableEntry = NtLdrEntry;
2262 LdrpInsertMemoryTableEntry(NtLdrEntry);
2263
2264 /* Let the world know */
2265 if (ShowSnaps)
2266 {
2267 DPRINT1("LDR: NEW PROCESS\n");
2268 DPRINT1(" Image Path: %wZ (%wZ)\n", &LdrpImageEntry->FullDllName, &LdrpImageEntry->BaseDllName);
2269 DPRINT1(" Current Directory: %wZ\n", &CurrentDirectory);
2270 DPRINT1(" Search Path: %wZ\n", &LdrpDefaultPath);
2271 }
2272
2273 /* Link the Init Order List */
2276
2277 /* Initialize Wine's active context implementation for the current process */
2278 RtlpInitializeActCtx(&OldShimData);
2279
2280 /* Set the current directory */
2282 if (!NT_SUCCESS(Status))
2283 {
2284 /* We failed, check if we should free it */
2285 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2286
2287 /* Set it to the NT Root */
2290 }
2291 else
2292 {
2293 /* We're done with it, free it */
2294 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2295 }
2296
2297 /* Check if we should look for a .local file */
2298 if (ProcessParameters && !(ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH))
2299 {
2300 LdrpInitializeDotLocalSupport(ProcessParameters);
2301 }
2302
2303 /* Check if the Application Verifier was enabled */
2305 {
2307 if (!NT_SUCCESS(Status))
2308 {
2309 DPRINT1("LDR: AVrfInitializeVerifier failed (ntstatus 0x%x)\n", Status);
2310 return Status;
2311 }
2312
2313 }
2314
2315 if (IsDotNetImage)
2316 {
2317 /* FIXME */
2318 DPRINT1("We don't support .NET applications yet\n");
2319 }
2320
2323 {
2324 PVOID Kernel32BaseAddress;
2325 PVOID FunctionAddress;
2326
2327 Status = LdrLoadDll(NULL, NULL, &Kernel32String, &Kernel32BaseAddress);
2328
2329 if (!NT_SUCCESS(Status))
2330 {
2331 if (ShowSnaps)
2332 DPRINT1("LDR: Unable to load %wZ, Status=0x%08lx\n", &Kernel32String, Status);
2333 return Status;
2334 }
2335
2336 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2337 &BaseProcessInitPostImportName,
2338 0,
2339 &FunctionAddress);
2340
2341 if (!NT_SUCCESS(Status))
2342 {
2343 if (ShowSnaps)
2344 DPRINT1("LDR: Unable to find post-import process init function, Status=0x%08lx\n", Status);
2345 return Status;
2346 }
2347 Kernel32ProcessInitPostImportFunction = FunctionAddress;
2348
2349 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2350 &BaseQueryModuleDataName,
2351 0,
2352 &FunctionAddress);
2353
2354 if (!NT_SUCCESS(Status))
2355 {
2356 if (ShowSnaps)
2357 DPRINT1("LDR: Unable to find BaseQueryModuleData, Status=0x%08lx\n", Status);
2358 return Status;
2359 }
2360 Kernel32BaseQueryModuleData = FunctionAddress;
2361 }
2362
2363 /* Walk the IAT and load all the DLLs */
2365
2366 /* Check if relocation is needed */
2368 {
2369 DPRINT1("LDR: Performing EXE relocation\n");
2370
2371 /* Change the protection to prepare for relocation */
2372 ViewBase = Peb->ImageBaseAddress;
2373 Status = LdrpSetProtection(ViewBase, FALSE);
2374 if (!NT_SUCCESS(Status)) return Status;
2375
2376 /* Do the relocation */
2378 0LL,
2379 NULL,
2383 if (!NT_SUCCESS(Status))
2384 {
2385 DPRINT1("LdrRelocateImageWithBias() failed\n");
2386 return Status;
2387 }
2388
2389 /* Check if a start context was provided */
2390 if (Context)
2391 {
2392 DPRINT1("WARNING: Relocated EXE Context");
2393 UNIMPLEMENTED; // We should support this
2395 }
2396
2397 /* Restore the protection */
2398 Status = LdrpSetProtection(ViewBase, TRUE);
2399 if (!NT_SUCCESS(Status)) return Status;
2400 }
2401
2402 /* Lock the DLLs */
2403 ListHead = &Peb->Ldr->InLoadOrderModuleList;
2404 NextEntry = ListHead->Flink;
2405 while (ListHead != NextEntry)
2406 {
2407 NtLdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
2408 NtLdrEntry->LoadCount = -1;
2409 NextEntry = NextEntry->Flink;
2410 }
2411
2412 /* Phase 0 is done */
2414
2415 /* Check whether all static imports were properly loaded and return here */
2416 if (!NT_SUCCESS(ImportStatus)) return ImportStatus;
2417
2418 /* Following two calls are for Vista+ support, required for winesync */
2419 /* Initialize the keyed event for condition variables */
2422
2423 /* Initialize TLS */
2425 if (!NT_SUCCESS(Status))
2426 {
2427 DPRINT1("LDR: LdrpProcessInitialization failed to initialize TLS slots; status %x\n",
2428 Status);
2429 return Status;
2430 }
2431
2432 /* FIXME Mark the DLL Ranges for Stack Traces later */
2433
2434 /* Notify the debugger now */
2435 if (Peb->BeingDebugged)
2436 {
2437 /* Break */
2438 DbgBreakPoint();
2439
2440 /* Update show snaps again */
2442 }
2443
2444 /* Validate the Image for MP Usage */
2446
2447 /* Check NX options and set them */
2448 if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSON)
2449 {
2450 ExecuteOptions = MEM_EXECUTE_OPTION_DISABLE |
2453 }
2454 else if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSOFF)
2455 {
2457 }
2460 &ExecuteOptions,
2461 sizeof(ExecuteOptions));
2462 if (!NT_SUCCESS(Status))
2463 {
2464 DPRINT1("LDR: Could not set process execute flags 0x%x; status %x\n",
2465 ExecuteOptions, Status);
2466 }
2467
2468 // FIXME: Should be done by Application Compatibility features,
2469 // by reading the registry, etc...
2470 // For now, this is the old code from ntdll!RtlGetVersion().
2471 RtlInitEmptyUnicodeString(&Peb->CSDVersion, NULL, 0);
2472 if (((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
2473 {
2474 WCHAR szCSDVersion[128];
2475 LONG i;
2476 USHORT Length = (USHORT)ARRAYSIZE(szCSDVersion) - 1;
2477 i = _snwprintf(szCSDVersion, Length,
2478 L"Service Pack %d",
2479 ((Peb->OSCSDVersion >> 8) & 0xFF));
2480 if (i < 0)
2481 {
2482 /* Null-terminate if it was overflowed */
2483 szCSDVersion[Length] = UNICODE_NULL;
2484 }
2485
2486 Length *= sizeof(WCHAR);
2487 Peb->CSDVersion.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
2488 0,
2489 Length + sizeof(UNICODE_NULL));
2490 if (Peb->CSDVersion.Buffer)
2491 {
2494
2496 szCSDVersion,
2499 }
2500 }
2501
2502 /* Check if we had Shim Data */
2503 if (OldShimData)
2504 {
2505 /* Load the Shim Engine */
2507 LdrpLoadShimEngine(OldShimData, &ImagePathName, OldShimData);
2508 }
2509 else
2510 {
2511 /* Check for Application Compatibility Goo */
2512 //LdrQueryApplicationCompatibilityGoo(hKey);
2513 DPRINT("Querying app compat hacks is missing!\n");
2514 }
2515
2516 /*
2517 * FIXME: Check for special images, SecuROM, SafeDisc and other NX-
2518 * incompatible images.
2519 */
2520
2521 /* Now call the Init Routines */
2523 if (!NT_SUCCESS(Status))
2524 {
2525 DPRINT1("LDR: LdrpProcessInitialization failed running initialization routines; status %x\n",
2526 Status);
2527 return Status;
2528 }
2529
2530 /* Notify Shim Engine */
2531 if (g_ShimsEnabled)
2532 {
2535 SE_InstallAfterInit(&ImagePathName, OldShimData);
2536 }
2537
2538 /* Check if we have a user-defined Post Process Routine */
2540 {
2541 /* Call it */
2543 }
2544
2545 /* Close the key if we have one opened */
2546 if (OptionsKey) NtClose(OptionsKey);
2547
2548 /* Return status */
2549 return Status;
2550}
#define VOID
Definition: acefi.h:82
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
struct _PEB_LDR_DATA PEB_LDR_DATA
#define RtlInitializeBitMap
Definition: dbgbitmap.h:326
#define RtlSetBit
Definition: dbgbitmap.h:344
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
#define ULONG_PTR
Definition: config.h:101
#define InsertHeadList(ListHead, Entry)
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
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
#define FLG_USER_STACK_TRACE_DB
Definition: pstypes.h:67
#define FLG_SHOW_LDR_SNAPS
Definition: pstypes.h:57
#define TLS_EXPANSION_SLOTS
Definition: pstypes.h:311
NTSYSAPI void WINAPI DbgBreakPoint(void)
@ ProcessAffinityMask
Definition: winternl.h:877
@ ProcessExecuteFlags
Definition: winternl.h:889
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(_In_opt_ PWSTR SearchPath, _In_opt_ PULONG DllCharacteristics, _In_ PUNICODE_STRING DllName, _Out_ PVOID *BaseAddress)
Definition: ldrapi.c:312
NTSTATUS NTAPI LdrGetProcedureAddress(_In_ PVOID BaseAddress, _In_opt_ _When_(Ordinal==0, _Notnull_) PANSI_STRING Name, _In_opt_ _When_(Name==NULL, _In_range_(>, 0)) ULONG Ordinal, _Out_ PVOID *ProcedureAddress)
Definition: ldrapi.c:789
PVOID NtDllBase
Definition: ldrinit.c:56
PLDR_DATA_TABLE_ENTRY LdrpImageEntry
Definition: ldrinit.c:39
VOID NTAPI LdrpInitializeDotLocalSupport(PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
Definition: ldrinit.c:1706
WCHAR LdrpKnownDllPathBuffer[128]
Definition: ldrinit.c:64
UNICODE_STRING LdrpDefaultPath
Definition: ldrinit.c:65
VOID NTAPI RtlpInitDeferredCriticalSection(VOID)
Definition: critical.c:272
NTSTATUS NTAPI LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PHANDLE OptionsKey)
Definition: ldrinit.c:1428
RTL_CRITICAL_SECTION FastPebLock
Definition: ldrinit.c:79
LIST_ENTRY LdrpDllNotificationList
Definition: ldrinit.c:61
ULONG LdrpNumberOfProcessors
Definition: ldrinit.c:55
PVOID LdrpHeap
Definition: ldrinit.c:59
RTL_BITMAP FlsBitMap
Definition: ldrinit.c:51
RTL_BITMAP TlsBitMap
Definition: ldrinit.c:49
BOOLEAN LdrpLoaderLockInit
Definition: ldrinit.c:32
LARGE_INTEGER RtlpTimeout
Definition: critical.c:25
NTSTATUS NTAPI LdrQueryImageFileKeyOption(_In_ HANDLE KeyHandle, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength)
Definition: ldrinit.c:185
VOID NTAPI RtlInitializeHeapManager(VOID)
Definition: libsupp.c:243
VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
Definition: ldrinit.c:1547
LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]
Definition: ldrinit.c:60
UNICODE_STRING LdrpKnownDllPath
Definition: ldrinit.c:63
RTL_BITMAP TlsExpansionBitMap
Definition: ldrinit.c:50
NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
Definition: ldrinit.c:649
BOOLEAN LdrpLdrDatabaseIsSetup
Definition: ldrinit.c:33
VOID NTAPI RtlpInitializeVectoredExceptionHandling(VOID)
Definition: vectoreh.c:30
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
HANDLE LdrpKnownDllObjectDirectory
Definition: ldrinit.c:62
RTL_CRITICAL_SECTION LdrpLoaderLock
Definition: ldrinit.c:70
VOID NTAPI LdrpInitFailure(NTSTATUS Status)
Definition: ldrinit.c:2554
PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry
Definition: ldrinit.c:44
NTSTATUS NTAPI LdrpInitializeTls(VOID)
Definition: ldrinit.c:1266
#define VALID_CONFIG_FIELD(Name)
UNICODE_STRING Kernel32String
Definition: ldrinit.c:27
BOOLEAN RtlpTimeoutDisable
Definition: critical.c:26
UNICODE_STRING NtDllString
Definition: ldrinit.c:26
NTSTATUS NTAPI RtlpInitializeActCtx(PVOID *pOldShimData)
BOOLEAN LdrpDllValidation
Definition: ldrinit.c:37
PEB_LDR_DATA PebLdr
Definition: ldrinit.c:67
#define LDRP_COR_IMAGE
Definition: ldrtypes.h:52
#define LDRP_IMAGE_DLL
Definition: ldrtypes.h:39
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
#define MEM_EXECUTE_OPTION_DISABLE
Definition: mmtypes.h:73
#define MEM_EXECUTE_OPTION_PERMANENT
Definition: mmtypes.h:76
#define MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
Definition: mmtypes.h:75
#define MEM_EXECUTE_OPTION_ENABLE
Definition: mmtypes.h:74
NTSYSAPI NTSTATUS NTAPI ZwOpenDirectoryObject(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSYSAPI VOID NTAPI RtlInitNlsTables(_In_ PUSHORT AnsiTableBase, _In_ PUSHORT OemTableBase, _In_ PUSHORT CaseTableBase, _Out_ PNLSTABLEINFO NlsTable)
NTSYSAPI VOID NTAPI RtlResetRtlTranslations(_In_ PNLSTABLEINFO NlsTable)
NTSYSAPI NTSTATUS NTAPI RtlSetCurrentDirectory_U(_In_ PUNICODE_STRING name)
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
NTSYSAPI PRTL_USER_PROCESS_PARAMETERS NTAPI RtlNormalizeProcessParams(_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
#define RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH
Definition: rtltypes.h:53
#define RTL_USER_PROCESS_PARAMETERS_NORMALIZED
Definition: rtltypes.h:41
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
#define HEAP_CLASS_1
Definition: nt_native.h:1711
NTSYSAPI PVOID NTAPI RtlCreateHeap(IN ULONG Flags, IN PVOID HeapBase OPTIONAL, IN ULONG ReserveSize OPTIONAL, IN ULONG CommitSize OPTIONAL, IN PVOID Lock OPTIONAL, IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL)
#define HEAP_GROWABLE
Definition: nt_native.h:1693
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define HEAP_CREATE_ALIGN_16
Definition: nt_native.h:1701
#define Int32x32To64(a, b)
PVOID g_pfnSE_InstallAfterInit
Definition: ldrutils.c:26
VOID NTAPI LdrpLoadShimEngine(IN PWSTR ImageName, IN PUNICODE_STRING ProcessImage, IN PVOID pShimData)
Definition: ldrutils.c:2752
NTSTATUS NTAPI LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrpe.c:670
NTSTATUS NTAPI AVrfInitializeVerifier(VOID)
Definition: verifier.c:612
#define LDR_HASH_TABLE_ENTRIES
Definition: ntdllp.h:11
VOID NTAPI RtlpInitializeThreadPooling(VOID)
VOID NTAPI LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrutils.c:1556
NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase, BOOLEAN Restore)
Definition: ldrutils.c:921
PVOID NTAPI LdrpFetchAddressOfEntryPoint(PVOID ImageBase)
BOOLEAN RtlpPageHeapEnabled
Definition: heappage.c:107
PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
Definition: ldrutils.c:1523
BOOLEAN g_ShimsEnabled
Definition: ldrutils.c:21
VOID NTAPI RtlpInitializeKeyedEvent(VOID)
Definition: condvar.c:460
#define IMAGE_SUBSYSTEM_WINDOWS_CUI
Definition: ntimage.h:438
#define IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: ntimage.h:437
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489
#define IMAGE_SUBSYSTEM_NATIVE
Definition: ntimage.h:436
UNICODE_STRING NtSystemRoot
Definition: init.c:76
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1154
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
static VOID LoadConfig(HWND hwndDlg, PPOWER_SCHEMES_PAGE_DATA pPageData, PPOWER_SCHEME pScheme)
Definition: powershemes.c:237
#define REG_DWORD
Definition: sdbapi.c:596
#define SharedUserData
VOID NTAPI RtlSetUnhandledExceptionFilter(IN PRTLP_UNHANDLED_EXCEPTION_FILTER TopLevelExceptionFilter)
Definition: exception.c:341
PVOID NTAPI RtlDecodeSystemPointer(IN PVOID Pointer)
Definition: process.c:439
VOID NTAPI SE_InstallAfterInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1436
#define TLS_MINIMUM_AVAILABLE
Definition: ntddk_ex.h:236
UNICODE_STRING DosPath
Definition: rtltypes.h:1368
PACTIVATION_CONTEXT EntryPointActivationContext
Definition: ldrtypes.h:163
USHORT LoadCount
Definition: ntddk_ex.h:208
LIST_ENTRY InInitializationOrderLinks
Definition: ldrtypes.h:140
LIST_ENTRY InInitializationOrderModuleList
Definition: ldrtypes.h:122
LIST_ENTRY InMemoryOrderModuleList
Definition: btrfs_drv.h:1895
ULONG Length
Definition: ntddk_ex.h:221
LIST_ENTRY InLoadOrderModuleList
Definition: ldrtypes.h:120
BOOLEAN Initialized
Definition: ntddk_ex.h:222
UNICODE_STRING CSDVersion
Definition: winternl.h:353
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1912
ULONG NumberOfProcessors
Definition: ntddk_ex.h:269
ULONG TlsBitmapBits[2]
Definition: ntddk_ex.h:260
ULONG ImageProcessAffinityMask
Definition: ntddk_ex.h:307
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
ULONG FlsBitmapBits[4]
Definition: winternl.h:362
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine
Definition: btrfs_drv.h:1916
PVOID ProcessHeap
Definition: ntddk_ex.h:249
LARGE_INTEGER CriticalSectionTimeout
Definition: ntddk_ex.h:274
ULONG TlsExpansionBitmapBits[32]
Definition: winternl.h:347
PVOID AnsiCodePageData
Definition: ntddk_ex.h:264
BYTE BeingDebugged
Definition: btrfs_drv.h:1909
PVOID FastPebLock
Definition: ntddk_ex.h:250
PVOID TlsBitmap
Definition: ntddk_ex.h:259
PVOID OemCodePageData
Definition: ntddk_ex.h:265
LIST_ENTRY FlsListHead
Definition: winternl.h:360
ULONG NtGlobalFlag
Definition: ntddk_ex.h:270
PRTL_BITMAP FlsBitmap
Definition: winternl.h:361
PVOID AppCompatInfo
Definition: winternl.h:352
PRTL_BITMAP TlsExpansionBitmap
Definition: winternl.h:346
PVOID UnicodeCaseTableData
Definition: ntddk_ex.h:266
ULONG DeCommitFreeBlockThreshold
Definition: nt_native.h:1670
ULONG VirtualMemoryThreshold
Definition: nt_native.h:1673
ULONG DeCommitTotalFreeThreshold
Definition: nt_native.h:1671
UNICODE_STRING CommandLine
Definition: btrfs_drv.h:1902
PVOID ActivationContextStackPointer
Definition: compat.h:854
CLIENT_ID ClientId
Definition: compat.h:839
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define LL
Definition: tui.h:166
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint16_t * PWSTR
Definition: typedefs.h:56
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
LONGLONG QuadPart
Definition: typedefs.h:114
#define FLS_MAXIMUM_AVAILABLE
Definition: winnt_old.h:1099
#define NX_SUPPORT_POLICY_ALWAYSOFF
Definition: ketypes.h:1260
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
#define NX_SUPPORT_POLICY_ALWAYSON
Definition: ketypes.h:1261
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by LdrpInit().

◆ LdrpInitializeThread()

VOID NTAPI LdrpInitializeThread ( IN PCONTEXT  Context)

Definition at line 506 of file ldrinit.c.

507{
509 PLDR_DATA_TABLE_ENTRY LdrEntry;
510 PLIST_ENTRY NextEntry, ListHead;
511 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
513 PVOID EntryPoint;
514
515 DPRINT("LdrpInitializeThread() called for %wZ (%p/%p)\n",
517 NtCurrentTeb()->RealClientId.UniqueProcess,
518 NtCurrentTeb()->RealClientId.UniqueThread);
519
520 /* Acquire the loader Lock */
522
523 /* Allocate an Activation Context Stack */
524 DPRINT("ActivationContextStack %p\n", NtCurrentTeb()->ActivationContextStackPointer);
525 Status = RtlAllocateActivationContextStack(&NtCurrentTeb()->ActivationContextStackPointer);
526 if (!NT_SUCCESS(Status))
527 {
528 DPRINT1("Warning: Unable to allocate ActivationContextStack\n");
529 }
530
531 /* Make sure we are not shutting down */
533
534 /* Allocate TLS */
536
537 /* Start at the beginning */
538 ListHead = &Peb->Ldr->InMemoryOrderModuleList;
539 NextEntry = ListHead->Flink;
540 while (NextEntry != ListHead)
541 {
542 /* Get the current entry */
543 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
544
545 /* Make sure it's not ourselves */
546 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
547 {
548 /* Check if we should call */
549 if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS))
550 {
551 /* Get the entrypoint */
552 EntryPoint = LdrEntry->EntryPoint;
553
554 /* Check if we are ready to call it */
555 if ((EntryPoint) &&
556 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
557 (LdrEntry->Flags & LDRP_IMAGE_DLL))
558 {
559 /* Set up the Act Ctx */
560 ActCtx.Size = sizeof(ActCtx);
561 ActCtx.Format = 1;
563
564 /* Activate the ActCtx */
565 RtlActivateActivationContextUnsafeFast(&ActCtx,
567
569 {
570 /* Check if it has TLS */
571 if (LdrEntry->TlsIndex)
572 {
573 /* Make sure we're not shutting down */
575 {
576 /* Call TLS */
578 }
579 }
580
581 /* Make sure we're not shutting down */
583 {
584 /* Call the Entrypoint */
585 DPRINT("%wZ - Calling entry point at %p for thread attaching, %p/%p\n",
586 &LdrEntry->BaseDllName, LdrEntry->EntryPoint,
587 NtCurrentTeb()->RealClientId.UniqueProcess,
588 NtCurrentTeb()->RealClientId.UniqueThread);
590 LdrEntry->DllBase,
592 NULL);
593 }
594 }
596 {
597 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_ATTACH) for %wZ\n",
598 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
599 }
600 _SEH2_END;
601
602 /* Deactivate the ActCtx */
603 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
604 }
605 }
606 }
607
608 /* Next entry */
609 NextEntry = NextEntry->Flink;
610 }
611
612 /* Check for TLS */
614 {
615 /* Set up the Act Ctx */
616 ActCtx.Size = sizeof(ActCtx);
617 ActCtx.Format = 1;
619
620 /* Activate the ActCtx */
621 RtlActivateActivationContextUnsafeFast(&ActCtx,
623
625 {
626 /* Do TLS callbacks */
628 }
630 {
631 /* Do nothing */
632 }
633 _SEH2_END;
634
635 /* Deactivate the ActCtx */
636 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
637 }
638
639Exit:
640
641 /* Release the loader lock */
643
644 DPRINT("LdrpInitializeThread() done\n");
645}
#define DLL_THREAD_ATTACH
Definition: compat.h:132
BOOLEAN LdrpShutdownInProgress
Definition: ldrinit.c:34
BOOLEAN LdrpImageHasTls
Definition: ldrinit.c:52
NTSTATUS NTAPI LdrpAllocateTls(VOID)
Definition: ldrinit.c:1329
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:247
#define LDRP_DONT_CALL_FOR_THREADS
Definition: ldrtypes.h:48
#define LDRP_PROCESS_ATTACH_CALLED
Definition: ldrtypes.h:49
VOID NTAPI LdrpCallTlsInitializers(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Reason)
Definition: ldrutils.c:447
BOOLEAN NTAPI LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context)
Definition: ldrutils.c:100
static void Exit(void)
Definition: sock.c:1330
USHORT TlsIndex
Definition: ntddk_ex.h:209

Referenced by LdrpInit().

◆ LdrpInitializeTls()

NTSTATUS NTAPI LdrpInitializeTls ( VOID  )

Definition at line 1266 of file ldrinit.c.

1267{
1268 PLIST_ENTRY NextEntry, ListHead;
1269 PLDR_DATA_TABLE_ENTRY LdrEntry;
1270 PIMAGE_TLS_DIRECTORY TlsDirectory;
1271 PLDRP_TLS_DATA TlsData;
1272 ULONG Size;
1273
1274 /* Initialize the TLS List */
1276
1277 /* Loop all the modules */
1278 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1279 NextEntry = ListHead->Flink;
1280 while (ListHead != NextEntry)
1281 {
1282 /* Get the entry */
1283 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1284 NextEntry = NextEntry->Flink;
1285
1286 /* Get the TLS directory */
1287 TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1288 TRUE,
1290 &Size);
1291
1292 /* Check if we have a directory */
1293 if (!TlsDirectory) continue;
1294
1295 /* Check if the image has TLS */
1297
1298 /* Show debug message */
1299 if (ShowSnaps)
1300 {
1301 DPRINT1("LDR: Tls Found in %wZ at %p\n",
1302 &LdrEntry->BaseDllName,
1303 TlsDirectory);
1304 }
1305
1306 /* Allocate an entry */
1307 TlsData = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LDRP_TLS_DATA));
1308 if (!TlsData) return STATUS_NO_MEMORY;
1309
1310 /* Lock the DLL and mark it for TLS Usage */
1311 LdrEntry->LoadCount = -1;
1312 LdrEntry->TlsIndex = -1;
1313
1314 /* Save the cached TLS data */
1315 TlsData->TlsDirectory = *TlsDirectory;
1316 InsertTailList(&LdrpTlsList, &TlsData->TlsLinks);
1317
1318 /* Update the index */
1321 }
1322
1323 /* Done setting up TLS, allocate entries */
1324 return LdrpAllocateTls();
1325}
LIST_ENTRY TlsLinks
Definition: ntdllp.h:28
int32_t * PLONG
Definition: typedefs.h:58

Referenced by LdrpInitializeProcess().

◆ LdrpInsertMemoryTableEntry()

VOID NTAPI LdrpInsertMemoryTableEntry ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 1556 of file ldrutils.c.

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

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

◆ LdrpLoadDll()

NTSTATUS NTAPI LdrpLoadDll ( IN BOOLEAN  Redirected,
IN PWSTR DllPath  OPTIONAL,
IN PULONG DllCharacteristics  OPTIONAL,
IN PUNICODE_STRING  DllName,
OUT PVOID BaseAddress,
IN BOOLEAN  CallInit 
)

Definition at line 2409 of file ldrutils.c.

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

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

◆ LdrpLoadImportModule()

NTSTATUS NTAPI LdrpLoadImportModule ( IN PWSTR DllPath  OPTIONAL,
IN LPSTR  ImportName,
OUT PLDR_DATA_TABLE_ENTRY DataTableEntry,
OUT PBOOLEAN  Existing 
)

Definition at line 808 of file ldrpe.c.

812{
814 PUNICODE_STRING ImpDescName;
815 const WCHAR *p;
816 BOOLEAN GotExtension;
817 WCHAR c;
820 PTEB Teb = NtCurrentTeb();
821 UNICODE_STRING RedirectedImpDescName;
822 BOOLEAN RedirectedDll;
823
824 DPRINT("LdrpLoadImportModule('%S' '%s' %p %p)\n", DllPath, ImportName, DataTableEntry, Existing);
825
826 RedirectedDll = FALSE;
827 RtlInitEmptyUnicodeString(&RedirectedImpDescName, NULL, 0);
828
829 /* Convert import descriptor name to unicode string */
830 ImpDescName = &Teb->StaticUnicodeString;
831 RtlInitAnsiString(&AnsiString, ImportName);
833 if (!NT_SUCCESS(Status)) return Status;
834
835 /* Find the extension, if present */
836 p = ImpDescName->Buffer + ImpDescName->Length / sizeof(WCHAR) - 1;
837 GotExtension = FALSE;
838 while (p >= ImpDescName->Buffer)
839 {
840 c = *p--;
841 if (c == L'.')
842 {
843 GotExtension = TRUE;
844 break;
845 }
846 else if (c == L'\\')
847 {
848 break;
849 }
850 }
851
852 /* If no extension was found, add the default extension */
853 if (!GotExtension)
854 {
855 /* Check that we have space to add one */
856 if ((ImpDescName->Length + LdrApiDefaultExtension.Length + sizeof(UNICODE_NULL)) >=
857 sizeof(Teb->StaticUnicodeBuffer))
858 {
859 /* No space to add the extension */
862 "LDR: %s - Dll name missing extension; with extension "
863 "added the name is too long\n"
864 " ImpDescName: (@ %p) \"%wZ\"\n"
865 " ImpDescName->Length: %u\n",
867 ImpDescName,
868 ImpDescName,
869 ImpDescName->Length);
871 }
872
873 /* Add it. Needs to be null terminated, thus the length check above */
876 }
877
878 /* Check if the SxS Assemblies specify another file */
880 ImpDescName, &LdrApiDefaultExtension, NULL, &RedirectedImpDescName, &ImpDescName, &RedirectedDll);
881
882 if (!NT_SUCCESS(Status))
883 {
884 /* Unrecoverable SxS failure */
885 DPRINT1("LDR: LdrpApplyFileNameRedirection failed with status %x for dll %wZ\n", Status, ImpDescName);
886 goto done;
887 }
888
889 /* Check if it's loaded */
891 ImpDescName,
892 TRUE,
893 RedirectedDll,
894 DataTableEntry))
895 {
896 /* It's already existing in the list */
897 *Existing = TRUE;
899 goto done;
900 }
901
902 /* We're loading it for the first time */
903 *Existing = FALSE;
904
905 /* Map it */
907 NULL,
908 ImpDescName->Buffer,
909 NULL,
910 TRUE,
911 RedirectedDll,
912 DataTableEntry);
913 if (!NT_SUCCESS(Status))
914 {
915 DPRINT1("LDR: LdrpMapDll failed with status %x for dll %wZ\n", Status, ImpDescName);
916 goto done;
917 }
918
919 /* Walk its import descriptor table */
921 *DataTableEntry);
922 if (!NT_SUCCESS(Status))
923 {
924 /* Add it to the in-init-order list in case of failure */
926 &(*DataTableEntry)->InInitializationOrderLinks);
927 }
928
929done:
930 RtlFreeUnicodeString(&RedirectedImpDescName);
931
932 return Status;
933}
@ AnsiString
Definition: dnslib.h:19
NTSYSAPI PEB *WINAPI RtlGetCurrentPeb(void)
Definition: libsupp.c:65
NTSTATUS NTAPI LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrpe.c:670
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
NTSYSAPI NTSTATUS NTAPI LdrpApplyFileNameRedirection(_In_ PUNICODE_STRING OriginalName, _In_ PUNICODE_STRING Extension, _Inout_opt_ PUNICODE_STRING StaticString, _Inout_opt_ PUNICODE_STRING DynamicString, _Inout_ PUNICODE_STRING *NewName, _Inout_ PBOOLEAN RedirectedDll)
NTSTATUS NTAPI LdrpMapDll(IN PWSTR SearchPath OPTIONAL, IN PWSTR DllPath2, IN PWSTR DllName OPTIONAL, IN PULONG DllCharacteristics, IN BOOLEAN Static, IN BOOLEAN Redirect, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
Definition: ldrutils.c:997
BOOLEAN NTAPI LdrpCheckForLoadedDll(IN PWSTR DllPath, IN PUNICODE_STRING DllName, IN BOOLEAN Flag, IN BOOLEAN RedirectedDll, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
Definition: ldrutils.c:1953
WCHAR StaticUnicodeBuffer[261]
Definition: compat.h:877
UNICODE_STRING StaticUnicodeString
Definition: compat.h:876

Referenced by LdrpHandleOneNewFormatImportDescriptor(), and LdrpHandleOneOldFormatImportDescriptor().

◆ LdrpLoadShimEngine()

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

Definition at line 2752 of file ldrutils.c.

2753{
2754 UNICODE_STRING ShimLibraryName;
2755 PVOID ShimLibrary;
2757 RtlInitUnicodeString(&ShimLibraryName, ImageName);
2758 /* We should NOT pass CallInit = TRUE!
2759 If we do this, other init routines will be called before we get a chance to shim stuff.. */
2760 Status = LdrpLoadDll(FALSE, NULL, NULL, &ShimLibraryName, &ShimLibrary, FALSE);
2761 if (NT_SUCCESS(Status))
2762 {
2763 g_pShimEngineModule = ShimLibrary;
2766 if (g_ShimsEnabled)
2767 {
2770 SE_InstallBeforeInit(ProcessImage, pShimData);
2771 }
2772 }
2773}
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
PVOID g_pfnSE_InstallBeforeInit
Definition: ldrutils.c:25
NTSTATUS NTAPI LdrpLoadDll(IN BOOLEAN Redirected, IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress, IN BOOLEAN CallInit)
Definition: ldrutils.c:2409
PVOID g_pShimEngineModule
Definition: ldrutils.c:22
VOID NTAPI LdrpRunShimEngineInitRoutine(IN ULONG Reason)
Definition: ldrutils.c:2717
VOID NTAPI LdrpGetShimEngineInterface()
Definition: ldrutils.c:2692
static const char * ImageName
Definition: image.c:34
VOID NTAPI SE_InstallBeforeInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1417

Referenced by LdrpInitializeProcess().

◆ LdrpMapDll()

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

Definition at line 997 of file ldrutils.c.

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

Referenced by LdrpLoadDll(), and LdrpLoadImportModule().

◆ LdrpRecordUnloadEvent()

VOID NTAPI LdrpRecordUnloadEvent ( _In_ PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 28 of file trace.c.

29{
30 PIMAGE_NT_HEADERS NtHeaders;
33 USHORT StringLen;
34
35 DPRINT("LdrpRecordUnloadEvent(%wZ, %p - %p)\n", &LdrEntry->BaseDllName, LdrEntry->DllBase,
36 (ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage);
37
38 RtlpUnloadEventTrace[Index].BaseAddress = LdrEntry->DllBase;
39 RtlpUnloadEventTrace[Index].SizeOfImage = LdrEntry->SizeOfImage;
41
42 NtHeaders = RtlImageNtHeader(LdrEntry->DllBase);
43
44 if (NtHeaders)
45 {
48 }
49 else
50 {
53 }
54
55 StringLen = min(LdrEntry->BaseDllName.Length / sizeof(WCHAR), RTL_NUMBER_OF(RtlpUnloadEventTrace[Index].ImageName));
56 RtlCopyMemory(RtlpUnloadEventTrace[Index].ImageName, LdrEntry->BaseDllName.Buffer, StringLen * sizeof(WCHAR));
58 RtlpUnloadEventTrace[Index].ImageName[StringLen] = 0;
59}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define RTL_UNLOAD_EVENT_TRACE_NUMBER
Definition: rtltypes.h:1231
static RTL_UNLOAD_EVENT_TRACE RtlpUnloadEventTrace[RTL_UNLOAD_EVENT_TRACE_NUMBER]
Definition: trace.c:13
static UINT RtlpUnloadEventTraceIndex
Definition: trace.c:14
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by LdrUnloadDll().

◆ LdrpRunInitializeRoutines()

NTSTATUS NTAPI LdrpRunInitializeRoutines ( IN PCONTEXT Context  OPTIONAL)

Definition at line 649 of file ldrinit.c.

650{
651 PLDR_DATA_TABLE_ENTRY LocalArray[16];
652 PLIST_ENTRY ListHead;
653 PLIST_ENTRY NextEntry;
654 PLDR_DATA_TABLE_ENTRY LdrEntry, *LdrRootEntry, OldInitializer;
655 PVOID EntryPoint;
656 ULONG Count, i;
657 //ULONG BreakOnInit;
660 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
661 ULONG BreakOnDllLoad;
662 PTEB OldTldTeb;
663 BOOLEAN DllStatus;
664
665 DPRINT("LdrpRunInitializeRoutines() called for %wZ (%p/%p)\n",
667 NtCurrentTeb()->RealClientId.UniqueProcess,
668 NtCurrentTeb()->RealClientId.UniqueThread);
669
670 /* Check the Loader Lock */
672
673 /* Get the number of entries to call */
675 {
676 /* Check if we can use our local buffer */
677 if (Count > 16)
678 {
679 /* Allocate space for all the entries */
680 LdrRootEntry = RtlAllocateHeap(LdrpHeap,
681 0,
682 Count * sizeof(*LdrRootEntry));
683 if (!LdrRootEntry) return STATUS_NO_MEMORY;
684 }
685 else
686 {
687 /* Use our local array */
688 LdrRootEntry = LocalArray;
689 }
690 }
691 else
692 {
693 /* Don't need one */
694 LdrRootEntry = NULL;
695 }
696
697 /* Show debug message */
698 if (ShowSnaps)
699 {
700 DPRINT1("[%p,%p] LDR: Real INIT LIST for Process %wZ\n",
701 NtCurrentTeb()->RealClientId.UniqueThread,
702 NtCurrentTeb()->RealClientId.UniqueProcess,
704 }
705
706 /* Loop in order */
708 NextEntry = ListHead->Flink;
709 i = 0;
710 while (NextEntry != ListHead)
711 {
712 /* Get the Data Entry */
713 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
714
715 /* Check if we have a Root Entry */
716 if (LdrRootEntry)
717 {
718 /* Check flags */
719 if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
720 {
721 /* Setup the Cookie for the DLL */
722 LdrpInitSecurityCookie(LdrEntry);
723
724 /* Check for valid entrypoint */
725 if (LdrEntry->EntryPoint)
726 {
727 /* Write in array */
728 ASSERT(i < Count);
729 LdrRootEntry[i] = LdrEntry;
730
731 /* Display debug message */
732 if (ShowSnaps)
733 {
734 DPRINT1("[%p,%p] LDR: %wZ init routine %p\n",
735 NtCurrentTeb()->RealClientId.UniqueThread,
736 NtCurrentTeb()->RealClientId.UniqueProcess,
737 &LdrEntry->FullDllName,
738 LdrEntry->EntryPoint);
739 }
740 i++;
741 }
742 }
743 }
744
745 /* Set the flag */
746 LdrEntry->Flags |= LDRP_ENTRY_PROCESSED;
747 NextEntry = NextEntry->Flink;
748 }
749
751
752 /* If we got a context, then we have to call Kernel32 for TS support */
753 if (Context)
754 {
755 /* Check if we have one */
756 if (Kernel32ProcessInitPostImportFunction)
757 {
758 /* Call it */
759 Status = Kernel32ProcessInitPostImportFunction();
760 if (!NT_SUCCESS(Status))
761 {
762 DPRINT1("LDR: LdrpRunInitializeRoutines - Failed running kernel32 post-import function, Status=0x%08lx\n", Status);
763 }
764 }
765 /* Clear it */
766 Kernel32ProcessInitPostImportFunction = NULL;
767 }
768
769 /* No root entry? return */
770 if (!LdrRootEntry)
771 return Status;
772
773 /* Set the TLD TEB */
776
777 /* Loop */
778 i = 0;
779 while (i < Count)
780 {
781 /* Get an entry */
782 LdrEntry = LdrRootEntry[i];
783
784 /* FIXME: Verify NX Compat */
785
786 /* Move to next entry */
787 i++;
788
789 /* Get its entrypoint */
790 EntryPoint = LdrEntry->EntryPoint;
791
792 /* Are we being debugged? */
793 BreakOnDllLoad = 0;
795 {
796 /* Check if we should break on load */
798 L"BreakOnDllLoad",
799 REG_DWORD,
800 &BreakOnDllLoad,
801 sizeof(ULONG),
802 NULL);
803 if (!NT_SUCCESS(Status)) BreakOnDllLoad = 0;
804
805 /* Reset status back to STATUS_SUCCESS */
807 }
808
809 /* Break if aksed */
810 if (BreakOnDllLoad)
811 {
812 /* Check if we should show a message */
813 if (ShowSnaps)
814 {
815 DPRINT1("LDR: %wZ loaded.", &LdrEntry->BaseDllName);
816 DPRINT1(" - About to call init routine at %p\n", EntryPoint);
817 }
818
819 /* Break in debugger */
821 }
822
823 /* Make sure we have an entrypoint */
824 if (EntryPoint)
825 {
826 /* Save the old Dll Initializer and write the current one */
827 OldInitializer = LdrpCurrentDllInitializer;
828 LdrpCurrentDllInitializer = LdrEntry;
829
830 /* Set up the Act Ctx */
831 ActCtx.Size = sizeof(ActCtx);
832 ActCtx.Format = 1;
834
835 /* Activate the ActCtx */
836 RtlActivateActivationContextUnsafeFast(&ActCtx,
838
840 {
841 /* Check if it has TLS */
842 if (LdrEntry->TlsIndex && Context)
843 {
844 /* Call TLS */
846 }
847
848 /* Call the Entrypoint */
849 if (ShowSnaps)
850 {
851 DPRINT1("%wZ - Calling entry point at %p for DLL_PROCESS_ATTACH\n",
852 &LdrEntry->BaseDllName, EntryPoint);
853 }
854 DllStatus = LdrpCallInitRoutine(EntryPoint,
855 LdrEntry->DllBase,
857 Context);
858 }
860 {
861 DllStatus = FALSE;
862 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_ATTACH) for %wZ\n",
863 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
864 }
865 _SEH2_END;
866
867 /* Deactivate the ActCtx */
868 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
869
870 /* Save the Current DLL Initializer */
871 LdrpCurrentDllInitializer = OldInitializer;
872
873 /* Mark the entry as processed */
875
876 /* Fail if DLL init failed */
877 if (!DllStatus)
878 {
879 DPRINT1("LDR: DLL_PROCESS_ATTACH for dll \"%wZ\" (InitRoutine: %p) failed\n",
880 &LdrEntry->BaseDllName, EntryPoint);
881
883 goto Quickie;
884 }
885 }
886 }
887
888 /* Loop in order */
890 NextEntry = NextEntry->Flink;
891 while (NextEntry != ListHead)
892 {
893 /* Get the Data Entry */
894 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
895
896 /* FIXME: Verify NX Compat */
897 // LdrpCheckNXCompatibility()
898
899 /* Next entry */
900 NextEntry = NextEntry->Flink;
901 }
902
903 /* Check for TLS */
905 {
906 /* Set up the Act Ctx */
907 ActCtx.Size = sizeof(ActCtx);
908 ActCtx.Format = 1;
910
911 /* Activate the ActCtx */
912 RtlActivateActivationContextUnsafeFast(&ActCtx,
914
916 {
917 /* Do TLS callbacks */
919 }
921 {
922 /* Do nothing */
923 }
924 _SEH2_END;
925
926 /* Deactivate the ActCtx */
927 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
928 }
929
930Quickie:
931 /* Restore old TEB */
933
934 /* Check if the array is in the heap */
935 if (LdrRootEntry != LocalArray)
936 {
937 /* Free the array */
938 RtlFreeHeap(LdrpHeap, 0, LdrRootEntry);
939 }
940
941 /* Return to caller */
942 DPRINT("LdrpRunInitializeRoutines() done\n");
943 return Status;
944}
PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer
Definition: ldrinit.c:43
NTSTATUS NTAPI LdrQueryImageFileExecutionOptions(_In_ PUNICODE_STRING SubKey, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength)
Definition: ldrinit.c:389
PVOID NTAPI LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrinit.c:453
PTEB LdrpTopLevelDllBeingLoadedTeb
Definition: libsupp.c:20
VOID NTAPI LdrpEnsureLoaderLockIsHeld(VOID)
Definition: ldrinit.c:409
int Count
Definition: noreturn.cpp:7
ULONG NTAPI LdrpClearLoadInProgress(VOID)
Definition: ldrutils.c:2644
#define STATUS_DLL_INIT_FAILED
Definition: ntstatus.h:558
BOOLEAN ReadImageFileExecOptions
Definition: ntddk_ex.h:240

Referenced by LdrpGetProcedureAddress(), LdrpInitializeProcess(), and LdrpLoadDll().

◆ LdrpSetProtection()

NTSTATUS NTAPI LdrpSetProtection ( PVOID  ViewBase,
BOOLEAN  Restore 
)

Definition at line 921 of file ldrutils.c.

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

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

◆ LdrpSnapThunk()

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 at line 937 of file ldrpe.c.

945{
946 BOOLEAN IsOrdinal;
947 USHORT Ordinal;
948 ULONG OriginalOrdinal = 0;
949 PIMAGE_IMPORT_BY_NAME AddressOfData;
950 PULONG NameTable;
951 PUSHORT OrdinalTable;
952 LPSTR ImportName = NULL, DotPosition;
953 USHORT Hint;
955 ULONG_PTR HardErrorParameters[3];
956 UNICODE_STRING HardErrorDllName, HardErrorEntryPointName;
957 ANSI_STRING TempString;
958 ULONG Mask;
960 PULONG AddressOfFunctions;
961 UNICODE_STRING TempUString;
962 ANSI_STRING ForwarderName;
963 PANSI_STRING ForwardName;
964 PVOID ForwarderHandle;
965 ULONG ForwardOrdinal;
966
967 /* Check if the snap is by ordinal */
968 if ((IsOrdinal = IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal)))
969 {
970 /* Get the ordinal number, and its normalized version */
971 OriginalOrdinal = IMAGE_ORDINAL(OriginalThunk->u1.Ordinal);
972 Ordinal = (USHORT)(OriginalOrdinal - ExportDirectory->Base);
973 }
974 else
975 {
976 /* First get the data VA */
977 AddressOfData = (PIMAGE_IMPORT_BY_NAME)
978 ((ULONG_PTR)ImportBase +
979 ((ULONG_PTR)OriginalThunk->u1.AddressOfData & 0xffffffff));
980
981 /* Get the name */
982 ImportName = (LPSTR)AddressOfData->Name;
983
984 /* Now get the VA of the Name and Ordinal Tables */
985 NameTable = (PULONG)((ULONG_PTR)ExportBase +
986 (ULONG_PTR)ExportDirectory->AddressOfNames);
987 OrdinalTable = (PUSHORT)((ULONG_PTR)ExportBase +
988 (ULONG_PTR)ExportDirectory->AddressOfNameOrdinals);
989
990 /* Get the hint */
991 Hint = AddressOfData->Hint;
992
993 /* Try to get a match by using the hint */
994 if (((ULONG)Hint < ExportDirectory->NumberOfNames) &&
995 (!strcmp(ImportName, ((LPSTR)((ULONG_PTR)ExportBase + NameTable[Hint])))))
996 {
997 /* We got a match, get the Ordinal from the hint */
998 Ordinal = OrdinalTable[Hint];
999 }
1000 else
1001 {
1002 /* Well bummer, hint didn't work, do it the long way */
1003 Ordinal = LdrpNameToOrdinal(ImportName,
1004 ExportDirectory->NumberOfNames,
1005 ExportBase,
1006 NameTable,
1007 OrdinalTable);
1008 }
1009 }
1010
1011 /* Check if the ordinal is invalid */
1012 if ((ULONG)Ordinal >= ExportDirectory->NumberOfFunctions)
1013 {
1014FailurePath:
1015 /* Is this a static snap? */
1016 if (Static)
1017 {
1018 UNICODE_STRING SnapTarget;
1019 PLDR_DATA_TABLE_ENTRY LdrEntry;
1020
1021 /* What was the module we were searching in */
1022 RtlInitAnsiString(&TempString, DllName ? DllName : "Unknown");
1023
1024 /* What was the module we were searching for */
1025 if (LdrpCheckForLoadedDllHandle(ImportBase, &LdrEntry))
1026 SnapTarget = LdrEntry->BaseDllName;
1027 else
1028 RtlInitUnicodeString(&SnapTarget, L"Unknown");
1029
1030 /* Inform the debug log */
1031 if (IsOrdinal)
1032 DPRINT1("Failed to snap ordinal %Z!0x%x for %wZ\n", &TempString, OriginalOrdinal, &SnapTarget);
1033 else
1034 DPRINT1("Failed to snap %Z!%s for %wZ\n", &TempString, ImportName, &SnapTarget);
1035
1036 /* These are critical errors. Setup a string for the DLL name */
1037 RtlAnsiStringToUnicodeString(&HardErrorDllName, &TempString, TRUE);
1038
1039 /* Set it as the parameter */
1040 HardErrorParameters[1] = (ULONG_PTR)&HardErrorDllName;
1041 Mask = 2;
1042
1043 /* Check if we have an ordinal */
1044 if (IsOrdinal)
1045 {
1046 /* Then set the ordinal as the 1st parameter */
1047 HardErrorParameters[0] = OriginalOrdinal;
1048 }
1049 else
1050 {
1051 /* We don't, use the entrypoint. Set up a string for it */
1052 RtlInitAnsiString(&TempString, ImportName);
1053 RtlAnsiStringToUnicodeString(&HardErrorEntryPointName,
1054 &TempString,
1055 TRUE);
1056
1057 /* Set it as the parameter */
1058 HardErrorParameters[0] = (ULONG_PTR)&HardErrorEntryPointName;
1059 Mask = 3;
1060 }
1061
1062 /* Raise the error */
1065 2,
1066 Mask,
1067 HardErrorParameters,
1068 OptionOk,
1069 &Response);
1070
1071 /* Increase the error count */
1073
1074 /* Free our string */
1075 RtlFreeUnicodeString(&HardErrorDllName);
1076 if (!IsOrdinal)
1077 {
1078 /* Free our second string. Return entrypoint error */
1079 RtlFreeUnicodeString(&HardErrorEntryPointName);
1081 }
1082
1083 /* Return ordinal error */
1085 }
1086 else
1087 {
1088 /* Inform the debug log */
1089 if (IsOrdinal)
1090 DPRINT("Non-fatal: Failed to snap ordinal 0x%x\n", OriginalOrdinal);
1091 else
1092 DPRINT("Non-fatal: Failed to snap %s\n", ImportName);
1093 }
1094
1095 /* Set this as a bad DLL */
1096 Thunk->u1.Function = (ULONG_PTR)0xffbadd11;
1097
1098 /* Return the right error code */
1099 Status = IsOrdinal ? STATUS_ORDINAL_NOT_FOUND :
1101 }
1102 else
1103 {
1104 /* The ordinal seems correct, get the AddressOfFunctions VA */
1105 AddressOfFunctions = (PULONG)
1106 ((ULONG_PTR)ExportBase +
1107 (ULONG_PTR)ExportDirectory->AddressOfFunctions);
1108
1109 /* Write the function pointer*/
1110 Thunk->u1.Function = (ULONG_PTR)ExportBase + AddressOfFunctions[Ordinal];
1111
1112 /* Make sure it's within the exports */
1113 if ((Thunk->u1.Function > (ULONG_PTR)ExportDirectory) &&
1114 (Thunk->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
1115 {
1116 /* Get the Import and Forwarder Names */
1117 ImportName = (LPSTR)Thunk->u1.Function;
1118
1119 DotPosition = strchr(ImportName, '.');
1120 ASSERT(DotPosition != NULL);
1121 if (!DotPosition)
1122 goto FailurePath;
1123
1124 ForwarderName.Buffer = ImportName;
1125 ForwarderName.Length = (USHORT)(DotPosition - ImportName);
1126 ForwarderName.MaximumLength = ForwarderName.Length;
1127 Status = RtlAnsiStringToUnicodeString(&TempUString,
1128 &ForwarderName,
1129 TRUE);
1130
1131 /* Make sure the conversion was OK */
1132 if (NT_SUCCESS(Status))
1133 {
1135 UNICODE_STRING StaticString, *RedirectedImportName;
1136 BOOLEAN Redirected = FALSE;
1137
1138 RtlInitEmptyUnicodeString(&StaticString, StringBuffer, sizeof(StringBuffer));
1139
1140 /* Check if the SxS Assemblies specify another file */
1142 &TempUString, &LdrApiDefaultExtension, &StaticString, NULL, &RedirectedImportName, &Redirected);
1143
1144 if (NT_SUCCESS(Status) && Redirected)
1145 {
1146 if (ShowSnaps)
1147 DPRINT1("LDR: %Z got redirected to %wZ\n", &ForwarderName, RedirectedImportName);
1148 }
1149 else
1150 {
1151 RedirectedImportName = &TempUString;
1152 }
1153
1154 /* Load the forwarder */
1155 Status = LdrpLoadDll(Redirected,
1156 NULL,
1157 NULL,
1158 RedirectedImportName,
1159 &ForwarderHandle,
1160 FALSE);
1161
1162 RtlFreeUnicodeString(&TempUString);
1163 }
1164
1165 /* If the load or conversion failed, use the failure path */
1166 if (!NT_SUCCESS(Status)) goto FailurePath;
1167
1168 /* Now set up a name for the actual forwarder dll */
1169 RtlInitAnsiString(&ForwarderName,
1170 ImportName + ForwarderName.Length + sizeof(CHAR));
1171
1172 /* Check if it's an ordinal forward */
1173 if ((ForwarderName.Length > 1) && (*ForwarderName.Buffer == '#'))
1174 {
1175 /* We don't have an actual function name */
1176 ForwardName = NULL;
1177
1178 /* Convert the string into an ordinal */
1179 Status = RtlCharToInteger(ForwarderName.Buffer + sizeof(CHAR),
1180 0,
1181 &ForwardOrdinal);
1182
1183 /* If this fails, then error out */
1184 if (!NT_SUCCESS(Status)) goto FailurePath;
1185 }
1186 else
1187 {
1188 /* Import by name */
1189 ForwardName = &ForwarderName;
1190 ForwardOrdinal = 0;
1191 }
1192
1193 /* Get the pointer */
1194 Status = LdrpGetProcedureAddress(ForwarderHandle,
1195 ForwardName,
1196 ForwardOrdinal,
1197 (PVOID*)&Thunk->u1.Function,
1198 FALSE);
1199 /* If this fails, then error out */
1200 if (!NT_SUCCESS(Status)) goto FailurePath;
1201 }
1202 else
1203 {
1204 /* It's not within the exports, let's hope it's valid */
1205 if (!AddressOfFunctions[Ordinal]) goto FailurePath;
1206 }
1207
1208 /* If we got here, then it's success */
1210 }
1211
1212 /* Return status */
1213 return Status;
1214}
IN PUNICODE_STRING StaticString
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * strchr(const char *String, int ch)
Definition: utclib.c:501
unsigned int Mask
Definition: fpcontrol.c:82
USHORT NTAPI LdrpNameToOrdinal(IN LPSTR ImportName, IN ULONG NumberOfNames, IN PVOID ExportBase, IN PULONG NameTable, IN PUSHORT OrdinalTable)
Definition: ldrpe.c:628
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
NTSYSAPI NTSTATUS NTAPI RtlCharToInteger(PCSZ String, ULONG Base, PULONG Value)
Definition: unicode.c:261
BOOLEAN NTAPI LdrpCheckForLoadedDllHandle(IN PVOID Base, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
Definition: ldrutils.c:1595
NTSTATUS NTAPI LdrpLoadDll(IN BOOLEAN Redirected, IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress, IN BOOLEAN CallInit)
Definition: ldrutils.c:2409
NTSTATUS NTAPI LdrpGetProcedureAddress(_In_ PVOID BaseAddress, _In_opt_ _When_(Ordinal==0, _Notnull_) PANSI_STRING Name, _In_opt_ _When_(Name==NULL, _In_range_(>, 0)) ULONG Ordinal, _Out_ PVOID *ProcedureAddress, _In_ BOOLEAN ExecuteInit)
Definition: ldrutils.c:2226
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
#define STATUS_ORDINAL_NOT_FOUND
Definition: ntstatus.h:548
#define STATUS_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:549
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
USHORT MaximumLength
Definition: env_spec_w32.h:377
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * PUSHORT
Definition: typedefs.h:56
char * LPSTR
Definition: xmlstorage.h:182
char CHAR
Definition: xmlstorage.h:175

Referenced by LdrpGetProcedureAddress(), and LdrpSnapIAT().

◆ LdrpUnloadShimEngine()

VOID NTAPI LdrpUnloadShimEngine ( VOID  )

◆ LdrpUpdateLoadCount2()

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

Definition at line 434 of file ldrutils.c.

436{
438 UNICODE_STRING UpdateString;
439
440 /* Setup the string and call the extended API */
441 RtlInitEmptyUnicodeString(&UpdateString, Buffer, sizeof(Buffer));
442 LdrpUpdateLoadCount3(LdrEntry, Flags, &UpdateString);
443}
Definition: bufpool.h:45
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().

◆ LdrpValidateImageForMp()

VOID NTAPI LdrpValidateImageForMp ( IN PLDR_DATA_TABLE_ENTRY  LdrDataTableEntry)

Definition at line 1547 of file ldrinit.c.

1548{
1549 DPRINT("LdrpValidateImageForMp is unimplemented\n");
1550 // TODO:
1551 // Scan the LockPrefixTable in the load config directory
1552}

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

◆ LdrpWalkImportDescriptor()

NTSTATUS NTAPI LdrpWalkImportDescriptor ( IN LPWSTR DllPath  OPTIONAL,
IN PLDR_DATA_TABLE_ENTRY  LdrEntry 
)

Definition at line 670 of file ldrpe.c.

672{
673 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
675 NTSTATUS Status = STATUS_SUCCESS, Status2;
677 PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
678 ULONG BoundSize, IatSize;
679
680 DPRINT("LdrpWalkImportDescriptor - BEGIN (%wZ %p '%S')\n", &LdrEntry->BaseDllName, LdrEntry, DllPath);
681
682 /* Set up the Act Ctx */
683 RtlZeroMemory(&ActCtx, sizeof(ActCtx));
684 ActCtx.Size = sizeof(ActCtx);
686
687 /* Check if we have a manifest prober routine */
689 {
690 /* Probe the DLL for its manifest. Some details are omitted */
691 Status2 = LdrpManifestProberRoutine(LdrEntry->DllBase, LdrEntry->FullDllName.Buffer, &LdrEntry->EntryPointActivationContext);
692
693 if (!NT_SUCCESS(Status2) &&
694 Status2 != STATUS_NO_SUCH_FILE &&
699 {
700 /* Some serious issue */
701 //Status = Status2; // FIXME: Ignore that error for now
704 "LDR: LdrpWalkImportDescriptor() failed to probe %wZ for its "
705 "manifest, ntstatus = 0x%08lx\n",
706 &LdrEntry->FullDllName, Status2);
707 }
708 }
709
710 /* Check if we failed above */
711 if (!NT_SUCCESS(Status)) return Status;
712
713 /* Get the Active ActCtx */
714 if (!LdrEntry->EntryPointActivationContext)
715 {
716 Status = RtlGetActiveActivationContext(&LdrEntry->EntryPointActivationContext);
717
718 if (!NT_SUCCESS(Status))
719 {
720 /* Exit */
723 "LDR: RtlGetActiveActivationContext() failed; ntstatus = "
724 "0x%08lx\n",
725 Status);
726 return Status;
727 }
728 }
729
730 /* Activate the ActCtx */
731 RtlActivateActivationContextUnsafeFast(&ActCtx,
732 LdrEntry->EntryPointActivationContext);
733
734 /* Check if we were redirected */
735 if (!(LdrEntry->Flags & LDRP_REDIRECTED))
736 {
737 /* Get the Bound IAT */
738 BoundEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
739 TRUE,
741 &BoundSize);
742 }
743
744 /* Get the regular IAT, for fallback */
745 ImportEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
746 TRUE,
748 &IatSize);
749
750 /* Check if we got at least one */
751 if ((BoundEntry) || (ImportEntry))
752 {
753 /* Do we have a Bound IAT */
754 if (BoundEntry)
755 {
756 /* Handle the descriptor */
758 LdrEntry,
759 BoundEntry);
760 }
761 else
762 {
763 /* Handle the descriptor */
765 LdrEntry,
766 ImportEntry);
767 }
768
769 /* Check the status of the handlers */
770 if (NT_SUCCESS(Status))
771 {
772 /* Check for Per-DLL Heap Tagging */
774 {
775 /* FIXME */
776 DPRINT1("We don't support Per-DLL Heap Tagging yet!\n");
777 }
778
779 /* Check if Page Heap was enabled */
781 {
782 /* Initialize target DLL */
784 }
785
786 /* Check if Application Verifier was enabled */
788 {
789 AVrfDllLoadNotification(LdrEntry);
790 }
791
792 /* Just to be safe */
794 }
795 }
796
797 /* Release the activation context */
798 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
799
800 DPRINT("LdrpWalkImportDescriptor - END (%wZ %p)\n", &LdrEntry->BaseDllName, LdrEntry);
801
802 /* Return status */
803 return Status;
804}
@ DPFLTR_SXS_ID
Definition: dpfilter.h:79
#define FLG_HEAP_PAGE_ALLOCS
Definition: pstypes.h:84
#define FLG_HEAP_ENABLE_TAG_BY_DLL
Definition: pstypes.h:70
NTSYSAPI NTSTATUS WINAPI RtlGetActiveActivationContext(HANDLE *)
Definition: actctx.c:5539
NTSTATUS NTAPI LdrpHandleOldFormatImportDescriptors(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PIMAGE_IMPORT_DESCRIPTOR ImportEntry)
Definition: ldrpe.c:606
PLDR_MANIFEST_PROBER_ROUTINE LdrpManifestProberRoutine
Definition: ldrpe.c:18
NTSTATUS NTAPI LdrpHandleNewFormatImportDescriptors(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry)
Definition: ldrpe.c:492
#define DPFLTR_WARNING_LEVEL
Definition: kdtypes.h:31
#define RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER
Definition: rtltypes.h:101
VOID NTAPI AVrfDllLoadNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: verifier.c:294
VOID NTAPI AVrfPageHeapDllNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: verifier.c:361
#define STATUS_RESOURCE_LANG_NOT_FOUND
Definition: ntstatus.h:648
#define STATUS_RESOURCE_NAME_NOT_FOUND
Definition: ntstatus.h:375
#define STATUS_RESOURCE_TYPE_NOT_FOUND
Definition: ntstatus.h:374
#define STATUS_RESOURCE_DATA_NOT_FOUND
Definition: ntstatus.h:373
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
Definition: pedump.c:270
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137

Referenced by LdrpInitializeProcess(), LdrpLoadDll(), and LdrpLoadImportModule().

◆ RtlDoesFileExists_UStr()

BOOLEAN NTAPI RtlDoesFileExists_UStr ( IN PUNICODE_STRING  FileName)

Definition at line 1503 of file path.c.

1504{
1505 /* Call the updated API */
1507}
BOOLEAN NTAPI RtlDoesFileExists_UstrEx(IN PCUNICODE_STRING FileName, IN BOOLEAN SucceedIfBusy)
Definition: path.c:1430

Referenced by LdrpInitializeDotLocalSupport(), RtlDosApplyFileIsolationRedirection_Ustr(), and START_TEST().

◆ RtlpInitializeKeyedEvent()

VOID NTAPI RtlpInitializeKeyedEvent ( VOID  )

Definition at line 460 of file condvar.c.

461{
464}
static HANDLE CondVarKeyedEventHandle
Definition: condvar.c:42
NTSYSAPI NTSTATUS WINAPI NtCreateKeyedEvent(HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG)
#define EVENT_ALL_ACCESS
Definition: isotest.c:82

Referenced by LdrpInitializeProcess().

◆ RtlpInitializeThreadPooling()

VOID NTAPI RtlpInitializeThreadPooling ( VOID  )

Referenced by LdrpInitializeProcess().

Variable Documentation

◆ g_pfnSE_DllLoaded

PVOID g_pfnSE_DllLoaded
extern

Definition at line 23 of file ldrutils.c.

Referenced by LdrpGetShimEngineInterface(), and LdrpLoadDll().

◆ g_pfnSE_DllUnloaded

PVOID g_pfnSE_DllUnloaded
extern

Definition at line 24 of file ldrutils.c.

Referenced by LdrpGetShimEngineInterface(), and LdrUnloadDll().

◆ g_pfnSE_InstallAfterInit

PVOID g_pfnSE_InstallAfterInit
extern

Definition at line 26 of file ldrutils.c.

Referenced by LdrpGetShimEngineInterface(), and LdrpInitializeProcess().