ReactOS 0.4.15-dev-6662-g1b3eed5
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)
 
NTSTATUS NTAPI LdrpGetProcedureAddress (IN PVOID BaseAddress, IN PANSI_STRING Name, IN 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)
 

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 198 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:588
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#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:1165
__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:115
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 1549 of file ldrutils.c.

1550{
1551 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
1552 PIMAGE_NT_HEADERS NtHeader;
1553
1554 /* Make sure the header is valid */
1555 NtHeader = RtlImageNtHeader(BaseAddress);
1556 DPRINT("LdrpAllocateDataTableEntry(%p), NtHeader %p\n", BaseAddress, NtHeader);
1557
1558 if (NtHeader)
1559 {
1560 /* Allocate an entry */
1561 LdrEntry = RtlAllocateHeap(LdrpHeap,
1563 sizeof(LDR_DATA_TABLE_ENTRY));
1564
1565 /* Make sure we got one */
1566 if (LdrEntry)
1567 {
1568 /* Set it up */
1569 LdrEntry->DllBase = BaseAddress;
1570 LdrEntry->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
1571 LdrEntry->TimeDateStamp = NtHeader->FileHeader.TimeDateStamp;
1572 LdrEntry->PatchInformation = NULL;
1573 }
1574 }
1575
1576 /* Return the entry */
1577 return LdrEntry;
1578}
#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:71
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
Definition: btrfs_drv.h:1876
ULONG SizeOfImage
Definition: ldrtypes.h:143
PVOID DllBase
Definition: btrfs_drv.h:1880
ULONG TimeDateStamp
Definition: btrfs_drv.h:1889
PVOID PatchInformation
Definition: ldrtypes.h:164

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

◆ LdrpAllocateTls()

NTSTATUS NTAPI LdrpAllocateTls ( VOID  )

Definition at line 1317 of file ldrinit.c.

1318{
1319 PTEB Teb = NtCurrentTeb();
1320 PLIST_ENTRY NextEntry, ListHead;
1321 PLDRP_TLS_DATA TlsData;
1322 SIZE_T TlsDataSize;
1323 PVOID *TlsVector;
1324
1325 /* Check if we have any entries */
1327 return STATUS_SUCCESS;
1328
1329 /* Allocate the vector array */
1330 TlsVector = RtlAllocateHeap(RtlGetProcessHeap(),
1331 0,
1332 LdrpNumberOfTlsEntries * sizeof(PVOID));
1333 if (!TlsVector) return STATUS_NO_MEMORY;
1334 Teb->ThreadLocalStoragePointer = TlsVector;
1335
1336 /* Loop the TLS Array */
1337 ListHead = &LdrpTlsList;
1338 NextEntry = ListHead->Flink;
1339 while (NextEntry != ListHead)
1340 {
1341 /* Get the entry */
1342 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1343 NextEntry = NextEntry->Flink;
1344
1345 /* Allocate this vector */
1346 TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
1348 TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
1349 0,
1350 TlsDataSize);
1351 if (!TlsVector[TlsData->TlsDirectory.Characteristics])
1352 {
1353 /* Out of memory */
1354 return STATUS_NO_MEMORY;
1355 }
1356
1357 /* Show debug message */
1358 if (ShowSnaps)
1359 {
1360 DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
1361 TlsVector,
1363 &TlsVector[TlsData->TlsDirectory.Characteristics],
1365 TlsVector[TlsData->TlsDirectory.Characteristics]);
1366 }
1367
1368 /* Copy the data */
1369 RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics],
1371 TlsDataSize);
1372 }
1373
1374 /* Done */
1375 return STATUS_SUCCESS;
1376}
#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().

◆ LdrpCallInitRoutine()

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

Definition at line 100 of file ldrutils.c.

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

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

◆ LdrpCallTlsInitializers()

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

Definition at line 473 of file ldrutils.c.

475{
476 PIMAGE_TLS_DIRECTORY TlsDirectory;
478 ULONG Size;
479
480 /* Get the TLS Directory */
481 TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
482 TRUE,
484 &Size);
485
486 /* Protect against invalid pointers */
488 {
489 /* Make sure it's valid */
490 if (TlsDirectory)
491 {
492 /* Get the array */
493 Array = (PIMAGE_TLS_CALLBACK *)TlsDirectory->AddressOfCallBacks;
494 if (Array)
495 {
496 /* Display debug */
497 if (ShowSnaps)
498 {
499 DPRINT1("LDR: Tls Callbacks Found. Imagebase %p Tls %p CallBacks %p\n",
500 LdrEntry->DllBase, TlsDirectory, Array);
501 }
502
503 /* Loop the array */
504 while (*Array)
505 {
506 /* Get the TLS Entrypoint */
507 Callback = *Array++;
508
509 /* Display debug */
510 if (ShowSnaps)
511 {
512 DPRINT1("LDR: Calling Tls Callback Imagebase %p Function %p\n",
513 LdrEntry->DllBase, Callback);
514 }
515
516 /* Call it */
518 LdrEntry->DllBase,
519 Reason,
520 NULL);
521 }
522 }
523 }
524 }
526 {
527 DPRINT1("LDR: Exception 0x%x during Tls Callback(%u) for %wZ\n",
528 _SEH2_GetExceptionCode(), Reason, &LdrEntry->BaseDllName);
529 }
530 _SEH2_END;
531}
#define TRUE
Definition: types.h:120
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOLEAN(NTAPI * PDLL_INIT_ROUTINE)(_In_ PVOID DllHandle, _In_ ULONG Reason, _In_opt_ PCONTEXT Context)
Definition: ldrtypes.h:254
BOOLEAN NTAPI LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context)
Definition: ldrutils.c:100
if(dx< 0)
Definition: linetemp.h:194
BOOLEAN ShowSnaps
Definition: ldrinit.c:81
VOID(NTAPI * PIMAGE_TLS_CALLBACK)(PVOID DllHandle, ULONG Reason, PVOID Reserved)
Definition: ntimage.h:531
#define IMAGE_DIRECTORY_ENTRY_TLS
Definition: pedump.c:268
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458

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

◆ LdrpCheckForLoadedDll()

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

Definition at line 1979 of file ldrutils.c.

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

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

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

◆ LdrpClearLoadInProgress()

ULONG NTAPI LdrpClearLoadInProgress ( VOID  )

Definition at line 2663 of file ldrutils.c.

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

406{
407 // Ignored atm
408}

Referenced by LdrpCheckForKnownDll(), and LdrpRunInitializeRoutines().

◆ LdrpFetchAddressOfEntryPoint()

PVOID NTAPI LdrpFetchAddressOfEntryPoint ( PVOID  ImageBase)

