ReactOS  0.4.14-dev-50-g13bb5e2
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)
 
BOOLEAN NTAPI MmChangeKernelResourceSectionProtection (IN ULONG_PTR ProtectionMask)
 
VOID NTAPI MmMakeKernelResourceSectionWritable (VOID)
 
LOGICAL NTAPI MiUseLargeDriverPage (IN ULONG NumberOfPtes, IN OUT PVOID *ImageBaseAddress, IN PUNICODE_STRING BaseImageName, IN BOOLEAN BootDriver)
 
VOID NTAPI MiSetSystemCodeProtection (_In_ PMMPTE FirstPte, _In_ PMMPTE LastPte, _In_ ULONG Protection)
 
VOID NTAPI MiWriteProtectSystemImage (_In_ PVOID ImageBase)
 
VOID NTAPI MiSetPagingOfDriver (IN PMMPTE PointerPte, IN PMMPTE LastPte)
 
VOID NTAPI MiEnablePagingOfDriver (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
BOOLEAN NTAPI MmVerifyImageIsOkForMpUse (IN PVOID BaseAddress)
 
NTSTATUS NTAPI MmCheckSystemImage (IN HANDLE ImageHandle, IN BOOLEAN PurgeSection)
 
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 1875 of file sysldr.c.

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

372 {
375  PAGED_CODE();
376 
377  /* Get the unload routine */
378  Func = (PMM_DLL_UNLOAD)MiLocateExportName(LdrEntry->DllBase, "DllUnload");
379  if (!Func) return FALSE;
380 
381  /* Call it and check for success */
382  Status = Func();
383  if (!NT_SUCCESS(Status)) return FALSE;
384 
385  /* Lie about the load count so we can unload the image */
386  ASSERT(LdrEntry->LoadCount == 0);
387  LdrEntry->LoadCount = 1;
388 
389  /* Unload it and return true */
390  MmUnloadSystemImage(LdrEntry);
391  return TRUE;
392 }
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:912
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS(NTAPI * PMM_DLL_UNLOAD)(VOID)
Definition: iotypes.h:2499
#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 471 of file sysldr.c.

472 {
473  PAGED_CODE();
474 
475  /* Check if there's no imports or we're a boot driver or only one entry */
476  if ((LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) ||
477  (LdrEntry->LoadedImports == MM_SYSLDR_NO_IMPORTS) ||
478  ((ULONG_PTR)LdrEntry->LoadedImports & MM_SYSLDR_SINGLE_ENTRY))
479  {
480  /* Nothing to do */
481  return;
482  }
483 
484  /* Otherwise, free the import list */
485  ExFreePoolWithTag(LdrEntry->LoadedImports, TAG_LDR_IMPORTS);
486  LdrEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
487 }
#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 396 of file sysldr.c.

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

2604 {
2605  ULONG_PTR ImageBase;
2606  PIMAGE_NT_HEADERS NtHeaders;
2607  ULONG Sections, Alignment, Size;
2608  PIMAGE_SECTION_HEADER Section;
2609  PMMPTE PointerPte = NULL, LastPte = NULL;
2610  if (MmDisablePagingExecutive) return;
2611 
2612  /* Get the driver base address and its NT header */
2613  ImageBase = (ULONG_PTR)LdrEntry->DllBase;
2614  NtHeaders = RtlImageNtHeader((PVOID)ImageBase);
2615  if (!NtHeaders) return;
2616 
2617  /* Get the sections and their alignment */
2618  Sections = NtHeaders->FileHeader.NumberOfSections;
2619  Alignment = NtHeaders->OptionalHeader.SectionAlignment - 1;
2620 
2621  /* Loop each section */
2622  Section = IMAGE_FIRST_SECTION(NtHeaders);
2623  while (Sections)
2624  {
2625  /* Find PAGE or .edata */
2626  if ((*(PULONG)Section->Name == 'EGAP') ||
2627  (*(PULONG)Section->Name == 'ade.'))
2628  {
2629  /* Had we already done some work? */
2630  if (!PointerPte)
2631  {
2632  /* Nope, setup the first PTE address */
2633  PointerPte = MiAddressToPte(ROUND_TO_PAGES(ImageBase +
2634  Section->VirtualAddress));
2635  }
2636 
2637  /* Compute the size */
2638  Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2639 
2640  /* Find the last PTE that maps this section */
2641  LastPte = MiAddressToPte(ImageBase +
2642  Section->VirtualAddress +
2643  Alignment + Size - PAGE_SIZE);
2644  }
2645  else
2646  {
2647  /* Had we found a section before? */
2648  if (PointerPte)
2649  {
2650  /* Mark it as pageable */
2651  MiSetPagingOfDriver(PointerPte, LastPte);
2652  PointerPte = NULL;
2653  }
2654  }
2655 
2656  /* Keep searching */
2657  Sections--;
2658  Section++;
2659  }
2660 
2661  /* Handle the straggler */
2662  if (PointerPte) MiSetPagingOfDriver(PointerPte, LastPte);
2663 }
#define max(a, b)
Definition: svc.c:63
VOID NTAPI MiSetPagingOfDriver(IN PMMPTE PointerPte, IN PMMPTE LastPte)
Definition: sysldr.c:2548
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 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
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
UCHAR MmDisablePagingExecutive
Definition: mminit.c:27
union _IMAGE_SECTION_HEADER::@1528 Misc

Referenced by MmLoadSystemImage().

◆ MiFindExportedRoutineByName()

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

Definition at line 491 of file sysldr.c.

493 {
494  PULONG NameTable;
495  PUSHORT OrdinalTable;
496  PIMAGE_EXPORT_DIRECTORY ExportDirectory;
497  LONG Low = 0, Mid = 0, High, Ret;
498  USHORT Ordinal;
499  PVOID Function;
500  ULONG ExportSize;
501  PULONG ExportTable;
502  PAGED_CODE();
503 
504  /* Get the export directory */
505  ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
506  TRUE,
508  &ExportSize);
509  if (!ExportDirectory) return NULL;
510 
511  /* Setup name tables */
512  NameTable = (PULONG)((ULONG_PTR)DllBase +
513  ExportDirectory->AddressOfNames);
514  OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
515  ExportDirectory->AddressOfNameOrdinals);
516 
517  /* Do a binary search */
518  High = ExportDirectory->NumberOfNames - 1;
519  while (High >= Low)
520  {
521  /* Get new middle value */
522  Mid = (Low + High) >> 1;
523 
524  /* Compare name */
525  Ret = strcmp(ExportName->Buffer, (PCHAR)DllBase + NameTable[Mid]);
526  if (Ret < 0)
527  {
528  /* Update high */
529  High = Mid - 1;
530  }
531  else if (Ret > 0)
532  {
533  /* Update low */
534  Low = Mid + 1;
535  }
536  else
537  {
538  /* We got it */
539  break;
540  }
541  }
542 
543  /* Check if we couldn't find it */
544  if (High < Low) return NULL;
545 
546  /* Otherwise, this is the ordinal */
547  Ordinal = OrdinalTable[Mid];
548 
549  /* Validate the ordinal */
550  if (Ordinal >= ExportDirectory->NumberOfFunctions) return NULL;
551 
552  /* Resolve the address and write it */
553  ExportTable = (PULONG)((ULONG_PTR)DllBase +
554  ExportDirectory->AddressOfFunctions);
555  Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
556 
557  /* We found it! */
558  ASSERT((Function < (PVOID)ExportDirectory) ||
559  (Function > (PVOID)((ULONG_PTR)ExportDirectory + ExportSize)));
560 
561  return Function;
562 }
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 1451 of file sysldr.c.

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

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiFreeInitializationCode()

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

