ReactOS  0.4.13-dev-479-gec9c8fd
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
 

Functions

static VOID sprintf_nt (IN PCHAR Buffer, IN PCHAR Format, IN ...)
 
PVOID NTAPI MiCacheImageSymbols (IN PVOID BaseAddress)
 
NTSTATUS NTAPI MiLoadImageSection (IN OUT PVOID *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)
 
INIT_FUNCTION 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)
 
INIT_FUNCTION VOID NTAPI MiFindInitializationCode (OUT PVOID *StartVa, OUT PVOID *EndVa)
 
VOID NTAPI MmFreeDriverInitialization (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
INIT_FUNCTION VOID NTAPI MiReloadBootLoadedDrivers (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
INIT_FUNCTION NTSTATUS NTAPI MiBuildImportsForBootDrivers (VOID)
 
INIT_FUNCTION VOID NTAPI MiLocateKernelSections (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
INIT_FUNCTION BOOLEAN NTAPI MiInitializeLoadedModuleList (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
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)
 
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

◆ 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

◆ MiBuildImportsForBootDrivers()

INIT_FUNCTION NTSTATUS NTAPI MiBuildImportsForBootDrivers ( VOID  )

Definition at line 1874 of file sysldr.c.

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

58 {
59  ULONG DebugSize;
60  PVOID DebugDirectory = NULL;
61  PAGED_CODE();
62 
63  /* Make sure it's safe to access the image */
64  _SEH2_TRY
65  {
66  /* Get the debug directory */
68  TRUE,
70  &DebugSize);
71  }
73  {
74  /* Nothing */
75  }
76  _SEH2_END;
77 
78  /* Return the directory */
79  return DebugDirectory;
80 }
#define TRUE
Definition: types.h:120
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define RtlImageDirectoryEntryToData
Definition: compat.h:460
_SEH2_END
Definition: create.c:4424
#define IMAGE_DIRECTORY_ENTRY_DEBUG
Definition: compat.h:141
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6

Referenced by MmLoadSystemImage().

◆ MiCallDllUnloadAndUnloadDll()

BOOLEAN NTAPI MiCallDllUnloadAndUnloadDll ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 370 of file sysldr.c.

371 {
374  PAGED_CODE();
375 
376  /* Get the unload routine */
377  Func = (PMM_DLL_UNLOAD)MiLocateExportName(LdrEntry->DllBase, "DllUnload");
378  if (!Func) return FALSE;
379 
380  /* Call it and check for success */
381  Status = Func();
382  if (!NT_SUCCESS(Status)) return FALSE;
383 
384  /* Lie about the load count so we can unload the image */
385  ASSERT(LdrEntry->LoadCount == 0);
386  LdrEntry->LoadCount = 1;
387 
388  /* Unload it and return true */
389  MmUnloadSystemImage(LdrEntry);
390  return TRUE;
391 }
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:911
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS(NTAPI * PMM_DLL_UNLOAD)(VOID)
Definition: iotypes.h:2498
#define PAGED_CODE()
Definition: video.h:57
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
void(* Func)(int)
PVOID NTAPI MiLocateExportName(IN PVOID DllBase, IN PCHAR ExportName)
Definition: sysldr.c:232

Referenced by MiDereferenceImports().

◆ MiClearImports()

VOID NTAPI MiClearImports ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 470 of file sysldr.c.

471 {
472  PAGED_CODE();
473 
474  /* Check if there's no imports or we're a boot driver or only one entry */
475  if ((LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) ||
476  (LdrEntry->LoadedImports == MM_SYSLDR_NO_IMPORTS) ||
477  ((ULONG_PTR)LdrEntry->LoadedImports & MM_SYSLDR_SINGLE_ENTRY))
478  {
479  /* Nothing to do */
480  return;
481  }
482 
483  /* Otherwise, free the import list */
484  ExFreePoolWithTag(LdrEntry->LoadedImports, TAG_LDR_IMPORTS);
485  LdrEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
486 }
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:211
#define TAG_LDR_IMPORTS
Definition: tag.h:111
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:209
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:208
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by MmUnloadSystemImage().

◆ MiDereferenceImports()

NTSTATUS NTAPI MiDereferenceImports ( IN PLOAD_IMPORTS  ImportList)

Definition at line 395 of file sysldr.c.

396 {
397  SIZE_T i;
398  LOAD_IMPORTS SingleEntry;
399  PLDR_DATA_TABLE_ENTRY LdrEntry;
400  PVOID CurrentImports;
401  PAGED_CODE();
402 
403  /* Check if there's no imports or if we're a boot driver */
404  if ((ImportList == MM_SYSLDR_NO_IMPORTS) ||
405  (ImportList == MM_SYSLDR_BOOT_LOADED) ||
406  (ImportList->Count == 0))
407  {
408  /* Then there's nothing to do */
409  return STATUS_SUCCESS;
410  }
411 
412  /* Check for single-entry */
413  if ((ULONG_PTR)ImportList & MM_SYSLDR_SINGLE_ENTRY)
414  {
415  /* Set it up */
416  SingleEntry.Count = 1;
417  SingleEntry.Entry[0] = (PVOID)((ULONG_PTR)ImportList &~ MM_SYSLDR_SINGLE_ENTRY);
418 
419  /* Use this as the import list */
420  ImportList = &SingleEntry;
421  }
422 
423  /* Loop the import list */
424  for (i = 0; (i < ImportList->Count) && (ImportList->Entry[i]); i++)
425  {
426  /* Get the entry */
427  LdrEntry = ImportList->Entry[i];
428  DPRINT1("%wZ <%wZ>\n", &LdrEntry->FullDllName, &LdrEntry->BaseDllName);
429 
430  /* Skip boot loaded images */
431  if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) continue;
432 
433  /* Dereference the entry */
434  ASSERT(LdrEntry->LoadCount >= 1);
435  if (!--LdrEntry->LoadCount)
436  {
437  /* Save the import data in case unload fails */
438  CurrentImports = LdrEntry->LoadedImports;
439 
440  /* This is the last entry */
442  if (MiCallDllUnloadAndUnloadDll(LdrEntry))
443  {
444  /* Unloading worked, parse this DLL's imports too */
445  MiDereferenceImports(CurrentImports);
446 
447  /* Check if we had valid imports */
448  if ((CurrentImports != MM_SYSLDR_BOOT_LOADED) &&
449  (CurrentImports != MM_SYSLDR_NO_IMPORTS) &&
450  !((ULONG_PTR)CurrentImports & MM_SYSLDR_SINGLE_ENTRY))
451  {
452  /* Free them */
453  ExFreePoolWithTag(CurrentImports, TAG_LDR_IMPORTS);
454  }
455  }
456  else
457  {
458  /* Unload failed, restore imports */
459  LdrEntry->LoadedImports = CurrentImports;
460  }
461  }
462  }
463 
464  /* Done */
465  return STATUS_SUCCESS;
466 }
PLDR_DATA_TABLE_ENTRY Entry[1]
Definition: ldrtypes.h:172
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:211
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:395
#define TAG_LDR_IMPORTS
Definition: tag.h:111
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
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
void * PVOID
Definition: retypes.h:9
PVOID LoadedImports
Definition: ldrtypes.h:160
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: btrfs_drv.h:1831
BOOLEAN NTAPI MiCallDllUnloadAndUnloadDll(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:370
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:209
SIZE_T Count
Definition: ldrtypes.h:171
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:208
ULONG_PTR SIZE_T
Definition: typedefs.h:78
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1837
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:144
#define DPRINT1
Definition: precomp.h:8
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2777
USHORT LoadCount
Definition: ntddk_ex.h:208

Referenced by MiResolveImageReferences(), and MmUnloadSystemImage().

◆ MiEnablePagingOfDriver()

VOID NTAPI MiEnablePagingOfDriver ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2552 of file sysldr.c.

2553 {
2554  ULONG_PTR ImageBase;
2555  PIMAGE_NT_HEADERS NtHeaders;
2556  ULONG Sections, Alignment, Size;
2557  PIMAGE_SECTION_HEADER Section;
2558  PMMPTE PointerPte = NULL, LastPte = NULL;
2559  if (MmDisablePagingExecutive) return;
2560 
2561  /* Get the driver base address and its NT header */
2562  ImageBase = (ULONG_PTR)LdrEntry->DllBase;
2563  NtHeaders = RtlImageNtHeader((PVOID)ImageBase);
2564  if (!NtHeaders) return;
2565 
2566  /* Get the sections and their alignment */
2567  Sections = NtHeaders->FileHeader.NumberOfSections;
2568  Alignment = NtHeaders->OptionalHeader.SectionAlignment - 1;
2569 
2570  /* Loop each section */
2571  Section = IMAGE_FIRST_SECTION(NtHeaders);
2572  while (Sections)
2573  {
2574  /* Find PAGE or .edata */
2575  if ((*(PULONG)Section->Name == 'EGAP') ||
2576  (*(PULONG)Section->Name == 'ade.'))
2577  {
2578  /* Had we already done some work? */
2579  if (!PointerPte)
2580  {
2581  /* Nope, setup the first PTE address */
2582  PointerPte = MiAddressToPte(ROUND_TO_PAGES(ImageBase +
2583  Section->
2584  VirtualAddress));
2585  }
2586 
2587  /* Compute the size */
2588  Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2589 
2590  /* Find the last PTE that maps this section */
2591  LastPte = MiAddressToPte(ImageBase +
2592  Section->VirtualAddress +
2593  Alignment +
2594  Size -
2595  PAGE_SIZE);
2596  }
2597  else
2598  {
2599  /* Had we found a section before? */
2600  if (PointerPte)
2601  {
2602  /* Mark it as pageable */
2603  MiSetPagingOfDriver(PointerPte, LastPte);
2604  PointerPte = NULL;
2605  }
2606  }
2607 
2608  /* Keep searching */
2609  Sections--;
2610  Section++;
2611  }
2612 
2613  /* Handle the straggler */
2614  if (PointerPte) MiSetPagingOfDriver(PointerPte, LastPte);
2615 }
#define max(a, b)
Definition: svc.c:63
VOID NTAPI MiSetPagingOfDriver(IN PMMPTE PointerPte, IN PMMPTE LastPte)
Definition: sysldr.c:2497
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
union Alignment_ Alignment
smooth NULL
Definition: ftsmooth.c:416
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#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:457
union _IMAGE_SECTION_HEADER::@1526 Misc
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
UCHAR MmDisablePagingExecutive
Definition: mminit.c:27

Referenced by MmLoadSystemImage().

◆ MiFindExportedRoutineByName()

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

Definition at line 490 of file sysldr.c.

492 {
493  PULONG NameTable;
494  PUSHORT OrdinalTable;
495  PIMAGE_EXPORT_DIRECTORY ExportDirectory;
496  LONG Low = 0, Mid = 0, High, Ret;
497  USHORT Ordinal;
498  PVOID Function;
499  ULONG ExportSize;
500  PULONG ExportTable;
501  PAGED_CODE();
502 
503  /* Get the export directory */
504  ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
505  TRUE,
507  &ExportSize);
508  if (!ExportDirectory) return NULL;
509 
510  /* Setup name tables */
511  NameTable = (PULONG)((ULONG_PTR)DllBase +
512  ExportDirectory->AddressOfNames);
513  OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
514  ExportDirectory->AddressOfNameOrdinals);
515 
516  /* Do a binary search */
517  High = ExportDirectory->NumberOfNames - 1;
518  while (High >= Low)
519  {
520  /* Get new middle value */
521  Mid = (Low + High) >> 1;
522 
523  /* Compare name */
524  Ret = strcmp(ExportName->Buffer, (PCHAR)DllBase + NameTable[Mid]);
525  if (Ret < 0)
526  {
527  /* Update high */
528  High = Mid - 1;
529  }
530  else if (Ret > 0)
531  {
532  /* Update low */
533  Low = Mid + 1;
534  }
535  else
536  {
537  /* We got it */
538  break;
539  }
540  }
541 
542  /* Check if we couldn't find it */
543  if (High < Low) return NULL;
544 
545  /* Otherwise, this is the ordinal */
546  Ordinal = OrdinalTable[Mid];
547 
548  /* Validate the ordinal */
549  if (Ordinal >= ExportDirectory->NumberOfFunctions) return NULL;
550 
551  /* Resolve the address and write it */
552  ExportTable = (PULONG)((ULONG_PTR)DllBase +
553  ExportDirectory->AddressOfFunctions);
554  Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
555 
556  /* We found it! */
557  ASSERT((Function < (PVOID)ExportDirectory) ||
558  (Function > (PVOID)((ULONG_PTR)ExportDirectory + ExportSize)));
559 
560  return Function;
561 }
signed char * PCHAR
Definition: retypes.h:7
#define TRUE
Definition: types.h:120
Definition: strmini.h:380
#define PAGED_CODE()
Definition: video.h:57
DWORD AddressOfNameOrdinals
Definition: compat.h:155
uint32_t ULONG_PTR
Definition: typedefs.h:63
static LPOVERLAPPED_COMPLETION_ROUTINE Function
Definition: sync.c:684
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
Definition: strmini.h:378
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define RtlImageDirectoryEntryToData
Definition: compat.h:460
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:140
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
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

