ReactOS 0.4.17-dev-573-g8315b8c
sysldr.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <mm/ARM3/miarm.h>
Include dependency graph for sysldr.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 
#define DEFAULT_SECURITY_COOKIE   0xBB40E64E
 
#define RVA(m, b)   ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))
 

Functions

PVOID NTAPI MiCacheImageSymbols (IN PVOID BaseAddress)
 
NTSTATUS NTAPI MiLoadImageSection (_Inout_ PSECTION *SectionPtr, _Out_ PVOID *ImageBase, _In_ PUNICODE_STRING FileName, _In_ BOOLEAN SessionLoad, _In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
 
static VOID MiUnmapSystemImage (_In_ PVOID ImageBase, _In_ ULONG ImageSize)
 Undoes the mapping performed by MiLoadImageSection(): frees the pages backing the image, and returns the system PTEs it had reserved.
 
USHORT NTAPI NameToOrdinal (_In_ PCSTR ExportName, _In_ PVOID ImageBase, _In_ ULONG NumberOfNames, _In_ PULONG NameTable, _In_ PUSHORT OrdinalTable)
 
NTSTATUS NTAPI RtlpFindExportedRoutineByName (_In_ PVOID ImageBase, _In_ PCSTR ExportName, _Out_ PVOID *Function, _Out_opt_ PBOOLEAN IsForwarder, _In_ NTSTATUS NotFoundStatus)
 ReactOS-only helper routine for RtlFindExportedRoutineByName(), that provides a finer granularity regarding the nature of the export, and the failure reasons.
 
PVOID NTAPI RtlFindExportedRoutineByName (_In_ PVOID ImageBase, _In_ PCSTR ExportName)
 Finds the address of a given named exported routine in a loaded image. Note that this function does not support forwarders.
 
NTSTATUS NTAPI MmCallDllInitialize (_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _In_ PLIST_ENTRY ModuleListHead)
 
BOOLEAN MiCallDllUnloadAndUnloadDll (_In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSTATUS NTAPI MiDereferenceImports (IN PLOAD_IMPORTS ImportList)
 
VOID NTAPI MiClearImports (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
VOID NTAPI MiProcessLoaderEntry (IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN BOOLEAN Insert)
 
VOID NTAPI MiUpdateThunks (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PVOID OldBase, IN PVOID NewBase, IN ULONG Size)
 
NTSTATUS NTAPI MiSnapThunk (IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA Name, IN PIMAGE_THUNK_DATA Address, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN SnapForwarder, OUT PCHAR *MissingApi)
 
NTSTATUS NTAPI MmUnloadSystemImage (IN PVOID ImageHandle)
 
NTSTATUS NTAPI MiResolveImageReferences (IN PVOID ImageBase, IN PUNICODE_STRING ImageFileDirectory, IN PUNICODE_STRING NamePrefix OPTIONAL, OUT PCHAR *MissingApi, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports)
 
VOID NTAPI MiFreeInitializationCode (IN PVOID InitStart, IN PVOID InitEnd)
 
VOID NTAPI MiFindInitializationCode (OUT PVOID *StartVa, OUT PVOID *EndVa)
 
VOID NTAPI MmFreeDriverInitialization (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
VOID NTAPI MiReloadBootLoadedDrivers (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
NTSTATUS NTAPI MiBuildImportsForBootDrivers (VOID)
 
VOID NTAPI MiLocateKernelSections (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
BOOLEAN NTAPI MiInitializeLoadedModuleList (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
BOOLEAN NTAPI MmChangeKernelResourceSectionProtection (IN ULONG_PTR ProtectionMask)
 
VOID NTAPI MmMakeKernelResourceSectionWritable (VOID)
 
LOGICAL NTAPI MiUseLargeDriverPage (IN ULONG NumberOfPtes, IN OUT PVOID *ImageBaseAddress, IN PUNICODE_STRING BaseImageName, IN BOOLEAN BootDriver)
 
VOID NTAPI MiSetSystemCodeProtection (_In_ PMMPTE FirstPte, _In_ PMMPTE LastPte, _In_ ULONG Protection)
 
VOID NTAPI MiWriteProtectSystemImage (_In_ PVOID ImageBase)
 
VOID NTAPI MiSetPagingOfDriver (IN PMMPTE PointerPte, IN PMMPTE LastPte)
 
VOID NTAPI MiEnablePagingOfDriver (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSTATUS NTAPI MmCheckSystemImage (_In_ HANDLE ImageHandle)
 
PVOID NTAPI LdrpFetchAddressOfSecurityCookie (PVOID BaseAddress, ULONG SizeOfImage)
 
PVOID NTAPI LdrpInitSecurityCookie (PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSTATUS NTAPI MmLoadSystemImage (IN PUNICODE_STRING FileName, IN PUNICODE_STRING NamePrefix OPTIONAL, IN PUNICODE_STRING LoadedName OPTIONAL, IN ULONG Flags, OUT PVOID *ModuleObject, OUT PVOID *ImageBaseAddress)
 
PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry (IN PVOID Address)
 
PVOID NTAPI MmPageEntireDriver (IN PVOID AddressWithinSection)
 
VOID NTAPI MmResetDriverPaging (IN PVOID AddressWithinSection)
 
PVOID NTAPI MmGetSystemRoutineAddress (IN PUNICODE_STRING SystemRoutineName)
 

Variables

LIST_ENTRY PsLoadedModuleList
 
LIST_ENTRY MmLoadedUserImageList
 
KSPIN_LOCK PsLoadedModuleSpinLock
 
ERESOURCE PsLoadedModuleResource
 
ULONG_PTR PsNtosImageBase
 
KMUTANT MmSystemLoadLock
 
PFN_NUMBER MmTotalSystemDriverPages
 
PVOID MmUnloadedDrivers
 
PVOID MmLastUnloadedDrivers
 
BOOLEAN MmMakeLowMemory
 
BOOLEAN MmEnforceWriteProtection = TRUE
 
PMMPTE MiKernelResourceStartPte
 
PMMPTE MiKernelResourceEndPte
 
ULONG_PTR ExPoolCodeStart
 
ULONG_PTR ExPoolCodeEnd
 
ULONG_PTR MmPoolCodeStart
 
ULONG_PTR MmPoolCodeEnd
 
ULONG_PTR MmPteCodeStart
 
ULONG_PTR MmPteCodeEnd
 

Macro Definition Documentation

◆ DEFAULT_SECURITY_COOKIE

#define DEFAULT_SECURITY_COOKIE   0xBB40E64E

Definition at line 44 of file sysldr.c.

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 16 of file sysldr.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file sysldr.c.

◆ RVA

#define RVA (   m,
  b 
)    ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))

Definition at line 249 of file sysldr.c.

Function Documentation

◆ LdrpFetchAddressOfSecurityCookie()

PVOID NTAPI LdrpFetchAddressOfSecurityCookie ( PVOID  BaseAddress,
ULONG  SizeOfImage 
)

Definition at line 2912 of file sysldr.c.

2913{
2915 ULONG DirSize;
2917
2918 /* Get the pointer to the config directory */
2920 TRUE,
2922 &DirSize);
2923
2924 /* Check for sanity */
2925 if (!ConfigDir ||
2926 DirSize < RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, SecurityCookie))
2927 {
2928 /* Invalid directory*/
2929 return NULL;
2930 }
2931
2932 /* Now get the cookie */
2933 Cookie = (PULONG_PTR)ConfigDir->SecurityCookie;
2934
2935 /* Check this cookie */
2937 (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage - sizeof(*Cookie))
2938 {
2939 Cookie = NULL;
2940 }
2941
2942 /* Return validated security cookie */
2943 return Cookie;
2944}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID * BaseAddress
Definition: mmfuncs.h:408
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:684
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14

Referenced by LdrpInitSecurityCookie().

◆ LdrpInitSecurityCookie()

PVOID NTAPI LdrpInitSecurityCookie ( PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2948 of file sysldr.c.

2949{
2951 ULONG_PTR NewCookie;
2952
2953 /* Fetch address of the cookie */
2955
2956 if (!Cookie)
2957 return NULL;
2958
2959 /* Check if it's a default one */
2960 if ((*Cookie == DEFAULT_SECURITY_COOKIE) ||
2961 (*Cookie == 0))
2962 {
2964 /* The address should be unique */
2965 NewCookie = (ULONG_PTR)Cookie;
2966
2967 /* We just need a simple tick, don't care about precision and whatnot */
2968 NewCookie ^= (ULONG_PTR)Counter.LowPart;
2969#ifdef _WIN64
2970 /* Some images expect first 16 bits to be kept clean (like in default cookie) */
2971 if (NewCookie > COOKIE_MAX)
2972 {
2973 NewCookie >>= 16;
2974 }
2975#endif
2976 /* If the result is 0 or the same as we got, just add one to the default value */
2977 if ((NewCookie == 0) || (NewCookie == *Cookie))
2978 {
2979 NewCookie = DEFAULT_SECURITY_COOKIE + 1;
2980 }
2981
2982 /* Set the new cookie value */
2983 *Cookie = NewCookie;
2984 }
2985
2986 return Cookie;
2987}
#define ULONG_PTR
Definition: config.h:101
LARGE_INTEGER NTAPI KeQueryPerformanceCounter(IN PLARGE_INTEGER PerformanceFreq)
Definition: timer.c:138
ULONG SizeOfImage
Definition: ldrtypes.h:147
PVOID DllBase
Definition: btrfs_drv.h:1880
static LARGE_INTEGER Counter
Definition: clock.c:43
#define DEFAULT_SECURITY_COOKIE
Definition: sysldr.c:44
PVOID NTAPI LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: sysldr.c:2912
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG LowPart
Definition: typedefs.h:106

Referenced by MmLoadSystemImage().

◆ MiBuildImportsForBootDrivers()

NTSTATUS NTAPI MiBuildImportsForBootDrivers ( VOID  )

Definition at line 1962 of file sysldr.c.

1963{
1964 PLIST_ENTRY NextEntry, NextEntry2;
1965 PLDR_DATA_TABLE_ENTRY LdrEntry, KernelEntry, HalEntry, LdrEntry2, LastEntry;
1966 PLDR_DATA_TABLE_ENTRY* EntryArray;
1967 UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
1969 PLOAD_IMPORTS LoadedImports;
1970 ULONG LoadedImportsSize, ImportSize;
1971 PULONG_PTR ImageThunk;
1972 ULONG_PTR DllBase, DllEnd;
1973 ULONG Modules = 0, i, j = 0;
1974 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
1975
1976 /* Initialize variables */
1977 KernelEntry = HalEntry = LastEntry = NULL;
1978
1979 /* Loop the loaded module list... we are early enough that no lock is needed */
1980 NextEntry = PsLoadedModuleList.Flink;
1981 while (NextEntry != &PsLoadedModuleList)
1982 {
1983 /* Get the entry */
1984 LdrEntry = CONTAINING_RECORD(NextEntry,
1986 InLoadOrderLinks);
1987
1988 /* Check if it's the kernel or HAL */
1989 if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
1990 {
1991 /* Found it */
1992 KernelEntry = LdrEntry;
1993 }
1994 else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
1995 {
1996 /* Found it */
1997 HalEntry = LdrEntry;
1998 }
1999
2000 /* Check if this is a driver DLL */
2001 if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
2002 {
2003 /* Check if this is the HAL or kernel */
2004 if ((LdrEntry == HalEntry) || (LdrEntry == KernelEntry))
2005 {
2006 /* Add a reference */
2007 LdrEntry->LoadCount = 1;
2008 }
2009 else
2010 {
2011 /* No referencing needed */
2012 LdrEntry->LoadCount = 0;
2013 }
2014 }
2015 else
2016 {
2017 /* Add a reference for all other modules as well */
2018 LdrEntry->LoadCount = 1;
2019 }
2020
2021 /* Remember this came from the loader */
2023
2024 /* Keep looping */
2025 NextEntry = NextEntry->Flink;
2026 Modules++;
2027 }
2028
2029 /* We must have at least found the kernel and HAL */
2030 if (!(HalEntry) || (!KernelEntry)) return STATUS_NOT_FOUND;
2031
2032 /* Allocate the list */
2033 EntryArray = ExAllocatePoolWithTag(PagedPool, Modules * sizeof(PVOID), TAG_LDR_IMPORTS);
2034 if (!EntryArray) return STATUS_INSUFFICIENT_RESOURCES;
2035
2036 /* Loop the loaded module list again */
2037 NextEntry = PsLoadedModuleList.Flink;
2038 while (NextEntry != &PsLoadedModuleList)
2039 {
2040 /* Get the entry */
2041 LdrEntry = CONTAINING_RECORD(NextEntry,
2043 InLoadOrderLinks);
2044#ifdef _WORKING_LOADER_
2045 /* Get its imports */
2046 ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
2047 TRUE,
2049 &ImportSize);
2050 if (!ImageThunk)
2051#else
2052 /* Get its imports */
2053 ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
2054 TRUE,
2056 &ImportSize);
2057 if (!ImportDescriptor)
2058#endif
2059 {
2060 /* None present */
2062 NextEntry = NextEntry->Flink;
2063 continue;
2064 }
2065
2066 /* Clear the list and count the number of IAT thunks */
2067 RtlZeroMemory(EntryArray, Modules * sizeof(PVOID));
2068#ifdef _WORKING_LOADER_
2069 ImportSize /= sizeof(ULONG_PTR);
2070
2071 /* Scan the thunks */
2072 for (i = 0, DllBase = 0, DllEnd = 0; i < ImportSize; i++, ImageThunk++)
2073#else
2074 DllBase = DllEnd = i = 0;
2075 while ((ImportDescriptor->Name) &&
2076 (ImportDescriptor->OriginalFirstThunk))
2077 {
2078 /* Get the image thunk */
2079 ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
2080 ImportDescriptor->FirstThunk);
2081 while (*ImageThunk)
2082#endif
2083 {
2084 /* Do we already have an address? */
2085 if (DllBase)
2086 {
2087 /* Is the thunk in the same address? */
2088 if ((*ImageThunk >= DllBase) && (*ImageThunk < DllEnd))
2089 {
2090 /* Skip it, we already have a reference for it */
2091 ASSERT(EntryArray[j]);
2092 ImageThunk++;
2093 continue;
2094 }
2095 }
2096
2097 /* Loop the loaded module list to locate this address owner */
2098 j = 0;
2099 NextEntry2 = PsLoadedModuleList.Flink;
2100 while (NextEntry2 != &PsLoadedModuleList)
2101 {
2102 /* Get the entry */
2103 LdrEntry2 = CONTAINING_RECORD(NextEntry2,
2105 InLoadOrderLinks);
2106
2107 /* Get the address range for this module */
2108 DllBase = (ULONG_PTR)LdrEntry2->DllBase;
2109 DllEnd = DllBase + LdrEntry2->SizeOfImage;
2110
2111 /* Check if this IAT entry matches it */
2112 if ((*ImageThunk >= DllBase) && (*ImageThunk < DllEnd))
2113 {
2114 /* Save it */
2115 //DPRINT1("Found imported dll: %wZ\n", &LdrEntry2->BaseDllName);
2116 EntryArray[j] = LdrEntry2;
2117 break;
2118 }
2119
2120 /* Keep searching */
2121 NextEntry2 = NextEntry2->Flink;
2122 j++;
2123 }
2124
2125 /* Do we have a thunk outside the range? */
2126 if ((*ImageThunk < DllBase) || (*ImageThunk >= DllEnd))
2127 {
2128 /* Could be 0... */
2129 if (*ImageThunk)
2130 {
2131 /* Should not be happening */
2132 ERROR_FATAL("Broken IAT entry for %p at %p (%lx)\n",
2133 LdrEntry, ImageThunk, *ImageThunk);
2134 }
2135
2136 /* Reset if we hit this */
2137 DllBase = 0;
2138 }
2139#ifndef _WORKING_LOADER_
2140 ImageThunk++;
2141 }
2142
2143 i++;
2144 ImportDescriptor++;
2145#endif
2146 }
2147
2148 /* Now scan how many imports we really have */
2149 for (i = 0, ImportSize = 0; i < Modules; i++)
2150 {
2151 /* Skip HAL and kernel */
2152 if ((EntryArray[i]) &&
2153 (EntryArray[i] != HalEntry) &&
2154 (EntryArray[i] != KernelEntry))
2155 {
2156 /* A valid reference */
2157 LastEntry = EntryArray[i];
2158 ImportSize++;
2159 }
2160 }
2161
2162 /* Do we have any imports after all? */
2163 if (!ImportSize)
2164 {
2165 /* No */
2167 }
2168 else if (ImportSize == 1)
2169 {
2170 /* A single entry import */
2171 LdrEntry->LoadedImports = (PVOID)((ULONG_PTR)LastEntry | MM_SYSLDR_SINGLE_ENTRY);
2172 LastEntry->LoadCount++;
2173 }
2174 else
2175 {
2176 /* We need an import table */
2177 LoadedImportsSize = ImportSize * sizeof(PVOID) + sizeof(SIZE_T);
2178 LoadedImports = ExAllocatePoolWithTag(PagedPool,
2179 LoadedImportsSize,
2181 ASSERT(LoadedImports);
2182
2183 /* Save the count */
2184 LoadedImports->Count = ImportSize;
2185
2186 /* Now copy all imports */
2187 for (i = 0, j = 0; i < Modules; i++)
2188 {
2189 /* Skip HAL and kernel */
2190 if ((EntryArray[i]) &&
2191 (EntryArray[i] != HalEntry) &&
2192 (EntryArray[i] != KernelEntry))
2193 {
2194 /* A valid reference */
2195 //DPRINT1("Found valid entry: %p\n", EntryArray[i]);
2196 LoadedImports->Entry[j] = EntryArray[i];
2197 EntryArray[i]->LoadCount++;
2198 j++;
2199 }
2200 }
2201
2202 /* Should had as many entries as we expected */
2203 ASSERT(j == ImportSize);
2204 LdrEntry->LoadedImports = LoadedImports;
2205 }
2206
2207 /* Next */
2208 NextEntry = NextEntry->Flink;
2209 }
2210
2211 /* Free the initial array */
2213
2214 /* FIXME: Might not need to keep the HAL/Kernel imports around */
2215
2216 /* Kernel and HAL are loaded at boot */
2217 KernelEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
2219
2220 /* All worked well */
2221 return STATUS_SUCCESS;
2222}
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define L(x)
Definition: resources.c:13
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
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
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 GLint GLint j
Definition: glfuncs.h:250
PWCHAR HalName
Definition: halacpi.c:45
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:60
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:214
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:215
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:216
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
#define IMAGE_DIRECTORY_ENTRY_IAT
Definition: pedump.c:271
#define ERROR_FATAL(...)
Definition: debug.h:238
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
Definition: btrfs_drv.h:1876
USHORT LoadCount
Definition: ntddk_ex.h:208
PVOID LoadedImports
Definition: ldrtypes.h:165
ULONG Flags
Definition: ntddk_ex.h:207
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:149
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
SIZE_T Count
Definition: ldrtypes.h:176
PLDR_DATA_TABLE_ENTRY Entry[1]
Definition: ldrtypes.h:177
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
#define TAG_LDR_IMPORTS
Definition: tag.h:103
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by MiInitializeLoadedModuleList().

◆ MiCacheImageSymbols()

PVOID NTAPI MiCacheImageSymbols ( IN PVOID  BaseAddress)

Definition at line 51 of file sysldr.c.

52{
53 ULONG DebugSize;
54 PVOID DebugDirectory = NULL;
55 PAGED_CODE();
56
57 /* Make sure it's safe to access the image */
59 {
60 /* Get the debug directory */
62 TRUE,
64 &DebugSize);
65 }
67 {
68 /* Nothing */
69 }
71
72 /* Return the directory */
73 return DebugDirectory;
74}
#define PAGED_CODE()
#define IMAGE_DIRECTORY_ENTRY_DEBUG
Definition: compat.h:152
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93

Referenced by MmLoadSystemImage().

◆ MiCallDllUnloadAndUnloadDll()

BOOLEAN MiCallDllUnloadAndUnloadDll ( _In_ PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 528 of file sysldr.c.

530{
533
534 PAGED_CODE();
535
536 /* Retrieve the DllUnload routine */
538 RtlFindExportedRoutineByName(LdrEntry->DllBase, "DllUnload");
539 if (!DllUnload)
540 return FALSE;
541
542 /* Call it and check for success */
543 Status = DllUnload();
544 if (!NT_SUCCESS(Status))
545 return FALSE;
546
547 /* Lie about the load count so we can unload the image */
548 ASSERT(LdrEntry->LoadCount == 0);
549 LdrEntry->LoadCount = 1;
550
551 /* Unload it */
552 MmUnloadSystemImage(LdrEntry);
553 return TRUE;
554}
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
ULONG NTAPI DllUnload()
Definition: dll.cpp:28
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:976
PVOID NTAPI RtlFindExportedRoutineByName(_In_ PVOID ImageBase, _In_ PCSTR ExportName)
Finds the address of a given named exported routine in a loaded image. Note that this function does n...
Definition: sysldr.c:432
NTSTATUS(NTAPI * PMM_DLL_UNLOAD)(VOID)
Definition: iotypes.h:2856

Referenced by MiDereferenceImports().

◆ MiClearImports()

VOID NTAPI MiClearImports ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 633 of file sysldr.c.

634{
635 PAGED_CODE();
636
637 /* Check if there's no imports or we're a boot driver or only one entry */
638 if ((LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) ||
639 (LdrEntry->LoadedImports == MM_SYSLDR_NO_IMPORTS) ||
640 ((ULONG_PTR)LdrEntry->LoadedImports & MM_SYSLDR_SINGLE_ENTRY))
641 {
642 /* Nothing to do */
643 return;
644 }
645
646 /* Otherwise, free the import list */
647 ExFreePoolWithTag(LdrEntry->LoadedImports, TAG_LDR_IMPORTS);
648 LdrEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
649}

Referenced by MmUnloadSystemImage().

◆ MiDereferenceImports()

NTSTATUS NTAPI MiDereferenceImports ( IN PLOAD_IMPORTS  ImportList)

Definition at line 558 of file sysldr.c.

559{
560 SIZE_T i;
561 LOAD_IMPORTS SingleEntry;
562 PLDR_DATA_TABLE_ENTRY LdrEntry;
563 PVOID CurrentImports;
564 PAGED_CODE();
565
566 /* Check if there's no imports or if we're a boot driver */
567 if ((ImportList == MM_SYSLDR_NO_IMPORTS) ||
568 (ImportList == MM_SYSLDR_BOOT_LOADED) ||
569 (ImportList->Count == 0))
570 {
571 /* Then there's nothing to do */
572 return STATUS_SUCCESS;
573 }
574
575 /* Check for single-entry */
576 if ((ULONG_PTR)ImportList & MM_SYSLDR_SINGLE_ENTRY)
577 {
578 /* Set it up */
579 SingleEntry.Count = 1;
580 SingleEntry.Entry[0] = (PVOID)((ULONG_PTR)ImportList &~ MM_SYSLDR_SINGLE_ENTRY);
581
582 /* Use this as the import list */
583 ImportList = &SingleEntry;
584 }
585
586 /* Loop the import list */
587 for (i = 0; (i < ImportList->Count) && (ImportList->Entry[i]); i++)
588 {
589 /* Get the entry */
590 LdrEntry = ImportList->Entry[i];
591 DPRINT1("%wZ <%wZ>\n", &LdrEntry->FullDllName, &LdrEntry->BaseDllName);
592
593 /* Skip boot loaded images */
594 if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) continue;
595
596 /* Dereference the entry */
597 ASSERT(LdrEntry->LoadCount >= 1);
598 if (!--LdrEntry->LoadCount)
599 {
600 /* Save the import data in case unload fails */
601 CurrentImports = LdrEntry->LoadedImports;
602
603 /* This is the last entry */
605 if (MiCallDllUnloadAndUnloadDll(LdrEntry))
606 {
607 /* Unloading worked, parse this DLL's imports too */
608 MiDereferenceImports(CurrentImports);
609
610 /* Check if we had valid imports */
611 if ((CurrentImports != MM_SYSLDR_BOOT_LOADED) &&
612 (CurrentImports != MM_SYSLDR_NO_IMPORTS) &&
613 !((ULONG_PTR)CurrentImports & MM_SYSLDR_SINGLE_ENTRY))
614 {
615 /* Free them */
616 ExFreePoolWithTag(CurrentImports, TAG_LDR_IMPORTS);
617 }
618 }
619 else
620 {
621 /* Unload failed, restore imports */
622 LdrEntry->LoadedImports = CurrentImports;
623 }
624 }
625 }
626
627 /* Done */
628 return STATUS_SUCCESS;
629}
#define DPRINT1
Definition: precomp.h:8
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:558
BOOLEAN MiCallDllUnloadAndUnloadDll(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:528

Referenced by MiDereferenceImports(), MiResolveImageReferences(), and MmUnloadSystemImage().

◆ MiEnablePagingOfDriver()

VOID NTAPI MiEnablePagingOfDriver ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2699 of file sysldr.c.

2700{
2701 ULONG_PTR ImageBase;
2702 PIMAGE_NT_HEADERS NtHeaders;
2703 ULONG Sections, Alignment, Size;
2704 PIMAGE_SECTION_HEADER Section;
2705 PMMPTE PointerPte = NULL, LastPte = NULL;
2706 if (MmDisablePagingExecutive) return;
2707
2708 /* Get the driver base address and its NT header */
2709 ImageBase = (ULONG_PTR)LdrEntry->DllBase;
2710 NtHeaders = RtlImageNtHeader((PVOID)ImageBase);
2711 if (!NtHeaders) return;
2712
2713 /* Get the sections and their alignment */
2714 Sections = NtHeaders->FileHeader.NumberOfSections;
2715 Alignment = NtHeaders->OptionalHeader.SectionAlignment - 1;
2716
2717 /* Loop each section */
2718 Section = IMAGE_FIRST_SECTION(NtHeaders);
2719 while (Sections)
2720 {
2721 /* Find PAGE or .edata */
2722 if ((*(PULONG)Section->Name == 'EGAP') ||
2723 (*(PULONG)Section->Name == 'ade.'))
2724 {
2725 /* Had we already done some work? */
2726 if (!PointerPte)
2727 {
2728 /* Nope, setup the first PTE address */
2729 PointerPte = MiAddressToPte(ROUND_TO_PAGES(ImageBase +
2730 Section->VirtualAddress));
2731 }
2732
2733 /* Compute the size */
2734 Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2735
2736 /* Find the last PTE that maps this section */
2737 LastPte = MiAddressToPte(ImageBase +
2738 Section->VirtualAddress +
2740 }
2741 else
2742 {
2743 /* Had we found a section before? */
2744 if (PointerPte)
2745 {
2746 /* Mark it as pageable */
2747 MiSetPagingOfDriver(PointerPte, LastPte);
2748 PointerPte = NULL;
2749 }
2750 }
2751
2752 /* Keep searching */
2753 Sections--;
2754 Section++;
2755 }
2756
2757 /* Handle the straggler */
2758 if (PointerPte) MiSetPagingOfDriver(PointerPte, LastPte);
2759}
#define RtlImageNtHeader
Definition: compat.h:806
#define PAGE_SIZE
Definition: env_spec_w32.h:49
union Alignment_ Alignment
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
#define MiAddressToPte(x)
Definition: mm.h:145
UCHAR MmDisablePagingExecutive
Definition: mminit.c:25
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
union _IMAGE_SECTION_HEADER::@1701 Misc
#define max(a, b)
Definition: svc.c:63
VOID NTAPI MiSetPagingOfDriver(IN PMMPTE PointerPte, IN PMMPTE LastPte)
Definition: sysldr.c:2640
uint32_t * PULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
#define ROUND_TO_PAGES(Size)

Referenced by MmLoadSystemImage().

◆ MiFindInitializationCode()

VOID NTAPI MiFindInitializationCode ( OUT PVOID StartVa,
OUT PVOID EndVa 
)

Definition at line 1530 of file sysldr.c.

1532{
1533 ULONG Size, SectionCount, Alignment;
1534 PLDR_DATA_TABLE_ENTRY LdrEntry;
1535 ULONG_PTR DllBase, InitStart, InitEnd, ImageEnd, InitCode;
1536 PLIST_ENTRY NextEntry;
1537 PIMAGE_NT_HEADERS NtHeader;
1538 PIMAGE_SECTION_HEADER Section, LastSection, InitSection;
1539 BOOLEAN InitFound;
1541
1542 /* So we don't free our own code yet */
1544
1545 /* Assume failure */
1546 *StartVa = NULL;
1547
1548 /* Acquire the necessary locks while we loop the list */
1552 KernelMode,
1553 FALSE,
1554 NULL);
1556
1557 /* Loop all loaded modules */
1558 NextEntry = PsLoadedModuleList.Flink;
1559 while (NextEntry != &PsLoadedModuleList)
1560 {
1561 /* Get the loader entry and its DLL base */
1562 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1563 DllBase = (ULONG_PTR)LdrEntry->DllBase;
1564
1565 /* Only process boot loaded images. Other drivers are processed by
1566 MmFreeDriverInitialization */
1567 if (LdrEntry->Flags & LDRP_MM_LOADED)
1568 {
1569 /* Keep going */
1570 NextEntry = NextEntry->Flink;
1571 continue;
1572 }
1573
1574 /* Get the NT header */
1575 NtHeader = RtlImageNtHeader((PVOID)DllBase);
1576 if (!NtHeader)
1577 {
1578 /* Keep going */
1579 NextEntry = NextEntry->Flink;
1580 continue;
1581 }
1582
1583 /* Get the first section, the section count, and scan them all */
1584 Section = IMAGE_FIRST_SECTION(NtHeader);
1585 SectionCount = NtHeader->FileHeader.NumberOfSections;
1586 InitStart = 0;
1587 while (SectionCount > 0)
1588 {
1589 /* Assume failure */
1590 InitFound = FALSE;
1591
1592 /* Is this the INIT section or a discardable section? */
1593 if ((strncmp((PCCH)Section->Name, "INIT", 5) == 0) ||
1595 {
1596 /* Remember this */
1597 InitFound = TRUE;
1598 InitSection = Section;
1599 }
1600
1601 if (InitFound)
1602 {
1603 /* Pick the biggest size -- either raw or virtual */
1604 Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
1605
1606 /* Read the section alignment */
1608
1609 /* Get the start and end addresses */
1610 InitStart = DllBase + Section->VirtualAddress;
1611 InitEnd = ALIGN_UP_BY(InitStart + Size, Alignment);
1612
1613 /* Align the addresses to PAGE_SIZE */
1614 InitStart = ALIGN_UP_BY(InitStart, PAGE_SIZE);
1615 InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1616
1617 /* Have we reached the last section? */
1618 if (SectionCount == 1)
1619 {
1620 /* Remember this */
1621 LastSection = Section;
1622 }
1623 else
1624 {
1625 /* We have not, loop all the sections */
1626 LastSection = NULL;
1627 do
1628 {
1629 /* Keep going until we find a non-discardable section range */
1630 SectionCount--;
1631 Section++;
1633 {
1634 /* Discardable, so record it, then keep going */
1635 LastSection = Section;
1636 }
1637 else
1638 {
1639 /* Non-contigous discard flag, or no flag, break out */
1640 break;
1641 }
1642 }
1643 while (SectionCount > 1);
1644 }
1645
1646 /* Have we found a discardable or init section? */
1647 if (LastSection)
1648 {
1649 /* Pick the biggest size -- either raw or virtual */
1650 Size = max(LastSection->SizeOfRawData, LastSection->Misc.VirtualSize);
1651
1652 /* Use this as the end of the section address */
1653 InitEnd = DllBase + LastSection->VirtualAddress + Size;
1654
1655 /* Have we reached the last section yet? */
1656 if (SectionCount != 1)
1657 {
1658 /* Then align this accross the session boundary */
1659 InitEnd = ALIGN_UP_BY(InitEnd, Alignment);
1660 InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1661 }
1662 }
1663
1664 /* Make sure we don't let the init section go past the image */
1665 ImageEnd = DllBase + LdrEntry->SizeOfImage;
1666 if (InitEnd > ImageEnd) InitEnd = ALIGN_UP_BY(ImageEnd, PAGE_SIZE);
1667
1668 /* Make sure we have a valid, non-zero init section */
1669 if (InitStart < InitEnd)
1670 {
1671 /* Make sure we are not within this code itself */
1672 if ((InitCode >= InitStart) && (InitCode < InitEnd))
1673 {
1674 /* Return it, we can't free ourselves now */
1675 ASSERT(*StartVa == 0);
1676 *StartVa = (PVOID)InitStart;
1677 *EndVa = (PVOID)InitEnd;
1678 }
1679 else
1680 {
1681 /* This isn't us -- go ahead and free it */
1682 ASSERT(MI_IS_PHYSICAL_ADDRESS((PVOID)InitStart) == FALSE);
1683 DPRINT("Freeing init code: %p-%p ('%wZ' @%p : '%s')\n",
1684 (PVOID)InitStart,
1685 (PVOID)InitEnd,
1686 &LdrEntry->BaseDllName,
1687 LdrEntry->DllBase,
1688 InitSection->Name);
1689 MiFreeInitializationCode((PVOID)InitStart, (PVOID)InitEnd);
1690 }
1691 }
1692 }
1693
1694 /* Move to the next section */
1695 SectionCount--;
1696 Section++;
1697 }
1698
1699 /* Move to the next module */
1700 NextEntry = NextEntry->Flink;
1701 }
1702
1703 /* Release the locks and return */
1707}
#define ALIGN_DOWN_BY(size, align)
#define ALIGN_UP_BY(size, align)
unsigned char BOOLEAN
Definition: actypes.h:127
_ACRTIMP int __cdecl strncmp(const char *, const char *, size_t)
Definition: string.c:3335
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define LDRP_MM_LOADED
Definition: ldrtypes.h:64
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:953
#define MUTANT_INCREMENT
Definition: extypes.h:84
#define KernelMode
Definition: asm.h:38
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:331
CONST CHAR * PCCH
Definition: ntbasedef.h:404
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
LONG NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
Definition: mutex.c:98
#define DPRINT
Definition: sndvol32.h:73
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1530
VOID NTAPI MiFreeInitializationCode(IN PVOID InitStart, IN PVOID InitEnd)
Definition: sysldr.c:1507
KMUTANT MmSystemLoadLock
Definition: sysldr.c:26
@ WrVirtualMemory
Definition: ketypes.h:485

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiFreeInitializationCode()

VOID NTAPI MiFreeInitializationCode ( IN PVOID  InitStart,
IN PVOID  InitEnd 
)

Definition at line 1507 of file sysldr.c.

1509{
1510 PMMPTE PointerPte;
1511 PFN_NUMBER PagesFreed;
1512
1513 /* Get the start PTE */
1514 PointerPte = MiAddressToPte(InitStart);
1515 ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE);
1516
1517 /* Compute the number of pages we expect to free */
1518 PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte);
1519
1520 /* Try to actually free them */
1521 PagesFreed = MiDeleteSystemPageableVm(PointerPte,
1522 PagesFreed,
1523 0,
1524 NULL);
1525}
ULONG_PTR PFN_NUMBER
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiInitializeLoadedModuleList()

BOOLEAN NTAPI MiInitializeLoadedModuleList ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 2284 of file sysldr.c.

2285{
2286 PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
2287 PLIST_ENTRY ListHead, NextEntry;
2289
2290 /* Setup the loaded module list and locks */
2294
2295 /* Get loop variables and the kernel entry */
2296 ListHead = &LoaderBlock->LoadOrderListHead;
2297 NextEntry = ListHead->Flink;
2298 LdrEntry = CONTAINING_RECORD(NextEntry,
2300 InLoadOrderLinks);
2301 PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
2302
2303 /* Locate resource section, pool code, and system pte code */
2304 MiLocateKernelSections(LdrEntry);
2305
2306 /* Loop the loader block */
2307 while (NextEntry != ListHead)
2308 {
2309 /* Get the loader entry */
2310 LdrEntry = CONTAINING_RECORD(NextEntry,
2312 InLoadOrderLinks);
2313
2314 /* FIXME: ROS HACK. Make sure this is a driver */
2315 if (!RtlImageNtHeader(LdrEntry->DllBase))
2316 {
2317 /* Skip this entry */
2318 NextEntry = NextEntry->Flink;
2319 continue;
2320 }
2321
2322 /* Calculate the size we'll need and allocate a copy */
2324 LdrEntry->BaseDllName.MaximumLength +
2325 sizeof(UNICODE_NULL);
2327 if (!NewEntry) return FALSE;
2328
2329 /* Copy the entry over */
2330 *NewEntry = *LdrEntry;
2331
2332 /* Allocate the name */
2333 NewEntry->FullDllName.Buffer =
2335 LdrEntry->FullDllName.MaximumLength +
2336 sizeof(UNICODE_NULL),
2337 TAG_LDR_WSTR);
2338 if (!NewEntry->FullDllName.Buffer)
2339 {
2341 return FALSE;
2342 }
2343
2344 /* Set the base name */
2345 NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
2346
2347 /* Copy the full and base name */
2349 LdrEntry->FullDllName.Buffer,
2350 LdrEntry->FullDllName.MaximumLength);
2352 LdrEntry->BaseDllName.Buffer,
2353 LdrEntry->BaseDllName.MaximumLength);
2354
2355 /* Null-terminate the base name */
2356 NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
2357 sizeof(WCHAR)] = UNICODE_NULL;
2358
2359 /* Insert the entry into the list */
2361 NextEntry = NextEntry->Flink;
2362 }
2363
2364 /* Build the import lists for the boot drivers */
2366
2367 /* We're done */
2368 return TRUE;
2369}
struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY
#define InsertTailList(ListHead, Entry)
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define UNICODE_NULL
short WCHAR
Definition: pedump.c:58
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:142
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSTATUS NTAPI MiBuildImportsForBootDrivers(VOID)
Definition: sysldr.c:1962
VOID NTAPI MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2227
KSPIN_LOCK PsLoadedModuleSpinLock
Definition: sysldr.c:23
ULONG_PTR PsNtosImageBase
Definition: sysldr.c:25
#define TAG_MODULE_OBJECT
Definition: tag.h:101
#define TAG_LDR_WSTR
Definition: tag.h:102
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ UCHAR EntrySize
Definition: iofuncs.h:642