Definition at line 1428 of file sysldr.c.

1430 {
1431  PMMPTE PointerPte;
1432  PFN_NUMBER PagesFreed;
1433 
1434  /* Get the start PTE */
1435  PointerPte = MiAddressToPte(InitStart);
1436  ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE);
1437 
1438  /* Compute the number of pages we expect to free */
1439  PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte);
1440 
1441  /* Try to actually free them */
1442  PagesFreed = MiDeleteSystemPageableVm(PointerPte,
1443  PagesFreed,
1444  0,
1445  NULL);
1446 }
#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 2197 of file sysldr.c.

2198 {
2199  PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
2200  PLIST_ENTRY ListHead, NextEntry;
2201  ULONG EntrySize;
2202 
2203  /* Setup the loaded module list and locks */
2207 
2208  /* Get loop variables and the kernel entry */
2209  ListHead = &LoaderBlock->LoadOrderListHead;
2210  NextEntry = ListHead->Flink;
2211  LdrEntry = CONTAINING_RECORD(NextEntry,
2213  InLoadOrderLinks);
2214  PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
2215 
2216  /* Locate resource section, pool code, and system pte code */
2217  MiLocateKernelSections(LdrEntry);
2218 
2219  /* Loop the loader block */
2220  while (NextEntry != ListHead)
2221  {
2222  /* Get the loader entry */
2223  LdrEntry = CONTAINING_RECORD(NextEntry,
2225  InLoadOrderLinks);
2226 
2227  /* FIXME: ROS HACK. Make sure this is a driver */
2228  if (!RtlImageNtHeader(LdrEntry->DllBase))
2229  {
2230  /* Skip this entry */
2231  NextEntry = NextEntry->Flink;
2232  continue;
2233  }
2234 
2235  /* Calculate the size we'll need and allocate a copy */
2236  EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
2237  LdrEntry->BaseDllName.MaximumLength +
2238  sizeof(UNICODE_NULL);
2240  if (!NewEntry) return FALSE;
2241 
2242  /* Copy the entry over */
2243  *NewEntry = *LdrEntry;
2244 
2245  /* Allocate the name */
2246  NewEntry->FullDllName.Buffer =
2248  LdrEntry->FullDllName.MaximumLength +
2249  sizeof(UNICODE_NULL),
2250  TAG_LDR_WSTR);
2251  if (!NewEntry->FullDllName.Buffer)
2252  {
2254  return FALSE;
2255  }
2256 
2257  /* Set the base name */
2258  NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
2259 
2260  /* Copy the full and base name */
2261  RtlCopyMemory(NewEntry->FullDllName.Buffer,
2262  LdrEntry->FullDllName.Buffer,
2263  LdrEntry->FullDllName.MaximumLength);
2264  RtlCopyMemory(NewEntry->BaseDllName.Buffer,
2265  LdrEntry->BaseDllName.Buffer,
2266  LdrEntry->BaseDllName.MaximumLength);
2267 
2268  /* Null-terminate the base name */
2269  NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
2270  sizeof(WCHAR)] = UNICODE_NULL;
2271 
2272  /* Insert the entry into the list */
2274  NextEntry = NextEntry->Flink;
2275  }
2276 
2277  /* Build the import lists for the boot drivers */
2279 
2280  /* We're done */
2281  return TRUE;
2282 }
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:1784
#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:1875
Definition: btrfs_drv.h:1780
Definition: typedefs.h:117
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
INIT_FUNCTION VOID NTAPI MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2140
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1786
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#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:2343
#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
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
union _MMPTE::@2236 u
#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:4502
_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:3053
#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:76
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:1492
#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 2140 of file sysldr.c.

2141 {
2142  ULONG_PTR DllBase;
2143  PIMAGE_NT_HEADERS NtHeaders;
2144  PIMAGE_SECTION_HEADER SectionHeader;
2145  ULONG Sections, Size;
2146 
2147  /* Get the kernel section header */
2148  DllBase = (ULONG_PTR)LdrEntry->DllBase;
2149  NtHeaders = RtlImageNtHeader((PVOID)DllBase);
2150  SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
2151 
2152  /* Loop all the sections */
2153  for (Sections = NtHeaders->FileHeader.NumberOfSections;
2154  Sections > 0; --Sections, ++SectionHeader)
2155  {
2156  /* Grab the size of the section */
2157  Size = max(SectionHeader->SizeOfRawData, SectionHeader->Misc.VirtualSize);
2158 
2159  /* Check for .RSRC section */
2160  if (*(PULONG)SectionHeader->Name == 'rsr.')
2161  {
2162  /* Remember the PTEs so we can modify them later */
2164  SectionHeader->VirtualAddress);
2166  SectionHeader->VirtualAddress + Size));
2167  }
2168  else if (*(PULONG)SectionHeader->Name == 'LOOP')
2169  {
2170  /* POOLCODE vs. POOLMI */
2171  if (*(PULONG)&SectionHeader->Name[4] == 'EDOC')
2172  {
2173  /* Found Ex* Pool code */
2174  ExPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2176  }
2177  else if (*(PUSHORT)&SectionHeader->Name[4] == 'MI')
2178  {
2179  /* Found Mm* Pool code */
2180  MmPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2182  }
2183  }
2184  else if ((*(PULONG)SectionHeader->Name == 'YSIM') &&
2185  (*(PULONG)&SectionHeader->Name[4] == 'ETPS'))
2186  {
2187  /* Found MISYSPTE (Mm System PTE code) */
2188  MmPteCodeStart = DllBase + SectionHeader->VirtualAddress;
2190  }
2191  }
2192 }
#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
ULONG_PTR ExPoolCodeEnd
Definition: sysldr.c:50
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
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
union _IMAGE_SECTION_HEADER::@1528 Misc
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 3330 of file sysldr.c.

3331 {
3332  PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL;
3333  PLIST_ENTRY NextEntry;
3334  PAGED_CODE();
3335 
3336  /* Loop entries */
3337  NextEntry = PsLoadedModuleList.Flink;
3338  do
3339  {
3340  /* Get the loader entry */
3341  LdrEntry = CONTAINING_RECORD(NextEntry,
3343  InLoadOrderLinks);
3344 
3345  /* Check if the address matches */
3346  if ((Address >= LdrEntry->DllBase) &&
3347  (Address < (PVOID)((ULONG_PTR)LdrEntry->DllBase +
3348  LdrEntry->SizeOfImage)))
3349  {
3350  /* Found a match */
3351  FoundEntry = LdrEntry;
3352  break;
3353  }
3354 
3355  /* Move on */
3356  NextEntry = NextEntry->Flink;
3357  } while(NextEntry != &PsLoadedModuleList);
3358 
3359  /* Return the entry */
3360  return FoundEntry;
3361 }
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
ULONG SizeOfImage
Definition: ldrtypes.h:143
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
PVOID DllBase
Definition: btrfs_drv.h:1784
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:1780
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 566 of file sysldr.c.

568 {
569  KIRQL OldIrql;
570 
571  /* Acquire module list lock */
574 
575  /* Acquire the spinlock too as we will insert or remove the entry */
577 
578  /* Insert or remove from the list */
579  if (Insert)
580  InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks);
581  else
582  RemoveEntryList(&LdrEntry->InLoadOrderLinks);
583 
584  /* Release locks */
588 }
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 1686 of file sysldr.c.

