ReactOS 0.4.16-dev-287-g2d3f3a1
ldrinit.c File Reference
#include <ntdll.h>
#include <compat_undoc.h>
#include <compatguid_undoc.h>
#include <debug.h>
Include dependency graph for ldrinit.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define DEFAULT_SECURITY_COOKIE   0xBB40E64E
 
#define VALID_CONFIG_FIELD(Name)   (ConfigSize >= RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, Name))
 

Functions

static NTSTATUS (WINAPI *Kernel32ProcessInitPostImportFunction)(VOID)
 
static BOOL (WINAPI *Kernel32BaseQueryModuleData)(IN LPSTR ModuleName
 
VOID NTAPI RtlpInitializeVectoredExceptionHandling (VOID)
 
VOID NTAPI RtlpInitDeferredCriticalSection (VOID)
 
VOID NTAPI RtlInitializeHeapManager (VOID)
 
NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders, PVOID ImageBase)
 
NTSTATUS NTAPI RtlpInitializeActCtx (PVOID *pOldShimData)
 
NTSTATUS NTAPI LdrOpenImageFileOptionsKey (_In_ PUNICODE_STRING SubKey, _In_ BOOLEAN Wow64, _Out_ PHANDLE NewKeyHandle)
 
NTSTATUS NTAPI LdrQueryImageFileKeyOption (_In_ HANDLE KeyHandle, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength)
 
NTSTATUS NTAPI LdrQueryImageFileExecutionOptionsEx (_In_ PUNICODE_STRING SubKey, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength, _In_ BOOLEAN Wow64)
 
NTSTATUS NTAPI LdrQueryImageFileExecutionOptions (_In_ PUNICODE_STRING SubKey, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength)
 
VOID NTAPI LdrpEnsureLoaderLockIsHeld (VOID)
 
PVOID NTAPI LdrpFetchAddressOfSecurityCookie (PVOID BaseAddress, ULONG SizeOfImage)
 
PVOID NTAPI LdrpInitSecurityCookie (PLDR_DATA_TABLE_ENTRY LdrEntry)
 
VOID NTAPI LdrpInitializeThread (IN PCONTEXT Context)
 
NTSTATUS NTAPI LdrpRunInitializeRoutines (IN PCONTEXT Context OPTIONAL)
 
NTSTATUS NTAPI LdrShutdownProcess (VOID)
 
NTSTATUS NTAPI LdrShutdownThread (VOID)
 
NTSTATUS NTAPI LdrpInitializeTls (VOID)
 
NTSTATUS NTAPI LdrpAllocateTls (VOID)
 
VOID NTAPI LdrpFreeTls (VOID)
 
NTSTATUS NTAPI LdrpInitializeExecutionOptions (PUNICODE_STRING ImagePathName, PPEB Peb, PHANDLE OptionsKey)
 
VOID NTAPI LdrpValidateImageForMp (IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
 
BOOLEAN NTAPI LdrpDisableProcessCompatGuidDetection (VOID)
 
VOID NTAPI LdrpInitializeProcessCompat (PVOID pProcessActctx, PVOID *pOldShimData)
 
VOID NTAPI LdrpInitializeDotLocalSupport (PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
 
NTSTATUS NTAPI LdrpInitializeProcess (IN PCONTEXT Context, IN PVOID SystemArgument1)
 
VOID NTAPI LdrpInitFailure (NTSTATUS Status)
 
VOID NTAPI LdrpInit (PCONTEXT Context, PVOID SystemArgument1, PVOID SystemArgument2)
 

Variables

HANDLE ImageExecOptionsKey
 
HANDLE Wow64ExecOptionsKey
 
UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options")
 
UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L"")
 
UNICODE_STRING NtDllString = RTL_CONSTANT_STRING(L"ntdll.dll")
 
UNICODE_STRING Kernel32String = RTL_CONSTANT_STRING(L"kernel32.dll")
 
const UNICODE_STRING LdrpDotLocal = RTL_CONSTANT_STRING(L".Local")
 
BOOLEAN LdrpInLdrInit
 
LONG LdrpProcessInitialized
 
BOOLEAN LdrpLoaderLockInit
 
BOOLEAN LdrpLdrDatabaseIsSetup
 
BOOLEAN LdrpShutdownInProgress
 
HANDLE LdrpShutdownThreadId
 
BOOLEAN LdrpDllValidation
 
PLDR_DATA_TABLE_ENTRY LdrpImageEntry
 
PUNICODE_STRING LdrpTopLevelDllBeingLoaded
 
WCHAR StringBuffer [156]
 
PTEB LdrpTopLevelDllBeingLoadedTeb
 
PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer
 
PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry
 
static IN LPSTR Unk1
 
static IN LPSTR IN PVOID Unk2
 
static IN LPSTR IN PVOID IN PVOID Unk3
 
static IN LPSTR IN PVOID IN PVOID IN PVOID Unk4
 
RTL_BITMAP TlsBitMap
 
RTL_BITMAP TlsExpansionBitMap
 
RTL_BITMAP FlsBitMap
 
BOOLEAN LdrpImageHasTls
 
LIST_ENTRY LdrpTlsList
 
ULONG LdrpNumberOfTlsEntries
 
ULONG LdrpNumberOfProcessors
 
PVOID NtDllBase
 
LARGE_INTEGER RtlpTimeout
 
BOOLEAN RtlpTimeoutDisable
 
PVOID LdrpHeap
 
LIST_ENTRY LdrpHashTable [LDR_HASH_TABLE_ENTRIES]
 
LIST_ENTRY LdrpDllNotificationList
 
HANDLE LdrpKnownDllObjectDirectory
 
UNICODE_STRING LdrpKnownDllPath
 
WCHAR LdrpKnownDllPathBuffer [128]
 
UNICODE_STRING LdrpDefaultPath
 
PEB_LDR_DATA PebLdr
 
RTL_CRITICAL_SECTION_DEBUG LdrpLoaderLockDebug
 
RTL_CRITICAL_SECTION LdrpLoaderLock
 
RTL_CRITICAL_SECTION FastPebLock
 
BOOLEAN ShowSnaps
 
ULONG LdrpFatalHardErrorCount
 
ULONG LdrpActiveUnloadCount
 
ULONG RtlpDisableHeapLookaside
 
ULONG RtlpShutdownProcessFlags
 
BOOLEAN RtlpUse16ByteSLists
 

Macro Definition Documentation

◆ DEFAULT_SECURITY_COOKIE

#define DEFAULT_SECURITY_COOKIE   0xBB40E64E

Definition at line 102 of file ldrinit.c.

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file ldrinit.c.

◆ VALID_CONFIG_FIELD

#define VALID_CONFIG_FIELD (   Name)    (ConfigSize >= RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, Name))

Function Documentation

◆ BOOL()

static BOOL ( WINAPI Kernel32BaseQueryModuleData)
static

◆ LdrOpenImageFileOptionsKey()

NTSTATUS NTAPI LdrOpenImageFileOptionsKey ( _In_ PUNICODE_STRING  SubKey,
_In_ BOOLEAN  Wow64,
_Out_ PHANDLE  NewKeyHandle 
)

Definition at line 112 of file ldrinit.c.

116{
117 PHANDLE RootKeyLocation;
119 UNICODE_STRING SubKeyString;
122 PWCHAR p1;
123
124 /* Check which root key to open */
125 if (Wow64)
126 RootKeyLocation = &Wow64ExecOptionsKey;
127 else
128 RootKeyLocation = &ImageExecOptionsKey;
129
130 /* Get the current key */
131 RootKey = *RootKeyLocation;
132
133 /* Setup the object attributes */
135 Wow64 ?
138 NULL,
139 NULL);
140
141 /* Open the root key */
143 if (NT_SUCCESS(Status))
144 {
145 /* Write the key handle */
146 if (InterlockedCompareExchangePointer(RootKeyLocation, RootKey, NULL) != NULL)
147 {
148 /* Someone already opened it, use it instead */
150 RootKey = *RootKeyLocation;
151 }
152
153 /* Extract the name */
154 SubKeyString = *SubKey;
155 p1 = (PWCHAR)((ULONG_PTR)SubKeyString.Buffer + SubKeyString.Length);
156 while (SubKeyString.Length)
157 {
158 if (p1[-1] == L'\\') break;
159 p1--;
160 SubKeyString.Length -= sizeof(*p1);
161 }
162 SubKeyString.Buffer = p1;
163 SubKeyString.Length = SubKey->Length - SubKeyString.Length;
164
165 /* Setup the object attributes */
167 &SubKeyString,
169 RootKey,
170 NULL);
171
172 /* Open the setting key */
173 Status = ZwOpenKey((PHANDLE)NewKeyHandle, GENERIC_READ, &ObjectAttributes);
174 }
175
176 /* Return to caller */
177 return Status;
178}
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define GENERIC_READ
Definition: compat.h:135
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
HANDLE ImageExecOptionsKey
Definition: ldrinit.c:22
HANDLE Wow64ExecOptionsKey
Definition: ldrinit.c:23
UNICODE_STRING ImageExecOptionsString
Definition: ldrinit.c:24
UNICODE_STRING Wow64OptionsString
Definition: ldrinit.c:25
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define L(x)
Definition: ntvdm.h:50
static PMEMKEY RootKey
Definition: registry.c:55
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56

Referenced by CreateProcessInternalW(), LdrpInitializeExecutionOptions(), and LdrQueryImageFileExecutionOptionsEx().

◆ LdrpAllocateTls()

NTSTATUS NTAPI LdrpAllocateTls ( VOID  )

Definition at line 1321 of file ldrinit.c.

1322{
1323 PTEB Teb = NtCurrentTeb();
1324 PLIST_ENTRY NextEntry, ListHead;
1325 PLDRP_TLS_DATA TlsData;
1326 SIZE_T TlsDataSize;
1327 PVOID *TlsVector;
1328
1329 /* Check if we have any entries */
1331 return STATUS_SUCCESS;
1332
1333 /* Allocate the vector array */
1334 TlsVector = RtlAllocateHeap(RtlGetProcessHeap(),
1335 0,
1336 LdrpNumberOfTlsEntries * sizeof(PVOID));
1337 if (!TlsVector) return STATUS_NO_MEMORY;
1338 Teb->ThreadLocalStoragePointer = TlsVector;
1339
1340 /* Loop the TLS Array */
1341 ListHead = &LdrpTlsList;
1342 NextEntry = ListHead->Flink;
1343 while (NextEntry != ListHead)
1344 {
1345 /* Get the entry */
1346 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1347 NextEntry = NextEntry->Flink;
1348
1349 /* Allocate this vector */
1350 TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
1352 TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
1353 0,
1354 TlsDataSize);
1355 if (!TlsVector[TlsData->TlsDirectory.Characteristics])
1356 {
1357 /* Out of memory */
1358 return STATUS_NO_MEMORY;
1359 }
1360
1361 /* Show debug message */
1362 if (ShowSnaps)
1363 {
1364 DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
1365 TlsVector,
1367 &TlsVector[TlsData->TlsDirectory.Characteristics],
1369 TlsVector[TlsData->TlsDirectory.Characteristics]);
1370 }
1371
1372 /* Copy the data */
1373 RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics],
1375 TlsDataSize);
1376 }
1377
1378 /* Done */
1379 return STATUS_SUCCESS;
1380}
#define DPRINT1
Definition: precomp.h:8
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NtCurrentTeb
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: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
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
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by LdrpInitializeThread(), and LdrpInitializeTls().

◆ LdrpDisableProcessCompatGuidDetection()

BOOLEAN NTAPI LdrpDisableProcessCompatGuidDetection ( VOID  )

Definition at line 1546 of file ldrinit.c.