Referenced by MmArmInitSystem().

◆ MiLoadImageSection()

NTSTATUS NTAPI MiLoadImageSection ( _Inout_ PSECTION SectionPtr,
_Out_ PVOID ImageBase,
_In_ PUNICODE_STRING  FileName,
_In_ BOOLEAN  SessionLoad,
_In_ PLDR_DATA_TABLE_ENTRY  LdrEntry 
)

Definition at line 78 of file sysldr.c.

83{
84 PSECTION Section = *SectionPtr;
87 PVOID Base = NULL;
88 SIZE_T ViewSize = 0;
92 PFN_COUNT PteCount;
93 PMMPTE PointerPte, LastPte;
94 PVOID DriverBase;
97 PFN_NUMBER PageFrameIndex;
98 PAGED_CODE();
99
100 /* Detect session load */
101 if (SessionLoad)
102 {
103 /* Fail */
104 UNIMPLEMENTED_DBGBREAK("Session loading not yet supported!\n");
106 }
107
108 /* Not session load, shouldn't have an entry */
109 ASSERT(LdrEntry == NULL);
110
111 /* Attach to the system process */
113
114 /* Check if we need to load symbols */
116 {
117 /* Yes we do */
119 NtGlobalFlag &= ~FLG_ENABLE_KDEBUG_SYMBOL_LOAD;
120 }
121
122 /* Map the driver */
124 Status = MmMapViewOfSection(Section,
125 Process,
126 &Base,
127 0,
128 0,
130 &ViewSize,
131 ViewUnmap,
132 0,
134
135 /* Re-enable the flag */
137
138 /* Check if we failed with distinguished status code */
140 {
141 /* Change it to something more generic */
143 }
144
145 /* Now check if we failed */
146 if (!NT_SUCCESS(Status))
147 {
148 /* Detach and return */
149 DPRINT1("MmMapViewOfSection failed with status 0x%x\n", Status);
151 return Status;
152 }
153
154 /* Reserve system PTEs needed */
155 PteCount = ROUND_TO_PAGES(((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize) >> PAGE_SHIFT;
156 PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
157 if (!PointerPte)
158 {
159 DPRINT1("MiReserveSystemPtes failed\n");
162 }
163
164 /* New driver base */
165 LastPte = PointerPte + PteCount;
166 DriverBase = MiPteToAddress(PointerPte);
167
168 /* The driver is here */
169 *ImageBase = DriverBase;
170 DPRINT1("Loading: %wZ at %p with %lx pages\n", FileName, DriverBase, PteCount);
171
172 /* Lock the PFN database */
173 OldIrql = MiAcquirePfnLock();
174
175 /* Loop the new driver PTEs */
177 while (PointerPte < LastPte)
178 {
179 /* Make sure the PTE is not valid for whatever reason */
180 ASSERT(PointerPte->u.Hard.Valid == 0);
181
182 /* Some debug stuff */
184#if MI_TRACE_PFNS
185 MI_SET_PROCESS_USTR(FileName);
186#endif
187
188 /* Grab a page */
189 PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
190
191 /* Initialize its PFN entry */
192 MiInitializePfn(PageFrameIndex, PointerPte, TRUE);
193
194 /* Write the PTE */
195 TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
196 MI_WRITE_VALID_PTE(PointerPte, TempPte);
197
198 /* Move on */
199 PointerPte++;
200 }
201
202 /* Release the PFN lock */
203 MiReleasePfnLock(OldIrql);
204
205 /* Copy the image */
206 RtlCopyMemory(DriverBase, Base, PteCount << PAGE_SHIFT);
207
208 /* Now unmap the view */
211
212 /* Detach and return status */
214 return Status;
215}
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:2766
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define FLG_ENABLE_KDEBUG_SYMBOL_LOAD
Definition: pstypes.h:68
static BOOLEAN LoadSymbols
Definition: kdb_symbols.c:30
@ SystemPteSpace
Definition: miarm.h:407
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:236
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:967
VOID NTAPI MiInitializePfn(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN BOOLEAN Modified)
Definition: pfnlist.c:970
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:411
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:412
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2486
#define PAGE_EXECUTE
Definition: nt_native.h:1309
@ ViewUnmap
Definition: nt_native.h:1282
ULONG NtGlobalFlag
Definition: init.c:54
#define MiPteToAddress(_Pte)
Definition: mm.h:116
@ MI_USAGE_DRIVER_PAGE
Definition: mm.h:347
#define MI_SET_USAGE(x)
Definition: mm.h:327
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1769
MMPTE ValidKernelPte
Definition: init.c:29
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:453
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH
Definition: ntstatus.h:203
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
NTSTATUS NTAPI MmMapViewOfSection(_In_ PVOID SectionObject, _In_ PEPROCESS Process, _Outptr_result_bytebuffer_(*ViewSize) _Pre_opt_valid_ PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_opt_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG AllocationType, _In_ ULONG Protect)
Definition: section.c:4031
KPROCESS Pcb
Definition: pstypes.h:1350
ULONG PageFrameNumber
Definition: mmtypes.h:109
ULONG64 Valid
Definition: mmtypes.h:150
union _MMPTE::@2562 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
PSEGMENT Segment
Definition: mmtypes.h:812
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
KAPC_STATE
Definition: ketypes.h:1727
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by MmLoadSystemImage().

◆ MiLocateKernelSections()

VOID NTAPI MiLocateKernelSections ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2227 of file sysldr.c.

2228{
2229 ULONG_PTR DllBase;
2230 PIMAGE_NT_HEADERS NtHeaders;
2231 PIMAGE_SECTION_HEADER SectionHeader;
2232 ULONG Sections, Size;
2233
2234 /* Get the kernel section header */
2235 DllBase = (ULONG_PTR)LdrEntry->DllBase;
2236 NtHeaders = RtlImageNtHeader((PVOID)DllBase);
2237 SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
2238
2239 /* Loop all the sections */
2240 for (Sections = NtHeaders->FileHeader.NumberOfSections;
2241 Sections > 0; --Sections, ++SectionHeader)
2242 {
2243 /* Grab the size of the section */
2244 Size = max(SectionHeader->SizeOfRawData, SectionHeader->Misc.VirtualSize);
2245
2246 /* Check for .RSRC section */
2247 if (*(PULONG)SectionHeader->Name == 'rsr.')
2248 {
2249 /* Remember the PTEs so we can modify them later */
2251 SectionHeader->VirtualAddress);
2253 SectionHeader->VirtualAddress + Size));
2254 }
2255 else if (*(PULONG)SectionHeader->Name == 'LOOP')
2256 {
2257 /* POOLCODE vs. POOLMI */
2258 if (*(PULONG)&SectionHeader->Name[4] == 'EDOC')
2259 {
2260 /* Found Ex* Pool code */
2261 ExPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2263 }
2264 else if (*(PUSHORT)&SectionHeader->Name[4] == 'MI')
2265 {
2266 /* Found Mm* Pool code */
2267 MmPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2269 }
2270 }
2271 else if ((*(PULONG)SectionHeader->Name == 'YSIM') &&
2272 (*(PULONG)&SectionHeader->Name[4] == 'ETPS'))
2273 {
2274 /* Found MISYSPTE (Mm System PTE code) */
2275 MmPteCodeStart = DllBase + SectionHeader->VirtualAddress;
2277 }
2278 }
2279}
ULONG_PTR ExPoolCodeStart
Definition: sysldr.c:37
ULONG_PTR MmPoolCodeEnd
Definition: sysldr.c:37
ULONG_PTR ExPoolCodeEnd
Definition: sysldr.c:37
ULONG_PTR MmPteCodeEnd
Definition: sysldr.c:38
ULONG_PTR MmPoolCodeStart
Definition: sysldr.c:37
ULONG_PTR MmPteCodeStart
Definition: sysldr.c:38
PMMPTE MiKernelResourceEndPte
Definition: sysldr.c:36
PMMPTE MiKernelResourceStartPte
Definition: sysldr.c:36
uint16_t * PUSHORT
Definition: typedefs.h:56

Referenced by MiInitializeLoadedModuleList().

◆ MiLookupDataTableEntry()

PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry ( IN PVOID  Address)

Definition at line 3582 of file sysldr.c.

3583{
3584 PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL;
3585 PLIST_ENTRY NextEntry;
3586 PAGED_CODE();
3587
3588 /* Loop entries */
3589 NextEntry = PsLoadedModuleList.Flink;
3590 do
3591 {
3592 /* Get the loader entry */
3593 LdrEntry = CONTAINING_RECORD(NextEntry,
3595 InLoadOrderLinks);
3596
3597 /* Check if the address matches */
3598 if ((Address >= LdrEntry->DllBase) &&
3599 (Address < (PVOID)((ULONG_PTR)LdrEntry->DllBase +
3600 LdrEntry->SizeOfImage)))
3601 {
3602 /* Found a match */
3603 FoundEntry = LdrEntry;
3604 break;
3605 }
3606
3607 /* Move on */
3608 NextEntry = NextEntry->Flink;
3609 } while(NextEntry != &PsLoadedModuleList);
3610
3611 /* Return the entry */
3612 return FoundEntry;
3613}
static WCHAR Address[46]
Definition: ping.c:68

Referenced by ExAllocatePool(), MmAddVerifierThunks(), and MmPageEntireDriver().

◆ MiProcessLoaderEntry()

VOID NTAPI MiProcessLoaderEntry ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry,
IN BOOLEAN  Insert 
)

Definition at line 653 of file sysldr.c.

655{
657
658 /* Acquire module list lock */
661
662 /* Acquire the spinlock too as we will insert or remove the entry */
664
665 /* Insert or remove from the list */
666 if (Insert)
667 InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks);
668 else
669 RemoveEntryList(&LdrEntry->InLoadOrderLinks);
670
671 /* Release locks */
675}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
KIRQL FASTCALL KeAcquireSpinLockRaiseToSynch(PKSPIN_LOCK SpinLock)
Definition: spinlock.c:62

Referenced by MmLoadSystemImage(), and MmUnloadSystemImage().

◆ MiReloadBootLoadedDrivers()

VOID NTAPI MiReloadBootLoadedDrivers ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 1773 of file sysldr.c.

1774{
1775 PLIST_ENTRY NextEntry;
1776 ULONG i = 0;
1777 PIMAGE_NT_HEADERS NtHeader;
1778 PLDR_DATA_TABLE_ENTRY LdrEntry;
1779 PIMAGE_FILE_HEADER FileHeader;
1780 BOOLEAN ValidRelocs;
1781 PIMAGE_DATA_DIRECTORY DataDirectory;
1782 PVOID DllBase, NewImageAddress;
1784 PMMPTE PointerPte, StartPte, LastPte;
1785 PFN_COUNT PteCount;
1786 PMMPFN Pfn1;
1787 MMPTE TempPte, OldPte;
1788
1789 /* Loop driver list */
1790 for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
1791 NextEntry != &LoaderBlock->LoadOrderListHead;
1792 NextEntry = NextEntry->Flink)
1793 {
1794 /* Get the loader entry and NT header */
1795 LdrEntry = CONTAINING_RECORD(NextEntry,
1797 InLoadOrderLinks);
1798 NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
1799
1800 /* Debug info */
1801 DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",
1802 LdrEntry->DllBase,
1803 (ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage,
1804 &LdrEntry->FullDllName);
1805
1806 /* Get the first PTE and the number of PTEs we'll need */
1807 PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
1808 PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
1809 LastPte = StartPte + PteCount;
1810
1811#if MI_TRACE_PFNS
1812 /* Loop the PTEs */
1813 while (PointerPte < LastPte)
1814 {
1815 ULONG len;
1816 ASSERT(PointerPte->u.Hard.Valid == 1);
1817 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1818 len = wcslen(LdrEntry->BaseDllName.Buffer) * sizeof(WCHAR);
1819 snprintf(Pfn1->ProcessName, min(16, len), "%S", LdrEntry->BaseDllName.Buffer);
1820 PointerPte++;
1821 }
1822#endif
1823 /* Skip kernel and HAL */
1824 /* ROS HACK: Skip BOOTVID/KDCOM too */
1825 i++;
1826 if (i <= 4) continue;
1827
1828 /* Skip non-drivers */
1829 if (!NtHeader) continue;
1830
1831 /* Get the file header and make sure we can relocate */
1832 FileHeader = &NtHeader->FileHeader;
1833 if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;
1834 if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <
1836
1837 /* Everything made sense until now, check the relocation section too */
1838 DataDirectory = &NtHeader->OptionalHeader.
1839 DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
1840 if (!DataDirectory->VirtualAddress)
1841 {
1842 /* We don't really have relocations */
1843 ValidRelocs = FALSE;
1844 }
1845 else
1846 {
1847 /* Make sure the size is valid */
1848 if ((DataDirectory->VirtualAddress + DataDirectory->Size) >
1849 LdrEntry->SizeOfImage)
1850 {
1851 /* They're not, skip */
1852 continue;
1853 }
1854
1855 /* We have relocations */
1856 ValidRelocs = TRUE;
1857 }
1858
1859 /* Remember the original address */
1860 DllBase = LdrEntry->DllBase;
1861
1862 /* Loop the PTEs */
1863 PointerPte = StartPte;
1864 while (PointerPte < LastPte)
1865 {
1866 /* Mark the page modified in the PFN database */
1867 ASSERT(PointerPte->u.Hard.Valid == 1);
1868 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1869 ASSERT(Pfn1->u3.e1.Rom == 0);
1870 Pfn1->u3.e1.Modified = TRUE;
1871
1872 /* Next */
1873 PointerPte++;
1874 }
1875
1876 /* Now reserve system PTEs for the image */
1877 PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
1878 if (!PointerPte)
1879 {
1880 /* Shouldn't happen */
1881 ERROR_FATAL("[Mm0]: Couldn't allocate driver section!\n");
1882 return;
1883 }
1884
1885 /* This is the new virtual address for the module */
1886 LastPte = PointerPte + PteCount;
1887 NewImageAddress = MiPteToAddress(PointerPte);
1888
1889 /* Sanity check */
1890 DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);
1892
1893 /* Loop the new driver PTEs */
1895 while (PointerPte < LastPte)
1896 {
1897 /* Copy the old data */
1898 OldPte = *StartPte;
1899 ASSERT(OldPte.u.Hard.Valid == 1);
1900
1901 /* Set page number from the loader's memory */
1903
1904 /* Write it */
1905 MI_WRITE_VALID_PTE(PointerPte, TempPte);
1906
1907 /* Move on */
1908 PointerPte++;
1909 StartPte++;
1910 }
1911
1912 /* Update position */
1913 PointerPte -= PteCount;
1914
1915 /* Sanity check */
1916 ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);
1917
1918 /* Set the image base to the address where the loader put it */
1919 NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
1920
1921 /* Check if we had relocations */
1922 if (ValidRelocs)
1923 {
1924 /* Relocate the image */
1925 Status = LdrRelocateImageWithBias(NewImageAddress,
1926 0,
1927 "SYSLDR",
1931 if (!NT_SUCCESS(Status))
1932 {
1933 /* This shouldn't happen */
1934 ERROR_FATAL("Relocations failed!\n");
1935 return;
1936 }
1937 }
1938
1939 /* Update the loader entry */
1940 LdrEntry->DllBase = NewImageAddress;
1941
1942 /* Update the thunks */
1943 DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);
1944 MiUpdateThunks(LoaderBlock,
1945 DllBase,
1946 NewImageAddress,
1947 LdrEntry->SizeOfImage);
1948
1949 /* Update the loader entry */
1950 LdrEntry->Flags |= LDRP_SYSTEM_MAPPED;
1951 LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +
1953 LdrEntry->SizeOfImage = PteCount << PAGE_SHIFT;
1954
1955 /* FIXME: We'll need to fixup the PFN linkage when switching to ARM3 */
1956 }
1957}
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
GLenum GLsizei len
Definition: glext.h:6722
#define LDRP_SYSTEM_MAPPED
Definition: ldrtypes.h:58
#define min(a, b)
Definition: monoChain.cc:55
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
ULONG ExpInitializationPhase
Definition: init.c:68
#define PFN_FROM_PTE(v)
Definition: mm.h:92
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1046
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:354
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define IMAGE_FILE_RELOCS_STRIPPED
Definition: pedump.c:159
PVOID EntryPoint
Definition: ntddk_ex.h:203
USHORT Modified
Definition: mm.h:370
USHORT Rom
Definition: mm.h:378
Definition: mm.h:390
MMPFNENTRY e1
Definition: mm.h:413
union _MMPFN::@1979 u3
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
VOID NTAPI MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PVOID OldBase, IN PVOID NewBase, IN ULONG Size)
Definition: sysldr.c:680
#define snprintf
Definition: wintirpc.h:48

