ReactOS 0.4.15-dev-7788-g1ad9096
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)
 
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)
 
BOOLEAN NTAPI MmVerifyImageIsOkForMpUse (IN PVOID BaseAddress)
 
NTSTATUS NTAPI MmCheckSystemImage (IN HANDLE ImageHandle, IN BOOLEAN PurgeSection)
 
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 43 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 217 of file sysldr.c.

Function Documentation

◆ LdrpFetchAddressOfSecurityCookie()

PVOID NTAPI LdrpFetchAddressOfSecurityCookie ( PVOID  BaseAddress,
ULONG  SizeOfImage 
)

Definition at line 2858 of file sysldr.c.

2859{
2861 ULONG DirSize;
2862 PVOID Cookie = NULL;
2863
2864 /* Check NT header first */
2865 if (!RtlImageNtHeader(BaseAddress)) return NULL;
2866
2867 /* Get the pointer to the config directory */
2869 TRUE,
2871 &DirSize);
2872
2873 /* Check for sanity */
2874 if (!ConfigDir ||
2875 DirSize < FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY, SEHandlerTable) || /* SEHandlerTable is after SecurityCookie */
2876 (ConfigDir->Size != DirSize))
2877 {
2878 /* Invalid directory*/
2879 return NULL;
2880 }
2881
2882 /* Now get the cookie */
2883 Cookie = (PVOID)ConfigDir->SecurityCookie;
2884
2885 /* Check this cookie */
2887 (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage)
2888 {
2889 Cookie = NULL;
2890 }
2891
2892 /* Return validated security cookie */
2893 return Cookie;
2894}
#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
#define RtlImageNtHeader
Definition: compat.h:806
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
void * PVOID
Definition: typedefs.h:50
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 2898 of file sysldr.c.

2899{
2901 ULONG_PTR NewCookie;
2902
2903 /* Fetch address of the cookie */
2905
2906 if (Cookie)
2907 {
2908 /* Check if it's a default one */
2909 if ((*Cookie == DEFAULT_SECURITY_COOKIE) ||
2910 (*Cookie == 0))
2911 {
2913 /* The address should be unique */
2914 NewCookie = (ULONG_PTR)Cookie;
2915
2916 /* We just need a simple tick, don't care about precision and whatnot */
2917 NewCookie ^= (ULONG_PTR)Counter.LowPart;
2918
2919 /* If the result is 0 or the same as we got, just add one to the default value */
2920 if ((NewCookie == 0) || (NewCookie == *Cookie))
2921 {
2922 NewCookie = DEFAULT_SECURITY_COOKIE + 1;
2923 }
2924
2925 /* Set the new cookie value */
2926 *Cookie = NewCookie;
2927 }
2928 }
2929
2930 return Cookie;
2931}
#define ULONG_PTR
Definition: config.h:101
LARGE_INTEGER NTAPI KeQueryPerformanceCounter(IN PLARGE_INTEGER PerformanceFreq)
Definition: timer.c:138
ULONG SizeOfImage
Definition: ldrtypes.h:143
PVOID DllBase
Definition: btrfs_drv.h:1880
static LARGE_INTEGER Counter
Definition: clock.c:43
#define DEFAULT_SECURITY_COOKIE
Definition: sysldr.c:43
PVOID NTAPI LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: sysldr.c:2858
uint32_t * PULONG_PTR
Definition: typedefs.h:65
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 1919 of file sysldr.c.

1920{
1921 PLIST_ENTRY NextEntry, NextEntry2;
1922 PLDR_DATA_TABLE_ENTRY LdrEntry, KernelEntry, HalEntry, LdrEntry2, LastEntry;
1923 PLDR_DATA_TABLE_ENTRY* EntryArray;
1924 UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
1926 PLOAD_IMPORTS LoadedImports;
1927 ULONG LoadedImportsSize, ImportSize;
1928 PULONG_PTR ImageThunk;
1929 ULONG_PTR DllBase, DllEnd;
1930 ULONG Modules = 0, i, j = 0;
1931 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
1932
1933 /* Initialize variables */
1934 KernelEntry = HalEntry = LastEntry = NULL;
1935
1936 /* Loop the loaded module list... we are early enough that no lock is needed */
1937 NextEntry = PsLoadedModuleList.Flink;
1938 while (NextEntry != &PsLoadedModuleList)
1939 {
1940 /* Get the entry */
1941 LdrEntry = CONTAINING_RECORD(NextEntry,
1943 InLoadOrderLinks);
1944
1945 /* Check if it's the kernel or HAL */
1946 if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
1947 {
1948 /* Found it */
1949 KernelEntry = LdrEntry;
1950 }
1951 else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
1952 {
1953 /* Found it */
1954 HalEntry = LdrEntry;
1955 }
1956
1957 /* Check if this is a driver DLL */
1958 if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1959 {
1960 /* Check if this is the HAL or kernel */
1961 if ((LdrEntry == HalEntry) || (LdrEntry == KernelEntry))
1962 {
1963 /* Add a reference */
1964 LdrEntry->LoadCount = 1;
1965 }
1966 else
1967 {
1968 /* No referencing needed */
1969 LdrEntry->LoadCount = 0;
1970 }
1971 }
1972 else
1973 {
1974 /* Add a reference for all other modules as well */
1975 LdrEntry->LoadCount = 1;
1976 }
1977
1978 /* Remember this came from the loader */
1980
1981 /* Keep looping */
1982 NextEntry = NextEntry->Flink;
1983 Modules++;
1984 }
1985
1986 /* We must have at least found the kernel and HAL */
1987 if (!(HalEntry) || (!KernelEntry)) return STATUS_NOT_FOUND;
1988
1989 /* Allocate the list */
1990 EntryArray = ExAllocatePoolWithTag(PagedPool, Modules * sizeof(PVOID), TAG_LDR_IMPORTS);
1991 if (!EntryArray) return STATUS_INSUFFICIENT_RESOURCES;
1992
1993 /* Loop the loaded module list again */
1994 NextEntry = PsLoadedModuleList.Flink;
1995 while (NextEntry != &PsLoadedModuleList)
1996 {
1997 /* Get the entry */
1998 LdrEntry = CONTAINING_RECORD(NextEntry,
2000 InLoadOrderLinks);
2001#ifdef _WORKING_LOADER_
2002 /* Get its imports */
2003 ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
2004 TRUE,
2006 &ImportSize);
2007 if (!ImageThunk)
2008#else
2009 /* Get its imports */
2010 ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
2011 TRUE,
2013 &ImportSize);
2014 if (!ImportDescriptor)
2015#endif
2016 {
2017 /* None present */
2019 NextEntry = NextEntry->Flink;
2020 continue;
2021 }
2022
2023 /* Clear the list and count the number of IAT thunks */
2024 RtlZeroMemory(EntryArray, Modules * sizeof(PVOID));
2025#ifdef _WORKING_LOADER_
2026 ImportSize /= sizeof(ULONG_PTR);
2027
2028 /* Scan the thunks */
2029 for (i = 0, DllBase = 0, DllEnd = 0; i < ImportSize; i++, ImageThunk++)
2030#else
2031 DllBase = DllEnd = i = 0;
2032 while ((ImportDescriptor->Name) &&
2033 (ImportDescriptor->OriginalFirstThunk))
2034 {
2035 /* Get the image thunk */
2036 ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
2037 ImportDescriptor->FirstThunk);
2038 while (*ImageThunk)
2039#endif
2040 {
2041 /* Do we already have an address? */
2042 if (DllBase)
2043 {
2044 /* Is the thunk in the same address? */
2045 if ((*ImageThunk >= DllBase) && (*ImageThunk < DllEnd))
2046 {
2047 /* Skip it, we already have a reference for it */
2048 ASSERT(EntryArray[j]);
2049 ImageThunk++;
2050 continue;
2051 }
2052 }
2053
2054 /* Loop the loaded module list to locate this address owner */
2055 j = 0;
2056 NextEntry2 = PsLoadedModuleList.Flink;
2057 while (NextEntry2 != &PsLoadedModuleList)
2058 {
2059 /* Get the entry */
2060 LdrEntry2 = CONTAINING_RECORD(NextEntry2,
2062 InLoadOrderLinks);
2063
2064 /* Get the address range for this module */
2065 DllBase = (ULONG_PTR)LdrEntry2->DllBase;
2066 DllEnd = DllBase + LdrEntry2->SizeOfImage;
2067
2068 /* Check if this IAT entry matches it */
2069 if ((*ImageThunk >= DllBase) && (*ImageThunk < DllEnd))
2070 {
2071 /* Save it */
2072 //DPRINT1("Found imported dll: %wZ\n", &LdrEntry2->BaseDllName);
2073 EntryArray[j] = LdrEntry2;
2074 break;
2075 }
2076
2077 /* Keep searching */
2078 NextEntry2 = NextEntry2->Flink;
2079 j++;
2080 }
2081
2082 /* Do we have a thunk outside the range? */
2083 if ((*ImageThunk < DllBase) || (*ImageThunk >= DllEnd))
2084 {
2085 /* Could be 0... */
2086 if (*ImageThunk)
2087 {
2088 /* Should not be happening */
2089 ERROR_FATAL("Broken IAT entry for %p at %p (%lx)\n",
2090 LdrEntry, ImageThunk, *ImageThunk);
2091 }
2092
2093 /* Reset if we hit this */
2094 DllBase = 0;
2095 }
2096#ifndef _WORKING_LOADER_
2097 ImageThunk++;
2098 }
2099
2100 i++;
2101 ImportDescriptor++;
2102#endif
2103 }
2104
2105 /* Now scan how many imports we really have */
2106 for (i = 0, ImportSize = 0; i < Modules; i++)
2107 {
2108 /* Skip HAL and kernel */
2109 if ((EntryArray[i]) &&
2110 (EntryArray[i] != HalEntry) &&
2111 (EntryArray[i] != KernelEntry))
2112 {
2113 /* A valid reference */
2114 LastEntry = EntryArray[i];
2115 ImportSize++;
2116 }
2117 }
2118
2119 /* Do we have any imports after all? */
2120 if (!ImportSize)
2121 {
2122 /* No */
2124 }
2125 else if (ImportSize == 1)
2126 {
2127 /* A single entry import */
2128 LdrEntry->LoadedImports = (PVOID)((ULONG_PTR)LastEntry | MM_SYSLDR_SINGLE_ENTRY);
2129 LastEntry->LoadCount++;
2130 }
2131 else
2132 {
2133 /* We need an import table */
2134 LoadedImportsSize = ImportSize * sizeof(PVOID) + sizeof(SIZE_T);
2135 LoadedImports = ExAllocatePoolWithTag(PagedPool,
2136 LoadedImportsSize,
2138 ASSERT(LoadedImports);
2139
2140 /* Save the count */
2141 LoadedImports->Count = ImportSize;
2142
2143 /* Now copy all imports */
2144 for (i = 0, j = 0; i < Modules; i++)
2145 {
2146 /* Skip HAL and kernel */
2147 if ((EntryArray[i]) &&
2148 (EntryArray[i] != HalEntry) &&
2149 (EntryArray[i] != KernelEntry))
2150 {
2151 /* A valid reference */
2152 //DPRINT1("Found valid entry: %p\n", EntryArray[i]);
2153 LoadedImports->Entry[j] = EntryArray[i];
2154 EntryArray[i]->LoadCount++;
2155 j++;
2156 }
2157 }
2158
2159 /* Should had as many entries as we expected */
2160 ASSERT(j == ImportSize);
2161 LdrEntry->LoadedImports = LoadedImports;
2162 }
2163
2164 /* Next */
2165 NextEntry = NextEntry->Flink;
2166 }
2167
2168 /* Free the initial array */
2170
2171 /* FIXME: Might not need to keep the HAL/Kernel imports around */
2172
2173 /* Kernel and HAL are loaded at boot */
2174 KernelEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
2176
2177 /* All worked well */
2178 return STATUS_SUCCESS;
2179}
#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:56
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:200
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:201
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:202
#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 L(x)
Definition: ntvdm.h:50
#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:161
ULONG Flags
Definition: ntddk_ex.h:207
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
SIZE_T Count
Definition: ldrtypes.h:172
PLDR_DATA_TABLE_ENTRY Entry[1]
Definition: ldrtypes.h:173
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
#define TAG_LDR_IMPORTS
Definition: tag.h:103
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
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 50 of file sysldr.c.

51{
52 ULONG DebugSize;
53 PVOID DebugDirectory = NULL;
54 PAGED_CODE();
55
56 /* Make sure it's safe to access the image */
58 {
59 /* Get the debug directory */
61 TRUE,
63 &DebugSize);
64 }
66 {
67 /* Nothing */
68 }
70
71 /* Return the directory */
72 return DebugDirectory;
73}
#define PAGED_CODE()
#define IMAGE_DIRECTORY_ENTRY_DEBUG
Definition: compat.h:152
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34

Referenced by MmLoadSystemImage().