◆ LdrpFinalizeAndDeallocateDataTableEntry()

VOID NTAPI LdrpFinalizeAndDeallocateDataTableEntry ( IN PLDR_DATA_TABLE_ENTRY  Entry)

Definition at line 1598 of file ldrutils.c.

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

Referenced by LdrUnloadDll().

◆ LdrpFreeTls()

VOID NTAPI LdrpFreeTls ( VOID  )

Definition at line 1380 of file ldrinit.c.

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

Referenced by LdrShutdownThread().

◆ LdrpFreeUnicodeString()

VOID NTAPI LdrpFreeUnicodeString ( PUNICODE_STRING  String)

◆ LdrpGetProcedureAddress()

NTSTATUS NTAPI LdrpGetProcedureAddress ( IN PVOID  BaseAddress,
IN PANSI_STRING  Name,
IN ULONG  Ordinal,
OUT PVOID ProcedureAddress,
IN BOOLEAN  ExecuteInit 
)

Definition at line 2252 of file ldrutils.c.

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

2536{
2538 PPEB Peb = NtCurrentPeb();
2539
2540 /* Print a debug message */
2541 DPRINT1("LDR: Process initialization failure for %wZ; NTSTATUS = %08lx\n",
2543
2544 /* Raise a hard error */
2546 {
2548 }
2549}
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 1753 of file ldrinit.c.

1755{
1756 RTL_HEAP_PARAMETERS HeapParameters;
1757 ULONG ComSectionSize;
1758 ANSI_STRING BaseProcessInitPostImportName = RTL_CONSTANT_STRING("BaseProcessInitPostImport");
1759 ANSI_STRING BaseQueryModuleDataName = RTL_CONSTANT_STRING("BaseQueryModuleData");
1760 PVOID OldShimData;
1762 //UNICODE_STRING LocalFileName, FullImageName;
1763 HANDLE SymLinkHandle;
1764 //ULONG DebugHeapOnly;
1765 UNICODE_STRING CommandLine, NtSystemRoot, ImagePathName, FullPath, ImageFileName, KnownDllString;
1766 PPEB Peb = NtCurrentPeb();
1767 BOOLEAN IsDotNetImage = FALSE;
1768 BOOLEAN FreeCurDir = FALSE;
1769 //HANDLE CompatKey;
1770 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
1771 //LPWSTR ImagePathBuffer;
1772 ULONG ConfigSize;
1774 HANDLE OptionsKey;
1775 ULONG HeapFlags;
1776 PIMAGE_NT_HEADERS NtHeader;
1777 LPWSTR NtDllName = NULL;
1778 NTSTATUS Status, ImportStatus;
1779 NLSTABLEINFO NlsTable;
1781 PTEB Teb = NtCurrentTeb();
1782 PLIST_ENTRY ListHead;
1783 PLIST_ENTRY NextEntry;
1784 ULONG i;
1785 PWSTR ImagePath;
1786 ULONG DebugProcessHeapOnly = 0;
1787 PLDR_DATA_TABLE_ENTRY NtLdrEntry;
1788 PWCHAR Current;
1789 ULONG ExecuteOptions = 0;
1790 PVOID ViewBase;
1791
1792 /* Set a NULL SEH Filter */
1794
1795 /* Get the image path */
1797
1798 /* Check if it's not normalized */
1800 {
1801 /* Normalize it*/
1802 ImagePath = (PWSTR)((ULONG_PTR)ImagePath + (ULONG_PTR)Peb->ProcessParameters);
1803 }
1804
1805 /* Create a unicode string for the Image Path */
1807 ImagePathName.MaximumLength = ImagePathName.Length + sizeof(WCHAR);
1808 ImagePathName.Buffer = ImagePath;
1809
1810 /* Get the NT Headers */
1812
1813 /* Get the execution options */
1814 Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &OptionsKey);
1815
1816 /* Check if this is a .NET executable */
1818 TRUE,
1820 &ComSectionSize))
1821 {
1822 /* Remember this for later */
1823 IsDotNetImage = TRUE;
1824 }
1825
1826 /* Save the NTDLL Base address */
1828
1829 /* If this is a Native Image */
1831 {
1832 /* Then do DLL Validation */
1834 }
1835
1836 /* Save the old Shim Data */
1837 OldShimData = Peb->pShimData;
1838
1839 /* ReactOS specific: do not clear it. (Windows starts doing the same in later versions) */
1840 //Peb->pShimData = NULL;
1841
1842 /* Save the number of processors and CS timeout */
1845
1846 /* Normalize the parameters */
1847 ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
1848 if (ProcessParameters)
1849 {
1850 /* Save the Image and Command Line Names */
1851 ImageFileName = ProcessParameters->ImagePathName;
1852 CommandLine = ProcessParameters->CommandLine;
1853 }
1854 else
1855 {
1856 /* It failed, initialize empty strings */
1857 RtlInitUnicodeString(&ImageFileName, NULL);
1858 RtlInitUnicodeString(&CommandLine, NULL);
1859 }
1860
1861 /* Initialize NLS data */
1865 &NlsTable);
1866
1867 /* Reset NLS Translations */
1868 RtlResetRtlTranslations(&NlsTable);
1869
1870 /* Get the Image Config Directory */
1872 TRUE,
1874 &ConfigSize);
1875
1876 /* Setup the Heap Parameters */
1877 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
1878 HeapFlags = HEAP_GROWABLE;
1879 HeapParameters.Length = sizeof(HeapParameters);
1880
1881 /* Check if we have Configuration Data */
1882#define VALID_CONFIG_FIELD(Name) (ConfigSize >= (FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY, Name) + sizeof(LoadConfig->Name)))
1883 /* The 'original' load config ends after SecurityCookie */
1884 if ((LoadConfig) && ConfigSize && (VALID_CONFIG_FIELD(SecurityCookie) || ConfigSize == LoadConfig->Size))
1885 {
1886 if (ConfigSize != sizeof(IMAGE_LOAD_CONFIG_DIRECTORY))
1887 DPRINT1("WARN: Accepting different LOAD_CONFIG size!\n");
1888 else
1889 DPRINT1("Applying LOAD_CONFIG\n");
1890
1891 if (VALID_CONFIG_FIELD(GlobalFlagsSet) && LoadConfig->GlobalFlagsSet)
1892 Peb->NtGlobalFlag |= LoadConfig->GlobalFlagsSet;
1893
1894 if (VALID_CONFIG_FIELD(GlobalFlagsClear) && LoadConfig->GlobalFlagsClear)
1895 Peb->NtGlobalFlag &= ~LoadConfig->GlobalFlagsClear;
1896
1897 /* Convert the default CS timeout from milliseconds to 100ns units */
1898 if (VALID_CONFIG_FIELD(CriticalSectionDefaultTimeout) && LoadConfig->CriticalSectionDefaultTimeout)
1899 RtlpTimeout.QuadPart = Int32x32To64(LoadConfig->CriticalSectionDefaultTimeout, -10000);
1900
1901 if (VALID_CONFIG_FIELD(DeCommitFreeBlockThreshold) && LoadConfig->DeCommitFreeBlockThreshold)
1902 HeapParameters.DeCommitFreeBlockThreshold = LoadConfig->DeCommitFreeBlockThreshold;
1903
1904 if (VALID_CONFIG_FIELD(DeCommitTotalFreeThreshold) && LoadConfig->DeCommitTotalFreeThreshold)
1905 HeapParameters.DeCommitTotalFreeThreshold = LoadConfig->DeCommitTotalFreeThreshold;
1906
1907 if (VALID_CONFIG_FIELD(MaximumAllocationSize) && LoadConfig->MaximumAllocationSize)
1908 HeapParameters.MaximumAllocationSize = LoadConfig->MaximumAllocationSize;
1909
1910 if (VALID_CONFIG_FIELD(VirtualMemoryThreshold) && LoadConfig->VirtualMemoryThreshold)
1911 HeapParameters.VirtualMemoryThreshold = LoadConfig->VirtualMemoryThreshold;
1912
1913 if (VALID_CONFIG_FIELD(ProcessHeapFlags) && LoadConfig->ProcessHeapFlags)
1914 HeapFlags = LoadConfig->ProcessHeapFlags;
1915 }
1916#undef VALID_CONFIG_FIELD
1917
1918 /* Check for custom affinity mask */
1920 {
1921 /* Set it */
1925 sizeof(Peb->ImageProcessAffinityMask));
1926 }
1927
1928 /* Check if verbose debugging (ShowSnaps) was requested */
1930
1931 /* Start verbose debugging messages right now if they were requested */
1932 if (ShowSnaps)
1933 {
1934 DPRINT1("LDR: PID: 0x%p started - '%wZ'\n",
1936 &CommandLine);
1937 }
1938
1939 /* If the CS timeout is longer than 1 hour, disable it */
1940 if (RtlpTimeout.QuadPart < Int32x32To64(3600, -10000000))
1942
1943 /* Initialize Critical Section Data */
1945
1946 /* Initialize VEH Call lists */
1948
1949 /* Set TLS/FLS Bitmap data */
1953
1954 /* Initialize FLS Bitmap */
1958 RtlSetBit(&FlsBitMap, 0);
1960
1961 /* Initialize TLS Bitmap */
1965 RtlSetBit(&TlsBitMap, 0);
1970
1971 /* Initialize the Hash Table */
1972 for (i = 0; i < LDR_HASH_TABLE_ENTRIES; i++)
1973 {
1975 }
1976
1977 /* Initialize the Loader Lock */
1978 // FIXME: What's the point of initing it manually, if two lines lower
1979 // a call to RtlInitializeCriticalSection() is being made anyway?
1980 //InsertTailList(&RtlCriticalSectionList, &LdrpLoaderLock.DebugInfo->ProcessLocksList);
1981 //LdrpLoaderLock.DebugInfo->CriticalSection = &LdrpLoaderLock;
1984
1985 /* Check if User Stack Trace Database support was requested */
1987 {
1988 DPRINT1("We don't support user stack trace databases yet\n");
1989 }
1990
1991 /* Setup Fast PEB Lock */
1994 //Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
1995 //Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
1996
1997 /* Setup Callout Lock and Notification list */
1998 //RtlInitializeCriticalSection(&RtlpCalloutEntryLock);
2000
2001 /* For old executables, use 16-byte aligned heap */
2002 if ((NtHeader->OptionalHeader.MajorSubsystemVersion <= 3) &&
2003 (NtHeader->OptionalHeader.MinorSubsystemVersion < 51))
2004 {
2005 HeapFlags |= HEAP_CREATE_ALIGN_16;
2006 }
2007
2008 /* Setup the Heap */
2010 Peb->ProcessHeap = RtlCreateHeap(HeapFlags,
2011 NULL,
2014 NULL,
2015 &HeapParameters);
2016
2017 if (!Peb->ProcessHeap)
2018 {
2019 DPRINT1("Failed to create process heap\n");
2020 return STATUS_NO_MEMORY;
2021 }
2022
2023 /* Allocate an Activation Context Stack */
2025 if (!NT_SUCCESS(Status)) return Status;
2026
2027 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
2028 HeapFlags = HEAP_GROWABLE | HEAP_CLASS_1;
2029 HeapParameters.Length = sizeof(HeapParameters);
2030 LdrpHeap = RtlCreateHeap(HeapFlags, 0, 0x10000, 0x6000, 0, &HeapParameters);
2031 if (!LdrpHeap)
2032 {
2033 DPRINT1("Failed to create loader private heap\n");
2034 return STATUS_NO_MEMORY;
2035 }
2036
2037 /* Check for Debug Heap */
2038 if (OptionsKey)
2039 {
2040 /* Query the setting */
2042 L"DebugProcessHeapOnly",
2043 REG_DWORD,
2044 &DebugProcessHeapOnly,
2045 sizeof(ULONG),
2046 NULL);
2047
2048 if (NT_SUCCESS(Status))
2049 {
2050 /* Reset DPH if requested */
2051 if (RtlpPageHeapEnabled && DebugProcessHeapOnly)
2052 {
2053 RtlpDphGlobalFlags &= ~DPH_FLAG_DLL_NOTIFY;
2055 }
2056 }
2057 }
2058
2059 /* Build the NTDLL Path */
2060 FullPath.Buffer = StringBuffer;
2061 FullPath.Length = 0;
2062 FullPath.MaximumLength = sizeof(StringBuffer);
2065 RtlAppendUnicodeToString(&FullPath, L"\\System32\\");
2066
2067 /* Open the Known DLLs directory */
2068 RtlInitUnicodeString(&KnownDllString, L"\\KnownDlls");
2070 &KnownDllString,
2072 NULL,
2073 NULL);
2077
2078 /* Check if it exists */
2079 if (NT_SUCCESS(Status))
2080 {
2081 /* Open the Known DLLs Path */
2082 RtlInitUnicodeString(&KnownDllString, L"KnownDllPath");
2084 &KnownDllString,
2087 NULL);
2088 Status = NtOpenSymbolicLinkObject(&SymLinkHandle,
2091 if (NT_SUCCESS(Status))
2092 {
2093 /* Query the path */
2097 Status = ZwQuerySymbolicLinkObject(SymLinkHandle, &LdrpKnownDllPath, NULL);
2098 NtClose(SymLinkHandle);
2099 if (!NT_SUCCESS(Status))
2100 {
2101 DPRINT1("LDR: %s - failed call to ZwQuerySymbolicLinkObject with status %x\n", "", Status);
2102 return Status;
2103 }
2104 }
2105 }
2106
2107 /* Check if we failed */
2108 if (!NT_SUCCESS(Status))
2109 {
2110 /* Assume System32 */
2113 LdrpKnownDllPath.Length -= sizeof(WCHAR);
2114 }
2115
2116 /* If we have process parameters, get the default path and current path */
2117 if (ProcessParameters)
2118 {
2119 /* Check if we have a Dll Path */
2120 if (ProcessParameters->DllPath.Length)
2121 {
2122 /* Get the path */
2123 LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath;
2124 }
2125 else
2126 {
2127 /* We need a valid path */
2128 DPRINT1("No valid DllPath was given!\n");
2130 }
2131
2132 /* Set the current directory */
2133 CurrentDirectory = ProcessParameters->CurrentDirectory.DosPath;
2134
2135 /* Check if it's empty or invalid */
2136 if ((!CurrentDirectory.Buffer) ||
2137 (CurrentDirectory.Buffer[0] == UNICODE_NULL) ||
2138 (!CurrentDirectory.Length))
2139 {
2140 /* Allocate space for the buffer */
2142 0,
2143 3 * sizeof(WCHAR) +
2144 sizeof(UNICODE_NULL));
2145 if (!CurrentDirectory.Buffer)
2146 {
2147 DPRINT1("LDR: LdrpInitializeProcess - unable to allocate current working directory buffer\n");
2148 // FIXME: And what?
2149 }
2150
2151 /* Copy the drive of the system root */
2153 SharedUserData->NtSystemRoot,
2154 3 * sizeof(WCHAR));
2155 CurrentDirectory.Buffer[3] = UNICODE_NULL;
2156 CurrentDirectory.Length = 3 * sizeof(WCHAR);
2157 CurrentDirectory.MaximumLength = CurrentDirectory.Length + sizeof(WCHAR);
2158
2159 FreeCurDir = TRUE;
2160 DPRINT("Using dynamically allocd curdir\n");
2161 }
2162 else
2163 {
2164 /* Use the local buffer */
2165 DPRINT("Using local system root\n");
2166 }
2167 }
2168
2169 /* Setup Loader Data */
2170 Peb->Ldr = &PebLdr;
2174 PebLdr.Length = sizeof(PEB_LDR_DATA);
2176
2177 /* Allocate a data entry for the Image */
2179
2180 /* Set it up */
2184 LdrpImageEntry->FullDllName = ImageFileName;
2185
2186 if (IsDotNetImage)
2188 else
2189 LdrpImageEntry->Flags = 0;
2190
2191 /* Check if the name is empty */
2192 if (!ImageFileName.Buffer[0])
2193 {
2194 /* Use the same Base name */
2196 }
2197 else
2198 {
2199 /* Find the last slash */
2200 Current = ImageFileName.Buffer;
2201 while (*Current)
2202 {
2203 if (*Current++ == '\\')
2204 {
2205 /* Set this path */
2206 NtDllName = Current;
2207 }
2208 }
2209
2210 /* Did we find anything? */
2211 if (!NtDllName)
2212 {
2213 /* Use the same Base name */
2215 }
2216 else
2217 {
2218 /* Setup the name */
2219 LdrpImageEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName);
2222 (ImageFileName.Length - LdrpImageEntry->BaseDllName.Length));
2223 }
2224 }
2225
2226 /* Processing done, insert it */
2229
2230 /* Now add an entry for NTDLL */
2232 NtLdrEntry->Flags = LDRP_IMAGE_DLL;
2233 NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase);
2234 NtLdrEntry->LoadCount = -1;
2235 NtLdrEntry->EntryPointActivationContext = 0;
2236
2237 NtLdrEntry->FullDllName.Length = FullPath.Length;
2238 NtLdrEntry->FullDllName.MaximumLength = FullPath.MaximumLength;
2239 NtLdrEntry->FullDllName.Buffer = StringBuffer;
2241
2242 NtLdrEntry->BaseDllName.Length = NtDllString.Length;
2244 NtLdrEntry->BaseDllName.Buffer = NtDllString.Buffer;
2245
2246 /* Processing done, insert it */
2247 LdrpNtDllDataTableEntry = NtLdrEntry;
2248 LdrpInsertMemoryTableEntry(NtLdrEntry);
2249
2250 /* Let the world know */
2251 if (ShowSnaps)
2252 {
2253 DPRINT1("LDR: NEW PROCESS\n");
2254 DPRINT1(" Image Path: %wZ (%wZ)\n", &LdrpImageEntry->FullDllName, &LdrpImageEntry->BaseDllName);
2255 DPRINT1(" Current Directory: %wZ\n", &CurrentDirectory);
2256 DPRINT1(" Search Path: %wZ\n", &LdrpDefaultPath);
2257 }
2258
2259 /* Link the Init Order List */
2262
2263 /* Initialize Wine's active context implementation for the current process */
2264 actctx_init(&OldShimData);
2265
2266 /* Set the current directory */
2268 if (!NT_SUCCESS(Status))
2269 {
2270 /* We failed, check if we should free it */
2271 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2272
2273 /* Set it to the NT Root */
2276 }
2277 else
2278 {
2279 /* We're done with it, free it */
2280 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2281 }
2282
2283 /* Check if we should look for a .local file */
2284 if (ProcessParameters && !(ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH))
2285 {
2286 LdrpInitializeDotLocalSupport(ProcessParameters);
2287 }
2288
2289 /* Check if the Application Verifier was enabled */
2291 {
2293 if (!NT_SUCCESS(Status))
2294 {
2295 DPRINT1("LDR: AVrfInitializeVerifier failed (ntstatus 0x%x)\n", Status);
2296 return Status;
2297 }
2298
2299 }
2300
2301 if (IsDotNetImage)
2302 {
2303 /* FIXME */
2304 DPRINT1("We don't support .NET applications yet\n");
2305 }
2306
2309 {
2310 PVOID Kernel32BaseAddress;
2311 PVOID FunctionAddress;
2312
2313 Status = LdrLoadDll(NULL, NULL, &Kernel32String, &Kernel32BaseAddress);
2314
2315 if (!NT_SUCCESS(Status))
2316 {
2317 if (ShowSnaps)
2318 DPRINT1("LDR: Unable to load %wZ, Status=0x%08lx\n", &Kernel32String, Status);
2319 return Status;
2320 }
2321
2322 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2323 &BaseProcessInitPostImportName,
2324 0,
2325 &FunctionAddress);
2326
2327 if (!NT_SUCCESS(Status))
2328 {
2329 if (ShowSnaps)
2330 DPRINT1("LDR: Unable to find post-import process init function, Status=0x%08lx\n", &Kernel32String, Status);
2331 return Status;
2332 }
2333 Kernel32ProcessInitPostImportFunction = FunctionAddress;
2334
2335 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2336 &BaseQueryModuleDataName,
2337 0,
2338 &FunctionAddress);
2339
2340 if (!NT_SUCCESS(Status))
2341 {
2342 if (ShowSnaps)
2343 DPRINT1("LDR: Unable to find BaseQueryModuleData, Status=0x%08lx\n", &Kernel32String, Status);
2344 return Status;
2345 }
2346 Kernel32BaseQueryModuleData = FunctionAddress;
2347 }
2348
2349 /* Walk the IAT and load all the DLLs */
2351
2352 /* Check if relocation is needed */
2354 {
2355 DPRINT1("LDR: Performing EXE relocation\n");
2356
2357 /* Change the protection to prepare for relocation */
2358 ViewBase = Peb->ImageBaseAddress;
2359 Status = LdrpSetProtection(ViewBase, FALSE);
2360 if (!NT_SUCCESS(Status)) return Status;
2361
2362 /* Do the relocation */
2364 0LL,
2365 NULL,
2369 if (!NT_SUCCESS(Status))
2370 {
2371 DPRINT1("LdrRelocateImageWithBias() failed\n");
2372 return Status;
2373 }
2374
2375 /* Check if a start context was provided */
2376 if (Context)
2377 {
2378 DPRINT1("WARNING: Relocated EXE Context");
2379 UNIMPLEMENTED; // We should support this
2381 }
2382
2383 /* Restore the protection */
2384 Status = LdrpSetProtection(ViewBase, TRUE);
2385 if (!NT_SUCCESS(Status)) return Status;
2386 }
2387
2388 /* Lock the DLLs */
2389 ListHead = &Peb->Ldr->InLoadOrderModuleList;
2390 NextEntry = ListHead->Flink;
2391 while (ListHead != NextEntry)
2392 {
2393 NtLdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
2394 NtLdrEntry->LoadCount = -1;
2395 NextEntry = NextEntry->Flink;
2396 }
2397
2398 /* Phase 0 is done */
2400
2401 /* Check whether all static imports were properly loaded and return here */
2402 if (!NT_SUCCESS(ImportStatus)) return ImportStatus;
2403
2404 /* Initialize TLS */
2406 if (!NT_SUCCESS(Status))
2407 {
2408 DPRINT1("LDR: LdrpProcessInitialization failed to initialize TLS slots; status %x\n",
2409 Status);
2410 return Status;
2411 }
2412
2413 /* FIXME Mark the DLL Ranges for Stack Traces later */
2414
2415 /* Notify the debugger now */
2416 if (Peb->BeingDebugged)
2417 {
2418 /* Break */
2419 DbgBreakPoint();
2420
2421 /* Update show snaps again */
2423 }
2424
2425 /* Validate the Image for MP Usage */
2427
2428 /* Check NX options and set them */
2429 if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSON)
2430 {
2431 ExecuteOptions = MEM_EXECUTE_OPTION_DISABLE |
2434 }
2435 else if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSOFF)
2436 {
2438 }
2441 &ExecuteOptions,
2442 sizeof(ExecuteOptions));
2443 if (!NT_SUCCESS(Status))
2444 {
2445 DPRINT1("LDR: Could not set process execute flags 0x%x; status %x\n",
2446 ExecuteOptions, Status);
2447 }
2448
2449 // FIXME: Should be done by Application Compatibility features,
2450 // by reading the registry, etc...
2451 // For now, this is the old code from ntdll!RtlGetVersion().
2452 RtlInitEmptyUnicodeString(&Peb->CSDVersion, NULL, 0);
2453 if (((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
2454 {
2455 WCHAR szCSDVersion[128];
2456 LONG i;
2457 USHORT Length = (USHORT)ARRAYSIZE(szCSDVersion) - 1;
2458 i = _snwprintf(szCSDVersion, Length,
2459 L"Service Pack %d",
2460 ((Peb->OSCSDVersion >> 8) & 0xFF));
2461 if (i < 0)
2462 {
2463 /* Null-terminate if it was overflowed */
2464 szCSDVersion[Length] = UNICODE_NULL;
2465 }
2466
2467 Length *= sizeof(WCHAR);
2468 Peb->CSDVersion.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
2469 0,
2470 Length + sizeof(UNICODE_NULL));
2471 if (Peb->CSDVersion.Buffer)
2472 {
2475
2477 szCSDVersion,
2480 }
2481 }
2482
2483 /* Check if we had Shim Data */
2484 if (OldShimData)
2485 {
2486 /* Load the Shim Engine */
2488 LdrpLoadShimEngine(OldShimData, &ImagePathName, OldShimData);
2489 }
2490 else
2491 {
2492 /* Check for Application Compatibility Goo */
2493 //LdrQueryApplicationCompatibilityGoo(hKey);
2494 DPRINT("Querying app compat hacks is missing!\n");
2495 }
2496
2497 /*
2498 * FIXME: Check for special images, SecuROM, SafeDisc and other NX-
2499 * incompatible images.
2500 */
2501
2502 /* Now call the Init Routines */
2504 if (!NT_SUCCESS(Status))
2505 {
2506 DPRINT1("LDR: LdrpProcessInitialization failed running initialization routines; status %x\n",
2507 Status);
2508 return Status;
2509 }
2510
2511 /* Notify Shim Engine */
2512 if (g_ShimsEnabled)
2513 {
2516 SE_InstallAfterInit(&ImagePathName, OldShimData);
2517 }
2518
2519 /* Check if we have a user-defined Post Process Routine */
2521 {
2522 /* Call it */
2524 }
2525
2526 /* Close the key if we have one opened */
2527 if (OptionsKey) NtClose(OptionsKey);
2528
2529 /* Return status */
2530 return Status;
2531}
#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 LdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress)
Definition: ldrapi.c:823
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(IN PWSTR SearchPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress)
Definition: ldrapi.c:310
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:1692
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:1416
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
VOID NTAPI RtlInitializeHeapManager(VOID)
Definition: libsupp.c:243
VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
Definition: ldrinit.c:1535
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:637
BOOLEAN LdrpLdrDatabaseIsSetup
Definition: ldrinit.c:33
VOID NTAPI RtlpInitializeVectoredExceptionHandling(VOID)
Definition: vectoreh.c:30
void actctx_init(PVOID *pOldShimData)
Definition: actctx.c:5075
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:2535
PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry
Definition: ldrinit.c:44
NTSTATUS NTAPI LdrpInitializeTls(VOID)
Definition: ldrinit.c:1254
#define VALID_CONFIG_FIELD(Name)
NTSTATUS NTAPI LdrQueryImageFileKeyOption(IN HANDLE KeyHandle, IN PCWSTR ValueName, IN ULONG Type, OUT PVOID Buffer, IN ULONG BufferSize, OUT PULONG ReturnedLength OPTIONAL)
Definition: ldrinit.c:184
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)
NTSYSAPI ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID NewAddress, _In_ LONGLONG AdditionalBias, _In_ PCCH LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
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:2771
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:1582
NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase, BOOLEAN Restore)
Definition: ldrutils.c:947
PVOID NTAPI LdrpFetchAddressOfEntryPoint(PVOID ImageBase)
BOOLEAN RtlpPageHeapEnabled
Definition: heappage.c:107
PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
Definition: ldrutils.c:1549
BOOLEAN g_ShimsEnabled
Definition: ldrutils.c:21
#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:75
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
NTSTATUS NTAPI RtlAllocateActivationContextStack(IN PACTIVATION_CONTEXT_STACK *Stack)
Definition: actctx.c:5906
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:150
#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:1104
#define NX_SUPPORT_POLICY_ALWAYSOFF
Definition: ketypes.h:1149
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:676
#define NX_SUPPORT_POLICY_ALWAYSON
Definition: ketypes.h:1150
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 502 of file ldrinit.c.