Referenced by MmArmInitSystem().

◆ MiResolveImageReferences()

NTSTATUS NTAPI MiResolveImageReferences ( IN PVOID  ImageBase,
IN PUNICODE_STRING  ImageFileDirectory,
IN PUNICODE_STRING NamePrefix  OPTIONAL,
OUT PCHAR MissingApi,
OUT PWCHAR MissingDriver,
OUT PLOAD_IMPORTS LoadImports 
)

Definition at line 1076 of file sysldr.c.

1082{
1083 static UNICODE_STRING DriversFolderName = RTL_CONSTANT_STRING(L"drivers\\");
1084 PCHAR MissingApiBuffer = *MissingApi, ImportName;
1085 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport;
1086 ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize;
1087 PLOAD_IMPORTS LoadedImports, NewImports;
1088 ULONG i;
1089 BOOLEAN GdiLink, NormalLink;
1090 BOOLEAN ReferenceNeeded, Loaded;
1091 ANSI_STRING TempString;
1092 UNICODE_STRING NameString, DllName;
1093 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL, DllEntry, ImportEntry = NULL;
1094 PVOID ImportBase, DllBase;
1095 PLIST_ENTRY NextEntry;
1096 PIMAGE_EXPORT_DIRECTORY ExportDirectory;
1098 PIMAGE_THUNK_DATA OrigThunk, FirstThunk;
1099
1100 PAGED_CODE();
1101
1102 DPRINT("%s - ImageBase: %p. ImageFileDirectory: %wZ\n",
1103 __FUNCTION__, ImageBase, ImageFileDirectory);
1104
1105 /* No name string buffer yet */
1106 NameString.Buffer = NULL;
1107
1108 /* Assume no imports */
1109 *LoadImports = MM_SYSLDR_NO_IMPORTS;
1110
1111 /* Get the import descriptor */
1112 ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase,
1113 TRUE,
1115 &ImportSize);
1116 if (!ImportDescriptor) return STATUS_SUCCESS;
1117
1118 /* Loop all imports to count them */
1119 for (CurrentImport = ImportDescriptor;
1120 (CurrentImport->Name) && (CurrentImport->OriginalFirstThunk);
1121 CurrentImport++)
1122 {
1123 /* One more */
1124 ImportCount++;
1125 }
1126
1127 /* Make sure we have non-zero imports */
1128 if (ImportCount)
1129 {
1130 /* Calculate and allocate the list we'll need */
1131 LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1132 LoadedImports = ExAllocatePoolWithTag(PagedPool,
1133 LoadedImportsSize,
1135 if (LoadedImports)
1136 {
1137 /* Zero it */
1138 RtlZeroMemory(LoadedImports, LoadedImportsSize);
1139 LoadedImports->Count = ImportCount;
1140 }
1141 }
1142 else
1143 {
1144 /* No table */
1145 LoadedImports = NULL;
1146 }
1147
1148 /* Reset the import count and loop descriptors again */
1149 GdiLink = NormalLink = FALSE;
1150 ImportCount = 0;
1151 while ((ImportDescriptor->Name) && (ImportDescriptor->OriginalFirstThunk))
1152 {
1153 /* Get the name */
1154 ImportName = (PCHAR)((ULONG_PTR)ImageBase + ImportDescriptor->Name);
1155
1156 /* Check if this is a GDI driver */
1157 GdiLink = GdiLink ||
1158 !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1));
1159
1160 /* We can also allow dxapi (for Windows compat, allow IRT and coverage) */
1161 NormalLink = NormalLink ||
1162 ((_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) &&
1163 (_strnicmp(ImportName, "dxapi", sizeof("dxapi") - 1)) &&
1164 (_strnicmp(ImportName, "coverage", sizeof("coverage") - 1)) &&
1165 (_strnicmp(ImportName, "irt", sizeof("irt") - 1)));
1166
1167 /* Check if this is a valid GDI driver */
1168 if (GdiLink && NormalLink)
1169 {
1170 /* It's not, it's importing stuff it shouldn't be! */
1172 goto Failure;
1173 }
1174
1175 /* Check for user-mode printer or video card drivers, which don't belong */
1176 if (!(_strnicmp(ImportName, "ntdll", sizeof("ntdll") - 1)) ||
1177 !(_strnicmp(ImportName, "winsrv", sizeof("winsrv") - 1)) ||
1178 !(_strnicmp(ImportName, "advapi32", sizeof("advapi32") - 1)) ||
1179 !(_strnicmp(ImportName, "kernel32", sizeof("kernel32") - 1)) ||
1180 !(_strnicmp(ImportName, "user32", sizeof("user32") - 1)) ||
1181 !(_strnicmp(ImportName, "gdi32", sizeof("gdi32") - 1)))
1182 {
1183 /* This is not kernel code */
1185 goto Failure;
1186 }
1187
1188 /* Check if this is a "core" import, which doesn't get referenced */
1189 if (!(_strnicmp(ImportName, "ntoskrnl", sizeof("ntoskrnl") - 1)) ||
1190 !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) ||
1191 !(_strnicmp(ImportName, "hal", sizeof("hal") - 1)))
1192 {
1193 /* Don't reference this */
1194 ReferenceNeeded = FALSE;
1195 }
1196 else
1197 {
1198 /* Reference these modules */
1199 ReferenceNeeded = TRUE;
1200 }
1201
1202 /* Now setup a unicode string for the import */
1203 RtlInitAnsiString(&TempString, ImportName);
1204 Status = RtlAnsiStringToUnicodeString(&NameString, &TempString, TRUE);
1205 if (!NT_SUCCESS(Status))
1206 {
1207 /* Failed */
1208 goto Failure;
1209 }
1210
1211 /* We don't support name prefixes yet */
1212 if (NamePrefix) DPRINT1("Name Prefix not yet supported!\n");
1213
1214 /* Remember that we haven't loaded the import at this point */
1215CheckDllState:
1216 Loaded = FALSE;
1217 ImportBase = NULL;
1218
1219 /* Loop the driver list */
1220 NextEntry = PsLoadedModuleList.Flink;
1221 while (NextEntry != &PsLoadedModuleList)
1222 {
1223 /* Get the loader entry and compare the name */
1224 LdrEntry = CONTAINING_RECORD(NextEntry,
1226 InLoadOrderLinks);
1227 if (RtlEqualUnicodeString(&NameString,
1228 &LdrEntry->BaseDllName,
1229 TRUE))
1230 {
1231 /* Get the base address */
1232 ImportBase = LdrEntry->DllBase;
1233
1234 /* Check if we haven't loaded yet, and we need references */
1235 if (!(Loaded) && (ReferenceNeeded))
1236 {
1237 /* Make sure we're not already loading */
1238 if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1239 {
1240 /* Increase the load count */
1241 LdrEntry->LoadCount++;
1242 }
1243 }
1244
1245 /* Done, break out */
1246 break;
1247 }
1248
1249 /* Go to the next entry */
1250 NextEntry = NextEntry->Flink;
1251 }
1252
1253 /* Check if we haven't loaded the import yet */
1254 if (!ImportBase)
1255 {
1256 /* Setup the import DLL name */
1257 DllName.MaximumLength = NameString.Length +
1258 ImageFileDirectory->Length +
1259 sizeof(UNICODE_NULL);
1261 DllName.MaximumLength,
1262 TAG_LDR_WSTR);
1263 if (!DllName.Buffer)
1264 {
1265 /* We're out of resources */
1267 goto Failure;
1268 }
1269
1270 /* Add the import name to the base directory */
1271 RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1273 &NameString);
1274
1275 /* Load the image */
1276 Status = MmLoadSystemImage(&DllName,
1277 NamePrefix,
1278 NULL,
1279 FALSE,
1280 (PVOID *)&DllEntry,
1281 &DllBase);
1282
1283 /* win32k / GDI drivers can also import from system32 folder */
1285 (MI_IS_SESSION_ADDRESS(ImageBase) || 1)) // HACK
1286 {
1287 /* Free the old name buffer */
1289
1290 /* Calculate size for a string the adds 'drivers\' */
1291 DllName.MaximumLength += DriversFolderName.Length;
1292
1293 /* Allocate the new buffer */
1295 DllName.MaximumLength,
1296 TAG_LDR_WSTR);
1297 if (!DllName.Buffer)
1298 {
1299 /* We're out of resources */
1301 goto Failure;
1302 }
1303
1304 /* Copy image directory and append 'drivers\' folder name */
1305 RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1306 RtlAppendUnicodeStringToString(&DllName, &DriversFolderName);
1307
1308 /* Now add the import name */
1309 RtlAppendUnicodeStringToString(&DllName, &NameString);
1310
1311 /* Try once again to load the image */
1312 Status = MmLoadSystemImage(&DllName,
1313 NamePrefix,
1314 NULL,
1315 FALSE,
1316 (PVOID *)&DllEntry,
1317 &DllBase);
1318 }
1319
1320 if (!NT_SUCCESS(Status))
1321 {
1322 /* Fill out the information for the error */
1323 *MissingDriver = DllName.Buffer;
1324 *(PULONG)MissingDriver |= 1;
1325 *MissingApi = NULL;
1326
1327 DPRINT1("Failed to load dependency: %wZ\n", &DllName);
1328
1329 /* Don't free the name */
1330 DllName.Buffer = NULL;
1331
1332 /* Cleanup and return */
1333 goto Failure;
1334 }
1335
1336 /* We can free the DLL Name */
1338 DllName.Buffer = NULL;
1339
1340 /* We're now loaded */
1341 Loaded = TRUE;
1342
1343 /* Sanity check */
1344 ASSERT(DllBase == DllEntry->DllBase);
1345
1346 /* Call the initialization routines */
1348 if (!NT_SUCCESS(Status))
1349 {
1350 /* We failed, unload the image */
1351 MmUnloadSystemImage(DllEntry);
1352 ERROR_DBGBREAK("MmCallDllInitialize failed with status 0x%x\n", Status);
1353 Loaded = FALSE;
1354 }
1355
1356 /* Loop again to make sure that everything is OK */
1357 goto CheckDllState;
1358 }
1359
1360 /* Check if we're support to reference this import */
1361 if ((ReferenceNeeded) && (LoadedImports))
1362 {
1363 /* Make sure we're not already loading */
1364 if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1365 {
1366 /* Add the entry */
1367 LoadedImports->Entry[ImportCount] = LdrEntry;
1368 ImportCount++;
1369 }
1370 }
1371
1372 /* Free the import name */
1373 RtlFreeUnicodeString(&NameString);
1374
1375 /* Set the missing driver name and get the export directory */
1376 *MissingDriver = LdrEntry->BaseDllName.Buffer;
1377 ExportDirectory = RtlImageDirectoryEntryToData(ImportBase,
1378 TRUE,
1380 &ExportSize);
1381 if (!ExportDirectory)
1382 {
1383 /* Cleanup and return */
1384 DPRINT1("Warning: Driver failed to load, %S not found\n", *MissingDriver);
1386 goto Failure;
1387 }
1388
1389 /* Make sure we have an IAT */
1390 if (ImportDescriptor->OriginalFirstThunk)
1391 {
1392 /* Get the first thunks */
1393 OrigThunk = (PVOID)((ULONG_PTR)ImageBase +
1394 ImportDescriptor->OriginalFirstThunk);
1395 FirstThunk = (PVOID)((ULONG_PTR)ImageBase +
1396 ImportDescriptor->FirstThunk);
1397
1398 /* Loop the IAT */
1399 while (OrigThunk->u1.AddressOfData)
1400 {
1401 /* Snap thunk */
1402 Status = MiSnapThunk(ImportBase,
1403 ImageBase,
1404 OrigThunk++,
1405 FirstThunk++,
1406 ExportDirectory,
1407 ExportSize,
1408 FALSE,
1409 MissingApi);
1410 if (!NT_SUCCESS(Status))
1411 {
1412 /* Cleanup and return */
1413 goto Failure;
1414 }
1415
1416 /* Reset the buffer */
1417 *MissingApi = MissingApiBuffer;
1418 }
1419 }
1420
1421 /* Go to the next import */
1422 ImportDescriptor++;
1423 }
1424
1425 /* Check if we have an import list */
1426 if (LoadedImports)
1427 {
1428 /* Reset the count again, and loop entries */
1429 ImportCount = 0;
1430 for (i = 0; i < LoadedImports->Count; i++)
1431 {
1432 if (LoadedImports->Entry[i])
1433 {
1434 /* Got an entry, OR it with 1 in case it's the single entry */
1435 ImportEntry = (PVOID)((ULONG_PTR)LoadedImports->Entry[i] |
1437 ImportCount++;
1438 }
1439 }
1440
1441 /* Check if we had no imports */
1442 if (!ImportCount)
1443 {
1444 /* Free the list and set it to no imports */
1445 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1446 LoadedImports = MM_SYSLDR_NO_IMPORTS;
1447 }
1448 else if (ImportCount == 1)
1449 {
1450 /* Just one entry, we can free the table and only use our entry */
1451 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1452 LoadedImports = (PLOAD_IMPORTS)ImportEntry;
1453 }
1454 else if (ImportCount != LoadedImports->Count)
1455 {
1456 /* Allocate a new list */
1457 LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1458 NewImports = ExAllocatePoolWithTag(PagedPool,
1459 LoadedImportsSize,
1461 if (NewImports)
1462 {
1463 /* Set count */
1464 NewImports->Count = 0;
1465
1466 /* Loop all the imports */
1467 for (i = 0; i < LoadedImports->Count; i++)
1468 {
1469 /* Make sure it's valid */
1470 if (LoadedImports->Entry[i])
1471 {
1472 /* Copy it */
1473 NewImports->Entry[NewImports->Count] = LoadedImports->Entry[i];
1474 NewImports->Count++;
1475 }
1476 }
1477
1478 /* Free the old copy */
1479 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1480 LoadedImports = NewImports;
1481 }
1482 }
1483
1484 /* Return the list */
1485 *LoadImports = LoadedImports;
1486 }
1487
1488 /* Return success */
1489 return STATUS_SUCCESS;
1490
1491Failure:
1492
1493 /* Cleanup and return */
1494 RtlFreeUnicodeString(&NameString);
1495
1496 if (LoadedImports)
1497 {
1498 MiDereferenceImports(LoadedImports);
1499 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1500 }
1501
1502 return Status;
1503}
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define __FUNCTION__
Definition: types.h:116
@ Loaded
Definition: fs_rec.h:187
#define LDRP_LOAD_IN_PROGRESS
Definition: ldrtypes.h:46
struct _LOAD_IMPORTS * PLOAD_IMPORTS
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:185
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:858
#define STATUS_PROCEDURE_NOT_FOUND
Definition: ntstatus.h:452
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
union _IMAGE_THUNK_DATA32::@2362 u1
NTSTATUS NTAPI MiSnapThunk(IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA Name, IN PIMAGE_THUNK_DATA Address, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN SnapForwarder, OUT PCHAR *MissingApi)
Definition: sysldr.c:779
NTSTATUS NTAPI MmLoadSystemImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING NamePrefix OPTIONAL, IN PUNICODE_STRING LoadedName OPTIONAL, IN ULONG Flags, OUT PVOID *ModuleObject, OUT PVOID *ImageBaseAddress)
Definition: sysldr.c:2991
NTSTATUS NTAPI MmCallDllInitialize(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _In_ PLIST_ENTRY ModuleListHead)
Definition: sysldr.c:464
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

Referenced by LdrProcessDriverModule(), and MmLoadSystemImage().

◆ MiSetPagingOfDriver()

VOID NTAPI MiSetPagingOfDriver ( IN PMMPTE  PointerPte,
IN PMMPTE  LastPte 
)

Definition at line 2640 of file sysldr.c.

