mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 11:31:40 +00:00
- Implement MmAddVerifierThunks, MmIsDriverVerifying, MmIsVerifierEnabled.
- Not used by anything, these are for 3rd-party drivers and Driver Verifier. svn path=/trunk/; revision=24732
This commit is contained in:
parent
00418f00bf
commit
29a0679654
1 changed files with 171 additions and 44 deletions
|
@ -1,63 +1,190 @@
|
||||||
/* $Id$
|
/*
|
||||||
*
|
* PROJECT: ReactOS Kernel
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* FILE: ntoskrnl/mm/verifier.c
|
||||||
* FILE: ntoskrnl/mm/verifier.c
|
* PURPOSE: Mm Driver Verifier Routines
|
||||||
* PURPOSE: Driver Verifier functions
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
*
|
*/
|
||||||
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <ntoskrnl.h>
|
#include <ntoskrnl.h>
|
||||||
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
MM_DRIVER_VERIFIER_DATA MmVerifierData;
|
||||||
|
LIST_ENTRY MiVerifierDriverAddedThunkListHead;
|
||||||
|
KMUTANT MmSystemLoadLock;
|
||||||
|
ULONG MiActiveVerifierThunks;
|
||||||
|
|
||||||
|
extern LIST_ENTRY ModuleListHead;
|
||||||
|
|
||||||
/*
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
* @unimplemented
|
|
||||||
*/
|
PLDR_DATA_TABLE_ENTRY
|
||||||
NTSTATUS
|
NTAPI
|
||||||
STDCALL
|
MiLookupDataTableEntry(IN PVOID Address)
|
||||||
MmAddVerifierThunks (
|
|
||||||
IN PVOID ThunkBuffer,
|
|
||||||
IN ULONG ThunkBufferSize
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
PLIST_ENTRY NextEntry;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Loop entries */
|
||||||
|
NextEntry = ModuleListHead.Flink;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Get the loader entry */
|
||||||
|
LdrEntry = CONTAINING_RECORD(NextEntry,
|
||||||
|
LDR_DATA_TABLE_ENTRY,
|
||||||
|
InLoadOrderLinks);
|
||||||
|
|
||||||
|
/* Check if the address matches */
|
||||||
|
if ((Address >= LdrEntry->DllBase) &&
|
||||||
|
(Address < (PVOID)((ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage)))
|
||||||
|
{
|
||||||
|
/* Found a match */
|
||||||
|
FoundEntry = LdrEntry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move on */
|
||||||
|
NextEntry = NextEntry->Flink;
|
||||||
|
} while(NextEntry != &ModuleListHead);
|
||||||
|
|
||||||
|
/* Return the entry */
|
||||||
|
return FoundEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
|
||||||
|
|
||||||
ULONG
|
|
||||||
STDCALL
|
|
||||||
MmIsDriverVerifying (
|
|
||||||
IN struct _DRIVER_OBJECT *DriverObject
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @unimplemented
|
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
NTAPI
|
||||||
MmIsVerifierEnabled (
|
MmAddVerifierThunks(IN PVOID ThunkBuffer,
|
||||||
OUT PULONG VerifierFlags
|
IN ULONG ThunkBufferSize)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PDRIVER_VERIFIER_THUNK_PAIRS ThunkPairs, DriverThunkTable;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
ULONG ThunkCount;
|
||||||
|
PDRIVER_SPECIFIED_VERIFIER_THUNKS ThunkTable;
|
||||||
|
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||||
|
PVOID ModuleBase, ModuleEnd;
|
||||||
|
ULONG i;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Make sure the driver verifier is initialized */
|
||||||
|
if (!MiVerifierDriverAddedThunkListHead.Flink) return STATUS_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
/* Get the thunk pairs and count them */
|
||||||
|
ThunkPairs = (PDRIVER_VERIFIER_THUNK_PAIRS)ThunkBuffer;
|
||||||
|
ThunkCount = ThunkBufferSize / sizeof(DRIVER_VERIFIER_THUNK_PAIRS);
|
||||||
|
if (!ThunkCount) return STATUS_INVALID_PARAMETER_1;
|
||||||
|
|
||||||
|
/* Now allocate our own thunk table */
|
||||||
|
ThunkTable = ExAllocatePoolWithTag(PagedPool,
|
||||||
|
sizeof(DRIVER_SPECIFIED_VERIFIER_THUNKS) +
|
||||||
|
ThunkCount *
|
||||||
|
sizeof(DRIVER_VERIFIER_THUNK_PAIRS),
|
||||||
|
TAG('M', 'm', 'V', 't'));
|
||||||
|
if (!ThunkTable) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Now copy the driver-fed part */
|
||||||
|
DriverThunkTable = (PDRIVER_VERIFIER_THUNK_PAIRS)(ThunkTable + 1);
|
||||||
|
RtlCopyMemory(DriverThunkTable,
|
||||||
|
ThunkPairs,
|
||||||
|
ThunkCount * sizeof(DRIVER_VERIFIER_THUNK_PAIRS));
|
||||||
|
|
||||||
|
/* Acquire the system load lock */
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
KeWaitForSingleObject(&MmSystemLoadLock,
|
||||||
|
WrVirtualMemory,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Get the loader entry */
|
||||||
|
LdrEntry = MiLookupDataTableEntry(DriverThunkTable->PristineRoutine);
|
||||||
|
if (!LdrEntry)
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
|
Status = STATUS_INVALID_PARAMETER_2;
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get driver base and end */
|
||||||
|
ModuleBase = LdrEntry->DllBase;
|
||||||
|
ModuleEnd = (PVOID)((ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage);
|
||||||
|
|
||||||
|
/* Loop all the thunks */
|
||||||
|
for (i = 0; i < ThunkCount; i++)
|
||||||
|
{
|
||||||
|
/* Make sure it's in the driver */
|
||||||
|
if (((ULONG_PTR)DriverThunkTable->PristineRoutine < (ULONG_PTR)ModuleBase) ||
|
||||||
|
((ULONG_PTR)DriverThunkTable->PristineRoutine >= (ULONG_PTR)ModuleEnd))
|
||||||
|
{
|
||||||
|
/* Nope, fail */
|
||||||
|
Status = STATUS_INVALID_PARAMETER_2;
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, add this entry */
|
||||||
|
ThunkTable->DataTableEntry = LdrEntry;
|
||||||
|
ThunkTable->NumberOfThunks = ThunkCount;
|
||||||
|
MiActiveVerifierThunks++;
|
||||||
|
InsertTailList(&MiVerifierDriverAddedThunkListHead,
|
||||||
|
&ThunkTable->ListEntry);
|
||||||
|
ThunkTable = NULL;
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
/* Release the lock */
|
||||||
|
KeReleaseMutant(&MmSystemLoadLock, 1, FALSE, FALSE);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
|
/* Free the table if we failed and return status */
|
||||||
|
ExFreePool(ThunkTable);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
LOGICAL
|
||||||
|
NTAPI
|
||||||
|
MmIsDriverVerifying(IN PDRIVER_OBJECT DriverObject)
|
||||||
|
{
|
||||||
|
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||||
|
|
||||||
|
/* Get the loader entry */
|
||||||
|
LdrEntry = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection;
|
||||||
|
if (!LdrEntry) return FALSE;
|
||||||
|
|
||||||
|
/* Check if we're verifying or not */
|
||||||
|
return (LdrEntry->Flags & LDRP_DRIVER_VERIFYING) ? TRUE: FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MmIsVerifierEnabled(OUT PULONG VerifierFlags)
|
||||||
|
{
|
||||||
|
/* Check if we've actually added anything to the list */
|
||||||
|
if (MiVerifierDriverAddedThunkListHead.Flink)
|
||||||
|
{
|
||||||
|
/* We have, read the verifier level */
|
||||||
|
*VerifierFlags = MmVerifierData.Level;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, we're disabled */
|
||||||
|
*VerifierFlags = 0;
|
||||||
|
return STATUS_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue