ReactOS  0.4.15-dev-5606-gf34e425
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
 

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)
 
PVOID NTAPI MiLocateExportName (IN PVOID DllBase, IN PCHAR ExportName)
 
NTSTATUS NTAPI MmCallDllInitialize (IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PLIST_ENTRY ListHead)
 
BOOLEAN NTAPI MiCallDllUnloadAndUnloadDll (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSTATUS NTAPI MiDereferenceImports (IN PLOAD_IMPORTS ImportList)
 
VOID NTAPI MiClearImports (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
PVOID NTAPI MiFindExportedRoutineByName (IN PVOID DllBase, IN PANSI_STRING ExportName)
 
VOID NTAPI MiProcessLoaderEntry (IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN BOOLEAN Insert)
 
VOID NTAPI MiUpdateThunks (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PVOID OldBase, IN PVOID NewBase, IN ULONG Size)
 
NTSTATUS NTAPI MiSnapThunk (IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA Name, IN PIMAGE_THUNK_DATA Address, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN SnapForwarder, OUT PCHAR *MissingApi)
 
NTSTATUS NTAPI MmUnloadSystemImage (IN PVOID ImageHandle)
 
NTSTATUS NTAPI MiResolveImageReferences (IN PVOID ImageBase, IN PUNICODE_STRING ImageFileDirectory, IN PUNICODE_STRING NamePrefix OPTIONAL, OUT PCHAR *MissingApi, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports)
 
VOID NTAPI MiFreeInitializationCode (IN PVOID InitStart, IN PVOID InitEnd)
 
VOID NTAPI MiFindInitializationCode (OUT PVOID *StartVa, OUT PVOID *EndVa)
 
VOID NTAPI MmFreeDriverInitialization (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
VOID NTAPI MiReloadBootLoadedDrivers (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
NTSTATUS NTAPI MiBuildImportsForBootDrivers (VOID)
 
VOID NTAPI MiLocateKernelSections (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
BOOLEAN NTAPI MiInitializeLoadedModuleList (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
BOOLEAN NTAPI MmChangeKernelResourceSectionProtection (IN ULONG_PTR ProtectionMask)
 
VOID NTAPI MmMakeKernelResourceSectionWritable (VOID)
 
LOGICAL NTAPI MiUseLargeDriverPage (IN ULONG NumberOfPtes, IN OUT PVOID *ImageBaseAddress, IN PUNICODE_STRING BaseImageName, IN BOOLEAN BootDriver)
 
VOID NTAPI MiSetSystemCodeProtection (_In_ PMMPTE FirstPte, _In_ PMMPTE LastPte, _In_ ULONG Protection)
 
VOID NTAPI MiWriteProtectSystemImage (_In_ PVOID ImageBase)
 
VOID NTAPI MiSetPagingOfDriver (IN PMMPTE PointerPte, IN PMMPTE LastPte)
 
VOID NTAPI MiEnablePagingOfDriver (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
BOOLEAN NTAPI MmVerifyImageIsOkForMpUse (IN PVOID BaseAddress)
 
NTSTATUS NTAPI MmCheckSystemImage (IN HANDLE ImageHandle, IN BOOLEAN PurgeSection)
 
PVOID NTAPI LdrpFetchAddressOfSecurityCookie (PVOID BaseAddress, ULONG SizeOfImage)
 
PVOID NTAPI LdrpInitSecurityCookie (PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSTATUS NTAPI MmLoadSystemImage (IN PUNICODE_STRING FileName, IN PUNICODE_STRING NamePrefix OPTIONAL, IN PUNICODE_STRING LoadedName OPTIONAL, IN ULONG Flags, OUT PVOID *ModuleObject, OUT PVOID *ImageBaseAddress)
 
PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry (IN PVOID Address)
 
PVOID NTAPI MmPageEntireDriver (IN PVOID AddressWithinSection)
 
VOID NTAPI MmResetDriverPaging (IN PVOID AddressWithinSection)
 
PVOID NTAPI MmGetSystemRoutineAddress (IN PUNICODE_STRING SystemRoutineName)
 

Variables

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

Macro Definition Documentation

◆ DEFAULT_SECURITY_COOKIE

#define DEFAULT_SECURITY_COOKIE   0xBB40E64E

Definition at line 43 of file sysldr.c.

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 16 of file sysldr.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file sysldr.c.

Function Documentation

◆ LdrpFetchAddressOfSecurityCookie()

PVOID NTAPI LdrpFetchAddressOfSecurityCookie ( PVOID  BaseAddress,
ULONG  SizeOfImage 
)

Definition at line 2808 of file sysldr.c.

2809 {
2810  PIMAGE_LOAD_CONFIG_DIRECTORY ConfigDir;
2811  ULONG DirSize;
2812  PVOID Cookie = NULL;
2813 
2814  /* Check NT header first */
2815  if (!RtlImageNtHeader(BaseAddress)) return NULL;
2816 
2817  /* Get the pointer to the config directory */
2819  TRUE,
2821  &DirSize);
2822 
2823  /* Check for sanity */
2824  if (!ConfigDir ||
2825  DirSize < FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY, SEHandlerTable) || /* SEHandlerTable is after SecurityCookie */
2826  (ConfigDir->Size != DirSize))
2827  {
2828  /* Invalid directory*/
2829  return NULL;
2830  }
2831 
2832  /* Now get the cookie */
2833  Cookie = (PVOID)ConfigDir->SecurityCookie;
2834 
2835  /* Check this cookie */
2836  if ((PCHAR)Cookie <= (PCHAR)BaseAddress ||
2837  (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage)
2838  {
2839  Cookie = NULL;
2840  }
2841 
2842  /* Return validated security cookie */
2843  return Cookie;
2844 }
signed char * PCHAR
Definition: retypes.h:7
#define TRUE
Definition: types.h:120
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
void * PVOID
Definition: retypes.h:9
#define PCHAR
Definition: match.c:90
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:13
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
#define RtlImageNtHeader
Definition: compat.h:806
unsigned int ULONG
Definition: retypes.h:1

Referenced by LdrpInitSecurityCookie().

◆ LdrpInitSecurityCookie()

PVOID NTAPI LdrpInitSecurityCookie ( PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2848 of file sysldr.c.

2849 {
2851  ULONG_PTR NewCookie;
2852 
2853  /* Fetch address of the cookie */
2855 
2856  if (Cookie)
2857  {
2858  /* Check if it's a default one */
2859  if ((*Cookie == DEFAULT_SECURITY_COOKIE) ||
2860  (*Cookie == 0))
2861  {
2863  /* The address should be unique */
2864  NewCookie = (ULONG_PTR)Cookie;
2865 
2866  /* We just need a simple tick, don't care about precision and whatnot */
2867  NewCookie ^= (ULONG_PTR)Counter.LowPart;
2868 
2869  /* If the result is 0 or the same as we got, just add one to the default value */
2870  if ((NewCookie == 0) || (NewCookie == *Cookie))
2871  {
2872  NewCookie = DEFAULT_SECURITY_COOKIE + 1;
2873  }
2874 
2875  /* Set the new cookie value */
2876  *Cookie = NewCookie;
2877  }
2878  }
2879 
2880  return Cookie;
2881 }
LARGE_INTEGER NTAPI KeQueryPerformanceCounter(IN PLARGE_INTEGER PerformanceFreq)
Definition: timer.c:138
#define DEFAULT_SECURITY_COOKIE
Definition: sysldr.c:43
ULONG SizeOfImage
Definition: ldrtypes.h:143
if(dx==0 &&dy==0)
Definition: linetemp.h:174
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID DllBase
Definition: btrfs_drv.h:1880
PVOID NTAPI LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: sysldr.c:2808
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:13
ULONG LowPart
Definition: typedefs.h:106
#define NULL
Definition: types.h:112
static LARGE_INTEGER Counter
Definition: clock.c:43
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:65

Referenced by MmLoadSystemImage().

◆ MiBuildImportsForBootDrivers()

NTSTATUS NTAPI MiBuildImportsForBootDrivers ( VOID  )

Definition at line 1869 of file sysldr.c.

1870 {
1871  PLIST_ENTRY NextEntry, NextEntry2;
1872  PLDR_DATA_TABLE_ENTRY LdrEntry, KernelEntry, HalEntry, LdrEntry2, LastEntry;
1873  PLDR_DATA_TABLE_ENTRY* EntryArray;
1874  UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
1876  PLOAD_IMPORTS LoadedImports;
1877  ULONG LoadedImportsSize, ImportSize;
1878  PULONG_PTR ImageThunk;
1879  ULONG_PTR DllBase, DllEnd;
1880  ULONG Modules = 0, i, j = 0;
1881  PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
1882 
1883  /* Initialize variables */
1884  KernelEntry = HalEntry = LastEntry = NULL;
1885 
1886  /* Loop the loaded module list... we are early enough that no lock is needed */
1887  NextEntry = PsLoadedModuleList.Flink;
1888  while (NextEntry != &PsLoadedModuleList)
1889  {
1890  /* Get the entry */
1891  LdrEntry = CONTAINING_RECORD(NextEntry,
1893  InLoadOrderLinks);
1894 
1895  /* Check if it's the kernel or HAL */
1896  if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
1897  {
1898  /* Found it */
1899  KernelEntry = LdrEntry;
1900  }
1901  else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
1902  {
1903  /* Found it */
1904  HalEntry = LdrEntry;
1905  }
1906 
1907  /* Check if this is a driver DLL */
1908  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1909  {
1910  /* Check if this is the HAL or kernel */
1911  if ((LdrEntry == HalEntry) || (LdrEntry == KernelEntry))
1912  {
1913  /* Add a reference */
1914  LdrEntry->LoadCount = 1;
1915  }
1916  else
1917  {
1918  /* No referencing needed */
1919  LdrEntry->LoadCount = 0;
1920  }
1921  }
1922  else
1923  {
1924  /* Add a reference for all other modules as well */
1925  LdrEntry->LoadCount = 1;
1926  }
1927 
1928  /* Remember this came from the loader */
1930 
1931  /* Keep looping */
1932  NextEntry = NextEntry->Flink;
1933  Modules++;
1934  }
1935 
1936  /* We must have at least found the kernel and HAL */
1937  if (!(HalEntry) || (!KernelEntry)) return STATUS_NOT_FOUND;
1938 
1939  /* Allocate the list */
1940  EntryArray = ExAllocatePoolWithTag(PagedPool, Modules * sizeof(PVOID), TAG_LDR_IMPORTS);
1941  if (!EntryArray) return STATUS_INSUFFICIENT_RESOURCES;
1942 
1943  /* Loop the loaded module list again */
1944  NextEntry = PsLoadedModuleList.Flink;
1945  while (NextEntry != &PsLoadedModuleList)
1946  {
1947  /* Get the entry */
1948  LdrEntry = CONTAINING_RECORD(NextEntry,
1950  InLoadOrderLinks);
1951 #ifdef _WORKING_LOADER_
1952  /* Get its imports */
1953  ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1954  TRUE,
1956  &ImportSize);
1957  if (!ImageThunk)
1958 #else
1959  /* Get its imports */
1960  ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1961  TRUE,
1963  &ImportSize);
1964  if (!ImportDescriptor)
1965 #endif
1966  {
1967  /* None present */
1968  LdrEntry->LoadedImports = MM_SYSLDR_NO_IMPORTS;
1969  NextEntry = NextEntry->Flink;
1970  continue;
1971  }
1972 
1973  /* Clear the list and count the number of IAT thunks */
1974  RtlZeroMemory(EntryArray, Modules * sizeof(PVOID));
1975 #ifdef _WORKING_LOADER_
1976  ImportSize /= sizeof(ULONG_PTR);
1977 
1978  /* Scan the thunks */
1979  for (i = 0, DllBase = 0, DllEnd = 0; i < ImportSize; i++, ImageThunk++)
1980 #else
1981  DllBase = DllEnd = i = 0;
1982  while ((ImportDescriptor->Name) &&
1983  (ImportDescriptor->OriginalFirstThunk))
1984  {
1985  /* Get the image thunk */
1986  ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
1987  ImportDescriptor->FirstThunk);
1988  while (*ImageThunk)
1989 #endif
1990  {
1991  /* Do we already have an address? */
1992  if (DllBase)
1993  {
1994  /* Is the thunk in the same address? */
1995  if ((*ImageThunk >= DllBase) && (*ImageThunk < DllEnd))
1996  {
1997  /* Skip it, we already have a reference for it */
1998  ASSERT(EntryArray[j]);
1999  ImageThunk++;
2000  continue;
2001  }
2002  }
2003 
2004  /* Loop the loaded module list to locate this address owner */
2005  j = 0;
2006  NextEntry2 = PsLoadedModuleList.Flink;
2007  while (NextEntry2 != &PsLoadedModuleList)
2008  {
2009  /* Get the entry */
2010  LdrEntry2 = CONTAINING_RECORD(NextEntry2,
2012  InLoadOrderLinks);
2013 
2014  /* Get the address range for this module */
2015  DllBase = (ULONG_PTR)LdrEntry2->DllBase;
2016  DllEnd = DllBase + LdrEntry2->SizeOfImage;
2017 
2018  /* Check if this IAT entry matches it */
2019  if ((*ImageThunk >= DllBase) && (*ImageThunk < DllEnd))
2020  {
2021  /* Save it */
2022  //DPRINT1("Found imported dll: %wZ\n", &LdrEntry2->BaseDllName);
2023  EntryArray[j] = LdrEntry2;
2024  break;
2025  }
2026 
2027  /* Keep searching */
2028  NextEntry2 = NextEntry2->Flink;
2029  j++;
2030  }
2031 
2032  /* Do we have a thunk outside the range? */
2033  if ((*ImageThunk < DllBase) || (*ImageThunk >= DllEnd))
2034  {
2035  /* Could be 0... */
2036  if (*ImageThunk)
2037  {
2038  /* Should not be happening */
2039  ERROR_FATAL("Broken IAT entry for %p at %p (%lx)\n",
2040  LdrEntry, ImageThunk, *ImageThunk);
2041  }
2042 
2043  /* Reset if we hit this */
2044  DllBase = 0;
2045  }
2046 #ifndef _WORKING_LOADER_
2047  ImageThunk++;
2048  }
2049 
2050  i++;
2051  ImportDescriptor++;
2052 #endif
2053  }
2054 
2055  /* Now scan how many imports we really have */
2056  for (i = 0, ImportSize = 0; i < Modules; i++)
2057  {
2058  /* Skip HAL and kernel */
2059  if ((EntryArray[i]) &&
2060  (EntryArray[i] != HalEntry) &&
2061  (EntryArray[i] != KernelEntry))
2062  {
2063  /* A valid reference */
2064  LastEntry = EntryArray[i];
2065  ImportSize++;
2066  }
2067  }
2068 
2069  /* Do we have any imports after all? */
2070  if (!ImportSize)
2071  {
2072  /* No */
2073  LdrEntry->LoadedImports = MM_SYSLDR_NO_IMPORTS;
2074  }
2075  else if (ImportSize == 1)
2076  {
2077  /* A single entry import */
2078  LdrEntry->LoadedImports = (PVOID)((ULONG_PTR)LastEntry | MM_SYSLDR_SINGLE_ENTRY);
2079  LastEntry->LoadCount++;
2080  }
2081  else
2082  {
2083  /* We need an import table */
2084  LoadedImportsSize = ImportSize * sizeof(PVOID) + sizeof(SIZE_T);
2085  LoadedImports = ExAllocatePoolWithTag(PagedPool,
2086  LoadedImportsSize,
2087  TAG_LDR_IMPORTS);
2088  ASSERT(LoadedImports);
2089 
2090  /* Save the count */
2091  LoadedImports->Count = ImportSize;
2092 
2093  /* Now copy all imports */
2094  for (i = 0, j = 0; i < Modules; i++)
2095  {
2096  /* Skip HAL and kernel */
2097  if ((EntryArray[i]) &&
2098  (EntryArray[i] != HalEntry) &&
2099  (EntryArray[i] != KernelEntry))
2100  {
2101  /* A valid reference */
2102  //DPRINT1("Found valid entry: %p\n", EntryArray[i]);
2103  LoadedImports->Entry[j] = EntryArray[i];
2104  EntryArray[i]->LoadCount++;
2105  j++;
2106  }
2107  }
2108 
2109  /* Should had as many entries as we expected */
2110  ASSERT(j == ImportSize);
2111  LdrEntry->LoadedImports = LoadedImports;
2112  }
2113 
2114  /* Next */
2115  NextEntry = NextEntry->Flink;
2116  }
2117 
2118  /* Free the initial array */
2119  ExFreePoolWithTag(EntryArray, TAG_LDR_IMPORTS);
2120 
2121  /* FIXME: Might not need to keep the HAL/Kernel imports around */
2122 
2123  /* Kernel and HAL are loaded at boot */
2124  KernelEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
2126 
2127  /* All worked well */
2128  return STATUS_SUCCESS;
2129 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PLDR_DATA_TABLE_ENTRY Entry[1]
Definition: ldrtypes.h:173
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:207
ULONG SizeOfImage
Definition: ldrtypes.h:143
#define TAG_LDR_IMPORTS
Definition: tag.h:103
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:56
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ERROR_FATAL(...)
Definition: debug.h:238
PVOID DllBase
Definition: btrfs_drv.h:1880
#define L(x)
Definition: ntvdm.h:50
PWCHAR HalName
Definition: halacpi.c:45
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define ASSERT(a)
Definition: mode.c:44
PVOID LoadedImports
Definition: ldrtypes.h:161
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
Definition: btrfs_drv.h:1876
Definition: typedefs.h:119
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:205
#define IMAGE_DIRECTORY_ENTRY_IAT
Definition: pedump.c:271
SIZE_T Count
Definition: ldrtypes.h:172
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:80
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
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define NULL
Definition: types.h:112
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
ULONG Flags
Definition: ntddk_ex.h:207
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
USHORT LoadCount
Definition: ntddk_ex.h:208
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by MiInitializeLoadedModuleList().

◆ MiCacheImageSymbols()

PVOID NTAPI MiCacheImageSymbols ( IN PVOID  BaseAddress)

Definition at line 50 of file sysldr.c.

51 {
52  ULONG DebugSize;
53  PVOID DebugDirectory = NULL;
54  PAGED_CODE();
55 
56  /* Make sure it's safe to access the image */
57  _SEH2_TRY
58  {
59  /* Get the debug directory */
61  TRUE,
63  &DebugSize);
64  }
66  {
67  /* Nothing */
68  }
69  _SEH2_END;
70 
71  /* Return the directory */
72  return DebugDirectory;
73 }
_SEH2_TRY
Definition: create.c:4226
#define TRUE
Definition: types.h:120
_SEH2_END
Definition: create.c:4400
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define IMAGE_DIRECTORY_ENTRY_DEBUG
Definition: compat.h:152
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define PAGED_CODE()

Referenced by MmLoadSystemImage().

◆ MiCallDllUnloadAndUnloadDll()

BOOLEAN NTAPI MiCallDllUnloadAndUnloadDll ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 357 of file sysldr.c.

358 {
361  PAGED_CODE();
362 
363  /* Get the unload routine */
364  Func = (PMM_DLL_UNLOAD)MiLocateExportName(LdrEntry->DllBase, "DllUnload");
365  if (!Func) return FALSE;
366 
367  /* Call it and check for success */
368  Status = Func();
369  if (!NT_SUCCESS(Status)) return FALSE;
370 
371  /* Lie about the load count so we can unload the image */
372  ASSERT(LdrEntry->LoadCount == 0);
373  LdrEntry->LoadCount = 1;
374 
375  /* Unload it and return true */
376  MmUnloadSystemImage(LdrEntry);
377  return TRUE;
378 }
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:898
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS(NTAPI * PMM_DLL_UNLOAD)(VOID)
Definition: iotypes.h:2854
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
void(* Func)(int)
PVOID NTAPI MiLocateExportName(IN PVOID DllBase, IN PCHAR ExportName)
Definition: sysldr.c:218
#define PAGED_CODE()

Referenced by MiDereferenceImports().

◆ MiClearImports()

VOID NTAPI MiClearImports ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 457 of file sysldr.c.

458 {
459  PAGED_CODE();
460 
461  /* Check if there's no imports or we're a boot driver or only one entry */
462  if ((LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) ||
463  (LdrEntry->LoadedImports == MM_SYSLDR_NO_IMPORTS) ||
464  ((ULONG_PTR)LdrEntry->LoadedImports & MM_SYSLDR_SINGLE_ENTRY))
465  {
466  /* Nothing to do */
467  return;
468  }
469 
470  /* Otherwise, free the import list */
471  ExFreePoolWithTag(LdrEntry->LoadedImports, TAG_LDR_IMPORTS);
472  LdrEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
473 }
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:207
#define TAG_LDR_IMPORTS
Definition: tag.h:103
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:205
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:204
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PAGED_CODE()

Referenced by MmUnloadSystemImage().

◆ MiDereferenceImports()

NTSTATUS NTAPI MiDereferenceImports ( IN PLOAD_IMPORTS  ImportList)

Definition at line 382 of file sysldr.c.

383 {
384  SIZE_T i;
385  LOAD_IMPORTS SingleEntry;
386  PLDR_DATA_TABLE_ENTRY LdrEntry;
387  PVOID CurrentImports;
388  PAGED_CODE();
389 
390  /* Check if there's no imports or if we're a boot driver */
391  if ((ImportList == MM_SYSLDR_NO_IMPORTS) ||
392  (ImportList == MM_SYSLDR_BOOT_LOADED) ||
393  (ImportList->Count == 0))
394  {
395  /* Then there's nothing to do */
396  return STATUS_SUCCESS;
397  }
398 
399  /* Check for single-entry */
400  if ((ULONG_PTR)ImportList & MM_SYSLDR_SINGLE_ENTRY)
401  {
402  /* Set it up */
403  SingleEntry.Count = 1;
404  SingleEntry.Entry[0] = (PVOID)((ULONG_PTR)ImportList &~ MM_SYSLDR_SINGLE_ENTRY);
405 
406  /* Use this as the import list */
407  ImportList = &SingleEntry;
408  }
409 
410  /* Loop the import list */
411  for (i = 0; (i < ImportList->Count) && (ImportList->Entry[i]); i++)
412  {
413  /* Get the entry */
414  LdrEntry = ImportList->Entry[i];
415  DPRINT1("%wZ <%wZ>\n", &LdrEntry->FullDllName, &LdrEntry->BaseDllName);
416 
417  /* Skip boot loaded images */
418  if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) continue;
419 
420  /* Dereference the entry */
421  ASSERT(LdrEntry->LoadCount >= 1);
422  if (!--LdrEntry->LoadCount)
423  {
424  /* Save the import data in case unload fails */
425  CurrentImports = LdrEntry->LoadedImports;
426 
427  /* This is the last entry */
429  if (MiCallDllUnloadAndUnloadDll(LdrEntry))
430  {
431  /* Unloading worked, parse this DLL's imports too */
432  MiDereferenceImports(CurrentImports);
433 
434  /* Check if we had valid imports */
435  if ((CurrentImports != MM_SYSLDR_BOOT_LOADED) &&
436  (CurrentImports != MM_SYSLDR_NO_IMPORTS) &&
437  !((ULONG_PTR)CurrentImports & MM_SYSLDR_SINGLE_ENTRY))
438  {
439  /* Free them */
440  ExFreePoolWithTag(CurrentImports, TAG_LDR_IMPORTS);
441  }
442  }
443  else
444  {
445  /* Unload failed, restore imports */
446  LdrEntry->LoadedImports = CurrentImports;
447  }
448  }
449  }
450 
451  /* Done */
452  return STATUS_SUCCESS;
453 }
PLDR_DATA_TABLE_ENTRY Entry[1]
Definition: ldrtypes.h:173
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:207
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:382
#define TAG_LDR_IMPORTS
Definition: tag.h:103
uint32_t ULONG_PTR
Definition: typedefs.h:65
void * PVOID
Definition: retypes.h:9
#define ASSERT(a)
Definition: mode.c:44
PVOID LoadedImports
Definition: ldrtypes.h:161
Definition: btrfs_drv.h:1876
BOOLEAN NTAPI MiCallDllUnloadAndUnloadDll(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:357
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:205
SIZE_T Count
Definition: ldrtypes.h:172
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:80
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
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define DPRINT1
Definition: precomp.h:8
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
USHORT LoadCount
Definition: ntddk_ex.h:208
#define PAGED_CODE()

Referenced by MiResolveImageReferences(), and MmUnloadSystemImage().

◆ MiEnablePagingOfDriver()

VOID NTAPI MiEnablePagingOfDriver ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2606 of file sysldr.c.

2607 {
2608  ULONG_PTR ImageBase;
2609  PIMAGE_NT_HEADERS NtHeaders;
2610  ULONG Sections, Alignment, Size;
2611  PIMAGE_SECTION_HEADER Section;
2612  PMMPTE PointerPte = NULL, LastPte = NULL;
2613  if (MmDisablePagingExecutive) return;
2614 
2615  /* Get the driver base address and its NT header */
2616  ImageBase = (ULONG_PTR)LdrEntry->DllBase;
2617  NtHeaders = RtlImageNtHeader((PVOID)ImageBase);
2618  if (!NtHeaders) return;
2619 
2620  /* Get the sections and their alignment */
2621  Sections = NtHeaders->FileHeader.NumberOfSections;
2622  Alignment = NtHeaders->OptionalHeader.SectionAlignment - 1;
2623 
2624  /* Loop each section */
2625  Section = IMAGE_FIRST_SECTION(NtHeaders);
2626  while (Sections)
2627  {
2628  /* Find PAGE or .edata */
2629  if ((*(PULONG)Section->Name == 'EGAP') ||
2630  (*(PULONG)Section->Name == 'ade.'))
2631  {
2632  /* Had we already done some work? */
2633  if (!PointerPte)
2634  {
2635  /* Nope, setup the first PTE address */
2636  PointerPte = MiAddressToPte(ROUND_TO_PAGES(ImageBase +
2637  Section->VirtualAddress));
2638  }
2639 
2640  /* Compute the size */
2641  Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2642 
2643  /* Find the last PTE that maps this section */
2644  LastPte = MiAddressToPte(ImageBase +
2645  Section->VirtualAddress +
2646  Alignment + Size - PAGE_SIZE);
2647  }
2648  else
2649  {
2650  /* Had we found a section before? */
2651  if (PointerPte)
2652  {
2653  /* Mark it as pageable */
2654  MiSetPagingOfDriver(PointerPte, LastPte);
2655  PointerPte = NULL;
2656  }
2657  }
2658 
2659  /* Keep searching */
2660  Sections--;
2661  Section++;
2662  }
2663 
2664  /* Handle the straggler */
2665  if (PointerPte) MiSetPagingOfDriver(PointerPte, LastPte);
2666 }
#define max(a, b)
Definition: svc.c:63
union _IMAGE_SECTION_HEADER::@1517 Misc
VOID NTAPI MiSetPagingOfDriver(IN PMMPTE PointerPte, IN PMMPTE LastPte)
Definition: sysldr.c:2547
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
union Alignment_ Alignment
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#define ROUND_TO_PAGES(Size)
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
#define RtlImageNtHeader
Definition: compat.h:806
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
UCHAR MmDisablePagingExecutive
Definition: mminit.c:25

Referenced by MmLoadSystemImage().

◆ MiFindExportedRoutineByName()

PVOID NTAPI MiFindExportedRoutineByName ( IN PVOID  DllBase,
IN PANSI_STRING  ExportName 
)

Definition at line 477 of file sysldr.c.

479 {
480  PULONG NameTable;
481  PUSHORT OrdinalTable;
482  PIMAGE_EXPORT_DIRECTORY ExportDirectory;
483  LONG Low = 0, Mid = 0, High, Ret;
484  USHORT Ordinal;
485  PVOID Function;
486  ULONG ExportSize;
487  PULONG ExportTable;
488  PAGED_CODE();
489 
490  /* Get the export directory */
491  ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
492  TRUE,
494  &ExportSize);
495  if (!ExportDirectory) return NULL;
496 
497  /* Setup name tables */
498  NameTable = (PULONG)((ULONG_PTR)DllBase +
499  ExportDirectory->AddressOfNames);
500  OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
501  ExportDirectory->AddressOfNameOrdinals);
502 
503  /* Do a binary search */
504  High = ExportDirectory->NumberOfNames - 1;
505  while (High >= Low)
506  {
507  /* Get new middle value */
508  Mid = (Low + High) >> 1;
509 
510  /* Compare name */
511  Ret = strcmp(ExportName->Buffer, (PCHAR)DllBase + NameTable[Mid]);
512  if (Ret < 0)
513  {
514  /* Update high */
515  High = Mid - 1;
516  }
517  else if (Ret > 0)
518  {
519  /* Update low */
520  Low = Mid + 1;
521  }
522  else
523  {
524  /* We got it */
525  break;
526  }
527  }
528 
529  /* Check if we couldn't find it */
530  if (High < Low) return NULL;
531 
532  /* Otherwise, this is the ordinal */
533  Ordinal = OrdinalTable[Mid];
534 
535  /* Validate the ordinal */
536  if (Ordinal >= ExportDirectory->NumberOfFunctions) return NULL;
537 
538  /* Resolve the address and write it */
539  ExportTable = (PULONG)((ULONG_PTR)DllBase +
540  ExportDirectory->AddressOfFunctions);
541  Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
542 
543  /* We found it! */
544  ASSERT((Function < (PVOID)ExportDirectory) ||
545  (Function > (PVOID)((ULONG_PTR)ExportDirectory + ExportSize)));
546 
547  return Function;
548 }
signed char * PCHAR
Definition: retypes.h:7
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1154
#define TRUE
Definition: types.h:120
Definition: strmini.h:380
DWORD AddressOfNameOrdinals
Definition: compat.h:167
uint32_t ULONG_PTR
Definition: typedefs.h:65
long LONG
Definition: pedump.c:60
void * PVOID
Definition: retypes.h:9
#define ASSERT(a)
Definition: mode.c:44
Definition: strmini.h:378
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
unsigned short * PUSHORT
Definition: retypes.h:2
#define PAGED_CODE()

Referenced by MmGetSystemRoutineAddress().

◆ MiFindInitializationCode()

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

Definition at line 1437 of file sysldr.c.

1439 {
1440  ULONG Size, SectionCount, Alignment;
1441  PLDR_DATA_TABLE_ENTRY LdrEntry;
1442  ULONG_PTR DllBase, InitStart, InitEnd, ImageEnd, InitCode;
1443  PLIST_ENTRY NextEntry;
1444  PIMAGE_NT_HEADERS NtHeader;
1445  PIMAGE_SECTION_HEADER Section, LastSection, InitSection;
1446  BOOLEAN InitFound;
1447  DBG_UNREFERENCED_LOCAL_VARIABLE(InitSection);
1448 
1449  /* So we don't free our own code yet */
1450  InitCode = (ULONG_PTR)&MiFindInitializationCode;
1451 
1452  /* Assume failure */
1453  *StartVa = NULL;
1454 
1455  /* Acquire the necessary locks while we loop the list */
1459  KernelMode,
1460  FALSE,
1461  NULL);
1463 
1464  /* Loop all loaded modules */
1465  NextEntry = PsLoadedModuleList.Flink;
1466  while (NextEntry != &PsLoadedModuleList)
1467  {
1468  /* Get the loader entry and its DLL base */
1469  LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1470  DllBase = (ULONG_PTR)LdrEntry->DllBase;
1471 
1472  /* Only process boot loaded images. Other drivers are processed by
1473  MmFreeDriverInitialization */
1474  if (LdrEntry->Flags & LDRP_MM_LOADED)
1475  {
1476  /* Keep going */
1477  NextEntry = NextEntry->Flink;
1478  continue;
1479  }
1480 
1481  /* Get the NT header */
1482  NtHeader = RtlImageNtHeader((PVOID)DllBase);
1483  if (!NtHeader)
1484  {
1485  /* Keep going */
1486  NextEntry = NextEntry->Flink;
1487  continue;
1488  }
1489 
1490  /* Get the first section, the section count, and scan them all */
1491  Section = IMAGE_FIRST_SECTION(NtHeader);
1492  SectionCount = NtHeader->FileHeader.NumberOfSections;
1493  InitStart = 0;
1494  while (SectionCount > 0)
1495  {
1496  /* Assume failure */
1497  InitFound = FALSE;
1498 
1499  /* Is this the INIT section or a discardable section? */
1500  if ((strncmp((PCCH)Section->Name, "INIT", 5) == 0) ||
1502  {
1503  /* Remember this */
1504  InitFound = TRUE;
1505  InitSection = Section;
1506  }
1507 
1508  if (InitFound)
1509  {
1510  /* Pick the biggest size -- either raw or virtual */
1511  Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
1512 
1513  /* Read the section alignment */
1515 
1516  /* Get the start and end addresses */
1517  InitStart = DllBase + Section->VirtualAddress;
1518  InitEnd = ALIGN_UP_BY(InitStart + Size, Alignment);
1519 
1520  /* Align the addresses to PAGE_SIZE */
1521  InitStart = ALIGN_UP_BY(InitStart, PAGE_SIZE);
1522  InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1523 
1524  /* Have we reached the last section? */
1525  if (SectionCount == 1)
1526  {
1527  /* Remember this */
1528  LastSection = Section;
1529  }
1530  else
1531  {
1532  /* We have not, loop all the sections */
1533  LastSection = NULL;
1534  do
1535  {
1536  /* Keep going until we find a non-discardable section range */
1537  SectionCount--;
1538  Section++;
1540  {
1541  /* Discardable, so record it, then keep going */
1542  LastSection = Section;
1543  }
1544  else
1545  {
1546  /* Non-contigous discard flag, or no flag, break out */
1547  break;
1548  }
1549  }
1550  while (SectionCount > 1);
1551  }
1552 
1553  /* Have we found a discardable or init section? */
1554  if (LastSection)
1555  {
1556  /* Pick the biggest size -- either raw or virtual */
1557  Size = max(LastSection->SizeOfRawData, LastSection->Misc.VirtualSize);
1558 
1559  /* Use this as the end of the section address */
1560  InitEnd = DllBase + LastSection->VirtualAddress + Size;
1561 
1562  /* Have we reached the last section yet? */
1563  if (SectionCount != 1)
1564  {
1565  /* Then align this accross the session boundary */
1566  InitEnd = ALIGN_UP_BY(InitEnd, Alignment);
1567  InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1568  }
1569  }
1570 
1571  /* Make sure we don't let the init section go past the image */
1572  ImageEnd = DllBase + LdrEntry->SizeOfImage;
1573  if (InitEnd > ImageEnd) InitEnd = ALIGN_UP_BY(ImageEnd, PAGE_SIZE);
1574 
1575  /* Make sure we have a valid, non-zero init section */
1576  if (InitStart < InitEnd)
1577  {
1578  /* Make sure we are not within this code itself */
1579  if ((InitCode >= InitStart) && (InitCode < InitEnd))
1580  {
1581  /* Return it, we can't free ourselves now */
1582  ASSERT(*StartVa == 0);
1583  *StartVa = (PVOID)InitStart;
1584  *EndVa = (PVOID)InitEnd;
1585  }
1586  else
1587  {
1588  /* This isn't us -- go ahead and free it */
1589  ASSERT(MI_IS_PHYSICAL_ADDRESS((PVOID)InitStart) == FALSE);
1590  DPRINT("Freeing init code: %p-%p ('%wZ' @%p : '%s')\n",
1591  (PVOID)InitStart,
1592  (PVOID)InitEnd,
1593  &LdrEntry->BaseDllName,
1594  LdrEntry->DllBase,
1595  InitSection->Name);
1596  MiFreeInitializationCode((PVOID)InitStart, (PVOID)InitEnd);
1597  }
1598  }
1599  }
1600 
1601  /* Move to the next section */
1602  SectionCount--;
1603  Section++;
1604  }
1605 
1606  /* Move to the next module */
1607  NextEntry = NextEntry->Flink;
1608  }
1609 
1610  /* Release the locks and return */
1614 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
union _IMAGE_SECTION_HEADER::@1517 Misc
ULONG SizeOfImage
Definition: ldrtypes.h:143
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
if(dx==0 &&dy==0)
Definition: linetemp.h:174
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
uint32_t ULONG_PTR
Definition: typedefs.h:65
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
PVOID DllBase
Definition: btrfs_drv.h:1880
VOID NTAPI MiFreeInitializationCode(IN PVOID InitStart, IN PVOID InitEnd)
Definition: sysldr.c:1414
#define FALSE
Definition: types.h:117
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
union Alignment_ Alignment
unsigned char BOOLEAN
void * PVOID
Definition: retypes.h:9
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:319
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
CONST CHAR * PCCH
Definition: ntbasedef.h:392
#define ASSERT(a)
Definition: mode.c:44
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
KMUTANT MmSystemLoadLock
Definition: sysldr.c:26
#define MUTANT_INCREMENT
Definition: extypes.h:84
LONG NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
Definition: mutex.c:98
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
Definition: btrfs_drv.h:1876
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:119
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#define ALIGN_DOWN_BY(size, align)
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define NULL
Definition: types.h:112
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
#define RtlImageNtHeader
Definition: compat.h:806
ULONG Flags
Definition: ntddk_ex.h:207
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define ALIGN_UP_BY(size, align)
#define DPRINT
Definition: sndvol32.h:71
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1437
#define LDRP_MM_LOADED
Definition: ldrtypes.h:60
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiFreeInitializationCode()

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

Definition at line 1414 of file sysldr.c.

1416 {
1417  PMMPTE PointerPte;
1418  PFN_NUMBER PagesFreed;
1419 
1420  /* Get the start PTE */
1421  PointerPte = MiAddressToPte(InitStart);
1422  ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE);
1423 
1424  /* Compute the number of pages we expect to free */
1425  PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte);
1426 
1427  /* Try to actually free them */
1428  PagesFreed = MiDeleteSystemPageableVm(PointerPte,
1429  PagesFreed,
1430  0,
1431  NULL);
1432 }
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
#define NULL
Definition: types.h:112
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiInitializeLoadedModuleList()

BOOLEAN NTAPI MiInitializeLoadedModuleList ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 2191 of file sysldr.c.

2192 {
2193  PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
2194  PLIST_ENTRY ListHead, NextEntry;
2195  ULONG EntrySize;
2196 
2197  /* Setup the loaded module list and locks */
2201 
2202  /* Get loop variables and the kernel entry */
2203  ListHead = &LoaderBlock->LoadOrderListHead;
2204  NextEntry = ListHead->Flink;
2205  LdrEntry = CONTAINING_RECORD(NextEntry,
2207  InLoadOrderLinks);
2208  PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
2209 
2210  /* Locate resource section, pool code, and system pte code */
2211  MiLocateKernelSections(LdrEntry);
2212 
2213  /* Loop the loader block */
2214  while (NextEntry != ListHead)
2215  {
2216  /* Get the loader entry */
2217  LdrEntry = CONTAINING_RECORD(NextEntry,
2219  InLoadOrderLinks);
2220 
2221  /* FIXME: ROS HACK. Make sure this is a driver */
2222  if (!RtlImageNtHeader(LdrEntry->DllBase))
2223  {
2224  /* Skip this entry */
2225  NextEntry = NextEntry->Flink;
2226  continue;
2227  }
2228 
2229  /* Calculate the size we'll need and allocate a copy */
2230  EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
2231  LdrEntry->BaseDllName.MaximumLength +
2232  sizeof(UNICODE_NULL);
2234  if (!NewEntry) return FALSE;
2235 
2236  /* Copy the entry over */
2237  *NewEntry = *LdrEntry;
2238 
2239  /* Allocate the name */
2240  NewEntry->FullDllName.Buffer =
2242  LdrEntry->FullDllName.MaximumLength +
2243  sizeof(UNICODE_NULL),
2244  TAG_LDR_WSTR);
2245  if (!NewEntry->FullDllName.Buffer)
2246  {
2248  return FALSE;
2249  }
2250 
2251  /* Set the base name */
2252  NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
2253 
2254  /* Copy the full and base name */
2255  RtlCopyMemory(NewEntry->FullDllName.Buffer,
2256  LdrEntry->FullDllName.Buffer,
2257  LdrEntry->FullDllName.MaximumLength);
2258  RtlCopyMemory(NewEntry->BaseDllName.Buffer,
2259  LdrEntry->BaseDllName.Buffer,
2260  LdrEntry->BaseDllName.MaximumLength);
2261 
2262  /* Null-terminate the base name */
2263  NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
2264  sizeof(WCHAR)] = UNICODE_NULL;
2265 
2266  /* Insert the entry into the list */
2268  NextEntry = NextEntry->Flink;
2269  }
2270 
2271  /* Build the import lists for the boot drivers */
2273 
2274  /* We're done */
2275  return TRUE;
2276 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY
VOID NTAPI MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2134
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG_PTR PsNtosImageBase
Definition: sysldr.c:25
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define InsertTailList(ListHead, Entry)
_In_ UCHAR EntrySize
Definition: iofuncs.h:642
KSPIN_LOCK PsLoadedModuleSpinLock
Definition: sysldr.c:23
PVOID DllBase
Definition: btrfs_drv.h:1880
#define TAG_LDR_WSTR
Definition: tag.h:102
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:240
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Definition: btrfs_drv.h:1876
Definition: typedefs.h:119
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NTSTATUS NTAPI MiBuildImportsForBootDrivers(VOID)
Definition: sysldr.c:1869
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define RtlImageNtHeader
Definition: compat.h:806
#define TAG_MODULE_OBJECT
Definition: tag.h:101
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by MmArmInitSystem().

◆ MiLoadImageSection()

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

Definition at line 77 of file sysldr.c.

82 {
83  PSECTION Section = *SectionPtr;
86  PVOID Base = NULL;
87  SIZE_T ViewSize = 0;
89  LARGE_INTEGER SectionOffset = {{0, 0}};
91  PFN_COUNT PteCount;
92  PMMPTE PointerPte, LastPte;
93  PVOID DriverBase;
94  MMPTE TempPte;
95  KIRQL OldIrql;
96  PFN_NUMBER PageFrameIndex;
97  PAGED_CODE();
98 
99  /* Detect session load */
100  if (SessionLoad)
101  {
102  /* Fail */
103  UNIMPLEMENTED_DBGBREAK("Session loading not yet supported!\n");
104  return STATUS_NOT_IMPLEMENTED;
105  }
106 
107  /* Not session load, shouldn't have an entry */
108  ASSERT(LdrEntry == NULL);
109 
110  /* Attach to the system process */
112 
113  /* Check if we need to load symbols */
115  {
116  /* Yes we do */
117  LoadSymbols = TRUE;
119  }
120 
121  /* Map the driver */
123  Status = MmMapViewOfSection(Section,
124  Process,
125  &Base,
126  0,
127  0,
128  &SectionOffset,
129  &ViewSize,
130  ViewUnmap,
131  0,
132  PAGE_EXECUTE);
133 
134  /* Re-enable the flag */
136 
137  /* Check if we failed with distinguished status code */
139  {
140  /* Change it to something more generic */
142  }
143 
144  /* Now check if we failed */
145  if (!NT_SUCCESS(Status))
146  {
147  /* Detach and return */
148  DPRINT1("MmMapViewOfSection failed with status 0x%x\n", Status);
150  return Status;
151  }
152 
153  /* Reserve system PTEs needed */
154  PteCount = ROUND_TO_PAGES(((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize) >> PAGE_SHIFT;
155  PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
156  if (!PointerPte)
157  {
158  DPRINT1("MiReserveSystemPtes failed\n");
161  }
162 
163  /* New driver base */
164  LastPte = PointerPte + PteCount;
165  DriverBase = MiPteToAddress(PointerPte);
166 
167  /* The driver is here */
168  *ImageBase = DriverBase;
169  DPRINT1("Loading: %wZ at %p with %lx pages\n", FileName, DriverBase, PteCount);
170 
171  /* Lock the PFN database */
172  OldIrql = MiAcquirePfnLock();
173 
174  /* Loop the new driver PTEs */
176  while (PointerPte < LastPte)
177  {
178  /* Make sure the PTE is not valid for whatever reason */
179  ASSERT(PointerPte->u.Hard.Valid == 0);
180 
181  /* Some debug stuff */
183 #if MI_TRACE_PFNS
184  MI_SET_PROCESS_USTR(FileName);
185 #endif
186 
187  /* Grab a page */
188  PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
189 
190  /* Initialize its PFN entry */
191  MiInitializePfn(PageFrameIndex, PointerPte, TRUE);
192 
193  /* Write the PTE */
194  TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
195  MI_WRITE_VALID_PTE(PointerPte, TempPte);
196 
197  /* Move on */
198  PointerPte++;
199  }
200 
201  /* Release the PFN lock */
202  MiReleasePfnLock(OldIrql);
203 
204  /* Copy the image */
205  RtlCopyMemory(DriverBase, Base, PteCount << PAGE_SHIFT);
206 
207  /* Now unmap the view */
210 
211  /* Detach and return status */
213  return Status;
214 }
VOID NTAPI MiInitializePfn(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN BOOLEAN Modified)
Definition: pfnlist.c:962
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
KAPC_STATE
Definition: ketypes.h:1285
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PSEGMENT Segment
Definition: mmtypes.h:809
union _MMPTE::@2288 u
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define TRUE
Definition: types.h:120
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2427
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:237
UCHAR KIRQL
Definition: env_spec_w32.h:591
return STATUS_NOT_IMPLEMENTED
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:964
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
#define PAGE_EXECUTE
Definition: nt_native.h:1306
#define MI_SET_USAGE(x)
Definition: mm.h:317
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:3918
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:404
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3117
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG64 Valid
Definition: mmtypes.h:150
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
MMPTE ValidKernelPte
Definition: init.c:29
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH
Definition: ntstatus.h:128
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
KPROCESS Pcb
Definition: pstypes.h:1262
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
ULONG_PTR SIZE_T
Definition: typedefs.h:80
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define ROUND_TO_PAGES(Size)
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1727
#define NULL
Definition: types.h:112
#define FLG_ENABLE_KDEBUG_SYMBOL_LOAD
Definition: pstypes.h:73
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
static BOOLEAN LoadSymbols
Definition: kdb_symbols.c:29
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:208
ULONG NtGlobalFlag
Definition: init.c:54
ULONG PageFrameNumber
Definition: mmtypes.h:109
#define PAGED_CODE()

Referenced by MmLoadSystemImage().

◆ MiLocateExportName()

PVOID NTAPI MiLocateExportName ( IN PVOID  DllBase,
IN PCHAR  ExportName 
)

Definition at line 218 of file sysldr.c.

220 {
221  PULONG NameTable;
222  PUSHORT OrdinalTable;
223  PIMAGE_EXPORT_DIRECTORY ExportDirectory;
224  LONG Low = 0, Mid = 0, High, Ret;
225  USHORT Ordinal;
226  PVOID Function;
227  ULONG ExportSize;
228  PULONG ExportTable;
229  PAGED_CODE();
230 
231  /* Get the export directory */
232  ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
233  TRUE,
235  &ExportSize);
236  if (!ExportDirectory) return NULL;
237 
238  /* Setup name tables */
239  NameTable = (PULONG)((ULONG_PTR)DllBase +
240  ExportDirectory->AddressOfNames);
241  OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
242  ExportDirectory->AddressOfNameOrdinals);
243 
244  /* Do a binary search */
245  High = ExportDirectory->NumberOfNames - 1;
246  while (High >= Low)
247  {
248  /* Get new middle value */
249  Mid = (Low + High) >> 1;
250 
251  /* Compare name */
252  Ret = strcmp(ExportName, (PCHAR)DllBase + NameTable[Mid]);
253  if (Ret < 0)
254  {
255  /* Update high */
256  High = Mid - 1;
257  }
258  else if (Ret > 0)
259  {
260  /* Update low */
261  Low = Mid + 1;
262  }
263  else
264  {
265  /* We got it */
266  break;
267  }
268  }
269 
270  /* Check if we couldn't find it */
271  if (High < Low) return NULL;
272 
273  /* Otherwise, this is the ordinal */
274  Ordinal = OrdinalTable[Mid];
275 
276  /* Resolve the address and write it */
277  ExportTable = (PULONG)((ULONG_PTR)DllBase +
278  ExportDirectory->AddressOfFunctions);
279  Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
280 
281  /* Check if the function is actually a forwarder */
282  if (((ULONG_PTR)Function > (ULONG_PTR)ExportDirectory) &&
283  ((ULONG_PTR)Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
284  {
285  /* It is, fail */
286  return NULL;
287  }
288 
289  /* We found it */
290  return Function;
291 }
signed char * PCHAR
Definition: retypes.h:7
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1154
#define TRUE
Definition: types.h:120
Definition: strmini.h:380
DWORD AddressOfNameOrdinals
Definition: compat.h:167
uint32_t ULONG_PTR
Definition: typedefs.h:65
long LONG
Definition: pedump.c:60
void * PVOID
Definition: retypes.h:9
Definition: strmini.h:378
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define ULONG_PTR
Definition: config.h:101
unsigned short * PUSHORT
Definition: retypes.h:2
#define PAGED_CODE()

Referenced by MiCallDllUnloadAndUnloadDll(), and MmCallDllInitialize().

◆ MiLocateKernelSections()

VOID NTAPI MiLocateKernelSections ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2134 of file sysldr.c.

2135 {
2136  ULONG_PTR DllBase;
2137  PIMAGE_NT_HEADERS NtHeaders;
2138  PIMAGE_SECTION_HEADER SectionHeader;
2139  ULONG Sections, Size;
2140 
2141  /* Get the kernel section header */
2142  DllBase = (ULONG_PTR)LdrEntry->DllBase;
2143  NtHeaders = RtlImageNtHeader((PVOID)DllBase);
2144  SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
2145 
2146  /* Loop all the sections */
2147  for (Sections = NtHeaders->FileHeader.NumberOfSections;
2148  Sections > 0; --Sections, ++SectionHeader)
2149  {
2150  /* Grab the size of the section */
2151  Size = max(SectionHeader->SizeOfRawData, SectionHeader->Misc.VirtualSize);
2152 
2153  /* Check for .RSRC section */
2154  if (*(PULONG)SectionHeader->Name == 'rsr.')
2155  {
2156  /* Remember the PTEs so we can modify them later */
2158  SectionHeader->VirtualAddress);
2160  SectionHeader->VirtualAddress + Size));
2161  }
2162  else if (*(PULONG)SectionHeader->Name == 'LOOP')
2163  {
2164  /* POOLCODE vs. POOLMI */
2165  if (*(PULONG)&SectionHeader->Name[4] == 'EDOC')
2166  {
2167  /* Found Ex* Pool code */
2168  ExPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2170  }
2171  else if (*(PUSHORT)&SectionHeader->Name[4] == 'MI')
2172  {
2173  /* Found Mm* Pool code */
2174  MmPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2176  }
2177  }
2178  else if ((*(PULONG)SectionHeader->Name == 'YSIM') &&
2179  (*(PULONG)&SectionHeader->Name[4] == 'ETPS'))
2180  {
2181  /* Found MISYSPTE (Mm System PTE code) */
2182  MmPteCodeStart = DllBase + SectionHeader->VirtualAddress;
2184  }
2185  }
2186 }
#define max(a, b)
Definition: svc.c:63
PMMPTE MiKernelResourceEndPte
Definition: sysldr.c:36
ULONG_PTR MmPoolCodeStart
Definition: sysldr.c:37
union _IMAGE_SECTION_HEADER::@1517 Misc
ULONG_PTR MmPoolCodeEnd
Definition: sysldr.c:37
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG_PTR MmPteCodeStart
Definition: sysldr.c:38
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
ULONG_PTR MmPteCodeEnd
Definition: sysldr.c:38
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
ULONG_PTR ExPoolCodeStart
Definition: sysldr.c:37
ULONG_PTR ExPoolCodeEnd
Definition: sysldr.c:37
#define ROUND_TO_PAGES(Size)
unsigned int * PULONG
Definition: retypes.h:1
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
#define RtlImageNtHeader
Definition: compat.h:806
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
PMMPTE MiKernelResourceStartPte
Definition: sysldr.c:36
unsigned short * PUSHORT
Definition: retypes.h:2