Referenced by MmGetSystemRoutineAddress().

◆ MiFindInitializationCode()

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

Definition at line 1450 of file sysldr.c.

1452 {
1453  ULONG Size, SectionCount, Alignment;
1454  PLDR_DATA_TABLE_ENTRY LdrEntry;
1455  ULONG_PTR DllBase, InitStart, InitEnd, ImageEnd, InitCode;
1456  PLIST_ENTRY NextEntry;
1457  PIMAGE_NT_HEADERS NtHeader;
1458  PIMAGE_SECTION_HEADER Section, LastSection, InitSection;
1459  BOOLEAN InitFound;
1460  DBG_UNREFERENCED_LOCAL_VARIABLE(InitSection);
1461 
1462  /* So we don't free our own code yet */
1463  InitCode = (ULONG_PTR)&MiFindInitializationCode;
1464 
1465  /* Assume failure */
1466  *StartVa = NULL;
1467 
1468  /* Enter a critical region while we loop the list */
1470 
1471  /* Loop all loaded modules */
1472  NextEntry = PsLoadedModuleList.Flink;
1473  while (NextEntry != &PsLoadedModuleList)
1474  {
1475  /* Get the loader entry and its DLL base */
1476  LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1477  DllBase = (ULONG_PTR)LdrEntry->DllBase;
1478 
1479  /* Only process boot loaded images. Other drivers are processed by
1480  MmFreeDriverInitialization */
1481  if (LdrEntry->Flags & LDRP_MM_LOADED)
1482  {
1483  /* Keep going */
1484  NextEntry = NextEntry->Flink;
1485  continue;
1486  }
1487 
1488  /* Get the NT header */
1489  NtHeader = RtlImageNtHeader((PVOID)DllBase);
1490  if (!NtHeader)
1491  {
1492  /* Keep going */
1493  NextEntry = NextEntry->Flink;
1494  continue;
1495  }
1496 
1497  /* Get the first section, the section count, and scan them all */
1498  Section = IMAGE_FIRST_SECTION(NtHeader);
1499  SectionCount = NtHeader->FileHeader.NumberOfSections;
1500  InitStart = 0;
1501  while (SectionCount > 0)
1502  {
1503  /* Assume failure */
1504  InitFound = FALSE;
1505 
1506  /* Is this the INIT section or a discardable section? */
1507  if ((strncmp((PCCH)Section->Name, "INIT", 5) == 0) ||
1509  {
1510  /* Remember this */
1511  InitFound = TRUE;
1512  InitSection = Section;
1513  }
1514 
1515  if (InitFound)
1516  {
1517  /* Pick the biggest size -- either raw or virtual */
1518  Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
1519 
1520  /* Read the section alignment */
1522 
1523  /* Get the start and end addresses */
1524  InitStart = DllBase + Section->VirtualAddress;
1525  InitEnd = ALIGN_UP_BY(InitStart + Size, Alignment);
1526 
1527  /* Align the addresses to PAGE_SIZE */
1528  InitStart = ALIGN_UP_BY(InitStart, PAGE_SIZE);
1529  InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1530 
1531  /* Have we reached the last section? */
1532  if (SectionCount == 1)
1533  {
1534  /* Remember this */
1535  LastSection = Section;
1536  }
1537  else
1538  {
1539  /* We have not, loop all the sections */
1540  LastSection = NULL;
1541  do
1542  {
1543  /* Keep going until we find a non-discardable section range */
1544  SectionCount--;
1545  Section++;
1547  {
1548  /* Discardable, so record it, then keep going */
1549  LastSection = Section;
1550  }
1551  else
1552  {
1553  /* Non-contigous discard flag, or no flag, break out */
1554  break;
1555  }
1556  }
1557  while (SectionCount > 1);
1558  }
1559 
1560  /* Have we found a discardable or init section? */
1561  if (LastSection)
1562  {
1563  /* Pick the biggest size -- either raw or virtual */
1564  Size = max(LastSection->SizeOfRawData, LastSection->Misc.VirtualSize);
1565 
1566  /* Use this as the end of the section address */
1567  InitEnd = DllBase + LastSection->VirtualAddress + Size;
1568 
1569  /* Have we reached the last section yet? */
1570  if (SectionCount != 1)
1571  {
1572  /* Then align this accross the session boundary */
1573  InitEnd = ALIGN_UP_BY(InitEnd, Alignment);
1574  InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1575  }
1576  }
1577 
1578  /* Make sure we don't let the init section go past the image */
1579  ImageEnd = DllBase + LdrEntry->SizeOfImage;
1580  if (InitEnd > ImageEnd) InitEnd = ALIGN_UP_BY(ImageEnd, PAGE_SIZE);
1581 
1582  /* Make sure we have a valid, non-zero init section */
1583  if (InitStart < InitEnd)
1584  {
1585  /* Make sure we are not within this code itself */
1586  if ((InitCode >= InitStart) && (InitCode < InitEnd))
1587  {
1588  /* Return it, we can't free ourselves now */
1589  ASSERT(*StartVa == 0);
1590  *StartVa = (PVOID)InitStart;
1591  *EndVa = (PVOID)InitEnd;
1592  }
1593  else
1594  {
1595  /* This isn't us -- go ahead and free it */
1596  ASSERT(MI_IS_PHYSICAL_ADDRESS((PVOID)InitStart) == FALSE);
1597  DPRINT("Freeing init code: %p-%p ('%wZ' @%p : '%s')\n",
1598  (PVOID)InitStart,
1599  (PVOID)InitEnd,
1600  &LdrEntry->BaseDllName,
1601  LdrEntry->DllBase,
1602  InitSection->Name);
1603  MiFreeInitializationCode((PVOID)InitStart, (PVOID)InitEnd);
1604  }
1605  }
1606  }
1607 
1608  /* Move to the next section */
1609  SectionCount--;
1610  Section++;
1611  }
1612 
1613  /* Move to the next module */
1614  NextEntry = NextEntry->Flink;
1615  }
1616 
1617  /* Leave the critical region and return */
1619 }
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
ULONG SizeOfImage
Definition: ldrtypes.h:142
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
uint32_t ULONG_PTR
Definition: typedefs.h:63
PVOID DllBase
Definition: btrfs_drv.h:1835
VOID NTAPI MiFreeInitializationCode(IN PVOID InitStart, IN PVOID InitEnd)
Definition: sysldr.c:1427
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
union Alignment_ Alignment
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
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:326
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
CONST CHAR * PCCH
Definition: ntbasedef.h:399
if(!(yy_init))
Definition: macro.lex.yy.c:714
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: btrfs_drv.h:1831
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:117
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define ALIGN_DOWN_BY(size, align)
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:144
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
#define RtlImageNtHeader
Definition: compat.h:457
union _IMAGE_SECTION_HEADER::@1526 Misc
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)
INIT_FUNCTION VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1450
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:937
#define LDRP_MM_LOADED
Definition: ldrtypes.h:59
#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 1427 of file sysldr.c.