◆ MiCallDllUnloadAndUnloadDll()

BOOLEAN MiCallDllUnloadAndUnloadDll ( _In_ PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 496 of file sysldr.c.

498{
501
502 PAGED_CODE();
503
504 /* Retrieve the DllUnload routine */
506 RtlFindExportedRoutineByName(LdrEntry->DllBase, "DllUnload");
507 if (!DllUnload)
508 return FALSE;
509
510 /* Call it and check for success */
511 Status = DllUnload();
512 if (!NT_SUCCESS(Status))
513 return FALSE;
514
515 /* Lie about the load count so we can unload the image */
516 ASSERT(LdrEntry->LoadCount == 0);
517 LdrEntry->LoadCount = 1;
518
519 /* Unload it */
520 MmUnloadSystemImage(LdrEntry);
521 return TRUE;
522}
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG NTAPI DllUnload()
Definition: dll.cpp:28
Status
Definition: gdiplustypes.h:25
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:944
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:400
NTSTATUS(NTAPI * PMM_DLL_UNLOAD)(VOID)
Definition: iotypes.h:2854

Referenced by MiDereferenceImports().

◆ MiClearImports()

VOID NTAPI MiClearImports ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 601 of file sysldr.c.

602{
603 PAGED_CODE();
604
605 /* Check if there's no imports or we're a boot driver or only one entry */
606 if ((LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) ||
607 (LdrEntry->LoadedImports == MM_SYSLDR_NO_IMPORTS) ||
608 ((ULONG_PTR)LdrEntry->LoadedImports & MM_SYSLDR_SINGLE_ENTRY))
609 {
610 /* Nothing to do */
611 return;
612 }
613
614 /* Otherwise, free the import list */
615 ExFreePoolWithTag(LdrEntry->LoadedImports, TAG_LDR_IMPORTS);
616 LdrEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
617}

Referenced by MmUnloadSystemImage().

◆ MiDereferenceImports()

NTSTATUS NTAPI MiDereferenceImports ( IN PLOAD_IMPORTS  ImportList)

Definition at line 526 of file sysldr.c.

527{
528 SIZE_T i;
529 LOAD_IMPORTS SingleEntry;
530 PLDR_DATA_TABLE_ENTRY LdrEntry;
531 PVOID CurrentImports;
532 PAGED_CODE();
533
534 /* Check if there's no imports or if we're a boot driver */
535 if ((ImportList == MM_SYSLDR_NO_IMPORTS) ||
536 (ImportList == MM_SYSLDR_BOOT_LOADED) ||
537 (ImportList->Count == 0))
538 {
539 /* Then there's nothing to do */
540 return STATUS_SUCCESS;
541 }
542
543 /* Check for single-entry */
544 if ((ULONG_PTR)ImportList & MM_SYSLDR_SINGLE_ENTRY)
545 {
546 /* Set it up */
547 SingleEntry.Count = 1;
548 SingleEntry.Entry[0] = (PVOID)((ULONG_PTR)ImportList &~ MM_SYSLDR_SINGLE_ENTRY);
549
550 /* Use this as the import list */
551 ImportList = &SingleEntry;
552 }
553
554 /* Loop the import list */
555 for (i = 0; (i < ImportList->Count) && (ImportList->Entry[i]); i++)
556 {
557 /* Get the entry */
558 LdrEntry = ImportList->Entry[i];
559 DPRINT1("%wZ <%wZ>\n", &LdrEntry->FullDllName, &LdrEntry->BaseDllName);
560
561 /* Skip boot loaded images */
562 if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) continue;
563
564 /* Dereference the entry */
565 ASSERT(LdrEntry->LoadCount >= 1);
566 if (!--LdrEntry->LoadCount)
567 {
568 /* Save the import data in case unload fails */
569 CurrentImports = LdrEntry->LoadedImports;
570
571 /* This is the last entry */
573 if (MiCallDllUnloadAndUnloadDll(LdrEntry))
574 {
575 /* Unloading worked, parse this DLL's imports too */
576 MiDereferenceImports(CurrentImports);
577
578 /* Check if we had valid imports */
579 if ((CurrentImports != MM_SYSLDR_BOOT_LOADED) &&
580 (CurrentImports != MM_SYSLDR_NO_IMPORTS) &&
581 !((ULONG_PTR)CurrentImports & MM_SYSLDR_SINGLE_ENTRY))
582 {
583 /* Free them */
584 ExFreePoolWithTag(CurrentImports, TAG_LDR_IMPORTS);
585 }
586 }
587 else
588 {
589 /* Unload failed, restore imports */
590 LdrEntry->LoadedImports = CurrentImports;
591 }
592 }
593 }
594
595 /* Done */
596 return STATUS_SUCCESS;
597}
#define DPRINT1
Definition: precomp.h:8
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:526
BOOLEAN MiCallDllUnloadAndUnloadDll(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:496

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

◆ MiEnablePagingOfDriver()

VOID NTAPI MiEnablePagingOfDriver ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2656 of file sysldr.c.

2657{
2658 ULONG_PTR ImageBase;
2659 PIMAGE_NT_HEADERS NtHeaders;
2660 ULONG Sections, Alignment, Size;
2661 PIMAGE_SECTION_HEADER Section;
2662 PMMPTE PointerPte = NULL, LastPte = NULL;
2663 if (MmDisablePagingExecutive) return;
2664
2665 /* Get the driver base address and its NT header */
2666 ImageBase = (ULONG_PTR)LdrEntry->DllBase;
2667 NtHeaders = RtlImageNtHeader((PVOID)ImageBase);
2668 if (!NtHeaders) return;
2669
2670 /* Get the sections and their alignment */
2671 Sections = NtHeaders->FileHeader.NumberOfSections;
2672 Alignment = NtHeaders->OptionalHeader.SectionAlignment - 1;
2673
2674 /* Loop each section */
2675 Section = IMAGE_FIRST_SECTION(NtHeaders);
2676 while (Sections)
2677 {
2678 /* Find PAGE or .edata */
2679 if ((*(PULONG)Section->Name == 'EGAP') ||
2680 (*(PULONG)Section->Name == 'ade.'))
2681 {
2682 /* Had we already done some work? */
2683 if (!PointerPte)
2684 {
2685 /* Nope, setup the first PTE address */
2686 PointerPte = MiAddressToPte(ROUND_TO_PAGES(ImageBase +
2687 Section->VirtualAddress));
2688 }
2689
2690 /* Compute the size */
2691 Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2692
2693 /* Find the last PTE that maps this section */
2694 LastPte = MiAddressToPte(ImageBase +
2695 Section->VirtualAddress +
2697 }
2698 else
2699 {
2700 /* Had we found a section before? */
2701 if (PointerPte)
2702 {
2703 /* Mark it as pageable */
2704 MiSetPagingOfDriver(PointerPte, LastPte);
2705 PointerPte = NULL;
2706 }
2707 }
2708
2709 /* Keep searching */
2710 Sections--;
2711 Section++;
2712 }
2713
2714 /* Handle the straggler */
2715 if (PointerPte) MiSetPagingOfDriver(PointerPte, LastPte);
2716}
#define PAGE_SIZE
Definition: env_spec_w32.h:49
union Alignment_ Alignment
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
UCHAR MmDisablePagingExecutive
Definition: mminit.c:25
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
union _IMAGE_SECTION_HEADER::@1555 Misc
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
#define max(a, b)
Definition: svc.c:63
VOID NTAPI MiSetPagingOfDriver(IN PMMPTE PointerPte, IN PMMPTE LastPte)
Definition: sysldr.c:2597
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:4533
#define ROUND_TO_PAGES(Size)

Referenced by MmLoadSystemImage().

◆ MiFindInitializationCode()

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

Definition at line 1487 of file sysldr.c.

1489{
1490 ULONG Size, SectionCount, Alignment;
1491 PLDR_DATA_TABLE_ENTRY LdrEntry;
1492 ULONG_PTR DllBase, InitStart, InitEnd, ImageEnd, InitCode;
1493 PLIST_ENTRY NextEntry;
1494 PIMAGE_NT_HEADERS NtHeader;
1495 PIMAGE_SECTION_HEADER Section, LastSection, InitSection;
1496 BOOLEAN InitFound;
1498
1499 /* So we don't free our own code yet */
1501
1502 /* Assume failure */
1503 *StartVa = NULL;
1504
1505 /* Acquire the necessary locks while we loop the list */
1509 KernelMode,
1510 FALSE,
1511 NULL);
1513
1514 /* Loop all loaded modules */
1515 NextEntry = PsLoadedModuleList.Flink;
1516 while (NextEntry != &PsLoadedModuleList)
1517 {
1518 /* Get the loader entry and its DLL base */
1519 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1520 DllBase = (ULONG_PTR)LdrEntry->DllBase;
1521
1522 /* Only process boot loaded images. Other drivers are processed by
1523 MmFreeDriverInitialization */
1524 if (LdrEntry->Flags & LDRP_MM_LOADED)
1525 {
1526 /* Keep going */
1527 NextEntry = NextEntry->Flink;
1528 continue;
1529 }
1530
1531 /* Get the NT header */
1532 NtHeader = RtlImageNtHeader((PVOID)DllBase);
1533 if (!NtHeader)
1534 {
1535 /* Keep going */
1536 NextEntry = NextEntry->Flink;
1537 continue;
1538 }
1539
1540 /* Get the first section, the section count, and scan them all */
1541 Section = IMAGE_FIRST_SECTION(NtHeader);
1542 SectionCount = NtHeader->FileHeader.NumberOfSections;
1543 InitStart = 0;
1544 while (SectionCount > 0)
1545 {
1546 /* Assume failure */
1547 InitFound = FALSE;
1548
1549 /* Is this the INIT section or a discardable section? */
1550 if ((strncmp((PCCH)Section->Name, "INIT", 5) == 0) ||
1552 {
1553 /* Remember this */
1554 InitFound = TRUE;
1555 InitSection = Section;
1556 }
1557
1558 if (InitFound)
1559 {
1560 /* Pick the biggest size -- either raw or virtual */
1561 Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
1562
1563 /* Read the section alignment */
1565
1566 /* Get the start and end addresses */
1567 InitStart = DllBase + Section->VirtualAddress;
1568 InitEnd = ALIGN_UP_BY(InitStart + Size, Alignment);
1569
1570 /* Align the addresses to PAGE_SIZE */
1571 InitStart = ALIGN_UP_BY(InitStart, PAGE_SIZE);
1572 InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1573
1574 /* Have we reached the last section? */
1575 if (SectionCount == 1)
1576 {
1577 /* Remember this */
1578 LastSection = Section;
1579 }
1580 else
1581 {
1582 /* We have not, loop all the sections */
1583 LastSection = NULL;
1584 do
1585 {
1586 /* Keep going until we find a non-discardable section range */
1587 SectionCount--;
1588 Section++;
1590 {
1591 /* Discardable, so record it, then keep going */
1592 LastSection = Section;
1593 }
1594 else
1595 {
1596 /* Non-contigous discard flag, or no flag, break out */
1597 break;
1598 }
1599 }
1600 while (SectionCount > 1);
1601 }
1602
1603 /* Have we found a discardable or init section? */
1604 if (LastSection)
1605 {
1606 /* Pick the biggest size -- either raw or virtual */
1607 Size = max(LastSection->SizeOfRawData, LastSection->Misc.VirtualSize);
1608
1609 /* Use this as the end of the section address */
1610 InitEnd = DllBase + LastSection->VirtualAddress + Size;
1611
1612 /* Have we reached the last section yet? */
1613 if (SectionCount != 1)
1614 {
1615 /* Then align this accross the session boundary */
1616 InitEnd = ALIGN_UP_BY(InitEnd, Alignment);
1617 InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1618 }
1619 }
1620
1621 /* Make sure we don't let the init section go past the image */
1622 ImageEnd = DllBase + LdrEntry->SizeOfImage;
1623 if (InitEnd > ImageEnd) InitEnd = ALIGN_UP_BY(ImageEnd, PAGE_SIZE);
1624
1625 /* Make sure we have a valid, non-zero init section */
1626 if (InitStart < InitEnd)
1627 {
1628 /* Make sure we are not within this code itself */
1629 if ((InitCode >= InitStart) && (InitCode < InitEnd))
1630 {
1631 /* Return it, we can't free ourselves now */
1632 ASSERT(*StartVa == 0);
1633 *StartVa = (PVOID)InitStart;
1634 *EndVa = (PVOID)InitEnd;
1635 }
1636 else
1637 {
1638 /* This isn't us -- go ahead and free it */
1639 ASSERT(MI_IS_PHYSICAL_ADDRESS((PVOID)InitStart) == FALSE);
1640 DPRINT("Freeing init code: %p-%p ('%wZ' @%p : '%s')\n",
1641 (PVOID)InitStart,
1642 (PVOID)InitEnd,
1643 &LdrEntry->BaseDllName,
1644 LdrEntry->DllBase,
1645 InitSection->Name);
1646 MiFreeInitializationCode((PVOID)InitStart, (PVOID)InitEnd);
1647 }
1648 }
1649 }
1650
1651 /* Move to the next section */
1652 SectionCount--;
1653 Section++;
1654 }
1655
1656 /* Move to the next module */
1657 NextEntry = NextEntry->Flink;
1658 }
1659
1660 /* Release the locks and return */
1664}
#define ALIGN_DOWN_BY(size, align)
#define ALIGN_UP_BY(size, align)
unsigned char BOOLEAN
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#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:60
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:945
#define KernelMode
Definition: asm.h:34
#define MUTANT_INCREMENT
Definition: extypes.h:84
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:319
CONST CHAR * PCCH
Definition: ntbasedef.h:392
#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:71
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1487
VOID NTAPI MiFreeInitializationCode(IN PVOID InitStart, IN PVOID InitEnd)
Definition: sysldr.c:1464
KMUTANT MmSystemLoadLock
Definition: sysldr.c:26
@ WrVirtualMemory
Definition: ketypes.h:433

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiFreeInitializationCode()

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

Definition at line 1464 of file sysldr.c.

1466{
1467 PMMPTE PointerPte;
1468 PFN_NUMBER PagesFreed;
1469
1470 /* Get the start PTE */
1471 PointerPte = MiAddressToPte(InitStart);
1472 ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE);
1473
1474 /* Compute the number of pages we expect to free */
1475 PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte);
1476
1477 /* Try to actually free them */
1478 PagesFreed = MiDeleteSystemPageableVm(PointerPte,
1479 PagesFreed,
1480 0,
1481 NULL);
1482}
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
ULONG PFN_NUMBER
Definition: ke.h:9

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiInitializeLoadedModuleList()

BOOLEAN NTAPI MiInitializeLoadedModuleList ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 2241 of file sysldr.c.

2242{
2243 PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
2244 PLIST_ENTRY ListHead, NextEntry;
2246
2247 /* Setup the loaded module list and locks */
2251
2252 /* Get loop variables and the kernel entry */
2253 ListHead = &LoaderBlock->LoadOrderListHead;
2254 NextEntry = ListHead->Flink;
2255 LdrEntry = CONTAINING_RECORD(NextEntry,
2257 InLoadOrderLinks);
2258 PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
2259
2260 /* Locate resource section, pool code, and system pte code */
2261 MiLocateKernelSections(LdrEntry);
2262
2263 /* Loop the loader block */
2264 while (NextEntry != ListHead)
2265 {
2266 /* Get the loader entry */
2267 LdrEntry = CONTAINING_RECORD(NextEntry,
2269 InLoadOrderLinks);
2270
2271 /* FIXME: ROS HACK. Make sure this is a driver */
2272 if (!RtlImageNtHeader(LdrEntry->DllBase))
2273 {
2274 /* Skip this entry */
2275 NextEntry = NextEntry->Flink;
2276 continue;
2277 }
2278
2279 /* Calculate the size we'll need and allocate a copy */
2281 LdrEntry->BaseDllName.MaximumLength +
2282 sizeof(UNICODE_NULL);
2284 if (!NewEntry) return FALSE;
2285
2286 /* Copy the entry over */
2287 *NewEntry = *LdrEntry;
2288
2289 /* Allocate the name */
2290 NewEntry->FullDllName.Buffer =
2292 LdrEntry->FullDllName.MaximumLength +
2293 sizeof(UNICODE_NULL),
2294 TAG_LDR_WSTR);
2295 if (!NewEntry->FullDllName.Buffer)
2296 {
2298 return FALSE;
2299 }
2300
2301 /* Set the base name */
2302 NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
2303
2304 /* Copy the full and base name */
2306 LdrEntry->FullDllName.Buffer,
2307 LdrEntry->FullDllName.MaximumLength);
2309 LdrEntry->BaseDllName.Buffer,
2310 LdrEntry->BaseDllName.MaximumLength);
2311
2312 /* Null-terminate the base name */
2313 NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
2314 sizeof(WCHAR)] = UNICODE_NULL;
2315
2316 /* Insert the entry into the list */
2318 NextEntry = NextEntry->Flink;
2319 }
2320
2321 /* Build the import lists for the boot drivers */
2323
2324 /* We're done */
2325 return TRUE;
2326}
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
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSTATUS NTAPI MiBuildImportsForBootDrivers(VOID)
Definition: sysldr.c:1919
VOID NTAPI MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2184
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
__wchar_t WCHAR
Definition: xmlstorage.h:180

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 77 of file sysldr.c.

82{
83 PSECTION Section = *SectionPtr;
86 PVOID Base = NULL;
87 SIZE_T ViewSize = 0;
91 PFN_COUNT PteCount;
92 PMMPTE PointerPte, LastPte;
93 PVOID DriverBase;
96 PFN_NUMBER PageFrameIndex;
97 PAGED_CODE();
98
99 /* Detect session load */
100 if (SessionLoad)
101 {
102 /* Fail */
103 UNIMPLEMENTED_DBGBREAK("Session loading not yet supported!\n");
105 }
106
107 /* Not session load, shouldn't have an entry */
108 ASSERT(LdrEntry == NULL);
109
110 /* Attach to the system process */
112
113 /* Check if we need to load symbols */
115 {
116 /* Yes we do */
118 NtGlobalFlag &= ~FLG_ENABLE_KDEBUG_SYMBOL_LOAD;
119 }
120
121 /* Map the driver */
123 Status = MmMapViewOfSection(Section,
124 Process,
125 &Base,
126 0,
127 0,
129 &ViewSize,
130 ViewUnmap,
131 0,
133
134 /* Re-enable the flag */
136
137 /* Check if we failed with distinguished status code */
139 {
140 /* Change it to something more generic */
142 }
143
144 /* Now check if we failed */
145 if (!NT_SUCCESS(Status))
146 {
147 /* Detach and return */
148 DPRINT1("MmMapViewOfSection failed with status 0x%x\n", Status);
150 return Status;
151 }
152
153 /* Reserve system PTEs needed */
154 PteCount = ROUND_TO_PAGES(((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize) >> PAGE_SHIFT;
155 PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
156 if (!PointerPte)
157 {
158 DPRINT1("MiReserveSystemPtes failed\n");
161 }
162
163 /* New driver base */
164 LastPte = PointerPte + PteCount;
165 DriverBase = MiPteToAddress(PointerPte);
166
167 /* The driver is here */
168 *ImageBase = DriverBase;
169 DPRINT1("Loading: %wZ at %p with %lx pages\n", FileName, DriverBase, PteCount);
170
171 /* Lock the PFN database */
172 OldIrql = MiAcquirePfnLock();
173
174 /* Loop the new driver PTEs */
176 while (PointerPte < LastPte)
177 {
178 /* Make sure the PTE is not valid for whatever reason */
179 ASSERT(PointerPte->u.Hard.Valid == 0);
180
181 /* Some debug stuff */
183#if MI_TRACE_PFNS
184 MI_SET_PROCESS_USTR(FileName);
185#endif
186
187 /* Grab a page */
188 PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
189
190 /* Initialize its PFN entry */
191 MiInitializePfn(PageFrameIndex, PointerPte, TRUE);
192
193 /* Write the PTE */
194 TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
195 MI_WRITE_VALID_PTE(PointerPte, TempPte);
196
197 /* Move on */
198 PointerPte++;
199 }
200
201 /* Release the PFN lock */
202 MiReleasePfnLock(OldIrql);
203
204 /* Copy the image */
205 RtlCopyMemory(DriverBase, Base, PteCount << PAGE_SHIFT);
206
207 /* Now unmap the view */
210
211 /* Detach and return status */
213 return Status;
214}
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3117
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#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:73
static BOOLEAN LoadSymbols
Definition: kdb_symbols.c:30
@ SystemPteSpace
Definition: miarm.h:403
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:232
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:959
VOID NTAPI MiInitializePfn(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN BOOLEAN Modified)
Definition: pfnlist.c:970
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:407
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2439
#define PAGE_EXECUTE
Definition: nt_native.h:1306
@ ViewUnmap
Definition: nt_native.h:1279
ULONG NtGlobalFlag
Definition: init.c:54
#define MiPteToAddress(_Pte)
Definition: mm.h:116
@ MI_USAGE_DRIVER_PAGE
Definition: mm.h:337
#define MI_SET_USAGE(x)
Definition: mm.h:317
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765
MMPTE ValidKernelPte
Definition: init.c:29
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH
Definition: ntstatus.h:128
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
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, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3996
KPROCESS Pcb
Definition: pstypes.h:1262
ULONG PageFrameNumber
Definition: mmtypes.h:109
ULONG64 Valid
Definition: mmtypes.h:150
union _MMPTE::@2325 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:1409
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 2184 of file sysldr.c.

2185{
2186 ULONG_PTR DllBase;
2187 PIMAGE_NT_HEADERS NtHeaders;
2188 PIMAGE_SECTION_HEADER SectionHeader;
2189 ULONG Sections, Size;
2190
2191 /* Get the kernel section header */
2192 DllBase = (ULONG_PTR)LdrEntry->DllBase;
2193 NtHeaders = RtlImageNtHeader((PVOID)DllBase);
2194 SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
2195
2196 /* Loop all the sections */
2197 for (Sections = NtHeaders->FileHeader.NumberOfSections;
2198 Sections > 0; --Sections, ++SectionHeader)
2199 {
2200 /* Grab the size of the section */
2201 Size = max(SectionHeader->SizeOfRawData, SectionHeader->Misc.VirtualSize);
2202
2203 /* Check for .RSRC section */
2204 if (*(PULONG)SectionHeader->Name == 'rsr.')
2205 {
2206 /* Remember the PTEs so we can modify them later */
2208 SectionHeader->VirtualAddress);
2210 SectionHeader->VirtualAddress + Size));
2211 }
2212 else if (*(PULONG)SectionHeader->Name == 'LOOP')
2213 {
2214 /* POOLCODE vs. POOLMI */
2215 if (*(PULONG)&SectionHeader->Name[4] == 'EDOC')
2216 {
2217 /* Found Ex* Pool code */
2218 ExPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2220 }
2221 else if (*(PUSHORT)&SectionHeader->Name[4] == 'MI')
2222 {
2223 /* Found Mm* Pool code */
2224 MmPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2226 }
2227 }
2228 else if ((*(PULONG)SectionHeader->Name == 'YSIM') &&
2229 (*(PULONG)&SectionHeader->Name[4] == 'ETPS'))
2230 {
2231 /* Found MISYSPTE (Mm System PTE code) */
2232 MmPteCodeStart = DllBase + SectionHeader->VirtualAddress;
2234 }
2235 }
2236}
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 3514 of file sysldr.c.

3515{
3516 PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL;
3517 PLIST_ENTRY NextEntry;
3518 PAGED_CODE();
3519
3520 /* Loop entries */
3521 NextEntry = PsLoadedModuleList.Flink;
3522 do
3523 {
3524 /* Get the loader entry */
3525 LdrEntry = CONTAINING_RECORD(NextEntry,
3527 InLoadOrderLinks);
3528
3529 /* Check if the address matches */
3530 if ((Address >= LdrEntry->DllBase) &&
3531 (Address < (PVOID)((ULONG_PTR)LdrEntry->DllBase +
3532 LdrEntry->SizeOfImage)))
3533 {
3534 /* Found a match */
3535 FoundEntry = LdrEntry;
3536 break;
3537 }
3538
3539 /* Move on */
3540 NextEntry = NextEntry->Flink;
3541 } while(NextEntry != &PsLoadedModuleList);
3542
3543 /* Return the entry */
3544 return FoundEntry;
3545}
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 621 of file sysldr.c.

623{
625
626 /* Acquire module list lock */
629
630 /* Acquire the spinlock too as we will insert or remove the entry */
632
633 /* Insert or remove from the list */
634 if (Insert)
635 InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks);
636 else
637 RemoveEntryList(&LdrEntry->InLoadOrderLinks);
638
639 /* Release locks */
643}
#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 1730 of file sysldr.c.