503{
505 PLDR_DATA_TABLE_ENTRY LdrEntry;
506 PLIST_ENTRY NextEntry, ListHead;
507 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
509 PVOID EntryPoint;
510
511 DPRINT("LdrpInitializeThread() called for %wZ (%p/%p)\n",
513 NtCurrentTeb()->RealClientId.UniqueProcess,
514 NtCurrentTeb()->RealClientId.UniqueThread);
515
516 /* Allocate an Activation Context Stack */
517 DPRINT("ActivationContextStack %p\n", NtCurrentTeb()->ActivationContextStackPointer);
518 Status = RtlAllocateActivationContextStack(&NtCurrentTeb()->ActivationContextStackPointer);
519 if (!NT_SUCCESS(Status))
520 {
521 DPRINT1("Warning: Unable to allocate ActivationContextStack\n");
522 }
523
524 /* Make sure we are not shutting down */
525 if (LdrpShutdownInProgress) return;
526
527 /* Allocate TLS */
529
530 /* Start at the beginning */
531 ListHead = &Peb->Ldr->InMemoryOrderModuleList;
532 NextEntry = ListHead->Flink;
533 while (NextEntry != ListHead)
534 {
535 /* Get the current entry */
536 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
537
538 /* Make sure it's not ourselves */
539 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
540 {
541 /* Check if we should call */
542 if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS))
543 {
544 /* Get the entrypoint */
545 EntryPoint = LdrEntry->EntryPoint;
546
547 /* Check if we are ready to call it */
548 if ((EntryPoint) &&
549 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
550 (LdrEntry->Flags & LDRP_IMAGE_DLL))
551 {
552 /* Set up the Act Ctx */
553 ActCtx.Size = sizeof(ActCtx);
554 ActCtx.Format = 1;
556
557 /* Activate the ActCtx */
560
562 {
563 /* Check if it has TLS */
564 if (LdrEntry->TlsIndex)
565 {
566 /* Make sure we're not shutting down */
568 {
569 /* Call TLS */
571 }
572 }
573
574 /* Make sure we're not shutting down */
576 {
577 /* Call the Entrypoint */
578 DPRINT("%wZ - Calling entry point at %p for thread attaching, %p/%p\n",
579 &LdrEntry->BaseDllName, LdrEntry->EntryPoint,
580 NtCurrentTeb()->RealClientId.UniqueProcess,
581 NtCurrentTeb()->RealClientId.UniqueThread);
583 LdrEntry->DllBase,
585 NULL);
586 }
587 }
589 {
590 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_ATTACH) for %wZ\n",
591 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
592 }
593 _SEH2_END;
594
595 /* Deactivate the ActCtx */
597 }
598 }
599 }
600
601 /* Next entry */
602 NextEntry = NextEntry->Flink;
603 }
604
605 /* Check for TLS */
607 {
608 /* Set up the Act Ctx */
609 ActCtx.Size = sizeof(ActCtx);
610 ActCtx.Format = 1;
612
613 /* Activate the ActCtx */
616
618 {
619 /* Do TLS callbacks */
621 }
623 {
624 /* Do nothing */
625 }
626 _SEH2_END;
627
628 /* Deactivate the ActCtx */
630 }
631
632 DPRINT("LdrpInitializeThread() done\n");
633}
#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:1317
_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:473
BOOLEAN NTAPI LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context)
Definition: ldrutils.c:100
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame, IN PVOID Context)
Definition: actctx.c:5934
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame)
Definition: actctx.c:6011
USHORT TlsIndex
Definition: ntddk_ex.h:209