1429 {
1430  PMMPTE PointerPte;
1431  PFN_NUMBER PagesFreed;
1432 
1433  /* Get the start PTE */
1434  PointerPte = MiAddressToPte(InitStart);
1435  ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE);
1436 
1437  /* Compute the number of pages we expect to free */
1438  PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte);
1439 
1440  /* Try to actually free them */
1441  PagesFreed = MiDeleteSystemPageableVm(PointerPte,
1442  PagesFreed,
1443  0,
1444  NULL);
1445 }
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
smooth NULL
Definition: ftsmooth.c:416
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:297
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:937

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiInitializeLoadedModuleList()

INIT_FUNCTION BOOLEAN NTAPI MiInitializeLoadedModuleList ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 2200 of file sysldr.c.

2201 {
2202  PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
2203  PLIST_ENTRY ListHead, NextEntry;
2204  ULONG EntrySize;
2205 
2206  /* Setup the loaded module list and locks */
2210 
2211  /* Get loop variables and the kernel entry */
2212  ListHead = &LoaderBlock->LoadOrderListHead;
2213  NextEntry = ListHead->Flink;
2214  LdrEntry = CONTAINING_RECORD(NextEntry,
2216  InLoadOrderLinks);
2217  PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
2218 
2219  /* Locate resource section, pool code, and system pte code */
2220  MiLocateKernelSections(LdrEntry);
2221 
2222  /* Loop the loader block */
2223  while (NextEntry != ListHead)
2224  {
2225  /* Get the loader entry */
2226  LdrEntry = CONTAINING_RECORD(NextEntry,
2228  InLoadOrderLinks);
2229 
2230  /* FIXME: ROS HACK. Make sure this is a driver */
2231  if (!RtlImageNtHeader(LdrEntry->DllBase))
2232  {
2233  /* Skip this entry */
2234  NextEntry = NextEntry->Flink;
2235  continue;
2236  }
2237 
2238  /* Calculate the size we'll need and allocate a copy */
2239  EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
2240  LdrEntry->BaseDllName.MaximumLength +
2241  sizeof(UNICODE_NULL);
2243  if (!NewEntry) return FALSE;
2244 
2245  /* Copy the entry over */
2246  *NewEntry = *LdrEntry;
2247 
2248  /* Allocate the name */
2249  NewEntry->FullDllName.Buffer =
2251  LdrEntry->FullDllName.MaximumLength +
2252  sizeof(UNICODE_NULL),
2253  TAG_LDR_WSTR);
2254  if (!NewEntry->FullDllName.Buffer)
2255  {
2257  return FALSE;
2258  }
2259 
2260  /* Set the base name */
2261  NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
2262 
2263  /* Copy the full and base name */
2264  RtlCopyMemory(NewEntry->FullDllName.Buffer,
2265  LdrEntry->FullDllName.Buffer,
2266  LdrEntry->FullDllName.MaximumLength);
2267  RtlCopyMemory(NewEntry->BaseDllName.Buffer,
2268  LdrEntry->BaseDllName.Buffer,
2269  LdrEntry->BaseDllName.MaximumLength);
2270 
2271  /* Null-terminate the base name */
2272  NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
2273  sizeof(WCHAR)] = UNICODE_NULL;
2274 
2275  /* Insert the entry into the list */
2277  NextEntry = NextEntry->Flink;
2278  }
2279 
2280  /* Build the import lists for the boot drivers */
2282 
2283  /* We're done */
2284  return TRUE;
2285 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:37
struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG_PTR PsNtosImageBase
Definition: sysldr.c:38
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define InsertTailList(ListHead, Entry)
_In_ UCHAR EntrySize
Definition: iofuncs.h:640
KSPIN_LOCK PsLoadedModuleSpinLock
Definition: sysldr.c:36
PVOID DllBase
Definition: btrfs_drv.h:1835
#define TAG_LDR_WSTR
Definition: tag.h:110
#define UNICODE_NULL
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
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:119
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
INIT_FUNCTION NTSTATUS NTAPI MiBuildImportsForBootDrivers(VOID)
Definition: sysldr.c:1874
Definition: btrfs_drv.h:1831
Definition: typedefs.h:117
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:137
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
INIT_FUNCTION VOID NTAPI MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2139
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1837
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:144
#define RtlImageNtHeader
Definition: compat.h:457
#define TAG_MODULE_OBJECT
Definition: tag.h:109
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by MmArmInitSystem().

◆ MiLoadImageSection()

NTSTATUS NTAPI MiLoadImageSection ( IN OUT PVOID SectionPtr,
OUT PVOID ImageBase,
IN PUNICODE_STRING  FileName,
IN BOOLEAN  SessionLoad,
IN PLDR_DATA_TABLE_ENTRY  LdrEntry 
)

Definition at line 84 of file sysldr.c.

89 {
90  PROS_SECTION_OBJECT Section = *SectionPtr;
93  PVOID Base = NULL;
94  SIZE_T ViewSize = 0;
96  LARGE_INTEGER SectionOffset = {{0, 0}};
98  PFN_COUNT PteCount;
99  PMMPTE PointerPte, LastPte;
100  PVOID DriverBase;
101  MMPTE TempPte;
102  KIRQL OldIrql;
103  PFN_NUMBER PageFrameIndex;
104  PAGED_CODE();
105 
106  /* Detect session load */
107  if (SessionLoad)
108  {
109  /* Fail */
110  UNIMPLEMENTED_DBGBREAK("Session loading not yet supported!\n");
111  return STATUS_NOT_IMPLEMENTED;
112  }
113 
114  /* Not session load, shouldn't have an entry */
115  ASSERT(LdrEntry == NULL);
116 
117  /* Attach to the system process */
119 
120  /* Check if we need to load symbols */
122  {
123  /* Yes we do */
124  LoadSymbols = TRUE;
126  }
127 
128  /* Map the driver */
130  Status = MmMapViewOfSection(Section,
131  Process,
132  &Base,
133  0,
134  0,
135  &SectionOffset,
136  &ViewSize,
137  ViewUnmap,
138  0,
139  PAGE_EXECUTE);
140 
141  /* Re-enable the flag */
143 
144  /* Check if we failed with distinguished status code */
146  {
147  /* Change it to something more generic */
149  }
150 
151  /* Now check if we failed */
152  if (!NT_SUCCESS(Status))
153  {
154  /* Detach and return */
155  DPRINT1("MmMapViewOfSection failed with status 0x%x\n", Status);
157  return Status;
158  }
159 
160  /* Reserve system PTEs needed */
162  PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
163  if (!PointerPte)
164  {
165  DPRINT1("MiReserveSystemPtes failed\n");
168  }
169 
170  /* New driver base */
171  LastPte = PointerPte + PteCount;
172  DriverBase = MiPteToAddress(PointerPte);
173 
174  /* The driver is here */
175  *ImageBase = DriverBase;
176  DPRINT1("Loading: %wZ at %p with %lx pages\n", FileName, DriverBase, PteCount);
177 
178  /* Lock the PFN database */
180 
181  /* Loop the new driver PTEs */
183  while (PointerPte < LastPte)
184  {
185  /* Make sure the PTE is not valid for whatever reason */
186  ASSERT(PointerPte->u.Hard.Valid == 0);
187 
188  /* Some debug stuff */
190 #if MI_TRACE_PFNS
191  if (FileName->Buffer)
192  {
193  PWCHAR pos = NULL;
194  ULONG len = 0;
195  pos = wcsrchr(FileName->Buffer, '\\');
196  len = wcslen(pos) * sizeof(WCHAR);
197  if (pos) snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%S", pos);
198  }
199 #endif
200 
201  /* Grab a page */
202  PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
203 
204  /* Initialize its PFN entry */
205  MiInitializePfn(PageFrameIndex, PointerPte, TRUE);
206 
207  /* Write the PTE */
208  TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
209  MI_WRITE_VALID_PTE(PointerPte, TempPte);
210 
211  /* Move on */
212  PointerPte++;
213  }
214 
215  /* Release the PFN lock */
217 
218  /* Copy the image */
219  RtlCopyMemory(DriverBase, Base, PteCount << PAGE_SHIFT);
220 
221  /* Now unmap the view */
224 
225  /* Detach and return status */
227  return Status;
228 }
VOID NTAPI MiInitializePfn(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN BOOLEAN Modified)
Definition: pfnlist.c:969
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
KAPC_STATE
Definition: ketypes.h:1273
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
ULONG PFN_COUNT
Definition: mmtypes.h:102
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:2327
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:246
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define snprintf
Definition: wintirpc.h:48
uint16_t * PWCHAR
Definition: typedefs.h:54
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
#define PAGED_CODE()
Definition: video.h:57
union _MMPTE::@2234 u
PMM_IMAGE_SECTION_OBJECT ImageSection
Definition: mm.h:202
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG PFN_NUMBER
Definition: ke.h:8
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:951
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:701
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:198
#define PAGE_EXECUTE
Definition: nt_native.h:1306
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
#define MI_SET_USAGE(x)
Definition: mm.h:253
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:4499
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:404
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3051
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:345
__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:75
MMPTE ValidKernelPte
Definition: init.c:31
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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:803
GLenum GLsizei len
Definition: glext.h:6722
KPROCESS Pcb
Definition: pstypes.h:1193
Status
Definition: gdiplustypes.h:24
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
ULONG_PTR SIZE_T
Definition: typedefs.h:78
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define ROUND_TO_PAGES(Size)
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:753
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1484
#define min(a, b)
Definition: monoChain.cc:55
#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
SECTION_IMAGE_INFORMATION ImageInformation
Definition: mm.h:186
_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
unsigned int ULONG
Definition: retypes.h:1
static BOOLEAN LoadSymbols
Definition: kdb_symbols.c:29
ULONG NtGlobalFlag
Definition: init.c:51
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
CHAR MI_PFN_CURRENT_PROCESS_NAME[16]
Definition: pfnlist.c:64
ULONG PageFrameNumber
Definition: mmtypes.h:109

Referenced by MmLoadSystemImage().

◆ MiLocateExportName()

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

Definition at line 232 of file sysldr.c.