Referenced by MiInitializeLoadedModuleList().

◆ MiLookupDataTableEntry()

PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry ( IN PVOID  Address)

Definition at line 3464 of file sysldr.c.

3465 {
3466  PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL;
3467  PLIST_ENTRY NextEntry;
3468  PAGED_CODE();
3469 
3470  /* Loop entries */
3471  NextEntry = PsLoadedModuleList.Flink;
3472  do
3473  {
3474  /* Get the loader entry */
3475  LdrEntry = CONTAINING_RECORD(NextEntry,
3477  InLoadOrderLinks);
3478 
3479  /* Check if the address matches */
3480  if ((Address >= LdrEntry->DllBase) &&
3481  (Address < (PVOID)((ULONG_PTR)LdrEntry->DllBase +
3482  LdrEntry->SizeOfImage)))
3483  {
3484  /* Found a match */
3485  FoundEntry = LdrEntry;
3486  break;
3487  }
3488 
3489  /* Move on */
3490  NextEntry = NextEntry->Flink;
3491  } while(NextEntry != &PsLoadedModuleList);
3492 
3493  /* Return the entry */
3494  return FoundEntry;
3495 }
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
ULONG SizeOfImage
Definition: ldrtypes.h:143
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID DllBase
Definition: btrfs_drv.h:1880
static WCHAR Address[46]
Definition: ping.c:68
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: btrfs_drv.h:1876
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
#define PAGED_CODE()

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