2642{
2643#ifdef ENABLE_MISETPAGINGOFDRIVER
2644 PVOID ImageBase;
2645 PETHREAD CurrentThread = PsGetCurrentThread();
2646 PFN_COUNT PageCount = 0;
2647 PFN_NUMBER PageFrameIndex;
2648 PMMPFN Pfn1;
2649#endif // ENABLE_MISETPAGINGOFDRIVER
2650
2651 PAGED_CODE();
2652
2653#ifndef ENABLE_MISETPAGINGOFDRIVER
2654 /* The page fault handler is broken and doesn't page back in! */
2655 DPRINT1("WARNING: MiSetPagingOfDriver() called, but paging is broken! ignoring!\n");
2656#else // ENABLE_MISETPAGINGOFDRIVER
2657 /* Get the driver's base address */
2658 ImageBase = MiPteToAddress(PointerPte);
2660
2661 /* If this is a large page, it's stuck in physical memory */
2662 if (MI_IS_PHYSICAL_ADDRESS(ImageBase)) return;
2663
2664 /* Lock the working set */
2665 MiLockWorkingSet(CurrentThread, &MmSystemCacheWs);
2666
2667 /* Loop the PTEs */
2668 while (PointerPte <= LastPte)
2669 {
2670 /* Check for valid PTE */
2671 if (PointerPte->u.Hard.Valid == 1)
2672 {
2673 PageFrameIndex = PFN_FROM_PTE(PointerPte);
2674 Pfn1 = MiGetPfnEntry(PageFrameIndex);
2675 ASSERT(Pfn1->u2.ShareCount == 1);
2676
2677 /* No working sets in ReactOS yet */
2678 PageCount++;
2679 }
2680
2681 ImageBase = (PVOID)((ULONG_PTR)ImageBase + PAGE_SIZE);
2682 PointerPte++;
2683 }
2684
2685 /* Release the working set */
2686 MiUnlockWorkingSet(CurrentThread, &MmSystemCacheWs);
2687
2688 /* Do we have any driver pages? */
2689 if (PageCount)
2690 {
2691 /* Update counters */
2693 }
2694#endif // ENABLE_MISETPAGINGOFDRIVER
2695}
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define InterlockedExchangeAdd
Definition: interlocked.h:196
FORCEINLINE VOID MiLockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1272
#define MI_IS_SESSION_IMAGE_ADDRESS(Address)
Definition: miarm.h:182
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1358
MMSUPPORT MmSystemCacheWs
Definition: init.c:55
union _MMPFN::@1978 u2
ULONG_PTR ShareCount
Definition: mm.h:406
PFN_NUMBER MmTotalSystemDriverPages
Definition: sysldr.c:28
int32_t * PLONG
Definition: typedefs.h:58

Referenced by MiEnablePagingOfDriver(), and MmPageEntireDriver().

◆ MiSetSystemCodeProtection()

VOID NTAPI MiSetSystemCodeProtection ( _In_ PMMPTE  FirstPte,
_In_ PMMPTE  LastPte,
_In_ ULONG  Protection 
)

Definition at line 2484 of file sysldr.c.

2488{
2489 PMMPTE PointerPte;
2490 MMPTE TempPte;
2491
2492 /* Loop the PTEs */
2493 for (PointerPte = FirstPte; PointerPte <= LastPte; PointerPte++)
2494 {
2495 /* Read the PTE */
2496 TempPte = *PointerPte;
2497
2498 /* Make sure it's valid */
2499 if (TempPte.u.Hard.Valid != 1)
2500 {
2501 DPRINT1("CORE-16449: FirstPte=%p, LastPte=%p, Protection=%lx\n", FirstPte, LastPte, Protection);
2502 DPRINT1("CORE-16449: PointerPte=%p, TempPte=%lx\n", PointerPte, TempPte.u.Long);
2503 DPRINT1("CORE-16449: Please issue the 'mod' and 'bt' (KDBG) or 'lm' and 'kp' (WinDbg) commands. Then report this in Jira.\n");
2504 ASSERT(TempPte.u.Hard.Valid == 1);
2505 break;
2506 }
2507
2508 /* Update the protection */
2509 TempPte.u.Hard.Write = BooleanFlagOn(Protection, IMAGE_SCN_MEM_WRITE);
2510#if _MI_HAS_NO_EXECUTE
2512#endif
2513
2514 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2515 }
2516
2517 /* Flush it all */
2519}
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:985
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
#define IMAGE_SCN_MEM_EXECUTE
Definition: ntimage.h:239
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:661

Referenced by MiWriteProtectSystemImage().

◆ MiSnapThunk()

NTSTATUS NTAPI MiSnapThunk ( IN PVOID  DllBase,
IN PVOID  ImageBase,
IN PIMAGE_THUNK_DATA  Name,
IN PIMAGE_THUNK_DATA  Address,
IN PIMAGE_EXPORT_DIRECTORY  ExportDirectory,
IN ULONG  ExportSize,
IN BOOLEAN  SnapForwarder,
OUT PCHAR MissingApi 
)

Definition at line 779 of file sysldr.c.

787{
788 BOOLEAN IsOrdinal;
789 USHORT Ordinal;
790 PULONG NameTable;
791 PUSHORT OrdinalTable;
792 PIMAGE_IMPORT_BY_NAME NameImport;
793 USHORT Hint;
795 PCHAR MissingForwarder;
796 CHAR NameBuffer[MAXIMUM_FILENAME_LENGTH];
797 PULONG ExportTable;
798 ANSI_STRING DllName;
799 UNICODE_STRING ForwarderName;
800 PLIST_ENTRY NextEntry;
801 PLDR_DATA_TABLE_ENTRY LdrEntry;
802 ULONG ForwardExportSize;
803 PIMAGE_EXPORT_DIRECTORY ForwardExportDirectory;
804 PIMAGE_IMPORT_BY_NAME ForwardName;
805 SIZE_T ForwardLength;
806 IMAGE_THUNK_DATA ForwardThunk;
807
808 PAGED_CODE();
809
810 /* Check if this is an ordinal */
811 IsOrdinal = IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal);
812 if ((IsOrdinal) && !(SnapForwarder))
813 {
814 /* Get the ordinal number and set it as missing */
815 Ordinal = (USHORT)(IMAGE_ORDINAL(Name->u1.Ordinal) -
816 ExportDirectory->Base);
817 *MissingApi = (PCHAR)(ULONG_PTR)Ordinal;
818 }
819 else
820 {
821 /* Get the VA if we don't have to snap */
822 if (!SnapForwarder) Name->u1.AddressOfData += (ULONG_PTR)ImageBase;
823 NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData;
824
825 /* Copy the procedure name */
826 RtlStringCbCopyA(*MissingApi,
828 (PCHAR)NameImport->Name);
829
830 /* Setup name tables */
831 DPRINT("Import name: %s\n", NameImport->Name);
832 NameTable = (PULONG)((ULONG_PTR)DllBase +
833 ExportDirectory->AddressOfNames);
834 OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
835 ExportDirectory->AddressOfNameOrdinals);
836
837 /* Get the hint and check if it's valid */
838 Hint = NameImport->Hint;
839 if ((Hint < ExportDirectory->NumberOfNames) &&
840 !(strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))
841 {
842 /* We have a match, get the ordinal number from here */
843 Ordinal = OrdinalTable[Hint];
844 }
845 else
846 {
847 /* Do a binary search */
848 Ordinal = NameToOrdinal((PCHAR)NameImport->Name,
849 DllBase,
850 ExportDirectory->NumberOfNames,
851 NameTable,
852 OrdinalTable);
853
854 /* Check if we couldn't find it */
855 if (Ordinal == -1)
856 {
857 DPRINT1("Warning: Driver failed to load, %s not found\n", NameImport->Name);
859 }
860 }
861 }
862
863 /* Check if the ordinal is valid */
864 if (Ordinal >= ExportDirectory->NumberOfFunctions)
865 {
866 /* It's not, fail */
868 }
869 else
870 {
871 /* In case the forwarder is missing */
872 MissingForwarder = NameBuffer;
873
874 /* Resolve the address and write it */
875 ExportTable = (PULONG)((ULONG_PTR)DllBase +
876 ExportDirectory->AddressOfFunctions);
877 Address->u1.Function = (ULONG_PTR)DllBase + ExportTable[Ordinal];
878
879 /* Assume success from now on */
881
882 /* Check if the function is actually a forwarder */
883 if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&
884 (Address->u1.Function < (ULONG_PTR)ExportDirectory + ExportSize))
885 {
886 /* Now assume failure in case the forwarder doesn't exist */
888
889 /* Build the forwarder name */
890 DllName.Buffer = (PCHAR)Address->u1.Function;
891 DllName.Length = (USHORT)(strchr(DllName.Buffer, '.') -
892 DllName.Buffer) +
893 sizeof(ANSI_NULL);
894 DllName.MaximumLength = DllName.Length;
895
896 /* Convert it */
897 if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ForwarderName,
898 &DllName,
899 TRUE)))
900 {
901 /* We failed, just return an error */
902 return Status;
903 }
904
905 /* Loop the module list */
906 NextEntry = PsLoadedModuleList.Flink;
907 while (NextEntry != &PsLoadedModuleList)
908 {
909 /* Get the loader entry */
910 LdrEntry = CONTAINING_RECORD(NextEntry,
912 InLoadOrderLinks);
913
914 /* Check if it matches */
915 if (RtlPrefixUnicodeString(&ForwarderName,
916 &LdrEntry->BaseDllName,
917 TRUE))
918 {
919 /* Get the forwarder export directory */
920 ForwardExportDirectory =
922 TRUE,
924 &ForwardExportSize);
925 if (!ForwardExportDirectory) break;
926
927 /* Allocate a name entry */
928 ForwardLength = strlen(DllName.Buffer + DllName.Length) +
929 sizeof(ANSI_NULL);
930 ForwardName = ExAllocatePoolWithTag(PagedPool,
931 sizeof(*ForwardName) +
932 ForwardLength,
934 if (!ForwardName) break;
935
936 /* Copy the data */
937 RtlCopyMemory(&ForwardName->Name[0],
938 DllName.Buffer + DllName.Length,
939 ForwardLength);
940 ForwardName->Hint = 0;
941
942 /* Set the new address */
943 ForwardThunk.u1.AddressOfData = (ULONG_PTR)ForwardName;
944
945 /* Snap the forwarder */
946 Status = MiSnapThunk(LdrEntry->DllBase,
947 ImageBase,
948 &ForwardThunk,
949 &ForwardThunk,
950 ForwardExportDirectory,
951 ForwardExportSize,
952 TRUE,
953 &MissingForwarder);
954
955 /* Free the forwarder name and set the thunk */
956 ExFreePoolWithTag(ForwardName, TAG_LDR_WSTR);
957 Address->u1 = ForwardThunk.u1;
958 break;
959 }
960
961 /* Go to the next entry */
962 NextEntry = NextEntry->Flink;
963 }
964
965 /* Free the name */
966 RtlFreeUnicodeString(&ForwarderName);
967 }
968 }
969
970 /* Return status */
971 return Status;
972}
LPWSTR Name
Definition: desk.c:124
_ACRTIMP char *__cdecl strchr(const char *, int)
Definition: string.c:3291
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define ANSI_NULL
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
#define STATUS_DRIVER_ORDINAL_NOT_FOUND
Definition: ntstatus.h:857
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
unsigned short USHORT
Definition: pedump.c:61
char CHAR
Definition: pedump.c:57
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
USHORT MaximumLength
Definition: env_spec_w32.h:377
USHORT NTAPI NameToOrdinal(_In_ PCSTR ExportName, _In_ PVOID ImageBase, _In_ ULONG NumberOfNames, _In_ PULONG NameTable, _In_ PUSHORT OrdinalTable)
Definition: sysldr.c:254

Referenced by MiResolveImageReferences(), and MiSnapThunk().

◆ MiUnmapSystemImage()

static VOID MiUnmapSystemImage ( _In_ PVOID  ImageBase,
_In_ ULONG  ImageSize 
)
static

Undoes the mapping performed by MiLoadImageSection(): frees the pages backing the image, and returns the system PTEs it had reserved.

Parameters
[in]ImageBaseThe base address of the image located in the system PTE space, as returned by MiLoadImageSection(). Do not pass the original base addresses of the boot-start drivers here.
[in]ImageSizeThe size of the image, in bytes.

Definition at line 232 of file sysldr.c.

235{
236 PMMPTE BasePte = MiAddressToPte(ImageBase);
237 PFN_COUNT NumberOfPages = BYTES_TO_PAGES(ImageSize);
238
239 /* TODO: Support large-page and session image mappings */
241 NT_ASSERT(!MI_IS_SESSION_ADDRESS(ImageBase));
242
243 /* Free the pages, then give the reserved PTEs back */
244 MiDeleteSystemPageableVm(BasePte, NumberOfPages, 0, NULL);
245 MiReleaseSystemPtes(BasePte, NumberOfPages, SystemPteSpace);
246}
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:264
#define BYTES_TO_PAGES(Size)
#define NT_ASSERT
Definition: rtlfuncs.h:3327

Referenced by MmLoadSystemImage(), and MmUnloadSystemImage().

◆ MiUpdateThunks()

VOID NTAPI MiUpdateThunks ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock,
IN PVOID  OldBase,
IN PVOID  NewBase,
IN ULONG  Size 
)

Definition at line 680 of file sysldr.c.

684{
685 ULONG_PTR OldBaseTop, Delta;
686 PLDR_DATA_TABLE_ENTRY LdrEntry;
687 PLIST_ENTRY NextEntry;
688 ULONG ImportSize;
689 //
690 // FIXME: MINGW-W64 must fix LD to generate drivers that Windows can load,
691 // since a real version of Windows would fail at this point, but they seem
692 // busy implementing features such as "HotPatch" support in GCC 4.6 instead,
693 // a feature which isn't even used by Windows. Priorities, priorities...
694 // Please note that Microsoft WDK EULA and license prohibits using
695 // the information contained within it for the generation of "non-Windows"
696 // drivers, which is precisely what LD will generate, since an LD driver
697 // will not load on Windows.
698 //
699#ifdef _WORKING_LINKER_
700 ULONG i;
701#endif
702 PULONG_PTR ImageThunk;
703 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
704
705 /* Calculate the top and delta */
706 OldBaseTop = (ULONG_PTR)OldBase + Size - 1;
707 Delta = (ULONG_PTR)NewBase - (ULONG_PTR)OldBase;
708
709 /* Loop the loader block */
710 for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
711 NextEntry != &LoaderBlock->LoadOrderListHead;
712 NextEntry = NextEntry->Flink)
713 {
714 /* Get the loader entry */
715 LdrEntry = CONTAINING_RECORD(NextEntry,
717 InLoadOrderLinks);
718#ifdef _WORKING_LINKER_
719 /* Get the IAT */
720 ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
721 TRUE,
723 &ImportSize);
724 if (!ImageThunk) continue;
725
726 /* Make sure we have an IAT */
727 DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
728 for (i = 0; i < ImportSize; i++, ImageThunk++)
729 {
730 /* Check if it's within this module */
731 if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
732 {
733 /* Relocate it */
734 DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
735 ImageThunk, *ImageThunk, *ImageThunk + Delta);
736 *ImageThunk += Delta;
737 }
738 }
739#else
740 /* Get the import table */
741 ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
742 TRUE,
744 &ImportSize);
745 if (!ImportDescriptor) continue;
746
747 /* Make sure we have an IAT */
748 DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
749 while ((ImportDescriptor->Name) &&
750 (ImportDescriptor->OriginalFirstThunk))
751 {
752 /* Get the image thunk */
753 ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
754 ImportDescriptor->FirstThunk);
755 while (*ImageThunk)
756 {
757 /* Check if it's within this module */
758 if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
759 {
760 /* Relocate it */
761 DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
762 ImageThunk, *ImageThunk, *ImageThunk + Delta);
763 *ImageThunk += Delta;
764 }
765
766 /* Go to the next thunk */
767 ImageThunk++;
768 }
769
770 /* Go to the next import */
771 ImportDescriptor++;
772 }
773#endif
774 }
775}

Referenced by MiReloadBootLoadedDrivers().

◆ MiUseLargeDriverPage()

LOGICAL NTAPI MiUseLargeDriverPage ( IN ULONG  NumberOfPtes,
IN OUT PVOID ImageBaseAddress,
IN PUNICODE_STRING  BaseImageName,
IN BOOLEAN  BootDriver 
)

Definition at line 2427 of file sysldr.c.

2431{
2432 PLIST_ENTRY NextEntry;
2433 BOOLEAN DriverFound = FALSE;
2434 PMI_LARGE_PAGE_DRIVER_ENTRY LargePageDriverEntry;
2436 ASSERT(*ImageBaseAddress >= MmSystemRangeStart);
2437
2438#ifdef _X86_
2439 if (!(KeFeatureBits & KF_LARGE_PAGE)) return FALSE;
2440 if (!(__readcr4() & CR4_PSE)) return FALSE;
2441#endif
2442
2443 /* Make sure there's enough system PTEs for a large page driver */
2445 {
2446 return FALSE;
2447 }
2448
2449 /* This happens if the registry key had a "*" (wildcard) in it */
2450 if (MiLargePageAllDrivers == 0)
2451 {
2452 /* It didn't, so scan the list */
2453 NextEntry = MiLargePageDriverList.Flink;
2454 while (NextEntry != &MiLargePageDriverList)
2455 {
2456 /* Check if the driver name matches */
2457 LargePageDriverEntry = CONTAINING_RECORD(NextEntry,
2459 Links);
2460 if (RtlEqualUnicodeString(BaseImageName,
2461 &LargePageDriverEntry->BaseName,
2462 TRUE))
2463 {
2464 /* Enable large pages for this driver */
2465 DriverFound = TRUE;
2466 break;
2467 }
2468
2469 /* Keep trying */
2470 NextEntry = NextEntry->Flink;
2471 }
2472
2473 /* If we didn't find the driver, it doesn't need large pages */
2474 if (DriverFound == FALSE) return FALSE;
2475 }
2476
2477 /* Nothing to do yet */
2478 DPRINT1("Large pages not supported!\n");
2479 return FALSE;
2480}
ULONG64 KeFeatureBits
Definition: krnlinit.c:22
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1857
BOOLEAN MiLargePageAllDrivers
Definition: largepag.c:27
LIST_ENTRY MiLargePageDriverList
Definition: largepag.c:26
ULONG MmTotalFreeSystemPtes[MaximumPtePoolTypes]
Definition: syspte.c:25
#define KF_LARGE_PAGE
Definition: ketypes.h:36
#define CR4_PSE
Definition: ketypes.h:158
#define MmSystemRangeStart
Definition: mm.h:32
#define PDE_MAPPED_VA
Definition: mm.h:39
Definition: miarm.h:400
UNICODE_STRING BaseName
Definition: miarm.h:402

Referenced by MmLoadSystemImage().

◆ MiWriteProtectSystemImage()

VOID NTAPI MiWriteProtectSystemImage ( _In_ PVOID  ImageBase)

Definition at line 2523 of file sysldr.c.