Referenced by LdrpInit().

◆ LdrpInitializeTls()

NTSTATUS NTAPI LdrpInitializeTls ( VOID  )

Definition at line 1254 of file ldrinit.c.

1255{
1256 PLIST_ENTRY NextEntry, ListHead;
1257 PLDR_DATA_TABLE_ENTRY LdrEntry;
1258 PIMAGE_TLS_DIRECTORY TlsDirectory;
1259 PLDRP_TLS_DATA TlsData;
1260 ULONG Size;
1261
1262 /* Initialize the TLS List */
1264
1265 /* Loop all the modules */
1266 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1267 NextEntry = ListHead->Flink;
1268 while (ListHead != NextEntry)
1269 {
1270 /* Get the entry */
1271 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1272 NextEntry = NextEntry->Flink;
1273
1274 /* Get the TLS directory */
1275 TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1276 TRUE,
1278 &Size);
1279
1280 /* Check if we have a directory */
1281 if (!TlsDirectory) continue;
1282
1283 /* Check if the image has TLS */
1285
1286 /* Show debug message */
1287 if (ShowSnaps)
1288 {
1289 DPRINT1("LDR: Tls Found in %wZ at %p\n",
1290 &LdrEntry->BaseDllName,
1291 TlsDirectory);
1292 }
1293
1294 /* Allocate an entry */
1295 TlsData = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LDRP_TLS_DATA));
1296 if (!TlsData) return STATUS_NO_MEMORY;
1297
1298 /* Lock the DLL and mark it for TLS Usage */
1299 LdrEntry->LoadCount = -1;
1300 LdrEntry->TlsIndex = -1;
1301
1302 /* Save the cached TLS data */
1303 TlsData->TlsDirectory = *TlsDirectory;
1304 InsertTailList(&LdrpTlsList, &TlsData->TlsLinks);
1305
1306 /* Update the index */
1309 }
1310
1311 /* Done setting up TLS, allocate entries */
1312 return LdrpAllocateTls();
1313}
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 1582 of file ldrutils.c.

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

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