234 {
235  PULONG NameTable;
236  PUSHORT OrdinalTable;
237  PIMAGE_EXPORT_DIRECTORY ExportDirectory;
238  LONG Low = 0, Mid = 0, High, Ret;
239  USHORT Ordinal;
240  PVOID Function;
241  ULONG ExportSize;
242  PULONG ExportTable;
243  PAGED_CODE();
244 
245  /* Get the export directory */
246  ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
247  TRUE,
249  &ExportSize);
250  if (!ExportDirectory) return NULL;
251 
252  /* Setup name tables */
253  NameTable = (PULONG)((ULONG_PTR)DllBase +
254  ExportDirectory->AddressOfNames);
255  OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
256  ExportDirectory->AddressOfNameOrdinals);
257 
258  /* Do a binary search */
259  High = ExportDirectory->NumberOfNames - 1;
260  while (High >= Low)
261  {
262  /* Get new middle value */
263  Mid = (Low + High) >> 1;
264 
265  /* Compare name */
266  Ret = strcmp(ExportName, (PCHAR)DllBase + NameTable[Mid]);
267  if (Ret < 0)
268  {
269  /* Update high */
270  High = Mid - 1;
271  }
272  else if (Ret > 0)
273  {
274  /* Update low */
275  Low = Mid + 1;
276  }
277  else
278  {
279  /* We got it */
280  break;
281  }
282  }
283 
284  /* Check if we couldn't find it */
285  if (High < Low) return NULL;
286 
287  /* Otherwise, this is the ordinal */
288  Ordinal = OrdinalTable[Mid];
289 
290  /* Resolve the address and write it */
291  ExportTable = (PULONG)((ULONG_PTR)DllBase +
292  ExportDirectory->AddressOfFunctions);
293  Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
294 
295  /* Check if the function is actually a forwarder */
296  if (((ULONG_PTR)Function > (ULONG_PTR)ExportDirectory) &&
297  ((ULONG_PTR)Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
298  {
299  /* It is, fail */
300  return NULL;
301  }
302 
303  /* We found it */
304  return Function;
305 }
signed char * PCHAR
Definition: retypes.h:7
#define TRUE
Definition: types.h:120
Definition: strmini.h:380
#define PAGED_CODE()
Definition: video.h:57
DWORD AddressOfNameOrdinals
Definition: compat.h:155
uint32_t ULONG_PTR
Definition: typedefs.h:63
static LPOVERLAPPED_COMPLETION_ROUTINE Function
Definition: sync.c:684
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
Definition: strmini.h:378
#define RtlImageDirectoryEntryToData
Definition: compat.h:460
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:140
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
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

Referenced by MiCallDllUnloadAndUnloadDll(), and MmCallDllInitialize().

◆ MiLocateKernelSections()

INIT_FUNCTION VOID NTAPI MiLocateKernelSections ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2139 of file sysldr.c.

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

Referenced by MiInitializeLoadedModuleList().

◆ MiLookupDataTableEntry()

PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry ( IN PVOID  Address)

Definition at line 3282 of file sysldr.c.

3283 {
3284  PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL;
3285  PLIST_ENTRY NextEntry;
3286  PAGED_CODE();
3287 
3288  /* Loop entries */
3289  NextEntry = PsLoadedModuleList.Flink;
3290  do
3291  {
3292  /* Get the loader entry */
3293  LdrEntry = CONTAINING_RECORD(NextEntry,
3295  InLoadOrderLinks);
3296 
3297  /* Check if the address matches */
3298  if ((Address >= LdrEntry->DllBase) &&
3299  (Address < (PVOID)((ULONG_PTR)LdrEntry->DllBase +
3300  LdrEntry->SizeOfImage)))
3301  {
3302  /* Found a match */
3303  FoundEntry = LdrEntry;
3304  break;
3305  }
3306 
3307  /* Move on */
3308  NextEntry = NextEntry->Flink;
3309  } while(NextEntry != &PsLoadedModuleList);
3310 
3311  /* Return the entry */
3312  return FoundEntry;
3313 }
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
ULONG SizeOfImage
Definition: ldrtypes.h:142
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
PVOID DllBase
Definition: btrfs_drv.h:1835
smooth NULL
Definition: ftsmooth.c:416
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:119
Definition: btrfs_drv.h:1831
Definition: typedefs.h:117

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

◆ MiProcessLoaderEntry()

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

Definition at line 565 of file sysldr.c.

567 {
568  KIRQL OldIrql;
569 
570  /* Acquire module list lock */
573 
574  /* Acquire the spinlock too as we will insert or remove the entry */
576 
577  /* Insert or remove from the list */
578  if (Insert)
579  InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks);
580  else
581  RemoveEntryList(&LdrEntry->InLoadOrderLinks);
582 
583  /* Release locks */
587 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:37
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
#define InsertTailList(ListHead, Entry)
KSPIN_LOCK PsLoadedModuleSpinLock
Definition: sysldr.c:36
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:803
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#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()

INIT_FUNCTION VOID NTAPI MiReloadBootLoadedDrivers ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 1685 of file sysldr.c.

1686 {
1687  PLIST_ENTRY NextEntry;
1688  ULONG i = 0;
1689  PIMAGE_NT_HEADERS NtHeader;
1690  PLDR_DATA_TABLE_ENTRY LdrEntry;
1691  PIMAGE_FILE_HEADER FileHeader;
1692  BOOLEAN ValidRelocs;
1693  PIMAGE_DATA_DIRECTORY DataDirectory;
1694  PVOID DllBase, NewImageAddress;
1695  NTSTATUS Status;
1696  PMMPTE PointerPte, StartPte, LastPte;
1697  PFN_COUNT PteCount;
1698  PMMPFN Pfn1;
1699  MMPTE TempPte, OldPte;
1700 
1701  /* Loop driver list */
1702  for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
1703  NextEntry != &LoaderBlock->LoadOrderListHead;
1704  NextEntry = NextEntry->Flink)
1705  {
1706  /* Get the loader entry and NT header */
1707  LdrEntry = CONTAINING_RECORD(NextEntry,
1709  InLoadOrderLinks);
1710  NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
1711 
1712  /* Debug info */
1713  DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",
1714  LdrEntry->DllBase,
1715  (ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage,
1716  &LdrEntry->FullDllName);
1717 
1718  /* Get the first PTE and the number of PTEs we'll need */
1719  PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
1720  PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
1721  LastPte = StartPte + PteCount;
1722 
1723 #if MI_TRACE_PFNS
1724  /* Loop the PTEs */
1725  while (PointerPte < LastPte)
1726  {
1727  ULONG len;
1728  ASSERT(PointerPte->u.Hard.Valid == 1);
1729  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1730  len = wcslen(LdrEntry->BaseDllName.Buffer) * sizeof(WCHAR);
1731  snprintf(Pfn1->ProcessName, min(16, len), "%S", LdrEntry->BaseDllName.Buffer);
1732  PointerPte++;
1733  }
1734 #endif
1735  /* Skip kernel and HAL */
1736  /* ROS HACK: Skip BOOTVID/KDCOM too */
1737  i++;
1738  if (i <= 4) continue;
1739 
1740  /* Skip non-drivers */
1741  if (!NtHeader) continue;
1742 
1743  /* Get the file header and make sure we can relocate */
1744  FileHeader = &NtHeader->FileHeader;
1745  if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;
1746  if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <
1748 
1749  /* Everything made sense until now, check the relocation section too */
1750  DataDirectory = &NtHeader->OptionalHeader.
1751  DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
1752  if (!DataDirectory->VirtualAddress)
1753  {
1754  /* We don't really have relocations */
1755  ValidRelocs = FALSE;
1756  }
1757  else
1758  {
1759  /* Make sure the size is valid */
1760  if ((DataDirectory->VirtualAddress + DataDirectory->Size) >
1761  LdrEntry->SizeOfImage)
1762  {
1763  /* They're not, skip */
1764  continue;
1765  }
1766 
1767  /* We have relocations */
1768  ValidRelocs = TRUE;
1769  }
1770 
1771  /* Remember the original address */
1772  DllBase = LdrEntry->DllBase;
1773 
1774  /* Loop the PTEs */
1775  PointerPte = StartPte;
1776  while (PointerPte < LastPte)
1777  {
1778  /* Mark the page modified in the PFN database */
1779  ASSERT(PointerPte->u.Hard.Valid == 1);
1780  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1781  ASSERT(Pfn1->u3.e1.Rom == 0);
1782  Pfn1->u3.e1.Modified = TRUE;
1783 
1784  /* Next */
1785  PointerPte++;
1786  }
1787 
1788  /* Now reserve system PTEs for the image */
1789  PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
1790  if (!PointerPte)
1791  {
1792  /* Shouldn't happen */
1793  ERROR_FATAL("[Mm0]: Couldn't allocate driver section!\n");
1794  return;
1795  }
1796 
1797  /* This is the new virtual address for the module */
1798  LastPte = PointerPte + PteCount;
1799  NewImageAddress = MiPteToAddress(PointerPte);
1800 
1801  /* Sanity check */
1802  DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);
1804 
1805  /* Loop the new driver PTEs */
1807  while (PointerPte < LastPte)
1808  {
1809  /* Copy the old data */
1810  OldPte = *StartPte;
1811  ASSERT(OldPte.u.Hard.Valid == 1);
1812 
1813  /* Set page number from the loader's memory */
1814  TempPte.u.Hard.PageFrameNumber = OldPte.u.Hard.PageFrameNumber;
1815 
1816  /* Write it */
1817  MI_WRITE_VALID_PTE(PointerPte, TempPte);
1818 
1819  /* Move on */
1820  PointerPte++;
1821  StartPte++;
1822  }
1823 
1824  /* Update position */
1825  PointerPte -= PteCount;
1826 
1827  /* Sanity check */
1828  ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);
1829 
1830  /* Set the image base to the address where the loader put it */
1831  NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
1832 
1833  /* Check if we had relocations */
1834  if (ValidRelocs)
1835  {
1836  /* Relocate the image */
1837  Status = LdrRelocateImageWithBias(NewImageAddress,
1838  0,
1839  "SYSLDR",
1843  if (!NT_SUCCESS(Status))
1844  {
1845  /* This shouldn't happen */
1846  ERROR_FATAL("Relocations failed!\n");
1847  return;
1848  }
1849  }
1850 
1851  /* Update the loader entry */
1852  LdrEntry->DllBase = NewImageAddress;
1853 
1854  /* Update the thunks */
1855  DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);
1856  MiUpdateThunks(LoaderBlock,
1857  DllBase,
1858  NewImageAddress,
1859  LdrEntry->SizeOfImage);
1860 
1861  /* Update the loader entry */
1862  LdrEntry->Flags |= LDRP_SYSTEM_MAPPED;
1863  LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +
1865  LdrEntry->SizeOfImage = PteCount << PAGE_SHIFT;
1866 
1867  /* FIXME: We'll need to fixup the PFN linkage when switching to ARM3 */
1868  }
1869 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define TRUE
Definition: types.h:120
ULONG PFN_COUNT
Definition: mmtypes.h:102
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
LONG NTSTATUS
Definition: precomp.h:26
ULONG SizeOfImage
Definition: ldrtypes.h:142
#define snprintf
Definition: wintirpc.h:48
USHORT Modified
Definition: mm.h:292
INIT_FUNCTION VOID NTAPI MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PVOID OldBase, IN PVOID NewBase, IN ULONG Size)
Definition: sysldr.c:592
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define ERROR_FATAL(...)
Definition: debug.h:238
PVOID DllBase
Definition: btrfs_drv.h:1835
union _MMPTE::@2234 u
MMPFNENTRY e1
Definition: mm.h:329
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 MiAddressToPte(x)
Definition: mmx86.c:19
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:951
PVOID EntryPoint
Definition: ntddk_ex.h:203
unsigned char BOOLEAN
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:198
void DPRINT(...)
Definition: polytest.cpp:61
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:345
__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:75
MMPTE ValidKernelPte
Definition: init.c:31
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: mm.h:305
Definition: btrfs_drv.h:1831
ULONG ExpInitializationPhase
Definition: init.c:65
GLenum GLsizei len
Definition: glext.h:6722
Definition: typedefs.h:117
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
Status
Definition: gdiplustypes.h:24
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)
#define ROUND_TO_PAGES(Size)
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1837
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:144
USHORT Rom
Definition: mm.h:300
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define RtlImageNtHeader
Definition: compat.h:457
ULONG Flags
Definition: ntddk_ex.h:207
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
union _MMPFN::@1728 u3
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:247
return STATUS_SUCCESS
Definition: btrfs.c:2777
#define PFN_FROM_PTE(v)
Definition: mm.h:89
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
ULONG PageFrameNumber
Definition: mmtypes.h:109
#define LDRP_SYSTEM_MAPPED
Definition: ldrtypes.h:53

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

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

