ReactOS 0.4.15-dev-8138-g1e75ea8
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)
 

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:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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 STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define L(x)
Definition: ntvdm.h:50
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: debug.h:118
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 1321 of file ldrinit.c.

1322{
1323 PTEB Teb = NtCurrentTeb();
1324 PLIST_ENTRY NextEntry, ListHead;
1325 PLDRP_TLS_DATA TlsData;
1326 SIZE_T TlsDataSize;
1327 PVOID *TlsVector;
1328
1329 /* Check if we have any entries */
1331 return STATUS_SUCCESS;
1332
1333 /* Allocate the vector array */
1334 TlsVector = RtlAllocateHeap(RtlGetProcessHeap(),
1335 0,
1336 LdrpNumberOfTlsEntries * sizeof(PVOID));
1337 if (!TlsVector) return STATUS_NO_MEMORY;
1338 Teb->ThreadLocalStoragePointer = TlsVector;
1339
1340 /* Loop the TLS Array */
1341 ListHead = &LdrpTlsList;
1342 NextEntry = ListHead->Flink;
1343 while (NextEntry != ListHead)
1344 {
1345 /* Get the entry */
1346 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1347 NextEntry = NextEntry->Flink;
1348
1349 /* Allocate this vector */
1350 TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
1352 TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
1353 0,
1354 TlsDataSize);
1355 if (!TlsVector[TlsData->TlsDirectory.Characteristics])
1356 {
1357 /* Out of memory */
1358 return STATUS_NO_MEMORY;
1359 }
1360
1361 /* Show debug message */
1362 if (ShowSnaps)
1363 {
1364 DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
1365 TlsVector,
1367 &TlsVector[TlsData->TlsDirectory.Characteristics],
1369 TlsVector[TlsData->TlsDirectory.Characteristics]);
1370 }
1371
1372 /* Copy the data */
1373 RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics],
1375 TlsDataSize);
1376 }
1377
1378 /* Done */
1379 return STATUS_SUCCESS;
1380}
#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 _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOLEAN(NTAPI * PDLL_INIT_ROUTINE)(_In_ PVOID DllHandle, _In_ ULONG Reason, _In_opt_ PCONTEXT Context)
Definition: ldrtypes.h:254
BOOLEAN NTAPI LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context)
Definition: ldrutils.c:100
if(dx< 0)
Definition: linetemp.h:194
BOOLEAN ShowSnaps
Definition: ldrinit.c:81
VOID(NTAPI * PIMAGE_TLS_CALLBACK)(PVOID DllHandle, ULONG Reason, PVOID Reserved)
Definition: ntimage.h:531
#define IMAGE_DIRECTORY_ENTRY_TLS
Definition: pedump.c:268
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
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:4402
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#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:3952
#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:2439

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

◆ LdrpClearLoadInProgress()

ULONG NTAPI LdrpClearLoadInProgress ( VOID  )

Definition at line 2644 of file ldrutils.c.

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

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

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:641
RTL_CRITICAL_SECTION LdrpLoaderLock
Definition: ldrinit.c:70
NTSTATUS NTAPI LdrpSnapThunk(IN PVOID ExportBase, IN PVOID ImportBase, IN PIMAGE_THUNK_DATA OriginalThunk, IN OUT PIMAGE_THUNK_DATA Thunk, IN PIMAGE_EXPORT_DIRECTORY ExportEntry, IN ULONG ExportSize, IN BOOLEAN Static, IN LPSTR DllName)
Definition: ldrpe.c:937
#define STATUS_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::@2139 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 2544 of file ldrinit.c.