1731{
1732 PLIST_ENTRY NextEntry;
1733 ULONG i = 0;
1734 PIMAGE_NT_HEADERS NtHeader;
1735 PLDR_DATA_TABLE_ENTRY LdrEntry;
1736 PIMAGE_FILE_HEADER FileHeader;
1737 BOOLEAN ValidRelocs;
1738 PIMAGE_DATA_DIRECTORY DataDirectory;
1739 PVOID DllBase, NewImageAddress;
1741 PMMPTE PointerPte, StartPte, LastPte;
1742 PFN_COUNT PteCount;
1743 PMMPFN Pfn1;
1744 MMPTE TempPte, OldPte;
1745
1746 /* Loop driver list */
1747 for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
1748 NextEntry != &LoaderBlock->LoadOrderListHead;
1749 NextEntry = NextEntry->Flink)
1750 {
1751 /* Get the loader entry and NT header */
1752 LdrEntry = CONTAINING_RECORD(NextEntry,
1754 InLoadOrderLinks);
1755 NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
1756
1757 /* Debug info */
1758 DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",
1759 LdrEntry->DllBase,
1760 (ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage,
1761 &LdrEntry->FullDllName);
1762
1763 /* Get the first PTE and the number of PTEs we'll need */
1764 PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
1765 PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
1766 LastPte = StartPte + PteCount;
1767
1768#if MI_TRACE_PFNS
1769 /* Loop the PTEs */
1770 while (PointerPte < LastPte)
1771 {
1772 ULONG len;
1773 ASSERT(PointerPte->u.Hard.Valid == 1);
1774 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1775 len = wcslen(LdrEntry->BaseDllName.Buffer) * sizeof(WCHAR);
1776 snprintf(Pfn1->ProcessName, min(16, len), "%S", LdrEntry->BaseDllName.Buffer);
1777 PointerPte++;
1778 }
1779#endif
1780 /* Skip kernel and HAL */
1781 /* ROS HACK: Skip BOOTVID/KDCOM too */
1782 i++;
1783 if (i <= 4) continue;
1784
1785 /* Skip non-drivers */
1786 if (!NtHeader) continue;
1787
1788 /* Get the file header and make sure we can relocate */
1789 FileHeader = &NtHeader->FileHeader;
1790 if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;
1791 if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <
1793
1794 /* Everything made sense until now, check the relocation section too */
1795 DataDirectory = &NtHeader->OptionalHeader.
1796 DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
1797 if (!DataDirectory->VirtualAddress)
1798 {
1799 /* We don't really have relocations */
1800 ValidRelocs = FALSE;
1801 }
1802 else
1803 {
1804 /* Make sure the size is valid */
1805 if ((DataDirectory->VirtualAddress + DataDirectory->Size) >
1806 LdrEntry->SizeOfImage)
1807 {
1808 /* They're not, skip */
1809 continue;
1810 }
1811
1812 /* We have relocations */
1813 ValidRelocs = TRUE;
1814 }
1815
1816 /* Remember the original address */
1817 DllBase = LdrEntry->DllBase;
1818
1819 /* Loop the PTEs */
1820 PointerPte = StartPte;
1821 while (PointerPte < LastPte)
1822 {
1823 /* Mark the page modified in the PFN database */
1824 ASSERT(PointerPte->u.Hard.Valid == 1);
1825 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1826 ASSERT(Pfn1->u3.e1.Rom == 0);
1827 Pfn1->u3.e1.Modified = TRUE;
1828
1829 /* Next */
1830 PointerPte++;
1831 }
1832
1833 /* Now reserve system PTEs for the image */
1834 PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
1835 if (!PointerPte)
1836 {
1837 /* Shouldn't happen */
1838 ERROR_FATAL("[Mm0]: Couldn't allocate driver section!\n");
1839 return;
1840 }
1841
1842 /* This is the new virtual address for the module */
1843 LastPte = PointerPte + PteCount;
1844 NewImageAddress = MiPteToAddress(PointerPte);
1845
1846 /* Sanity check */
1847 DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);
1849
1850 /* Loop the new driver PTEs */
1852 while (PointerPte < LastPte)
1853 {
1854 /* Copy the old data */
1855 OldPte = *StartPte;
1856 ASSERT(OldPte.u.Hard.Valid == 1);
1857
1858 /* Set page number from the loader's memory */
1860
1861 /* Write it */
1862 MI_WRITE_VALID_PTE(PointerPte, TempPte);
1863
1864 /* Move on */
1865 PointerPte++;
1866 StartPte++;
1867 }
1868
1869 /* Update position */
1870 PointerPte -= PteCount;
1871
1872 /* Sanity check */
1873 ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);
1874
1875 /* Set the image base to the address where the loader put it */
1876 NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
1877
1878 /* Check if we had relocations */
1879 if (ValidRelocs)
1880 {
1881 /* Relocate the image */
1882 Status = LdrRelocateImageWithBias(NewImageAddress,
1883 0,
1884 "SYSLDR",
1888 if (!NT_SUCCESS(Status))
1889 {
1890 /* This shouldn't happen */
1891 ERROR_FATAL("Relocations failed!\n");
1892 return;
1893 }
1894 }
1895
1896 /* Update the loader entry */
1897 LdrEntry->DllBase = NewImageAddress;
1898
1899 /* Update the thunks */
1900 DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);
1901 MiUpdateThunks(LoaderBlock,
1902 DllBase,
1903 NewImageAddress,
1904 LdrEntry->SizeOfImage);
1905
1906 /* Update the loader entry */
1907 LdrEntry->Flags |= LDRP_SYSTEM_MAPPED;
1908 LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +
1910 LdrEntry->SizeOfImage = PteCount << PAGE_SHIFT;
1911
1912 /* FIXME: We'll need to fixup the PFN linkage when switching to ARM3 */
1913 }
1914}
GLenum GLsizei len
Definition: glext.h:6722
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define LDRP_SYSTEM_MAPPED
Definition: ldrtypes.h:54
#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:1047
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#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:360
USHORT Rom
Definition: mm.h:368
Definition: mm.h:374
union _MMPFN::@1790 u3
MMPFNENTRY e1
Definition: mm.h:397
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:648
#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 1033 of file sysldr.c.

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

2599{
2600#ifdef ENABLE_MISETPAGINGOFDRIVER
2601 PVOID ImageBase;
2602 PETHREAD CurrentThread = PsGetCurrentThread();
2603 PFN_COUNT PageCount = 0;
2604 PFN_NUMBER PageFrameIndex;
2605 PMMPFN Pfn1;
2606#endif // ENABLE_MISETPAGINGOFDRIVER
2607
2608 PAGED_CODE();
2609
2610#ifndef ENABLE_MISETPAGINGOFDRIVER
2611 /* The page fault handler is broken and doesn't page back in! */
2612 DPRINT1("WARNING: MiSetPagingOfDriver() called, but paging is broken! ignoring!\n");
2613#else // ENABLE_MISETPAGINGOFDRIVER
2614 /* Get the driver's base address */
2615 ImageBase = MiPteToAddress(PointerPte);
2617
2618 /* If this is a large page, it's stuck in physical memory */
2619 if (MI_IS_PHYSICAL_ADDRESS(ImageBase)) return;
2620
2621 /* Lock the working set */
2622 MiLockWorkingSet(CurrentThread, &MmSystemCacheWs);
2623
2624 /* Loop the PTEs */
2625 while (PointerPte <= LastPte)
2626 {
2627 /* Check for valid PTE */
2628 if (PointerPte->u.Hard.Valid == 1)
2629 {
2630 PageFrameIndex = PFN_FROM_PTE(PointerPte);
2631 Pfn1 = MiGetPfnEntry(PageFrameIndex);
2632 ASSERT(Pfn1->u2.ShareCount == 1);
2633
2634 /* No working sets in ReactOS yet */
2635 PageCount++;
2636 }
2637
2638 ImageBase = (PVOID)((ULONG_PTR)ImageBase + PAGE_SIZE);
2639 PointerPte++;
2640 }
2641
2642 /* Release the working set */
2643 MiUnlockWorkingSet(CurrentThread, &MmSystemCacheWs);
2644
2645 /* Do we have any driver pages? */
2646 if (PageCount)
2647 {
2648 /* Update counters */
2650 }
2651#endif // ENABLE_MISETPAGINGOFDRIVER
2652}
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define InterlockedExchangeAdd
Definition: interlocked.h:181
FORCEINLINE VOID MiLockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1265
#define MI_IS_SESSION_IMAGE_ADDRESS(Address)
Definition: miarm.h:168
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1351
MMSUPPORT MmSystemCacheWs
Definition: init.c:55
union _MMPFN::@1789 u2
ULONG_PTR ShareCount
Definition: mm.h:390
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 2441 of file sysldr.c.

2445{
2446 PMMPTE PointerPte;
2447 MMPTE TempPte;
2448
2449 /* Loop the PTEs */
2450 for (PointerPte = FirstPte; PointerPte <= LastPte; PointerPte++)
2451 {
2452 /* Read the PTE */
2453 TempPte = *PointerPte;
2454
2455 /* Make sure it's valid */
2456 if (TempPte.u.Hard.Valid != 1)
2457 {
2458 DPRINT1("CORE-16449: FirstPte=%p, LastPte=%p, Protection=%lx\n", FirstPte, LastPte, Protection);
2459 DPRINT1("CORE-16449: PointerPte=%p, TempPte=%lx\n", PointerPte, TempPte.u.Long);
2460 DPRINT1("CORE-16449: Please issue the 'mod' and 'bt' (KDBG) or 'lm' and 'kp' (WinDbg) commands. Then report this in Jira.\n");
2461 ASSERT(TempPte.u.Hard.Valid == 1);
2462 break;
2463 }
2464
2465 /* Update the protection */
2466 TempPte.u.Hard.Write = BooleanFlagOn(Protection, IMAGE_SCN_MEM_WRITE);
2467#if _MI_HAS_NO_EXECUTE
2469#endif
2470
2471 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2472 }
2473
2474 /* Flush it all */
2476}
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:977
#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:617

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 747 of file sysldr.c.

755{
756 BOOLEAN IsOrdinal;
757 USHORT Ordinal;
758 PULONG NameTable;
759 PUSHORT OrdinalTable;
760 PIMAGE_IMPORT_BY_NAME NameImport;
761 USHORT Hint;
763 PCHAR MissingForwarder;
764 CHAR NameBuffer[MAXIMUM_FILENAME_LENGTH];
765 PULONG ExportTable;
766 ANSI_STRING DllName;
767 UNICODE_STRING ForwarderName;
768 PLIST_ENTRY NextEntry;
769 PLDR_DATA_TABLE_ENTRY LdrEntry;
770 ULONG ForwardExportSize;
771 PIMAGE_EXPORT_DIRECTORY ForwardExportDirectory;
772 PIMAGE_IMPORT_BY_NAME ForwardName;
773 SIZE_T ForwardLength;
774 IMAGE_THUNK_DATA ForwardThunk;
775
776 PAGED_CODE();
777
778 /* Check if this is an ordinal */
779 IsOrdinal = IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal);
780 if ((IsOrdinal) && !(SnapForwarder))
781 {
782 /* Get the ordinal number and set it as missing */
783 Ordinal = (USHORT)(IMAGE_ORDINAL(Name->u1.Ordinal) -
784 ExportDirectory->Base);
785 *MissingApi = (PCHAR)(ULONG_PTR)Ordinal;
786 }
787 else
788 {
789 /* Get the VA if we don't have to snap */
790 if (!SnapForwarder) Name->u1.AddressOfData += (ULONG_PTR)ImageBase;
791 NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData;
792
793 /* Copy the procedure name */
794 RtlStringCbCopyA(*MissingApi,
796 (PCHAR)NameImport->Name);
797
798 /* Setup name tables */
799 DPRINT("Import name: %s\n", NameImport->Name);
800 NameTable = (PULONG)((ULONG_PTR)DllBase +
801 ExportDirectory->AddressOfNames);
802 OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
803 ExportDirectory->AddressOfNameOrdinals);
804
805 /* Get the hint and check if it's valid */
806 Hint = NameImport->Hint;
807 if ((Hint < ExportDirectory->NumberOfNames) &&
808 !(strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))
809 {
810 /* We have a match, get the ordinal number from here */
811 Ordinal = OrdinalTable[Hint];
812 }
813 else
814 {
815 /* Do a binary search */
816 Ordinal = NameToOrdinal((PCHAR)NameImport->Name,
817 DllBase,
818 ExportDirectory->NumberOfNames,
819 NameTable,
820 OrdinalTable);
821
822 /* Check if we couldn't find it */
823 if (Ordinal == -1)
824 {
825 DPRINT1("Warning: Driver failed to load, %s not found\n", NameImport->Name);
827 }
828 }
829 }
830
831 /* Check if the ordinal is valid */
832 if (Ordinal >= ExportDirectory->NumberOfFunctions)
833 {
834 /* It's not, fail */
836 }
837 else
838 {
839 /* In case the forwarder is missing */
840 MissingForwarder = NameBuffer;
841
842 /* Resolve the address and write it */
843 ExportTable = (PULONG)((ULONG_PTR)DllBase +
844 ExportDirectory->AddressOfFunctions);
845 Address->u1.Function = (ULONG_PTR)DllBase + ExportTable[Ordinal];
846
847 /* Assume success from now on */
849
850 /* Check if the function is actually a forwarder */
851 if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&
852 (Address->u1.Function < (ULONG_PTR)ExportDirectory + ExportSize))
853 {
854 /* Now assume failure in case the forwarder doesn't exist */
856
857 /* Build the forwarder name */
858 DllName.Buffer = (PCHAR)Address->u1.Function;
859 DllName.Length = (USHORT)(strchr(DllName.Buffer, '.') -
860 DllName.Buffer) +
861 sizeof(ANSI_NULL);
862 DllName.MaximumLength = DllName.Length;
863
864 /* Convert it */
865 if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ForwarderName,
866 &DllName,
867 TRUE)))
868 {
869 /* We failed, just return an error */
870 return Status;
871 }
872
873 /* Loop the module list */
874 NextEntry = PsLoadedModuleList.Flink;
875 while (NextEntry != &PsLoadedModuleList)
876 {
877 /* Get the loader entry */
878 LdrEntry = CONTAINING_RECORD(NextEntry,
880 InLoadOrderLinks);
881
882 /* Check if it matches */
883 if (RtlPrefixUnicodeString(&ForwarderName,
884 &LdrEntry->BaseDllName,
885 TRUE))
886 {
887 /* Get the forwarder export directory */
888 ForwardExportDirectory =
890 TRUE,
892 &ForwardExportSize);
893 if (!ForwardExportDirectory) break;
894
895 /* Allocate a name entry */
896 ForwardLength = strlen(DllName.Buffer + DllName.Length) +
897 sizeof(ANSI_NULL);
898 ForwardName = ExAllocatePoolWithTag(PagedPool,
899 sizeof(*ForwardName) +
900 ForwardLength,
902 if (!ForwardName) break;
903
904 /* Copy the data */
905 RtlCopyMemory(&ForwardName->Name[0],
906 DllName.Buffer + DllName.Length,
907 ForwardLength);
908 ForwardName->Hint = 0;
909
910 /* Set the new address */
911 ForwardThunk.u1.AddressOfData = (ULONG_PTR)ForwardName;
912
913 /* Snap the forwarder */
914 Status = MiSnapThunk(LdrEntry->DllBase,
915 ImageBase,
916 &ForwardThunk,
917 &ForwardThunk,
918 ForwardExportDirectory,
919 ForwardExportSize,
920 TRUE,
921 &MissingForwarder);
922
923 /* Free the forwarder name and set the thunk */
924 ExFreePoolWithTag(ForwardName, TAG_LDR_WSTR);
925 Address->u1 = ForwardThunk.u1;
926 break;
927 }
928
929 /* Go to the next entry */
930 NextEntry = NextEntry->Flink;
931 }
932
933 /* Free the name */
934 RtlFreeUnicodeString(&ForwarderName);
935 }
936 }
937
938 /* Return status */
939 return Status;
940}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#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:735
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
#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:222
char CHAR
Definition: xmlstorage.h:175