◆ MiProcessLoaderEntry()

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

Definition at line 552 of file sysldr.c.

554 {
555  KIRQL OldIrql;
556 
557  /* Acquire module list lock */
560 
561  /* Acquire the spinlock too as we will insert or remove the entry */
563 
564  /* Insert or remove from the list */
565  if (Insert)
566  InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks);
567  else
568  RemoveEntryList(&LdrEntry->InLoadOrderLinks);
569 
570  /* Release locks */
574 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
#define InsertTailList(ListHead, Entry)
KSPIN_LOCK PsLoadedModuleSpinLock
Definition: sysldr.c:23
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#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 1680 of file sysldr.c.

1681 {
1682  PLIST_ENTRY NextEntry;
1683  ULONG i = 0;
1684  PIMAGE_NT_HEADERS NtHeader;
1685  PLDR_DATA_TABLE_ENTRY LdrEntry;
1686  PIMAGE_FILE_HEADER FileHeader;
1687  BOOLEAN ValidRelocs;
1688  PIMAGE_DATA_DIRECTORY DataDirectory;
1689  PVOID DllBase, NewImageAddress;
1690  NTSTATUS Status;
1691  PMMPTE PointerPte, StartPte, LastPte;
1692  PFN_COUNT PteCount;
1693  PMMPFN Pfn1;
1694  MMPTE TempPte, OldPte;
1695 
1696  /* Loop driver list */
1697  for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
1698  NextEntry != &LoaderBlock->LoadOrderListHead;
1699  NextEntry = NextEntry->Flink)
1700  {
1701  /* Get the loader entry and NT header */
1702  LdrEntry = CONTAINING_RECORD(NextEntry,
1704  InLoadOrderLinks);
1705  NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
1706 
1707  /* Debug info */
1708  DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",
1709  LdrEntry->DllBase,
1710  (ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage,
1711  &LdrEntry->FullDllName);
1712 
1713  /* Get the first PTE and the number of PTEs we'll need */
1714  PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
1715  PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
1716  LastPte = StartPte + PteCount;
1717 
1718 #if MI_TRACE_PFNS
1719  /* Loop the PTEs */
1720  while (PointerPte < LastPte)
1721  {
1722  ULONG len;
1723  ASSERT(PointerPte->u.Hard.Valid == 1);
1724  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1725  len = wcslen(LdrEntry->BaseDllName.Buffer) * sizeof(WCHAR);
1726  snprintf(Pfn1->ProcessName, min(16, len), "%S", LdrEntry->BaseDllName.Buffer);
1727  PointerPte++;
1728  }
1729 #endif
1730  /* Skip kernel and HAL */
1731  /* ROS HACK: Skip BOOTVID/KDCOM too */
1732  i++;
1733  if (i <= 4) continue;
1734 
1735  /* Skip non-drivers */
1736  if (!NtHeader) continue;
1737 
1738  /* Get the file header and make sure we can relocate */
1739  FileHeader = &NtHeader->FileHeader;
1740  if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;
1741  if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <
1743 
1744  /* Everything made sense until now, check the relocation section too */
1745  DataDirectory = &NtHeader->OptionalHeader.
1746  DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
1747  if (!DataDirectory->VirtualAddress)
1748  {
1749  /* We don't really have relocations */
1750  ValidRelocs = FALSE;
1751  }
1752  else
1753  {
1754  /* Make sure the size is valid */
1755  if ((DataDirectory->VirtualAddress + DataDirectory->Size) >
1756  LdrEntry->SizeOfImage)
1757  {
1758  /* They're not, skip */
1759  continue;
1760  }
1761 
1762  /* We have relocations */
1763  ValidRelocs = TRUE;
1764  }
1765 
1766  /* Remember the original address */
1767  DllBase = LdrEntry->DllBase;
1768 
1769  /* Loop the PTEs */
1770  PointerPte = StartPte;
1771  while (PointerPte < LastPte)
1772  {
1773  /* Mark the page modified in the PFN database */
1774  ASSERT(PointerPte->u.Hard.Valid == 1);
1775  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1776  ASSERT(Pfn1->u3.e1.Rom == 0);
1777  Pfn1->u3.e1.Modified = TRUE;
1778 
1779  /* Next */
1780  PointerPte++;
1781  }
1782 
1783  /* Now reserve system PTEs for the image */
1784  PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
1785  if (!PointerPte)
1786  {
1787  /* Shouldn't happen */
1788  ERROR_FATAL("[Mm0]: Couldn't allocate driver section!\n");
1789  return;
1790  }
1791 
1792  /* This is the new virtual address for the module */
1793  LastPte = PointerPte + PteCount;
1794  NewImageAddress = MiPteToAddress(PointerPte);
1795 
1796  /* Sanity check */
1797  DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);
1799 
1800  /* Loop the new driver PTEs */
1802  while (PointerPte < LastPte)
1803  {
1804  /* Copy the old data */
1805  OldPte = *StartPte;
1806  ASSERT(OldPte.u.Hard.Valid == 1);
1807 
1808  /* Set page number from the loader's memory */
1809  TempPte.u.Hard.PageFrameNumber = OldPte.u.Hard.PageFrameNumber;
1810 
1811  /* Write it */
1812  MI_WRITE_VALID_PTE(PointerPte, TempPte);
1813 
1814  /* Move on */
1815  PointerPte++;
1816  StartPte++;
1817  }
1818 
1819  /* Update position */
1820  PointerPte -= PteCount;
1821 
1822  /* Sanity check */
1823  ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);
1824 
1825  /* Set the image base to the address where the loader put it */
1826  NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
1827 
1828  /* Check if we had relocations */
1829  if (ValidRelocs)
1830  {
1831  /* Relocate the image */
1832  Status = LdrRelocateImageWithBias(NewImageAddress,
1833  0,
1834  "SYSLDR",
1838  if (!NT_SUCCESS(Status))
1839  {
1840  /* This shouldn't happen */
1841  ERROR_FATAL("Relocations failed!\n");
1842  return;
1843  }
1844  }
1845 
1846  /* Update the loader entry */
1847  LdrEntry->DllBase = NewImageAddress;
1848 
1849  /* Update the thunks */
1850  DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);
1851  MiUpdateThunks(LoaderBlock,
1852  DllBase,
1853  NewImageAddress,
1854  LdrEntry->SizeOfImage);
1855 
1856  /* Update the loader entry */
1857  LdrEntry->Flags |= LDRP_SYSTEM_MAPPED;
1858  LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +
1860  LdrEntry->SizeOfImage = PteCount << PAGE_SHIFT;
1861 
1862  /* FIXME: We'll need to fixup the PFN linkage when switching to ARM3 */
1863  }
1864 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
union _MMPTE::@2288 u
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define TRUE
Definition: types.h:120
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
LONG NTSTATUS
Definition: precomp.h:26
union _MMPFN::@1757 u3
ULONG SizeOfImage
Definition: ldrtypes.h:143
#define snprintf
Definition: wintirpc.h:48
USHORT Modified
Definition: mm.h:360
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ERROR_FATAL(...)
Definition: debug.h:238
PVOID DllBase
Definition: btrfs_drv.h:1880
MMPFNENTRY e1
Definition: mm.h:397
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:964
PVOID EntryPoint
Definition: ntddk_ex.h:203
unsigned char BOOLEAN
void * PVOID
Definition: retypes.h:9
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG64 Valid
Definition: mmtypes.h:150
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
MMPTE ValidKernelPte
Definition: init.c:29
Definition: mm.h:373
Definition: btrfs_drv.h:1876
ULONG ExpInitializationPhase
Definition: init.c:68
GLenum GLsizei len
Definition: glext.h:6722
Definition: typedefs.h:119
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
NTSYSAPI ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID NewAddress, _In_ LONGLONG AdditionalBias, _In_ PCCH LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
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
#define ROUND_TO_PAGES(Size)
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
USHORT Rom
Definition: mm.h:368
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define RtlImageNtHeader
Definition: compat.h:806
ULONG Flags
Definition: ntddk_ex.h:207
VOID NTAPI MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PVOID OldBase, IN PVOID NewBase, IN ULONG Size)
Definition: sysldr.c:579
unsigned int ULONG
Definition: retypes.h:1
#define IMAGE_FILE_RELOCS_STRIPPED
Definition: pedump.c:159
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:208
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#define PFN_FROM_PTE(v)
Definition: mm.h:92
ULONG PageFrameNumber
Definition: mmtypes.h:109
#define LDRP_SYSTEM_MAPPED
Definition: ldrtypes.h:54

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

993 {
994  static UNICODE_STRING DriversFolderName = RTL_CONSTANT_STRING(L"drivers\\");
995  PCHAR MissingApiBuffer = *MissingApi, ImportName;
996  PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport;
997  ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize;
998  PLOAD_IMPORTS LoadedImports, NewImports;
999  ULONG GdiLink, NormalLink, i;
1000  BOOLEAN ReferenceNeeded, Loaded;
1001  ANSI_STRING TempString;
1002  UNICODE_STRING NameString, DllName;
1003  PLDR_DATA_TABLE_ENTRY LdrEntry = NULL, DllEntry, ImportEntry = NULL;
1004  PVOID ImportBase, DllBase;
1005  PLIST_ENTRY NextEntry;
1006  PIMAGE_EXPORT_DIRECTORY ExportDirectory;
1007  NTSTATUS Status;
1008  PIMAGE_THUNK_DATA OrigThunk, FirstThunk;
1009  PAGED_CODE();
1010  DPRINT("%s - ImageBase: %p. ImageFileDirectory: %wZ\n",
1011  __FUNCTION__, ImageBase, ImageFileDirectory);
1012 
1013  /* No name string buffer yet */
1014  NameString.Buffer = NULL;
1015 
1016  /* Assume no imports */
1017  *LoadImports = MM_SYSLDR_NO_IMPORTS;
1018 
1019  /* Get the import descriptor */
1020  ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase,
1021  TRUE,
1023  &ImportSize);
1024  if (!ImportDescriptor) return STATUS_SUCCESS;
1025 
1026  /* Loop all imports to count them */
1027  for (CurrentImport = ImportDescriptor;
1028  (CurrentImport->Name) && (CurrentImport->OriginalFirstThunk);
1029  CurrentImport++)
1030  {
1031  /* One more */
1032  ImportCount++;
1033  }
1034 
1035  /* Make sure we have non-zero imports */
1036  if (ImportCount)
1037  {
1038  /* Calculate and allocate the list we'll need */
1039  LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1040  LoadedImports = ExAllocatePoolWithTag(PagedPool,
1041  LoadedImportsSize,
1042  TAG_LDR_IMPORTS);
1043  if (LoadedImports)
1044  {
1045  /* Zero it */
1046  RtlZeroMemory(LoadedImports, LoadedImportsSize);
1047  LoadedImports->Count = ImportCount;
1048  }
1049  }
1050  else
1051  {
1052  /* No table */
1053  LoadedImports = NULL;
1054  }
1055 
1056  /* Reset the import count and loop descriptors again */
1057  ImportCount = GdiLink = NormalLink = 0;
1058  while ((ImportDescriptor->Name) && (ImportDescriptor->OriginalFirstThunk))
1059  {
1060  /* Get the name */
1061  ImportName = (PCHAR)((ULONG_PTR)ImageBase + ImportDescriptor->Name);
1062 
1063  /* Check if this is a GDI driver */
1064  GdiLink = GdiLink |
1065  !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1));
1066 
1067  /* We can also allow dxapi (for Windows compat, allow IRT and coverage) */
1068  NormalLink = NormalLink |
1069  ((_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) &&
1070  (_strnicmp(ImportName, "dxapi", sizeof("dxapi") - 1)) &&
1071  (_strnicmp(ImportName, "coverage", sizeof("coverage") - 1)) &&
1072  (_strnicmp(ImportName, "irt", sizeof("irt") - 1)));
1073 
1074  /* Check if this is a valid GDI driver */
1075  if ((GdiLink) && (NormalLink))
1076  {
1077  /* It's not, it's importing stuff it shouldn't be! */
1079  goto Failure;
1080  }
1081 
1082  /* Check for user-mode printer or video card drivers, which don't belong */
1083  if (!(_strnicmp(ImportName, "ntdll", sizeof("ntdll") - 1)) ||
1084  !(_strnicmp(ImportName, "winsrv", sizeof("winsrv") - 1)) ||
1085  !(_strnicmp(ImportName, "advapi32", sizeof("advapi32") - 1)) ||
1086  !(_strnicmp(ImportName, "kernel32", sizeof("kernel32") - 1)) ||
1087  !(_strnicmp(ImportName, "user32", sizeof("user32") - 1)) ||
1088  !(_strnicmp(ImportName, "gdi32", sizeof("gdi32") - 1)))
1089  {
1090  /* This is not kernel code */
1092  goto Failure;
1093  }
1094 
1095  /* Check if this is a "core" import, which doesn't get referenced */
1096  if (!(_strnicmp(ImportName, "ntoskrnl", sizeof("ntoskrnl") - 1)) ||
1097  !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) ||
1098  !(_strnicmp(ImportName, "hal", sizeof("hal") - 1)))
1099  {
1100  /* Don't reference this */
1101  ReferenceNeeded = FALSE;
1102  }
1103  else
1104  {
1105  /* Reference these modules */
1106  ReferenceNeeded = TRUE;
1107  }
1108 
1109  /* Now setup a unicode string for the import */
1110  RtlInitAnsiString(&TempString, ImportName);
1111  Status = RtlAnsiStringToUnicodeString(&NameString, &TempString, TRUE);
1112  if (!NT_SUCCESS(Status))
1113  {
1114  /* Failed */
1115  goto Failure;
1116  }
1117 
1118  /* We don't support name prefixes yet */
1119  if (NamePrefix) DPRINT1("Name Prefix not yet supported!\n");
1120 
1121  /* Remember that we haven't loaded the import at this point */
1122 CheckDllState:
1123  Loaded = FALSE;
1124  ImportBase = NULL;
1125 
1126  /* Loop the driver list */
1127  NextEntry = PsLoadedModuleList.Flink;
1128  while (NextEntry != &PsLoadedModuleList)
1129  {
1130  /* Get the loader entry and compare the name */
1131  LdrEntry = CONTAINING_RECORD(NextEntry,
1133  InLoadOrderLinks);
1134  if (RtlEqualUnicodeString(&NameString,
1135  &LdrEntry->BaseDllName,
1136  TRUE))
1137  {
1138  /* Get the base address */
1139  ImportBase = LdrEntry->DllBase;
1140 
1141  /* Check if we haven't loaded yet, and we need references */
1142  if (!(Loaded) && (ReferenceNeeded))
1143  {
1144  /* Make sure we're not already loading */
1145  if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1146  {
1147  /* Increase the load count */
1148  LdrEntry->LoadCount++;
1149  }
1150  }
1151 
1152  /* Done, break out */
1153  break;
1154  }
1155 
1156  /* Go to the next entry */
1157  NextEntry = NextEntry->Flink;
1158  }
1159 
1160  /* Check if we haven't loaded the import yet */
1161  if (!ImportBase)
1162  {
1163  /* Setup the import DLL name */
1164  DllName.MaximumLength = NameString.Length +
1165  ImageFileDirectory->Length +
1166  sizeof(UNICODE_NULL);
1168  DllName.MaximumLength,
1169  TAG_LDR_WSTR);
1170  if (!DllName.Buffer)
1171  {
1172  /* We're out of resources */
1174  goto Failure;
1175  }
1176 
1177  /* Add the import name to the base directory */
1178  RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1180  &NameString);
1181 
1182  /* Load the image */
1183  Status = MmLoadSystemImage(&DllName,
1184  NamePrefix,
1185  NULL,
1186  FALSE,
1187  (PVOID *)&DllEntry,
1188  &DllBase);
1189 
1190  /* win32k / GDI drivers can also import from system32 folder */
1192  (MI_IS_SESSION_ADDRESS(ImageBase) || 1)) // HACK
1193  {
1194  /* Free the old name buffer */
1196 
1197  /* Calculate size for a string the adds 'drivers\' */
1198  DllName.MaximumLength += DriversFolderName.Length;
1199 
1200  /* Allocate the new buffer */
1202  DllName.MaximumLength,
1203  TAG_LDR_WSTR);
1204  if (!DllName.Buffer)
1205  {
1206  /* We're out of resources */
1208  goto Failure;
1209  }
1210 
1211  /* Copy image directory and append 'drivers\' folder name */
1212  RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1213  RtlAppendUnicodeStringToString(&DllName, &DriversFolderName);
1214 
1215  /* Now add the import name */
1216  RtlAppendUnicodeStringToString(&DllName, &NameString);
1217 
1218  /* Try once again to load the image */
1219  Status = MmLoadSystemImage(&DllName,
1220  NamePrefix,
1221  NULL,
1222  FALSE,
1223  (PVOID *)&DllEntry,
1224  &DllBase);
1225  }
1226 
1227  if (!NT_SUCCESS(Status))
1228  {
1229  /* Fill out the information for the error */
1230  *MissingDriver = DllName.Buffer;
1231  *(PULONG)MissingDriver |= 1;
1232  *MissingApi = NULL;
1233 
1234  DPRINT1("Failed to load dependency: %wZ\n", &DllName);
1235 
1236  /* Don't free the name */
1237  DllName.Buffer = NULL;
1238 
1239  /* Cleanup and return */
1240  goto Failure;
1241  }
1242 
1243  /* We can free the DLL Name */
1245  DllName.Buffer = NULL;
1246 
1247  /* We're now loaded */
1248  Loaded = TRUE;
1249 
1250  /* Sanity check */
1251  ASSERT(DllBase == DllEntry->DllBase);
1252 
1253  /* Call the initialization routines */
1255  if (!NT_SUCCESS(Status))
1256  {
1257  /* We failed, unload the image */
1258  MmUnloadSystemImage(DllEntry);
1259  ERROR_DBGBREAK("MmCallDllInitialize failed with status 0x%x\n", Status);
1260  Loaded = FALSE;
1261  }
1262 
1263  /* Loop again to make sure that everything is OK */
1264  goto CheckDllState;
1265  }
1266 
1267  /* Check if we're support to reference this import */
1268  if ((ReferenceNeeded) && (LoadedImports))
1269  {
1270  /* Make sure we're not already loading */
1271  if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1272  {
1273  /* Add the entry */
1274  LoadedImports->Entry[ImportCount] = LdrEntry;
1275  ImportCount++;
1276  }
1277  }
1278 
1279  /* Free the import name */
1280  RtlFreeUnicodeString(&NameString);
1281 
1282  /* Set the missing driver name and get the export directory */
1283  *MissingDriver = LdrEntry->BaseDllName.Buffer;
1284  ExportDirectory = RtlImageDirectoryEntryToData(ImportBase,
1285  TRUE,
1287  &ExportSize);
1288  if (!ExportDirectory)
1289  {
1290  /* Cleanup and return */
1291  DPRINT1("Warning: Driver failed to load, %S not found\n", *MissingDriver);
1293  goto Failure;
1294  }
1295 
1296  /* Make sure we have an IAT */
1297  if (ImportDescriptor->OriginalFirstThunk)
1298  {
1299  /* Get the first thunks */
1300  OrigThunk = (PVOID)((ULONG_PTR)ImageBase +
1301  ImportDescriptor->OriginalFirstThunk);
1302  FirstThunk = (PVOID)((ULONG_PTR)ImageBase +
1303  ImportDescriptor->FirstThunk);
1304 
1305  /* Loop the IAT */
1306  while (OrigThunk->u1.AddressOfData)
1307  {
1308  /* Snap thunk */
1309  Status = MiSnapThunk(ImportBase,
1310  ImageBase,
1311  OrigThunk++,
1312  FirstThunk++,
1313  ExportDirectory,
1314  ExportSize,
1315  FALSE,
1316  MissingApi);
1317  if (!NT_SUCCESS(Status))
1318  {
1319  /* Cleanup and return */
1320  goto Failure;
1321  }
1322 
1323  /* Reset the buffer */
1324  *MissingApi = MissingApiBuffer;
1325  }
1326  }
1327 
1328  /* Go to the next import */
1329  ImportDescriptor++;
1330  }
1331 
1332  /* Check if we have an import list */
1333  if (LoadedImports)
1334  {
1335  /* Reset the count again, and loop entries */
1336  ImportCount = 0;
1337  for (i = 0; i < LoadedImports->Count; i++)
1338  {
1339  if (LoadedImports->Entry[i])
1340  {
1341  /* Got an entry, OR it with 1 in case it's the single entry */
1342  ImportEntry = (PVOID)((ULONG_PTR)LoadedImports->Entry[i] |
1344  ImportCount++;
1345  }
1346  }
1347 
1348  /* Check if we had no imports */
1349  if (!ImportCount)
1350  {
1351  /* Free the list and set it to no imports */
1352  ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1353  LoadedImports = MM_SYSLDR_NO_IMPORTS;
1354  }
1355  else if (ImportCount == 1)
1356  {
1357  /* Just one entry, we can free the table and only use our entry */
1358  ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1359  LoadedImports = (PLOAD_IMPORTS)ImportEntry;
1360  }
1361  else if (ImportCount != LoadedImports->Count)
1362  {
1363  /* Allocate a new list */
1364  LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1365  NewImports = ExAllocatePoolWithTag(PagedPool,
1366  LoadedImportsSize,
1367  TAG_LDR_IMPORTS);
1368  if (NewImports)
1369  {
1370  /* Set count */
1371  NewImports->Count = 0;
1372 
1373  /* Loop all the imports */
1374  for (i = 0; i < LoadedImports->Count; i++)
1375  {
1376  /* Make sure it's valid */
1377  if (LoadedImports->Entry[i])
1378  {
1379  /* Copy it */
1380  NewImports->Entry[NewImports->Count] = LoadedImports->Entry[i];
1381  NewImports->Count++;
1382  }
1383  }
1384 
1385  /* Free the old copy */
1386  ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1387  LoadedImports = NewImports;
1388  }
1389  }
1390 
1391  /* Return the list */
1392  *LoadImports = LoadedImports;
1393  }
1394 
1395  /* Return success */
1396  return STATUS_SUCCESS;
1397 
1398 Failure:
1399 
1400  /* Cleanup and return */
1401  RtlFreeUnicodeString(&NameString);
1402 
1403  if (LoadedImports)
1404  {
1405  MiDereferenceImports(LoadedImports);
1406  ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1407  }
1408 
1409  return Status;
1410 }
signed char * PCHAR
Definition: retypes.h:7
#define LDRP_LOAD_IN_PROGRESS
Definition: ldrtypes.h:42
NTSTATUS NTAPI MmCallDllInitialize(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PLIST_ENTRY ListHead)
Definition: sysldr.c:295
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PLDR_DATA_TABLE_ENTRY Entry[1]
Definition: ldrtypes.h:173
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:898
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:171
LONG NTSTATUS
Definition: precomp.h:26
struct _LOAD_IMPORTS * PLOAD_IMPORTS
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:207
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:382
#define TAG_LDR_IMPORTS
Definition: tag.h:103
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
Definition: fs_rec.h:187
#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:736
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID DllBase
Definition: btrfs_drv.h:1880
#define L(x)
Definition: ntvdm.h:50
#define TAG_LDR_WSTR
Definition: tag.h:102
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
unsigned char BOOLEAN
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define PCHAR
Definition: match.c:90
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
union _IMAGE_THUNK_DATA32::@2092 u1
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
Definition: btrfs_drv.h:1876
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:2885
Definition: typedefs.h:119
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
SIZE_T Count
Definition: ldrtypes.h:172
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
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
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
#define STATUS_PROCEDURE_NOT_FOUND
Definition: ntstatus.h:358
#define DPRINT1
Definition: precomp.h:8
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
ULONG Flags
Definition: ntddk_ex.h:207
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define __FUNCTION__
Definition: types.h:112
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
USHORT LoadCount
Definition: ntddk_ex.h:208
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:678
#define PAGED_CODE()
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by LdrProcessDriverModule(), and MmLoadSystemImage().

◆ MiSetPagingOfDriver()

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

Definition at line 2547 of file sysldr.c.

2549 {
2550 #ifdef ENABLE_MISETPAGINGOFDRIVER
2551  PVOID ImageBase;
2552  PETHREAD CurrentThread = PsGetCurrentThread();
2553  PFN_COUNT PageCount = 0;
2554  PFN_NUMBER PageFrameIndex;
2555  PMMPFN Pfn1;
2556 #endif // ENABLE_MISETPAGINGOFDRIVER
2557 
2558  PAGED_CODE();
2559 
2560 #ifndef ENABLE_MISETPAGINGOFDRIVER
2561  /* The page fault handler is broken and doesn't page back in! */
2562  DPRINT1("WARNING: MiSetPagingOfDriver() called, but paging is broken! ignoring!\n");
2563 #else // ENABLE_MISETPAGINGOFDRIVER
2564  /* Get the driver's base address */
2565  ImageBase = MiPteToAddress(PointerPte);
2566  ASSERT(MI_IS_SESSION_IMAGE_ADDRESS(ImageBase) == FALSE);
2567 
2568  /* If this is a large page, it's stuck in physical memory */
2569  if (MI_IS_PHYSICAL_ADDRESS(ImageBase)) return;
2570 
2571  /* Lock the working set */
2572  MiLockWorkingSet(CurrentThread, &MmSystemCacheWs);
2573 
2574  /* Loop the PTEs */
2575  while (PointerPte <= LastPte)
2576  {
2577  /* Check for valid PTE */
2578  if (PointerPte->u.Hard.Valid == 1)
2579  {
2580  PageFrameIndex = PFN_FROM_PTE(PointerPte);
2581  Pfn1 = MiGetPfnEntry(PageFrameIndex);
2582  ASSERT(Pfn1->u2.ShareCount == 1);
2583 
2584  /* No working sets in ReactOS yet */
2585  PageCount++;
2586  }
2587 
2588  ImageBase = (PVOID)((ULONG_PTR)ImageBase + PAGE_SIZE);
2589  PointerPte++;
2590  }
2591 
2592  /* Release the working set */
2593  MiUnlockWorkingSet(CurrentThread, &MmSystemCacheWs);
2594 
2595  /* Do we have any driver pages? */
2596  if (PageCount)
2597  {
2598  /* Update counters */
2600  }
2601 #endif // ENABLE_MISETPAGINGOFDRIVER
2602 }
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ULONG PFN_COUNT
Definition: mmtypes.h:102
PFN_NUMBER MmTotalSystemDriverPages
Definition: sysldr.c:28
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
ULONG_PTR ShareCount
Definition: mm.h:390
MMSUPPORT MmSystemCacheWs
Definition: init.c:55
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1356
void * PVOID
Definition: retypes.h:9
#define InterlockedExchangeAdd
Definition: interlocked.h:181
#define ASSERT(a)
Definition: mode.c:44
union _MMPFN::@1756 u2
Definition: mm.h:373
#define PAGE_SIZE
Definition: env_spec_w32.h:49
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define DPRINT1
Definition: precomp.h:8
#define MI_IS_SESSION_IMAGE_ADDRESS(Address)
Definition: miarm.h:168
FORCEINLINE VOID MiLockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1270
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:208
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
signed int * PLONG
Definition: retypes.h:5
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define PAGED_CODE()