1547{
1548 UNICODE_STRING PolicyKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\Software\\Policies\\Microsoft\\Windows\\AppCompat");
1549 UNICODE_STRING DisableDetection = RTL_CONSTANT_STRING(L"DisableCompatGuidDetection");
1555
1556 Status = NtOpenKey(&KeyHandle, KEY_QUERY_VALUE, &PolicyKeyAttributes);
1557 if (NT_SUCCESS(Status))
1558 {
1560 &DisableDetection,
1562 &KeyInfo,
1563 sizeof(KeyInfo),
1564 &ResultLength);
1566 if ((NT_SUCCESS(Status)) &&
1567 (KeyInfo.Type == REG_DWORD) &&
1568 (KeyInfo.DataLength == sizeof(ULONG)) &&
1569 (KeyInfo.Data[0] == TRUE))
1570 {
1571 return TRUE;
1572 }
1573 }
1574 return FALSE;
1575}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
@ KeyValuePartialInformation
Definition: nt_native.h:1182
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
#define REG_DWORD
Definition: sdbapi.c:596
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776

Referenced by LdrpInitializeProcessCompat().

◆ LdrpEnsureLoaderLockIsHeld()

VOID NTAPI LdrpEnsureLoaderLockIsHeld ( VOID  )

Definition at line 409 of file ldrinit.c.

410{
411 // Ignored atm
412}

Referenced by LdrpCheckForKnownDll(), and LdrpRunInitializeRoutines().

◆ LdrPerformRelocations()

NTSTATUS LdrPerformRelocations ( PIMAGE_NT_HEADERS  NTHeaders,
PVOID  ImageBase 
)

◆ LdrpFetchAddressOfSecurityCookie()

PVOID NTAPI LdrpFetchAddressOfSecurityCookie ( PVOID  BaseAddress,
ULONG  SizeOfImage 
)

Definition at line 416 of file ldrinit.c.

417{
419 ULONG DirSize;
420 PVOID Cookie = NULL;
421
422 /* Check NT header first */
423 if (!RtlImageNtHeader(BaseAddress)) return NULL;
424
425 /* Get the pointer to the config directory */
427 TRUE,
429 &DirSize);
430
431 /* Check for sanity */
432 if (!ConfigDir ||
433 (DirSize != 64 && ConfigDir->Size != DirSize) ||
434 (ConfigDir->Size < 0x48))
435 return NULL;
436
437 /* Now get the cookie */
438 Cookie = (PVOID)ConfigDir->SecurityCookie;
439
440 /* Check this cookie */
442 (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage)
443 {
444 Cookie = NULL;
445 }
446
447 /* Return validated security cookie */
448 return Cookie;
449}
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
#define RtlImageNtHeader
Definition: compat.h:806
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
void * PVOID
Definition: typedefs.h:50
char * PCHAR
Definition: typedefs.h:51
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14

Referenced by LdrpInitSecurityCookie().

◆ LdrpFreeTls()

VOID NTAPI LdrpFreeTls ( VOID  )

Definition at line 1384 of file ldrinit.c.

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

Referenced by LdrShutdownThread().

◆ LdrpInit()

VOID NTAPI LdrpInit ( PCONTEXT  Context,
PVOID  SystemArgument1,
PVOID  SystemArgument2 
)

Definition at line 2562 of file ldrinit.c.

2565{
2567 PTEB Teb = NtCurrentTeb();
2568 NTSTATUS Status, LoaderStatus = STATUS_SUCCESS;
2569 MEMORY_BASIC_INFORMATION MemoryBasicInfo;
2570 PPEB Peb = NtCurrentPeb();
2571
2572 DPRINT("LdrpInit() %p/%p\n",
2573 NtCurrentTeb()->RealClientId.UniqueProcess,
2574 NtCurrentTeb()->RealClientId.UniqueThread);
2575
2576#ifdef _WIN64
2577 /* Set the SList header usage */
2579#endif /* _WIN64 */
2580
2581 /* Check if we have a deallocation stack */
2582 if (!Teb->DeallocationStack)
2583 {
2584 /* We don't, set one */
2586 Teb->NtTib.StackLimit,
2588 &MemoryBasicInfo,
2590 NULL);
2591 if (!NT_SUCCESS(Status))
2592 {
2593 /* Fail */
2596 return;
2597 }
2598
2599 /* Set the stack */
2600 Teb->DeallocationStack = MemoryBasicInfo.AllocationBase;
2601 }
2602
2603 /* Now check if the process is already being initialized */
2605 1,
2606 0) == 1)
2607 {
2608 /* Set the timeout to 30 milliseconds */
2609 Timeout.QuadPart = Int32x32To64(30, -10000);
2610
2611 /* Make sure the status hasn't changed */
2612 while (LdrpProcessInitialized == 1)
2613 {
2614 /* Do the wait */
2616 }
2617 }
2618
2619 /* Check if we have already setup LDR data */
2620 if (!Peb->Ldr)
2621 {
2622 /* Setup the Loader Lock */
2624
2625 /* Let other code know we're initializing */
2627
2628 /* Protect with SEH */
2629 _SEH2_TRY
2630 {
2631 /* Initialize the Process */
2632 LoaderStatus = LdrpInitializeProcess(Context,
2634
2635 /* Check for success and if MinimumStackCommit was requested */
2636 if (NT_SUCCESS(LoaderStatus) && Peb->MinimumStackCommit)
2637 {
2638 /* Enforce the limit */
2639 //LdrpTouchThreadStack(Peb->MinimumStackCommit);
2641 }
2642 }
2644 {
2645 /* Fail with the SEH error */
2646 LoaderStatus = _SEH2_GetExceptionCode();
2647 }
2648 _SEH2_END;
2649
2650 /* We're not initializing anymore */
2652
2653 /* Check if init worked */
2654 if (NT_SUCCESS(LoaderStatus))
2655 {
2656 /* Set the process as Initialized */
2658 }
2659 }
2660 else
2661 {
2662 /* Loader data is there... is this a fork() ? */
2664 {
2665 /* Handle the fork() */
2666 //LoaderStatus = LdrpForkProcess();
2667 LoaderStatus = STATUS_NOT_IMPLEMENTED;
2669 }
2670 else
2671 {
2672 /* This is a new thread initializing */
2674 }
2675 }
2676
2677 /* All done, test alert the thread */
2678 NtTestAlert();
2679
2680 /* Return */
2681 if (!NT_SUCCESS(LoaderStatus))
2682 {
2683 /* Fail */
2684 LdrpInitFailure(LoaderStatus);
2685 RtlRaiseStatus(LoaderStatus);
2686 }
2687}
#define NtCurrentPeb()
Definition: FLS.c:22
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
PPEB Peb
Definition: dllmain.c:27
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
long __cdecl _InterlockedCompareExchange(_Interlocked_operand_ long volatile *_Destination, long _Exchange, long _Comparand)
BOOLEAN LdrpInLdrInit
Definition: ldrinit.c:30
LONG LdrpProcessInitialized
Definition: ldrinit.c:31
NTSTATUS NTAPI LdrpInitializeProcess(IN PCONTEXT Context, IN PVOID SystemArgument1)
Definition: ldrinit.c:1757
RTL_CRITICAL_SECTION LdrpLoaderLock
Definition: ldrinit.c:70
VOID NTAPI LdrpInitFailure(NTSTATUS Status)
Definition: ldrinit.c:2544
VOID NTAPI LdrpInitializeThread(IN PCONTEXT Context)
Definition: ldrinit.c:506
BOOLEAN RtlpUse16ByteSLists
NTSYSAPI NTSTATUS NTAPI ZwDelayExecution(_In_ BOOLEAN Alertable, _In_ LARGE_INTEGER *Interval)
@ MemoryBasicInformation
Definition: mmtypes.h:183
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define Int32x32To64(a, b)
NTSTATUS NTAPI NtQueryVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN MEMORY_INFORMATION_CLASS MemoryInformationClass, OUT PVOID MemoryInformation, IN SIZE_T MemoryInformationLength, OUT PSIZE_T ReturnLength)
Definition: virtual.c:4409
NTSTATUS NTAPI NtTestAlert(VOID)
Definition: state.c:465
static ULONG Timeout
Definition: ping.c:61
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define SharedUserData
#define DPRINT
Definition: sndvol32.h:73
PVOID StackLimit
Definition: compat.h:713
PVOID LoaderLock
Definition: ntddk_ex.h:295
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1912
SIZE_T MinimumStackCommit
Definition: winternl.h:358
BOOLEAN InheritedAddressSpace
Definition: ntddk_ex.h:239
NT_TIB NtTib
Definition: ntddk_ex.h:332
PVOID DeallocationStack
Definition: compat.h:878
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
#define PF_COMPARE_EXCHANGE128
Definition: ketypes.h:138

◆ LdrpInitFailure()

VOID NTAPI LdrpInitFailure ( NTSTATUS  Status)

Definition at line 2544 of file ldrinit.c.

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

◆ LdrpInitializeDotLocalSupport()

VOID NTAPI LdrpInitializeDotLocalSupport ( PRTL_USER_PROCESS_PARAMETERS  ProcessParameters)

Definition at line 1696 of file ldrinit.c.

1697{
1698 UNICODE_STRING ImagePathName = ProcessParameters->ImagePathName;
1699 WCHAR LocalBuffer[MAX_PATH];
1700 UNICODE_STRING DotLocal;
1703
1704 RequiredSize = ImagePathName.Length + LdrpDotLocal.Length + sizeof(UNICODE_NULL);
1705 if (RequiredSize <= sizeof(LocalBuffer))
1706 {
1707 RtlInitEmptyUnicodeString(&DotLocal, LocalBuffer, sizeof(LocalBuffer));
1708 }
1710 {
1711 DotLocal.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, RequiredSize);
1712 DotLocal.Length = 0;
1713 DotLocal.MaximumLength = RequiredSize;
1714 if (!DotLocal.Buffer)
1715 DPRINT1("LDR: Failed to allocate memory for .local check\n");
1716 }
1717 else
1718 {
1719 DotLocal.Buffer = NULL;
1720 DotLocal.Length = 0;
1721 DotLocal.MaximumLength = 0;
1722 DPRINT1("LDR: String too big for .local check\n");
1723 }
1724
1725 if (DotLocal.Buffer)
1726 {
1727 Status = RtlAppendUnicodeStringToString(&DotLocal, &ImagePathName);
1729 if (NT_SUCCESS(Status))
1730 {
1733 }
1734
1735 if (NT_SUCCESS(Status))
1736 {
1737 if (RtlDoesFileExists_UStr(&DotLocal))
1738 {
1740 }
1741 }
1742 else
1743 {
1744 DPRINT1("LDR: Failed to append: 0x%lx\n", Status);
1745 }
1746
1747 if (DotLocal.Buffer != LocalBuffer)
1748 {
1749 RtlFreeHeap(RtlGetProcessHeap(), 0, DotLocal.Buffer);
1750 }
1751 }
1752}
#define MAX_PATH
Definition: compat.h:34
const UNICODE_STRING LdrpDotLocal
Definition: ldrinit.c:28
#define ASSERT(a)
Definition: mode.c:44
#define RTL_USER_PROCESS_PARAMETERS_PRIVATE_DLL_PATH
Definition: rtltypes.h:52
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define UNICODE_NULL
#define UNICODE_STRING_MAX_BYTES
BOOLEAN NTAPI RtlDoesFileExists_UStr(IN PUNICODE_STRING FileName)
Definition: path.c:1503
USHORT MaximumLength
Definition: env_spec_w32.h:370
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4439
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by LdrpInitializeProcess().

◆ LdrpInitializeExecutionOptions()

NTSTATUS NTAPI LdrpInitializeExecutionOptions ( PUNICODE_STRING  ImagePathName,
PPEB  Peb,
PHANDLE  OptionsKey 
)

Definition at line 1420 of file ldrinit.c.