2525{
2526 PIMAGE_NT_HEADERS NtHeaders;
2527 PIMAGE_SECTION_HEADER SectionHeaders, Section;
2528 ULONG i;
2529 PVOID SectionBase, SectionEnd;
2530 ULONG SectionSize;
2531 ULONG Protection;
2532 PMMPTE FirstPte, LastPte;
2533
2534 /* Check if the registry setting is on or not */
2536 {
2537 /* Ignore section protection */
2538 return;
2539 }
2540
2541 /* Large page mapped images are not supported */
2542 NT_ASSERT(!MI_IS_PHYSICAL_ADDRESS(ImageBase));
2543
2544 /* Session images are not yet supported */
2545 NT_ASSERT(!MI_IS_SESSION_ADDRESS(ImageBase));
2546
2547 /* Get the NT headers */
2548 NtHeaders = RtlImageNtHeader(ImageBase);
2549 if (NtHeaders == NULL)
2550 {
2551 DPRINT1("Failed to get NT headers for image @ %p\n", ImageBase);
2552 return;
2553 }
2554
2555 /* Don't touch NT4 drivers */
2556 if ((NtHeaders->OptionalHeader.MajorOperatingSystemVersion < 5) ||
2557 (NtHeaders->OptionalHeader.MajorSubsystemVersion < 5))
2558 {
2559 DPRINT1("Skipping NT 4 driver @ %p\n", ImageBase);
2560 return;
2561 }
2562
2563 /* Get the section headers */
2564 SectionHeaders = IMAGE_FIRST_SECTION(NtHeaders);
2565
2566 /* Get the base address of the first section */
2567 SectionBase = Add2Ptr(ImageBase, SectionHeaders[0].VirtualAddress);
2568
2569 /* Start protecting the image header as R/W */
2570 FirstPte = MiAddressToPte(ImageBase);
2571 LastPte = MiAddressToPte(SectionBase) - 1;
2573 if (LastPte >= FirstPte)
2574 {
2575 MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2576 }
2577
2578 /* Loop the sections */
2579 for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
2580 {
2581 /* Get the section base address and size */
2582 Section = &SectionHeaders[i];
2583 SectionBase = Add2Ptr(ImageBase, Section->VirtualAddress);
2584 SectionSize = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2585
2586 /* Get the first PTE of this section */
2587 FirstPte = MiAddressToPte(SectionBase);
2588
2589 /* Check for overlap with the previous range */
2590 if (FirstPte == LastPte)
2591 {
2592 /* Combine the old and new protection by ORing them */
2593 Protection |= (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2594
2595 /* Update the protection for this PTE */
2596 MiSetSystemCodeProtection(FirstPte, FirstPte, Protection);
2597
2598 /* Skip this PTE */
2599 FirstPte++;
2600 }
2601
2602 /* There can not be gaps! */
2603 NT_ASSERT(FirstPte == (LastPte + 1));
2604
2605 /* Get the end of the section and the last PTE */
2606 SectionEnd = Add2Ptr(SectionBase, SectionSize - 1);
2607 NT_ASSERT(SectionEnd < Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage));
2608 LastPte = MiAddressToPte(SectionEnd);
2609
2610 /* If there are no more pages (after an overlap), skip this section */
2611 if (LastPte < FirstPte)
2612 {
2613 NT_ASSERT(FirstPte == (LastPte + 1));
2614 continue;
2615 }
2616
2617 /* Get the section protection */
2618 Protection = (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2619
2620 /* Update the protection for this section */
2621 MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2622 }
2623
2624 /* Image should end with the last section */
2625 if (ALIGN_UP_POINTER_BY(SectionEnd, PAGE_SIZE) !=
2626 Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage))
2627 {
2628 DPRINT1("ImageBase 0x%p ImageSize 0x%lx Section %u VA 0x%lx Raw 0x%lx virt 0x%lx\n",
2629 ImageBase,
2630 NtHeaders->OptionalHeader.SizeOfImage,
2631 i,
2632 Section->VirtualAddress,
2633 Section->SizeOfRawData,
2634 Section->Misc.VirtualSize);
2635 }
2636}
#define Add2Ptr(PTR, INC)
#define IMAGE_SCN_PROTECTION_MASK
Definition: miarm.h:174
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
WORD MajorOperatingSystemVersion
Definition: ntddk_ex.h:160
BOOLEAN MmEnforceWriteProtection
Definition: sysldr.c:34
VOID NTAPI MiSetSystemCodeProtection(_In_ PMMPTE FirstPte, _In_ PMMPTE LastPte, _In_ ULONG Protection)
Definition: sysldr.c:2484
#define ALIGN_UP_POINTER_BY(ptr, align)
Definition: umtypes.h:85
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress

Referenced by MmInitSystem(), and MmLoadSystemImage().

◆ MmCallDllInitialize()

NTSTATUS NTAPI MmCallDllInitialize ( _In_ PLDR_DATA_TABLE_ENTRY  LdrEntry,
_In_ PLIST_ENTRY  ModuleListHead 
)

Definition at line 464 of file sysldr.c.

467{
469 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
470 PMM_DLL_INITIALIZE DllInit;
471 UNICODE_STRING RegPath, ImportName;
474
475 PAGED_CODE();
476
477 /* Try to see if the image exports a DllInitialize routine */
478 DllInit = (PMM_DLL_INITIALIZE)
479 RtlFindExportedRoutineByName(LdrEntry->DllBase, "DllInitialize");
480 if (!DllInit)
481 return STATUS_SUCCESS;
482
483 /* Make a temporary copy of BaseDllName because we will alter its length */
484 ImportName.Length = LdrEntry->BaseDllName.Length;
485 ImportName.MaximumLength = LdrEntry->BaseDllName.MaximumLength;
486 ImportName.Buffer = LdrEntry->BaseDllName.Buffer;
487
488 /* Obtain the path to this dll's service in the registry */
489 RegPath.MaximumLength = ServicesKeyName.Length +
490 ImportName.Length + sizeof(UNICODE_NULL);
492 RegPath.MaximumLength,
494
495 /* Check if this allocation was unsuccessful */
496 if (!RegPath.Buffer)
498
499 /* Build and append the service name itself */
500 RegPath.Length = ServicesKeyName.Length;
501 RtlCopyMemory(RegPath.Buffer,
502 ServicesKeyName.Buffer,
503 ServicesKeyName.Length);
504
505 /* If the filename has an extension, remove it */
506 Extension = wcschr(ImportName.Buffer, L'.');
507 if (Extension)
508 ImportName.Length = (USHORT)(Extension - ImportName.Buffer) * sizeof(WCHAR);
509
510 /* Append the service name (base name without extension) */
511 RtlAppendUnicodeStringToString(&RegPath, &ImportName);
512
513 /* Now call DllInitialize */
514 DPRINT("Calling DllInit(%wZ)\n", &RegPath);
515 Status = DllInit(&RegPath);
516
517 /* Clean up */
519
520 // TODO: This is for Driver Verifier support.
522
523 /* Return the DllInitialize status value */
524 return Status;
525}
#define wcschr
Definition: compat.h:17
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
LIST_ENTRY * ModuleListHead
Definition: kdpacket.c:23
CONST WCHAR * PCWCH
Definition: ntbasedef.h:423
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
static const WCHAR ServicesKeyName[]
Definition: driver.c:32
NTSTATUS(NTAPI * PMM_DLL_INITIALIZE)(_In_ PUNICODE_STRING RegistryPath)
Definition: iotypes.h:2852

Referenced by IopInitializeBootDrivers(), and MiResolveImageReferences().

◆ MmChangeKernelResourceSectionProtection()

BOOLEAN NTAPI MmChangeKernelResourceSectionProtection ( IN ULONG_PTR  ProtectionMask)

Definition at line 2373 of file sysldr.c.

2374{
2375 PMMPTE PointerPte;
2376 MMPTE TempPte;
2377
2378 /* Don't do anything if the resource section is already writable */
2380 return FALSE;
2381
2382 /* If the resource section is physical, we cannot change its protection */
2384 return FALSE;
2385
2386 /* Loop the PTEs */
2387 for (PointerPte = MiKernelResourceStartPte; PointerPte < MiKernelResourceEndPte; ++PointerPte)
2388 {
2389 /* Read the PTE */
2390 TempPte = *PointerPte;
2391
2392 /* Update the protection */
2393 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, ProtectionMask, TempPte.u.Hard.PageFrameNumber);
2394 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2395 }
2396
2397 /* Only flush the current processor's TLB */
2399 return TRUE;
2400}
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:778
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:535

Referenced by DisplayBootBitmap(), and MmMakeKernelResourceSectionWritable().

◆ MmCheckSystemImage()

NTSTATUS NTAPI MmCheckSystemImage ( _In_ HANDLE  ImageHandle)

Definition at line 2796 of file sysldr.c.

2798{
2800 HANDLE SectionHandle;
2801 PVOID ViewBase = NULL;
2802 SIZE_T ViewSize = 0;
2806 PIMAGE_NT_HEADERS NtHeaders;
2808 PAGED_CODE();
2809
2810 /* Setup the object attributes */
2812 NULL,
2814 NULL,
2815 NULL);
2816
2817 /* Create a section for the DLL */
2818 Status = ZwCreateSection(&SectionHandle,
2821 NULL,
2823 SEC_IMAGE,
2824 ImageHandle);
2825 if (!NT_SUCCESS(Status))
2826 {
2827 DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2828 return Status;
2829 }
2830
2831 /* Make sure we're in the system process */
2833
2834 /* Map it */
2835 Status = ZwMapViewOfSection(SectionHandle,
2837 &ViewBase,
2838 0,
2839 0,
2840 NULL,
2841 &ViewSize,
2842 ViewShare,
2843 0,
2844 PAGE_EXECUTE);
2845 if (!NT_SUCCESS(Status))
2846 {
2847 /* We failed, close the handle and return */
2848 DPRINT1("ZwMapViewOfSection failed with status 0x%x\n", Status);
2850 ZwClose(SectionHandle);
2851 return Status;
2852 }
2853
2854 /* Now query image information */
2855 Status = ZwQueryInformationFile(ImageHandle,
2858 sizeof(FileStandardInfo),
2860 if (NT_SUCCESS(Status))
2861 {
2862 /* First, verify the checksum */
2864 ViewSize,
2866 EndOfFile.LowPart))
2867 {
2868 /* Set checksum failure */
2870 goto Fail;
2871 }
2872
2873 /* Make sure it's a real image */
2874 NtHeaders = RtlImageNtHeader(ViewBase);
2875 if (!NtHeaders)
2876 {
2877 /* Set checksum failure */
2879 goto Fail;
2880 }
2881
2882 /* Make sure it's for the correct architecture */
2883 if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
2885 {
2886 /* Set protection failure */
2888 goto Fail;
2889 }
2890
2891#ifdef CONFIG_SMP
2892 /* Check that the image is safe to use if we have more than one CPU */
2893 if (!MiVerifyImageIsOkForMpUse(NtHeaders))
2894 {
2895 /* Otherwise it's not the right image */
2897 }
2898#endif // CONFIG_SMP
2899 }
2900
2901 /* Unmap the section, close the handle, and return status */
2902Fail:
2903 ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
2905 ZwClose(SectionHandle);
2906 return Status;
2907}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
int Fail
Definition: ehthrow.cxx:24
BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum(_In_ PVOID BaseAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG FileLength)
@ FileStandardInfo
Definition: minwinbase.h:305
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define SEC_IMAGE
Definition: mmtypes.h:97
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1293
#define NtCurrentProcess()
Definition: nt_native.h:1660
@ ViewShare
Definition: nt_native.h:1281
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:100
#define IMAGE_NT_OPTIONAL_HDR_MAGIC
Definition: ntimage.h:387
#define STATUS_IMAGE_CHECKSUM_MISMATCH
Definition: ntstatus.h:799
#define STATUS_IMAGE_MP_UP_MISMATCH
Definition: ntstatus.h:839
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:634
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FileStandardInformation
Definition: propsheet.cpp:61

Referenced by MmLoadSystemImage(), and PsLocateSystemDll().

◆ MmFreeDriverInitialization()

VOID NTAPI MmFreeDriverInitialization ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 1715 of file sysldr.c.

1716{
1717 PMMPTE StartPte, EndPte;
1718 PFN_NUMBER PageCount;
1719 PVOID DllBase;
1720 ULONG i;
1721 PIMAGE_NT_HEADERS NtHeader;
1722 PIMAGE_SECTION_HEADER Section, DiscardSection;
1723
1724 /* Get the base address and the page count */
1725 DllBase = LdrEntry->DllBase;
1726 PageCount = LdrEntry->SizeOfImage >> PAGE_SHIFT;
1727
1728 /* Get the last PTE in this image */
1729 EndPte = MiAddressToPte(DllBase) + PageCount;
1730
1731 /* Get the NT header */
1732 NtHeader = RtlImageNtHeader(DllBase);
1733 if (!NtHeader) return;
1734
1735 /* Get the last section and loop each section backwards */
1736 Section = IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections;
1737 DiscardSection = NULL;
1738 for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
1739 {
1740 /* Go back a section and check if it's discardable */
1741 Section--;
1743 {
1744 /* It is, select it for freeing */
1745 DiscardSection = Section;
1746 }
1747 else
1748 {
1749 /* No more discardable sections exist, bail out */
1750 break;
1751 }
1752 }
1753
1754 /* Bail out if there's nothing to free */
1755 if (!DiscardSection) return;
1756
1757 /* Push the DLL base to the first disacrable section, and get its PTE */
1758 DllBase = (PVOID)ROUND_TO_PAGES((ULONG_PTR)DllBase + DiscardSection->VirtualAddress);
1759 ASSERT(MI_IS_PHYSICAL_ADDRESS(DllBase) == FALSE);
1760 StartPte = MiAddressToPte(DllBase);
1761
1762 /* Check how many pages to free total */
1763 PageCount = (PFN_NUMBER)(EndPte - StartPte);
1764 if (!PageCount) return;
1765
1766 /* Delete this many PTEs */
1767 MiDeleteSystemPageableVm(StartPte, PageCount, 0, NULL);
1768}

Referenced by IopInitializeDriverModule().

◆ MmGetSystemRoutineAddress()

PVOID NTAPI MmGetSystemRoutineAddress ( IN PUNICODE_STRING  SystemRoutineName)

Definition at line 3669 of file sysldr.c.

3670{
3671 PVOID ProcAddress = NULL;
3672 ANSI_STRING AnsiRoutineName;
3674 PLIST_ENTRY NextEntry;
3675 PLDR_DATA_TABLE_ENTRY LdrEntry;
3677 UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
3679 ULONG Modules = 0;
3680
3681 /* Convert routine to ANSI name */
3682 Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName,
3683 SystemRoutineName,
3684 TRUE);
3685 if (!NT_SUCCESS(Status)) return NULL;
3686
3687 /* Lock the list */
3690
3691 /* Loop the loaded module list */
3692 NextEntry = PsLoadedModuleList.Flink;
3693 while (NextEntry != &PsLoadedModuleList)
3694 {
3695 /* Get the entry */
3696 LdrEntry = CONTAINING_RECORD(NextEntry,
3698 InLoadOrderLinks);
3699
3700 /* Check if it's the kernel or HAL */
3701 if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
3702 {
3703 /* Found it */
3704 Found = TRUE;
3705 Modules++;
3706 }
3707 else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
3708 {
3709 /* Found it */
3710 Found = TRUE;
3711 Modules++;
3712 }
3713
3714 /* Check if we found a valid binary */
3715 if (Found)
3716 {
3717 /* Find the procedure name */
3718 ProcAddress = RtlFindExportedRoutineByName(LdrEntry->DllBase,
3719 AnsiRoutineName.Buffer);
3720
3721 /* Break out if we found it or if we already tried both modules */
3722 if (ProcAddress) break;
3723 if (Modules == 2) break;
3724 }
3725
3726 /* Keep looping */
3727 NextEntry = NextEntry->Flink;
3728 }
3729
3730 /* Release the lock */
3733
3734 /* Free the string and return */
3735 RtlFreeAnsiString(&AnsiRoutineName);
3736 return ProcAddress;
3737}
return Found
Definition: dirsup.c:1270
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)

Referenced by _Function_class_(), AuxKlibInitialize(), FxInitializeBugCheckDriverInfo(), FxLibraryCommonCommission(), FxLibraryGlobalsCommission(), FxRegisterBugCheckCallback(), FxRegistrySettingsInitialize(), FxUninitializeBugCheckDriverInfo(), FxUnregisterBugCheckCallback(), KmtGetSystemRoutineAddress(), Mx::MxGetSystemRoutineAddress(), ParaNdis_DebugInitialize(), _FX_DRIVER_TRACKER_CACHE_AWARE::Register(), START_TEST(), TestPrivateFunctions(), and WdmlibRtlIsNtDdiVersionAvailable().

◆ MmLoadSystemImage()

NTSTATUS NTAPI MmLoadSystemImage ( IN PUNICODE_STRING  FileName,
IN PUNICODE_STRING NamePrefix  OPTIONAL,
IN PUNICODE_STRING LoadedName  OPTIONAL,
IN ULONG  Flags,
OUT PVOID ModuleObject,
OUT PVOID ImageBaseAddress 
)

Definition at line 2991 of file sysldr.c.