Referenced by MiEnablePagingOfDriver(), and MmPageEntireDriver().

◆ MiSetSystemCodeProtection()

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

Definition at line 2391 of file sysldr.c.

2395 {
2396  PMMPTE PointerPte;
2397  MMPTE TempPte;
2398 
2399  /* Loop the PTEs */
2400  for (PointerPte = FirstPte; PointerPte <= LastPte; PointerPte++)
2401  {
2402  /* Read the PTE */
2403  TempPte = *PointerPte;
2404 
2405  /* Make sure it's valid */
2406  if (TempPte.u.Hard.Valid != 1)
2407  {
2408  DPRINT1("CORE-16449: FirstPte=%p, LastPte=%p, Protection=%lx\n", FirstPte, LastPte, Protection);
2409  DPRINT1("CORE-16449: PointerPte=%p, TempPte=%lx\n", PointerPte, TempPte.u.Long);
2410  DPRINT1("CORE-16449: Please issue the 'mod' and 'bt' (KDBG) or 'lm' and 'kp' (WinDbg) commands. Then report this in Jira.\n");
2411  ASSERT(TempPte.u.Hard.Valid == 1);
2412  break;
2413  }
2414 
2415  /* Update the protection */
2416  TempPte.u.Hard.Write = BooleanFlagOn(Protection, IMAGE_SCN_MEM_WRITE);
2417 #if _MI_HAS_NO_EXECUTE
2418  TempPte.u.Hard.NoExecute = !BooleanFlagOn(Protection, IMAGE_SCN_MEM_EXECUTE);
2419 #endif
2420 
2421  MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2422  }
2423 
2424  /* Flush it all */
2426 }
#define TRUE
Definition: types.h:120
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:438
#define ASSERT(a)
Definition: mode.c:44
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:982
#define IMAGE_SCN_MEM_EXECUTE
Definition: ntimage.h:239

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

686 {
687  BOOLEAN IsOrdinal;
688  USHORT Ordinal;
689  PULONG NameTable;
690  PUSHORT OrdinalTable;
691  PIMAGE_IMPORT_BY_NAME NameImport;
692  USHORT Hint;
693  ULONG Low = 0, Mid = 0, High;
694  LONG Ret;
696  PCHAR MissingForwarder;
697  CHAR NameBuffer[MAXIMUM_FILENAME_LENGTH];
698  PULONG ExportTable;
699  ANSI_STRING DllName;
700  UNICODE_STRING ForwarderName;
701  PLIST_ENTRY NextEntry;
702  PLDR_DATA_TABLE_ENTRY LdrEntry;
703  ULONG ForwardExportSize;
704  PIMAGE_EXPORT_DIRECTORY ForwardExportDirectory;
705  PIMAGE_IMPORT_BY_NAME ForwardName;
706  SIZE_T ForwardLength;
707  IMAGE_THUNK_DATA ForwardThunk;
708  PAGED_CODE();
709 
710  /* Check if this is an ordinal */
711  IsOrdinal = IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal);
712  if ((IsOrdinal) && !(SnapForwarder))
713  {
714  /* Get the ordinal number and set it as missing */
715  Ordinal = (USHORT)(IMAGE_ORDINAL(Name->u1.Ordinal) -
716  ExportDirectory->Base);
717  *MissingApi = (PCHAR)(ULONG_PTR)Ordinal;
718  }
719  else
720  {
721  /* Get the VA if we don't have to snap */
722  if (!SnapForwarder) Name->u1.AddressOfData += (ULONG_PTR)ImageBase;
723  NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData;
724 
725  /* Copy the procedure name */
726  RtlStringCbCopyA(*MissingApi,
728  (PCHAR)&NameImport->Name[0]);
729 
730  /* Setup name tables */
731  DPRINT("Import name: %s\n", NameImport->Name);
732  NameTable = (PULONG)((ULONG_PTR)DllBase +
733  ExportDirectory->AddressOfNames);
734  OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
735  ExportDirectory->AddressOfNameOrdinals);
736 
737  /* Get the hint and check if it's valid */
738  Hint = NameImport->Hint;
739  if ((Hint < ExportDirectory->NumberOfNames) &&
740  !(strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))
741  {
742  /* We have a match, get the ordinal number from here */
743  Ordinal = OrdinalTable[Hint];
744  }
745  else
746  {
747  /* Do a binary search */
748  High = ExportDirectory->NumberOfNames - 1;
749  while (High >= Low)
750  {
751  /* Get new middle value */
752  Mid = (Low + High) >> 1;
753 
754  /* Compare name */
755  Ret = strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Mid]);
756  if (Ret < 0)
757  {
758  /* Update high */
759  High = Mid - 1;
760  }
761  else if (Ret > 0)
762  {
763  /* Update low */
764  Low = Mid + 1;
765  }
766  else
767  {
768  /* We got it */
769  break;
770  }
771  }
772 
773  /* Check if we couldn't find it */
774  if (High < Low)
775  {
776  DPRINT1("Warning: Driver failed to load, %s not found\n", NameImport->Name);
778  }
779 
780  /* Otherwise, this is the ordinal */
781  Ordinal = OrdinalTable[Mid];
782  }
783  }
784 
785  /* Check if the ordinal is invalid */
786  if (Ordinal >= ExportDirectory->NumberOfFunctions)
787  {
788  /* Fail */
790  }
791  else
792  {
793  /* In case the forwarder is missing */
794  MissingForwarder = NameBuffer;
795 
796  /* Resolve the address and write it */
797  ExportTable = (PULONG)((ULONG_PTR)DllBase +
798  ExportDirectory->AddressOfFunctions);
799  Address->u1.Function = (ULONG_PTR)DllBase + ExportTable[Ordinal];
800 
801  /* Assume success from now on */
803 
804  /* Check if the function is actually a forwarder */
805  if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&
806  (Address->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
807  {
808  /* Now assume failure in case the forwarder doesn't exist */
810 
811  /* Build the forwarder name */
812  DllName.Buffer = (PCHAR)Address->u1.Function;
813  DllName.Length = (USHORT)(strchr(DllName.Buffer, '.') -
814  DllName.Buffer) +
815  sizeof(ANSI_NULL);
816  DllName.MaximumLength = DllName.Length;
817 
818  /* Convert it */
819  if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ForwarderName,
820  &DllName,
821  TRUE)))
822  {
823  /* We failed, just return an error */
824  return Status;
825  }
826 
827  /* Loop the module list */
828  NextEntry = PsLoadedModuleList.Flink;
829  while (NextEntry != &PsLoadedModuleList)
830  {
831  /* Get the loader entry */
832  LdrEntry = CONTAINING_RECORD(NextEntry,
834  InLoadOrderLinks);
835 
836  /* Check if it matches */
837  if (RtlPrefixUnicodeString(&ForwarderName,
838  &LdrEntry->BaseDllName,
839  TRUE))
840  {
841  /* Get the forwarder export directory */
842  ForwardExportDirectory =
844  TRUE,
846  &ForwardExportSize);
847  if (!ForwardExportDirectory) break;
848 
849  /* Allocate a name entry */
850  ForwardLength = strlen(DllName.Buffer + DllName.Length) +
851  sizeof(ANSI_NULL);
852  ForwardName = ExAllocatePoolWithTag(PagedPool,
853  sizeof(*ForwardName) +
854  ForwardLength,
855  TAG_LDR_WSTR);
856  if (!ForwardName) break;
857 
858  /* Copy the data */
859  RtlCopyMemory(&ForwardName->Name[0],
860  DllName.Buffer + DllName.Length,
861  ForwardLength);
862  ForwardName->Hint = 0;
863 
864  /* Set the new address */
865  ForwardThunk.u1.AddressOfData = (ULONG_PTR)ForwardName;
866 
867  /* Snap the forwarder */
868  Status = MiSnapThunk(LdrEntry->DllBase,
869  ImageBase,
870  &ForwardThunk,
871  &ForwardThunk,
872  ForwardExportDirectory,
873  ForwardExportSize,
874  TRUE,
875  &MissingForwarder);
876 
877  /* Free the forwarder name and set the thunk */
878  ExFreePoolWithTag(ForwardName, TAG_LDR_WSTR);
879  Address->u1 = ForwardThunk.u1;
880  break;
881  }
882 
883  /* Go to the next entry */
884  NextEntry = NextEntry->Flink;
885  }
886 
887  /* Free the name */
888  RtlFreeUnicodeString(&ForwarderName);
889  }
890  }
891 
892  /* Return status */
893  return Status;
894 }
signed char * PCHAR
Definition: retypes.h:7
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_DRIVER_ORDINAL_NOT_FOUND
Definition: ntstatus.h:735
Definition: strmini.h:380
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:736
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
PVOID DllBase
Definition: btrfs_drv.h:1880
#define TAG_LDR_WSTR
Definition: tag.h:102
#define ANSI_NULL
long LONG
Definition: pedump.c:60
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define PCHAR
Definition: match.c:90
Status
Definition: gdiplustypes.h:24
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
union _IMAGE_THUNK_DATA32::@2092 u1
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
Definition: strmini.h:378
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
Definition: btrfs_drv.h:1876
Definition: typedefs.h:119
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
unsigned int * PULONG
Definition: retypes.h:1
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define ULONG_PTR
Definition: config.h:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
unsigned short * PUSHORT
Definition: retypes.h:2
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:678
#define PAGED_CODE()

Referenced by MiResolveImageReferences().

◆ MiUpdateThunks()

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

Definition at line 579 of file sysldr.c.