Referenced by MiResolveImageReferences(), and MiSnapThunk().

◆ MiUpdateThunks()

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

Definition at line 648 of file sysldr.c.

652{
653 ULONG_PTR OldBaseTop, Delta;
654 PLDR_DATA_TABLE_ENTRY LdrEntry;
655 PLIST_ENTRY NextEntry;
656 ULONG ImportSize;
657 //
658 // FIXME: MINGW-W64 must fix LD to generate drivers that Windows can load,
659 // since a real version of Windows would fail at this point, but they seem
660 // busy implementing features such as "HotPatch" support in GCC 4.6 instead,
661 // a feature which isn't even used by Windows. Priorities, priorities...
662 // Please note that Microsoft WDK EULA and license prohibits using
663 // the information contained within it for the generation of "non-Windows"
664 // drivers, which is precisely what LD will generate, since an LD driver
665 // will not load on Windows.
666 //
667#ifdef _WORKING_LINKER_
668 ULONG i;
669#endif
670 PULONG_PTR ImageThunk;
671 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
672
673 /* Calculate the top and delta */
674 OldBaseTop = (ULONG_PTR)OldBase + Size - 1;
675 Delta = (ULONG_PTR)NewBase - (ULONG_PTR)OldBase;
676
677 /* Loop the loader block */
678 for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
679 NextEntry != &LoaderBlock->LoadOrderListHead;
680 NextEntry = NextEntry->Flink)
681 {
682 /* Get the loader entry */
683 LdrEntry = CONTAINING_RECORD(NextEntry,
685 InLoadOrderLinks);
686#ifdef _WORKING_LINKER_
687 /* Get the IAT */
688 ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
689 TRUE,
691 &ImportSize);
692 if (!ImageThunk) continue;
693
694 /* Make sure we have an IAT */
695 DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
696 for (i = 0; i < ImportSize; i++, ImageThunk++)
697 {
698 /* Check if it's within this module */
699 if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
700 {
701 /* Relocate it */
702 DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
703 ImageThunk, *ImageThunk, *ImageThunk + Delta);
704 *ImageThunk += Delta;
705 }
706 }
707#else
708 /* Get the import table */
709 ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
710 TRUE,
712 &ImportSize);
713 if (!ImportDescriptor) continue;
714
715 /* Make sure we have an IAT */
716 DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
717 while ((ImportDescriptor->Name) &&
718 (ImportDescriptor->OriginalFirstThunk))
719 {
720 /* Get the image thunk */
721 ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
722 ImportDescriptor->FirstThunk);
723 while (*ImageThunk)
724 {
725 /* Check if it's within this module */
726 if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
727 {
728 /* Relocate it */
729 DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
730 ImageThunk, *ImageThunk, *ImageThunk + Delta);
731 *ImageThunk += Delta;
732 }
733
734 /* Go to the next thunk */
735 ImageThunk++;
736 }
737
738 /* Go to the next import */
739 ImportDescriptor++;
740 }
741#endif
742 }
743}
static ULONG Delta
Definition: xboxvideo.c:33

Referenced by MiReloadBootLoadedDrivers().

◆ MiUseLargeDriverPage()

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

Definition at line 2384 of file sysldr.c.

2388{
2389 PLIST_ENTRY NextEntry;
2390 BOOLEAN DriverFound = FALSE;
2391 PMI_LARGE_PAGE_DRIVER_ENTRY LargePageDriverEntry;
2393 ASSERT(*ImageBaseAddress >= MmSystemRangeStart);
2394
2395#ifdef _X86_
2396 if (!(KeFeatureBits & KF_LARGE_PAGE)) return FALSE;
2397 if (!(__readcr4() & CR4_PSE)) return FALSE;
2398#endif
2399
2400 /* Make sure there's enough system PTEs for a large page driver */
2402 {
2403 return FALSE;
2404 }
2405
2406 /* This happens if the registry key had a "*" (wildcard) in it */
2407 if (MiLargePageAllDrivers == 0)
2408 {
2409 /* It didn't, so scan the list */
2410 NextEntry = MiLargePageDriverList.Flink;
2411 while (NextEntry != &MiLargePageDriverList)
2412 {
2413 /* Check if the driver name matches */
2414 LargePageDriverEntry = CONTAINING_RECORD(NextEntry,
2416 Links);
2417 if (RtlEqualUnicodeString(BaseImageName,
2418 &LargePageDriverEntry->BaseName,
2419 TRUE))
2420 {
2421 /* Enable large pages for this driver */
2422 DriverFound = TRUE;
2423 break;
2424 }
2425
2426 /* Keep trying */
2427 NextEntry = NextEntry->Flink;
2428 }
2429
2430 /* If we didn't find the driver, it doesn't need large pages */
2431 if (DriverFound == FALSE) return FALSE;
2432 }
2433
2434 /* Nothing to do yet */
2435 DPRINT1("Large pages not supported!\n");
2436 return FALSE;
2437}
#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:1825
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:149
#define MmSystemRangeStart
Definition: mm.h:32
#define PDE_MAPPED_VA
Definition: mm.h:39
ULONG KeFeatureBits
Definition: krnlinit.c:22
Definition: miarm.h:396
UNICODE_STRING BaseName
Definition: miarm.h:398

Referenced by MmLoadSystemImage().

◆ MiWriteProtectSystemImage()

VOID NTAPI MiWriteProtectSystemImage ( _In_ PVOID  ImageBase)

Definition at line 2480 of file sysldr.c.

2482{
2483 PIMAGE_NT_HEADERS NtHeaders;
2484 PIMAGE_SECTION_HEADER SectionHeaders, Section;
2485 ULONG i;
2486 PVOID SectionBase, SectionEnd;
2487 ULONG SectionSize;
2488 ULONG Protection;
2489 PMMPTE FirstPte, LastPte;
2490
2491 /* Check if the registry setting is on or not */
2493 {
2494 /* Ignore section protection */
2495 return;
2496 }
2497
2498 /* Large page mapped images are not supported */
2499 NT_ASSERT(!MI_IS_PHYSICAL_ADDRESS(ImageBase));
2500
2501 /* Session images are not yet supported */
2502 NT_ASSERT(!MI_IS_SESSION_ADDRESS(ImageBase));
2503
2504 /* Get the NT headers */
2505 NtHeaders = RtlImageNtHeader(ImageBase);
2506 if (NtHeaders == NULL)
2507 {
2508 DPRINT1("Failed to get NT headers for image @ %p\n", ImageBase);
2509 return;
2510 }
2511
2512 /* Don't touch NT4 drivers */
2513 if ((NtHeaders->OptionalHeader.MajorOperatingSystemVersion < 5) ||
2514 (NtHeaders->OptionalHeader.MajorSubsystemVersion < 5))
2515 {
2516 DPRINT1("Skipping NT 4 driver @ %p\n", ImageBase);
2517 return;
2518 }
2519
2520 /* Get the section headers */
2521 SectionHeaders = IMAGE_FIRST_SECTION(NtHeaders);
2522
2523 /* Get the base address of the first section */
2524 SectionBase = Add2Ptr(ImageBase, SectionHeaders[0].VirtualAddress);
2525
2526 /* Start protecting the image header as R/W */
2527 FirstPte = MiAddressToPte(ImageBase);
2528 LastPte = MiAddressToPte(SectionBase) - 1;
2530 if (LastPte >= FirstPte)
2531 {
2532 MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2533 }
2534
2535 /* Loop the sections */
2536 for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
2537 {
2538 /* Get the section base address and size */
2539 Section = &SectionHeaders[i];
2540 SectionBase = Add2Ptr(ImageBase, Section->VirtualAddress);
2541 SectionSize = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2542
2543 /* Get the first PTE of this section */
2544 FirstPte = MiAddressToPte(SectionBase);
2545
2546 /* Check for overlap with the previous range */
2547 if (FirstPte == LastPte)
2548 {
2549 /* Combine the old and new protection by ORing them */
2550 Protection |= (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2551
2552 /* Update the protection for this PTE */
2553 MiSetSystemCodeProtection(FirstPte, FirstPte, Protection);
2554
2555 /* Skip this PTE */
2556 FirstPte++;
2557 }
2558
2559 /* There can not be gaps! */
2560 NT_ASSERT(FirstPte == (LastPte + 1));
2561
2562 /* Get the end of the section and the last PTE */
2563 SectionEnd = Add2Ptr(SectionBase, SectionSize - 1);
2564 NT_ASSERT(SectionEnd < Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage));
2565 LastPte = MiAddressToPte(SectionEnd);
2566
2567 /* If there are no more pages (after an overlap), skip this section */
2568 if (LastPte < FirstPte)
2569 {
2570 NT_ASSERT(FirstPte == (LastPte + 1));
2571 continue;
2572 }
2573
2574 /* Get the section protection */
2575 Protection = (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2576
2577 /* Update the protection for this section */
2578 MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2579 }
2580
2581 /* Image should end with the last section */
2582 if (ALIGN_UP_POINTER_BY(SectionEnd, PAGE_SIZE) !=
2583 Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage))
2584 {
2585 DPRINT1("ImageBase 0x%p ImageSize 0x%lx Section %u VA 0x%lx Raw 0x%lx virt 0x%lx\n",
2586 ImageBase,
2587 NtHeaders->OptionalHeader.SizeOfImage,
2588 i,
2589 Section->VirtualAddress,
2590 Section->SizeOfRawData,
2591 Section->Misc.VirtualSize);
2592 }
2593}
#define Add2Ptr(PTR, INC)
#define IMAGE_SCN_PROTECTION_MASK
Definition: miarm.h:160
#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:2441
#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
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by MmInitSystem(), and MmLoadSystemImage().

◆ MmCallDllInitialize()

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

Definition at line 432 of file sysldr.c.