2997{
2998 PVOID ModuleLoadBase = NULL;
3003 PIMAGE_NT_HEADERS NtHeader;
3004 UNICODE_STRING BaseName, BaseDirectory, PrefixName;
3005 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
3006 ULONG EntrySize, DriverSize = 0;
3007 PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
3008 PCHAR MissingApiName, Buffer;
3009 PWCHAR MissingDriverName, PrefixedBuffer = NULL;
3010 HANDLE SectionHandle;
3012 PSECTION Section = NULL;
3013 BOOLEAN LockOwned = FALSE;
3014 PLIST_ENTRY NextEntry;
3015 IMAGE_INFO ImageInfo;
3016
3017 PAGED_CODE();
3018
3019 /* Detect session-load */
3020 if (Flags)
3021 {
3022 /* Sanity checks */
3023 ASSERT(NamePrefix == NULL);
3024 ASSERT(LoadedName == NULL);
3025
3026 /* Make sure the process is in session too */
3027 if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;
3028 }
3029
3030 /* Allocate a buffer we'll use for names */
3033 TAG_LDR_WSTR);
3035
3036 /* Check for a separator */
3037 if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
3038 {
3039 PWCHAR p;
3040 ULONG BaseLength;
3041
3042 /* Loop the path until we get to the base name */
3043 p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
3044 while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
3045
3046 /* Get the length */
3047 BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
3048 BaseLength *= sizeof(WCHAR);
3049
3050 /* Setup the string */
3051 BaseName.Length = (USHORT)BaseLength;
3052 BaseName.Buffer = p;
3053 }
3054 else
3055 {
3056 /* Otherwise, we already have a base name */
3057 BaseName.Length = FileName->Length;
3058 BaseName.Buffer = FileName->Buffer;
3059 }
3060
3061 /* Setup the maximum length */
3062 BaseName.MaximumLength = BaseName.Length;
3063
3064 /* Now compute the base directory */
3065 BaseDirectory = *FileName;
3066 BaseDirectory.Length -= BaseName.Length;
3067 BaseDirectory.MaximumLength = BaseDirectory.Length;
3068
3069 /* And the prefix, which for now is just the name itself */
3070 PrefixName = *FileName;
3071
3072 /* Check if we have a prefix */
3073 if (NamePrefix)
3074 {
3075 /* Check if "directory + prefix" is too long for the string */
3076 Status = RtlUShortAdd(BaseDirectory.Length,
3077 NamePrefix->Length,
3078 &PrefixName.MaximumLength);
3079 if (!NT_SUCCESS(Status))
3080 {
3082 goto Quickie;
3083 }
3084
3085 /* Check if "directory + prefix + basename" is too long for the string */
3086 Status = RtlUShortAdd(PrefixName.MaximumLength,
3087 BaseName.Length,
3088 &PrefixName.MaximumLength);
3089 if (!NT_SUCCESS(Status))
3090 {
3092 goto Quickie;
3093 }
3094
3095 /* Allocate the buffer exclusively used for prefixed name */
3096 PrefixedBuffer = ExAllocatePoolWithTag(PagedPool,
3097 PrefixName.MaximumLength,
3098 TAG_LDR_WSTR);
3099 if (!PrefixedBuffer)
3100 {
3102 goto Quickie;
3103 }
3104
3105 /* Clear out the prefixed name string */
3106 PrefixName.Buffer = PrefixedBuffer;
3107 PrefixName.Length = 0;
3108
3109 /* Concatenate the strings */
3110 RtlAppendUnicodeStringToString(&PrefixName, &BaseDirectory);
3111 RtlAppendUnicodeStringToString(&PrefixName, NamePrefix);
3112 RtlAppendUnicodeStringToString(&PrefixName, &BaseName);
3113
3114 /* Now the base name of the image becomes the prefixed version */
3115 BaseName.Buffer = &(PrefixName.Buffer[BaseDirectory.Length / sizeof(WCHAR)]);
3116 BaseName.Length += NamePrefix->Length;
3117 BaseName.MaximumLength = (PrefixName.MaximumLength - BaseDirectory.Length);
3118 }
3119
3120 /* Check if we already have a name, use it instead */
3121 if (LoadedName) BaseName = *LoadedName;
3122
3123 /* Check for loader snap debugging */
3125 {
3126 /* Print out standard string */
3127 DPRINT1("MM:SYSLDR Loading %wZ (%wZ) %s\n",
3128 &PrefixName, &BaseName, Flags ? "in session space" : "");
3129 }
3130
3131 /* Acquire the load lock */
3132LoaderScan:
3133 ASSERT(LockOwned == FALSE);
3134 LockOwned = TRUE;
3138 KernelMode,
3139 FALSE,
3140 NULL);
3141
3142 /* Scan the module list */
3143 NextEntry = PsLoadedModuleList.Flink;
3144 while (NextEntry != &PsLoadedModuleList)
3145 {
3146 /* Get the entry and compare the names */
3147 LdrEntry = CONTAINING_RECORD(NextEntry,
3149 InLoadOrderLinks);
3150 if (RtlEqualUnicodeString(&PrefixName, &LdrEntry->FullDllName, TRUE))
3151 {
3152 /* Found it, break out */
3153 break;
3154 }
3155
3156 /* Keep scanning */
3157 NextEntry = NextEntry->Flink;
3158 }
3159
3160 /* Check if we found the image */
3161 if (NextEntry != &PsLoadedModuleList)
3162 {
3163 /* Check if we had already mapped a section */
3164 if (Section)
3165 {
3166 /* Dereference and clear */
3167 ObDereferenceObject(Section);
3168 Section = NULL;
3169 }
3170
3171 /* Check if this was supposed to be a session load */
3172 if (!Flags)
3173 {
3174 /* It wasn't, so just return the data */
3175 *ModuleObject = LdrEntry;
3176 *ImageBaseAddress = LdrEntry->DllBase;
3178 }
3179 else
3180 {
3181 /* We don't support session loading yet */
3182 UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3184 }
3185
3186 /* Do cleanup */
3187 goto Quickie;
3188 }
3189 else if (!Section)
3190 {
3191 /* It wasn't loaded, and we didn't have a previous attempt */
3194 LockOwned = FALSE;
3195
3196 /* Check if KD is enabled */
3198 {
3199 /* FIXME: Attempt to get image from KD */
3200 }
3201
3202 /* We don't have a valid entry */
3203 LdrEntry = NULL;
3204
3205 /* Setup image attributes */
3207 FileName,
3209 NULL,
3210 NULL);
3211
3212 /* Open the image */
3218 0);
3219 if (!NT_SUCCESS(Status))
3220 {
3221 DPRINT1("ZwOpenFile failed for '%wZ' with status 0x%x\n",
3222 FileName, Status);
3223 goto Quickie;
3224 }
3225
3226 /* Validate it */
3231 {
3232 /* Fail loading */
3233 goto Quickie;
3234 }
3235
3236 /* Check if this is a session-load */
3237 if (Flags)
3238 {
3239 /* Then we only need read and execute */
3241 }
3242 else
3243 {
3244 /* Otherwise, we can allow write access */
3246 }
3247
3248 /* Initialize the attributes for the section */
3250 NULL,
3252 NULL,
3253 NULL);
3254
3255 /* Create the section */
3256 Status = ZwCreateSection(&SectionHandle,
3259 NULL,
3261 SEC_IMAGE,
3262 FileHandle);
3263 if (!NT_SUCCESS(Status))
3264 {
3265 DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
3266 goto Quickie;
3267 }
3268
3269 /* Now get the section pointer */
3270 Status = ObReferenceObjectByHandle(SectionHandle,
3273 KernelMode,
3274 (PVOID*)&Section,
3275 NULL);
3276 ZwClose(SectionHandle);
3277 if (!NT_SUCCESS(Status)) goto Quickie;
3278
3279 /* Check if this was supposed to be a session-load */
3280 if (Flags)
3281 {
3282 /* We don't support session loading yet */
3283 UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3284 goto Quickie;
3285 }
3286
3287 /* Check the loader list again, we should end up in the path below */
3288 goto LoaderScan;
3289 }
3290 else
3291 {
3292 /* We don't have a valid entry */
3293 LdrEntry = NULL;
3294 }
3295
3296 /* Load the image */
3297 Status = MiLoadImageSection(&Section,
3298 &ModuleLoadBase,
3299 FileName,
3300 FALSE,
3301 NULL);
3303
3304 /* Get the size of the driver */
3305 DriverSize = ((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize;
3306
3307 /* Make sure we're not being loaded into session space */
3308 if (!Flags)
3309 {
3310 /* Check for success */
3311 if (NT_SUCCESS(Status))
3312 {
3313 /* Support large pages for drivers */
3314 MiUseLargeDriverPage(DriverSize / PAGE_SIZE,
3315 &ModuleLoadBase,
3316 &BaseName,
3317 TRUE);
3318 }
3319
3320 /* Dereference the section */
3321 ObDereferenceObject(Section);
3322 Section = NULL;
3323 }
3324
3325 /* Check for failure of the load earlier */
3326 if (!NT_SUCCESS(Status))
3327 {
3328 DPRINT1("MiLoadImageSection failed with status 0x%x\n", Status);
3329 goto Quickie;
3330 }
3331
3332 /* Relocate the driver */
3333 Status = LdrRelocateImageWithBias(ModuleLoadBase,
3334 0,
3335 "SYSLDR",
3339 if (!NT_SUCCESS(Status))
3340 {
3341 DPRINT1("LdrRelocateImageWithBias failed with status 0x%x\n", Status);
3342 goto Quickie;
3343 }
3344
3345 /* Get the NT Header */
3346 NtHeader = RtlImageNtHeader(ModuleLoadBase);
3347
3348 /* Calculate the size we'll need for the entry and allocate it */
3350 BaseName.Length +
3351 sizeof(UNICODE_NULL);
3352
3353 /* Allocate the entry */
3355 if (!LdrEntry)
3356 {
3357 /* Fail */
3359 goto Quickie;
3360 }
3361
3362 /* Setup the entry */
3363 LdrEntry->Flags = LDRP_LOAD_IN_PROGRESS;
3364 LdrEntry->LoadCount = 1;
3365 LdrEntry->LoadedImports = LoadedImports;
3366 LdrEntry->PatchInformation = NULL;
3367
3368 /* Check the version */
3369 if ((NtHeader->OptionalHeader.MajorOperatingSystemVersion >= 5) &&
3370 (NtHeader->OptionalHeader.MajorImageVersion >= 5))
3371 {
3372 /* Mark this image as a native image */
3373 LdrEntry->Flags |= LDRP_ENTRY_NATIVE;
3374 }
3375
3376 /* Setup the rest of the entry */
3377 LdrEntry->DllBase = ModuleLoadBase;
3378 LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase +
3380 LdrEntry->SizeOfImage = DriverSize;
3381 LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;
3382 LdrEntry->SectionPointer = Section;
3383
3384 /* Now write the DLL name */
3385 LdrEntry->BaseDllName.Buffer = (PVOID)(LdrEntry + 1);
3386 LdrEntry->BaseDllName.Length = BaseName.Length;
3387 LdrEntry->BaseDllName.MaximumLength = BaseName.Length;
3388
3389 /* Copy and null-terminate it */
3391 BaseName.Buffer,
3392 BaseName.Length);
3393 LdrEntry->BaseDllName.Buffer[BaseName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3394
3395 /* Now allocate the full name */
3397 PrefixName.Length +
3398 sizeof(UNICODE_NULL),
3399 TAG_LDR_WSTR);
3400 if (!LdrEntry->FullDllName.Buffer)
3401 {
3402 /* Don't fail, just set it to zero */
3403 LdrEntry->FullDllName.Length = 0;
3404 LdrEntry->FullDllName.MaximumLength = 0;
3405 }
3406 else
3407 {
3408 /* Set it up */
3409 LdrEntry->FullDllName.Length = PrefixName.Length;
3410 LdrEntry->FullDllName.MaximumLength = PrefixName.Length;
3411
3412 /* Copy and null-terminate */
3414 PrefixName.Buffer,
3415 PrefixName.Length);
3416 LdrEntry->FullDllName.Buffer[PrefixName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3417 }
3418
3419 /* Add the entry */
3420 MiProcessLoaderEntry(LdrEntry, TRUE);
3421
3422 /* Resolve imports */
3423 MissingApiName = Buffer;
3424 MissingDriverName = NULL;
3425 Status = MiResolveImageReferences(ModuleLoadBase,
3426 &BaseDirectory,
3427 NULL,
3428 &MissingApiName,
3429 &MissingDriverName,
3430 &LoadedImports);
3431 if (!NT_SUCCESS(Status))
3432 {
3433 BOOLEAN NeedToFreeString = FALSE;
3434
3435 /* If the lowest bit is set to 1, this is a hint that we need to free */
3436 if (*(ULONG_PTR*)&MissingDriverName & 1)
3437 {
3438 NeedToFreeString = TRUE;
3439 *(ULONG_PTR*)&MissingDriverName &= ~1;
3440 }
3441
3442 DPRINT1("MiResolveImageReferences failed with status 0x%x\n", Status);
3443 DPRINT1(" Missing driver '%ls', missing API '%s'\n",
3444 MissingDriverName, MissingApiName);
3445
3446 if (NeedToFreeString)
3447 {
3448 ExFreePoolWithTag(MissingDriverName, TAG_LDR_WSTR);
3449 }
3450
3451 /* Fail */
3452 MiProcessLoaderEntry(LdrEntry, FALSE);
3453
3454 /* Check if we need to free the name */
3455 if (LdrEntry->FullDllName.Buffer)
3456 {
3457 /* Free it */
3459 }
3460
3461 /* Free the entry itself */
3463 LdrEntry = NULL;
3464 goto Quickie;
3465 }
3466
3467 /* Update the loader entry */
3468 LdrEntry->Flags |= (LDRP_SYSTEM_MAPPED |
3471 LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
3472 LdrEntry->LoadedImports = LoadedImports;
3473
3474 /* FIXME: Call driver verifier's loader function */
3475
3476 /* Write-protect the system image */
3478
3479 /* Initialize the security cookie (Win7 is not doing this yet!) */
3480 LdrpInitSecurityCookie(LdrEntry);
3481
3482 /* Check if notifications are enabled */
3484 {
3485 /* Fill out the notification data */
3486 ImageInfo.Properties = 0;
3488 ImageInfo.SystemModeImage = TRUE;
3489 ImageInfo.ImageSize = LdrEntry->SizeOfImage;
3490 ImageInfo.ImageBase = LdrEntry->DllBase;
3491 ImageInfo.ImageSectionNumber = ImageInfo.ImageSelector = 0;
3492
3493 /* Send the notification */
3495 }
3496
3497#ifdef __ROS_ROSSYM__
3498 /* MiCacheImageSymbols doesn't detect rossym */
3499 if (TRUE)
3500#else
3501 /* Check if there's symbols */
3502 if (MiCacheImageSymbols(LdrEntry->DllBase))
3503#endif
3504 {
3505 UNICODE_STRING UnicodeTemp;
3506 STRING AnsiTemp;
3507
3508 /* Check if the system root is present */
3509 if ((PrefixName.Length > (11 * sizeof(WCHAR))) &&
3510 !(_wcsnicmp(PrefixName.Buffer, L"\\SystemRoot", 11)))
3511 {
3512 /* Add the system root */
3513 UnicodeTemp = PrefixName;
3514 UnicodeTemp.Buffer += 11;
3515 UnicodeTemp.Length -= (11 * sizeof(WCHAR));
3518 "%ws%wZ",
3519 &SharedUserData->NtSystemRoot[2],
3520 &UnicodeTemp);
3521 }
3522 else
3523 {
3524 /* Build the name */
3526 "%wZ", &BaseName);
3527 }
3528
3529 /* Setup the ANSI string */
3530 RtlInitString(&AnsiTemp, Buffer);
3531
3532 /* Notify the debugger */
3533 DbgLoadImageSymbols(&AnsiTemp,
3534 LdrEntry->DllBase,
3536 LdrEntry->Flags |= LDRP_DEBUG_SYMBOLS_LOADED;
3537 }
3538
3539 /* Page the driver */
3540 ASSERT(Section == NULL);
3541 MiEnablePagingOfDriver(LdrEntry);
3542
3543 /* Return pointers */
3544 *ModuleObject = LdrEntry;
3545 *ImageBaseAddress = LdrEntry->DllBase;
3546
3547Quickie:
3548 /*
3549 * If we failed after the image had been mapped, tear the mapping down.
3550 * ModuleLoadBase is only set once MiLoadImageSection() has reserved the
3551 * system PTEs for it, and the load lock is still held at that point.
3552 */
3553 if (!NT_SUCCESS(Status) && (ModuleLoadBase != NULL))
3554 {
3555 ASSERT(LockOwned);
3556 MiUnmapSystemImage(ModuleLoadBase, DriverSize);
3557 ModuleLoadBase = NULL;
3558 }
3559
3560 /* Check if we have the lock acquired */
3561 if (LockOwned)
3562 {
3563 /* Release the lock */
3566 LockOwned = FALSE;
3567 }
3568
3569 /* If we have a file handle, close it */
3571
3572 /* If we have allocated a prefixed name buffer, free it */
3573 if (PrefixedBuffer) ExFreePoolWithTag(PrefixedBuffer, TAG_LDR_WSTR);
3574
3575 /* Free the name buffer and return status */
3577 return Status;
3578}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
Definition: bufpool.h:45
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define SECTION_MAP_READ
Definition: compat.h:139
#define FILE_SHARE_READ
Definition: compat.h:136
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:200
struct _FileName FileName
Definition: fatprocs.h:897
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
std::wstring STRING
Definition: fontsub.cpp:33
GLfloat GLfloat p
Definition: glext.h:8902
#define FLG_SHOW_LDR_SNAPS
Definition: pstypes.h:52
#define IMAGE_ADDRESSING_MODE_32BIT
Definition: pstypes.h:194
BOOLEAN KdDebuggerNotPresent
Definition: kddata.c:81
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:82
#define LDRP_DEBUG_SYMBOLS_LOADED
Definition: ldrtypes.h:54
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:48
#define LDRP_ENTRY_NATIVE
Definition: ldrtypes.h:61
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
VOID NTAPI DbgLoadImageSymbols(_In_ PSTRING Name, _In_ PVOID Base, _In_ ULONG_PTR ProcessId)
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1296
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_EXECUTE
Definition: nt_native.h:642
struct _MM_IMAGE_SECTION_OBJECT * PMM_IMAGE_SECTION_OBJECT
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
#define STATUS_IMAGE_ALREADY_LOADED
Definition: ntstatus.h:600
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:363
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:493
BOOLEAN PsImageNotifyEnabled
Definition: psnotify.c:18
FORCEINLINE VOID PspRunLoadImageNotifyRoutines(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo)
Definition: ps_x.h:84
#define SharedUserData
POBJECT_TYPE MmSectionObjectType
Definition: section.c:196
SIZE_T ImageSize
Definition: pstypes.h:209
ULONG SystemModeImage
Definition: pstypes.h:201
ULONG ImageSectionNumber
Definition: pstypes.h:210
PVOID ImageBase
Definition: pstypes.h:207
ULONG Properties
Definition: pstypes.h:198
ULONG ImageAddressingMode
Definition: pstypes.h:200
ULONG ImageSelector
Definition: pstypes.h:208
PVOID SectionPointer
Definition: ntddk_ex.h:213
ULONG CheckSum
Definition: btrfs_drv.h:1886
PVOID PatchInformation
Definition: ldrtypes.h:168
NTSTATUS NTAPI MmCheckSystemImage(_In_ HANDLE ImageHandle)
Definition: sysldr.c:2796
NTSTATUS NTAPI MiResolveImageReferences(IN PVOID ImageBase, IN PUNICODE_STRING ImageFileDirectory, IN PUNICODE_STRING NamePrefix OPTIONAL, OUT PCHAR *MissingApi, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports)
Definition: sysldr.c:1076
PVOID NTAPI LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2948
VOID NTAPI MiWriteProtectSystemImage(_In_ PVOID ImageBase)
Definition: sysldr.c:2523
VOID NTAPI MiEnablePagingOfDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2699
VOID NTAPI MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN BOOLEAN Insert)
Definition: sysldr.c:653
PVOID NTAPI MiCacheImageSymbols(IN PVOID BaseAddress)
Definition: sysldr.c:51
NTSTATUS NTAPI MiLoadImageSection(_Inout_ PSECTION *SectionPtr, _Out_ PVOID *ImageBase, _In_ PUNICODE_STRING FileName, _In_ BOOLEAN SessionLoad, _In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:78
static VOID MiUnmapSystemImage(_In_ PVOID ImageBase, _In_ ULONG ImageSize)
Undoes the mapping performed by MiLoadImageSection(): frees the pages backing the image,...
Definition: sysldr.c:232
LOGICAL NTAPI MiUseLargeDriverPage(IN ULONG NumberOfPtes, IN OUT PVOID *ImageBaseAddress, IN PUNICODE_STRING BaseImageName, IN BOOLEAN BootDriver)
Definition: sysldr.c:2427
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by IopLoadDriver(), MiResolveImageReferences(), and SSI_DEF().

◆ MmMakeKernelResourceSectionWritable()

VOID NTAPI MmMakeKernelResourceSectionWritable ( VOID  )

Definition at line 2404 of file sysldr.c.

2405{
2406 /* Don't do anything if the resource section is already writable */
2408 return;
2409
2410 /* If the resource section is physical, we cannot change its protection */
2412 return;
2413
2415 {
2416 /*
2417 * Invalidate the cached resource section PTEs
2418 * so as to not change its protection again later.
2419 */
2422 }
2423}
#define MM_READWRITE
Definition: bootanim.c:19
BOOLEAN NTAPI MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask)
Definition: sysldr.c:2373

Referenced by KeGetBugMessageText().

◆ MmPageEntireDriver()

PVOID NTAPI MmPageEntireDriver ( IN PVOID  AddressWithinSection)

Definition at line 3622 of file sysldr.c.

3623{
3624 PMMPTE StartPte, EndPte;
3625 PLDR_DATA_TABLE_ENTRY LdrEntry;
3626 PAGED_CODE();
3627
3628 /* Get the loader entry */
3629 LdrEntry = MiLookupDataTableEntry(AddressWithinSection);
3630 if (!LdrEntry) return NULL;
3631
3632 /* Check if paging of kernel mode is disabled or if the driver is mapped as an image */
3633 if ((MmDisablePagingExecutive) || (LdrEntry->SectionPointer))
3634 {
3635 /* Don't do anything, just return the base address */
3636 return LdrEntry->DllBase;
3637 }
3638
3639 /* Wait for active DPCs to finish before we page out the driver */
3640 KeFlushQueuedDpcs();
3641
3642 /* Get the PTE range for the whole driver image */
3643 StartPte = MiAddressToPte((ULONG_PTR)LdrEntry->DllBase);
3644 EndPte = MiAddressToPte((ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage);
3645
3646 /* Enable paging for the PTE range */
3647 ASSERT(MI_IS_SESSION_IMAGE_ADDRESS(AddressWithinSection) == FALSE);
3648 MiSetPagingOfDriver(StartPte, EndPte);
3649
3650 /* Return the base address */
3651 return LdrEntry->DllBase;
3652}
PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry(IN PVOID Address)
Definition: sysldr.c:3582

Referenced by DriverEntry().

◆ MmResetDriverPaging()

VOID NTAPI MmResetDriverPaging ( IN PVOID  AddressWithinSection)

Definition at line 3659 of file sysldr.c.

3660{
3662}
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15

◆ MmUnloadSystemImage()

NTSTATUS NTAPI MmUnloadSystemImage ( IN PVOID  ImageHandle)

Definition at line 976 of file sysldr.c.

977{
978 PLDR_DATA_TABLE_ENTRY LdrEntry = ImageHandle;
979 PVOID BaseAddress = LdrEntry->DllBase;
981 STRING TempName;
982 BOOLEAN HadEntry = FALSE;
983
984 /* Acquire the loader lock */
989 FALSE,
990 NULL);
991
992 /* Check if this driver was loaded at boot and didn't get imports parsed */
993 if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) goto Done;
994
995 /* We should still be alive */
996 ASSERT(LdrEntry->LoadCount != 0);
997 LdrEntry->LoadCount--;
998
999 /* Check if we're still loaded */
1000 if (LdrEntry->LoadCount) goto Done;
1001
1002 /* We should cleanup... are symbols loaded */
1003 if (LdrEntry->Flags & LDRP_DEBUG_SYMBOLS_LOADED)
1004 {
1005 /* Create the ANSI name */
1007 &LdrEntry->BaseDllName,
1008 TRUE);
1009 if (NT_SUCCESS(Status))
1010 {
1011 /* Unload the symbols */
1012 DbgUnLoadImageSymbols(&TempName,
1015 RtlFreeAnsiString(&TempName);
1016 }
1017 }
1018
1019 /*
1020 * Delete the image mapping and return its system PTEs. Only images that
1021 * MiLoadImageSection or MiReloadBootLoadedDrivers put into system PTE
1022 * space can be released this way; the boot drivers that the latter had
1023 * to skip still sit wherever the bootloader placed them.
1024 */
1025 if (LdrEntry->Flags & LDRP_SYSTEM_MAPPED)
1026 {
1027 MiUnmapSystemImage(LdrEntry->DllBase, LdrEntry->SizeOfImage);
1028 }
1029 else
1030 {
1031 DPRINT1("Leaking non system-mapped image: %wZ\n", &LdrEntry->BaseDllName);
1032 }
1033
1034 /* Check if we're linked in */
1035 if (LdrEntry->InLoadOrderLinks.Flink)
1036 {
1037 /* Remove us */
1038 MiProcessLoaderEntry(LdrEntry, FALSE);
1039 HadEntry = TRUE;
1040 }
1041
1042 /* Dereference and clear the imports */
1044 MiClearImports(LdrEntry);
1045
1046 /* Check if the entry needs to go away */
1047 if (HadEntry)
1048 {
1049 /* Check if it had a name */
1050 if (LdrEntry->FullDllName.Buffer)
1051 {
1052 /* Free it */
1054 }
1055
1056 /* Check if we had a section */
1057 if (LdrEntry->SectionPointer)
1058 {
1059 /* Dereference it */
1061 }
1062
1063 /* Free the entry */
1065 }
1066
1067 /* Release the system lock and return */
1068Done:
1071 return STATUS_SUCCESS;
1072}
VOID NTAPI DbgUnLoadImageSymbols(_In_ PSTRING Name, _In_ PVOID Base, _In_ ULONG_PTR ProcessId)
VOID NTAPI MiClearImports(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:633

Referenced by IopDeleteDriver(), IopInitializeDriverModule(), LoadSymbolsRoutine(), MiCallDllUnloadAndUnloadDll(), MiResolveImageReferences(), and SSI_DEF().

◆ NameToOrdinal()

USHORT NTAPI NameToOrdinal ( _In_ PCSTR  ExportName,
_In_ PVOID  ImageBase,
_In_ ULONG  NumberOfNames,
_In_ PULONG  NameTable,
_In_ PUSHORT  OrdinalTable 
)

Definition at line 254 of file sysldr.c.

260{
261 LONG Low, Mid, High, Ret;
262
263 /* Fail if no names */
264 if (!NumberOfNames)
265 return -1;
266
267 /* Do a binary search */
268 Low = Mid = 0;
269 High = NumberOfNames - 1;
270 while (High >= Low)
271 {
272 /* Get new middle value */
273 Mid = (Low + High) >> 1;
274
275 /* Compare name */
276 Ret = strcmp(ExportName, (PCHAR)RVA(ImageBase, NameTable[Mid]));
277 if (Ret < 0)
278 {
279 /* Update high */
280 High = Mid - 1;
281 }
282 else if (Ret > 0)
283 {
284 /* Update low */
285 Low = Mid + 1;
286 }
287 else
288 {
289 /* We got it */
290 break;
291 }
292 }
293
294 /* Check if we couldn't find it */
295 if (High < Low)
296 return -1;
297
298 /* Otherwise, this is the ordinal */
299 return OrdinalTable[Mid];
300}
long LONG
Definition: pedump.c:60
@ High
Definition: strmini.h:378
@ Low
Definition: strmini.h:380
#define RVA(m, b)
Definition: sysldr.c:249

Referenced by MiSnapThunk(), and RtlpFindExportedRoutineByName().

◆ RtlFindExportedRoutineByName()

PVOID NTAPI RtlFindExportedRoutineByName ( _In_ PVOID  ImageBase,
_In_ PCSTR  ExportName 
)

Finds the address of a given named exported routine in a loaded image. Note that this function does not support forwarders.

Parameters
[in]ImageBaseThe base address of the loaded image.
[in]ExportNameThe name of the export, given as an ANSI NULL-terminated string.
Returns
The address of the named exported routine, or NULL if not found. If the export is a forwarder, this function returns NULL as well.
Note
This routine was originally named MiLocateExportName(), with a separate duplicated MiFindExportedRoutineByName() one (taking a PANSI_STRING) on Windows <= 2003. Both routines have been then merged and renamed to MiFindExportedRoutineByName() on Windows 8 (taking a PCSTR instead), and finally renamed and exported as RtlFindExportedRoutineByName() on Windows 10.
See also
https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/mm/sysload/mmgetsystemroutineaddress.htm

Definition at line 432 of file sysldr.c.

435{
437 BOOLEAN IsForwarder = FALSE;
439
440 PAGED_CODE();
441
442 /* Call the internal API */
444 ExportName,
445 &Function,
446 &IsForwarder,
448 if (!NT_SUCCESS(Status))
449 return NULL;
450
451 /* If the export is actually a forwarder, log the error and fail */
452 if (IsForwarder)
453 {
454 DPRINT1("RtlFindExportedRoutineByName does not support forwarders!\n", FALSE);
455 return NULL;
456 }
457
458 /* We've found the export */
459 return Function;
460}
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
#define STATUS_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:643
NTSTATUS NTAPI RtlpFindExportedRoutineByName(_In_ PVOID ImageBase, _In_ PCSTR ExportName, _Out_ PVOID *Function, _Out_opt_ PBOOLEAN IsForwarder, _In_ NTSTATUS NotFoundStatus)
ReactOS-only helper routine for RtlFindExportedRoutineByName(), that provides a finer granularity reg...
Definition: sysldr.c:340

Referenced by init(), MiCallDllUnloadAndUnloadDll(), MmCallDllInitialize(), and MmGetSystemRoutineAddress().

◆ RtlpFindExportedRoutineByName()

NTSTATUS NTAPI RtlpFindExportedRoutineByName ( _In_ PVOID  ImageBase,
_In_ PCSTR  ExportName,
_Out_ PVOID Function,
_Out_opt_ PBOOLEAN  IsForwarder,
_In_ NTSTATUS  NotFoundStatus 
)

ReactOS-only helper routine for RtlFindExportedRoutineByName(), that provides a finer granularity regarding the nature of the export, and the failure reasons.

Parameters
[in]ImageBaseThe base address of the loaded image.
[in]ExportNameThe name of the export, given as an ANSI NULL-terminated string.
[out]FunctionThe address of the named exported routine, or NULL if not found. If the export is a forwarder (see IsForwarder below), this address points to the forwarder name.
[out]IsForwarderAn optional pointer to a BOOLEAN variable, that is set to TRUE if the found export is a forwarder, and FALSE otherwise.
[in]NotFoundStatusThe status code to return in case the export could not be found (examples: STATUS_ENTRYPOINT_NOT_FOUND, STATUS_PROCEDURE_NOT_FOUND).
Returns
A status code as follows:
  • STATUS_SUCCESS if the named exported routine is found;
  • The custom NotFoundStatus if the export could not be found;
  • STATUS_INVALID_PARAMETER if the image is invalid or does not contain an Export Directory.
Note
See RtlFindExportedRoutineByName() for more remarks. Used by psmgr.c PspLookupSystemDllEntryPoint() as well.

Definition at line 340 of file sysldr.c.

346{
347 PIMAGE_EXPORT_DIRECTORY ExportDirectory;
348 PULONG NameTable;
349 PUSHORT OrdinalTable;
350 ULONG ExportSize;
351 USHORT Ordinal;
352 PULONG ExportTable;
353 ULONG_PTR FunctionAddress;
354
355 PAGED_CODE();
356
357 /* Get the export directory */
358 ExportDirectory = RtlImageDirectoryEntryToData(ImageBase,
359 TRUE,
361 &ExportSize);
362 if (!ExportDirectory)
364
365 /* Setup name tables */
366 NameTable = (PULONG)RVA(ImageBase, ExportDirectory->AddressOfNames);
367 OrdinalTable = (PUSHORT)RVA(ImageBase, ExportDirectory->AddressOfNameOrdinals);
368
369 /* Get the ordinal */
370 Ordinal = NameToOrdinal(ExportName,
371 ImageBase,
372 ExportDirectory->NumberOfNames,
373 NameTable,
374 OrdinalTable);
375
376 /* Check if we couldn't find it */
377 if (Ordinal == -1)
378 return NotFoundStatus;
379
380 /* Validate the ordinal */
381 if (Ordinal >= ExportDirectory->NumberOfFunctions)
382 return NotFoundStatus;
383
384 /* Resolve the function's address */
385 ExportTable = (PULONG)RVA(ImageBase, ExportDirectory->AddressOfFunctions);
386 FunctionAddress = (ULONG_PTR)RVA(ImageBase, ExportTable[Ordinal]);
387
388 /* Check if the function is actually a forwarder */
389 if (IsForwarder)
390 {
391 *IsForwarder = FALSE;
392 if ((FunctionAddress > (ULONG_PTR)ExportDirectory) &&
393 (FunctionAddress < (ULONG_PTR)ExportDirectory + ExportSize))
394 {
395 /* It is, and points to the forwarder name */
396 *IsForwarder = TRUE;
397 }
398 }
399
400 /* We've found it */
401 *Function = (PVOID)FunctionAddress;
402 return STATUS_SUCCESS;
403}
DWORD AddressOfNameOrdinals
Definition: compat.h:167

Referenced by CODE_SEG(), and RtlFindExportedRoutineByName().

Variable Documentation

◆ ExPoolCodeEnd

ULONG_PTR ExPoolCodeEnd

Definition at line 37 of file sysldr.c.

Referenced by MiLocateKernelSections().

◆ ExPoolCodeStart

ULONG_PTR ExPoolCodeStart

Definition at line 37 of file sysldr.c.

Referenced by MiLocateKernelSections().

◆ MiKernelResourceEndPte

PMMPTE MiKernelResourceEndPte

◆ MiKernelResourceStartPte

PMMPTE MiKernelResourceStartPte

◆ MmEnforceWriteProtection

BOOLEAN MmEnforceWriteProtection = TRUE

Definition at line 34 of file sysldr.c.

Referenced by MiWriteProtectSystemImage().

◆ MmLastUnloadedDrivers

PVOID MmLastUnloadedDrivers

Definition at line 31 of file sysldr.c.

◆ MmLoadedUserImageList

LIST_ENTRY MmLoadedUserImageList

Definition at line 22 of file sysldr.c.

Referenced by MmArmInitSystem(), and QSI_DEF().

◆ MmMakeLowMemory

BOOLEAN MmMakeLowMemory

Definition at line 33 of file sysldr.c.

◆ MmPoolCodeEnd

ULONG_PTR MmPoolCodeEnd

Definition at line 37 of file sysldr.c.

Referenced by MiLocateKernelSections().

◆ MmPoolCodeStart

ULONG_PTR MmPoolCodeStart

Definition at line 37 of file sysldr.c.

Referenced by MiLocateKernelSections().

◆ MmPteCodeEnd

ULONG_PTR MmPteCodeEnd

Definition at line 38 of file sysldr.c.

Referenced by MiLocateKernelSections().

◆ MmPteCodeStart

ULONG_PTR MmPteCodeStart

Definition at line 38 of file sysldr.c.

Referenced by MiLocateKernelSections().

◆ MmSystemLoadLock

◆ MmTotalSystemDriverPages

PFN_NUMBER MmTotalSystemDriverPages

Definition at line 28 of file sysldr.c.

Referenced by MiSetPagingOfDriver().

◆ MmUnloadedDrivers

PVOID MmUnloadedDrivers

Definition at line 30 of file sysldr.c.

◆ PsLoadedModuleList

◆ PsLoadedModuleResource

◆ PsLoadedModuleSpinLock

KSPIN_LOCK PsLoadedModuleSpinLock

◆ PsNtosImageBase

ULONG_PTR PsNtosImageBase

Definition at line 25 of file sysldr.c.

Referenced by KdInitSystem(), and MiInitializeLoadedModuleList().