1687 {
1688  PLIST_ENTRY NextEntry;
1689  ULONG i = 0;
1690  PIMAGE_NT_HEADERS NtHeader;
1691  PLDR_DATA_TABLE_ENTRY LdrEntry;
1692  PIMAGE_FILE_HEADER FileHeader;
1693  BOOLEAN ValidRelocs;
1694  PIMAGE_DATA_DIRECTORY DataDirectory;
1695  PVOID DllBase, NewImageAddress;
1696  NTSTATUS Status;
1697  PMMPTE PointerPte, StartPte, LastPte;
1698  PFN_COUNT PteCount;
1699  PMMPFN Pfn1;
1700  MMPTE TempPte, OldPte;
1701 
1702  /* Loop driver list */
1703  for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
1704  NextEntry != &LoaderBlock->LoadOrderListHead;
1705  NextEntry = NextEntry->Flink)
1706  {
1707  /* Get the loader entry and NT header */
1708  LdrEntry = CONTAINING_RECORD(NextEntry,
1710  InLoadOrderLinks);
1711  NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
1712 
1713  /* Debug info */
1714  DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",
1715  LdrEntry->DllBase,
1716  (ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage,
1717  &LdrEntry->FullDllName);
1718 
1719  /* Get the first PTE and the number of PTEs we'll need */
1720  PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
1721  PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
1722  LastPte = StartPte + PteCount;
1723 
1724 #if MI_TRACE_PFNS
1725  /* Loop the PTEs */
1726  while (PointerPte < LastPte)
1727  {
1728  ULONG len;
1729  ASSERT(PointerPte->u.Hard.Valid == 1);
1730  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1731  len = wcslen(LdrEntry->BaseDllName.Buffer) * sizeof(WCHAR);
1732  snprintf(Pfn1->ProcessName, min(16, len), "%S", LdrEntry->BaseDllName.Buffer);
1733  PointerPte++;
1734  }
1735 #endif
1736  /* Skip kernel and HAL */
1737  /* ROS HACK: Skip BOOTVID/KDCOM too */
1738  i++;
1739  if (i <= 4) continue;
1740 
1741  /* Skip non-drivers */
1742  if (!NtHeader) continue;
1743 
1744  /* Get the file header and make sure we can relocate */
1745  FileHeader = &NtHeader->FileHeader;
1746  if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;
1747  if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <
1749 
1750  /* Everything made sense until now, check the relocation section too */
1751  DataDirectory = &NtHeader->OptionalHeader.
1752  DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
1753  if (!DataDirectory->VirtualAddress)
1754  {
1755  /* We don't really have relocations */
1756  ValidRelocs = FALSE;
1757  }
1758  else
1759  {
1760  /* Make sure the size is valid */
1761  if ((DataDirectory->VirtualAddress + DataDirectory->Size) >
1762  LdrEntry->SizeOfImage)
1763  {
1764  /* They're not, skip */
1765  continue;
1766  }
1767 
1768  /* We have relocations */
1769  ValidRelocs = TRUE;
1770  }
1771 
1772  /* Remember the original address */
1773  DllBase = LdrEntry->DllBase;
1774 
1775  /* Loop the PTEs */
1776  PointerPte = StartPte;
1777  while (PointerPte < LastPte)
1778  {
1779  /* Mark the page modified in the PFN database */
1780  ASSERT(PointerPte->u.Hard.Valid == 1);
1781  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1782  ASSERT(Pfn1->u3.e1.Rom == 0);
1783  Pfn1->u3.e1.Modified = TRUE;
1784 
1785  /* Next */
1786  PointerPte++;
1787  }
1788 
1789  /* Now reserve system PTEs for the image */
1790  PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
1791  if (!PointerPte)
1792  {
1793  /* Shouldn't happen */
1794  ERROR_FATAL("[Mm0]: Couldn't allocate driver section!\n");
1795  return;
1796  }
1797 
1798  /* This is the new virtual address for the module */
1799  LastPte = PointerPte + PteCount;
1800  NewImageAddress = MiPteToAddress(PointerPte);
1801 
1802  /* Sanity check */
1803  DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);
1805 
1806  /* Loop the new driver PTEs */
1808  while (PointerPte < LastPte)
1809  {
1810  /* Copy the old data */
1811  OldPte = *StartPte;
1812  ASSERT(OldPte.u.Hard.Valid == 1);
1813 
1814  /* Set page number from the loader's memory */
1815  TempPte.u.Hard.PageFrameNumber = OldPte.u.Hard.PageFrameNumber;
1816 
1817  /* Write it */
1818  MI_WRITE_VALID_PTE(PointerPte, TempPte);
1819 
1820  /* Move on */
1821  PointerPte++;
1822  StartPte++;
1823  }
1824 
1825  /* Update position */
1826  PointerPte -= PteCount;
1827 
1828  /* Sanity check */
1829  ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);
1830 
1831  /* Set the image base to the address where the loader put it */
1832  NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
1833 
1834  /* Check if we had relocations */
1835  if (ValidRelocs)
1836  {
1837  /* Relocate the image */
1838  Status = LdrRelocateImageWithBias(NewImageAddress,
1839  0,
1840  "SYSLDR",
1844  if (!NT_SUCCESS(Status))
1845  {
1846  /* This shouldn't happen */
1847  ERROR_FATAL("Relocations failed!\n");
1848  return;
1849  }
1850  }
1851 
1852  /* Update the loader entry */
1853  LdrEntry->DllBase = NewImageAddress;
1854 
1855  /* Update the thunks */
1856  DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);
1857  MiUpdateThunks(LoaderBlock,
1858  DllBase,
1859  NewImageAddress,
1860  LdrEntry->SizeOfImage);
1861 
1862  /* Update the loader entry */
1863  LdrEntry->Flags |= LDRP_SYSTEM_MAPPED;
1864  LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +
1866  LdrEntry->SizeOfImage = PteCount << PAGE_SHIFT;
1867 
1868  /* FIXME: We'll need to fixup the PFN linkage when switching to ARM3 */
1869  }
1870 }
#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:143
#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:593
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:1784
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
union _MMPTE::@2236 u
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:76
MMPTE ValidKernelPte
Definition: init.c:31
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: mm.h:305
Definition: btrfs_drv.h:1780
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:1786
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
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
union _MMPFN::@1730 u3
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
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:247
return STATUS_SUCCESS
Definition: btrfs.c:2966
#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:54

Referenced by MmArmInitSystem().

◆ MiResolveImageReferences()

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

Definition at line 1001 of file sysldr.c.

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

2550 {
2551  PVOID ImageBase;
2552  PETHREAD CurrentThread = PsGetCurrentThread();
2553  PFN_COUNT PageCount = 0;
2554  PFN_NUMBER PageFrameIndex;
2555  PMMPFN Pfn1;
2556  PAGED_CODE();
2557 
2558  /* The page fault handler is broken and doesn't page back in! */
2559  DPRINT1("WARNING: MiSetPagingOfDriver() called, but paging is broken! ignoring!\n");
2560  return;
2561 
2562  /* Get the driver's base address */
2563  ImageBase = MiPteToAddress(PointerPte);
2564  ASSERT(MI_IS_SESSION_IMAGE_ADDRESS(ImageBase) == FALSE);
2565 
2566  /* If this is a large page, it's stuck in physical memory */
2567  if (MI_IS_PHYSICAL_ADDRESS(ImageBase)) return;
2568 
2569  /* Lock the working set */
2570  MiLockWorkingSet(CurrentThread, &MmSystemCacheWs);
2571 
2572  /* Loop the PTEs */
2573  while (PointerPte <= LastPte)
2574  {
2575  /* Check for valid PTE */
2576  if (PointerPte->u.Hard.Valid == 1)
2577  {
2578  PageFrameIndex = PFN_FROM_PTE(PointerPte);
2579  Pfn1 = MiGetPfnEntry(PageFrameIndex);
2580  ASSERT(Pfn1->u2.ShareCount == 1);
2581 
2582  /* No working sets in ReactOS yet */
2583  PageCount++;
2584  }
2585 
2586  ImageBase = (PVOID)((ULONG_PTR)ImageBase + PAGE_SIZE);
2587  PointerPte++;
2588  }
2589 
2590  /* Release the working set */
2591  MiUnlockWorkingSet(CurrentThread, &MmSystemCacheWs);
2592 
2593  /* Do we have any driver pages? */
2594  if (PageCount)
2595  {
2596  /* Update counters */
2598  }
2599 }
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ULONG PFN_COUNT
Definition: mmtypes.h:102
PFN_NUMBER MmTotalSystemDriverPages
Definition: sysldr.c:41
union _MMPFN::@1729 u2
#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
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 2397 of file sysldr.c.