435{
437 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
438 PMM_DLL_INITIALIZE DllInit;
439 UNICODE_STRING RegPath, ImportName;
442
443 PAGED_CODE();
444
445 /* Try to see if the image exports a DllInitialize routine */
446 DllInit = (PMM_DLL_INITIALIZE)
447 RtlFindExportedRoutineByName(LdrEntry->DllBase, "DllInitialize");
448 if (!DllInit)
449 return STATUS_SUCCESS;
450
451 /* Make a temporary copy of BaseDllName because we will alter its length */
452 ImportName.Length = LdrEntry->BaseDllName.Length;
453 ImportName.MaximumLength = LdrEntry->BaseDllName.MaximumLength;
454 ImportName.Buffer = LdrEntry->BaseDllName.Buffer;
455
456 /* Obtain the path to this dll's service in the registry */
457 RegPath.MaximumLength = ServicesKeyName.Length +
458 ImportName.Length + sizeof(UNICODE_NULL);
460 RegPath.MaximumLength,
462
463 /* Check if this allocation was unsuccessful */
464 if (!RegPath.Buffer)
466
467 /* Build and append the service name itself */
468 RegPath.Length = ServicesKeyName.Length;
469 RtlCopyMemory(RegPath.Buffer,
470 ServicesKeyName.Buffer,
471 ServicesKeyName.Length);
472
473 /* If the filename has an extension, remove it */
474 Extension = wcschr(ImportName.Buffer, L'.');
475 if (Extension)
476 ImportName.Length = (USHORT)(Extension - ImportName.Buffer) * sizeof(WCHAR);
477
478 /* Append the service name (base name without extension) */
479 RtlAppendUnicodeStringToString(&RegPath, &ImportName);
480
481 /* Now call DllInitialize */
482 DPRINT("Calling DllInit(%wZ)\n", &RegPath);
483 Status = DllInit(&RegPath);
484
485 /* Clean up */
487
488 // TODO: This is for Driver Verifier support.
490
491 /* Return the DllInitialize status value */
492 return Status;
493}
#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:411
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
static const WCHAR ServicesKeyName[]
Definition: driver.c:32
NTSTATUS(NTAPI * PMM_DLL_INITIALIZE)(_In_ PUNICODE_STRING RegistryPath)
Definition: iotypes.h:2850

Referenced by IopInitializeBootDrivers(), and MiResolveImageReferences().

◆ MmChangeKernelResourceSectionProtection()

BOOLEAN NTAPI MmChangeKernelResourceSectionProtection ( IN ULONG_PTR  ProtectionMask)

Definition at line 2330 of file sysldr.c.

2331{
2332 PMMPTE PointerPte;
2333 MMPTE TempPte;
2334
2335 /* Don't do anything if the resource section is already writable */
2337 return FALSE;
2338
2339 /* If the resource section is physical, we cannot change its protection */
2341 return FALSE;
2342
2343 /* Loop the PTEs */
2344 for (PointerPte = MiKernelResourceStartPte; PointerPte < MiKernelResourceEndPte; ++PointerPte)
2345 {
2346 /* Read the PTE */
2347 TempPte = *PointerPte;
2348
2349 /* Update the protection */
2350 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, ProtectionMask, TempPte.u.Hard.PageFrameNumber);
2351 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2352 }
2353
2354 /* Only flush the current processor's TLB */
2356 return TRUE;
2357}
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:773
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:526

Referenced by DisplayBootBitmap(), and MmMakeKernelResourceSectionWritable().

◆ MmCheckSystemImage()

NTSTATUS NTAPI MmCheckSystemImage ( IN HANDLE  ImageHandle,
IN BOOLEAN  PurgeSection 
)

Definition at line 2744 of file sysldr.c.

2746{
2748 HANDLE SectionHandle;
2749 PVOID ViewBase = NULL;
2750 SIZE_T ViewSize = 0;
2752 FILE_STANDARD_INFORMATION FileStandardInfo;
2754 PIMAGE_NT_HEADERS NtHeaders;
2756 PAGED_CODE();
2757
2758 /* Setup the object attributes */
2760 NULL,
2762 NULL,
2763 NULL);
2764
2765 /* Create a section for the DLL */
2766 Status = ZwCreateSection(&SectionHandle,
2769 NULL,
2771 SEC_IMAGE,
2772 ImageHandle);
2773 if (!NT_SUCCESS(Status))
2774 {
2775 DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2776 return Status;
2777 }
2778
2779 /* Make sure we're in the system process */
2781
2782 /* Map it */
2783 Status = ZwMapViewOfSection(SectionHandle,
2785 &ViewBase,
2786 0,
2787 0,
2788 NULL,
2789 &ViewSize,
2790 ViewShare,
2791 0,
2792 PAGE_EXECUTE);
2793 if (!NT_SUCCESS(Status))
2794 {
2795 /* We failed, close the handle and return */
2796 DPRINT1("ZwMapViewOfSection failed with status 0x%x\n", Status);
2798 ZwClose(SectionHandle);
2799 return Status;
2800 }
2801
2802 /* Now query image information */
2803 Status = ZwQueryInformationFile(ImageHandle,
2805 &FileStandardInfo,
2806 sizeof(FileStandardInfo),
2808 if (NT_SUCCESS(Status))
2809 {
2810 /* First, verify the checksum */
2812 ViewSize,
2813 FileStandardInfo.
2814 EndOfFile.LowPart))
2815 {
2816 /* Set checksum failure */
2818 goto Fail;
2819 }
2820
2821 /* Make sure it's a real image */
2822 NtHeaders = RtlImageNtHeader(ViewBase);
2823 if (!NtHeaders)
2824 {
2825 /* Set checksum failure */
2827 goto Fail;
2828 }
2829
2830 /* Make sure it's for the correct architecture */
2831 if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
2833 {
2834 /* Set protection failure */
2836 goto Fail;
2837 }
2838
2839 /* Check that it's a valid SMP image if we have more then one CPU */
2840 if (!MmVerifyImageIsOkForMpUse(ViewBase))
2841 {
2842 /* Otherwise it's not the right image */
2844 }
2845 }
2846
2847 /* Unmap the section, close the handle, and return status */
2848Fail:
2849 ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
2851 ZwClose(SectionHandle);
2852 return Status;
2853}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
int Fail
Definition: ehthrow.cxx:24
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum(_In_ PVOID BaseAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG FileLength)
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define SEC_IMAGE
Definition: mmtypes.h:97
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1290
#define NtCurrentProcess()
Definition: nt_native.h:1657
@ ViewShare
Definition: nt_native.h:1278
#define IMAGE_NT_OPTIONAL_HDR_MAGIC
Definition: ntimage.h:387
#define STATUS_IMAGE_CHECKSUM_MISMATCH
Definition: ntstatus.h:677
#define STATUS_IMAGE_MP_UP_MISMATCH
Definition: ntstatus.h:717
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:540
#define FileStandardInformation
Definition: propsheet.cpp:61
BOOLEAN NTAPI MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)
Definition: sysldr.c:2720

Referenced by MmLoadSystemImage(), and PsLocateSystemDll().

◆ MmFreeDriverInitialization()

VOID NTAPI MmFreeDriverInitialization ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 1672 of file sysldr.c.

1673{
1674 PMMPTE StartPte, EndPte;
1675 PFN_NUMBER PageCount;
1676 PVOID DllBase;
1677 ULONG i;
1678 PIMAGE_NT_HEADERS NtHeader;
1679 PIMAGE_SECTION_HEADER Section, DiscardSection;
1680
1681 /* Get the base address and the page count */
1682 DllBase = LdrEntry->DllBase;
1683 PageCount = LdrEntry->SizeOfImage >> PAGE_SHIFT;
1684
1685 /* Get the last PTE in this image */
1686 EndPte = MiAddressToPte(DllBase) + PageCount;
1687
1688 /* Get the NT header */
1689 NtHeader = RtlImageNtHeader(DllBase);
1690 if (!NtHeader) return;
1691
1692 /* Get the last section and loop each section backwards */
1693 Section = IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections;
1694 DiscardSection = NULL;
1695 for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
1696 {
1697 /* Go back a section and check if it's discardable */
1698 Section--;
1700 {
1701 /* It is, select it for freeing */
1702 DiscardSection = Section;
1703 }
1704 else
1705 {
1706 /* No more discardable sections exist, bail out */
1707 break;
1708 }
1709 }
1710
1711 /* Bail out if there's nothing to free */
1712 if (!DiscardSection) return;
1713
1714 /* Push the DLL base to the first disacrable section, and get its PTE */
1715 DllBase = (PVOID)ROUND_TO_PAGES((ULONG_PTR)DllBase + DiscardSection->VirtualAddress);
1716 ASSERT(MI_IS_PHYSICAL_ADDRESS(DllBase) == FALSE);
1717 StartPte = MiAddressToPte(DllBase);
1718
1719 /* Check how many pages to free total */
1720 PageCount = (PFN_NUMBER)(EndPte - StartPte);
1721 if (!PageCount) return;
1722
1723 /* Delete this many PTEs */
1724 MiDeleteSystemPageableVm(StartPte, PageCount, 0, NULL);
1725}

Referenced by IopInitializeDriverModule().

◆ MmGetSystemRoutineAddress()

PVOID NTAPI MmGetSystemRoutineAddress ( IN PUNICODE_STRING  SystemRoutineName)

Definition at line 3601 of file sysldr.c.

3602{
3603 PVOID ProcAddress = NULL;
3604 ANSI_STRING AnsiRoutineName;
3606 PLIST_ENTRY NextEntry;
3607 PLDR_DATA_TABLE_ENTRY LdrEntry;
3609 UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
3611 ULONG Modules = 0;
3612
3613 /* Convert routine to ANSI name */
3614 Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName,
3615 SystemRoutineName,
3616 TRUE);
3617 if (!NT_SUCCESS(Status)) return NULL;
3618
3619 /* Lock the list */
3622
3623 /* Loop the loaded module list */
3624 NextEntry = PsLoadedModuleList.Flink;
3625 while (NextEntry != &PsLoadedModuleList)
3626 {
3627 /* Get the entry */
3628 LdrEntry = CONTAINING_RECORD(NextEntry,
3630 InLoadOrderLinks);
3631
3632 /* Check if it's the kernel or HAL */
3633 if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
3634 {
3635 /* Found it */
3636 Found = TRUE;
3637 Modules++;
3638 }
3639 else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
3640 {
3641 /* Found it */
3642 Found = TRUE;
3643 Modules++;
3644 }
3645
3646 /* Check if we found a valid binary */
3647 if (Found)
3648 {
3649 /* Find the procedure name */
3650 ProcAddress = RtlFindExportedRoutineByName(LdrEntry->DllBase,
3651 AnsiRoutineName.Buffer);
3652
3653 /* Break out if we found it or if we already tried both modules */
3654 if (ProcAddress) break;
3655 if (Modules == 2) break;
3656 }
3657
3658 /* Keep looping */
3659 NextEntry = NextEntry->Flink;
3660 }
3661
3662 /* Release the lock */
3665
3666 /* Free the string and return */
3667 RtlFreeAnsiString(&AnsiRoutineName);
3668 return ProcAddress;
3669}
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(), 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 2935 of file sysldr.c.

2941{
2942 PVOID ModuleLoadBase = NULL;
2947 PIMAGE_NT_HEADERS NtHeader;
2948 UNICODE_STRING BaseName, BaseDirectory, PrefixName;
2949 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
2950 ULONG EntrySize, DriverSize;
2951 PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
2952 PCHAR MissingApiName, Buffer;
2953 PWCHAR MissingDriverName, PrefixedBuffer = NULL;
2954 HANDLE SectionHandle;
2956 PSECTION Section = NULL;
2957 BOOLEAN LockOwned = FALSE;
2958 PLIST_ENTRY NextEntry;
2959 IMAGE_INFO ImageInfo;
2960
2961 PAGED_CODE();
2962
2963 /* Detect session-load */
2964 if (Flags)
2965 {
2966 /* Sanity checks */
2967 ASSERT(NamePrefix == NULL);
2968 ASSERT(LoadedName == NULL);
2969
2970 /* Make sure the process is in session too */
2971 if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;
2972 }
2973
2974 /* Allocate a buffer we'll use for names */
2977 TAG_LDR_WSTR);
2979
2980 /* Check for a separator */
2981 if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2982 {
2983 PWCHAR p;
2984 ULONG BaseLength;
2985
2986 /* Loop the path until we get to the base name */
2987 p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
2988 while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
2989
2990 /* Get the length */
2991 BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
2992 BaseLength *= sizeof(WCHAR);
2993
2994 /* Setup the string */
2995 BaseName.Length = (USHORT)BaseLength;
2996 BaseName.Buffer = p;
2997 }
2998 else
2999 {
3000 /* Otherwise, we already have a base name */
3001 BaseName.Length = FileName->Length;
3002 BaseName.Buffer = FileName->Buffer;
3003 }
3004
3005 /* Setup the maximum length */
3006 BaseName.MaximumLength = BaseName.Length;
3007
3008 /* Now compute the base directory */
3009 BaseDirectory = *FileName;
3010 BaseDirectory.Length -= BaseName.Length;
3011 BaseDirectory.MaximumLength = BaseDirectory.Length;
3012
3013 /* And the prefix, which for now is just the name itself */
3014 PrefixName = *FileName;
3015
3016 /* Check if we have a prefix */
3017 if (NamePrefix)
3018 {
3019 /* Check if "directory + prefix" is too long for the string */
3020 Status = RtlUShortAdd(BaseDirectory.Length,
3021 NamePrefix->Length,
3022 &PrefixName.MaximumLength);
3023 if (!NT_SUCCESS(Status))
3024 {
3026 goto Quickie;
3027 }
3028
3029 /* Check if "directory + prefix + basename" is too long for the string */
3030 Status = RtlUShortAdd(PrefixName.MaximumLength,
3031 BaseName.Length,
3032 &PrefixName.MaximumLength);
3033 if (!NT_SUCCESS(Status))
3034 {
3036 goto Quickie;
3037 }
3038
3039 /* Allocate the buffer exclusively used for prefixed name */
3040 PrefixedBuffer = ExAllocatePoolWithTag(PagedPool,
3041 PrefixName.MaximumLength,
3042 TAG_LDR_WSTR);
3043 if (!PrefixedBuffer)
3044 {
3046 goto Quickie;
3047 }
3048
3049 /* Clear out the prefixed name string */
3050 PrefixName.Buffer = PrefixedBuffer;
3051 PrefixName.Length = 0;
3052
3053 /* Concatenate the strings */
3054 RtlAppendUnicodeStringToString(&PrefixName, &BaseDirectory);
3055 RtlAppendUnicodeStringToString(&PrefixName, NamePrefix);
3056 RtlAppendUnicodeStringToString(&PrefixName, &BaseName);
3057
3058 /* Now the base name of the image becomes the prefixed version */
3059 BaseName.Buffer = &(PrefixName.Buffer[BaseDirectory.Length / sizeof(WCHAR)]);
3060 BaseName.Length += NamePrefix->Length;
3061 BaseName.MaximumLength = (PrefixName.MaximumLength - BaseDirectory.Length);
3062 }
3063
3064 /* Check if we already have a name, use it instead */
3065 if (LoadedName) BaseName = *LoadedName;
3066
3067 /* Check for loader snap debugging */
3069 {
3070 /* Print out standard string */
3071 DPRINT1("MM:SYSLDR Loading %wZ (%wZ) %s\n",
3072 &PrefixName, &BaseName, Flags ? "in session space" : "");
3073 }
3074
3075 /* Acquire the load lock */
3076LoaderScan:
3077 ASSERT(LockOwned == FALSE);
3078 LockOwned = TRUE;
3082 KernelMode,
3083 FALSE,
3084 NULL);
3085
3086 /* Scan the module list */
3087 NextEntry = PsLoadedModuleList.Flink;
3088 while (NextEntry != &PsLoadedModuleList)
3089 {
3090 /* Get the entry and compare the names */
3091 LdrEntry = CONTAINING_RECORD(NextEntry,
3093 InLoadOrderLinks);
3094 if (RtlEqualUnicodeString(&PrefixName, &LdrEntry->FullDllName, TRUE))
3095 {
3096 /* Found it, break out */
3097 break;
3098 }
3099
3100 /* Keep scanning */
3101 NextEntry = NextEntry->Flink;
3102 }
3103
3104 /* Check if we found the image */
3105 if (NextEntry != &PsLoadedModuleList)
3106 {
3107 /* Check if we had already mapped a section */
3108 if (Section)
3109 {
3110 /* Dereference and clear */
3111 ObDereferenceObject(Section);
3112 Section = NULL;
3113 }
3114
3115 /* Check if this was supposed to be a session load */
3116 if (!Flags)
3117 {
3118 /* It wasn't, so just return the data */
3119 *ModuleObject = LdrEntry;
3120 *ImageBaseAddress = LdrEntry->DllBase;
3122 }
3123 else
3124 {
3125 /* We don't support session loading yet */
3126 UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3128 }
3129
3130 /* Do cleanup */
3131 goto Quickie;
3132 }
3133 else if (!Section)
3134 {
3135 /* It wasn't loaded, and we didn't have a previous attempt */
3138 LockOwned = FALSE;
3139
3140 /* Check if KD is enabled */
3142 {
3143 /* FIXME: Attempt to get image from KD */
3144 }
3145
3146 /* We don't have a valid entry */
3147 LdrEntry = NULL;
3148
3149 /* Setup image attributes */
3151 FileName,
3153 NULL,
3154 NULL);
3155
3156 /* Open the image */
3162 0);
3163 if (!NT_SUCCESS(Status))
3164 {
3165 DPRINT1("ZwOpenFile failed for '%wZ' with status 0x%x\n",
3166 FileName, Status);
3167 goto Quickie;
3168 }
3169
3170 /* Validate it */
3175 {
3176 /* Fail loading */
3177 goto Quickie;
3178 }
3179
3180 /* Check if this is a session-load */
3181 if (Flags)
3182 {
3183 /* Then we only need read and execute */
3185 }
3186 else
3187 {
3188 /* Otherwise, we can allow write access */
3190 }
3191
3192 /* Initialize the attributes for the section */
3194 NULL,
3196 NULL,
3197 NULL);
3198
3199 /* Create the section */
3200 Status = ZwCreateSection(&SectionHandle,
3203 NULL,
3205 SEC_IMAGE,
3206 FileHandle);
3207 if (!NT_SUCCESS(Status))
3208 {
3209 DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
3210 goto Quickie;
3211 }
3212
3213 /* Now get the section pointer */
3214 Status = ObReferenceObjectByHandle(SectionHandle,
3217 KernelMode,
3218 (PVOID*)&Section,
3219 NULL);
3220 ZwClose(SectionHandle);
3221 if (!NT_SUCCESS(Status)) goto Quickie;
3222
3223 /* Check if this was supposed to be a session-load */
3224 if (Flags)
3225 {
3226 /* We don't support session loading yet */
3227 UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3228 goto Quickie;
3229 }
3230
3231 /* Check the loader list again, we should end up in the path below */
3232 goto LoaderScan;
3233 }
3234 else
3235 {
3236 /* We don't have a valid entry */
3237 LdrEntry = NULL;
3238 }
3239
3240 /* Load the image */
3241 Status = MiLoadImageSection(&Section,
3242 &ModuleLoadBase,
3243 FileName,
3244 FALSE,
3245 NULL);
3247
3248 /* Get the size of the driver */
3249 DriverSize = ((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize;
3250
3251 /* Make sure we're not being loaded into session space */
3252 if (!Flags)
3253 {
3254 /* Check for success */
3255 if (NT_SUCCESS(Status))
3256 {
3257 /* Support large pages for drivers */
3258 MiUseLargeDriverPage(DriverSize / PAGE_SIZE,
3259 &ModuleLoadBase,
3260 &BaseName,
3261 TRUE);
3262 }
3263
3264 /* Dereference the section */
3265 ObDereferenceObject(Section);
3266 Section = NULL;
3267 }
3268
3269 /* Check for failure of the load earlier */
3270 if (!NT_SUCCESS(Status))
3271 {
3272 DPRINT1("MiLoadImageSection failed with status 0x%x\n", Status);
3273 goto Quickie;
3274 }
3275
3276 /* Relocate the driver */
3277 Status = LdrRelocateImageWithBias(ModuleLoadBase,
3278 0,
3279 "SYSLDR",
3283 if (!NT_SUCCESS(Status))
3284 {
3285 DPRINT1("LdrRelocateImageWithBias failed with status 0x%x\n", Status);
3286 goto Quickie;
3287 }
3288
3289 /* Get the NT Header */
3290 NtHeader = RtlImageNtHeader(ModuleLoadBase);
3291
3292 /* Calculate the size we'll need for the entry and allocate it */
3294 BaseName.Length +
3295 sizeof(UNICODE_NULL);
3296
3297 /* Allocate the entry */
3299 if (!LdrEntry)
3300 {
3301 /* Fail */
3303 goto Quickie;
3304 }
3305
3306 /* Setup the entry */
3307 LdrEntry->Flags = LDRP_LOAD_IN_PROGRESS;
3308 LdrEntry->LoadCount = 1;
3309 LdrEntry->LoadedImports = LoadedImports;
3310 LdrEntry->PatchInformation = NULL;
3311
3312 /* Check the version */
3313 if ((NtHeader->OptionalHeader.MajorOperatingSystemVersion >= 5) &&
3314 (NtHeader->OptionalHeader.MajorImageVersion >= 5))
3315 {
3316 /* Mark this image as a native image */
3317 LdrEntry->Flags |= LDRP_ENTRY_NATIVE;
3318 }
3319
3320 /* Setup the rest of the entry */
3321 LdrEntry->DllBase = ModuleLoadBase;
3322 LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase +
3324 LdrEntry->SizeOfImage = DriverSize;
3325 LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;
3326 LdrEntry->SectionPointer = Section;
3327
3328 /* Now write the DLL name */
3329 LdrEntry->BaseDllName.Buffer = (PVOID)(LdrEntry + 1);
3330 LdrEntry->BaseDllName.Length = BaseName.Length;
3331 LdrEntry->BaseDllName.MaximumLength = BaseName.Length;
3332
3333 /* Copy and null-terminate it */
3335 BaseName.Buffer,
3336 BaseName.Length);
3337 LdrEntry->BaseDllName.Buffer[BaseName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3338
3339 /* Now allocate the full name */
3341 PrefixName.Length +
3342 sizeof(UNICODE_NULL),
3343 TAG_LDR_WSTR);
3344 if (!LdrEntry->FullDllName.Buffer)
3345 {
3346 /* Don't fail, just set it to zero */
3347 LdrEntry->FullDllName.Length = 0;
3348 LdrEntry->FullDllName.MaximumLength = 0;
3349 }
3350 else
3351 {
3352 /* Set it up */
3353 LdrEntry->FullDllName.Length = PrefixName.Length;
3354 LdrEntry->FullDllName.MaximumLength = PrefixName.Length;
3355
3356 /* Copy and null-terminate */
3358 PrefixName.Buffer,
3359 PrefixName.Length);
3360 LdrEntry->FullDllName.Buffer[PrefixName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3361 }
3362
3363 /* Add the entry */
3364 MiProcessLoaderEntry(LdrEntry, TRUE);
3365
3366 /* Resolve imports */
3367 MissingApiName = Buffer;
3368 MissingDriverName = NULL;
3369 Status = MiResolveImageReferences(ModuleLoadBase,
3370 &BaseDirectory,
3371 NULL,
3372 &MissingApiName,
3373 &MissingDriverName,
3374 &LoadedImports);
3375 if (!NT_SUCCESS(Status))
3376 {
3377 BOOLEAN NeedToFreeString = FALSE;
3378
3379 /* If the lowest bit is set to 1, this is a hint that we need to free */
3380 if (*(ULONG_PTR*)&MissingDriverName & 1)
3381 {
3382 NeedToFreeString = TRUE;
3383 *(ULONG_PTR*)&MissingDriverName &= ~1;
3384 }
3385
3386 DPRINT1("MiResolveImageReferences failed with status 0x%x\n", Status);
3387 DPRINT1(" Missing driver '%ls', missing API '%s'\n",
3388 MissingDriverName, MissingApiName);
3389
3390 if (NeedToFreeString)
3391 {
3392 ExFreePoolWithTag(MissingDriverName, TAG_LDR_WSTR);
3393 }
3394
3395 /* Fail */
3396 MiProcessLoaderEntry(LdrEntry, FALSE);
3397
3398 /* Check if we need to free the name */
3399 if (LdrEntry->FullDllName.Buffer)
3400 {
3401 /* Free it */
3403 }
3404
3405 /* Free the entry itself */
3407 LdrEntry = NULL;
3408 goto Quickie;
3409 }
3410
3411 /* Update the loader entry */
3412 LdrEntry->Flags |= (LDRP_SYSTEM_MAPPED |
3415 LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
3416 LdrEntry->LoadedImports = LoadedImports;
3417
3418 /* FIXME: Call driver verifier's loader function */
3419
3420 /* Write-protect the system image */
3422
3423 /* Initialize the security cookie (Win7 is not doing this yet!) */
3424 LdrpInitSecurityCookie(LdrEntry);
3425
3426 /* Check if notifications are enabled */
3428 {
3429 /* Fill out the notification data */
3430 ImageInfo.Properties = 0;
3432 ImageInfo.SystemModeImage = TRUE;
3433 ImageInfo.ImageSize = LdrEntry->SizeOfImage;
3434 ImageInfo.ImageBase = LdrEntry->DllBase;
3435 ImageInfo.ImageSectionNumber = ImageInfo.ImageSelector = 0;
3436
3437 /* Send the notification */
3439 }
3440
3441#ifdef __ROS_ROSSYM__
3442 /* MiCacheImageSymbols doesn't detect rossym */
3443 if (TRUE)
3444#else
3445 /* Check if there's symbols */
3446 if (MiCacheImageSymbols(LdrEntry->DllBase))
3447#endif
3448 {
3449 UNICODE_STRING UnicodeTemp;
3450 STRING AnsiTemp;
3451
3452 /* Check if the system root is present */
3453 if ((PrefixName.Length > (11 * sizeof(WCHAR))) &&
3454 !(_wcsnicmp(PrefixName.Buffer, L"\\SystemRoot", 11)))
3455 {
3456 /* Add the system root */
3457 UnicodeTemp = PrefixName;
3458 UnicodeTemp.Buffer += 11;
3459 UnicodeTemp.Length -= (11 * sizeof(WCHAR));
3462 "%ws%wZ",
3463 &SharedUserData->NtSystemRoot[2],
3464 &UnicodeTemp);
3465 }
3466 else
3467 {
3468 /* Build the name */
3470 "%wZ", &BaseName);
3471 }
3472
3473 /* Setup the ANSI string */
3474 RtlInitString(&AnsiTemp, Buffer);
3475
3476 /* Notify the debugger */
3477 DbgLoadImageSymbols(&AnsiTemp,
3478 LdrEntry->DllBase,
3480 LdrEntry->Flags |= LDRP_DEBUG_SYMBOLS_LOADED;
3481 }
3482
3483 /* Page the driver */
3484 ASSERT(Section == NULL);
3485 MiEnablePagingOfDriver(LdrEntry);
3486
3487 /* Return pointers */
3488 *ModuleObject = LdrEntry;
3489 *ImageBaseAddress = LdrEntry->DllBase;
3490
3491Quickie:
3492 /* Check if we have the lock acquired */
3493 if (LockOwned)
3494 {
3495 /* Release the lock */
3498 LockOwned = FALSE;
3499 }
3500
3501 /* If we have a file handle, close it */
3503
3504 /* If we have allocated a prefixed name buffer, free it */
3505 if (PrefixedBuffer) ExFreePoolWithTag(PrefixedBuffer, TAG_LDR_WSTR);
3506
3507 /* Free the name buffer and return status */
3509 return Status;
3510}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
Definition: bufpool.h:45
#define SECTION_MAP_READ
Definition: compat.h:139
#define FILE_SHARE_READ
Definition: compat.h:136
struct _FileName FileName
Definition: fatprocs.h:896
_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:57
#define IMAGE_ADDRESSING_MODE_32BIT
Definition: pstypes.h:194
BOOLEAN KdDebuggerNotPresent
Definition: kddata.c:82
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:83
#define LDRP_DEBUG_SYMBOLS_LOADED
Definition: ldrtypes.h:50
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:44
#define LDRP_ENTRY_NATIVE
Definition: ldrtypes.h:57
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)
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#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:506
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:270
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
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:494
BOOLEAN PsImageNotifyEnabled
Definition: psnotify.c:18
FORCEINLINE VOID PspRunLoadImageNotifyRoutines(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo)
Definition: ps_x.h:84
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define SharedUserData
POBJECT_TYPE MmSectionObjectType
Definition: section.c:194
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:164
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:1033
PVOID NTAPI LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2898
VOID NTAPI MiWriteProtectSystemImage(_In_ PVOID ImageBase)
Definition: sysldr.c:2480
VOID NTAPI MiEnablePagingOfDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2656
VOID NTAPI MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN BOOLEAN Insert)
Definition: sysldr.c:621
PVOID NTAPI MiCacheImageSymbols(IN PVOID BaseAddress)
Definition: sysldr.c:50
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:77
NTSTATUS NTAPI MmCheckSystemImage(IN HANDLE ImageHandle, IN BOOLEAN PurgeSection)
Definition: sysldr.c:2744
LOGICAL NTAPI MiUseLargeDriverPage(IN ULONG NumberOfPtes, IN OUT PVOID *ImageBaseAddress, IN PUNICODE_STRING BaseImageName, IN BOOLEAN BootDriver)
Definition: sysldr.c:2384
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:2658
_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 2361 of file sysldr.c.