2545{
2547 PPEB Peb = NtCurrentPeb();
2548
2549 /* Print a debug message */
2550 DPRINT1("LDR: Process initialization failure for %wZ; NTSTATUS = %08lx\n",
2552
2553 /* Raise a hard error */
2555 {
2557 }
2558}
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 1757 of file ldrinit.c.

1759{
1760 RTL_HEAP_PARAMETERS HeapParameters;
1761 ULONG ComSectionSize;
1762 ANSI_STRING BaseProcessInitPostImportName = RTL_CONSTANT_STRING("BaseProcessInitPostImport");
1763 ANSI_STRING BaseQueryModuleDataName = RTL_CONSTANT_STRING("BaseQueryModuleData");
1764 PVOID OldShimData;
1766 //UNICODE_STRING LocalFileName, FullImageName;
1767 HANDLE SymLinkHandle;
1768 //ULONG DebugHeapOnly;
1769 UNICODE_STRING CommandLine, NtSystemRoot, ImagePathName, FullPath, ImageFileName, KnownDllString;
1770 PPEB Peb = NtCurrentPeb();
1771 BOOLEAN IsDotNetImage = FALSE;
1772 BOOLEAN FreeCurDir = FALSE;
1773 //HANDLE CompatKey;
1774 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
1775 //LPWSTR ImagePathBuffer;
1776 ULONG ConfigSize;
1778 HANDLE OptionsKey;
1779 ULONG HeapFlags;
1780 PIMAGE_NT_HEADERS NtHeader;
1781 LPWSTR NtDllName = NULL;
1782 NTSTATUS Status, ImportStatus;
1783 NLSTABLEINFO NlsTable;
1785 PTEB Teb = NtCurrentTeb();
1786 PLIST_ENTRY ListHead;
1787 PLIST_ENTRY NextEntry;
1788 ULONG i;
1789 PWSTR ImagePath;
1790 ULONG DebugProcessHeapOnly = 0;
1791 PLDR_DATA_TABLE_ENTRY NtLdrEntry;
1792 PWCHAR Current;
1793 ULONG ExecuteOptions = 0;
1794 PVOID ViewBase;
1795
1796 /* Set a NULL SEH Filter */
1798
1799 /* Get the image path */
1801
1802 /* Check if it's not normalized */
1804 {
1805 /* Normalize it*/
1806 ImagePath = (PWSTR)((ULONG_PTR)ImagePath + (ULONG_PTR)Peb->ProcessParameters);
1807 }
1808
1809 /* Create a unicode string for the Image Path */
1811 ImagePathName.MaximumLength = ImagePathName.Length + sizeof(WCHAR);
1812 ImagePathName.Buffer = ImagePath;
1813
1814 /* Get the NT Headers */
1816
1817 /* Get the execution options */
1818 Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &OptionsKey);
1819
1820 /* Check if this is a .NET executable */
1822 TRUE,
1824 &ComSectionSize))
1825 {
1826 /* Remember this for later */
1827 IsDotNetImage = TRUE;
1828 }
1829
1830 /* Save the NTDLL Base address */
1832
1833 /* If this is a Native Image */
1835 {
1836 /* Then do DLL Validation */
1838 }
1839
1840 /* Save the old Shim Data */
1841 OldShimData = Peb->pShimData;
1842
1843 /* ReactOS specific: do not clear it. (Windows starts doing the same in later versions) */
1844 //Peb->pShimData = NULL;
1845
1846 /* Save the number of processors and CS timeout */
1849
1850 /* Normalize the parameters */
1851 ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
1852 if (ProcessParameters)
1853 {
1854 /* Save the Image and Command Line Names */
1855 ImageFileName = ProcessParameters->ImagePathName;
1856 CommandLine = ProcessParameters->CommandLine;
1857 }
1858 else
1859 {
1860 /* It failed, initialize empty strings */
1861 RtlInitUnicodeString(&ImageFileName, NULL);
1862 RtlInitUnicodeString(&CommandLine, NULL);
1863 }
1864
1865 /* Initialize NLS data */
1869 &NlsTable);
1870
1871 /* Reset NLS Translations */
1872 RtlResetRtlTranslations(&NlsTable);
1873
1874 /* Get the Image Config Directory */
1876 TRUE,
1878 &ConfigSize);
1879
1880 /* Setup the Heap Parameters */
1881 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
1882 HeapFlags = HEAP_GROWABLE;
1883 HeapParameters.Length = sizeof(HeapParameters);
1884
1885 /* Check if we have Configuration Data */
1886#define VALID_CONFIG_FIELD(Name) (ConfigSize >= RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, Name))
1887 /* The 'original' load config ends after SecurityCookie */
1888 if ((LoadConfig) && ConfigSize && (VALID_CONFIG_FIELD(SecurityCookie) || ConfigSize == LoadConfig->Size))
1889 {
1890 if (ConfigSize != sizeof(IMAGE_LOAD_CONFIG_DIRECTORY))
1891 DPRINT1("WARN: Accepting different LOAD_CONFIG size!\n");
1892 else
1893 DPRINT1("Applying LOAD_CONFIG\n");
1894
1895 if (VALID_CONFIG_FIELD(GlobalFlagsSet) && LoadConfig->GlobalFlagsSet)
1896 Peb->NtGlobalFlag |= LoadConfig->GlobalFlagsSet;
1897
1898 if (VALID_CONFIG_FIELD(GlobalFlagsClear) && LoadConfig->GlobalFlagsClear)
1899 Peb->NtGlobalFlag &= ~LoadConfig->GlobalFlagsClear;
1900
1901 /* Convert the default CS timeout from milliseconds to 100ns units */
1902 if (VALID_CONFIG_FIELD(CriticalSectionDefaultTimeout) && LoadConfig->CriticalSectionDefaultTimeout)
1903 RtlpTimeout.QuadPart = Int32x32To64(LoadConfig->CriticalSectionDefaultTimeout, -10000);
1904
1905 if (VALID_CONFIG_FIELD(DeCommitFreeBlockThreshold) && LoadConfig->DeCommitFreeBlockThreshold)
1906 HeapParameters.DeCommitFreeBlockThreshold = LoadConfig->DeCommitFreeBlockThreshold;
1907
1908 if (VALID_CONFIG_FIELD(DeCommitTotalFreeThreshold) && LoadConfig->DeCommitTotalFreeThreshold)
1909 HeapParameters.DeCommitTotalFreeThreshold = LoadConfig->DeCommitTotalFreeThreshold;
1910
1911 if (VALID_CONFIG_FIELD(MaximumAllocationSize) && LoadConfig->MaximumAllocationSize)
1912 HeapParameters.MaximumAllocationSize = LoadConfig->MaximumAllocationSize;
1913
1914 if (VALID_CONFIG_FIELD(VirtualMemoryThreshold) && LoadConfig->VirtualMemoryThreshold)
1915 HeapParameters.VirtualMemoryThreshold = LoadConfig->VirtualMemoryThreshold;
1916
1917 if (VALID_CONFIG_FIELD(ProcessHeapFlags) && LoadConfig->ProcessHeapFlags)
1918 HeapFlags = LoadConfig->ProcessHeapFlags;
1919 }
1920#undef VALID_CONFIG_FIELD
1921
1922 /* Check for custom affinity mask */
1924 {
1925 /* Set it */
1929 sizeof(Peb->ImageProcessAffinityMask));
1930 }
1931
1932 /* Check if verbose debugging (ShowSnaps) was requested */
1934
1935 /* Start verbose debugging messages right now if they were requested */
1936 if (ShowSnaps)
1937 {
1938 DPRINT1("LDR: PID: 0x%p started - '%wZ'\n",
1940 &CommandLine);
1941 }
1942
1943 /* If the CS timeout is longer than 1 hour, disable it */
1944 if (RtlpTimeout.QuadPart < Int32x32To64(3600, -10000000))
1946
1947 /* Initialize Critical Section Data */
1949
1950 /* Initialize VEH Call lists */
1952
1953 /* Set TLS/FLS Bitmap data */
1957
1958 /* Initialize FLS Bitmap */
1962 RtlSetBit(&FlsBitMap, 0);
1964
1965 /* Initialize TLS Bitmap */
1969 RtlSetBit(&TlsBitMap, 0);
1974
1975 /* Initialize the Hash Table */
1976 for (i = 0; i < LDR_HASH_TABLE_ENTRIES; i++)
1977 {
1979 }
1980
1981 /* Initialize the Loader Lock */
1982 // FIXME: What's the point of initing it manually, if two lines lower
1983 // a call to RtlInitializeCriticalSection() is being made anyway?
1984 //InsertTailList(&RtlCriticalSectionList, &LdrpLoaderLock.DebugInfo->ProcessLocksList);
1985 //LdrpLoaderLock.DebugInfo->CriticalSection = &LdrpLoaderLock;
1988
1989 /* Check if User Stack Trace Database support was requested */
1991 {
1992 DPRINT1("We don't support user stack trace databases yet\n");
1993 }
1994
1995 /* Setup Fast PEB Lock */
1998 //Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
1999 //Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
2000
2001 /* Setup Callout Lock and Notification list */
2002 //RtlInitializeCriticalSection(&RtlpCalloutEntryLock);
2004
2005 /* For old executables, use 16-byte aligned heap */
2006 if ((NtHeader->OptionalHeader.MajorSubsystemVersion <= 3) &&
2007 (NtHeader->OptionalHeader.MinorSubsystemVersion < 51))
2008 {
2009 HeapFlags |= HEAP_CREATE_ALIGN_16;
2010 }
2011
2012 /* Setup the Heap */
2014 Peb->ProcessHeap = RtlCreateHeap(HeapFlags,
2015 NULL,
2018 NULL,
2019 &HeapParameters);
2020
2021 if (!Peb->ProcessHeap)
2022 {
2023 DPRINT1("Failed to create process heap\n");
2024 return STATUS_NO_MEMORY;
2025 }
2026
2027 /* Allocate an Activation Context Stack */
2028 Status = RtlAllocateActivationContextStack(&Teb->ActivationContextStackPointer);
2029 if (!NT_SUCCESS(Status)) return Status;
2030
2031 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
2032 HeapFlags = HEAP_GROWABLE | HEAP_CLASS_1;
2033 HeapParameters.Length = sizeof(HeapParameters);
2034 LdrpHeap = RtlCreateHeap(HeapFlags, 0, 0x10000, 0x6000, 0, &HeapParameters);
2035 if (!LdrpHeap)
2036 {
2037 DPRINT1("Failed to create loader private heap\n");
2038 return STATUS_NO_MEMORY;
2039 }
2040
2041 /* Check for Debug Heap */
2042 if (OptionsKey)
2043 {
2044 /* Query the setting */
2046 L"DebugProcessHeapOnly",
2047 REG_DWORD,
2048 &DebugProcessHeapOnly,
2049 sizeof(ULONG),
2050 NULL);
2051
2052 if (NT_SUCCESS(Status))
2053 {
2054 /* Reset DPH if requested */
2055 if (RtlpPageHeapEnabled && DebugProcessHeapOnly)
2056 {
2057 RtlpDphGlobalFlags &= ~DPH_FLAG_DLL_NOTIFY;
2059 }
2060 }
2061 }
2062
2063 /* Build the NTDLL Path */
2064 FullPath.Buffer = StringBuffer;
2065 FullPath.Length = 0;
2066 FullPath.MaximumLength = sizeof(StringBuffer);
2069 RtlAppendUnicodeToString(&FullPath, L"\\System32\\");
2070
2071 /* Open the Known DLLs directory */
2072 RtlInitUnicodeString(&KnownDllString, L"\\KnownDlls");
2074 &KnownDllString,
2076 NULL,
2077 NULL);
2081
2082 /* Check if it exists */
2083 if (NT_SUCCESS(Status))
2084 {
2085 /* Open the Known DLLs Path */
2086 RtlInitUnicodeString(&KnownDllString, L"KnownDllPath");
2088 &KnownDllString,
2091 NULL);
2092 Status = NtOpenSymbolicLinkObject(&SymLinkHandle,
2095 if (NT_SUCCESS(Status))
2096 {
2097 /* Query the path */
2101 Status = ZwQuerySymbolicLinkObject(SymLinkHandle, &LdrpKnownDllPath, NULL);
2102 NtClose(SymLinkHandle);
2103 if (!NT_SUCCESS(Status))
2104 {
2105 DPRINT1("LDR: %s - failed call to ZwQuerySymbolicLinkObject with status %x\n", "", Status);
2106 return Status;
2107 }
2108 }
2109 }
2110
2111 /* Check if we failed */
2112 if (!NT_SUCCESS(Status))
2113 {
2114 /* Assume System32 */
2117 LdrpKnownDllPath.Length -= sizeof(WCHAR);
2118 }
2119
2120 /* If we have process parameters, get the default path and current path */
2121 if (ProcessParameters)
2122 {
2123 /* Check if we have a Dll Path */
2124 if (ProcessParameters->DllPath.Length)
2125 {
2126 /* Get the path */
2127 LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath;
2128 }
2129 else
2130 {
2131 /* We need a valid path */
2132 DPRINT1("No valid DllPath was given!\n");
2134 }
2135
2136 /* Set the current directory */
2137 CurrentDirectory = ProcessParameters->CurrentDirectory.DosPath;
2138
2139 /* Check if it's empty or invalid */
2140 if ((!CurrentDirectory.Buffer) ||
2141 (CurrentDirectory.Buffer[0] == UNICODE_NULL) ||
2142 (!CurrentDirectory.Length))
2143 {
2144 /* Allocate space for the buffer */
2146 0,
2147 3 * sizeof(WCHAR) +
2148 sizeof(UNICODE_NULL));
2149 if (!CurrentDirectory.Buffer)
2150 {
2151 DPRINT1("LDR: LdrpInitializeProcess - unable to allocate current working directory buffer\n");
2152 // FIXME: And what?
2153 }
2154
2155 /* Copy the drive of the system root */
2157 SharedUserData->NtSystemRoot,
2158 3 * sizeof(WCHAR));
2159 CurrentDirectory.Buffer[3] = UNICODE_NULL;
2160 CurrentDirectory.Length = 3 * sizeof(WCHAR);
2161 CurrentDirectory.MaximumLength = CurrentDirectory.Length + sizeof(WCHAR);
2162
2163 FreeCurDir = TRUE;
2164 DPRINT("Using dynamically allocd curdir\n");
2165 }
2166 else
2167 {
2168 /* Use the local buffer */
2169 DPRINT("Using local system root\n");
2170 }
2171 }
2172
2173 /* Setup Loader Data */
2174 Peb->Ldr = &PebLdr;
2178 PebLdr.Length = sizeof(PEB_LDR_DATA);
2180
2181 /* Allocate a data entry for the Image */
2183
2184 /* Set it up */
2188 LdrpImageEntry->FullDllName = ImageFileName;
2189
2190 if (IsDotNetImage)
2192 else
2193 LdrpImageEntry->Flags = 0;
2194
2195 /* Check if the name is empty */
2196 if (!ImageFileName.Buffer[0])
2197 {
2198 /* Use the same Base name */
2200 }
2201 else
2202 {
2203 /* Find the last slash */
2204 Current = ImageFileName.Buffer;
2205 while (*Current)
2206 {
2207 if (*Current++ == '\\')
2208 {
2209 /* Set this path */
2210 NtDllName = Current;
2211 }
2212 }
2213
2214 /* Did we find anything? */
2215 if (!NtDllName)
2216 {
2217 /* Use the same Base name */
2219 }
2220 else
2221 {
2222 /* Setup the name */
2223 LdrpImageEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName);
2226 (ImageFileName.Length - LdrpImageEntry->BaseDllName.Length));
2227 }
2228 }
2229
2230 /* Processing done, insert it */
2233
2234 /* Now add an entry for NTDLL */
2236 NtLdrEntry->Flags = LDRP_IMAGE_DLL;
2237 NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase);
2238 NtLdrEntry->LoadCount = -1;
2239 NtLdrEntry->EntryPointActivationContext = 0;
2240
2241 NtLdrEntry->FullDllName.Length = FullPath.Length;
2242 NtLdrEntry->FullDllName.MaximumLength = FullPath.MaximumLength;
2243 NtLdrEntry->FullDllName.Buffer = StringBuffer;
2245
2246 NtLdrEntry->BaseDllName.Length = NtDllString.Length;
2248 NtLdrEntry->BaseDllName.Buffer = NtDllString.Buffer;
2249
2250 /* Processing done, insert it */
2251 LdrpNtDllDataTableEntry = NtLdrEntry;
2252 LdrpInsertMemoryTableEntry(NtLdrEntry);
2253
2254 /* Let the world know */
2255 if (ShowSnaps)
2256 {
2257 DPRINT1("LDR: NEW PROCESS\n");
2258 DPRINT1(" Image Path: %wZ (%wZ)\n", &LdrpImageEntry->FullDllName, &LdrpImageEntry->BaseDllName);
2259 DPRINT1(" Current Directory: %wZ\n", &CurrentDirectory);
2260 DPRINT1(" Search Path: %wZ\n", &LdrpDefaultPath);
2261 }
2262
2263 /* Link the Init Order List */
2266
2267 /* Initialize Wine's active context implementation for the current process */
2268 actctx_init(&OldShimData);
2269
2270 /* Set the current directory */
2272 if (!NT_SUCCESS(Status))
2273 {
2274 /* We failed, check if we should free it */
2275 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2276
2277 /* Set it to the NT Root */
2280 }
2281 else
2282 {
2283 /* We're done with it, free it */
2284 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2285 }
2286
2287 /* Check if we should look for a .local file */
2288 if (ProcessParameters && !(ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH))
2289 {
2290 LdrpInitializeDotLocalSupport(ProcessParameters);
2291 }
2292
2293 /* Check if the Application Verifier was enabled */
2295 {
2297 if (!NT_SUCCESS(Status))
2298 {
2299 DPRINT1("LDR: AVrfInitializeVerifier failed (ntstatus 0x%x)\n", Status);
2300 return Status;
2301 }
2302
2303 }
2304
2305 if (IsDotNetImage)
2306 {
2307 /* FIXME */
2308 DPRINT1("We don't support .NET applications yet\n");
2309 }
2310
2313 {
2314 PVOID Kernel32BaseAddress;
2315 PVOID FunctionAddress;
2316
2317 Status = LdrLoadDll(NULL, NULL, &Kernel32String, &Kernel32BaseAddress);
2318
2319 if (!NT_SUCCESS(Status))
2320 {
2321 if (ShowSnaps)
2322 DPRINT1("LDR: Unable to load %wZ, Status=0x%08lx\n", &Kernel32String, Status);
2323 return Status;
2324 }
2325
2326 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2327 &BaseProcessInitPostImportName,
2328 0,
2329 &FunctionAddress);
2330
2331 if (!NT_SUCCESS(Status))
2332 {
2333 if (ShowSnaps)
2334 DPRINT1("LDR: Unable to find post-import process init function, Status=0x%08lx\n", Status);
2335 return Status;
2336 }
2337 Kernel32ProcessInitPostImportFunction = FunctionAddress;
2338
2339 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2340 &BaseQueryModuleDataName,
2341 0,
2342 &FunctionAddress);
2343
2344 if (!NT_SUCCESS(Status))
2345 {
2346 if (ShowSnaps)
2347 DPRINT1("LDR: Unable to find BaseQueryModuleData, Status=0x%08lx\n", Status);
2348 return Status;
2349 }
2350 Kernel32BaseQueryModuleData = FunctionAddress;
2351 }
2352
2353 /* Walk the IAT and load all the DLLs */
2355
2356 /* Check if relocation is needed */
2358 {
2359 DPRINT1("LDR: Performing EXE relocation\n");
2360
2361 /* Change the protection to prepare for relocation */
2362 ViewBase = Peb->ImageBaseAddress;
2363 Status = LdrpSetProtection(ViewBase, FALSE);
2364 if (!NT_SUCCESS(Status)) return Status;
2365
2366 /* Do the relocation */
2368 0LL,
2369 NULL,
2373 if (!NT_SUCCESS(Status))
2374 {
2375 DPRINT1("LdrRelocateImageWithBias() failed\n");
2376 return Status;
2377 }
2378
2379 /* Check if a start context was provided */
2380 if (Context)
2381 {
2382 DPRINT1("WARNING: Relocated EXE Context");
2383 UNIMPLEMENTED; // We should support this
2385 }
2386
2387 /* Restore the protection */
2388 Status = LdrpSetProtection(ViewBase, TRUE);
2389 if (!NT_SUCCESS(Status)) return Status;
2390 }
2391
2392 /* Lock the DLLs */
2393 ListHead = &Peb->Ldr->InLoadOrderModuleList;
2394 NextEntry = ListHead->Flink;
2395 while (ListHead != NextEntry)
2396 {
2397 NtLdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
2398 NtLdrEntry->LoadCount = -1;
2399 NextEntry = NextEntry->Flink;
2400 }
2401
2402 /* Phase 0 is done */
2404
2405 /* Check whether all static imports were properly loaded and return here */
2406 if (!NT_SUCCESS(ImportStatus)) return ImportStatus;
2407
2408#if (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
2409 /* Initialize the keyed event for condition variables */
2411#endif
2412
2413 /* Initialize TLS */
2415 if (!NT_SUCCESS(Status))
2416 {
2417 DPRINT1("LDR: LdrpProcessInitialization failed to initialize TLS slots; status %x\n",
2418 Status);
2419 return Status;
2420 }
2421
2422 /* FIXME Mark the DLL Ranges for Stack Traces later */
2423
2424 /* Notify the debugger now */
2425 if (Peb->BeingDebugged)
2426 {
2427 /* Break */
2428 DbgBreakPoint();
2429
2430 /* Update show snaps again */
2432 }
2433
2434 /* Validate the Image for MP Usage */
2436
2437 /* Check NX options and set them */
2438 if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSON)
2439 {
2440 ExecuteOptions = MEM_EXECUTE_OPTION_DISABLE |
2443 }
2444 else if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSOFF)
2445 {
2447 }
2450 &ExecuteOptions,
2451 sizeof(ExecuteOptions));
2452 if (!NT_SUCCESS(Status))
2453 {
2454 DPRINT1("LDR: Could not set process execute flags 0x%x; status %x\n",
2455 ExecuteOptions, Status);
2456 }
2457
2458 // FIXME: Should be done by Application Compatibility features,
2459 // by reading the registry, etc...
2460 // For now, this is the old code from ntdll!RtlGetVersion().
2461 RtlInitEmptyUnicodeString(&Peb->CSDVersion, NULL, 0);
2462 if (((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
2463 {
2464 WCHAR szCSDVersion[128];
2465 LONG i;
2466 USHORT Length = (USHORT)ARRAYSIZE(szCSDVersion) - 1;
2467 i = _snwprintf(szCSDVersion, Length,
2468 L"Service Pack %d",
2469 ((Peb->OSCSDVersion >> 8) & 0xFF));
2470 if (i < 0)
2471 {
2472 /* Null-terminate if it was overflowed */
2473 szCSDVersion[Length] = UNICODE_NULL;
2474 }
2475
2476 Length *= sizeof(WCHAR);
2477 Peb->CSDVersion.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
2478 0,
2479 Length + sizeof(UNICODE_NULL));
2480 if (Peb->CSDVersion.Buffer)
2481 {
2484
2486 szCSDVersion,
2489 }
2490 }
2491
2492 /* Check if we had Shim Data */
2493 if (OldShimData)
2494 {
2495 /* Load the Shim Engine */
2497 LdrpLoadShimEngine(OldShimData, &ImagePathName, OldShimData);
2498 }
2499 else
2500 {
2501 /* Check for Application Compatibility Goo */
2502 //LdrQueryApplicationCompatibilityGoo(hKey);
2503 DPRINT("Querying app compat hacks is missing!\n");
2504 }
2505
2506 /*
2507 * FIXME: Check for special images, SecuROM, SafeDisc and other NX-
2508 * incompatible images.
2509 */
2510
2511 /* Now call the Init Routines */
2513 if (!NT_SUCCESS(Status))
2514 {
2515 DPRINT1("LDR: LdrpProcessInitialization failed running initialization routines; status %x\n",
2516 Status);
2517 return Status;
2518 }
2519
2520 /* Notify Shim Engine */
2521 if (g_ShimsEnabled)
2522 {
2525 SE_InstallAfterInit(&ImagePathName, OldShimData);
2526 }
2527
2528 /* Check if we have a user-defined Post Process Routine */
2530 {
2531 /* Call it */
2533 }
2534
2535 /* Close the key if we have one opened */
2536 if (OptionsKey) NtClose(OptionsKey);
2537
2538 /* Return status */
2539 return Status;
2540}
#define VOID
Definition: acefi.h:82
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
struct _PEB_LDR_DATA PEB_LDR_DATA
#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:310
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
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:1696
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:1420
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:1539
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:641
BOOLEAN LdrpLdrDatabaseIsSetup
Definition: ldrinit.c:33
VOID NTAPI RtlpInitializeVectoredExceptionHandling(VOID)
Definition: vectoreh.c:30
void actctx_init(PVOID *pOldShimData)
Definition: actctx.c:5113
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:2544
PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry
Definition: ldrinit.c:44
NTSTATUS NTAPI LdrpInitializeTls(VOID)
Definition: ldrinit.c:1258
#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
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 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:1105
#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:167
#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:1070
#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
NTSYSAPI VOID NTAPI RtlSetBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:304
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 /* Allocate an Activation Context Stack */
521 DPRINT("ActivationContextStack %p\n", NtCurrentTeb()->ActivationContextStackPointer);
522 Status = RtlAllocateActivationContextStack(&NtCurrentTeb()->ActivationContextStackPointer);
523 if (!NT_SUCCESS(Status))
524 {
525 DPRINT1("Warning: Unable to allocate ActivationContextStack\n");
526 }
527
528 /* Make sure we are not shutting down */
529 if (LdrpShutdownInProgress) return;
530
531 /* Allocate TLS */
533
534 /* Start at the beginning */
535 ListHead = &Peb->Ldr->InMemoryOrderModuleList;
536 NextEntry = ListHead->Flink;
537 while (NextEntry != ListHead)
538 {
539 /* Get the current entry */
540 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
541
542 /* Make sure it's not ourselves */
543 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
544 {
545 /* Check if we should call */
546 if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS))
547 {
548 /* Get the entrypoint */
549 EntryPoint = LdrEntry->EntryPoint;
550
551 /* Check if we are ready to call it */
552 if ((EntryPoint) &&
553 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
554 (LdrEntry->Flags & LDRP_IMAGE_DLL))
555 {
556 /* Set up the Act Ctx */
557 ActCtx.Size = sizeof(ActCtx);
558 ActCtx.Format = 1;
560
561 /* Activate the ActCtx */
562 RtlActivateActivationContextUnsafeFast(&ActCtx,
564
566 {
567 /* Check if it has TLS */
568 if (LdrEntry->TlsIndex)
569 {
570 /* Make sure we're not shutting down */
572 {
573 /* Call TLS */
575 }
576 }
577
578 /* Make sure we're not shutting down */
580 {
581 /* Call the Entrypoint */
582 DPRINT("%wZ - Calling entry point at %p for thread attaching, %p/%p\n",
583 &LdrEntry->BaseDllName, LdrEntry->EntryPoint,
584 NtCurrentTeb()->RealClientId.UniqueProcess,
585 NtCurrentTeb()->RealClientId.UniqueThread);
587 LdrEntry->DllBase,
589 NULL);
590 }
591 }
593 {
594 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_ATTACH) for %wZ\n",
595 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
596 }
597 _SEH2_END;
598
599 /* Deactivate the ActCtx */
600 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
601 }
602 }
603 }
604
605 /* Next entry */
606 NextEntry = NextEntry->Flink;
607 }
608
609 /* Check for TLS */
611 {
612 /* Set up the Act Ctx */
613 ActCtx.Size = sizeof(ActCtx);
614 ActCtx.Format = 1;
616
617 /* Activate the ActCtx */
618 RtlActivateActivationContextUnsafeFast(&ActCtx,
620
622 {
623 /* Do TLS callbacks */
625 }
627 {
628 /* Do nothing */
629 }
630 _SEH2_END;
631
632 /* Deactivate the ActCtx */
633 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
634 }
635
636 DPRINT("LdrpInitializeThread() done\n");
637}
#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:1321
_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
USHORT TlsIndex
Definition: ntddk_ex.h:209