1421{
1424 ULONG ExecuteOptions, MinimumStackCommit = 0, GlobalFlag;
1425
1426 /* Return error if we were not provided a pointer where to save the options key handle */
1427 if (!OptionsKey) return STATUS_INVALID_HANDLE;
1428
1429 /* Zero initialize the options key pointer */
1430 *OptionsKey = NULL;
1431
1432 /* Open the options key */
1433 Status = LdrOpenImageFileOptionsKey(ImagePathName, 0, &KeyHandle);
1434
1435 /* Save it if it was opened successfully */
1436 if (NT_SUCCESS(Status))
1437 *OptionsKey = KeyHandle;
1438
1439 if (KeyHandle)
1440 {
1441 /* There are image specific options, read them starting with NXCOMPAT */
1443 L"ExecuteOptions",
1444 4,
1445 &ExecuteOptions,
1446 sizeof(ExecuteOptions),
1447 0);
1448
1449 if (NT_SUCCESS(Status))
1450 {
1451 /* TODO: Set execution options for the process */
1452 /*
1453 if (ExecuteOptions == 0)
1454 ExecuteOptions = 1;
1455 else
1456 ExecuteOptions = 2;
1457 ZwSetInformationProcess(NtCurrentProcess(),
1458 ProcessExecuteFlags,
1459 &ExecuteOptions,
1460 sizeof(ULONG));*/
1461
1462 }
1463
1464 /* Check if this image uses large pages */
1465 if (Peb->ImageUsesLargePages)
1466 {
1467 /* TODO: If it does, open large page key */
1469 }
1470
1471 /* Get various option values */
1473 L"DisableHeapLookaside",
1474 REG_DWORD,
1477 NULL);
1478
1480 L"ShutdownFlags",
1481 REG_DWORD,
1484 NULL);
1485
1487 L"MinimumStackCommitInBytes",
1488 REG_DWORD,
1489 &MinimumStackCommit,
1490 sizeof(MinimumStackCommit),
1491 NULL);
1492
1493 /* Update PEB's minimum stack commit if it's lower */
1494 if (Peb->MinimumStackCommit < MinimumStackCommit)
1495 Peb->MinimumStackCommit = MinimumStackCommit;
1496
1497 /* Set the global flag */
1499 L"GlobalFlag",
1500 REG_DWORD,
1501 &GlobalFlag,
1502 sizeof(GlobalFlag),
1503 NULL);
1504
1505 if (NT_SUCCESS(Status))
1506 Peb->NtGlobalFlag = GlobalFlag;
1507 else
1508 GlobalFlag = 0;
1509
1510 /* Call AVRF if necessary */
1512 {
1514 if (!NT_SUCCESS(Status))
1515 {
1516 DPRINT1("AVRF: LdrpInitializeApplicationVerifierPackage failed with %08X\n", Status);
1517 }
1518 }
1519 }
1520 else
1521 {
1522 /* There are no image-specific options, so perform global initialization */
1524 {
1525 /* Initialize app verifier package */
1527 if (!NT_SUCCESS(Status))
1528 {
1529 DPRINT1("AVRF: LdrpInitializeApplicationVerifierPackage failed with %08X\n", Status);
1530 }
1531 }
1532 }
1533
1534 return STATUS_SUCCESS;
1535}
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define FLG_HEAP_PAGE_ALLOCS
Definition: pstypes.h:84
#define FLG_APPLICATION_VERIFIER
Definition: pstypes.h:64
ULONG RtlpDisableHeapLookaside
Definition: ldrinit.c:92
ULONG RtlpShutdownProcessFlags
Definition: ldrinit.c:93
NTSTATUS NTAPI LdrQueryImageFileKeyOption(_In_ HANDLE KeyHandle, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength)
Definition: ldrinit.c:185
NTSTATUS NTAPI LdrOpenImageFileOptionsKey(_In_ PUNICODE_STRING SubKey, _In_ BOOLEAN Wow64, _Out_ PHANDLE NewKeyHandle)
Definition: ldrinit.c:112
NTSTATUS NTAPI LdrpInitializeApplicationVerifierPackage(IN HANDLE KeyHandle, IN PPEB Peb, IN BOOLEAN SystemWide, IN BOOLEAN ReadAdvancedOptions)
ULONG NtGlobalFlag
Definition: ntddk_ex.h:270

Referenced by LdrpInitializeProcess().

◆ LdrpInitializeProcess()

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

Definition at line 1757 of file ldrinit.c.