2499 {
2500  PVOID ImageBase;
2501  PETHREAD CurrentThread = PsGetCurrentThread();
2502  PFN_COUNT PageCount = 0;
2503  PFN_NUMBER PageFrameIndex;
2504  PMMPFN Pfn1;
2505  PAGED_CODE();
2506 
2507  /* The page fault handler is broken and doesn't page back in! */
2508  DPRINT1("WARNING: MiSetPagingOfDriver() called, but paging is broken! ignoring!\n");
2509  return;
2510 
2511  /* Get the driver's base address */
2512  ImageBase = MiPteToAddress(PointerPte);
2513  ASSERT(MI_IS_SESSION_IMAGE_ADDRESS(ImageBase) == FALSE);
2514 
2515  /* If this is a large page, it's stuck in physical memory */
2516  if (MI_IS_PHYSICAL_ADDRESS(ImageBase)) return;
2517 
2518  /* Lock the working set */
2519  MiLockWorkingSet(CurrentThread, &MmSystemCacheWs);
2520 
2521  /* Loop the PTEs */
2522  while (PointerPte <= LastPte)
2523  {
2524  /* Check for valid PTE */
2525  if (PointerPte->u.Hard.Valid == 1)
2526  {
2527  PageFrameIndex = PFN_FROM_PTE(PointerPte);
2528  Pfn1 = MiGetPfnEntry(PageFrameIndex);
2529  ASSERT(Pfn1->u2.ShareCount == 1);
2530 
2531  /* No working sets in ReactOS yet */
2532  PageCount++;
2533  }
2534 
2535  ImageBase = (PVOID)((ULONG_PTR)ImageBase + PAGE_SIZE);
2536  PointerPte++;
2537  }
2538 
2539  /* Release the working set */
2540  MiUnlockWorkingSet(CurrentThread, &MmSystemCacheWs);
2541 
2542  /* Do we have any driver pages? */
2543  if (PageCount)
2544  {
2545  /* Update counters */
2547  }
2548 }
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ULONG PFN_COUNT
Definition: mmtypes.h:102
PFN_NUMBER MmTotalSystemDriverPages
Definition: sysldr.c:41
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG PFN_NUMBER
Definition: ke.h:8
ULONG_PTR ShareCount
Definition: mm.h:322
MMSUPPORT MmSystemCacheWs
Definition: init.c:55
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:198
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1284
void * PVOID
Definition: retypes.h:9
#define InterlockedExchangeAdd
Definition: interlocked.h:181
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: mm.h:305
#define PAGE_SIZE
Definition: env_spec_w32.h:49
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
#define DPRINT1
Definition: precomp.h:8
#define MI_IS_SESSION_IMAGE_ADDRESS(Address)
Definition: miarm.h:172
union _MMPFN::@1727 u2
FORCEINLINE VOID MiLockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1240
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:937
signed int * PLONG
Definition: retypes.h:5
#define PFN_FROM_PTE(v)
Definition: mm.h:89

Referenced by MiEnablePagingOfDriver(), and MmPageEntireDriver().

◆ MiSetSystemCodeProtection()

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

Definition at line 2346 of file sysldr.c.

2350 {
2351  PMMPTE PointerPte;
2352  MMPTE TempPte;
2353 
2354  /* Loop the PTEs */
2355  for (PointerPte = FirstPte; PointerPte <= LastPte; PointerPte++)
2356  {
2357  /* Read the PTE */
2358  TempPte = *PointerPte;
2359 
2360  /* Make sure it's valid */
2361  ASSERT(TempPte.u.Hard.Valid == 1);
2362 
2363  /* Update the protection */
2364  TempPte.u.Hard.Write = BooleanFlagOn(Protection, IMAGE_SCN_MEM_WRITE);
2365 #if _MI_HAS_NO_EXECUTE
2366  TempPte.u.Hard.NoExecute = !BooleanFlagOn(Protection, IMAGE_SCN_MEM_EXECUTE);
2367 #endif
2368 
2369  MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2370  }
2371 
2372  /* Flush it all */
2374 
2375  return;
2376 }
#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:413
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:965
#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 691 of file sysldr.c.

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

Referenced by MiResolveImageReferences().

◆ MiUpdateThunks()

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

Definition at line 592 of file sysldr.c.

596 {
597  ULONG_PTR OldBaseTop, Delta;
598  PLDR_DATA_TABLE_ENTRY LdrEntry;
599  PLIST_ENTRY NextEntry;
600  ULONG ImportSize;
601  //
602  // FIXME: MINGW-W64 must fix LD to generate drivers that Windows can load,
603  // since a real version of Windows would fail at this point, but they seem
604  // busy implementing features such as "HotPatch" support in GCC 4.6 instead,
605  // a feature which isn't even used by Windows. Priorities, priorities...
606  // Please note that Microsoft WDK EULA and license prohibits using
607  // the information contained within it for the generation of "non-Windows"
608  // drivers, which is precisely what LD will generate, since an LD driver
609  // will not load on Windows.
610  //
611 #ifdef _WORKING_LINKER_
612  ULONG i;
613 #endif
614  PULONG_PTR ImageThunk;
615  PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
616 
617  /* Calculate the top and delta */
618  OldBaseTop = (ULONG_PTR)OldBase + Size - 1;
619  Delta = (ULONG_PTR)NewBase - (ULONG_PTR)OldBase;
620 
621  /* Loop the loader block */
622  for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
623  NextEntry != &LoaderBlock->LoadOrderListHead;
624  NextEntry = NextEntry->Flink)
625  {
626  /* Get the loader entry */
627  LdrEntry = CONTAINING_RECORD(NextEntry,
629  InLoadOrderLinks);
630 #ifdef _WORKING_LINKER_
631  /* Get the IAT */
632  ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
633  TRUE,
635  &ImportSize);
636  if (!ImageThunk) continue;
637 
638  /* Make sure we have an IAT */
639  DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
640  for (i = 0; i < ImportSize; i++, ImageThunk++)
641  {
642  /* Check if it's within this module */
643  if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
644  {
645  /* Relocate it */
646  DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
647  ImageThunk, *ImageThunk, *ImageThunk + Delta);
648  *ImageThunk += Delta;
649  }
650  }
651 #else
652  /* Get the import table */
653  ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
654  TRUE,
656  &ImportSize);
657  if (!ImportDescriptor) continue;
658 
659  /* Make sure we have an IAT */
660  DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
661  while ((ImportDescriptor->Name) &&
662  (ImportDescriptor->OriginalFirstThunk))
663  {
664  /* Get the image thunk */
665  ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
666  ImportDescriptor->FirstThunk);
667  while (*ImageThunk)
668  {
669  /* Check if it's within this module */
670  if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
671  {
672  /* Relocate it */
673  DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
674  ImageThunk, *ImageThunk, *ImageThunk + Delta);
675  *ImageThunk += Delta;
676  }
677 
678  /* Go to the next thunk */
679  ImageThunk++;
680  }
681 
682  /* Go to the next import */
683  ImportDescriptor++;
684  }
685 #endif
686  }
687 }
#define TRUE
Definition: types.h:120
uint32_t ULONG_PTR
Definition: typedefs.h:63
PVOID DllBase
Definition: btrfs_drv.h:1835
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
void DPRINT(...)
Definition: polytest.cpp:61
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:119
#define RtlImageDirectoryEntryToData
Definition: compat.h:460
Definition: btrfs_drv.h:1831
Definition: typedefs.h:117
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define IMAGE_DIRECTORY_ENTRY_IAT
Definition: pedump.c:271
static ULONG Delta
Definition: xboxvideo.c:28
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:144
#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:63

Referenced by MiReloadBootLoadedDrivers().

◆ MiUseLargeDriverPage()

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

Definition at line 2289 of file sysldr.c.