Referenced by LdrpInit().

◆ LdrpInitializeTls()

NTSTATUS NTAPI LdrpInitializeTls ( VOID  )

Definition at line 1258 of file ldrinit.c.

1259{
1260 PLIST_ENTRY NextEntry, ListHead;
1261 PLDR_DATA_TABLE_ENTRY LdrEntry;
1262 PIMAGE_TLS_DIRECTORY TlsDirectory;
1263 PLDRP_TLS_DATA TlsData;
1264 ULONG Size;
1265
1266 /* Initialize the TLS List */
1268
1269 /* Loop all the modules */
1270 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1271 NextEntry = ListHead->Flink;
1272 while (ListHead != NextEntry)
1273 {
1274 /* Get the entry */
1275 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1276 NextEntry = NextEntry->Flink;
1277
1278 /* Get the TLS directory */
1279 TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1280 TRUE,
1282 &Size);
1283
1284 /* Check if we have a directory */
1285 if (!TlsDirectory) continue;
1286
1287 /* Check if the image has TLS */
1289
1290 /* Show debug message */
1291 if (ShowSnaps)
1292 {
1293 DPRINT1("LDR: Tls Found in %wZ at %p\n",
1294 &LdrEntry->BaseDllName,
1295 TlsDirectory);
1296 }
1297
1298 /* Allocate an entry */
1299 TlsData = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LDRP_TLS_DATA));
1300 if (!TlsData) return STATUS_NO_MEMORY;
1301
1302 /* Lock the DLL and mark it for TLS Usage */
1303 LdrEntry->LoadCount = -1;
1304 LdrEntry->TlsIndex = -1;
1305
1306 /* Save the cached TLS data */
1307 TlsData->TlsDirectory = *TlsDirectory;
1308 InsertTailList(&LdrpTlsList, &TlsData->TlsLinks);
1309
1310 /* Update the index */
1313 }
1314
1315 /* Done setting up TLS, allocate entries */
1316 return LdrpAllocateTls();
1317}
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
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_LEAVE
Definition: filesup.c:20
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
#define c
Definition: ke_i.h:80
NTSTATUS NTAPI LdrUnloadDll(_In_ PVOID BaseAddress)
Definition: ldrapi.c:1291
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 ULONG __cdecl DbgPrintEx(_In_ ULONG ComponentId, _In_ ULONG Level, _In_z_ _Printf_format_string_ PCSTR Format,...)
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
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
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:1539
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:3900

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 641 of file ldrinit.c.

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

1540{
1542}

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:5528
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().

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().

◆ g_pfnSE_InstallBeforeInit

PVOID g_pfnSE_InstallBeforeInit
extern

Definition at line 25 of file ldrutils.c.

Referenced by LdrpGetShimEngineInterface(), and LdrpLoadShimEngine().

◆ g_pfnSE_ProcessDying

PVOID g_pfnSE_ProcessDying
extern

Definition at line 27 of file ldrutils.c.

Referenced by LdrpGetShimEngineInterface(), and LdrShutdownProcess().

◆ g_pShimEngineModule

◆ g_ShimsEnabled

◆ LdrApiDefaultExtension

UNICODE_STRING LdrApiDefaultExtension
extern

Definition at line 22 of file ldrapi.c.

Referenced by LdrGetDllHandleEx(),