1759{
1760 RTL_HEAP_PARAMETERS HeapParameters;
1761 ULONG ComSectionSize;
1762 ANSI_STRING BaseProcessInitPostImportName = RTL_CONSTANT_STRING("BaseProcessInitPostImport");
1763 ANSI_STRING BaseQueryModuleDataName = RTL_CONSTANT_STRING("BaseQueryModuleData");
1764 PVOID OldShimData;
1766 //UNICODE_STRING LocalFileName, FullImageName;
1767 HANDLE SymLinkHandle;
1768 //ULONG DebugHeapOnly;
1769 UNICODE_STRING CommandLine, NtSystemRoot, ImagePathName, FullPath, ImageFileName, KnownDllString;
1770 PPEB Peb = NtCurrentPeb();
1771 BOOLEAN IsDotNetImage = FALSE;
1772 BOOLEAN FreeCurDir = FALSE;
1773 //HANDLE CompatKey;
1774 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
1775 //LPWSTR ImagePathBuffer;
1776 ULONG ConfigSize;
1778 HANDLE OptionsKey;
1779 ULONG HeapFlags;
1780 PIMAGE_NT_HEADERS NtHeader;
1781 LPWSTR NtDllName = NULL;
1782 NTSTATUS Status, ImportStatus;
1783 NLSTABLEINFO NlsTable;
1785 PTEB Teb = NtCurrentTeb();
1786 PLIST_ENTRY ListHead;
1787 PLIST_ENTRY NextEntry;
1788 ULONG i;
1789 PWSTR ImagePath;
1790 ULONG DebugProcessHeapOnly = 0;
1791 PLDR_DATA_TABLE_ENTRY NtLdrEntry;
1792 PWCHAR Current;
1793 ULONG ExecuteOptions = 0;
1794 PVOID ViewBase;
1795
1796 /* Set a NULL SEH Filter */
1798
1799 /* Get the image path */
1801
1802 /* Check if it's not normalized */
1804 {
1805 /* Normalize it*/
1806 ImagePath = (PWSTR)((ULONG_PTR)ImagePath + (ULONG_PTR)Peb->ProcessParameters);
1807 }
1808
1809 /* Create a unicode string for the Image Path */
1811 ImagePathName.MaximumLength = ImagePathName.Length + sizeof(WCHAR);
1812 ImagePathName.Buffer = ImagePath;
1813
1814 /* Get the NT Headers */
1816
1817 /* Get the execution options */
1818 Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &OptionsKey);
1819
1820 /* Check if this is a .NET executable */
1822 TRUE,
1824 &ComSectionSize))
1825 {
1826 /* Remember this for later */
1827 IsDotNetImage = TRUE;
1828 }
1829
1830 /* Save the NTDLL Base address */
1832
1833 /* If this is a Native Image */
1835 {
1836 /* Then do DLL Validation */
1838 }
1839
1840 /* Save the old Shim Data */
1841 OldShimData = Peb->pShimData;
1842
1843 /* ReactOS specific: do not clear it. (Windows starts doing the same in later versions) */
1844 //Peb->pShimData = NULL;
1845
1846 /* Save the number of processors and CS timeout */
1849
1850 /* Normalize the parameters */
1851 ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
1852 if (ProcessParameters)
1853 {
1854 /* Save the Image and Command Line Names */
1855 ImageFileName = ProcessParameters->ImagePathName;
1856 CommandLine = ProcessParameters->CommandLine;
1857 }
1858 else
1859 {
1860 /* It failed, initialize empty strings */
1861 RtlInitUnicodeString(&ImageFileName, NULL);
1862 RtlInitUnicodeString(&CommandLine, NULL);
1863 }
1864
1865 /* Initialize NLS data */
1869 &NlsTable);
1870
1871 /* Reset NLS Translations */
1872 RtlResetRtlTranslations(&NlsTable);
1873
1874 /* Get the Image Config Directory */
1876 TRUE,
1878 &ConfigSize);
1879
1880 /* Setup the Heap Parameters */
1881 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
1882 HeapFlags = HEAP_GROWABLE;
1883 HeapParameters.Length = sizeof(HeapParameters);
1884
1885 /* Check if we have Configuration Data */
1886#define VALID_CONFIG_FIELD(Name) (ConfigSize >= RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, Name))
1887 /* The 'original' load config ends after SecurityCookie */
1888 if ((LoadConfig) && ConfigSize && (VALID_CONFIG_FIELD(SecurityCookie) || ConfigSize == LoadConfig->Size))
1889 {
1890 if (ConfigSize != sizeof(IMAGE_LOAD_CONFIG_DIRECTORY))
1891 DPRINT1("WARN: Accepting different LOAD_CONFIG size!\n");
1892 else
1893 DPRINT1("Applying LOAD_CONFIG\n");
1894
1895 if (VALID_CONFIG_FIELD(GlobalFlagsSet) && LoadConfig->GlobalFlagsSet)
1896 Peb->NtGlobalFlag |= LoadConfig->GlobalFlagsSet;
1897
1898 if (VALID_CONFIG_FIELD(GlobalFlagsClear) && LoadConfig->GlobalFlagsClear)
1899 Peb->NtGlobalFlag &= ~LoadConfig->GlobalFlagsClear;
1900
1901 /* Convert the default CS timeout from milliseconds to 100ns units */
1902 if (VALID_CONFIG_FIELD(CriticalSectionDefaultTimeout) && LoadConfig->CriticalSectionDefaultTimeout)
1903 RtlpTimeout.QuadPart = Int32x32To64(LoadConfig->CriticalSectionDefaultTimeout, -10000);
1904
1905 if (VALID_CONFIG_FIELD(DeCommitFreeBlockThreshold) && LoadConfig->DeCommitFreeBlockThreshold)
1906 HeapParameters.DeCommitFreeBlockThreshold = LoadConfig->DeCommitFreeBlockThreshold;
1907
1908 if (VALID_CONFIG_FIELD(DeCommitTotalFreeThreshold) && LoadConfig->DeCommitTotalFreeThreshold)
1909 HeapParameters.DeCommitTotalFreeThreshold = LoadConfig->DeCommitTotalFreeThreshold;
1910
1911 if (VALID_CONFIG_FIELD(MaximumAllocationSize) && LoadConfig->MaximumAllocationSize)
1912 HeapParameters.MaximumAllocationSize = LoadConfig->MaximumAllocationSize;
1913
1914 if (VALID_CONFIG_FIELD(VirtualMemoryThreshold) && LoadConfig->VirtualMemoryThreshold)
1915 HeapParameters.VirtualMemoryThreshold = LoadConfig->VirtualMemoryThreshold;
1916
1917 if (VALID_CONFIG_FIELD(ProcessHeapFlags) && LoadConfig->ProcessHeapFlags)
1918 HeapFlags = LoadConfig->ProcessHeapFlags;
1919 }
1920#undef VALID_CONFIG_FIELD
1921
1922 /* Check for custom affinity mask */
1924 {
1925 /* Set it */
1929 sizeof(Peb->ImageProcessAffinityMask));
1930 }
1931
1932 /* Check if verbose debugging (ShowSnaps) was requested */
1934
1935 /* Start verbose debugging messages right now if they were requested */
1936 if (ShowSnaps)
1937 {
1938 DPRINT1("LDR: PID: 0x%p started - '%wZ'\n",
1940 &CommandLine);
1941 }
1942
1943 /* If the CS timeout is longer than 1 hour, disable it */
1944 if (RtlpTimeout.QuadPart < Int32x32To64(3600, -10000000))
1946
1947 /* Initialize Critical Section Data */
1949
1950 /* Initialize VEH Call lists */
1952
1953 /* Set TLS/FLS Bitmap data */
1957
1958 /* Initialize FLS Bitmap */
1962 RtlSetBit(&FlsBitMap, 0);
1964
1965 /* Initialize TLS Bitmap */
1969 RtlSetBit(&TlsBitMap, 0);
1974
1975 /* Initialize the Hash Table */
1976 for (i = 0; i < LDR_HASH_TABLE_ENTRIES; i++)
1977 {
1979 }
1980
1981 /* Initialize the Loader Lock */
1982 // FIXME: What's the point of initing it manually, if two lines lower
1983 // a call to RtlInitializeCriticalSection() is being made anyway?
1984 //InsertTailList(&RtlCriticalSectionList, &LdrpLoaderLock.DebugInfo->ProcessLocksList);
1985 //LdrpLoaderLock.DebugInfo->CriticalSection = &LdrpLoaderLock;
1988
1989 /* Check if User Stack Trace Database support was requested */
1991 {
1992 DPRINT1("We don't support user stack trace databases yet\n");
1993 }
1994
1995 /* Setup Fast PEB Lock */
1998 //Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
1999 //Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
2000
2001 /* Setup Callout Lock and Notification list */
2002 //RtlInitializeCriticalSection(&RtlpCalloutEntryLock);
2004
2005 /* For old executables, use 16-byte aligned heap */
2006 if ((NtHeader->OptionalHeader.MajorSubsystemVersion <= 3) &&
2007 (NtHeader->OptionalHeader.MinorSubsystemVersion < 51))
2008 {
2009 HeapFlags |= HEAP_CREATE_ALIGN_16;
2010 }
2011
2012 /* Setup the Heap */
2014 Peb->ProcessHeap = RtlCreateHeap(HeapFlags,
2015 NULL,
2018 NULL,
2019 &HeapParameters);
2020
2021 if (!Peb->ProcessHeap)
2022 {
2023 DPRINT1("Failed to create process heap\n");
2024 return STATUS_NO_MEMORY;
2025 }
2026
2027 /* Allocate an Activation Context Stack */
2028 Status = RtlAllocateActivationContextStack(&Teb->ActivationContextStackPointer);
2029 if (!NT_SUCCESS(Status)) return Status;
2030
2031 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
2032 HeapFlags = HEAP_GROWABLE | HEAP_CLASS_1;
2033 HeapParameters.Length = sizeof(HeapParameters);
2034 LdrpHeap = RtlCreateHeap(HeapFlags, 0, 0x10000, 0x6000, 0, &HeapParameters);
2035 if (!LdrpHeap)
2036 {
2037 DPRINT1("Failed to create loader private heap\n");
2038 return STATUS_NO_MEMORY;
2039 }
2040
2041 /* Check for Debug Heap */
2042 if (OptionsKey)
2043 {
2044 /* Query the setting */
2046 L"DebugProcessHeapOnly",
2047 REG_DWORD,
2048 &DebugProcessHeapOnly,
2049 sizeof(ULONG),
2050 NULL);
2051
2052 if (NT_SUCCESS(Status))
2053 {
2054 /* Reset DPH if requested */
2055 if (RtlpPageHeapEnabled && DebugProcessHeapOnly)
2056 {
2057 RtlpDphGlobalFlags &= ~DPH_FLAG_DLL_NOTIFY;
2059 }
2060 }
2061 }
2062
2063 /* Build the NTDLL Path */
2064 FullPath.Buffer = StringBuffer;
2065 FullPath.Length = 0;
2066 FullPath.MaximumLength = sizeof(StringBuffer);
2069 RtlAppendUnicodeToString(&FullPath, L"\\System32\\");
2070
2071 /* Open the Known DLLs directory */
2072 RtlInitUnicodeString(&KnownDllString, L"\\KnownDlls");
2074 &KnownDllString,
2076 NULL,
2077 NULL);
2081
2082 /* Check if it exists */
2083 if (NT_SUCCESS(Status))
2084 {
2085 /* Open the Known DLLs Path */
2086 RtlInitUnicodeString(&KnownDllString, L"KnownDllPath");
2088 &KnownDllString,
2091 NULL);
2092 Status = NtOpenSymbolicLinkObject(&SymLinkHandle,
2095 if (NT_SUCCESS(Status))
2096 {
2097 /* Query the path */
2101 Status = ZwQuerySymbolicLinkObject(SymLinkHandle, &LdrpKnownDllPath, NULL);
2102 NtClose(SymLinkHandle);
2103 if (!NT_SUCCESS(Status))
2104 {
2105 DPRINT1("LDR: %s - failed call to ZwQuerySymbolicLinkObject with status %x\n", "", Status);
2106 return Status;
2107 }
2108 }
2109 }
2110
2111 /* Check if we failed */
2112 if (!NT_SUCCESS(Status))
2113 {
2114 /* Assume System32 */
2117 LdrpKnownDllPath.Length -= sizeof(WCHAR);
2118 }
2119
2120 /* If we have process parameters, get the default path and current path */
2121 if (ProcessParameters)
2122 {
2123 /* Check if we have a Dll Path */
2124 if (ProcessParameters->DllPath.Length)
2125 {
2126 /* Get the path */
2127 LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath;
2128 }
2129 else
2130 {
2131 /* We need a valid path */
2132 DPRINT1("No valid DllPath was given!\n");
2134 }
2135
2136 /* Set the current directory */
2137 CurrentDirectory = ProcessParameters->CurrentDirectory.DosPath;
2138
2139 /* Check if it's empty or invalid */
2140 if ((!CurrentDirectory.Buffer) ||
2141 (CurrentDirectory.Buffer[0] == UNICODE_NULL) ||
2142 (!CurrentDirectory.Length))
2143 {
2144 /* Allocate space for the buffer */
2146 0,
2147 3 * sizeof(WCHAR) +
2148 sizeof(UNICODE_NULL));
2149 if (!CurrentDirectory.Buffer)
2150 {
2151 DPRINT1("LDR: LdrpInitializeProcess - unable to allocate current working directory buffer\n");
2152 // FIXME: And what?
2153 }
2154
2155 /* Copy the drive of the system root */
2157 SharedUserData->NtSystemRoot,
2158 3 * sizeof(WCHAR));
2159 CurrentDirectory.Buffer[3] = UNICODE_NULL;
2160 CurrentDirectory.Length = 3 * sizeof(WCHAR);
2161 CurrentDirectory.MaximumLength = CurrentDirectory.Length + sizeof(WCHAR);
2162
2163 FreeCurDir = TRUE;
2164 DPRINT("Using dynamically allocd curdir\n");
2165 }
2166 else
2167 {
2168 /* Use the local buffer */
2169 DPRINT("Using local system root\n");
2170 }
2171 }
2172
2173 /* Setup Loader Data */
2174 Peb->Ldr = &PebLdr;
2178 PebLdr.Length = sizeof(PEB_LDR_DATA);
2180
2181 /* Allocate a data entry for the Image */
2183
2184 /* Set it up */
2188 LdrpImageEntry->FullDllName = ImageFileName;
2189
2190 if (IsDotNetImage)
2192 else
2193 LdrpImageEntry->Flags = 0;
2194
2195 /* Check if the name is empty */
2196 if (!ImageFileName.Buffer[0])
2197 {
2198 /* Use the same Base name */
2200 }
2201 else
2202 {
2203 /* Find the last slash */
2204 Current = ImageFileName.Buffer;
2205 while (*Current)
2206 {
2207 if (*Current++ == '\\')
2208 {
2209 /* Set this path */
2210 NtDllName = Current;
2211 }
2212 }
2213
2214 /* Did we find anything? */
2215 if (!NtDllName)
2216 {
2217 /* Use the same Base name */
2219 }
2220 else
2221 {
2222 /* Setup the name */
2223 LdrpImageEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName);
2226 (ImageFileName.Length - LdrpImageEntry->BaseDllName.Length));
2227 }
2228 }
2229
2230 /* Processing done, insert it */
2233
2234 /* Now add an entry for NTDLL */
2236 NtLdrEntry->Flags = LDRP_IMAGE_DLL;
2237 NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase);
2238 NtLdrEntry->LoadCount = -1;
2239 NtLdrEntry->EntryPointActivationContext = 0;
2240
2241 NtLdrEntry->FullDllName.Length = FullPath.Length;
2242 NtLdrEntry->FullDllName.MaximumLength = FullPath.MaximumLength;
2243 NtLdrEntry->FullDllName.Buffer = StringBuffer;
2245
2246 NtLdrEntry->BaseDllName.Length = NtDllString.Length;
2248 NtLdrEntry->BaseDllName.Buffer = NtDllString.Buffer;
2249
2250 /* Processing done, insert it */
2251 LdrpNtDllDataTableEntry = NtLdrEntry;
2252 LdrpInsertMemoryTableEntry(NtLdrEntry);
2253
2254 /* Let the world know */
2255 if (ShowSnaps)
2256 {
2257 DPRINT1("LDR: NEW PROCESS\n");
2258 DPRINT1(" Image Path: %wZ (%wZ)\n", &LdrpImageEntry->FullDllName, &LdrpImageEntry->BaseDllName);
2259 DPRINT1(" Current Directory: %wZ\n", &CurrentDirectory);
2260 DPRINT1(" Search Path: %wZ\n", &LdrpDefaultPath);
2261 }
2262
2263 /* Link the Init Order List */
2266
2267 /* Initialize Wine's active context implementation for the current process */
2268 RtlpInitializeActCtx(&OldShimData);
2269
2270 /* Set the current directory */
2272 if (!NT_SUCCESS(Status))
2273 {
2274 /* We failed, check if we should free it */
2275 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2276
2277 /* Set it to the NT Root */
2280 }
2281 else
2282 {
2283 /* We're done with it, free it */
2284 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2285 }
2286
2287 /* Check if we should look for a .local file */
2288 if (ProcessParameters && !(ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH))
2289 {
2290 LdrpInitializeDotLocalSupport(ProcessParameters);
2291 }
2292
2293 /* Check if the Application Verifier was enabled */
2295 {
2297 if (!NT_SUCCESS(Status))
2298 {
2299 DPRINT1("LDR: AVrfInitializeVerifier failed (ntstatus 0x%x)\n", Status);
2300 return Status;
2301 }
2302
2303 }
2304
2305 if (IsDotNetImage)
2306 {
2307 /* FIXME */
2308 DPRINT1("We don't support .NET applications yet\n");
2309 }
2310
2313 {
2314 PVOID Kernel32BaseAddress;
2315 PVOID FunctionAddress;
2316
2317 Status = LdrLoadDll(NULL, NULL, &Kernel32String, &Kernel32BaseAddress);
2318
2319 if (!NT_SUCCESS(Status))
2320 {
2321 if (ShowSnaps)
2322 DPRINT1("LDR: Unable to load %wZ, Status=0x%08lx\n", &Kernel32String, Status);
2323 return Status;
2324 }
2325
2326 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2327 &BaseProcessInitPostImportName,
2328 0,
2329 &FunctionAddress);
2330
2331 if (!NT_SUCCESS(Status))
2332 {
2333 if (ShowSnaps)
2334 DPRINT1("LDR: Unable to find post-import process init function, Status=0x%08lx\n", Status);
2335 return Status;
2336 }
2337 Kernel32ProcessInitPostImportFunction = FunctionAddress;
2338
2339 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2340 &BaseQueryModuleDataName,
2341 0,
2342 &FunctionAddress);
2343
2344 if (!NT_SUCCESS(Status))
2345 {
2346 if (ShowSnaps)
2347 DPRINT1("LDR: Unable to find BaseQueryModuleData, Status=0x%08lx\n", Status);
2348 return Status;
2349 }
2350 Kernel32BaseQueryModuleData = FunctionAddress;
2351 }
2352
2353 /* Walk the IAT and load all the DLLs */
2355
2356 /* Check if relocation is needed */
2358 {
2359 DPRINT1("LDR: Performing EXE relocation\n");
2360
2361 /* Change the protection to prepare for relocation */
2362 ViewBase = Peb->ImageBaseAddress;
2363 Status = LdrpSetProtection(ViewBase, FALSE);
2364 if (!NT_SUCCESS(Status)) return Status;
2365
2366 /* Do the relocation */
2368 0LL,
2369 NULL,
2373 if (!NT_SUCCESS(Status))
2374 {
2375 DPRINT1("LdrRelocateImageWithBias() failed\n");
2376 return Status;
2377 }
2378
2379 /* Check if a start context was provided */
2380 if (Context)
2381 {
2382 DPRINT1("WARNING: Relocated EXE Context");
2383 UNIMPLEMENTED; // We should support this
2385 }
2386
2387 /* Restore the protection */
2388 Status = LdrpSetProtection(ViewBase, TRUE);
2389 if (!NT_SUCCESS(Status)) return Status;
2390 }
2391
2392 /* Lock the DLLs */
2393 ListHead = &Peb->Ldr->InLoadOrderModuleList;
2394 NextEntry = ListHead->Flink;
2395 while (ListHead != NextEntry)
2396 {
2397 NtLdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
2398 NtLdrEntry->LoadCount = -1;
2399 NextEntry = NextEntry->Flink;
2400 }
2401
2402 /* Phase 0 is done */
2404
2405 /* Check whether all static imports were properly loaded and return here */
2406 if (!NT_SUCCESS(ImportStatus)) return ImportStatus;
2407
2408#if (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
2409 /* Initialize the keyed event for condition variables */
2411#endif
2412
2413 /* Initialize TLS */
2415 if (!NT_SUCCESS(Status))
2416 {
2417 DPRINT1("LDR: LdrpProcessInitialization failed to initialize TLS slots; status %x\n",
2418 Status);
2419 return Status;
2420 }
2421
2422 /* FIXME Mark the DLL Ranges for Stack Traces later */
2423
2424 /* Notify the debugger now */
2425 if (Peb->BeingDebugged)
2426 {
2427 /* Break */
2428 DbgBreakPoint();
2429
2430 /* Update show snaps again */
2432 }
2433
2434 /* Validate the Image for MP Usage */
2436
2437 /* Check NX options and set them */
2438 if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSON)
2439 {
2440 ExecuteOptions = MEM_EXECUTE_OPTION_DISABLE |
2443 }
2444 else if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSOFF)
2445 {
2447 }
2450 &ExecuteOptions,
2451 sizeof(ExecuteOptions));
2452 if (!NT_SUCCESS(Status))
2453 {
2454 DPRINT1("LDR: Could not set process execute flags 0x%x; status %x\n",
2455 ExecuteOptions, Status);
2456 }
2457
2458 // FIXME: Should be done by Application Compatibility features,
2459 // by reading the registry, etc...
2460 // For now, this is the old code from ntdll!RtlGetVersion().
2461 RtlInitEmptyUnicodeString(&Peb->CSDVersion, NULL, 0);
2462 if (((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
2463 {
2464 WCHAR szCSDVersion[128];
2465 LONG i;
2466 USHORT Length = (USHORT)ARRAYSIZE(szCSDVersion) - 1;
2467 i = _snwprintf(szCSDVersion, Length,
2468 L"Service Pack %d",
2469 ((Peb->OSCSDVersion >> 8) & 0xFF));
2470 if (i < 0)
2471 {
2472 /* Null-terminate if it was overflowed */
2473 szCSDVersion[Length] = UNICODE_NULL;
2474 }
2475
2476 Length *= sizeof(WCHAR);
2477 Peb->CSDVersion.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
2478 0,
2479 Length + sizeof(UNICODE_NULL));
2480 if (Peb->CSDVersion.Buffer)
2481 {
2484
2486 szCSDVersion,
2489 }
2490 }
2491
2492 /* Check if we had Shim Data */
2493 if (OldShimData)
2494 {
2495 /* Load the Shim Engine */
2497 LdrpLoadShimEngine(OldShimData, &ImagePathName, OldShimData);
2498 }
2499 else
2500 {
2501 /* Check for Application Compatibility Goo */
2502 //LdrQueryApplicationCompatibilityGoo(hKey);
2503 DPRINT("Querying app compat hacks is missing!\n");
2504 }
2505
2506 /*
2507 * FIXME: Check for special images, SecuROM, SafeDisc and other NX-
2508 * incompatible images.
2509 */
2510
2511 /* Now call the Init Routines */
2513 if (!NT_SUCCESS(Status))
2514 {
2515 DPRINT1("LDR: LdrpProcessInitialization failed running initialization routines; status %x\n",
2516 Status);
2517 return Status;
2518 }
2519
2520 /* Notify Shim Engine */
2521 if (g_ShimsEnabled)
2522 {
2525 SE_InstallAfterInit(&ImagePathName, OldShimData);
2526 }
2527
2528 /* Check if we have a user-defined Post Process Routine */
2530 {
2531 /* Call it */
2533 }
2534
2535 /* Close the key if we have one opened */
2536 if (OptionsKey) NtClose(OptionsKey);
2537
2538 /* Return status */
2539 return Status;
2540}
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
struct _PEB_LDR_DATA PEB_LDR_DATA
#define RtlInitializeBitMap
Definition: dbgbitmap.h:326
#define RtlSetBit
Definition: dbgbitmap.h:344
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define 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
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define FLG_USER_STACK_TRACE_DB
Definition: pstypes.h:67
#define FLG_SHOW_LDR_SNAPS
Definition: pstypes.h:57
#define TLS_EXPANSION_SLOTS
Definition: pstypes.h:311
NTSYSAPI void WINAPI DbgBreakPoint(void)
@ ProcessAffinityMask
Definition: winternl.h:877
@ ProcessExecuteFlags
Definition: winternl.h:889
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(_In_opt_ PWSTR SearchPath, _In_opt_ PULONG DllCharacteristics, _In_ PUNICODE_STRING DllName, _Out_ PVOID *BaseAddress)
Definition: ldrapi.c:312
NTSTATUS NTAPI LdrGetProcedureAddress(_In_ PVOID BaseAddress, _In_opt_ _When_(Ordinal==0, _Notnull_) PANSI_STRING Name, _In_opt_ _When_(Name==NULL, _In_range_(>, 0)) ULONG Ordinal, _Out_ PVOID *ProcedureAddress)
Definition: ldrapi.c:789
PVOID NtDllBase
Definition: ldrinit.c:56
PLDR_DATA_TABLE_ENTRY LdrpImageEntry
Definition: ldrinit.c:39
VOID NTAPI LdrpInitializeDotLocalSupport(PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
Definition: ldrinit.c:1696
WCHAR LdrpKnownDllPathBuffer[128]
Definition: ldrinit.c:64
UNICODE_STRING LdrpDefaultPath
Definition: ldrinit.c:65
VOID NTAPI RtlpInitDeferredCriticalSection(VOID)
Definition: critical.c:272
NTSTATUS NTAPI LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PHANDLE OptionsKey)
Definition: ldrinit.c:1420
RTL_CRITICAL_SECTION FastPebLock
Definition: ldrinit.c:79
LIST_ENTRY LdrpDllNotificationList
Definition: ldrinit.c:61
ULONG LdrpNumberOfProcessors
Definition: ldrinit.c:55
PVOID LdrpHeap
Definition: ldrinit.c:59
RTL_BITMAP FlsBitMap
Definition: ldrinit.c:51
RTL_BITMAP TlsBitMap
Definition: ldrinit.c:49
BOOLEAN LdrpLoaderLockInit
Definition: ldrinit.c:32
LARGE_INTEGER RtlpTimeout
Definition: critical.c:25
VOID NTAPI RtlInitializeHeapManager(VOID)
Definition: libsupp.c:243
VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
Definition: ldrinit.c:1539
LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]
Definition: ldrinit.c:60
UNICODE_STRING LdrpKnownDllPath
Definition: ldrinit.c:63
RTL_BITMAP TlsExpansionBitMap
Definition: ldrinit.c:50
NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
Definition: ldrinit.c:641
BOOLEAN LdrpLdrDatabaseIsSetup
Definition: ldrinit.c:33
VOID NTAPI RtlpInitializeVectoredExceptionHandling(VOID)
Definition: vectoreh.c:30
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
HANDLE LdrpKnownDllObjectDirectory
Definition: ldrinit.c:62
PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry
Definition: ldrinit.c:44
NTSTATUS NTAPI LdrpInitializeTls(VOID)
Definition: ldrinit.c:1258
#define VALID_CONFIG_FIELD(Name)
UNICODE_STRING Kernel32String
Definition: ldrinit.c:27
BOOLEAN RtlpTimeoutDisable
Definition: critical.c:26
UNICODE_STRING NtDllString
Definition: ldrinit.c:26
NTSTATUS NTAPI RtlpInitializeActCtx(PVOID *pOldShimData)
BOOLEAN LdrpDllValidation
Definition: ldrinit.c:37
PEB_LDR_DATA PebLdr
Definition: ldrinit.c:67
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:44
#define LDRP_COR_IMAGE
Definition: ldrtypes.h:52
#define LDRP_IMAGE_DLL
Definition: ldrtypes.h:39
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
#define MEM_EXECUTE_OPTION_DISABLE
Definition: mmtypes.h:73
#define MEM_EXECUTE_OPTION_PERMANENT
Definition: mmtypes.h:76
#define MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
Definition: mmtypes.h:75
#define MEM_EXECUTE_OPTION_ENABLE
Definition: mmtypes.h:74
NTSYSAPI NTSTATUS NTAPI ZwOpenDirectoryObject(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSYSAPI VOID NTAPI RtlInitNlsTables(_In_ PUSHORT AnsiTableBase, _In_ PUSHORT OemTableBase, _In_ PUSHORT CaseTableBase, _Out_ PNLSTABLEINFO NlsTable)
NTSYSAPI VOID NTAPI RtlResetRtlTranslations(_In_ PNLSTABLEINFO NlsTable)
NTSYSAPI NTSTATUS NTAPI RtlSetCurrentDirectory_U(_In_ PUNICODE_STRING name)
ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID BaseAddress, _In_ LONGLONG AdditionalBias, _In_opt_ PCSTR LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
Definition: image.c:474
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
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
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PVOID g_pfnSE_InstallAfterInit
Definition: ldrutils.c:26
VOID NTAPI LdrpLoadShimEngine(IN PWSTR ImageName, IN PUNICODE_STRING ProcessImage, IN PVOID pShimData)
Definition: ldrutils.c:2752
ULONG RtlpDphGlobalFlags
Definition: heappage.c:108
NTSTATUS NTAPI LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrpe.c:670
NTSTATUS NTAPI AVrfInitializeVerifier(VOID)
Definition: verifier.c:612
#define LDR_HASH_TABLE_ENTRIES
Definition: ntdllp.h:11
VOID NTAPI LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrutils.c:1556
NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase, BOOLEAN Restore)
Definition: ldrutils.c:921
PVOID NTAPI LdrpFetchAddressOfEntryPoint(PVOID ImageBase)
BOOLEAN RtlpPageHeapEnabled
Definition: heappage.c:107
PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
Definition: ldrutils.c:1523
BOOLEAN g_ShimsEnabled
Definition: ldrutils.c:21
VOID NTAPI RtlpInitializeKeyedEvent(VOID)
Definition: condvar.c:460
#define IMAGE_SUBSYSTEM_WINDOWS_CUI
Definition: ntimage.h:438
#define IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: ntimage.h:437
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489
#define IMAGE_SUBSYSTEM_NATIVE
Definition: ntimage.h:436
UNICODE_STRING NtSystemRoot
Definition: init.c:76
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1105
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
static VOID LoadConfig(HWND hwndDlg, PPOWER_SCHEMES_PAGE_DATA pPageData, PPOWER_SCHEME pScheme)
Definition: powershemes.c:237
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
HANDLE UniqueProcess
Definition: compat.h:825
UNICODE_STRING DosPath
Definition: rtltypes.h:1368
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
Definition: btrfs_drv.h:1876
PACTIVATION_CONTEXT EntryPointActivationContext
Definition: ldrtypes.h:163
USHORT LoadCount
Definition: ntddk_ex.h:208
PVOID EntryPoint
Definition: ntddk_ex.h:203
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
LIST_ENTRY InInitializationOrderLinks
Definition: ldrtypes.h:140
PVOID DllBase
Definition: btrfs_drv.h:1880
ULONG Flags
Definition: ntddk_ex.h:207
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
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
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
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
#define LL
Definition: tui.h:167
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
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONGLONG QuadPart
Definition: typedefs.h:114
#define FLS_MAXIMUM_AVAILABLE
Definition: winnt_old.h:1099
#define NX_SUPPORT_POLICY_ALWAYSOFF
Definition: ketypes.h:1260
#define NX_SUPPORT_POLICY_ALWAYSON
Definition: ketypes.h:1261
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by LdrpInit().

◆ LdrpInitializeProcessCompat()

VOID NTAPI LdrpInitializeProcessCompat ( PVOID  pProcessActctx,
PVOID pOldShimData 
)

Definition at line 1580 of file ldrinit.c.

1581{
1582 static const struct
1583 {
1584 const GUID* Guid;
1585 const DWORD Version;
1586 } KnownCompatGuids[] = {
1587 { &COMPAT_GUID_WIN10, _WIN32_WINNT_WIN10 },
1588 { &COMPAT_GUID_WIN81, _WIN32_WINNT_WINBLUE },
1589 { &COMPAT_GUID_WIN8, _WIN32_WINNT_WIN8 },
1590 { &COMPAT_GUID_WIN7, _WIN32_WINNT_WIN7 },
1591 { &COMPAT_GUID_VISTA, _WIN32_WINNT_VISTA },
1592 };
1593
1594 ULONG Buffer[(sizeof(COMPATIBILITY_CONTEXT_ELEMENT) * 10 + sizeof(ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION)) / sizeof(ULONG)];
1595 ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION* ContextCompatInfo;
1596 SIZE_T SizeRequired;
1598 DWORD n, cur;
1599 ReactOS_ShimData* pShimData = *pOldShimData;
1600
1601 if (pShimData)
1602 {
1603 if (pShimData->dwMagic != REACTOS_SHIMDATA_MAGIC ||
1604 pShimData->dwSize != sizeof(ReactOS_ShimData))
1605 {
1606 DPRINT1("LdrpInitializeProcessCompat: Corrupt pShimData (0x%x, %u)\n", pShimData->dwMagic, pShimData->dwSize);
1607 return;
1608 }
1609 if (pShimData->dwRosProcessCompatVersion)
1610 {
1612 {
1613 DPRINT1("LdrpInitializeProcessCompat: ProcessCompatVersion set to ignore manifest\n");
1614 }
1615 else
1616 {
1617 DPRINT1("LdrpInitializeProcessCompat: ProcessCompatVersion already set to 0x%x\n", pShimData->dwRosProcessCompatVersion);
1618 }
1619 return;
1620 }
1621 }
1622
1623 SizeRequired = sizeof(Buffer);
1625 pProcessActctx,
1626 NULL,
1627 CompatibilityInformationInActivationContext,
1628 Buffer,
1629 sizeof(Buffer),
1630 &SizeRequired);
1631
1632 if (!NT_SUCCESS(Status))
1633 {
1634 DPRINT1("LdrpInitializeProcessCompat: Unable to query process actctx with status %x\n", Status);
1635 return;
1636 }
1637
1638 ContextCompatInfo = (ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION*)Buffer;
1639 /* No Compatibility elements present, bail out */
1640 if (ContextCompatInfo->ElementCount == 0)
1641 return;
1642
1643 /* Search for known GUIDs, starting from oldest to newest.
1644 Note that on Windows it is somewhat reversed, starting from the latest known
1645 version, going down. But we are not Windows, trying to allow a lower version,
1646 we are ReactOS trying to fake a higher version. So we interpret what Windows
1647 does as "try the closest version to the actual version", so we start with the
1648 lowest version, which is closest to Windows 2003, which we mostly are. */
1649 for (cur = RTL_NUMBER_OF(KnownCompatGuids) - 1; cur != -1; --cur)
1650 {
1651 for (n = 0; n < ContextCompatInfo->ElementCount; ++n)
1652 {
1653 if (ContextCompatInfo->Elements[n].Type == ACTCTX_COMPATIBILITY_ELEMENT_TYPE_OS &&
1654 RtlCompareMemory(&ContextCompatInfo->Elements[n].Id, KnownCompatGuids[cur].Guid, sizeof(GUID)) == sizeof(GUID))
1655 {
1657 {
1658 DPRINT1("LdrpInitializeProcessCompat: Not applying automatic fix for winver 0x%x due to policy\n", KnownCompatGuids[cur].Version);
1659 return;
1660 }
1661
1662 /* If this process did not need shim data before, allocate and store it */
1663 if (pShimData == NULL)
1664 {
1665 PPEB Peb = NtCurrentPeb();
1666
1667 ASSERT(Peb->pShimData == NULL);
1668 pShimData = RtlAllocateHeap(Peb->ProcessHeap, HEAP_ZERO_MEMORY, sizeof(*pShimData));
1669
1670 if (!pShimData)
1671 {
1672 DPRINT1("LdrpInitializeProcessCompat: Unable to allocated %u bytes\n", sizeof(*pShimData));
1673 return;
1674 }
1675
1676 pShimData->dwSize = sizeof(*pShimData);
1677 pShimData->dwMagic = REACTOS_SHIMDATA_MAGIC;
1678
1679 Peb->pShimData = pShimData;
1680 *pOldShimData = pShimData;
1681 }
1682
1683 /* Store the lowest found version, and bail out. */
1684 pShimData->dwRosProcessCompatVersion = KnownCompatGuids[cur].Version;
1685 DPRINT1("LdrpInitializeProcessCompat: Found guid for winver 0x%x in manifest from %wZ\n",
1686 KnownCompatGuids[cur].Version,
1687 &(NtCurrentPeb()->ProcessParameters->ImagePathName));
1688 return;
1689 }
1690 }
1691 }
1692}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
Definition: bufpool.h:45
#define REACTOS_SHIMDATA_MAGIC
Definition: compat_undoc.h:15
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
unsigned long DWORD
Definition: ntddk_ex.h:95
FxCollectionEntry * cur
GLdouble n
Definition: glext.h:7729
#define REACTOS_COMPATVERSION_IGNOREMANIFEST
Definition: hsdb.c:32
NTSYSAPI NTSTATUS WINAPI RtlQueryInformationActivationContext(ULONG, HANDLE, PVOID, ULONG, PVOID, SIZE_T, SIZE_T *)
Definition: actctx.c:5572
BOOLEAN NTAPI LdrpDisableProcessCompatGuidDetection(VOID)
Definition: ldrinit.c:1546
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_NO_ADDREF
Definition: rtltypes.h:119
#define _WIN32_WINNT_WIN10
Definition: sdkddkver.h:32
#define _WIN32_WINNT_WINBLUE
Definition: sdkddkver.h:30
#define _WIN32_WINNT_WIN8
Definition: sdkddkver.h:29
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
DWORD dwRosProcessCompatVersion
Definition: compat_undoc.h:11
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:762

◆ LdrpInitializeThread()

VOID NTAPI LdrpInitializeThread ( IN PCONTEXT  Context)

Definition at line 506 of file ldrinit.c.

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

Referenced by LdrpInit().

◆ LdrpInitializeTls()

NTSTATUS NTAPI LdrpInitializeTls ( VOID  )

Definition at line 1258 of file ldrinit.c.

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

Referenced by LdrpInitializeProcess().

◆ LdrpInitSecurityCookie()

PVOID NTAPI LdrpInitSecurityCookie ( PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 453 of file ldrinit.c.

454{
457 ULONG_PTR NewCookie;
458
459 /* Fetch address of the cookie */
461
462 if (Cookie)
463 {
464 /* Check if it's a default one */
466 (*Cookie == 0xBB40))
467 {
468 /* Make up a cookie from a bunch of values which may uniquely represent
469 current moment of time, environment, etc */
471
472 NewCookie = Counter.LowPart ^ Counter.HighPart;
473 NewCookie ^= (ULONG_PTR)NtCurrentTeb()->ClientId.UniqueProcess;
474 NewCookie ^= (ULONG_PTR)NtCurrentTeb()->ClientId.UniqueThread;
475
476 /* Loop like it's done in KeQueryTickCount(). We don't want to call it directly. */
477 while (SharedUserData->SystemTime.High1Time != SharedUserData->SystemTime.High2Time)
478 {
480 };
481
482 /* Calculate the milliseconds value and xor it to the cookie */
483 NewCookie ^= Int64ShrlMod32(UInt32x32To64(SharedUserData->TickCountMultiplier, SharedUserData->TickCount.LowPart), 24) +
484 (SharedUserData->TickCountMultiplier * (SharedUserData->TickCount.High1Time << 8));
485
486 /* Make the cookie 16bit if necessary */
487 if (*Cookie == 0xBB40) NewCookie &= 0xFFFF;
488
489 /* If the result is 0 or the same as we got, just subtract one from the existing value
490 and that's it */
491 if ((NewCookie == 0) || (NewCookie == *Cookie))
492 {
493 NewCookie = *Cookie - 1;
494 }
495
496 /* Set the new cookie value */
497 *Cookie = NewCookie;
498 }
499 }
500
501 return Cookie;
502}
#define UInt32x32To64(a, b)
Definition: intsafe.h:252
#define DEFAULT_SECURITY_COOKIE
Definition: ldrinit.c:102
PVOID NTAPI LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: ldrinit.c:416
#define Int64ShrlMod32(a, b)
NTSTATUS NTAPI NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter, OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
Definition: profile.c:272
#define YieldProcessor
Definition: ke.h:48
ULONG SizeOfImage
Definition: ldrtypes.h:143
static LARGE_INTEGER Counter
Definition: clock.c:43
ULONG LowPart
Definition: typedefs.h:106

Referenced by LdrpRunInitializeRoutines().

◆ LdrpRunInitializeRoutines()

NTSTATUS NTAPI LdrpRunInitializeRoutines ( IN PCONTEXT Context  OPTIONAL)

Definition at line 641 of file ldrinit.c.

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

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

◆ LdrpValidateImageForMp()

VOID NTAPI LdrpValidateImageForMp ( IN PLDR_DATA_TABLE_ENTRY  LdrDataTableEntry)

Definition at line 1539 of file ldrinit.c.

1540{
1542}

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

◆ LdrQueryImageFileExecutionOptions()

NTSTATUS NTAPI LdrQueryImageFileExecutionOptions ( _In_ PUNICODE_STRING  SubKey,
_In_ PCWSTR  ValueName,
_In_ ULONG  Type,
_Out_ PVOID  Buffer,
_In_ ULONG  BufferSize,
_Out_opt_ PULONG  ReturnedLength 
)

Definition at line 389 of file ldrinit.c.

396{
397 /* Call the newer function */
399 ValueName,
400 Type,
401 Buffer,
404 FALSE);
405}
Type
Definition: Type.h:7
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:188
NTSTATUS NTAPI LdrQueryImageFileExecutionOptionsEx(_In_ PUNICODE_STRING SubKey, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength, _In_ BOOLEAN Wow64)
Definition: ldrinit.c:350
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243

Referenced by LdrpRunInitializeRoutines(), and SmpLoadSubSystemsForMuSession().

◆ LdrQueryImageFileExecutionOptionsEx()

NTSTATUS NTAPI LdrQueryImageFileExecutionOptionsEx ( _In_ PUNICODE_STRING  SubKey,
_In_ PCWSTR  ValueName,
_In_ ULONG  Type,
_Out_ PVOID  Buffer,
_In_ ULONG  BufferSize,
_Out_opt_ PULONG  ReturnedLength,
_In_ BOOLEAN  Wow64 
)

Definition at line 350 of file ldrinit.c.

358{
361
362 /* Open a handle to the key */
364
365 /* Check for success */
366 if (NT_SUCCESS(Status))
367 {
368 /* Query the data */
370 ValueName,
371 Type,
372 Buffer,
375
376 /* Close the key */
378 }
379
380 /* Return to caller */
381 return Status;
382}

Referenced by LdrQueryImageFileExecutionOptions().

◆ LdrQueryImageFileKeyOption()

NTSTATUS NTAPI LdrQueryImageFileKeyOption ( _In_ HANDLE  KeyHandle,
_In_ PCWSTR  ValueName,
_In_ ULONG  Type,
_Out_ PVOID  Buffer,
_In_ ULONG  BufferSize,
_Out_opt_ PULONG  ReturnedLength 
)

