ReactOS 0.4.15-dev-7931-gfd331f1
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 44 of file sysldr.c.

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 16 of file sysldr.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file sysldr.c.

◆ RVA

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

Definition at line 218 of file sysldr.c.

Function Documentation

◆ LdrpFetchAddressOfSecurityCookie()

PVOID NTAPI LdrpFetchAddressOfSecurityCookie ( PVOID  BaseAddress,
ULONG  SizeOfImage 
)

Definition at line 2859 of file sysldr.c.

2860{
2862 ULONG DirSize;
2864
2865 /* Get the pointer to the config directory */
2867 TRUE,
2869 &DirSize);
2870
2871 /* Check for sanity */
2872 if (!ConfigDir ||
2873 DirSize < RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, SecurityCookie))
2874 {
2875 /* Invalid directory*/
2876 return NULL;
2877 }
2878
2879 /* Now get the cookie */
2880 Cookie = (PULONG_PTR)ConfigDir->SecurityCookie;
2881
2882 /* Check this cookie */
2884 (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage - sizeof(*Cookie))
2885 {
2886 Cookie = NULL;
2887 }
2888
2889 /* Return validated security cookie */
2890 return Cookie;
2891}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:672
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14

Referenced by LdrpInitSecurityCookie().

◆ LdrpInitSecurityCookie()

PVOID NTAPI LdrpInitSecurityCookie ( PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2895 of file sysldr.c.

2896{
2898 ULONG_PTR NewCookie;
2899
2900 /* Fetch address of the cookie */
2902
2903 if (!Cookie)
2904 return NULL;
2905
2906 /* Check if it's a default one */
2907 if ((*Cookie == DEFAULT_SECURITY_COOKIE) ||
2908 (*Cookie == 0))
2909 {
2911 /* The address should be unique */
2912 NewCookie = (ULONG_PTR)Cookie;
2913
2914 /* We just need a simple tick, don't care about precision and whatnot */
2915 NewCookie ^= (ULONG_PTR)Counter.LowPart;
2916#ifdef _WIN64
2917 /* Some images expect first 16 bits to be kept clean (like in default cookie) */
2918 if (NewCookie > COOKIE_MAX)
2919 {
2920 NewCookie >>= 16;
2921 }
2922#endif
2923 /* If the result is 0 or the same as we got, just add one to the default value */
2924 if ((NewCookie == 0) || (NewCookie == *Cookie))
2925 {
2926 NewCookie = DEFAULT_SECURITY_COOKIE + 1;
2927 }
2928
2929 /* Set the new cookie value */
2930 *Cookie = NewCookie;
2931 }
2932
2933 return Cookie;
2934}
#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:44
PVOID NTAPI LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: sysldr.c:2859
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 1920 of file sysldr.c.

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

Referenced by MiInitializeLoadedModuleList().

◆ MiCacheImageSymbols()

PVOID NTAPI MiCacheImageSymbols ( IN PVOID  BaseAddress)

Definition at line 51 of file sysldr.c.

52{
53 ULONG DebugSize;
54 PVOID DebugDirectory = NULL;
55 PAGED_CODE();
56
57 /* Make sure it's safe to access the image */
59 {
60 /* Get the debug directory */
62 TRUE,
64 &DebugSize);
65 }
67 {
68 /* Nothing */
69 }
71
72 /* Return the directory */
73 return DebugDirectory;
74}
#define PAGED_CODE()
#define IMAGE_DIRECTORY_ENTRY_DEBUG
Definition: compat.h:152
#define _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 497 of file sysldr.c.

499{
502
503 PAGED_CODE();
504
505 /* Retrieve the DllUnload routine */
507 RtlFindExportedRoutineByName(LdrEntry->DllBase, "DllUnload");
508 if (!DllUnload)
509 return FALSE;
510
511 /* Call it and check for success */
512 Status = DllUnload();
513 if (!NT_SUCCESS(Status))
514 return FALSE;
515
516 /* Lie about the load count so we can unload the image */
517 ASSERT(LdrEntry->LoadCount == 0);
518 LdrEntry->LoadCount = 1;
519
520 /* Unload it */
521 MmUnloadSystemImage(LdrEntry);
522 return TRUE;
523}
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:945
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:401
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 602 of file sysldr.c.

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

Referenced by MmUnloadSystemImage().

◆ MiDereferenceImports()

NTSTATUS NTAPI MiDereferenceImports ( IN PLOAD_IMPORTS  ImportList)

Definition at line 527 of file sysldr.c.

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

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

◆ MiEnablePagingOfDriver()

VOID NTAPI MiEnablePagingOfDriver ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2657 of file sysldr.c.

2658{
2659 ULONG_PTR ImageBase;
2660 PIMAGE_NT_HEADERS NtHeaders;
2661 ULONG Sections, Alignment, Size;
2662 PIMAGE_SECTION_HEADER Section;
2663 PMMPTE PointerPte = NULL, LastPte = NULL;
2664 if (MmDisablePagingExecutive) return;
2665
2666 /* Get the driver base address and its NT header */
2667 ImageBase = (ULONG_PTR)LdrEntry->DllBase;
2668 NtHeaders = RtlImageNtHeader((PVOID)ImageBase);
2669 if (!NtHeaders) return;
2670
2671 /* Get the sections and their alignment */
2672 Sections = NtHeaders->FileHeader.NumberOfSections;
2673 Alignment = NtHeaders->OptionalHeader.SectionAlignment - 1;
2674
2675 /* Loop each section */
2676 Section = IMAGE_FIRST_SECTION(NtHeaders);
2677 while (Sections)
2678 {
2679 /* Find PAGE or .edata */
2680 if ((*(PULONG)Section->Name == 'EGAP') ||
2681 (*(PULONG)Section->Name == 'ade.'))
2682 {
2683 /* Had we already done some work? */
2684 if (!PointerPte)
2685 {
2686 /* Nope, setup the first PTE address */
2687 PointerPte = MiAddressToPte(ROUND_TO_PAGES(ImageBase +
2688 Section->VirtualAddress));
2689 }
2690
2691 /* Compute the size */
2692 Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2693
2694 /* Find the last PTE that maps this section */
2695 LastPte = MiAddressToPte(ImageBase +
2696 Section->VirtualAddress +
2698 }
2699 else
2700 {
2701 /* Had we found a section before? */
2702 if (PointerPte)
2703 {
2704 /* Mark it as pageable */
2705 MiSetPagingOfDriver(PointerPte, LastPte);
2706 PointerPte = NULL;
2707 }
2708 }
2709
2710 /* Keep searching */
2711 Sections--;
2712 Section++;
2713 }
2714
2715 /* Handle the straggler */
2716 if (PointerPte) MiSetPagingOfDriver(PointerPte, LastPte);
2717}
#define RtlImageNtHeader
Definition: compat.h:806
#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::@1556 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:2598
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 1488 of file sysldr.c.

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

1467{
1468 PMMPTE PointerPte;
1469 PFN_NUMBER PagesFreed;
1470
1471 /* Get the start PTE */
1472 PointerPte = MiAddressToPte(InitStart);
1473 ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE);
1474
1475 /* Compute the number of pages we expect to free */
1476 PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte);
1477
1478 /* Try to actually free them */
1479 PagesFreed = MiDeleteSystemPageableVm(PointerPte,
1480 PagesFreed,
1481 0,
1482 NULL);
1483}
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 2242 of file sysldr.c.

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