2293 {
2294  PLIST_ENTRY NextEntry;
2295  BOOLEAN DriverFound = FALSE;
2296  PMI_LARGE_PAGE_DRIVER_ENTRY LargePageDriverEntry;
2298  ASSERT(*ImageBaseAddress >= MmSystemRangeStart);
2299 
2300 #ifdef _X86_
2301  if (!(KeFeatureBits & KF_LARGE_PAGE)) return FALSE;
2302  if (!(__readcr4() & CR4_PSE)) return FALSE;
2303 #endif
2304 
2305  /* Make sure there's enough system PTEs for a large page driver */
2307  {
2308  return FALSE;
2309  }
2310 
2311  /* This happens if the registry key had a "*" (wildcard) in it */
2312  if (MiLargePageAllDrivers == 0)
2313  {
2314  /* It didn't, so scan the list */
2315  NextEntry = MiLargePageDriverList.Flink;
2316  while (NextEntry != &MiLargePageDriverList)
2317  {
2318  /* Check if the driver name matches */
2319  LargePageDriverEntry = CONTAINING_RECORD(NextEntry,
2321  Links);
2322  if (RtlEqualUnicodeString(BaseImageName,
2323  &LargePageDriverEntry->BaseName,
2324  TRUE))
2325  {
2326  /* Enable large pages for this driver */
2327  DriverFound = TRUE;
2328  break;
2329  }
2330 
2331  /* Keep trying */
2332  NextEntry = NextEntry->Flink;
2333  }
2334 
2335  /* If we didn't find the driver, it doesn't need large pages */
2336  if (DriverFound == FALSE) return FALSE;
2337  }
2338 
2339  /* Nothing to do yet */
2340  DPRINT1("Large pages not supported!\n");
2341  return FALSE;
2342 }
#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:412
#define KF_LARGE_PAGE
Definition: ketypes.h:148
unsigned char BOOLEAN
Definition: miarm.h:409
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:119
#define PDE_MAPPED_VA
Definition: miarm.h:22
BOOLEAN MiLargePageAllDrivers
Definition: largepag.c:27
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: typedefs.h:117
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1713
#define DPRINT1
Definition: precomp.h:8
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 2380 of file sysldr.c.

2382 {
2383  PIMAGE_NT_HEADERS NtHeaders;
2384  PIMAGE_SECTION_HEADER SectionHeaders, Section;
2385  ULONG i;
2386  PVOID SectionBase, SectionEnd;
2387  ULONG SectionSize;
2388  ULONG Protection;
2389  PMMPTE FirstPte, LastPte;
2390 
2391  /* Check if the registry setting is on or not */
2393  {
2394  /* Ignore section protection */
2395  return;
2396  }
2397 
2398  /* Large page mapped images are not supported */
2399  NT_ASSERT(!MI_IS_PHYSICAL_ADDRESS(ImageBase));
2400 
2401  /* Session images are not yet supported */
2402  NT_ASSERT(!MI_IS_SESSION_ADDRESS(ImageBase));
2403 
2404  /* Get the NT headers */
2405  NtHeaders = RtlImageNtHeader(ImageBase);
2406  if (NtHeaders == NULL)
2407  {
2408  DPRINT1("Failed to get NT headers for image @ %p\n", ImageBase);
2409  return;
2410  }
2411 
2412  /* Don't touch NT4 drivers */
2413  if ((NtHeaders->OptionalHeader.MajorOperatingSystemVersion < 5) ||
2414  (NtHeaders->OptionalHeader.MajorSubsystemVersion < 5))
2415  {
2416  DPRINT1("Skipping NT 4 driver @ %p\n", ImageBase);
2417  return;
2418  }
2419 
2420  /* Get the section headers */
2421  SectionHeaders = IMAGE_FIRST_SECTION(NtHeaders);
2422 
2423  /* Get the base address of the first section */
2424  SectionBase = Add2Ptr(ImageBase, SectionHeaders[0].VirtualAddress);
2425 
2426  /* Start protecting the image header as R/O */
2427  FirstPte = MiAddressToPte(ImageBase);
2428  LastPte = MiAddressToPte(SectionBase) - 1;
2429  Protection = IMAGE_SCN_MEM_READ;
2430  if (LastPte >= FirstPte)
2431  {
2432  MiSetSystemCodeProtection(FirstPte, LastPte, IMAGE_SCN_MEM_READ);
2433  }
2434 
2435  /* Loop the sections */
2436  for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
2437  {
2438  /* Get the section base address and size */
2439  Section = &SectionHeaders[i];
2440  SectionBase = Add2Ptr(ImageBase, Section->VirtualAddress);
2441  SectionSize = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2442 
2443  /* Get the first PTE of this section */
2444  FirstPte = MiAddressToPte(SectionBase);
2445 
2446  /* Check for overlap with the previous range */
2447  if (FirstPte == LastPte)
2448  {
2449  /* Combine the old and new protection by ORing them */
2450  Protection |= (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2451 
2452  /* Update the protection for this PTE */
2453  MiSetSystemCodeProtection(FirstPte, FirstPte, Protection);
2454 
2455  /* Skip this PTE */
2456  FirstPte++;
2457  }
2458 
2459  /* There can not be gaps! */
2460  NT_ASSERT(FirstPte == (LastPte + 1));
2461 
2462  /* Get the end of the section and the last PTE */
2463  SectionEnd = Add2Ptr(SectionBase, SectionSize - 1);
2464  NT_ASSERT(SectionEnd < Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage));
2465  LastPte = MiAddressToPte(SectionEnd);
2466 
2467  /* If there are no more pages (after an overlap), skip this section */
2468  if (LastPte < FirstPte)
2469  {
2470  NT_ASSERT(FirstPte == (LastPte + 1));
2471  continue;
2472  }
2473 
2474  /* Get the section protection */
2475  Protection = (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2476 
2477  /* Update the protection for this section */
2478  MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2479  }
2480 
2481  /* Image should end with the last section */
2482  if (ALIGN_UP_POINTER_BY(SectionEnd, PAGE_SIZE) !=
2483  Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage))
2484  {
2485  DPRINT1("ImageBase 0x%p ImageSize 0x%lx Section %u VA 0x%lx Raw 0x%lx virt 0x%lx\n",
2486  ImageBase,
2487  NtHeaders->OptionalHeader.SizeOfImage,
2488  i,
2489  Section->VirtualAddress,
2490  Section->SizeOfRawData,
2491  Section->Misc.VirtualSize);
2492  }
2493 }
#define max(a, b)
Definition: svc.c:63
#define Add2Ptr(PTR, INC)
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:175
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
WORD MajorOperatingSystemVersion
Definition: ntddk_ex.h:160
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 MiAddressToPte(x)
Definition: mmx86.c:19
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
VOID NTAPI MiSetSystemCodeProtection(_In_ PMMPTE FirstPte, _In_ PMMPTE LastPte, _In_ ULONG Protection)
Definition: sysldr.c:2346
#define IMAGE_SCN_PROTECTION_MASK
Definition: miarm.h:164
smooth NULL
Definition: ftsmooth.c:416
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define ALIGN_UP_POINTER_BY(ptr, align)
Definition: umtypes.h:85
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
BOOLEAN MmEnforceWriteProtection
Definition: sysldr.c:47
#define DPRINT1
Definition: precomp.h:8
#define RtlImageNtHeader
Definition: compat.h:457
union _IMAGE_SECTION_HEADER::@1526 Misc
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:937
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by MmInitSystem(), and MmLoadSystemImage().

◆ MmCallDllInitialize()

NTSTATUS NTAPI MmCallDllInitialize ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry,
IN PLIST_ENTRY  ListHead 
)

Definition at line 309 of file sysldr.c.