2401 {
2402  PMMPTE PointerPte;
2403  MMPTE TempPte;
2404 
2405  /* Loop the PTEs */
2406  for (PointerPte = FirstPte; PointerPte <= LastPte; PointerPte++)
2407  {
2408  /* Read the PTE */
2409  TempPte = *PointerPte;
2410 
2411  /* Make sure it's valid */
2412  ASSERT(TempPte.u.Hard.Valid == 1);
2413 
2414  /* Update the protection */
2415  TempPte.u.Hard.Write = BooleanFlagOn(Protection, IMAGE_SCN_MEM_WRITE);
2416 #if _MI_HAS_NO_EXECUTE
2417  TempPte.u.Hard.NoExecute = !BooleanFlagOn(Protection, IMAGE_SCN_MEM_EXECUTE);
2418 #endif
2419 
2420  MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2421  }
2422 
2423  /* Flush it all */
2425 
2426  return;
2427 }
#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:76
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 692 of file sysldr.c.

700 {
701  BOOLEAN IsOrdinal;
702  USHORT Ordinal;
703  PULONG NameTable;
704  PUSHORT OrdinalTable;
705  PIMAGE_IMPORT_BY_NAME NameImport;
706  USHORT Hint;
707  ULONG Low = 0, Mid = 0, High;
708  LONG Ret;
710  PCHAR MissingForwarder;
711  CHAR NameBuffer[MAXIMUM_FILENAME_LENGTH];
712  PULONG ExportTable;
713  ANSI_STRING DllName;
714  UNICODE_STRING ForwarderName;
715  PLIST_ENTRY NextEntry;
716  PLDR_DATA_TABLE_ENTRY LdrEntry;
717  ULONG ForwardExportSize;
718  PIMAGE_EXPORT_DIRECTORY ForwardExportDirectory;
719  PIMAGE_IMPORT_BY_NAME ForwardName;
720  SIZE_T ForwardLength;
721  IMAGE_THUNK_DATA ForwardThunk;
722  PAGED_CODE();
723 
724  /* Check if this is an ordinal */
725  IsOrdinal = IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal);
726  if ((IsOrdinal) && !(SnapForwarder))
727  {
728  /* Get the ordinal number and set it as missing */
729  Ordinal = (USHORT)(IMAGE_ORDINAL(Name->u1.Ordinal) -
730  ExportDirectory->Base);
731  *MissingApi = (PCHAR)(ULONG_PTR)Ordinal;
732  }
733  else
734  {
735  /* Get the VA if we don't have to snap */
736  if (!SnapForwarder) Name->u1.AddressOfData += (ULONG_PTR)ImageBase;
737  NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData;
738 
739  /* Copy the procedure name */
740  RtlStringCbCopyA(*MissingApi,
742  (PCHAR)&NameImport->Name[0]);
743 
744  /* Setup name tables */
745  DPRINT("Import name: %s\n", NameImport->Name);
746  NameTable = (PULONG)((ULONG_PTR)DllBase +
747  ExportDirectory->AddressOfNames);
748  OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
749  ExportDirectory->AddressOfNameOrdinals);
750 
751  /* Get the hint and check if it's valid */
752  Hint = NameImport->Hint;
753  if ((Hint < ExportDirectory->NumberOfNames) &&
754  !(strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))
755  {
756  /* We have a match, get the ordinal number from here */
757  Ordinal = OrdinalTable[Hint];
758  }
759  else
760  {
761  /* Do a binary search */
762  High = ExportDirectory->NumberOfNames - 1;
763  while (High >= Low)
764  {
765  /* Get new middle value */
766  Mid = (Low + High) >> 1;
767 
768  /* Compare name */
769  Ret = strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Mid]);
770  if (Ret < 0)
771  {
772  /* Update high */
773  High = Mid - 1;
774  }
775  else if (Ret > 0)
776  {
777  /* Update low */
778  Low = Mid + 1;
779  }
780  else
781  {
782  /* We got it */
783  break;
784  }
785  }
786 
787  /* Check if we couldn't find it */
788  if (High < Low)
789  {
790  DPRINT1("Warning: Driver failed to load, %s not found\n", NameImport->Name);
792  }
793 
794  /* Otherwise, this is the ordinal */
795  Ordinal = OrdinalTable[Mid];
796  }
797  }
798 
799  /* Check if the ordinal is invalid */
800  if (Ordinal >= ExportDirectory->NumberOfFunctions)
801  {
802  /* Fail */
804  }
805  else
806  {
807  /* In case the forwarder is missing */
808  MissingForwarder = NameBuffer;
809 
810  /* Resolve the address and write it */
811  ExportTable = (PULONG)((ULONG_PTR)DllBase +
812  ExportDirectory->AddressOfFunctions);
813  Address->u1.Function = (ULONG_PTR)DllBase + ExportTable[Ordinal];
814 
815  /* Assume success from now on */
817 
818  /* Check if the function is actually a forwarder */
819  if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&
820  (Address->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
821  {
822  /* Now assume failure in case the forwarder doesn't exist */
824 
825  /* Build the forwarder name */
826  DllName.Buffer = (PCHAR)Address->u1.Function;
827  DllName.Length = (USHORT)(strchr(DllName.Buffer, '.') -
828  DllName.Buffer) +
829  sizeof(ANSI_NULL);
830  DllName.MaximumLength = DllName.Length;
831 
832  /* Convert it */
833  if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ForwarderName,
834  &DllName,
835  TRUE)))
836  {
837  /* We failed, just return an error */
838  return Status;
839  }
840 
841  /* Loop the module list */
842  NextEntry = PsLoadedModuleList.Flink;
843  while (NextEntry != &PsLoadedModuleList)
844  {
845  /* Get the loader entry */
846  LdrEntry = CONTAINING_RECORD(NextEntry,
848  InLoadOrderLinks);
849 
850  /* Check if it matches */
851  if (RtlPrefixUnicodeString(&ForwarderName,
852  &LdrEntry->BaseDllName,
853  TRUE))
854  {
855  /* Get the forwarder export directory */
856  ForwardExportDirectory =
858  TRUE,
860  &ForwardExportSize);
861  if (!ForwardExportDirectory) break;
862 
863  /* Allocate a name entry */
864  ForwardLength = strlen(DllName.Buffer + DllName.Length) +
865  sizeof(ANSI_NULL);
866  ForwardName = ExAllocatePoolWithTag(PagedPool,
867  sizeof(*ForwardName) +
868  ForwardLength,
869  TAG_LDR_WSTR);
870  if (!ForwardName) break;
871 
872  /* Copy the data */
873  RtlCopyMemory(&ForwardName->Name[0],
874  DllName.Buffer + DllName.Length,
875  ForwardLength);
876  ForwardName->Hint = 0;
877 
878  /* Set the new address */
879  ForwardThunk.u1.AddressOfData = (ULONG_PTR)ForwardName;
880 
881  /* Snap the forwarder */
882  Status = MiSnapThunk(LdrEntry->DllBase,
883  ImageBase,
884  &ForwardThunk,
885  &ForwardThunk,
886  ForwardExportDirectory,
887  ForwardExportSize,
888  TRUE,
889  &MissingForwarder);
890 
891  /* Free the forwarder name and set the thunk */
892  ExFreePoolWithTag(ForwardName, TAG_LDR_WSTR);
893  Address->u1 = ForwardThunk.u1;
894  break;
895  }
896 
897  /* Go to the next entry */
898  NextEntry = NextEntry->Flink;
899  }
900 
901  /* Free the name */
902  RtlFreeUnicodeString(&ForwarderName);
903  }
904  }
905 
906  /* Return status */
907  return Status;
908 }
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:156
PVOID DllBase
Definition: btrfs_drv.h:1784
#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
union _IMAGE_THUNK_DATA32::@2055 u1
#define RtlImageDirectoryEntryToData
Definition: compat.h:460
Definition: btrfs_drv.h:1780
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)
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
unsigned int * PULONG
Definition: retypes.h:1
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define ULONG_PTR
Definition: config.h:101
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
return STATUS_SUCCESS
Definition: btrfs.c:2966
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:692

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

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

