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@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@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 */