Definition at line 185 of file ldrinit.c.

192{
193 ULONG KeyInfo[256];
194 UNICODE_STRING ValueNameString, IntegerString;
195 ULONG KeyInfoSize, ResultSize;
197 BOOLEAN FreeHeap = FALSE;
199
200 /* Build a string for the value name */
201 Status = RtlInitUnicodeStringEx(&ValueNameString, ValueName);
202 if (!NT_SUCCESS(Status)) return Status;
203
204 /* Query the value */
205 Status = ZwQueryValueKey(KeyHandle,
206 &ValueNameString,
208 KeyValueInformation,
209 sizeof(KeyInfo),
210 &ResultSize);
212 {
213 /* Our local buffer wasn't enough, allocate one */
214 KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
215 KeyValueInformation->DataLength;
216 KeyValueInformation = RtlAllocateHeap(RtlGetProcessHeap(),
217 0,
218 KeyInfoSize);
219 if (KeyValueInformation != NULL)
220 {
221 /* Try again */
222 Status = ZwQueryValueKey(KeyHandle,
223 &ValueNameString,
225 KeyValueInformation,
226 KeyInfoSize,
227 &ResultSize);
228 FreeHeap = TRUE;
229 }
230 else
231 {
232 /* Give up this time */
234 }
235 }
236
237 /* Check for success */
238 if (NT_SUCCESS(Status))
239 {
240 /* Handle binary data */
241 if (KeyValueInformation->Type == REG_BINARY)
242 {
243 /* Check validity */
244 if ((Buffer) && (KeyValueInformation->DataLength <= BufferSize))
245 {
246 /* Copy into buffer */
248 &KeyValueInformation->Data,
249 KeyValueInformation->DataLength);
250 }
251 else
252 {
254 }
255
256 /* Copy the result length */
257 if (ReturnedLength) *ReturnedLength = KeyValueInformation->DataLength;
258 }
259 else if (KeyValueInformation->Type == REG_DWORD)
260 {
261 /* Check for valid type */
262 if (KeyValueInformation->Type != Type)
263 {
264 /* Error */
266 }
267 else
268 {
269 /* Check validity */
270 if ((Buffer) &&
271 (BufferSize == sizeof(ULONG)) &&
272 (KeyValueInformation->DataLength <= BufferSize))
273 {
274 /* Copy into buffer */
276 &KeyValueInformation->Data,
277 KeyValueInformation->DataLength);
278 }
279 else
280 {
282 }
283
284 /* Copy the result length */
285 if (ReturnedLength) *ReturnedLength = KeyValueInformation->DataLength;
286 }
287 }
288 else if (KeyValueInformation->Type != REG_SZ)
289 {
290 /* We got something weird */
292 }
293 else
294 {
295 /* String, check what you requested */
296 if (Type == REG_DWORD)
297 {
298 /* Validate */
299 if (BufferSize != sizeof(ULONG))
300 {
301 /* Invalid size */
302 BufferSize = 0;
304 }
305 else
306 {
307 /* OK, we know what you want... */
308 IntegerString.Buffer = (PWSTR)KeyValueInformation->Data;
309 IntegerString.Length = (USHORT)KeyValueInformation->DataLength -
310 sizeof(WCHAR);
311 IntegerString.MaximumLength = (USHORT)KeyValueInformation->DataLength;
312 Status = RtlUnicodeStringToInteger(&IntegerString, 0, (PULONG)Buffer);
313 }
314 }
315 else
316 {
317 /* Validate */
318 if (KeyValueInformation->DataLength > BufferSize)
319 {
320 /* Invalid */
322 }
323 else
324 {
325 /* Set the size */
326 BufferSize = KeyValueInformation->DataLength;
327 }
328
329 /* Copy the string */
330 RtlMoveMemory(Buffer, &KeyValueInformation->Data, BufferSize);
331 }
332
333 /* Copy the result length */
334 if (ReturnedLength) *ReturnedLength = KeyValueInformation->DataLength;
335 }
336 }
337
338 /* Check if buffer was in heap */
339 if (FreeHeap) RtlFreeHeap(RtlGetProcessHeap(), 0, KeyValueInformation);
340
341 /* Return status */
342 return Status;
343}
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: d3dkmdt.h:46
NTSYSAPI NTSTATUS WINAPI RtlInitUnicodeStringEx(PUNICODE_STRING, PCWSTR)
#define REG_SZ
Definition: layer.c:22
#define REG_BINARY
Definition: nt_native.h:1496
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
uint32_t * PULONG
Definition: typedefs.h:59
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133

Referenced by AVrfReadIFEO(), CreateProcessInternalW(), LdrpInitializeExecutionOptions(), LdrpInitializeProcess(), and LdrQueryImageFileExecutionOptionsEx().

◆ LdrShutdownProcess()

NTSTATUS NTAPI LdrShutdownProcess ( VOID  )

Definition at line 943 of file ldrinit.c.

944{
946 PLDR_DATA_TABLE_ENTRY LdrEntry;
947 PLIST_ENTRY NextEntry, ListHead;
948 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
949 PVOID EntryPoint;
950
951 DPRINT("LdrShutdownProcess() called for %wZ\n", &LdrpImageEntry->BaseDllName);
953
954 /* Tell the Shim Engine */
955 if (g_ShimsEnabled)
956 {
960 }
961
962 /* Tell the world */
963 if (ShowSnaps)
964 {
965 DPRINT1("\n");
966 }
967
968 /* Set the shutdown variables */
969 LdrpShutdownThreadId = NtCurrentTeb()->RealClientId.UniqueThread;
971
972 /* Enter the Loader Lock */
974
975 /* Cleanup trace logging data (Etw) */
976 if (SharedUserData->TraceLogging)
977 {
978 /* FIXME */
979 DPRINT1("We don't support Etw yet.\n");
980 }
981
982 /* Start at the end */
984 NextEntry = ListHead->Blink;
985 while (NextEntry != ListHead)
986 {
987 /* Get the current entry */
988 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
989 NextEntry = NextEntry->Blink;
990
991 /* Make sure it's not ourselves */
992 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
993 {
994 /* Get the entrypoint */
995 EntryPoint = LdrEntry->EntryPoint;
996
997 /* Check if we are ready to call it */
998 if (EntryPoint &&
999 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
1000 LdrEntry->Flags)
1001 {
1002 /* Set up the Act Ctx */
1003 ActCtx.Size = sizeof(ActCtx);
1004 ActCtx.Format = 1;
1006
1007 /* Activate the ActCtx */
1008 RtlActivateActivationContextUnsafeFast(&ActCtx,
1009 LdrEntry->EntryPointActivationContext);
1010
1011 _SEH2_TRY
1012 {
1013 /* Check if it has TLS */
1014 if (LdrEntry->TlsIndex)
1015 {
1016 /* Call TLS */
1018 }
1019
1020 /* Call the Entrypoint */
1021 DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
1022 &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
1023 LdrpCallInitRoutine(EntryPoint,
1024 LdrEntry->DllBase,
1026 (PVOID)1);
1027 }
1029 {
1030 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_DETACH) for %wZ\n",
1031 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
1032 }
1033 _SEH2_END;
1034
1035 /* Deactivate the ActCtx */
1036 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1037 }
1038 }
1039 }
1040
1041 /* Check for TLS */
1042 if (LdrpImageHasTls)
1043 {
1044 /* Set up the Act Ctx */
1045 ActCtx.Size = sizeof(ActCtx);
1046 ActCtx.Format = 1;
1048
1049 /* Activate the ActCtx */
1050 RtlActivateActivationContextUnsafeFast(&ActCtx,
1052
1053 _SEH2_TRY
1054 {
1055 /* Do TLS callbacks */
1057 }
1059 {
1060 /* Do nothing */
1061 }
1062 _SEH2_END;
1063
1064 /* Deactivate the ActCtx */
1065 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1066 }
1067
1068 /* FIXME: Do Heap detection and Etw final shutdown */
1069
1070 /* Release the lock */
1072 DPRINT("LdrpShutdownProcess() done\n");
1073
1074 return STATUS_SUCCESS;
1075}
#define DLL_PROCESS_DETACH
Definition: compat.h:130
HANDLE LdrpShutdownThreadId
Definition: ldrinit.c:35
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
PVOID g_pfnSE_ProcessDying
Definition: ldrutils.c:27
VOID NTAPI SE_ProcessDying(VOID)
Definition: shimeng.c:1441
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122

Referenced by ExitProcess().

◆ LdrShutdownThread()

NTSTATUS NTAPI LdrShutdownThread ( VOID  )

Definition at line 1082 of file ldrinit.c.

1083{
1084 PPEB Peb = NtCurrentPeb();
1085 PTEB Teb = NtCurrentTeb();
1086 PLDR_DATA_TABLE_ENTRY LdrEntry;
1087 PLIST_ENTRY NextEntry, ListHead;
1088 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
1089 PVOID EntryPoint;
1090
1091 DPRINT("LdrShutdownThread() called for %wZ\n",
1093
1094 /* Cleanup trace logging data (Etw) */
1095 if (SharedUserData->TraceLogging)
1096 {
1097 /* FIXME */
1098 DPRINT1("We don't support Etw yet.\n");
1099 }
1100
1101 /* Get the Ldr Lock */
1103
1104 /* Start at the end */
1106 NextEntry = ListHead->Blink;
1107 while (NextEntry != ListHead)
1108 {
1109 /* Get the current entry */
1110 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1111 NextEntry = NextEntry->Blink;
1112
1113 /* Make sure it's not ourselves */
1114 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
1115 {
1116 /* Check if we should call */
1117 if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS) &&
1118 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
1119 (LdrEntry->Flags & LDRP_IMAGE_DLL))
1120 {
1121 /* Get the entrypoint */
1122 EntryPoint = LdrEntry->EntryPoint;
1123
1124 /* Check if we are ready to call it */
1125 if (EntryPoint)
1126 {
1127 /* Set up the Act Ctx */
1128 ActCtx.Size = sizeof(ActCtx);
1129 ActCtx.Format = 1;
1131
1132 /* Activate the ActCtx */
1133 RtlActivateActivationContextUnsafeFast(&ActCtx,
1134 LdrEntry->EntryPointActivationContext);
1135
1136 _SEH2_TRY
1137 {
1138 /* Check if it has TLS */
1139 if (LdrEntry->TlsIndex)
1140 {
1141 /* Make sure we're not shutting down */
1143 {
1144 /* Call TLS */
1146 }
1147 }
1148
1149 /* Make sure we're not shutting down */
1151 {
1152 /* Call the Entrypoint */
1153 DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
1154 &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
1155 LdrpCallInitRoutine(EntryPoint,
1156 LdrEntry->DllBase,
1158 NULL);
1159 }
1160 }
1162 {
1163 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_DETACH) for %wZ\n",
1164 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
1165 }
1166 _SEH2_END;
1167
1168 /* Deactivate the ActCtx */
1169 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1170 }
1171 }
1172 }
1173 }
1174
1175 /* Check for TLS */
1176 if (LdrpImageHasTls)
1177 {
1178 /* Set up the Act Ctx */
1179 ActCtx.Size = sizeof(ActCtx);
1180 ActCtx.Format = 1;
1182
1183 /* Activate the ActCtx */
1184 RtlActivateActivationContextUnsafeFast(&ActCtx,
1186
1187 _SEH2_TRY
1188 {
1189 /* Do TLS callbacks */
1191 }
1193 {
1194 /* Do nothing */
1195 }
1196 _SEH2_END;
1197
1198 /* Deactivate the ActCtx */
1199 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1200 }
1201
1202 /* Free TLS */
1203 LdrpFreeTls();
1205
1206 /* Check for expansion slots */
1207 if (Teb->TlsExpansionSlots)
1208 {
1209 /* Free expansion slots */
1210 RtlFreeHeap(RtlGetProcessHeap(), 0, Teb->TlsExpansionSlots);
1211 }
1212
1213 /* Check for FLS Data */
1214 if (Teb->FlsData)
1215 {
1216 /* Mimic BaseRundownFls */
1217 ULONG n, FlsHighIndex;
1218 PRTL_FLS_DATA pFlsData;
1219 PFLS_CALLBACK_FUNCTION lpCallback;
1220
1221 pFlsData = Teb->FlsData;
1222
1224 FlsHighIndex = NtCurrentPeb()->FlsHighIndex;
1225 RemoveEntryList(&pFlsData->ListEntry);
1227
1228 for (n = 1; n <= FlsHighIndex; ++n)
1229 {
1230 lpCallback = NtCurrentPeb()->FlsCallback[n];
1231 if (lpCallback && pFlsData->Data[n])
1232 {
1233 lpCallback(pFlsData->Data[n]);
1234 }
1235 }
1236
1237 RtlFreeHeap(RtlGetProcessHeap(), 0, pFlsData);
1238 Teb->FlsData = NULL;
1239 }
1240
1241 /* Check for Fiber data */
1242 if (Teb->HasFiberData)
1243 {
1244 /* Free Fiber data*/
1245 RtlFreeHeap(RtlGetProcessHeap(), 0, Teb->NtTib.FiberData);
1246 Teb->NtTib.FiberData = NULL;
1247 }
1248
1249 /* Free the activation context stack */
1251 DPRINT("LdrShutdownThread() done\n");
1252
1253 return STATUS_SUCCESS;
1254}
#define DLL_THREAD_DETACH
Definition: compat.h:133
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
NTSYSAPI void WINAPI RtlReleasePebLock(void)
Definition: libsupp.c:84
NTSYSAPI void WINAPI RtlAcquirePebLock(void)
Definition: libsupp.c:74
NTSYSAPI void WINAPI RtlFreeThreadActivationContextStack(void)
Definition: actctx.c:5515
VOID NTAPI LdrpFreeTls(VOID)
Definition: ldrinit.c:1384
PVOID FiberData
Definition: compat.h:716
LIST_ENTRY ListEntry
Definition: rtltypes.h:1223
PVOID Data[RTL_FLS_MAXIMUM_AVAILABLE]
Definition: rtltypes.h:1224
PVOID * TlsExpansionSlots
Definition: compat.h:894
VOID(WINAPI * PFLS_CALLBACK_FUNCTION)(PVOID)
Definition: winbase.h:1469