2435{
2436 PPEB Peb = NtCurrentPeb();
2438 const WCHAR *p;
2439 BOOLEAN GotExtension;
2440 WCHAR c;
2441 WCHAR NameBuffer[MAX_PATH + 6];
2442 UNICODE_STRING RawDllName;
2443 PLDR_DATA_TABLE_ENTRY LdrEntry;
2444 BOOLEAN InInit = LdrpInLdrInit;
2445
2446 /* Save the Raw DLL Name */
2447 if (DllName->Length >= sizeof(NameBuffer)) return STATUS_NAME_TOO_LONG;
2448 RtlInitEmptyUnicodeString(&RawDllName, NameBuffer, sizeof(NameBuffer));
2449 RtlCopyUnicodeString(&RawDllName, DllName);
2450
2451 /* Find the extension, if present */
2452 p = DllName->Buffer + DllName->Length / sizeof(WCHAR) - 1;
2453 GotExtension = FALSE;
2454 while (p >= DllName->Buffer)
2455 {
2456 c = *p--;
2457 if (c == L'.')
2458 {
2459 GotExtension = TRUE;
2460 break;
2461 }
2462 else if (c == L'\\')
2463 {
2464 break;
2465 }
2466 }
2467
2468 /* If no extension was found, add the default extension */
2469 if (!GotExtension)
2470 {
2471 /* Check that we have space to add one */
2472 if ((DllName->Length + LdrApiDefaultExtension.Length + sizeof(UNICODE_NULL)) >=
2473 sizeof(NameBuffer))
2474 {
2475 /* No space to add the extension */
2478 "LDR: %s - Dll name missing extension; with extension "
2479 "added the name is too long\n"
2480 " DllName: (@ %p) \"%wZ\"\n"
2481 " DllName->Length: %u\n",
2483 DllName,
2484 DllName,
2485 DllName->Length);
2486 return STATUS_NAME_TOO_LONG;
2487 }
2488
2489 /* Add it. Needs to be null terminated, thus the length check above */
2492 }
2493
2494 /* Check for init flag and acquire lock */
2496
2497 _SEH2_TRY
2498 {
2499 /* Show debug message */
2500 if (ShowSnaps)
2501 {
2502 DPRINT1("LDR: LdrLoadDll, loading %wZ from %ws\n",
2503 &RawDllName,
2504 DllPath ? DllPath : L"");
2505 }
2506
2507 /* Check if the DLL is already loaded */
2509 &RawDllName,
2510 FALSE,
2511 Redirected,
2512 &LdrEntry))
2513 {
2514 /* Map it */
2516 DllPath,
2517 NameBuffer,
2518 DllCharacteristics,
2519 FALSE,
2520 Redirected,
2521 &LdrEntry);
2522 if (!NT_SUCCESS(Status))
2524
2525 /* FIXME: Need to mark the DLL range for the stack DB */
2526 //RtlpStkMarkDllRange(LdrEntry);
2527
2528 /* Check if IMAGE_FILE_EXECUTABLE_IMAGE was provided */
2529 if ((DllCharacteristics) &&
2530 (*DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
2531 {
2532 /* This is not a DLL, so remove such data */
2533 LdrEntry->EntryPoint = NULL;
2534 LdrEntry->Flags &= ~LDRP_IMAGE_DLL;
2535 }
2536
2537 /* Make sure it's a DLL */
2538 if (LdrEntry->Flags & LDRP_IMAGE_DLL)
2539 {
2540 /* Check if this is a .NET Image */
2541 if (!(LdrEntry->Flags & LDRP_COR_IMAGE))
2542 {
2543 /* Walk the Import Descriptor */
2545 }
2546
2547 /* Update load count, unless it's locked */
2548 if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
2550
2551 /* Check if we failed */
2552 if (!NT_SUCCESS(Status))
2553 {
2554 /* Clear entrypoint, and insert into list */
2555 LdrEntry->EntryPoint = NULL;
2557 &LdrEntry->InInitializationOrderLinks);
2558
2559 /* Cancel the load */
2561
2562 /* Unload the DLL */
2563 if (ShowSnaps)
2564 {
2565 DbgPrint("LDR: Unloading %wZ due to error %x walking "
2566 "import descriptors\n",
2567 DllName,
2568 Status);
2569 }
2570 LdrUnloadDll(LdrEntry->DllBase);
2571
2572 /* Return the error */
2574 }
2575 }
2576 else if (LdrEntry->LoadCount != 0xFFFF)
2577 {
2578 /* Increase load count */
2579 LdrEntry->LoadCount++;
2580 }
2581
2582 /* Insert it into the list */
2584 &LdrEntry->InInitializationOrderLinks);
2585
2586 /* If we have to run the entrypoint, make sure the DB is ready */
2587 if (CallInit && LdrpLdrDatabaseIsSetup)
2588 {
2589 /* Notify Shim Engine */
2590 if (g_ShimsEnabled)
2591 {
2593 SE_DllLoaded(LdrEntry);
2594 }
2595
2596 /* Run the init routine */
2598 if (!NT_SUCCESS(Status))
2599 {
2600 /* Failed, unload the DLL */
2601 if (ShowSnaps)
2602 {
2603 DbgPrint("LDR: Unloading %wZ because either its init "
2604 "routine or one of its static imports failed; "
2605 "status = 0x%08lx\n",
2606 DllName,
2607 Status);
2608 }
2609 LdrUnloadDll(LdrEntry->DllBase);
2610 }
2611 }
2612 else
2613 {
2614 /* The DB isn't ready, which means we were loaded because of a forwarder */
2616 }
2617 }
2618 else
2619 {
2620 /* We were already loaded. Are we a DLL? */
2621 if ((LdrEntry->Flags & LDRP_IMAGE_DLL) && (LdrEntry->LoadCount != 0xFFFF))
2622 {
2623 /* Increase load count */
2624 LdrEntry->LoadCount++;
2626
2627 /* Clear the load in progress */
2629 }
2630 else
2631 {
2632 /* Not a DLL, just increase the load count */
2633 if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
2634 }
2635 }
2636
2637 }
2639 {
2640 /* Release the lock */
2642 }
2643 _SEH2_END;
2644
2645 /* Check for success */
2646 if (NT_SUCCESS(Status))
2647 {
2648 /* Return the base address */
2649 *BaseAddress = LdrEntry->DllBase;
2650 }
2651 else
2652 {
2653 /* Nothing found */
2654 *BaseAddress = NULL;
2655 }
2656
2657 /* Return status */
2658 return Status;
2659}
#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:1322
NTSTATUS NTAPI LdrpMapDll(IN PWSTR SearchPath OPTIONAL, IN PWSTR DllPath2, IN PWSTR DllName OPTIONAL, IN PULONG DllCharacteristics, IN BOOLEAN Static, IN BOOLEAN Redirect, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
Definition: ldrutils.c:1023
VOID NTAPI LdrpUpdateLoadCount2(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Flags)
Definition: ldrutils.c:460
BOOLEAN NTAPI LdrpCheckForLoadedDll(IN PWSTR DllPath, IN PUNICODE_STRING DllName, IN BOOLEAN Flag, IN BOOLEAN RedirectedDll, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
Definition: ldrutils.c:1979
BOOLEAN g_ShimsEnabled
Definition: ldrutils.c:21
ULONG NTAPI LdrpClearLoadInProgress(VOID)
Definition: ldrutils.c:2663
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,
882 NULL,
883 &RedirectedImpDescName,
884 &ImpDescName,
885 NULL,
886 NULL,
887 NULL);
888
889 /* Check success */
890 if (NT_SUCCESS(Status))
891 {
892 /* Let Ldrp know */
893 RedirectedDll = TRUE;
894 }
896 {
897 /* Unrecoverable SxS failure */
898 DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed with status %x for dll %wZ\n", Status, ImpDescName);
899 goto done;
900 }
901
902 /* Check if it's loaded */
904 ImpDescName,
905 TRUE,
906 RedirectedDll,
907 DataTableEntry))
908 {
909 /* It's already existing in the list */
910 *Existing = TRUE;
912 goto done;
913 }
914
915 /* We're loading it for the first time */
916 *Existing = FALSE;
917
918 /* Map it */
920 NULL,
921 ImpDescName->Buffer,
922 NULL,
923 TRUE,
924 RedirectedDll,
925 DataTableEntry);
926 if (!NT_SUCCESS(Status))
927 {
928 DPRINT1("LDR: LdrpMapDll failed with status %x for dll %wZ\n", Status, ImpDescName);
929 goto done;
930 }
931
932 /* Walk its import descriptor table */
934 *DataTableEntry);
935 if (!NT_SUCCESS(Status))
936 {
937 /* Add it to the in-init-order list in case of failure */
939 &(*DataTableEntry)->InInitializationOrderLinks);
940 }
941
942done:
943 RtlFreeUnicodeString(&RedirectedImpDescName);
944
945 return Status;
946}
NTSYSAPI NTSTATUS NTAPI RtlDosApplyFileIsolationRedirection_Ustr(IN ULONG Flags, IN PUNICODE_STRING OriginalName, IN PUNICODE_STRING Extension, IN OUT PUNICODE_STRING StaticString, IN OUT PUNICODE_STRING DynamicString, IN OUT PUNICODE_STRING *NewName, IN PULONG NewFlags, IN PSIZE_T FileNameSize, IN PSIZE_T RequiredLength)
Definition: libsupp.c:821
@ AnsiString
Definition: dnslib.h:19
NTSYSAPI PEB *WINAPI RtlGetCurrentPeb(void)
Definition: libsupp.c:63
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)
NTSTATUS NTAPI LdrpMapDll(IN PWSTR SearchPath OPTIONAL, IN PWSTR DllPath2, IN PWSTR DllName OPTIONAL, IN PULONG DllCharacteristics, IN BOOLEAN Static, IN BOOLEAN Redirect, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
Definition: ldrutils.c:1023
BOOLEAN NTAPI LdrpCheckForLoadedDll(IN PWSTR DllPath, IN PUNICODE_STRING DllName, IN BOOLEAN Flag, IN BOOLEAN RedirectedDll, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
Definition: ldrutils.c:1979
#define STATUS_SXS_KEY_NOT_FOUND
Definition: ntstatus.h:1389
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 2771 of file ldrutils.c.

2772{
2773 UNICODE_STRING ShimLibraryName;
2774 PVOID ShimLibrary;
2776 RtlInitUnicodeString(&ShimLibraryName, ImageName);
2777 /* We should NOT pass CallInit = TRUE!
2778 If we do this, other init routines will be called before we get a chance to shim stuff.. */
2779 Status = LdrpLoadDll(FALSE, NULL, NULL, &ShimLibraryName, &ShimLibrary, FALSE);
2780 if (NT_SUCCESS(Status))
2781 {
2782 g_pShimEngineModule = ShimLibrary;
2785 if (g_ShimsEnabled)
2786 {
2789 SE_InstallBeforeInit(ProcessImage, pShimData);
2790 }
2791 }
2792}
#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:2429
PVOID g_pShimEngineModule
Definition: ldrutils.c:22
VOID NTAPI LdrpRunShimEngineInitRoutine(IN ULONG Reason)
Definition: ldrutils.c:2736
VOID NTAPI LdrpGetShimEngineInterface()
Definition: ldrutils.c:2711
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 1023 of file ldrutils.c.

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

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

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

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

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

◆ 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 950 of file ldrpe.c.

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

462{
464 UNICODE_STRING UpdateString;
465
466 /* Setup the string and call the extended API */
467 RtlInitEmptyUnicodeString(&UpdateString, Buffer, sizeof(Buffer));
468 LdrpUpdateLoadCount3(LdrEntry, Flags, &UpdateString);
469}
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 1535 of file ldrinit.c.

1536{
1538}

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 */
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 */
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:5482
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().

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

◆ LdrpActiveUnloadCount

ULONG LdrpActiveUnloadCount
extern

Definition at line 84 of file ldrinit.c.

Referenced by LdrUnloadDll().

◆ LdrpCurrentDllInitializer

PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer
extern

Definition at line 43 of file ldrinit.c.

Referenced by LdrLoadDll(), and LdrpRunInitializeRoutines().

◆ LdrpDefaultPath

UNICODE_STRING LdrpDefaultPath
extern

◆ LdrpFatalHardErrorCount

ULONG LdrpFatalHardErrorCount
extern

Definition at line 83 of file ldrinit.c.

Referenced by LdrpCreateDllSection(), LdrpInitFailure(), LdrpMapDll(), and LdrpSnapThunk().

◆ LdrpGetModuleHandleCache

PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache
extern

Definition at line 19 of file ldrutils.c.

Referenced by LdrGetDllHandleEx(), and LdrUnloadDll().

◆ LdrpHashTable