83{
84 PSECTION Section = *SectionPtr;
87 PVOID Base = NULL;
88 SIZE_T ViewSize = 0;
92 PFN_COUNT PteCount;
93 PMMPTE PointerPte, LastPte;
94 PVOID DriverBase;
97 PFN_NUMBER PageFrameIndex;
98 PAGED_CODE();
99
100 /* Detect session load */
101 if (SessionLoad)
102 {
103 /* Fail */
104 UNIMPLEMENTED_DBGBREAK("Session loading not yet supported!\n");
106 }
107
108 /* Not session load, shouldn't have an entry */
109 ASSERT(LdrEntry == NULL);
110
111 /* Attach to the system process */
113
114 /* Check if we need to load symbols */
116 {
117 /* Yes we do */
119 NtGlobalFlag &= ~FLG_ENABLE_KDEBUG_SYMBOL_LOAD;
120 }
121
122 /* Map the driver */
124 Status = MmMapViewOfSection(Section,
125 Process,
126 &Base,
127 0,
128 0,
130 &ViewSize,
131 ViewUnmap,
132 0,
134
135 /* Re-enable the flag */
137
138 /* Check if we failed with distinguished status code */
140 {
141 /* Change it to something more generic */
143 }
144
145 /* Now check if we failed */
146 if (!NT_SUCCESS(Status))
147 {
148 /* Detach and return */
149 DPRINT1("MmMapViewOfSection failed with status 0x%x\n", Status);
151 return Status;
152 }
153
154 /* Reserve system PTEs needed */
155 PteCount = ROUND_TO_PAGES(((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize) >> PAGE_SHIFT;
156 PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
157 if (!PointerPte)
158 {
159 DPRINT1("MiReserveSystemPtes failed\n");
162 }
163
164 /* New driver base */
165 LastPte = PointerPte + PteCount;
166 DriverBase = MiPteToAddress(PointerPte);
167
168 /* The driver is here */
169 *ImageBase = DriverBase;
170 DPRINT1("Loading: %wZ at %p with %lx pages\n", FileName, DriverBase, PteCount);
171
172 /* Lock the PFN database */
173 OldIrql = MiAcquirePfnLock();
174
175 /* Loop the new driver PTEs */
177 while (PointerPte < LastPte)
178 {
179 /* Make sure the PTE is not valid for whatever reason */
180 ASSERT(PointerPte->u.Hard.Valid == 0);
181
182 /* Some debug stuff */
184#if MI_TRACE_PFNS
185 MI_SET_PROCESS_USTR(FileName);
186#endif
187
188 /* Grab a page */
189 PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
190
191 /* Initialize its PFN entry */
192 MiInitializePfn(PageFrameIndex, PointerPte, TRUE);
193
194 /* Write the PTE */
195 TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
196 MI_WRITE_VALID_PTE(PointerPte, TempPte);
197
198 /* Move on */
199 PointerPte++;
200 }
201
202 /* Release the PFN lock */
203 MiReleasePfnLock(OldIrql);
204
205 /* Copy the image */
206 RtlCopyMemory(DriverBase, Base, PteCount << PAGE_SHIFT);
207
208 /* Now unmap the view */
211
212 /* Detach and return status */
214 return Status;
215}
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c: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::@2330 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 2185 of file sysldr.c.

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

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

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

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

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

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

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

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

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

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

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

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

2332{
2333 PMMPTE PointerPte;
2334 MMPTE TempPte;
2335
2336 /* Don't do anything if the resource section is already writable */
2338 return FALSE;
2339
2340 /* If the resource section is physical, we cannot change its protection */
2342 return FALSE;
2343
2344 /* Loop the PTEs */
2345 for (PointerPte = MiKernelResourceStartPte; PointerPte < MiKernelResourceEndPte; ++PointerPte)
2346 {
2347 /* Read the PTE */
2348 TempPte = *PointerPte;
2349
2350 /* Update the protection */
2351 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, ProtectionMask, TempPte.u.Hard.PageFrameNumber);
2352 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2353 }
2354
2355 /* Only flush the current processor's TLB */
2357 return TRUE;
2358}
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 2745 of file sysldr.c.

2747{
2749 HANDLE SectionHandle;
2750 PVOID ViewBase = NULL;
2751 SIZE_T ViewSize = 0;
2753 FILE_STANDARD_INFORMATION FileStandardInfo;
2755 PIMAGE_NT_HEADERS NtHeaders;
2757 PAGED_CODE();
2758
2759 /* Setup the object attributes */
2761 NULL,
2763 NULL,
2764 NULL);
2765
2766 /* Create a section for the DLL */
2767 Status = ZwCreateSection(&SectionHandle,
2770 NULL,
2772 SEC_IMAGE,
2773 ImageHandle);
2774 if (!NT_SUCCESS(Status))
2775 {
2776 DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2777 return Status;
2778 }
2779
2780 /* Make sure we're in the system process */
2782
2783 /* Map it */
2784 Status = ZwMapViewOfSection(SectionHandle,
2786 &ViewBase,
2787 0,
2788 0,
2789 NULL,
2790 &ViewSize,
2791 ViewShare,
2792 0,
2793 PAGE_EXECUTE);
2794 if (!NT_SUCCESS(Status))
2795 {
2796 /* We failed, close the handle and return */
2797 DPRINT1("ZwMapViewOfSection failed with status 0x%x\n", Status);
2799 ZwClose(SectionHandle);
2800 return Status;
2801 }
2802
2803 /* Now query image information */
2804 Status = ZwQueryInformationFile(ImageHandle,
2806 &FileStandardInfo,
2807 sizeof(FileStandardInfo),
2809 if (NT_SUCCESS(Status))
2810 {
2811 /* First, verify the checksum */
2813 ViewSize,
2814 FileStandardInfo.
2815 EndOfFile.LowPart))
2816 {
2817 /* Set checksum failure */
2819 goto Fail;
2820 }
2821
2822 /* Make sure it's a real image */
2823 NtHeaders = RtlImageNtHeader(ViewBase);
2824 if (!NtHeaders)
2825 {
2826 /* Set checksum failure */
2828 goto Fail;
2829 }
2830
2831 /* Make sure it's for the correct architecture */
2832 if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
2834 {
2835 /* Set protection failure */
2837 goto Fail;
2838 }
2839
2840 /* Check that it's a valid SMP image if we have more then one CPU */
2841 if (!MmVerifyImageIsOkForMpUse(ViewBase))
2842 {
2843 /* Otherwise it's not the right image */
2845 }
2846 }
2847
2848 /* Unmap the section, close the handle, and return status */
2849Fail:
2850 ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
2852 ZwClose(SectionHandle);
2853 return Status;
2854}
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:2721