2344 {
2345  PLIST_ENTRY NextEntry;
2346  BOOLEAN DriverFound = FALSE;
2347  PMI_LARGE_PAGE_DRIVER_ENTRY LargePageDriverEntry;
2349  ASSERT(*ImageBaseAddress >= MmSystemRangeStart);
2350 
2351 #ifdef _X86_
2352  if (!(KeFeatureBits & KF_LARGE_PAGE)) return FALSE;
2353  if (!(__readcr4() & CR4_PSE)) return FALSE;
2354 #endif
2355 
2356  /* Make sure there's enough system PTEs for a large page driver */
2358  {
2359  return FALSE;
2360  }
2361 
2362  /* This happens if the registry key had a "*" (wildcard) in it */
2363  if (MiLargePageAllDrivers == 0)
2364  {
2365  /* It didn't, so scan the list */
2366  NextEntry = MiLargePageDriverList.Flink;
2367  while (NextEntry != &MiLargePageDriverList)
2368  {
2369  /* Check if the driver name matches */
2370  LargePageDriverEntry = CONTAINING_RECORD(NextEntry,
2372  Links);
2373  if (RtlEqualUnicodeString(BaseImageName,
2374  &LargePageDriverEntry->BaseName,
2375  TRUE))
2376  {
2377  /* Enable large pages for this driver */
2378  DriverFound = TRUE;
2379  break;
2380  }
2381 
2382  /* Keep trying */
2383  NextEntry = NextEntry->Flink;
2384  }
2385 
2386  /* If we didn't find the driver, it doesn't need large pages */
2387  if (DriverFound == FALSE) return FALSE;
2388  }
2389 
2390  /* Nothing to do yet */
2391  DPRINT1("Large pages not supported!\n");
2392  return FALSE;
2393 }
#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 2431 of file sysldr.c.

2433 {
2434  PIMAGE_NT_HEADERS NtHeaders;
2435  PIMAGE_SECTION_HEADER SectionHeaders, Section;
2436  ULONG i;
2437  PVOID SectionBase, SectionEnd;
2438  ULONG SectionSize;
2439  ULONG Protection;
2440  PMMPTE FirstPte, LastPte;
2441 
2442  /* Check if the registry setting is on or not */
2444  {
2445  /* Ignore section protection */
2446  return;
2447  }
2448 
2449  /* Large page mapped images are not supported */
2450  NT_ASSERT(!MI_IS_PHYSICAL_ADDRESS(ImageBase));
2451 
2452  /* Session images are not yet supported */
2453  NT_ASSERT(!MI_IS_SESSION_ADDRESS(ImageBase));
2454 
2455  /* Get the NT headers */
2456  NtHeaders = RtlImageNtHeader(ImageBase);
2457  if (NtHeaders == NULL)
2458  {
2459  DPRINT1("Failed to get NT headers for image @ %p\n", ImageBase);
2460  return;
2461  }
2462 
2463  /* Don't touch NT4 drivers */
2464  if ((NtHeaders->OptionalHeader.MajorOperatingSystemVersion < 5) ||
2465  (NtHeaders->OptionalHeader.MajorSubsystemVersion < 5))
2466  {
2467  DPRINT1("Skipping NT 4 driver @ %p\n", ImageBase);
2468  return;
2469  }
2470 
2471  /* Get the section headers */
2472  SectionHeaders = IMAGE_FIRST_SECTION(NtHeaders);
2473 
2474  /* Get the base address of the first section */
2475  SectionBase = Add2Ptr(ImageBase, SectionHeaders[0].VirtualAddress);
2476 
2477  /* Start protecting the image header as R/O */
2478  FirstPte = MiAddressToPte(ImageBase);
2479  LastPte = MiAddressToPte(SectionBase) - 1;
2480  Protection = IMAGE_SCN_MEM_READ;
2481  if (LastPte >= FirstPte)
2482  {
2483  MiSetSystemCodeProtection(FirstPte, LastPte, IMAGE_SCN_MEM_READ);
2484  }
2485 
2486  /* Loop the sections */
2487  for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
2488  {
2489  /* Get the section base address and size */
2490  Section = &SectionHeaders[i];
2491  SectionBase = Add2Ptr(ImageBase, Section->VirtualAddress);
2492  SectionSize = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2493 
2494  /* Get the first PTE of this section */
2495  FirstPte = MiAddressToPte(SectionBase);
2496 
2497  /* Check for overlap with the previous range */
2498  if (FirstPte == LastPte)
2499  {
2500  /* Combine the old and new protection by ORing them */
2501  Protection |= (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2502 
2503  /* Update the protection for this PTE */
2504  MiSetSystemCodeProtection(FirstPte, FirstPte, Protection);
2505 
2506  /* Skip this PTE */
2507  FirstPte++;
2508  }
2509 
2510  /* There can not be gaps! */
2511  NT_ASSERT(FirstPte == (LastPte + 1));
2512 
2513  /* Get the end of the section and the last PTE */
2514  SectionEnd = Add2Ptr(SectionBase, SectionSize - 1);
2515  NT_ASSERT(SectionEnd < Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage));
2516  LastPte = MiAddressToPte(SectionEnd);
2517 
2518  /* If there are no more pages (after an overlap), skip this section */
2519  if (LastPte < FirstPte)
2520  {
2521  NT_ASSERT(FirstPte == (LastPte + 1));
2522  continue;
2523  }
2524 
2525  /* Get the section protection */
2526  Protection = (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2527 
2528  /* Update the protection for this section */
2529  MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2530  }
2531 
2532  /* Image should end with the last section */
2533  if (ALIGN_UP_POINTER_BY(SectionEnd, PAGE_SIZE) !=
2534  Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage))
2535  {
2536  DPRINT1("ImageBase 0x%p ImageSize 0x%lx Section %u VA 0x%lx Raw 0x%lx virt 0x%lx\n",
2537  ImageBase,
2538  NtHeaders->OptionalHeader.SizeOfImage,
2539  i,
2540  Section->VirtualAddress,
2541  Section->SizeOfRawData,
2542  Section->Misc.VirtualSize);
2543  }
2544 }
#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:2397
#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
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:937
union _IMAGE_SECTION_HEADER::@1528 Misc
#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  /*
324  * Do a temporary copy of BaseDllName called ImportName
325  * because we'll alter the length of the string.
326  */
327  ImportName.Length = LdrEntry->BaseDllName.Length;
328  ImportName.MaximumLength = LdrEntry->BaseDllName.MaximumLength;
329  ImportName.Buffer = LdrEntry->BaseDllName.Buffer;
330 
331  /* Obtain the path to this dll's service in the registry */
332  RegPath.MaximumLength = ServicesKeyName.Length +
333  ImportName.Length + sizeof(UNICODE_NULL);
335  RegPath.MaximumLength,
336  TAG_LDR_WSTR);
337 
338  /* Check if this allocation was unsuccessful */
339  if (!RegPath.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
340 
341  /* Build and append the service name itself */
342  RegPath.Length = ServicesKeyName.Length;
343  RtlCopyMemory(RegPath.Buffer,
344  ServicesKeyName.Buffer,
345  ServicesKeyName.Length);
346 
347  /* Check if there is a dot in the filename */
348  if (wcschr(ImportName.Buffer, L'.'))
349  {
350  /* Remove the extension */
351  ImportName.Length = (USHORT)(wcschr(ImportName.Buffer, L'.') -
352  ImportName.Buffer) * sizeof(WCHAR);
353  }
354 
355  /* Append service name (the basename without extension) */
356  RtlAppendUnicodeStringToString(&RegPath, &ImportName);
357 
358  /* Now call the DllInit func */
359  DPRINT("Calling DllInit(%wZ)\n", &RegPath);
360  Status = DllInit(&RegPath);
361 
362  /* Clean up */
364 
365  /* Return status value which DllInitialize returned */
366  return Status;
367 }
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:2495
_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:2966
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by IopInitializeBootDrivers(), and MiResolveImageReferences().

