windows-nt/Source/XPSP1/NT/base/ntdll/ldrp.h
2020-09-26 16:20:57 +08:00

703 lines
17 KiB
C

/*++
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 <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <string.h>
#define NOEXTAPI
#include "wdbgexts.h"
#include <ntdbg.h>
#include <sxstypes.h>
#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_