583 {
584  ULONG_PTR OldBaseTop, Delta;
585  PLDR_DATA_TABLE_ENTRY LdrEntry;
586  PLIST_ENTRY NextEntry;
587  ULONG ImportSize;
588  //
589  // FIXME: MINGW-W64 must fix LD to generate drivers that Windows can load,
590  // since a real version of Windows would fail at this point, but they seem
591  // busy implementing features such as "HotPatch" support in GCC 4.6 instead,
592  // a feature which isn't even used by Windows. Priorities, priorities...
593  // Please note that Microsoft WDK EULA and license prohibits using
594  // the information contained within it for the generation of "non-Windows"
595  // drivers, which is precisely what LD will generate, since an LD driver
596  // will not load on Windows.
597  //
598 #ifdef _WORKING_LINKER_
599  ULONG i;
600 #endif
601  PULONG_PTR ImageThunk;
602  PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
603 
604  /* Calculate the top and delta */
605  OldBaseTop = (ULONG_PTR)OldBase + Size - 1;
606  Delta = (ULONG_PTR)NewBase - (ULONG_PTR)OldBase;
607 
608  /* Loop the loader block */
609  for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
610  NextEntry != &LoaderBlock->LoadOrderListHead;
611  NextEntry = NextEntry->Flink)
612  {
613  /* Get the loader entry */
614  LdrEntry = CONTAINING_RECORD(NextEntry,
616  InLoadOrderLinks);
617 #ifdef _WORKING_LINKER_
618  /* Get the IAT */
619  ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
620  TRUE,
622  &ImportSize);
623  if (!ImageThunk) continue;
624 
625  /* Make sure we have an IAT */
626  DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
627  for (i = 0; i < ImportSize; i++, ImageThunk++)
628  {
629  /* Check if it's within this module */
630  if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
631  {
632  /* Relocate it */
633  DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
634  ImageThunk, *ImageThunk, *ImageThunk + Delta);
635  *ImageThunk += Delta;
636  }
637  }
638 #else
639  /* Get the import table */
640  ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
641  TRUE,
643  &ImportSize);
644  if (!ImportDescriptor) continue;
645 
646  /* Make sure we have an IAT */
647  DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
648  while ((ImportDescriptor->Name) &&
649  (ImportDescriptor->OriginalFirstThunk))
650  {
651  /* Get the image thunk */
652  ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
653  ImportDescriptor->FirstThunk);
654  while (*ImageThunk)
655  {
656  /* Check if it's within this module */
657  if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
658  {
659  /* Relocate it */
660  DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
661  ImageThunk, *ImageThunk, *ImageThunk + Delta);
662  *ImageThunk += Delta;
663  }
664 
665  /* Go to the next thunk */
666  ImageThunk++;
667  }
668 
669  /* Go to the next import */
670  ImportDescriptor++;
671  }
672 #endif
673  }
674 }
#define TRUE
Definition: types.h:120
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID DllBase
Definition: btrfs_drv.h:1880
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
Definition: btrfs_drv.h:1876
Definition: typedefs.h:119
#define IMAGE_DIRECTORY_ENTRY_IAT
Definition: pedump.c:271
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
static ULONG Delta
Definition: xboxvideo.c:33
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define DPRINT
Definition: sndvol32.h:71

Referenced by MiReloadBootLoadedDrivers().

◆ MiUseLargeDriverPage()

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

Definition at line 2334 of file sysldr.c.

2338 {
2339  PLIST_ENTRY NextEntry;
2340  BOOLEAN DriverFound = FALSE;
2341  PMI_LARGE_PAGE_DRIVER_ENTRY LargePageDriverEntry;
2343  ASSERT(*ImageBaseAddress >= MmSystemRangeStart);
2344 
2345 #ifdef _X86_
2346  if (!(KeFeatureBits & KF_LARGE_PAGE)) return FALSE;
2347  if (!(__readcr4() & CR4_PSE)) return FALSE;
2348 #endif
2349 
2350  /* Make sure there's enough system PTEs for a large page driver */
2352  {
2353  return FALSE;
2354  }
2355 
2356  /* This happens if the registry key had a "*" (wildcard) in it */
2357  if (MiLargePageAllDrivers == 0)
2358  {
2359  /* It didn't, so scan the list */
2360  NextEntry = MiLargePageDriverList.Flink;
2361  while (NextEntry != &MiLargePageDriverList)
2362  {
2363  /* Check if the driver name matches */
2364  LargePageDriverEntry = CONTAINING_RECORD(NextEntry,
2366  Links);
2367  if (RtlEqualUnicodeString(BaseImageName,
2368  &LargePageDriverEntry->BaseName,
2369  TRUE))
2370  {
2371  /* Enable large pages for this driver */
2372  DriverFound = TRUE;
2373  break;
2374  }
2375 
2376  /* Keep trying */
2377  NextEntry = NextEntry->Flink;
2378  }
2379 
2380  /* If we didn't find the driver, it doesn't need large pages */
2381  if (DriverFound == FALSE) return FALSE;
2382  }
2383 
2384  /* Nothing to do yet */
2385  DPRINT1("Large pages not supported!\n");
2386  return FALSE;
2387 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define TRUE
Definition: types.h:120
#define CR4_PSE
Definition: ketypes.h:88
LIST_ENTRY MiLargePageDriverList
Definition: largepag.c:26
ULONG MmTotalFreeSystemPtes[MaximumPtePoolTypes]
Definition: syspte.c:25
ULONG KeFeatureBits
Definition: krnlinit.c:22
UNICODE_STRING BaseName
Definition: miarm.h:403
#define KF_LARGE_PAGE
Definition: ketypes.h:148
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
Definition: miarm.h:400
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:44
BOOLEAN MiLargePageAllDrivers
Definition: largepag.c:27
Definition: typedefs.h:119
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1825
#define DPRINT1
Definition: precomp.h:8
#define PDE_MAPPED_VA
Definition: mm.h:39
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define MmSystemRangeStart
Definition: mm.h:32

Referenced by MmLoadSystemImage().

◆ MiWriteProtectSystemImage()

VOID NTAPI MiWriteProtectSystemImage ( _In_ PVOID  ImageBase)

Definition at line 2430 of file sysldr.c.

2432 {
2433  PIMAGE_NT_HEADERS NtHeaders;
2434  PIMAGE_SECTION_HEADER SectionHeaders, Section;
2435  ULONG i;
2436  PVOID SectionBase, SectionEnd;
2437  ULONG SectionSize;
2438  ULONG Protection;
2439  PMMPTE FirstPte, LastPte;
2440 
2441  /* Check if the registry setting is on or not */
2443  {
2444  /* Ignore section protection */
2445  return;
2446  }
2447 
2448  /* Large page mapped images are not supported */
2449  NT_ASSERT(!MI_IS_PHYSICAL_ADDRESS(ImageBase));
2450 
2451  /* Session images are not yet supported */
2452  NT_ASSERT(!MI_IS_SESSION_ADDRESS(ImageBase));
2453 
2454  /* Get the NT headers */
2455  NtHeaders = RtlImageNtHeader(ImageBase);
2456  if (NtHeaders == NULL)
2457  {
2458  DPRINT1("Failed to get NT headers for image @ %p\n", ImageBase);
2459  return;
2460  }
2461 
2462  /* Don't touch NT4 drivers */
2463  if ((NtHeaders->OptionalHeader.MajorOperatingSystemVersion < 5) ||
2464  (NtHeaders->OptionalHeader.MajorSubsystemVersion < 5))
2465  {
2466  DPRINT1("Skipping NT 4 driver @ %p\n", ImageBase);
2467  return;
2468  }
2469 
2470  /* Get the section headers */
2471  SectionHeaders = IMAGE_FIRST_SECTION(NtHeaders);
2472 
2473  /* Get the base address of the first section */
2474  SectionBase = Add2Ptr(ImageBase, SectionHeaders[0].VirtualAddress);
2475 
2476  /* Start protecting the image header as R/W */
2477  FirstPte = MiAddressToPte(ImageBase);
2478  LastPte = MiAddressToPte(SectionBase) - 1;
2479  Protection = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
2480  if (LastPte >= FirstPte)
2481  {
2482  MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2483  }
2484 
2485  /* Loop the sections */
2486  for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
2487  {
2488  /* Get the section base address and size */
2489  Section = &SectionHeaders[i];
2490  SectionBase = Add2Ptr(ImageBase, Section->VirtualAddress);
2491  SectionSize = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2492 
2493  /* Get the first PTE of this section */
2494  FirstPte = MiAddressToPte(SectionBase);
2495 
2496  /* Check for overlap with the previous range */
2497  if (FirstPte == LastPte)
2498  {
2499  /* Combine the old and new protection by ORing them */
2500  Protection |= (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2501 
2502  /* Update the protection for this PTE */
2503  MiSetSystemCodeProtection(FirstPte, FirstPte, Protection);
2504 
2505  /* Skip this PTE */
2506  FirstPte++;
2507  }
2508 
2509  /* There can not be gaps! */
2510  NT_ASSERT(FirstPte == (LastPte + 1));
2511 
2512  /* Get the end of the section and the last PTE */
2513  SectionEnd = Add2Ptr(SectionBase, SectionSize - 1);
2514  NT_ASSERT(SectionEnd < Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage));
2515  LastPte = MiAddressToPte(SectionEnd);
2516 
2517  /* If there are no more pages (after an overlap), skip this section */
2518  if (LastPte < FirstPte)
2519  {
2520  NT_ASSERT(FirstPte == (LastPte + 1));
2521  continue;
2522  }
2523 
2524  /* Get the section protection */
2525  Protection = (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2526 
2527  /* Update the protection for this section */
2528  MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2529  }
2530 
2531  /* Image should end with the last section */
2532  if (ALIGN_UP_POINTER_BY(SectionEnd, PAGE_SIZE) !=
2533  Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage))
2534  {
2535  DPRINT1("ImageBase 0x%p ImageSize 0x%lx Section %u VA 0x%lx Raw 0x%lx virt 0x%lx\n",
2536  ImageBase,
2537  NtHeaders->OptionalHeader.SizeOfImage,
2538  i,
2539  Section->VirtualAddress,
2540  Section->SizeOfRawData,
2541  Section->Misc.VirtualSize);
2542  }
2543 }
#define max(a, b)
Definition: svc.c:63
#define Add2Ptr(PTR, INC)
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:171
union _IMAGE_SECTION_HEADER::@1517 Misc
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
WORD MajorOperatingSystemVersion
Definition: ntddk_ex.h:160
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define FALSE
Definition: types.h:117
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
VOID NTAPI MiSetSystemCodeProtection(_In_ PMMPTE FirstPte, _In_ PMMPTE LastPte, _In_ ULONG Protection)
Definition: sysldr.c:2391
#define IMAGE_SCN_PROTECTION_MASK
Definition: miarm.h:160
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
#define ALIGN_UP_POINTER_BY(ptr, align)
Definition: umtypes.h:85
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
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
BOOLEAN MmEnforceWriteProtection
Definition: sysldr.c:34
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define RtlImageNtHeader
Definition: compat.h:806
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
#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  ListHead 
)

Definition at line 295 of file sysldr.c.

297 {
299  L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
300  PMM_DLL_INITIALIZE DllInit;
301  UNICODE_STRING RegPath, ImportName;
303 
304  /* Try to see if the image exports a DllInitialize routine */
305  DllInit = (PMM_DLL_INITIALIZE)MiLocateExportName(LdrEntry->DllBase,
306  "DllInitialize");
307  if (!DllInit) return STATUS_SUCCESS;
308 
309  /*
310  * Do a temporary copy of BaseDllName called ImportName
311  * because we'll alter the length of the string.
312  */
313  ImportName.Length = LdrEntry->BaseDllName.Length;
314  ImportName.MaximumLength = LdrEntry->BaseDllName.MaximumLength;
315  ImportName.Buffer = LdrEntry->BaseDllName.Buffer;
316 
317  /* Obtain the path to this dll's service in the registry */
318  RegPath.MaximumLength = ServicesKeyName.Length +
319  ImportName.Length + sizeof(UNICODE_NULL);
321  RegPath.MaximumLength,
322  TAG_LDR_WSTR);
323 
324  /* Check if this allocation was unsuccessful */
325  if (!RegPath.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
326 
327  /* Build and append the service name itself */
328  RegPath.Length = ServicesKeyName.Length;
329  RtlCopyMemory(RegPath.Buffer,
330  ServicesKeyName.Buffer,
331  ServicesKeyName.Length);
332 
333  /* Check if there is a dot in the filename */
334  if (wcschr(ImportName.Buffer, L'.'))
335  {
336  /* Remove the extension */
337  ImportName.Length = (USHORT)(wcschr(ImportName.Buffer, L'.') -
338  ImportName.Buffer) * sizeof(WCHAR);
339  }
340 
341  /* Append service name (the basename without extension) */
342  RtlAppendUnicodeStringToString(&RegPath, &ImportName);
343 
344  /* Now call the DllInit func */
345  DPRINT("Calling DllInit(%wZ)\n", &RegPath);
346  Status = DllInit(&RegPath);
347 
348  /* Clean up */
350 
351  /* Return status value which DllInitialize returned */
352  return Status;
353 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
LONG NTSTATUS
Definition: precomp.h:26
#define L(x)
Definition: ntvdm.h:50
#define TAG_LDR_WSTR
Definition: tag.h:102
#define UNICODE_NULL
Status
Definition: gdiplustypes.h:24
NTSTATUS(NTAPI * PMM_DLL_INITIALIZE)(_In_ PUNICODE_STRING RegistryPath)
Definition: iotypes.h:2850
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
PVOID NTAPI MiLocateExportName(IN PVOID DllBase, IN PCHAR ExportName)
Definition: sysldr.c:218
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
static const WCHAR ServicesKeyName[]
Definition: driver.c:31
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by IopInitializeBootDrivers(), and MiResolveImageReferences().

◆ MmChangeKernelResourceSectionProtection()

BOOLEAN NTAPI MmChangeKernelResourceSectionProtection ( IN ULONG_PTR  ProtectionMask)

Definition at line 2280 of file sysldr.c.

2281 {
2282  PMMPTE PointerPte;
2283  MMPTE TempPte;
2284 
2285  /* Don't do anything if the resource section is already writable */
2287  return FALSE;
2288 
2289  /* If the resource section is physical, we cannot change its protection */
2291  return FALSE;
2292 
2293  /* Loop the PTEs */
2294  for (PointerPte = MiKernelResourceStartPte; PointerPte < MiKernelResourceEndPte; ++PointerPte)
2295  {
2296  /* Read the PTE */
2297  TempPte = *PointerPte;
2298 
2299  /* Update the protection */
2300  MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, ProtectionMask, TempPte.u.Hard.PageFrameNumber);
2301  MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2302  }
2303 
2304  /* Only flush the current processor's TLB */
2305  KeFlushCurrentTb();
2306  return TRUE;
2307 }
PMMPTE MiKernelResourceEndPte
Definition: sysldr.c:36
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define NULL
Definition: types.h:112
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:778
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:208
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:982
PMMPTE MiKernelResourceStartPte
Definition: sysldr.c:36
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:347
ULONG PageFrameNumber
Definition: mmtypes.h:109

Referenced by DisplayBootBitmap(), and MmMakeKernelResourceSectionWritable().

◆ MmCheckSystemImage()

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

Definition at line 2694 of file sysldr.c.