◆ MmChangeKernelResourceSectionProtection()

BOOLEAN NTAPI MmChangeKernelResourceSectionProtection ( IN ULONG_PTR  ProtectionMask)

Definition at line 2286 of file sysldr.c.

2287 {
2288  PMMPTE PointerPte;
2289  MMPTE TempPte;
2290 
2291  /* Don't do anything if the resource section is already writable */
2293  return FALSE;
2294 
2295  /* If the resource section is physical, we cannot change its protection */
2297  return FALSE;
2298 
2299  /* Loop the PTEs */
2300  for (PointerPte = MiKernelResourceStartPte; PointerPte < MiKernelResourceEndPte; ++PointerPte)
2301  {
2302  /* Read the PTE */
2303  TempPte = *PointerPte;
2304 
2305  /* Update the protection */
2306  MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, ProtectionMask, TempPte.u.Hard.PageFrameNumber);
2307  MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2308  }
2309 
2310  /* Only flush the current processor's TLB */
2311  KeFlushCurrentTb();
2312  return TRUE;
2313 }
#define TRUE
Definition: types.h:120
PMMPTE MiKernelResourceEndPte
Definition: sysldr.c:49
smooth NULL
Definition: ftsmooth.c:416
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:198
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:783
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:937
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:965
PMMPTE MiKernelResourceStartPte
Definition: sysldr.c:49
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:322
ULONG PageFrameNumber
Definition: mmtypes.h:109

Referenced by DisplayBootBitmap(), and MmMakeKernelResourceSectionWritable().

◆ MmCheckSystemImage()

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

Definition at line 2691 of file sysldr.c.

2693 {
2694  NTSTATUS Status;
2695  HANDLE SectionHandle;
2696  PVOID ViewBase = NULL;
2697  SIZE_T ViewSize = 0;
2699  FILE_STANDARD_INFORMATION FileStandardInfo;
2701  PIMAGE_NT_HEADERS NtHeaders;
2703  PAGED_CODE();
2704 
2705  /* Setup the object attributes */
2707  NULL,
2709  NULL,
2710  NULL);
2711 
2712  /* Create a section for the DLL */
2713  Status = ZwCreateSection(&SectionHandle,
2716  NULL,
2717  PAGE_EXECUTE,
2718  SEC_IMAGE,
2719  ImageHandle);
2720  if (!NT_SUCCESS(Status))
2721  {
2722  DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2723  return Status;
2724  }
2725 
2726  /* Make sure we're in the system process */
2728 
2729  /* Map it */
2730  Status = ZwMapViewOfSection(SectionHandle,
2731  NtCurrentProcess(),
2732  &ViewBase,
2733  0,
2734  0,
2735  NULL,
2736  &ViewSize,
2737  ViewShare,
2738  0,
2739  PAGE_EXECUTE);
2740  if (!NT_SUCCESS(Status))
2741  {
2742  /* We failed, close the handle and return */
2743  DPRINT1("ZwMapViewOfSection failed with status 0x%x\n", Status);
2745  ZwClose(SectionHandle);
2746  return Status;
2747  }
2748 
2749  /* Now query image information */
2750  Status = ZwQueryInformationFile(ImageHandle,
2751  &IoStatusBlock,
2752  &FileStandardInfo,
2753  sizeof(FileStandardInfo),
2755  if (NT_SUCCESS(Status))
2756  {
2757  /* First, verify the checksum */
2759  ViewSize,
2760  FileStandardInfo.
2761  EndOfFile.LowPart))
2762  {
2763  /* Set checksum failure */
2765  goto Fail;
2766  }
2767 
2768  /* Make sure it's a real image */
2769  NtHeaders = RtlImageNtHeader(ViewBase);
2770  if (!NtHeaders)
2771  {
2772  /* Set checksum failure */
2774  goto Fail;
2775  }
2776 
2777  /* Make sure it's for the correct architecture */
2778  if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
2780  {
2781  /* Set protection failure */
2783  goto Fail;
2784  }
2785 
2786  /* Check that it's a valid SMP image if we have more then one CPU */
2787  if (!MmVerifyImageIsOkForMpUse(ViewBase))
2788  {
2789  /* Otherwise it's not the right image */
2791  }
2792  }
2793 
2794  /* Unmap the section, close the handle, and return status */
2795 Fail:
2796  ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
2798  ZwClose(SectionHandle);
2799  return Status;
2800 }
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:2667
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:1492
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 1628 of file sysldr.c.

1629 {
1630  PMMPTE StartPte, EndPte;
1631  PFN_NUMBER PageCount;
1632  PVOID DllBase;
1633  ULONG i;
1634  PIMAGE_NT_HEADERS NtHeader;
1635  PIMAGE_SECTION_HEADER Section, DiscardSection;
1636 
1637  /* Get the base address and the page count */
1638  DllBase = LdrEntry->DllBase;
1639  PageCount = LdrEntry->SizeOfImage >> PAGE_SHIFT;
1640 
1641  /* Get the last PTE in this image */
1642  EndPte = MiAddressToPte(DllBase) + PageCount;
1643 
1644  /* Get the NT header */
1645  NtHeader = RtlImageNtHeader(DllBase);
1646  if (!NtHeader) return;
1647 
1648  /* Get the last section and loop each section backwards */
1649  Section = IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections;
1650  DiscardSection = NULL;
1651  for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
1652  {
1653  /* Go back a section and check if it's discardable */
1654  Section--;
1656  {
1657  /* It is, select it for freeing */
1658  DiscardSection = Section;
1659  }
1660  else
1661  {
1662  /* No more discardable sections exist, bail out */
1663  break;
1664  }
1665  }
1666 
1667  /* Bail out if there's nothing to free */
1668  if (!DiscardSection) return;
1669 
1670  /* Push the DLL base to the first disacrable section, and get its PTE */
1671  DllBase = (PVOID)ROUND_TO_PAGES((ULONG_PTR)DllBase + DiscardSection->VirtualAddress);
1672  ASSERT(MI_IS_PHYSICAL_ADDRESS(DllBase) == FALSE);
1673  StartPte = MiAddressToPte(DllBase);
1674 
1675  /* Check how many pages to free total */
1676  PageCount = (PFN_NUMBER)(EndPte - StartPte);
1677  if (!PageCount) return;
1678 
1679  /* Delete this many PTEs */
1680  MiDeleteSystemPageableVm(StartPte, PageCount, 0, NULL);
1681 }
#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 3417 of file sysldr.c.