311 {
312  UNICODE_STRING ServicesKeyName = RTL_CONSTANT_STRING(
313  L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
314  PMM_DLL_INITIALIZE DllInit;
315  UNICODE_STRING RegPath, ImportName;
317 
318  /* Try to see if the image exports a DllInitialize routine */
319  DllInit = (PMM_DLL_INITIALIZE)MiLocateExportName(LdrEntry->DllBase,
320  "DllInitialize");
321  if (!DllInit) return STATUS_SUCCESS;
322 
323  /* Do a temporary copy of BaseDllName called ImportName
324  * because we'll alter the length of the string
325  */
326  ImportName.Length = LdrEntry->BaseDllName.Length;
327  ImportName.MaximumLength = LdrEntry->BaseDllName.MaximumLength;
328  ImportName.Buffer = LdrEntry->BaseDllName.Buffer;
329 
330  /* Obtain the path to this dll's service in the registry */
331  RegPath.MaximumLength = ServicesKeyName.Length +
332  ImportName.Length + sizeof(UNICODE_NULL);
334  RegPath.MaximumLength,
335  TAG_LDR_WSTR);
336 
337  /* Check if this allocation was unsuccessful */
338  if (!RegPath.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
339 
340  /* Build and append the service name itself */
341  RegPath.Length = ServicesKeyName.Length;
342  RtlCopyMemory(RegPath.Buffer,
343  ServicesKeyName.Buffer,
344  ServicesKeyName.Length);
345 
346  /* Check if there is a dot in the filename */
347  if (wcschr(ImportName.Buffer, L'.'))
348  {
349  /* Remove the extension */
350  ImportName.Length = (USHORT)(wcschr(ImportName.Buffer, L'.') -
351  ImportName.Buffer) * sizeof(WCHAR);
352  }
353 
354  /* Append service name (the basename without extension) */
355  RtlAppendUnicodeStringToString(&RegPath, &ImportName);
356 
357  /* Now call the DllInit func */
358  DPRINT("Calling DllInit(%wZ)\n", &RegPath);
359  Status = DllInit(&RegPath);
360 
361  /* Clean up */
363 
364  /* Return status value which DllInitialize returned */
365  return Status;
366 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
LONG NTSTATUS
Definition: precomp.h:26
#define TAG_LDR_WSTR
Definition: tag.h:110
#define UNICODE_NULL
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS(NTAPI * PMM_DLL_INITIALIZE)(_In_ PUNICODE_STRING RegistryPath)
Definition: iotypes.h:2494
_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
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
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:232
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2777
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by IopInitializeBootDrivers(), and MiResolveImageReferences().

◆ MmCheckSystemImage()

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

Definition at line 2643 of file sysldr.c.

2645 {
2646  NTSTATUS Status;
2647  HANDLE SectionHandle;
2648  PVOID ViewBase = NULL;
2649  SIZE_T ViewSize = 0;
2651  FILE_STANDARD_INFORMATION FileStandardInfo;
2653  PIMAGE_NT_HEADERS NtHeaders;
2655  PAGED_CODE();
2656 
2657  /* Setup the object attributes */
2659  NULL,
2661  NULL,
2662  NULL);
2663 
2664  /* Create a section for the DLL */
2665  Status = ZwCreateSection(&SectionHandle,
2668  NULL,
2669  PAGE_EXECUTE,
2670  SEC_IMAGE,
2671  ImageHandle);
2672  if (!NT_SUCCESS(Status))
2673  {
2674  DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2675  return Status;
2676  }
2677 
2678  /* Make sure we're in the system process */
2680 
2681  /* Map it */
2682  Status = ZwMapViewOfSection(SectionHandle,
2683  NtCurrentProcess(),
2684  &ViewBase,
2685  0,
2686  0,
2687  NULL,
2688  &ViewSize,
2689  ViewShare,
2690  0,
2691  PAGE_EXECUTE);
2692  if (!NT_SUCCESS(Status))
2693  {
2694  /* We failed, close the handle and return */
2695  DPRINT1("ZwMapViewOfSection failed with status 0x%x\n", Status);
2697  ZwClose(SectionHandle);
2698  return Status;
2699  }
2700 
2701  /* Now query image information */
2702  Status = ZwQueryInformationFile(ImageHandle,
2703  &IoStatusBlock,
2704  &FileStandardInfo,
2705  sizeof(FileStandardInfo),
2707  if (NT_SUCCESS(Status))
2708  {
2709  /* First, verify the checksum */
2711  ViewSize,
2712  FileStandardInfo.
2713  EndOfFile.LowPart))
2714  {
2715  /* Set checksum failure */
2717  goto Fail;
2718  }
2719 
2720  /* Make sure it's a real image */
2721  NtHeaders = RtlImageNtHeader(ViewBase);
2722  if (!NtHeaders)
2723  {
2724  /* Set checksum failure */
2726  goto Fail;
2727  }
2728 
2729  /* Make sure it's for the correct architecture */
2730  if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
2732  {
2733  /* Set protection failure */
2735  goto Fail;
2736  }
2737 
2738  /* Check that it's a valid SMP image if we have more then one CPU */
2739  if (!MmVerifyImageIsOkForMpUse(ViewBase))
2740  {
2741  /* Otherwise it's not the right image */
2743  }
2744  }
2745 
2746  /* Unmap the section, close the handle, and return status */
2747 Fail:
2748  ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
2750  ZwClose(SectionHandle);
2751  return Status;
2752 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
KAPC_STATE
Definition: ketypes.h:1273
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum(_In_ PVOID BaseAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG FileLength)
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#define PAGED_CODE()
Definition: video.h:57
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:701
#define STATUS_IMAGE_MP_UP_MISMATCH
Definition: ntstatus.h:703
smooth NULL
Definition: ftsmooth.c:416
#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:663
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:526
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
BOOLEAN NTAPI MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)
Definition: sysldr.c:2619
KPROCESS Pcb
Definition: pstypes.h:1193
Status
Definition: gdiplustypes.h:24
Definition: hiveinit.c:368
ULONG_PTR SIZE_T
Definition: typedefs.h:78
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:753
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1484
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#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:457
_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 OBJ_KERNEL_HANDLE
Definition: winternl.h:231

Referenced by MmLoadSystemImage(), and PsLocateSystemDll().

◆ MmFreeDriverInitialization()

VOID NTAPI MmFreeDriverInitialization ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 1627 of file sysldr.c.

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

Referenced by IopInitializeDriverModule().

◆ MmGetSystemRoutineAddress()

PVOID NTAPI MmGetSystemRoutineAddress ( IN PUNICODE_STRING  SystemRoutineName)

Definition at line 3369 of file sysldr.c.

3370 {
3371  PVOID ProcAddress = NULL;
3372  ANSI_STRING AnsiRoutineName;
3373  NTSTATUS Status;
3374  PLIST_ENTRY NextEntry;
3375  PLDR_DATA_TABLE_ENTRY LdrEntry;
3376  BOOLEAN Found = FALSE;
3377  UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
3379  ULONG Modules = 0;
3380 
3381  /* Convert routine to ansi name */
3382  Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName,
3383  SystemRoutineName,
3384  TRUE);
3385  if (!NT_SUCCESS(Status)) return NULL;
3386 
3387  /* Lock the list */
3390 
3391  /* Loop the loaded module list */
3392  NextEntry = PsLoadedModuleList.Flink;
3393  while (NextEntry != &PsLoadedModuleList)
3394  {
3395  /* Get the entry */
3396  LdrEntry = CONTAINING_RECORD(NextEntry,
3398  InLoadOrderLinks);
3399 
3400  /* Check if it's the kernel or HAL */
3401  if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
3402  {
3403  /* Found it */
3404  Found = TRUE;
3405  Modules++;
3406  }
3407  else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
3408  {
3409  /* Found it */
3410  Found = TRUE;
3411  Modules++;
3412  }
3413 
3414  /* Check if we found a valid binary */
3415  if (Found)
3416  {
3417  /* Find the procedure name */
3418  ProcAddress = MiFindExportedRoutineByName(LdrEntry->DllBase,
3419  &AnsiRoutineName);
3420 
3421  /* Break out if we found it or if we already tried both modules */
3422  if (ProcAddress) break;
3423  if (Modules == 2) break;
3424  }
3425 
3426  /* Keep looping */
3427  NextEntry = NextEntry->Flink;
3428  }
3429 
3430  /* Release the lock */
3433 
3434  /* Free the string and return */
3435  RtlFreeAnsiString(&AnsiRoutineName);
3436  return ProcAddress;
3437 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:37
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
LONG NTSTATUS
Definition: precomp.h:26
PVOID DllBase
Definition: btrfs_drv.h:1835
PWCHAR HalName
Definition: halacpi.c:45
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#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
static const WCHAR L[]
Definition: oid.c:1250
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: btrfs_drv.h:1831
Definition: typedefs.h:117
Status
Definition: gdiplustypes.h:24
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:144
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:490
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_(), KmtGetSystemRoutineAddress(), 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 2756 of file sysldr.c.