Referenced by MmLoadSystemImage(), and PsLocateSystemDll().

◆ MmFreeDriverInitialization()

VOID NTAPI MmFreeDriverInitialization ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 1673 of file sysldr.c.

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

Referenced by IopInitializeDriverModule().

◆ MmGetSystemRoutineAddress()

PVOID NTAPI MmGetSystemRoutineAddress ( IN PUNICODE_STRING  SystemRoutineName)

Definition at line 3604 of file sysldr.c.

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

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

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

Referenced by KeGetBugMessageText().

◆ MmPageEntireDriver()

PVOID NTAPI MmPageEntireDriver ( IN PVOID  AddressWithinSection)

Definition at line 3557 of file sysldr.c.

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

Referenced by DriverEntry().

◆ MmResetDriverPaging()

VOID NTAPI MmResetDriverPaging ( IN PVOID  AddressWithinSection)

Definition at line 3594 of file sysldr.c.

3595{
3597}
#define UNIMPLEMENTED
Definition: debug.h:115

◆ MmUnloadSystemImage()

NTSTATUS NTAPI MmUnloadSystemImage ( IN PVOID  ImageHandle)

Definition at line 945 of file sysldr.c.

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

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

◆ MmVerifyImageIsOkForMpUse()

BOOLEAN NTAPI MmVerifyImageIsOkForMpUse ( IN PVOID  BaseAddress)

Definition at line 2721 of file sysldr.c.

2722{
2723 PIMAGE_NT_HEADERS NtHeader;
2724 PAGED_CODE();
2725
2726 /* Get NT Headers */
2727 NtHeader = RtlImageNtHeader(BaseAddress);
2728 if (NtHeader)
2729 {
2730 /* Check if this image is only safe for UP while we have 2+ CPUs */
2731 if ((KeNumberProcessors > 1) &&
2733 {
2734 /* Fail */
2735 return FALSE;
2736 }
2737 }
2738
2739 /* Otherwise, it's safe */
2740 return TRUE;
2741}
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 223 of file sysldr.c.

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

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

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

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

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