3418 {
3419  PVOID ProcAddress = NULL;
3420  ANSI_STRING AnsiRoutineName;
3421  NTSTATUS Status;
3422  PLIST_ENTRY NextEntry;
3423  PLDR_DATA_TABLE_ENTRY LdrEntry;
3424  BOOLEAN Found = FALSE;
3425  UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
3427  ULONG Modules = 0;
3428 
3429  /* Convert routine to ansi name */
3430  Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName,
3431  SystemRoutineName,
3432  TRUE);
3433  if (!NT_SUCCESS(Status)) return NULL;
3434 
3435  /* Lock the list */
3438 
3439  /* Loop the loaded module list */
3440  NextEntry = PsLoadedModuleList.Flink;
3441  while (NextEntry != &PsLoadedModuleList)
3442  {
3443  /* Get the entry */
3444  LdrEntry = CONTAINING_RECORD(NextEntry,
3446  InLoadOrderLinks);
3447 
3448  /* Check if it's the kernel or HAL */
3449  if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
3450  {
3451  /* Found it */
3452  Found = TRUE;
3453  Modules++;
3454  }
3455  else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
3456  {
3457  /* Found it */
3458  Found = TRUE;
3459  Modules++;
3460  }
3461 
3462  /* Check if we found a valid binary */
3463  if (Found)
3464  {
3465  /* Find the procedure name */
3466  ProcAddress = MiFindExportedRoutineByName(LdrEntry->DllBase,
3467  &AnsiRoutineName);
3468 
3469  /* Break out if we found it or if we already tried both modules */
3470  if (ProcAddress) break;
3471  if (Modules == 2) break;
3472  }
3473 
3474  /* Keep looping */
3475  NextEntry = NextEntry->Flink;
3476  }
3477 
3478  /* Release the lock */
3481 
3482  /* Free the string and return */
3483  RtlFreeAnsiString(&AnsiRoutineName);
3484  return ProcAddress;
3485 }
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:1784
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:1780
Definition: typedefs.h:117
Status
Definition: gdiplustypes.h:24
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
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:491
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 2804 of file sysldr.c.

2810 {
2811  PVOID ModuleLoadBase = NULL;
2812  NTSTATUS Status;
2816  PIMAGE_NT_HEADERS NtHeader;
2817  UNICODE_STRING BaseName, BaseDirectory, PrefixName, UnicodeTemp;
2818  PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
2819  ULONG EntrySize, DriverSize;
2820  PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
2821  PCHAR MissingApiName, Buffer;
2822  PWCHAR MissingDriverName;
2823  HANDLE SectionHandle;
2825  PVOID Section = NULL;
2826  BOOLEAN LockOwned = FALSE;
2827  PLIST_ENTRY NextEntry;
2828  IMAGE_INFO ImageInfo;
2829  STRING AnsiTemp;
2830  PAGED_CODE();
2831 
2832  /* Detect session-load */
2833  if (Flags)
2834  {
2835  /* Sanity checks */
2836  ASSERT(NamePrefix == NULL);
2837  ASSERT(LoadedName == NULL);
2838 
2839  /* Make sure the process is in session too */
2840  if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;
2841  }
2842 
2843  /* Allocate a buffer we'll use for names */
2846  TAG_LDR_WSTR);
2848 
2849  /* Check for a separator */
2850  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2851  {
2852  PWCHAR p;
2853  ULONG BaseLength;
2854 
2855  /* Loop the path until we get to the base name */
2856  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
2857  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
2858 
2859  /* Get the length */
2860  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
2861  BaseLength *= sizeof(WCHAR);
2862 
2863  /* Setup the string */
2864  BaseName.Length = (USHORT)BaseLength;
2865  BaseName.Buffer = p;
2866  }
2867  else
2868  {
2869  /* Otherwise, we already have a base name */
2870  BaseName.Length = FileName->Length;
2871  BaseName.Buffer = FileName->Buffer;
2872  }
2873 
2874  /* Setup the maximum length */
2875  BaseName.MaximumLength = BaseName.Length;
2876 
2877  /* Now compute the base directory */
2878  BaseDirectory = *FileName;
2879  BaseDirectory.Length -= BaseName.Length;
2880  BaseDirectory.MaximumLength = BaseDirectory.Length;
2881 
2882  /* And the prefix, which for now is just the name itself */
2883  PrefixName = *FileName;
2884 
2885  /* Check if we have a prefix */
2886  if (NamePrefix) DPRINT1("Prefixed images are not yet supported!\n");
2887 
2888  /* Check if we already have a name, use it instead */
2889  if (LoadedName) BaseName = *LoadedName;
2890 
2891  /* Check for loader snap debugging */
2893  {
2894  /* Print out standard string */
2895  DPRINT1("MM:SYSLDR Loading %wZ (%wZ) %s\n",
2896  &PrefixName, &BaseName, Flags ? "in session space" : "");
2897  }
2898 
2899  /* Acquire the load lock */
2900 LoaderScan:
2901  ASSERT(LockOwned == FALSE);
2902  LockOwned = TRUE;
2906  KernelMode,
2907  FALSE,
2908  NULL);
2909 
2910  /* Scan the module list */
2911  NextEntry = PsLoadedModuleList.Flink;
2912  while (NextEntry != &PsLoadedModuleList)
2913  {
2914  /* Get the entry and compare the names */
2915  LdrEntry = CONTAINING_RECORD(NextEntry,
2917  InLoadOrderLinks);
2918  if (RtlEqualUnicodeString(&PrefixName, &LdrEntry->FullDllName, TRUE))
2919  {
2920  /* Found it, break out */
2921  break;
2922  }
2923 
2924  /* Keep scanning */
2925  NextEntry = NextEntry->Flink;
2926  }
2927 
2928  /* Check if we found the image */
2929  if (NextEntry != &PsLoadedModuleList)
2930  {
2931  /* Check if we had already mapped a section */
2932  if (Section)
2933  {
2934  /* Dereference and clear */
2935  ObDereferenceObject(Section);
2936  Section = NULL;
2937  }
2938 
2939  /* Check if this was supposed to be a session load */
2940  if (!Flags)
2941  {
2942  /* It wasn't, so just return the data */
2943  *ModuleObject = LdrEntry;
2944  *ImageBaseAddress = LdrEntry->DllBase;
2946  }
2947  else
2948  {
2949  /* We don't support session loading yet */
2950  UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
2952  }
2953 
2954  /* Do cleanup */
2955  goto Quickie;
2956  }
2957  else if (!Section)
2958  {
2959  /* It wasn't loaded, and we didn't have a previous attempt */
2962  LockOwned = FALSE;
2963 
2964  /* Check if KD is enabled */
2966  {
2967  /* FIXME: Attempt to get image from KD */
2968  }
2969 
2970  /* We don't have a valid entry */
2971  LdrEntry = NULL;
2972 
2973  /* Setup image attributes */
2975  FileName,
2977  NULL,
2978  NULL);
2979 
2980  /* Open the image */
2982  FILE_EXECUTE,
2984  &IoStatusBlock,
2986  0);
2987  if (!NT_SUCCESS(Status))
2988  {
2989  DPRINT1("ZwOpenFile failed for '%wZ' with status 0x%x\n",
2990  FileName, Status);
2991  goto Quickie;
2992  }
2993 
2994  /* Validate it */
2999  {
3000  /* Fail loading */
3001  goto Quickie;
3002  }
3003 
3004  /* Check if this is a session-load */
3005  if (Flags)
3006  {
3007  /* Then we only need read and execute */
3009  }
3010  else
3011  {
3012  /* Otherwise, we can allow write access */
3014  }
3015 
3016  /* Initialize the attributes for the section */
3018  NULL,
3020  NULL,
3021  NULL);
3022 
3023  /* Create the section */
3024  Status = ZwCreateSection(&SectionHandle,
3025  DesiredAccess,
3027  NULL,
3028  PAGE_EXECUTE,
3029  SEC_IMAGE,
3030  FileHandle);
3031  if (!NT_SUCCESS(Status))
3032  {
3033  DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
3034  goto Quickie;
3035  }
3036 
3037  /* Now get the section pointer */
3038  Status = ObReferenceObjectByHandle(SectionHandle,
3041  KernelMode,
3042  &Section,
3043  NULL);
3044  ZwClose(SectionHandle);
3045  if (!NT_SUCCESS(Status)) goto Quickie;
3046 
3047  /* Check if this was supposed to be a session-load */
3048  if (Flags)
3049  {
3050  /* We don't support session loading yet */
3051  UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3052  goto Quickie;
3053  }
3054 
3055  /* Check the loader list again, we should end up in the path below */
3056  goto LoaderScan;
3057  }
3058  else
3059  {
3060  /* We don't have a valid entry */
3061  LdrEntry = NULL;
3062  }
3063 
3064  /* Load the image */
3065  Status = MiLoadImageSection(&Section,
3066  &ModuleLoadBase,
3067  FileName,
3068  FALSE,
3069  NULL);
3071 
3072  /* Get the size of the driver */
3073  DriverSize = ((PROS_SECTION_OBJECT)Section)->ImageSection->ImageInformation.ImageFileSize;
3074 
3075  /* Make sure we're not being loaded into session space */
3076  if (!Flags)
3077  {
3078  /* Check for success */
3079  if (NT_SUCCESS(Status))
3080  {
3081  /* Support large pages for drivers */
3082  MiUseLargeDriverPage(DriverSize / PAGE_SIZE,
3083  &ModuleLoadBase,
3084  &BaseName,
3085  TRUE);
3086  }
3087 
3088  /* Dereference the section */
3089  ObDereferenceObject(Section);
3090  Section = NULL;
3091  }
3092 
3093  /* Check for failure of the load earlier */
3094  if (!NT_SUCCESS(Status))
3095  {
3096  DPRINT1("MiLoadImageSection failed with status 0x%x\n", Status);
3097  goto Quickie;
3098  }
3099 
3100  /* Relocate the driver */
3101  Status = LdrRelocateImageWithBias(ModuleLoadBase,
3102  0,
3103  "SYSLDR",
3107  if (!NT_SUCCESS(Status))
3108  {
3109  DPRINT1("LdrRelocateImageWithBias failed with status 0x%x\n", Status);
3110  goto Quickie;
3111  }
3112 
3113  /* Get the NT Header */
3114  NtHeader = RtlImageNtHeader(ModuleLoadBase);
3115 
3116  /* Calculate the size we'll need for the entry and allocate it */
3117  EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
3118  BaseName.Length +
3119  sizeof(UNICODE_NULL);
3120 
3121  /* Allocate the entry */
3123  if (!LdrEntry)
3124  {
3125  /* Fail */
3127  goto Quickie;
3128  }
3129 
3130  /* Setup the entry */
3131  LdrEntry->Flags = LDRP_LOAD_IN_PROGRESS;
3132  LdrEntry->LoadCount = 1;
3133  LdrEntry->LoadedImports = LoadedImports;
3134  LdrEntry->PatchInformation = NULL;
3135 
3136  /* Check the version */
3137  if ((NtHeader->OptionalHeader.MajorOperatingSystemVersion >= 5) &&
3138  (NtHeader->OptionalHeader.MajorImageVersion >= 5))
3139  {
3140  /* Mark this image as a native image */
3141  LdrEntry->Flags |= LDRP_ENTRY_NATIVE;
3142  }
3143 
3144  /* Setup the rest of the entry */
3145  LdrEntry->DllBase = ModuleLoadBase;
3146  LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase +
3148  LdrEntry->SizeOfImage = DriverSize;
3149  LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;
3150  LdrEntry->SectionPointer = Section;
3151 
3152  /* Now write the DLL name */
3153  LdrEntry->BaseDllName.Buffer = (PVOID)(LdrEntry + 1);
3154  LdrEntry->BaseDllName.Length = BaseName.Length;
3155  LdrEntry->BaseDllName.MaximumLength = BaseName.Length;
3156 
3157  /* Copy and null-terminate it */
3158  RtlCopyMemory(LdrEntry->BaseDllName.Buffer,
3159  BaseName.Buffer,
3160  BaseName.Length);
3161  LdrEntry->BaseDllName.Buffer[BaseName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3162 
3163  /* Now allocate the full name */
3165  PrefixName.Length +
3166  sizeof(UNICODE_NULL),
3167  TAG_LDR_WSTR);
3168  if (!LdrEntry->FullDllName.Buffer)
3169  {
3170  /* Don't fail, just set it to zero */
3171  LdrEntry->FullDllName.Length = 0;
3172  LdrEntry->FullDllName.MaximumLength = 0;
3173  }
3174  else
3175  {
3176  /* Set it up */
3177  LdrEntry->FullDllName.Length = PrefixName.Length;
3178  LdrEntry->FullDllName.MaximumLength = PrefixName.Length;
3179 
3180  /* Copy and null-terminate */
3181  RtlCopyMemory(LdrEntry->FullDllName.Buffer,
3182  PrefixName.Buffer,
3183  PrefixName.Length);
3184  LdrEntry->FullDllName.Buffer[PrefixName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3185  }
3186 
3187  /* Add the entry */
3188  MiProcessLoaderEntry(LdrEntry, TRUE);
3189 
3190  /* Resolve imports */
3191  MissingApiName = Buffer;
3192  MissingDriverName = NULL;
3193  Status = MiResolveImageReferences(ModuleLoadBase,
3194  &BaseDirectory,
3195  NULL,
3196  &MissingApiName,
3197  &MissingDriverName,
3198  &LoadedImports);
3199  if (!NT_SUCCESS(Status))
3200  {
3201  BOOLEAN NeedToFreeString = FALSE;
3202 
3203  /* If the lowest bit is set to 1, this is a hint that we need to free */
3204  if (*(ULONG_PTR*)&MissingDriverName & 1)
3205  {
3206  NeedToFreeString = TRUE;
3207  *(ULONG_PTR*)&MissingDriverName &= ~1;
3208  }
3209 
3210  DPRINT1("MiResolveImageReferences failed with status 0x%x\n", Status);
3211  DPRINT1(" Missing driver '%ls', missing API '%s'\n",
3212  MissingDriverName, MissingApiName);
3213 
3214  if (NeedToFreeString)
3215  {</