2696 {
2697  NTSTATUS Status;
2698  HANDLE SectionHandle;
2699  PVOID ViewBase = NULL;
2700  SIZE_T ViewSize = 0;
2702  FILE_STANDARD_INFORMATION FileStandardInfo;
2704  PIMAGE_NT_HEADERS NtHeaders;
2706  PAGED_CODE();
2707 
2708  /* Setup the object attributes */
2710  NULL,
2712  NULL,
2713  NULL);
2714 
2715  /* Create a section for the DLL */
2716  Status = ZwCreateSection(&SectionHandle,
2719  NULL,
2720  PAGE_EXECUTE,
2721  SEC_IMAGE,
2722  ImageHandle);
2723  if (!NT_SUCCESS(Status))
2724  {
2725  DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2726  return Status;
2727  }
2728 
2729  /* Make sure we're in the system process */
2731 
2732  /* Map it */
2733  Status = ZwMapViewOfSection(SectionHandle,
2734  NtCurrentProcess(),
2735  &ViewBase,
2736  0,
2737  0,
2738  NULL,
2739  &ViewSize,
2740  ViewShare,
2741  0,
2742  PAGE_EXECUTE);
2743  if (!NT_SUCCESS(Status))
2744  {
2745  /* We failed, close the handle and return */
2746  DPRINT1("ZwMapViewOfSection failed with status 0x%x\n", Status);
2748  ZwClose(SectionHandle);
2749  return Status;
2750  }
2751 
2752  /* Now query image information */
2753  Status = ZwQueryInformationFile(ImageHandle,
2754  &IoStatusBlock,
2755  &FileStandardInfo,
2756  sizeof(FileStandardInfo),
2758  if (NT_SUCCESS(Status))
2759  {
2760  /* First, verify the checksum */
2762  ViewSize,
2763  FileStandardInfo.
2764  EndOfFile.LowPart))
2765  {
2766  /* Set checksum failure */
2768  goto Fail;
2769  }
2770 
2771  /* Make sure it's a real image */
2772  NtHeaders = RtlImageNtHeader(ViewBase);
2773  if (!NtHeaders)
2774  {
2775  /* Set checksum failure */
2777  goto Fail;
2778  }
2779 
2780  /* Make sure it's for the correct architecture */
2781  if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
2783  {
2784  /* Set protection failure */
2786  goto Fail;
2787  }
2788 
2789  /* Check that it's a valid SMP image if we have more then one CPU */
2790  if (!MmVerifyImageIsOkForMpUse(ViewBase))
2791  {
2792  /* Otherwise it's not the right image */
2794  }
2795  }
2796 
2797  /* Unmap the section, close the handle, and return status */
2798 Fail:
2799  ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
2801  ZwClose(SectionHandle);
2802  return Status;
2803 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
KAPC_STATE
Definition: ketypes.h:1285
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
int Fail
Definition: ehthrow.cxx:24
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum(_In_ PVOID BaseAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG FileLength)
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
#define STATUS_IMAGE_MP_UP_MISMATCH
Definition: ntstatus.h:717
#define PAGE_EXECUTE
Definition: nt_native.h:1306
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define STATUS_IMAGE_CHECKSUM_MISMATCH
Definition: ntstatus.h:677
Status
Definition: gdiplustypes.h:24
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:540
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN NTAPI MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)
Definition: sysldr.c:2670
KPROCESS Pcb
Definition: pstypes.h:1262
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
ULONG_PTR SIZE_T
Definition: typedefs.h:80
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1727
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define IMAGE_NT_OPTIONAL_HDR_MAGIC
Definition: ntimage.h:387
#define DPRINT1
Definition: precomp.h:8
#define FileStandardInformation
Definition: propsheet.cpp:61
#define RtlImageNtHeader
Definition: compat.h:806
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1290
#define SEC_IMAGE
Definition: mmtypes.h:96
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define PAGED_CODE()

Referenced by MmLoadSystemImage(), and PsLocateSystemDll().

◆ MmFreeDriverInitialization()

VOID NTAPI MmFreeDriverInitialization ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 1622 of file sysldr.c.

1623 {
1624  PMMPTE StartPte, EndPte;
1625  PFN_NUMBER PageCount;
1626  PVOID DllBase;
1627  ULONG i;
1628  PIMAGE_NT_HEADERS NtHeader;
1629  PIMAGE_SECTION_HEADER Section, DiscardSection;
1630 
1631  /* Get the base address and the page count */
1632  DllBase = LdrEntry->DllBase;
1633  PageCount = LdrEntry->SizeOfImage >> PAGE_SHIFT;
1634 
1635  /* Get the last PTE in this image */
1636  EndPte = MiAddressToPte(DllBase) + PageCount;
1637 
1638  /* Get the NT header */
1639  NtHeader = RtlImageNtHeader(DllBase);
1640  if (!NtHeader) return;
1641 
1642  /* Get the last section and loop each section backwards */
1643  Section = IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections;
1644  DiscardSection = NULL;
1645  for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
1646  {
1647  /* Go back a section and check if it's discardable */
1648  Section--;
1650  {
1651  /* It is, select it for freeing */
1652  DiscardSection = Section;
1653  }
1654  else
1655  {
1656  /* No more discardable sections exist, bail out */
1657  break;
1658  }
1659  }
1660 
1661  /* Bail out if there's nothing to free */
1662  if (!DiscardSection) return;
1663 
1664  /* Push the DLL base to the first disacrable section, and get its PTE */
1665  DllBase = (PVOID)ROUND_TO_PAGES((ULONG_PTR)DllBase + DiscardSection->VirtualAddress);
1666  ASSERT(MI_IS_PHYSICAL_ADDRESS(DllBase) == FALSE);
1667  StartPte = MiAddressToPte(DllBase);
1668 
1669  /* Check how many pages to free total */
1670  PageCount = (PFN_NUMBER)(EndPte - StartPte);
1671  if (!PageCount) return;
1672 
1673  /* Delete this many PTEs */
1674  MiDeleteSystemPageableVm(StartPte, PageCount, 0, NULL);
1675 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
void * PVOID
Definition: retypes.h:9
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define ASSERT(a)
Definition: mode.c:44
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
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
#define ROUND_TO_PAGES(Size)
#define NULL
Definition: types.h:112
#define RtlImageNtHeader
Definition: compat.h:806
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235

Referenced by IopInitializeDriverModule().

◆ MmGetSystemRoutineAddress()

PVOID NTAPI MmGetSystemRoutineAddress ( IN PUNICODE_STRING  SystemRoutineName)

Definition at line 3551 of file sysldr.c.

3552 {
3553  PVOID ProcAddress = NULL;
3554  ANSI_STRING AnsiRoutineName;
3555  NTSTATUS Status;
3556  PLIST_ENTRY NextEntry;
3557  PLDR_DATA_TABLE_ENTRY LdrEntry;
3558  BOOLEAN Found = FALSE;
3559  UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
3561  ULONG Modules = 0;
3562 
3563  /* Convert routine to ANSI name */
3564  Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName,
3565  SystemRoutineName,
3566  TRUE);
3567  if (!NT_SUCCESS(Status)) return NULL;
3568 
3569  /* Lock the list */
3572 
3573  /* Loop the loaded module list */
3574  NextEntry = PsLoadedModuleList.Flink;
3575  while (NextEntry != &PsLoadedModuleList)
3576  {
3577  /* Get the entry */
3578  LdrEntry = CONTAINING_RECORD(NextEntry,
3580  InLoadOrderLinks);
3581 
3582  /* Check if it's the kernel or HAL */
3583  if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
3584  {
3585  /* Found it */
3586  Found = TRUE;
3587  Modules++;
3588  }
3589  else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
3590  {
3591  /* Found it */
3592  Found = TRUE;
3593  Modules++;
3594  }
3595 
3596  /* Check if we found a valid binary */
3597  if (Found)
3598  {
3599  /* Find the procedure name */
3600  ProcAddress = MiFindExportedRoutineByName(LdrEntry->DllBase,
3601  &AnsiRoutineName);
3602 
3603  /* Break out if we found it or if we already tried both modules */
3604  if (ProcAddress) break;
3605  if (Modules == 2) break;
3606  }
3607 
3608  /* Keep looping */
3609  NextEntry = NextEntry->Flink;
3610  }
3611 
3612  /* Release the lock */
3615 
3616  /* Free the string and return */
3617  RtlFreeAnsiString(&AnsiRoutineName);
3618  return ProcAddress;
3619 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
LONG NTSTATUS
Definition: precomp.h:26
PVOID DllBase
Definition: btrfs_drv.h:1880
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
PWCHAR HalName
Definition: halacpi.c:45
unsigned char BOOLEAN
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
return Found
Definition: dirsup.c:1270
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
Definition: btrfs_drv.h:1876
Definition: typedefs.h:119
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define NULL
Definition: types.h:112
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
unsigned int ULONG
Definition: retypes.h:1
PVOID NTAPI MiFindExportedRoutineByName(IN PVOID DllBase, IN PANSI_STRING ExportName)
Definition: sysldr.c:477
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

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

2891 {
2892  PVOID ModuleLoadBase = NULL;
2893  NTSTATUS Status;
2897  PIMAGE_NT_HEADERS NtHeader;
2898  UNICODE_STRING BaseName, BaseDirectory, PrefixName;
2899  PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
2900  ULONG EntrySize, DriverSize;
2901  PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
2902  PCHAR MissingApiName, Buffer;
2903  PWCHAR MissingDriverName, PrefixedBuffer = NULL;
2904  HANDLE SectionHandle;
2906  PSECTION Section = NULL;
2907  BOOLEAN LockOwned = FALSE;
2908  PLIST_ENTRY NextEntry;
2909  IMAGE_INFO ImageInfo;
2910 
2911  PAGED_CODE();
2912 
2913  /* Detect session-load */
2914  if (Flags)
2915  {
2916  /* Sanity checks */
2917  ASSERT(NamePrefix == NULL);
2918  ASSERT(LoadedName == NULL);
2919 
2920  /* Make sure the process is in session too */
2921  if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;
2922  }
2923 
2924  /* Allocate a buffer we'll use for names */
2927  TAG_LDR_WSTR);
2929 
2930  /* Check for a separator */
2931  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2932  {
2933  PWCHAR p;
2934  ULONG BaseLength;
2935 
2936  /* Loop the path until we get to the base name */
2937  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
2938  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
2939 
2940  /* Get the length */
2941  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
2942  BaseLength *= sizeof(WCHAR);
2943 
2944  /* Setup the string */
2945  BaseName.Length = (USHORT)BaseLength;
2946  BaseName.Buffer = p;
2947  }
2948  else
2949  {
2950  /* Otherwise, we already have a base name */
2951  BaseName.Length = FileName->Length;
2952  BaseName.Buffer = FileName->Buffer;
2953  }
2954 
2955  /* Setup the maximum length */
2956  BaseName.MaximumLength = BaseName.Length;
2957 
2958  /* Now compute the base directory */
2959  BaseDirectory = *FileName;
2960  BaseDirectory.Length -= BaseName.Length;
2961  BaseDirectory.MaximumLength = BaseDirectory.Length;
2962 
2963  /* And the prefix, which for now is just the name itself */
2964  PrefixName = *FileName;
2965 
2966  /* Check if we have a prefix */
2967  if (NamePrefix)
2968  {
2969  /* Check if "directory + prefix" is too long for the string */
2970  Status = RtlUShortAdd(BaseDirectory.Length,
2971  NamePrefix->Length,
2972  &PrefixName.MaximumLength);
2973  if (!NT_SUCCESS(Status))
2974  {
2976  goto Quickie;
2977  }
2978 
2979  /* Check if "directory + prefix + basename" is too long for the string */
2980  Status = RtlUShortAdd(PrefixName.MaximumLength,
2981  BaseName.Length,
2982  &PrefixName.MaximumLength);
2983  if (!NT_SUCCESS(Status))
2984  {
2986  goto Quickie;
2987  }
2988 
2989  /* Allocate the buffer exclusively used for prefixed name */
2990  PrefixedBuffer = ExAllocatePoolWithTag(PagedPool,
2991  PrefixName.MaximumLength,
2992  TAG_LDR_WSTR);
2993  if (!PrefixedBuffer)
2994  {
2996  goto Quickie;
2997  }
2998 
2999  /* Clear out the prefixed name string */
3000  PrefixName.Buffer = PrefixedBuffer;
3001  PrefixName.Length = 0;
3002 
3003  /* Concatenate the strings */
3004  RtlAppendUnicodeStringToString(&PrefixName, &BaseDirectory);
3005  RtlAppendUnicodeStringToString(&PrefixName, NamePrefix);
3006  RtlAppendUnicodeStringToString(&PrefixName, &BaseName);
3007 
3008  /* Now the base name of the image becomes the prefixed version */
3009  BaseName.Buffer = &(PrefixName.Buffer[BaseDirectory.Length / sizeof(WCHAR)]);
3010  BaseName.Length += NamePrefix->Length;
3011  BaseName.MaximumLength = (PrefixName.MaximumLength - BaseDirectory.Length);
3012  }
3013 
3014  /* Check if we already have a name, use it instead */
3015  if (LoadedName) BaseName = *LoadedName;
3016 
3017  /* Check for loader snap debugging */
3019  {
3020  /* Print out standard string */
3021  DPRINT1("MM:SYSLDR Loading %wZ (%wZ) %s\n",
3022  &PrefixName, &BaseName, Flags ? "in session space" : "");
3023  }
3024 
3025  /* Acquire the load lock */
3026 LoaderScan:
3027  ASSERT(LockOwned == FALSE);
3028  LockOwned = TRUE;
3032  KernelMode,
3033  FALSE,
3034  NULL);
3035 
3036  /* Scan the module list */
3037  NextEntry = PsLoadedModuleList.Flink;
3038  while (NextEntry != &PsLoadedModuleList)
3039  {
3040  /* Get the entry and compare the names */
3041  LdrEntry = CONTAINING_RECORD(NextEntry,
3043  InLoadOrderLinks);
3044  if (RtlEqualUnicodeString(&PrefixName, &LdrEntry->FullDllName, TRUE))
3045  {
3046  /* Found it, break out */
3047  break;
3048  }
3049 
3050  /* Keep scanning */
3051  NextEntry = NextEntry->Flink;
3052  }
3053 
3054  /* Check if we found the image */
3055  if (NextEntry != &PsLoadedModuleList)
3056  {
3057  /* Check if we had already mapped a section */
3058  if (Section)
3059  {
3060  /* Dereference and clear */
3061  ObDereferenceObject(Section);
3062  Section = NULL;
3063  }
3064 
3065  /* Check if this was supposed to be a session load */
3066  if (!Flags)
3067  {
3068  /* It wasn't, so just return the data */
3069  *ModuleObject = LdrEntry;
3070  *ImageBaseAddress = LdrEntry->DllBase;
3072  }
3073  else
3074  {
3075  /* We don't support session loading yet */
3076  UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3078  }
3079 
3080  /* Do cleanup */
3081  goto Quickie;
3082  }
3083  else if (!Section)
3084  {
3085  /* It wasn't loaded, and we didn't have a previous attempt */
3088  LockOwned = FALSE;
3089 
3090  /* Check if KD is enabled */
3092  {
3093  /* FIXME: Attempt to get image from KD */
3094  }
3095 
3096  /* We don't have a valid entry */
3097  LdrEntry = NULL;
3098 
3099  /* Setup image attributes */
3101  FileName,
3103  NULL,
3104  NULL);
3105 
3106  /* Open the image */
3108  FILE_EXECUTE,
3110  &IoStatusBlock,
3112  0);
3113  if (!NT_SUCCESS(Status))
3114  {
3115  DPRINT1("ZwOpenFile failed for '%wZ' with status 0x%x\n",
3116  FileName, Status);
3117  goto Quickie;
3118  }
3119 
3120  /* Validate it */
3122  if ((