Author: ion
Date: Mon Nov 13 01:34:28 2006
New Revision: 24732
URL:
http://svn.reactos.org/svn/reactos?rev=24732&view=rev
Log:
- Implement MmAddVerifierThunks, MmIsDriverVerifying, MmIsVerifierEnabled.
- Not used by anything, these are for 3rd-party drivers and Driver Verifier.
Modified:
trunk/reactos/ntoskrnl/mm/verifier.c
Modified: trunk/reactos/ntoskrnl/mm/verifier.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/verifier.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/verifier.c (original)
+++ trunk/reactos/ntoskrnl/mm/verifier.c Mon Nov 13 01:34:28 2006
@@ -1,63 +1,190 @@
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/mm/verifier.c
- * PURPOSE: Driver Verifier functions
- *
- * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net)
- */
+/*
+* PROJECT: ReactOS Kernel
+* LICENSE: GPL - See COPYING in the top level directory
+* FILE: ntoskrnl/mm/verifier.c
+* PURPOSE: Mm Driver Verifier Routines
+* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+*/
-/* INCLUDES *****************************************************************/
+/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
+#define NDEBUG
#include <internal/debug.h>
+/* GLOBALS *******************************************************************/
-/* FUNCTIONS *****************************************************************/
+MM_DRIVER_VERIFIER_DATA MmVerifierData;
+LIST_ENTRY MiVerifierDriverAddedThunkListHead;
+KMUTANT MmSystemLoadLock;
+ULONG MiActiveVerifierThunks;
+extern LIST_ENTRY ModuleListHead;
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+PLDR_DATA_TABLE_ENTRY
+NTAPI
+MiLookupDataTableEntry(IN PVOID Address)
+{
+ PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL;
+ 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
*/
NTSTATUS
-STDCALL
-MmAddVerifierThunks (
- IN PVOID ThunkBuffer,
- IN ULONG ThunkBufferSize
- )
+NTAPI
+MmAddVerifierThunks(IN PVOID ThunkBuffer,
+ IN ULONG ThunkBufferSize)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PDRIVER_VERIFIER_THUNK_PAIRS ThunkPairs, DriverThunkTable;
+ 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;
+}
/*
- * @unimplemented
- */
-
-ULONG
-STDCALL
-MmIsDriverVerifying (
- IN struct _DRIVER_OBJECT *DriverObject
- )
-{
- UNIMPLEMENTED;
- return 0;
-}
-
-
-/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
-STDCALL
-MmIsVerifierEnabled (
- OUT PULONG VerifierFlags
- )
+NTAPI
+MmIsVerifierEnabled(OUT PULONG VerifierFlags)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ /* 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 */