2762 {
2763  PVOID ModuleLoadBase = NULL;
2764  NTSTATUS Status;
2768  PIMAGE_NT_HEADERS NtHeader;
2769  UNICODE_STRING BaseName, BaseDirectory, PrefixName, UnicodeTemp;
2770  PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
2771  ULONG EntrySize, DriverSize;
2772  PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
2773  PCHAR MissingApiName, Buffer;
2774  PWCHAR MissingDriverName;
2775  HANDLE SectionHandle;
2777  PVOID Section = NULL;
2778  BOOLEAN LockOwned = FALSE;
2779  PLIST_ENTRY NextEntry;
2780  IMAGE_INFO ImageInfo;
2781  STRING AnsiTemp;
2782  PAGED_CODE();
2783 
2784  /* Detect session-load */
2785  if (Flags)
2786  {
2787  /* Sanity checks */
2788  ASSERT(NamePrefix == NULL);
2789  ASSERT(LoadedName == NULL);
2790 
2791  /* Make sure the process is in session too */
2792  if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;
2793  }
2794 
2795  /* Allocate a buffer we'll use for names */
2798  TAG_LDR_WSTR);
2800 
2801  /* Check for a separator */
2802  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2803  {
2804  PWCHAR p;
2805  ULONG BaseLength;
2806 
2807  /* Loop the path until we get to the base name */
2808  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
2809  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
2810 
2811  /* Get the length */
2812  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
2813  BaseLength *= sizeof(WCHAR);
2814 
2815  /* Setup the string */
2816  BaseName.Length = (USHORT)BaseLength;
2817  BaseName.Buffer = p;
2818  }
2819  else
2820  {
2821  /* Otherwise, we already have a base name */
2822  BaseName.Length = FileName->Length;
2823  BaseName.Buffer = FileName->Buffer;
2824  }
2825 
2826  /* Setup the maximum length */
2827  BaseName.MaximumLength = BaseName.Length;
2828 
2829  /* Now compute the base directory */
2830  BaseDirectory = *FileName;
2831  BaseDirectory.Length -= BaseName.Length;
2832  BaseDirectory.MaximumLength = BaseDirectory.Length;
2833 
2834  /* And the prefix, which for now is just the name itself */
2835  PrefixName = *FileName;
2836 
2837  /* Check if we have a prefix */
2838  if (NamePrefix) DPRINT1("Prefixed images are not yet supported!\n");
2839 
2840  /* Check if we already have a name, use it instead */
2841  if (LoadedName) BaseName = *LoadedName;
2842 
2843  /* Check for loader snap debugging */
2845  {
2846  /* Print out standard string */
2847  DPRINT1("MM:SYSLDR Loading %wZ (%wZ) %s\n",
2848  &PrefixName, &BaseName, Flags ? "in session space" : "");
2849  }
2850 
2851  /* Acquire the load lock */
2852 LoaderScan:
2853  ASSERT(LockOwned == FALSE);
2854  LockOwned = TRUE;
2858  KernelMode,
2859  FALSE,
2860  NULL);
2861 
2862  /* Scan the module list */
2863  NextEntry = PsLoadedModuleList.Flink;
2864  while (NextEntry != &PsLoadedModuleList)
2865  {
2866  /* Get the entry and compare the names */
2867  LdrEntry = CONTAINING_RECORD(NextEntry,
2869  InLoadOrderLinks);
2870  if (RtlEqualUnicodeString(&PrefixName, &LdrEntry->FullDllName, TRUE))
2871  {
2872  /* Found it, break out */
2873  break;
2874  }
2875 
2876  /* Keep scanning */
2877  NextEntry = NextEntry->Flink;
2878  }
2879 
2880  /* Check if we found the image */
2881  if (NextEntry != &PsLoadedModuleList)
2882  {
2883  /* Check if we had already mapped a section */
2884  if (Section)
2885  {
2886  /* Dereference and clear */
2887  ObDereferenceObject(Section);
2888  Section = NULL;
2889  }
2890 
2891  /* Check if this was supposed to be a session load */
2892  if (!Flags)
2893  {
2894  /* It wasn't, so just return the data */
2895  *ModuleObject = LdrEntry;
2896  *ImageBaseAddress = LdrEntry->DllBase;
2898  }
2899  else
2900  {
2901  /* We don't support session loading yet */
2902  UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
2904  }
2905 
2906  /* Do cleanup */
2907  goto Quickie;
2908  }
2909  else if (!Section)
2910  {
2911  /* It wasn't loaded, and we didn't have a previous attempt */
2914  LockOwned = FALSE;
2915 
2916  /* Check if KD is enabled */
2918  {
2919  /* FIXME: Attempt to get image from KD */
2920  }
2921 
2922  /* We don't have a valid entry */
2923  LdrEntry = NULL;
2924 
2925  /* Setup image attributes */
2927  FileName,
2929  NULL,
2930  NULL);
2931 
2932  /* Open the image */
2934  FILE_EXECUTE,
2936  &IoStatusBlock,
2938  0);
2939  if (!NT_SUCCESS(Status))
2940  {
2941  DPRINT1("ZwOpenFile failed for '%wZ' with status 0x%x\n",
2942  FileName, Status);
2943  goto Quickie;
2944  }
2945 
2946  /* Validate it */
2951  {
2952  /* Fail loading */
2953  goto Quickie;
2954  }
2955 
2956  /* Check if this is a session-load */
2957  if (Flags)
2958  {
2959  /* Then we only need read and execute */
2961  }
2962  else
2963  {
2964  /* Otherwise, we can allow write access */
2966  }
2967 
2968  /* Initialize the attributes for the section */
2970  NULL,
2972  NULL,
2973  NULL);
2974 
2975  /* Create the section */
2976  Status = ZwCreateSection(&SectionHandle,
2977  DesiredAccess,
2979  NULL,
2980  PAGE_EXECUTE,
2981  SEC_IMAGE,
2982  FileHandle);
2983  if (!NT_SUCCESS(Status))
2984  {
2985  DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2986  goto Quickie;
2987  }
2988 
2989  /* Now get the section pointer */
2990  Status = ObReferenceObjectByHandle(SectionHandle,
2993  KernelMode,
2994  &Section,
2995  NULL);
2996  ZwClose(SectionHandle);
2997  if (!NT_SUCCESS(Status)) goto Quickie;
2998 
2999  /* Check if this was supposed to be a session-load */
3000  if (Flags)
3001  {
3002  /* We don't support session loading yet */
3003  UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3004  goto Quickie;
3005  }
3006 
3007  /* Check the loader list again, we should end up in the path below */
3008  goto LoaderScan;
3009  }
3010  else
3011  {
3012  /* We don't have a valid entry */
3013  LdrEntry = NULL;
3014  }
3015 
3016  /* Load the image */
3017  Status = MiLoadImageSection(&Section,
3018  &ModuleLoadBase,
3019  FileName,
3020  FALSE,
3021  NULL);
3023 
3024  /* Get the size of the driver */
3025  DriverSize = ((PROS_SECTION_OBJECT)Section)->ImageSection->ImageInformation.ImageFileSize;
3026 
3027  /* Make sure we're not being loaded into session space */
3028  if (!Flags)
3029  {
3030  /* Check for success */
3031  if (NT_SUCCESS(Status))
3032  {
3033  /* Support large pages for drivers */
3034  MiUseLargeDriverPage(DriverSize / PAGE_SIZE,
3035  &ModuleLoadBase,
3036  &BaseName,
3037  TRUE);
3038  }
3039 
3040  /* Dereference the section */
3041  ObDereferenceObject(Section);
3042  Section = NULL;
3043  }
3044 
3045  /* Check for failure of the load earlier */
3046  if (!NT_SUCCESS(Status))
3047  {
3048  DPRINT1("MiLoadImageSection failed with status 0x%x\n", Status);
3049  goto Quickie;
3050  }
3051 
3052  /* Relocate the driver */
3053  Status = LdrRelocateImageWithBias(ModuleLoadBase,
3054  0,
3055  "SYSLDR",
3059  if (!NT_SUCCESS(Status))
3060  {
3061  DPRINT1("LdrRelocateImageWithBias failed with status 0x%x\n", Status);
3062  goto Quickie;
3063  }
3064 
3065  /* Get the NT Header */
3066  NtHeader = RtlImageNtHeader(ModuleLoadBase);
3067 
3068  /* Calculate the size we'll need for the entry and allocate it */
3069  EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
3070  BaseName.Length +
3071  sizeof(UNICODE_NULL);
3072 
3073  /* Allocate the entry */
3075  if (!LdrEntry)
3076  {
3077  /* Fail */
3079  goto Quickie;
3080  }
3081 
3082  /* Setup the entry */
3083  LdrEntry->Flags = LDRP_LOAD_IN_PROGRESS;
3084  LdrEntry->LoadCount = 1;
3085  LdrEntry->LoadedImports = LoadedImports;
3086  LdrEntry->PatchInformation = NULL;
3087 
3088  /* Check the version */
3089  if ((NtHeader->OptionalHeader.MajorOperatingSystemVersion >= 5) &&
3090  (NtHeader->OptionalHeader.MajorImageVersion >= 5))
3091  {
3092  /* Mark this image as a native image */
3093  LdrEntry->Flags |= LDRP_ENTRY_NATIVE;
3094  }
3095 
3096  /* Setup the rest of the entry */
3097  LdrEntry->DllBase = ModuleLoadBase;
3098  LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase +
3100  LdrEntry->SizeOfImage = DriverSize;
3101  LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;
3102  LdrEntry->SectionPointer = Section;
3103 
3104  /* Now write the DLL name */
3105  LdrEntry->BaseDllName.Buffer = (PVOID)(LdrEntry + 1);
3106  LdrEntry->BaseDllName.Length = BaseName.Length;
3107  LdrEntry->BaseDllName.MaximumLength = BaseName.Length;
3108 
3109  /* Copy and null-terminate it */
3110  RtlCopyMemory(LdrEntry->BaseDllName.Buffer,
3111  BaseName.Buffer,
3112  BaseName.Length);
3113  LdrEntry->BaseDllName.Buffer[BaseName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3114 
3115  /* Now allocate the full name */
3117  PrefixName.Length +
3118  sizeof(UNICODE_NULL),
3119  TAG_LDR_WSTR);
3120  if (!LdrEntry->FullDllName.Buffer)
3121  {
3122  /* Don't fail, just set it to zero */
3123  LdrEntry->FullDllName.Length = 0;
3124  LdrEntry->FullDllName.MaximumLength = 0;
3125  }
3126  else
3127  {
3128  /* Set it up */
3129  LdrEntry->FullDllName.Length = PrefixName.Length;
3130  LdrEntry->FullDllName.MaximumLength = PrefixName.Length;
3131 
3132  /* Copy and null-terminate */
3133  RtlCopyMemory(LdrEntry->FullDllName.Buffer,
3134  PrefixName.Buffer,
3135  PrefixName.Length);
3136  LdrEntry->FullDllName.Buffer[PrefixName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3137  }
3138 
3139  /* Add the entry */
3140  MiProcessLoaderEntry(LdrEntry, TRUE);
3141 
3142  /* Resolve imports */
3143  MissingApiName = Buffer;
3144  MissingDriverName = NULL;
3145  Status = MiResolveImageReferences(ModuleLoadBase,
3146  &BaseDirectory,
3147  NULL,
3148  &MissingApiName,
3149  &MissingDriverName,
3150  &LoadedImports);
3151  if (!NT_SUCCESS(Status))
3152  {
3153  BOOLEAN NeedToFreeString = FALSE;
3154 
3155  /* If the lowest bit is set to 1, this is a hint that we need to free */
3156  if (*(ULONG_PTR*)&MissingDriverName & 1)
3157  {
3158  NeedToFreeString = TRUE;
3159  *(ULONG_PTR*)&MissingDriverName &= ~1;
3160  }
3161 
3162  DPRINT1("MiResolveImageReferences failed with status 0x%x\n", Status);
3163  DPRINT1(" Missing driver '%ls', missing API '%s'\n",
3164  MissingDriverName, MissingApiName);
3165 
3166  if (NeedToFreeString)
3167  {
3168  ExFreePoolWithTag(MissingDriverName, TAG_LDR_WSTR);
3169  }
3170 
3171  /* Fail */
3172  MiProcessLoaderEntry(LdrEntry, FALSE);
3173 
3174  /* Check if we need to free the name */
3175  if (LdrEntry->FullDllName.Buffer)
3176  {
3177  /* Free it */
3179  }
3180 
3181  /* Free the entry itself */
3183  LdrEntry = NULL;
3184  goto Quickie;
3185  }
3186 
3187  /* Update the loader entry */
3188  LdrEntry->Flags |= (LDRP_SYSTEM_MAPPED |
3190  LDRP_MM_LOADED);
3191  LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
3192  LdrEntry->LoadedImports = LoadedImports;
3193 
3194  /* FIXME: Call driver verifier's loader function */
3195 
3196  /* Write-protect the system image */
3198 
3199  /* Check if notifications are enabled */
3201  {
3202  /* Fill out the notification data */
3203  ImageInfo.Properties = 0;
3205  ImageInfo.SystemModeImage = TRUE;
3206  ImageInfo.ImageSize = LdrEntry->SizeOfImage;
3207  ImageInfo.ImageBase = LdrEntry->DllBase;
3208  ImageInfo.ImageSectionNumber = ImageInfo.ImageSelector = 0;
3209 
3210  /* Send the notification */
3212  }
3213 
3214 #if defined(KDBG) || defined(_WINKD_)
3215  /* MiCacheImageSymbols doesn't detect rossym */
3216  if (TRUE)
3217 #else
3218  /* Check if there's symbols */
3219  if (MiCacheImageSymbols(LdrEntry->DllBase))
3220 #endif
3221  {
3222  /* Check if the system root is present */
3223  if ((PrefixName.Length > (11 * sizeof(WCHAR))) &&
3224  !(_wcsnicmp(PrefixName.Buffer, L"\\SystemRoot", 11)))
3225  {
3226  /* Add the system root */
3227  UnicodeTemp = PrefixName;
3228  UnicodeTemp.Buffer += 11;
3229  UnicodeTemp.Length -= (11 * sizeof(WCHAR));