2362{
2363 /* Don't do anything if the resource section is already writable */
2365 return;
2366
2367 /* If the resource section is physical, we cannot change its protection */
2369 return;
2370
2372 {
2373 /*
2374 * Invalidate the cached resource section PTEs
2375 * so as to not change its protection again later.
2376 */
2379 }
2380}
#define MM_READWRITE
Definition: bootanim.c:19
BOOLEAN NTAPI MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask)
Definition: sysldr.c:2330

Referenced by KeGetBugMessageText().

◆ MmPageEntireDriver()

PVOID NTAPI MmPageEntireDriver ( IN PVOID  AddressWithinSection)

Definition at line 3554 of file sysldr.c.

3555{
3556 PMMPTE StartPte, EndPte;
3557 PLDR_DATA_TABLE_ENTRY LdrEntry;
3558 PAGED_CODE();
3559
3560 /* Get the loader entry */
3561 LdrEntry = MiLookupDataTableEntry(AddressWithinSection);
3562 if (!LdrEntry) return NULL;
3563
3564 /* Check if paging of kernel mode is disabled or if the driver is mapped as an image */
3565 if ((MmDisablePagingExecutive) || (LdrEntry->SectionPointer))
3566 {
3567 /* Don't do anything, just return the base address */
3568 return LdrEntry->DllBase;
3569 }
3570
3571 /* Wait for active DPCs to finish before we page out the driver */
3573
3574 /* Get the PTE range for the whole driver image */
3575 StartPte = MiAddressToPte((ULONG_PTR)LdrEntry->DllBase);
3576 EndPte = MiAddressToPte((ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage);
3577
3578 /* Enable paging for the PTE range */
3579 ASSERT(MI_IS_SESSION_IMAGE_ADDRESS(AddressWithinSection) == FALSE);
3580 MiSetPagingOfDriver(StartPte, EndPte);
3581
3582 /* Return the base address */
3583 return LdrEntry->DllBase;
3584}
VOID NTAPI KeFlushQueuedDpcs(VOID)
Definition: dpc.c:919
PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry(IN PVOID Address)
Definition: sysldr.c:3514

Referenced by DriverEntry().

◆ MmResetDriverPaging()

VOID NTAPI MmResetDriverPaging ( IN PVOID  AddressWithinSection)

Definition at line 3591 of file sysldr.c.

3592{
3594}
#define UNIMPLEMENTED
Definition: debug.h:115

◆ MmUnloadSystemImage()

NTSTATUS NTAPI MmUnloadSystemImage ( IN PVOID  ImageHandle)

Definition at line 944 of file sysldr.c.

945{
946 PLDR_DATA_TABLE_ENTRY LdrEntry = ImageHandle;
947 PVOID BaseAddress = LdrEntry->DllBase;
949 STRING TempName;
950 BOOLEAN HadEntry = FALSE;
951
952 /* Acquire the loader lock */
957 FALSE,
958 NULL);
959
960 /* Check if this driver was loaded at boot and didn't get imports parsed */
961 if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) goto Done;
962
963 /* We should still be alive */
964 ASSERT(LdrEntry->LoadCount != 0);
965 LdrEntry->LoadCount--;
966
967 /* Check if we're still loaded */
968 if (LdrEntry->LoadCount) goto Done;
969
970 /* We should cleanup... are symbols loaded */
971 if (LdrEntry->Flags & LDRP_DEBUG_SYMBOLS_LOADED)
972 {
973 /* Create the ANSI name */
975 &LdrEntry->BaseDllName,
976 TRUE);
977 if (NT_SUCCESS(Status))
978 {
979 /* Unload the symbols */
980 DbgUnLoadImageSymbols(&TempName,
983 RtlFreeAnsiString(&TempName);
984 }
985 }
986
987 /* FIXME: Free the driver */
988 DPRINT1("Leaking driver: %wZ\n", &LdrEntry->BaseDllName);
989 //MmFreeSection(LdrEntry->DllBase);
990
991 /* Check if we're linked in */
992 if (LdrEntry->InLoadOrderLinks.Flink)
993 {
994 /* Remove us */
995 MiProcessLoaderEntry(LdrEntry, FALSE);
996 HadEntry = TRUE;
997 }
998
999 /* Dereference and clear the imports */
1001 MiClearImports(LdrEntry);
1002
1003 /* Check if the entry needs to go away */
1004 if (HadEntry)
1005 {
1006 /* Check if it had a name */
1007 if (LdrEntry->FullDllName.Buffer)
1008 {
1009 /* Free it */
1011 }
1012
1013 /* Check if we had a section */
1014 if (LdrEntry->SectionPointer)
1015 {
1016 /* Dereference it */
1018 }
1019
1020 /* Free the entry */
1022 }
1023
1024 /* Release the system lock and return */
1025Done:
1028 return STATUS_SUCCESS;
1029}
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:601

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

◆ MmVerifyImageIsOkForMpUse()

BOOLEAN NTAPI MmVerifyImageIsOkForMpUse ( IN PVOID  BaseAddress)

Definition at line 2720 of file sysldr.c.

2721{
2722 PIMAGE_NT_HEADERS NtHeader;
2723 PAGED_CODE();
2724
2725 /* Get NT Headers */
2726 NtHeader = RtlImageNtHeader(BaseAddress);
2727 if (NtHeader)
2728 {
2729 /* Check if this image is only safe for UP while we have 2+ CPUs */
2730 if ((KeNumberProcessors > 1) &&
2732 {
2733 /* Fail */
2734 return FALSE;
2735 }
2736 }
2737
2738 /* Otherwise, it's safe */
2739 return TRUE;
2740}
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define IMAGE_FILE_UP_SYSTEM_ONLY
Definition: pedump.c:170

Referenced by MmCheckSystemImage().

◆ NameToOrdinal()

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

Definition at line 222 of file sysldr.c.

228{
229 LONG Low, Mid, High, Ret;
230
231 /* Fail if no names */
232 if (!NumberOfNames)
233 return -1;
234
235 /* Do a binary search */
236 Low = Mid = 0;
237 High = NumberOfNames - 1;
238 while (High >= Low)
239 {
240 /* Get new middle value */
241 Mid = (Low + High) >> 1;
242
243 /* Compare name */
244 Ret = strcmp(ExportName, (PCHAR)RVA(ImageBase, NameTable[Mid]));
245 if (Ret < 0)
246 {
247 /* Update high */
248 High = Mid - 1;
249 }
250 else if (Ret > 0)
251 {
252 /* Update low */
253 Low = Mid + 1;
254 }
255 else
256 {
257 /* We got it */
258 break;
259 }
260 }
261
262 /* Check if we couldn't find it */
263 if (High < Low)
264 return -1;
265
266 /* Otherwise, this is the ordinal */
267 return OrdinalTable[Mid];
268}
long LONG
Definition: pedump.c:60
@ High
Definition: strmini.h:378
@ Low
Definition: strmini.h:380
#define RVA(m, b)
Definition: sysldr.c:217

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 400 of file sysldr.c.

403{
405 BOOLEAN IsForwarder = FALSE;
407
408 PAGED_CODE();
409
410 /* Call the internal API */
412 ExportName,
413 &Function,
414 &IsForwarder,
416 if (!NT_SUCCESS(Status))
417 return NULL;
418
419 /* If the export is actually a forwarder, log the error and fail */
420 if (IsForwarder)
421 {
422 DPRINT1("RtlFindExportedRoutineByName does not support forwarders!\n", FALSE);
423 return NULL;
424 }
425
426 /* We've found the export */
427 return Function;
428}
_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:549
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:308

Referenced by 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 308 of file sysldr.c.

314{
315 PIMAGE_EXPORT_DIRECTORY ExportDirectory;
316 PULONG NameTable;
317 PUSHORT OrdinalTable;
318 ULONG ExportSize;
319 USHORT Ordinal;
320 PULONG ExportTable;
321 ULONG_PTR FunctionAddress;
322
323 PAGED_CODE();
324
325 /* Get the export directory */
326 ExportDirectory = RtlImageDirectoryEntryToData(ImageBase,
327 TRUE,
329 &ExportSize);
330 if (!ExportDirectory)
332
333 /* Setup name tables */
334 NameTable = (PULONG)RVA(ImageBase, ExportDirectory->AddressOfNames);
335 OrdinalTable = (PUSHORT)RVA(ImageBase, ExportDirectory->AddressOfNameOrdinals);
336
337 /* Get the ordinal */
338 Ordinal = NameToOrdinal(ExportName,
339 ImageBase,
340 ExportDirectory->NumberOfNames,
341 NameTable,
342 OrdinalTable);
343
344 /* Check if we couldn't find it */
345 if (Ordinal == -1)
346 return NotFoundStatus;
347
348 /* Validate the ordinal */
349 if (Ordinal >= ExportDirectory->NumberOfFunctions)
350 return NotFoundStatus;
351
352 /* Resolve the function's address */
353 ExportTable = (PULONG)RVA(ImageBase, ExportDirectory->AddressOfFunctions);
354 FunctionAddress = (ULONG_PTR)RVA(ImageBase, ExportTable[Ordinal]);
355
356 /* Check if the function is actually a forwarder */
357 if (IsForwarder)
358 {
359 *IsForwarder = FALSE;
360 if ((FunctionAddress > (ULONG_PTR)ExportDirectory) &&
361 (FunctionAddress < (ULONG_PTR)ExportDirectory + ExportSize))
362 {
363 /* It is, and points to the forwarder name */
364 *IsForwarder = TRUE;
365 }
366 }
367
368 /* We've found it */
369 *Function = (PVOID)FunctionAddress;
370 return STATUS_SUCCESS;
371}
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 MiLoadUserSymbols(), 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().