/*++ Copyright (c) 1989 Microsoft Corporation Module Name: ldrp.h Abstract: Private types... for executive portion of loader Author: Mark Lucovsky (markl) 26-Mar-1990 Revision History: --*/ #ifndef _LDRP_ #define _LDRP_ #include #include #include #include #define NOEXTAPI #include "wdbgexts.h" #include #include #if defined(_WIN64) extern INVERTED_FUNCTION_TABLE LdrpInvertedFunctionTable; #endif #if DBG #define LdrpShouldDbgPrintStatus(st) \ (!NT_SUCCESS(st) \ && (ShowSnaps \ || ( (st) != STATUS_NO_SUCH_FILE \ && (st) != STATUS_DLL_NOT_FOUND \ && (st) != STATUS_OBJECT_NAME_NOT_FOUND \ ))) #else #define LdrpShouldDbgPrintStatus(st) (FALSE) #endif #if DBG #define LDR_ERROR_DPFLTR DPFLTR_ERROR_LEVEL #else #define LDR_ERROR_DPFLTR ((ShowSnaps || ShowErrors) ? DPFLTR_ERROR_LEVEL : DPFLTR_INFO_LEVEL) #endif // DBG extern BOOLEAN LdrpImageHasTls; extern UNICODE_STRING LdrpDefaultPath; HANDLE LdrpKnownDllObjectDirectory; #define LDRP_MAX_KNOWN_PATH 128 WCHAR LdrpKnownDllPathBuffer[LDRP_MAX_KNOWN_PATH]; UNICODE_STRING LdrpKnownDllPath; extern PLDR_MANIFEST_PROBER_ROUTINE LdrpManifestProberRoutine; extern PLDR_APP_COMPAT_DLL_REDIRECTION_CALLBACK_FUNCTION LdrpAppCompatDllRedirectionCallbackFunction; extern PVOID LdrpAppCompatDllRedirectionCallbackData; extern PVOID LdrpHeap; extern RTL_CRITICAL_SECTION LdrpLoaderLock; extern PCUNICODE_STRING LdrpTopLevelDllBeingLoaded; extern PTEB LdrpTopLevelDllBeingLoadedTeb; extern BOOLEAN LdrpBreakOnExceptions; extern PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry; extern PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer; extern BOOLEAN LdrpShowInitRoutines; extern BOOLEAN LdrpShowRecursiveDllLoads; extern BOOLEAN LdrpBreakOnRecursiveDllLoads; extern BOOLEAN LdrpLoaderLockAcquisionCount; #define ASCII_CHAR_IS_N(_ch) (((_ch) == 'n') || ((_ch) == 'N')) #define ASCII_CHAR_IS_T(_ch) (((_ch) == 't') || ((_ch) == 'T')) #define ASCII_CHAR_IS_D(_ch) (((_ch) == 'd') || ((_ch) == 'D')) #define ASCII_CHAR_IS_L(_ch) (((_ch) == 'l') || ((_ch) == 'L')) #define ASCII_CHAR_IS_DOT(_ch) ((_ch) == '.') #define ASCII_STRING_IS_NTDLL(_p) \ ((_p) != NULL) && \ (((_p)->Length == (5 * sizeof(CHAR))) && \ (ASCII_CHAR_IS_N((_p)->Buffer[0]) && \ ASCII_CHAR_IS_T((_p)->Buffer[1]) && \ ASCII_CHAR_IS_D((_p)->Buffer[2]) && \ ASCII_CHAR_IS_L((_p)->Buffer[3]) && \ ASCII_CHAR_IS_L((_p)->Buffer[4])) || \ ((_p)->Length == ((5 + 1 + 3) * sizeof(CHAR))) && \ (ASCII_CHAR_IS_N((_p)->Buffer[0]) && \ ASCII_CHAR_IS_T((_p)->Buffer[1]) && \ ASCII_CHAR_IS_D((_p)->Buffer[2]) && \ ASCII_CHAR_IS_L((_p)->Buffer[3]) && \ ASCII_CHAR_IS_L((_p)->Buffer[4]) && \ ASCII_CHAR_IS_DOT((_p)->Buffer[5]) && \ ASCII_CHAR_IS_D((_p)->Buffer[6]) && \ ASCII_CHAR_IS_L((_p)->Buffer[7]) && \ ASCII_CHAR_IS_L((_p)->Buffer[8]))) // // + 1 is to preserve that code was using 266 // after explaining why it should be 265. Note // that sizeof("") includes a nul. // DOS_MAX_PATH_LENGTH is 260 (Win32 MAX_PATH) // LDR_MAX_PATH is 266 // We will be removing path length limits in the // ldr in the future. // // a-JayK August 2000 // #define LDR_MAX_PATH (DOS_MAX_PATH_LENGTH + sizeof("\\??\\") + 1) LIST_ENTRY RtlpCalloutEntryList; #if defined(_AMD64_) || defined(_IA64_) extern LIST_ENTRY RtlpDynamicFunctionTable; #endif RTL_CRITICAL_SECTION RtlpCalloutEntryLock; typedef struct _LDRP_DLL_NOTIFICATION_BLOCK { LIST_ENTRY Links; PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction; PVOID Context; } LDRP_DLL_NOTIFICATION_BLOCK, *PLDRP_DLL_NOTIFICATION_BLOCK; // // Synchronized via LdrpLoaderLock // LIST_ENTRY LdrpDllNotificationList; #define LDR_NUMBER_OF(x) (sizeof(x) / sizeof((x)[0])) #if defined (BUILD_WOW6432) NTSTATUS LdrpWx86FormatVirtualImage( IN PUNICODE_STRING DosImagePathName OPTIONAL, IN PIMAGE_NT_HEADERS32 NtHeaders, IN PVOID DllBase ); NTSTATUS Wx86SetRelocatedSharedProtection ( IN PVOID Base, IN BOOLEAN Reset ); ULONG LdrpWx86RelocatedFixupDiff( IN PUCHAR ImageBase, IN PIMAGE_NT_HEADERS NtHeaders, IN ULONG Offset ); BOOLEAN LdrpWx86DllHasRelocatedSharedSection( IN PUCHAR ImageBase); #define NATIVE_PAGE_SIZE 0x2000 #define NATIVE_PAGE_SHIFT 13L #define NATIVE_BYTES_TO_PAGES(Size) ((ULONG)((ULONG_PTR)(Size) >> NATIVE_PAGE_SHIFT) + \ (((ULONG)(Size) & (NATIVE_PAGE_SIZE - 1)) != 0)) #else #define NATIVE_PAGE_SIZE PAGE_SIZE #define NATIVE_PAGE_SHIFT PAGE_SHIFT #define NATIVE_BYTES_TO_PAGES(Size) BYTES_TO_PAGES(Size) #endif VOID RtlpWaitForCriticalSection ( IN PRTL_CRITICAL_SECTION CriticalSection ); VOID RtlpUnWaitCriticalSection ( IN PRTL_CRITICAL_SECTION CriticalSection ); #define LDRP_HASH_TABLE_SIZE 32 #define LDRP_HASH_MASK (LDRP_HASH_TABLE_SIZE-1) #define LDRP_COMPUTE_HASH_INDEX(wch) ( (RtlUpcaseUnicodeChar((wch)) - (WCHAR)'A') & LDRP_HASH_MASK ) LIST_ENTRY LdrpHashTable[LDRP_HASH_TABLE_SIZE]; // LDRP_BAD_DLL Sundown: sign-extended value. #define LDRP_BAD_DLL LongToPtr(0xffbadd11) LIST_ENTRY LdrpDefaultPathCache; typedef struct _LDRP_PATH_CACHE { LIST_ENTRY Links; UNICODE_STRING Component; HANDLE Directory; } LDRP_PATH_CACHE, *PLDRP_PATH_CACHE; NTSTATUS LdrpSnapIAT( IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry_Export, IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry_Import, IN PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, IN BOOLEAN SnapForwardersOnly ); NTSTATUS LdrpSnapThunk( IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA OriginalThunk, IN OUT PIMAGE_THUNK_DATA Thunk, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN StaticSnap, IN PSZ DllName OPTIONAL ); USHORT LdrpNameToOrdinal( IN PSZ Name, IN ULONG NumberOfNames, IN PVOID DllBase, IN PULONG NameTableBase, IN PUSHORT NameOrdinalTableBase ); PLDR_DATA_TABLE_ENTRY LdrpAllocateDataTableEntry( IN PVOID DllBase ); VOID LdrpDeallocateDataTableEntry( IN PLDR_DATA_TABLE_ENTRY Entry ); VOID LdrpFinalizeAndDeallocateDataTableEntry( IN PLDR_DATA_TABLE_ENTRY Entry ); BOOLEAN LdrpCheckForLoadedDll( IN PWSTR DllPath OPTIONAL, IN PUNICODE_STRING DllName, IN BOOLEAN StaticLink, IN BOOLEAN Redirected, OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry ); BOOLEAN LdrpCheckForLoadedDllHandle( IN PVOID DllHandle, OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry ); NTSTATUS LdrpMapDll( IN PWSTR DllPath OPTIONAL, IN PWSTR DllName, IN PULONG DllCharacteristics OPTIONAL, IN BOOLEAN StaticLink, IN BOOLEAN Redirected, OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry ); NTSTATUS LdrpWalkImportDescriptor( IN PWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry ); NTSTATUS LdrpRunInitializeRoutines( IN PCONTEXT Context OPTIONAL ); int LdrpInitializeProcessWrapperFilter( IN const struct _EXCEPTION_POINTERS *ExceptionPointers ); int LdrpGenericExceptionFilter( IN const struct _EXCEPTION_POINTERS *ExceptionPointers, IN PCSTR FunctionName ); // // These functions are VOID because they should really never be able to fail. // // In the current implementation, they do perform ANSI -> UNICODE conversions // which may fail in the current code page (may have been changed since when // the DLL was loaded) and apply Fusion DLL redirection to DLLs which can // require a large filename buffer than is allocated on the stack. // // These cases are ignored for now. Both problems should be fixed by // reworking the LDR_DATA_TABLE_ENTRY to have an array of pointers to the // downstream LDR_DATA_TABLE_ENTRY structs and not have to do any work // later on, but that's a lot of work for now; the ANSI -> UNICODE thing // has been there for ages and in practice, the paths that Fusion // redirects to have to fix in DOS_MAX_PATH_LENGTH, so we'll emit some // debug spew in the failure case, but ignore the failures. // // I started both fixes (returning status or allocating the array // at dll load time) but neither are trivial. Returning a status will just // make FreeLibrary() fail and leave the refcounts of the DLLs after the // one that failed inconsistent. Allocating the array is nontrivial // to do it the right way where the LDR_DATA_TABLE_ENTRY and the array // are allocated in a single allocation, and having the loader make more // even heap allocations seems like the wrong thing to do. // // -mgrier 11/20/2000 // /* VOID LdrpReferenceLoadedDll( IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry ); VOID LdrpDereferenceLoadedDll( IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry ); VOID LdrpPinLoadedDll( IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry ); */ #define LdrpReferenceLoadedDll(LdrDataTableEntry) LdrpUpdateLoadCount2(LdrDataTableEntry, LDRP_UPDATE_LOAD_COUNT_INCREMENT) #define LdrpDereferenceLoadedDll(LdrDataTableEntry) LdrpUpdateLoadCount2(LdrDataTableEntry, LDRP_UPDATE_LOAD_COUNT_DECREMENT) #define LdrpPinLoadedDll(LdrDataTableEntry) LdrpUpdateLoadCount2(LdrDataTableEntry, LDRP_UPDATE_LOAD_COUNT_PIN) #define LDRP_UPDATE_LOAD_COUNT_INCREMENT (1) #define LDRP_UPDATE_LOAD_COUNT_DECREMENT (2) #define LDRP_UPDATE_LOAD_COUNT_PIN (3) VOID LdrpUpdateLoadCount3( IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry, IN ULONG UpdateCountHow, IN OUT PUNICODE_STRING PreAllocatedRedirectionBuffer OPTIONAL ); VOID LdrpUpdateLoadCount2( IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry, IN ULONG UpdateCountHow ); NTSTATUS LdrpInitializeProcess( IN PCONTEXT Context OPTIONAL, IN PVOID SystemDllBase, IN PUNICODE_STRING UnicodeImageName, IN BOOLEAN UseCOR, IN BOOLEAN ImageFileOptionsPresent ); VOID LdrpInitialize( IN PCONTEXT Context, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ); VOID LdrpInsertMemoryTableEntry( IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry ); NTSTATUS LdrpResolveDllName( IN PWSTR DllPath OPTIONAL, IN PWSTR DllName, IN BOOLEAN Redirected, OUT PUNICODE_STRING FullDllName, OUT PUNICODE_STRING BaseDllName, OUT PHANDLE DllFile ); NTSTATUS LdrpResolveDllNameForAppPrivateRedirection( IN PCUNICODE_STRING DllName, OUT PUNICODE_STRING FullDllName ); NTSTATUS LdrpCreateDllSection( IN PUNICODE_STRING FullDllName, IN HANDLE DllFile, IN PUNICODE_STRING BaseName, IN PULONG DllCharacteristics OPTIONAL, OUT PHANDLE SectionHandle ); VOID LdrpInitializePathCache( VOID ); PVOID LdrpFetchAddressOfEntryPoint( IN PVOID Base ); NTSTATUS LdrpCheckForKnownDll( IN PWSTR DllName, OUT PUNICODE_STRING FullDllName, OUT PUNICODE_STRING BaseDllName, OUT HANDLE *Section ); NTSTATUS LdrpSetProtection( IN PVOID Base, IN BOOLEAN Reset, IN BOOLEAN StaticLink ); #if DBG ULONG LdrpCompareCount; ULONG LdrpSnapBypass; ULONG LdrpNormalSnap; ULONG LdrpSectionOpens; ULONG LdrpSectionCreates; ULONG LdrpSectionMaps; ULONG LdrpSectionRelocates; BOOLEAN LdrpDisplayLoadTime; LARGE_INTEGER BeginTime, InitcTime, InitbTime, IniteTime, EndTime, ElapsedTime, Interval; #endif // DBG extern BOOLEAN ShowSnaps; extern BOOLEAN ShowErrors; BOOLEAN RtlpTimoutDisable; LARGE_INTEGER RtlpTimeout; ULONG NtGlobalFlag; LIST_ENTRY RtlCriticalSectionList; RTL_CRITICAL_SECTION RtlCriticalSectionLock; BOOLEAN LdrpShutdownInProgress; extern BOOLEAN LdrpInLdrInit; extern BOOLEAN LdrpLdrDatabaseIsSetup; extern BOOLEAN LdrpVerifyDlls; extern BOOLEAN LdrpShutdownInProgress; extern BOOLEAN LdrpImageHasTls; extern BOOLEAN LdrpVerifyDlls; PLDR_DATA_TABLE_ENTRY LdrpImageEntry; LIST_ENTRY LdrpUnloadHead; BOOLEAN LdrpActiveUnloadCount; PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache; PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache; ULONG LdrpFatalHardErrorCount; UNICODE_STRING LdrpDefaultPath; RTL_CRITICAL_SECTION FastPebLock; HANDLE LdrpShutdownThreadId; PLDR_DATA_TABLE_ENTRY LdrpImageEntry; ULONG LdrpNumberOfProcessors; extern UNICODE_STRING DefaultExtension; extern UNICODE_STRING User32String; extern UNICODE_STRING Kernel32String; typedef struct _LDRP_TLS_ENTRY { LIST_ENTRY Links; IMAGE_TLS_DIRECTORY Tls; } LDRP_TLS_ENTRY, *PLDRP_TLS_ENTRY; LIST_ENTRY LdrpTlsList; ULONG LdrpNumberOfTlsEntries; NTSTATUS LdrpInitializeTls( VOID ); NTSTATUS LdrpAllocateTls( VOID ); VOID LdrpFreeTls( VOID ); VOID LdrpCallTlsInitializers( PVOID DllBase, ULONG Reason ); NTSTATUS LdrpAllocateUnicodeString( OUT PUNICODE_STRING StringOut, IN USHORT Length ); NTSTATUS LdrpCopyUnicodeString( OUT PUNICODE_STRING StringOut, IN PCUNICODE_STRING StringIn ); VOID LdrpFreeUnicodeString( IN OUT PUNICODE_STRING String ); VOID LdrpEnsureLoaderLockIsHeld( VOID ); #define LDRP_LOAD_DLL_FLAG_DLL_IS_REDIRECTED (0x00000001) NTSTATUS LdrpLoadDll( IN ULONG Flags OPTIONAL, IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle, IN BOOLEAN RunInitRoutines ); NTSTATUS NTAPI LdrpGetProcedureAddress( IN PVOID DllHandle, IN CONST ANSI_STRING* ProcedureName OPTIONAL, IN ULONG ProcedureNumber OPTIONAL, OUT PVOID *ProcedureAddress, IN BOOLEAN RunInitRoutines ); PLIST_ENTRY RtlpLockProcessHeapsList( VOID ); VOID RtlpUnlockProcessHeapsList( VOID ); BOOLEAN RtlpSerializeHeap( IN PVOID HeapHandle ); ULONG NtdllBaseTag; #define MAKE_TAG( t ) (RTL_HEAP_MAKE_TAG( NtdllBaseTag, t )) #define CSR_TAG 0 #define LDR_TAG 1 #define CURDIR_TAG 2 #define TLS_TAG 3 #define DBG_TAG 4 #define SE_TAG 5 #define TEMP_TAG 6 #define ATOM_TAG 7 PVOID LdrpDefineDllTag( PWSTR TagName, PUSHORT TagIndex ); #define LDRP_ACTIVATE_ACTIVATION_CONTEXT(LdrpDllActivateActivationContext_TableEntry) \ { \ RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME LdrpDllActivateActivationContext_ActivationFrame = \ { sizeof(LdrpDllActivateActivationContext_ActivationFrame), \ RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER \ }; \ \ RtlActivateActivationContextUnsafeFast(&LdrpDllActivateActivationContext_ActivationFrame, LdrpDllActivateActivationContext_TableEntry->EntryPointActivationContext); \ __try { #define LDRP_DEACTIVATE_ACTIVATION_CONTEXT() \ } __finally { \ RtlDeactivateActivationContextUnsafeFast(&LdrpDllActivateActivationContext_ActivationFrame); \ } \ } #if defined(_X86_) BOOLEAN LdrpCallInitRoutine( IN PDLL_INIT_ROUTINE InitRoutine, IN PVOID DllHandle, IN ULONG Reason, IN PCONTEXT Context OPTIONAL ); #else #define LdrpCallInitRoutine(InitRoutine, DllHandle, Reason, Context) \ (InitRoutine)((DllHandle), (Reason), (Context)) #endif NTSTATUS LdrpCorValidateImage( IN OUT PVOID *pImageBase, IN LPWSTR ImageName ); VOID LdrpCorUnloadImage( IN PVOID ImageBase ); VOID LdrpCorReplaceStartContext( IN PCONTEXT Context ); typedef VOID (*PCOR_EXE_MAIN)(VOID); extern PCOR_EXE_MAIN CorExeMain; VOID LdrpSendDllUnloadedNotifications( PLDR_DATA_TABLE_ENTRY Entry, ULONG Flags ); VOID LdrpSendDllLoadedNotifications( PLDR_DATA_TABLE_ENTRY Entry, ULONG Flags ); // // The prototypes for the shim engine callback // typedef void (*PFNSE_INSTALLBEFOREINIT)(PUNICODE_STRING UnicodeImageName, PVOID pShimExeData); typedef BOOLEAN (*PFNSE_INSTALLAFTERINIT)(PUNICODE_STRING UnicodeImageName, PVOID pShimExeData); typedef void (*PFNSE_DLLLOADED)(PLDR_DATA_TABLE_ENTRY LdrEntry); typedef void (*PFNSE_DLLUNLOADED)(PLDR_DATA_TABLE_ENTRY LdrEntry); typedef void (*PFNSE_GETPROCADDRESS)(PVOID* pProcAddress); typedef int (*PFNSE_ISSHIMDLL)(PVOID pDllBase); typedef void (*PFNSE_PROCESSDYING)(void); // // Private function from ntos\rtl\stktrace.c needed to pickup the real address // of a stack trace given an index. // PVOID RtlpGetStackTraceAddress ( USHORT Index ); // // Function defined in ntos\rtl\stktrace.c needed to speedup // RtlCaptureStackContext on x86. // VOID RtlpStkMarkDllRange ( PLDR_DATA_TABLE_ENTRY DllEntry ); VOID RtlpCheckForCriticalSectionsInMemoryRange( IN PVOID StartAddress, IN SIZE_T RegionSize, IN PVOID Information ); // // resource.c // extern BOOLEAN RtlpCriticalSectionVerifier; BOOLEAN RtlpCreateCriticalSectionSem( IN PRTL_CRITICAL_SECTION CriticalSection ); // // Application verifier // #include "avrfp.h" #endif // _LDRP_