◆ NTSTATUS()

static NTSTATUS ( WINAPI Kernel32ProcessInitPostImportFunction)
static

◆ RtlInitializeHeapManager()

VOID NTAPI RtlInitializeHeapManager ( VOID  )

Definition at line 243 of file libsupp.c.

244{
245}

Referenced by LdrpInitializeProcess().

◆ RtlpInitDeferredCriticalSection()

VOID NTAPI RtlpInitDeferredCriticalSection ( VOID  )

Definition at line 272 of file critical.c.

273{
274 /* Initialize the CS Protecting the List */
276
277 /* It's now safe to enter it */
279}
NTSTATUS NTAPI RtlInitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:545
static BOOLEAN RtlpCritSectInitialized
Definition: critical.c:21
static RTL_CRITICAL_SECTION RtlCriticalSectionLock
Definition: critical.c:19

Referenced by LdrpInitializeProcess().

◆ RtlpInitializeActCtx()

NTSTATUS NTAPI RtlpInitializeActCtx ( PVOID pOldShimData)

Referenced by LdrpInitializeProcess().

◆ RtlpInitializeVectoredExceptionHandling()

VOID NTAPI RtlpInitializeVectoredExceptionHandling ( VOID  )

Definition at line 30 of file vectoreh.c.

31{
32 /* Initialize our two lists and the common lock */
36}
LIST_ENTRY RtlpVectoredContinueList
Definition: vectoreh.c:17
RTL_CRITICAL_SECTION RtlpVectoredHandlerLock
Definition: vectoreh.c:16
LIST_ENTRY RtlpVectoredExceptionList
Definition: vectoreh.c:17

Referenced by LdrpInitializeProcess().

Variable Documentation

◆ FastPebLock

RTL_CRITICAL_SECTION FastPebLock

Definition at line 79 of file ldrinit.c.

Referenced by FlsCallback3(), LdrpInitializeProcess(), and START_TEST().

◆ FlsBitMap

RTL_BITMAP FlsBitMap

Definition at line 51 of file ldrinit.c.

Referenced by LdrpInitializeProcess().

◆ ImageExecOptionsKey

HANDLE ImageExecOptionsKey

Definition at line 22 of file ldrinit.c.

Referenced by LdrOpenImageFileOptionsKey().

◆ ImageExecOptionsString

UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options")

Definition at line 24 of file ldrinit.c.

Referenced by DisplayImageInfo(), LdrOpenImageFileOptionsKey(), and ModifyStatus().

◆ Kernel32String

UNICODE_STRING Kernel32String = RTL_CONSTANT_STRING(L"kernel32.dll")

Definition at line 27 of file ldrinit.c.

Referenced by LdrpInitializeProcess().

◆ LdrpActiveUnloadCount

ULONG LdrpActiveUnloadCount

Definition at line 84 of file ldrinit.c.

Referenced by LdrUnloadDll().

◆ LdrpCurrentDllInitializer

PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer

Definition at line 43 of file ldrinit.c.

Referenced by LdrLoadDll(), and LdrpRunInitializeRoutines().

◆ LdrpDefaultPath

◆ LdrpDllNotificationList

LIST_ENTRY LdrpDllNotificationList

Definition at line 61 of file ldrinit.c.

Referenced by LdrpInitializeProcess().

◆ LdrpDllValidation

BOOLEAN LdrpDllValidation

Definition at line 37 of file ldrinit.c.

Referenced by LdrpInitializeProcess().

◆ LdrpDotLocal

const UNICODE_STRING LdrpDotLocal = RTL_CONSTANT_STRING(L".Local")

Definition at line 28 of file ldrinit.c.

Referenced by LdrpInitializeDotLocalSupport().

◆ LdrpFatalHardErrorCount

ULONG LdrpFatalHardErrorCount

Definition at line 83 of file ldrinit.c.

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

◆ LdrpHashTable

◆ LdrpHeap

◆ LdrpImageEntry

◆ LdrpImageHasTls

◆ LdrpInLdrInit

◆ LdrpKnownDllObjectDirectory

HANDLE LdrpKnownDllObjectDirectory

Definition at line 62 of file ldrinit.c.

Referenced by LdrpCheckForKnownDll(), LdrpInitializeProcess(), and LdrpMapDll().

◆ LdrpKnownDllPath

UNICODE_STRING LdrpKnownDllPath

Definition at line 63 of file ldrinit.c.

Referenced by LdrpCheckForKnownDll(), and LdrpInitializeProcess().

◆ LdrpKnownDllPathBuffer

WCHAR LdrpKnownDllPathBuffer[128]

Definition at line 64 of file ldrinit.c.

Referenced by LdrpInitializeProcess().

◆ LdrpLdrDatabaseIsSetup

BOOLEAN LdrpLdrDatabaseIsSetup

Definition at line 33 of file ldrinit.c.

Referenced by LdrpInitializeProcess(), and LdrpLoadDll().

◆ LdrpLoaderLock

RTL_CRITICAL_SECTION LdrpLoaderLock
Initial value:
=
{
-1,
0,
0,
0,
0
}
RTL_CRITICAL_SECTION_DEBUG LdrpLoaderLockDebug
Definition: ldrinit.c:69

Definition at line 70 of file ldrinit.c.

Referenced by LdrLockLoaderLock(), LdrpGetProcedureAddress(), LdrpInit(), LdrpInitializeProcess(), LdrpLoadDll(), LdrShutdownProcess(), LdrShutdownThread(), and LdrUnlockLoaderLock().

◆ LdrpLoaderLockDebug

RTL_CRITICAL_SECTION_DEBUG LdrpLoaderLockDebug

Definition at line 69 of file ldrinit.c.

◆ LdrpLoaderLockInit

BOOLEAN LdrpLoaderLockInit

Definition at line 32 of file ldrinit.c.

Referenced by LdrpInitializeProcess().

◆ LdrpNtDllDataTableEntry

PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry

Definition at line 44 of file ldrinit.c.

Referenced by LdrpInitializeProcess().

◆ LdrpNumberOfProcessors

ULONG LdrpNumberOfProcessors

Definition at line 55 of file ldrinit.c.

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

◆ LdrpNumberOfTlsEntries

ULONG LdrpNumberOfTlsEntries

Definition at line 54 of file ldrinit.c.

Referenced by LdrpAllocateTls(), and LdrpInitializeTls().

◆ LdrpProcessInitialized

LONG LdrpProcessInitialized

Definition at line 31 of file ldrinit.c.

Referenced by LdrpInit().

◆ LdrpShutdownInProgress

BOOLEAN LdrpShutdownInProgress

Definition at line 34 of file ldrinit.c.

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

◆ LdrpShutdownThreadId

HANDLE LdrpShutdownThreadId

Definition at line 35 of file ldrinit.c.

Referenced by LdrShutdownProcess().

◆ LdrpTlsList

LIST_ENTRY LdrpTlsList

Definition at line 53 of file ldrinit.c.

Referenced by LdrpAllocateTls(), LdrpFreeTls(), and LdrpInitializeTls().

◆ LdrpTopLevelDllBeingLoaded

PUNICODE_STRING LdrpTopLevelDllBeingLoaded

Definition at line 40 of file ldrinit.c.

Referenced by LdrLoadDll().

◆ LdrpTopLevelDllBeingLoadedTeb

PTEB LdrpTopLevelDllBeingLoadedTeb
extern

Definition at line 20 of file libsupp.c.

Referenced by LdrpRunInitializeRoutines(), and RtlIsThreadWithinLoaderCallout().

◆ NtDllBase

PVOID NtDllBase

Definition at line 56 of file ldrinit.c.

Referenced by LdrpInitializeProcess().

◆ NtDllString

UNICODE_STRING NtDllString = RTL_CONSTANT_STRING(L"ntdll.dll")

Definition at line 26 of file ldrinit.c.

Referenced by LdrpInitializeProcess().

◆ PebLdr

PEB_LDR_DATA PebLdr

Definition at line 67 of file ldrinit.c.

Referenced by KiPrepareUserDebugData(), and LdrpInitializeProcess().

◆ RtlpDisableHeapLookaside

ULONG RtlpDisableHeapLookaside

Definition at line 92 of file ldrinit.c.

Referenced by LdrpInitializeExecutionOptions().

◆ RtlpShutdownProcessFlags

ULONG RtlpShutdownProcessFlags

Definition at line 93 of file ldrinit.c.

Referenced by LdrpInitializeExecutionOptions().

◆ RtlpTimeout

LARGE_INTEGER RtlpTimeout
extern

◆ RtlpTimeoutDisable

BOOLEAN RtlpTimeoutDisable
extern

Definition at line 26 of file critical.c.

Referenced by LdrpInitializeProcess(), and RtlpWaitForCriticalSection().

◆ RtlpUse16ByteSLists

BOOLEAN RtlpUse16ByteSLists
extern

◆ ShowSnaps

◆ StringBuffer

◆ TlsBitMap

RTL_BITMAP TlsBitMap

Definition at line 49 of file ldrinit.c.

Referenced by LdrpInitializeProcess().

◆ TlsExpansionBitMap

RTL_BITMAP TlsExpansionBitMap

Definition at line 50 of file ldrinit.c.

Referenced by LdrpInitializeProcess().

◆ Unk1

PVOID Unk1

Definition at line 47 of file ldrinit.c.

◆ Unk2

PVOID PVOID Unk2

Definition at line 47 of file ldrinit.c.

◆ Unk3

Definition at line 47 of file ldrinit.c.

◆ Unk4

Definition at line 47 of file ldrinit.c.

◆ Wow64ExecOptionsKey

HANDLE Wow64ExecOptionsKey

Definition at line 23 of file ldrinit.c.

Referenced by LdrOpenImageFileOptionsKey().

◆ Wow64OptionsString

UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L"")

Definition at line 25 of file ldrinit.c.

Referenced by LdrOpenImageFileOptionsKey().