mirror of
https://github.com/reactos/reactos.git
synced 2024-07-11 23:25:09 +00:00
- Move some Mm routines from pe.c to sysldr.c where they belong.
- Create and initialize Mm Loader lock. - Re-arrange some code in MmLoadSystemImage, no code changes yet. - Add new LDRP_ flags for LDR_DATA_TABLE_ENTRY to the NDK. svn path=/trunk/; revision=25881
This commit is contained in:
parent
50b11bc313
commit
e81f8006bb
|
@ -49,8 +49,14 @@ Author:
|
|||
#define LDRP_IMAGE_NOT_AT_BASE 0x00200000
|
||||
#define LDRP_COR_IMAGE 0x00400000
|
||||
#define LDR_COR_OWNS_UNMAP 0x00800000
|
||||
#define LDRP_DRIVER_VERIFYING 0x02000000
|
||||
#define LDRP_SYSTEM_MAPPED 0x01000000
|
||||
#define LDRP_IMAGE_VERIFYING 0x02000000
|
||||
#define LDRP_DRIVER_DEPENDENT_DLL 0x04000000
|
||||
#define LDRP_ENTRY_NATIVE 0x08800000
|
||||
#define LDRP_REDIRECTED 0x10000000
|
||||
#define LDRP_NON_PAGED_DEBUG_INFO 0x20000000
|
||||
#define LDRP_MM_LOADED 0x40000000
|
||||
#define LDRP_COMPAT_DATABASE_PROCESSED 0x80000000
|
||||
|
||||
//
|
||||
// Dll Characteristics for LdrLoadDll
|
||||
|
|
|
@ -201,11 +201,71 @@ MmLoadSystemImage(IN PUNICODE_STRING FileName,
|
|||
PLOAD_IMPORTS LoadedImports = (PVOID)-2;
|
||||
PCHAR MissingApiName, Buffer;
|
||||
PWCHAR MissingDriverName;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Detect session-load */
|
||||
if (Flags)
|
||||
{
|
||||
/* Sanity checks */
|
||||
ASSERT(NamePrefix == NULL);
|
||||
ASSERT(LoadedName == NULL);
|
||||
|
||||
/* Make sure the process is in session too */
|
||||
if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (ModuleObject) *ModuleObject = NULL;
|
||||
if (ImageBaseAddress) *ImageBaseAddress = NULL;
|
||||
|
||||
DPRINT("Loading Module %wZ...\n", FileName);
|
||||
/* Allocate a buffer we'll use for names */
|
||||
Buffer = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH, TAG_LDR_WSTR);
|
||||
if (!Buffer)
|
||||
{
|
||||
/* Fail */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Check for a separator */
|
||||
if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
|
||||
{
|
||||
PWCHAR p;
|
||||
ULONG BaseLength;
|
||||
|
||||
/* Loop the path until we get to the base name */
|
||||
p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
|
||||
while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
|
||||
|
||||
/* Get the length */
|
||||
BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
|
||||
BaseLength *= sizeof(WCHAR);
|
||||
|
||||
/* Setup the string */
|
||||
BaseName.Length = (USHORT)BaseLength;
|
||||
BaseName.Buffer = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, we already have a base name */
|
||||
BaseName.Length = FileName->Length;
|
||||
BaseName.Buffer = FileName->Buffer;
|
||||
}
|
||||
|
||||
/* Setup the maximum length */
|
||||
BaseName.MaximumLength = BaseName.Length;
|
||||
|
||||
/* Now compute the base directory */
|
||||
BaseDirectory = *FileName;
|
||||
BaseDirectory.Length -= BaseName.Length;
|
||||
BaseDirectory.MaximumLength = BaseDirectory.Length;
|
||||
|
||||
/* And the prefix, which for now is just the name itself */
|
||||
PrefixName = *FileName;
|
||||
|
||||
/* Check if we have a prefix */
|
||||
if (NamePrefix) DPRINT1("Prefixed images are not yet supported!\n");
|
||||
|
||||
/* Check if we already have a name, use it instead */
|
||||
if (LoadedName) BaseName = *LoadedName;
|
||||
|
||||
/* Open the Module */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
|
@ -370,50 +430,6 @@ MmLoadSystemImage(IN PUNICODE_STRING FileName,
|
|||
return Status;
|
||||
}
|
||||
|
||||
/* Allocate a buffer we'll use for names */
|
||||
Buffer = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH, TAG_LDR_WSTR);
|
||||
if (!Buffer)
|
||||
{
|
||||
/* Fail */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Check for a separator */
|
||||
if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
|
||||
{
|
||||
PWCHAR p;
|
||||
ULONG BaseLength;
|
||||
|
||||
/* Loop the path until we get to the base name */
|
||||
p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
|
||||
while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
|
||||
|
||||
/* Get the length */
|
||||
BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
|
||||
BaseLength *= sizeof(WCHAR);
|
||||
|
||||
/* Setup the string */
|
||||
BaseName.Length = (USHORT)BaseLength;
|
||||
BaseName.Buffer = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, we already have a base name */
|
||||
BaseName.Length = FileName->Length;
|
||||
BaseName.Buffer = FileName->Buffer;
|
||||
}
|
||||
|
||||
/* Setup the maximum length */
|
||||
BaseName.MaximumLength = BaseName.Length;
|
||||
|
||||
/* Now compute the base directory */
|
||||
BaseDirectory = *FileName;
|
||||
BaseDirectory.Length -= BaseName.Length;
|
||||
BaseDirectory.MaximumLength = BaseDirectory.Length;
|
||||
|
||||
/* And the prefix */
|
||||
PrefixName = *FileName;
|
||||
|
||||
/* Calculate the size we'll need for the entry and allocate it */
|
||||
EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
|
||||
BaseName.Length +
|
||||
|
|
|
@ -453,6 +453,7 @@ MmInit1(ULONG_PTR FirstKrnlPhysAddr,
|
|||
}
|
||||
|
||||
BOOLEAN RmapReady, PageOpReady, SectionsReady, PagingReady;
|
||||
extern KMUTANT MmSystemLoadLock;
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
|
@ -461,6 +462,9 @@ MmInitSystem(IN ULONG Phase,
|
|||
{
|
||||
if (Phase == 0)
|
||||
{
|
||||
/* Initialize the Loader Lock */
|
||||
KeInitializeMutant(&MmSystemLoadLock, FALSE);
|
||||
|
||||
/* Reload boot drivers */
|
||||
MiReloadBootLoadedDrivers(LoaderBlock);
|
||||
|
||||
|
|
|
@ -677,108 +677,4 @@ l_Return:
|
|||
return nStatus;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Get NT Headers */
|
||||
NtHeader = RtlImageNtHeader(BaseAddress);
|
||||
if (NtHeader)
|
||||
{
|
||||
/* Check if this image is only safe for UP while we have 2+ CPUs */
|
||||
if ((KeNumberProcessors > 1) &&
|
||||
(NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY))
|
||||
{
|
||||
/* Fail */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, it's safe */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCheckSystemImage(IN HANDLE ImageHandle,
|
||||
IN BOOLEAN PurgeSection)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE SectionHandle;
|
||||
PVOID ViewBase = NULL;
|
||||
SIZE_T ViewSize = 0;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
FILE_STANDARD_INFORMATION FileStandardInfo;
|
||||
KAPC_STATE ApcState;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Create a section for the DLL */
|
||||
Status = ZwCreateSection(&SectionHandle,
|
||||
SECTION_MAP_EXECUTE,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_EXECUTE,
|
||||
SEC_COMMIT,
|
||||
ImageHandle);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Make sure we're in the system process */
|
||||
KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState);
|
||||
|
||||
/* Map it */
|
||||
Status = ZwMapViewOfSection(SectionHandle,
|
||||
NtCurrentProcess(),
|
||||
&ViewBase,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
&ViewSize,
|
||||
ViewShare,
|
||||
0,
|
||||
PAGE_EXECUTE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* We failed, close the handle and return */
|
||||
KeUnstackDetachProcess(&ApcState);
|
||||
ZwClose(SectionHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Now query image information */
|
||||
Status = ZwQueryInformationFile(ImageHandle,
|
||||
&IoStatusBlock,
|
||||
&FileStandardInfo,
|
||||
sizeof(FileStandardInfo),
|
||||
FileStandardInformation);
|
||||
if ( NT_SUCCESS(Status) )
|
||||
{
|
||||
/* First, verify the checksum */
|
||||
if (!LdrVerifyMappedImageMatchesChecksum(ViewBase,
|
||||
FileStandardInfo.
|
||||
EndOfFile.LowPart,
|
||||
FileStandardInfo.
|
||||
EndOfFile.LowPart))
|
||||
{
|
||||
/* Set checksum failure */
|
||||
Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
|
||||
}
|
||||
|
||||
/* Check that it's a valid SMP image if we have more then one CPU */
|
||||
if (!MmVerifyImageIsOkForMpUse(ViewBase))
|
||||
{
|
||||
/* Otherwise it's not the right image */
|
||||
Status = STATUS_IMAGE_MP_UP_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unmap the section, close the handle, and return status */
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
|
||||
KeUnstackDetachProcess(&ApcState);
|
||||
ZwClose(SectionHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
LIST_ENTRY PsLoadedModuleList;
|
||||
KSPIN_LOCK PsLoadedModuleSpinLock;
|
||||
PVOID PsNtosImageBase;
|
||||
KMUTANT MmSystemLoadLock;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
@ -914,3 +915,107 @@ MiInitializeLoadedModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
/* We're done */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Get NT Headers */
|
||||
NtHeader = RtlImageNtHeader(BaseAddress);
|
||||
if (NtHeader)
|
||||
{
|
||||
/* Check if this image is only safe for UP while we have 2+ CPUs */
|
||||
if ((KeNumberProcessors > 1) &&
|
||||
(NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY))
|
||||
{
|
||||
/* Fail */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, it's safe */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCheckSystemImage(IN HANDLE ImageHandle,
|
||||
IN BOOLEAN PurgeSection)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE SectionHandle;
|
||||
PVOID ViewBase = NULL;
|
||||
SIZE_T ViewSize = 0;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
FILE_STANDARD_INFORMATION FileStandardInfo;
|
||||
KAPC_STATE ApcState;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Create a section for the DLL */
|
||||
Status = ZwCreateSection(&SectionHandle,
|
||||
SECTION_MAP_EXECUTE,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_EXECUTE,
|
||||
SEC_COMMIT,
|
||||
ImageHandle);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Make sure we're in the system process */
|
||||
KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState);
|
||||
|
||||
/* Map it */
|
||||
Status = ZwMapViewOfSection(SectionHandle,
|
||||
NtCurrentProcess(),
|
||||
&ViewBase,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
&ViewSize,
|
||||
ViewShare,
|
||||
0,
|
||||
PAGE_EXECUTE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* We failed, close the handle and return */
|
||||
KeUnstackDetachProcess(&ApcState);
|
||||
ZwClose(SectionHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Now query image information */
|
||||
Status = ZwQueryInformationFile(ImageHandle,
|
||||
&IoStatusBlock,
|
||||
&FileStandardInfo,
|
||||
sizeof(FileStandardInfo),
|
||||
FileStandardInformation);
|
||||
if ( NT_SUCCESS(Status) )
|
||||
{
|
||||
/* First, verify the checksum */
|
||||
if (!LdrVerifyMappedImageMatchesChecksum(ViewBase,
|
||||
FileStandardInfo.
|
||||
EndOfFile.LowPart,
|
||||
FileStandardInfo.
|
||||
EndOfFile.LowPart))
|
||||
{
|
||||
/* Set checksum failure */
|
||||
Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
|
||||
}
|
||||
|
||||
/* Check that it's a valid SMP image if we have more then one CPU */
|
||||
if (!MmVerifyImageIsOkForMpUse(ViewBase))
|
||||
{
|
||||
/* Otherwise it's not the right image */
|
||||
Status = STATUS_IMAGE_MP_UP_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unmap the section, close the handle, and return status */
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
|
||||
KeUnstackDetachProcess(&ApcState);
|
||||
ZwClose(SectionHandle);
|
||||
return Status;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue