Author: mbosma Date: Fri Jan 5 23:28:18 2007 New Revision: 25317
URL: http://svn.reactos.org/svn/reactos?rev=25317&view=rev Log: Merge changes from HEAD. It compiles but does not boot yet, because of changes in PS.
Removed: branches/cache_manager_rewrite/mm/i386/memsafe.s branches/cache_manager_rewrite/mm/i386/pfault.c Modified: branches/cache_manager_rewrite/Instructions.txt branches/cache_manager_rewrite/cc/cacheman.c branches/cache_manager_rewrite/cc/pin.c branches/cache_manager_rewrite/mm/elf.inc.h branches/cache_manager_rewrite/mm/elf32.c branches/cache_manager_rewrite/mm/freelist.c branches/cache_manager_rewrite/mm/i386/page.c branches/cache_manager_rewrite/mm/iospace.c branches/cache_manager_rewrite/mm/mdl.c branches/cache_manager_rewrite/mm/mm.c branches/cache_manager_rewrite/mm/mminit.c branches/cache_manager_rewrite/mm/pagefile.c branches/cache_manager_rewrite/mm/pe.c branches/cache_manager_rewrite/mm/pool.c branches/cache_manager_rewrite/mm/process.c branches/cache_manager_rewrite/mm/rmap.c branches/cache_manager_rewrite/mm/section.c branches/cache_manager_rewrite/mm/verifier.c branches/cache_manager_rewrite/mm/virtual.c
Modified: branches/cache_manager_rewrite/Instructions.txt URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/Instructio... ============================================================================== --- branches/cache_manager_rewrite/Instructions.txt (original) +++ branches/cache_manager_rewrite/Instructions.txt Fri Jan 5 23:28:18 2007 @@ -1,2 +1,2 @@ To build this branch apply the patch to trunk. And replace ntoskrnl/mm, ntoskrnl/cc with the folders from here. -Please note that the version are very likely to be outdated you might want to use svn merge to keep them up to date. +This branch currently applies against: r25313
Modified: branches/cache_manager_rewrite/cc/cacheman.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/cc/cachema... ============================================================================== --- branches/cache_manager_rewrite/cc/cacheman.c (original) +++ branches/cache_manager_rewrite/cc/cacheman.c Fri Jan 5 23:28:18 2007 @@ -17,7 +17,7 @@ /* FUNCTIONS *****************************************************************/
VOID NTAPI -CcInit (VOID) +CcInitializeCacheManager (VOID) { CcInitView (); }
Modified: branches/cache_manager_rewrite/cc/pin.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/cc/pin.c?r... ============================================================================== --- branches/cache_manager_rewrite/cc/pin.c (original) +++ branches/cache_manager_rewrite/cc/pin.c Fri Jan 5 23:28:18 2007 @@ -34,7 +34,7 @@ CcMapData (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, - IN BOOLEAN Wait, + IN ULONG Flags, OUT PVOID * piBcb, OUT PVOID * pBuffer) { @@ -55,8 +55,9 @@ ASSERT (piBcb); ASSERT (pBuffer);
- if (!Wait) - { + if (Flags) + { + DPRINT1("No Flags implemented yet."); *piBcb = NULL; *pBuffer = NULL; return FALSE;
Modified: branches/cache_manager_rewrite/mm/elf.inc.h URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/elf.inc... ============================================================================== --- branches/cache_manager_rewrite/mm/elf.inc.h (original) +++ branches/cache_manager_rewrite/mm/elf.inc.h Fri Jan 5 23:28:18 2007 @@ -448,7 +448,6 @@ nReadStatus = ReadFileCb ( File, - ImageSectionObject->BytesPerSector, &lnOffset, cbPHdrSize, &pData,
Modified: branches/cache_manager_rewrite/mm/elf32.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/elf32.c... ============================================================================== --- branches/cache_manager_rewrite/mm/elf32.c (original) +++ branches/cache_manager_rewrite/mm/elf32.c Fri Jan 5 23:28:18 2007 @@ -10,11 +10,6 @@
#define __ELF_WORD_SIZE 32 #include "elf.inc.h" - -#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM little-endian -#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 -#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // Alpha AXP, full 64-bit support -#define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian
extern NTSTATUS NTAPI Elf64FmtCreateSection (
Modified: branches/cache_manager_rewrite/mm/freelist.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/freelis... ============================================================================== --- branches/cache_manager_rewrite/mm/freelist.c (original) +++ branches/cache_manager_rewrite/mm/freelist.c Fri Jan 5 23:28:18 2007 @@ -17,7 +17,6 @@
#if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, MmInitializePageList) -#pragma alloc_text(INIT, MmInitZeroPageThread) #endif
@@ -63,8 +62,6 @@ static LIST_ENTRY FreeUnzeroedPageListHead; static LIST_ENTRY BiosPageListHead;
-static PETHREAD ZeroPageThread; -static CLIENT_ID ZeroPageThreadId; static KEVENT ZeroPageThreadEvent; static BOOLEAN ZeroPageThreadShouldTerminate = FALSE;
@@ -336,6 +333,7 @@ NTSTATUS Status; PFN_TYPE LastPage; PFN_TYPE FirstUninitializedPage; + ULONG PdeStart = PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart;
DPRINT("MmInitializePageList(FirstPhysKernelAddress %x, " "LastPhysKernelAddress %x, " @@ -456,7 +454,7 @@ MmStats.NrReservedPages++; } /* Protect the Page Directory. This will be changed in r3 */ - else if (j >= (KeLoaderBlock.PageDirectoryStart / PAGE_SIZE) && j < (KeLoaderBlock.PageDirectoryEnd / PAGE_SIZE)) + else if (j >= (PdeStart / PAGE_SIZE) && j < (MmFreeLdrPageDirectoryEnd / PAGE_SIZE)) { MmPageArray[j].Flags.Type = MM_PHYSICAL_PAGE_BIOS; MmPageArray[j].Flags.Zero = 0; @@ -1216,7 +1214,8 @@ return NumberOfPagesFound; }
-VOID STDCALL +NTSTATUS +NTAPI MmZeroPageThreadMain(PVOID Ignored) { NTSTATUS Status; @@ -1225,6 +1224,13 @@ PPHYSICAL_PAGE PageDescriptor; PFN_TYPE Pfn; ULONG Count; + + /* Free initial kernel memory */ + MiFreeInitMemory(); + + /* Set our priority to 0 */ + KeGetCurrentThread()->BasePriority = 0; + KeSetPriorityThread(KeGetCurrentThread(), 0);
while(1) { @@ -1237,13 +1243,12 @@ { DbgPrint("ZeroPageThread: Wait failed\n"); KEBUGCHECK(0); - return; }
if (ZeroPageThreadShouldTerminate) { DbgPrint("ZeroPageThread: Terminating\n"); - return; + return STATUS_SUCCESS; } Count = 0; KeAcquireSpinLock(&PageListLock, &oldIrql); @@ -1282,42 +1287,7 @@ KeResetEvent(&ZeroPageThreadEvent); KeReleaseSpinLock(&PageListLock, oldIrql); } -} - -NTSTATUS -INIT_FUNCTION -NTAPI -MmInitZeroPageThread(VOID) -{ - NTSTATUS Status; - HANDLE ThreadHandle; - - ZeroPageThreadShouldTerminate = FALSE; - Status = PsCreateSystemThread(&ThreadHandle, - THREAD_ALL_ACCESS, - NULL, - NULL, - &ZeroPageThreadId, - MmZeroPageThreadMain, - NULL); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - - Status = ObReferenceObjectByHandle(ThreadHandle, - THREAD_ALL_ACCESS, - PsThreadType, - KernelMode, - (PVOID*)&ZeroPageThread, - NULL); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - - KeSetPriorityThread(&ZeroPageThread->Tcb, LOW_PRIORITY); - NtClose(ThreadHandle); + return STATUS_SUCCESS; }
Removed: branches/cache_manager_rewrite/mm/i386/memsafe.s URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/i386/me... ============================================================================== --- branches/cache_manager_rewrite/mm/i386/memsafe.s (original) +++ branches/cache_manager_rewrite/mm/i386/memsafe.s (removed) @@ -1,17 +1,0 @@ -.globl @MmSafeReadPtr@4 -.globl _MmSafeReadPtrStart -.globl _MmSafeReadPtrEnd - -/*****************************************************************************/ - - /* - * PVOID FASTCALL MmSafeReadPtr(PVOID Source) - */ -@MmSafeReadPtr@4: -_MmSafeReadPtrStart: - /* - * If we incur a pagefault, eax will be set NULL - */ - movl (%ecx),%eax -_MmSafeReadPtrEnd: - ret
Modified: branches/cache_manager_rewrite/mm/i386/page.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/i386/pa... ============================================================================== --- branches/cache_manager_rewrite/mm/i386/page.c (original) +++ branches/cache_manager_rewrite/mm/i386/page.c Fri Jan 5 23:28:18 2007 @@ -70,7 +70,6 @@
extern BOOLEAN Ke386Pae; extern BOOLEAN Ke386NoExecute; -extern BOOLEAN Ke386GlobalPagesEnabled;
/* FUNCTIONS ***************************************************************/
@@ -86,11 +85,11 @@ } else if (Address == (PVOID)0xfffffffe) { - FLUSH_TLB; - } - else - { - FLUSH_TLB_ONE(Address); + KeFlushCurrentTb(); + } + else + { + __invlpg(Address); } }
@@ -113,7 +112,7 @@ #else if ((Pt && MmUnmapPageTable(Pt)) || Address >= MmSystemRangeStart) { - FLUSH_TLB_ONE(Address); + __invlpg(Address); } #endif } @@ -123,9 +122,7 @@ PULONG MmGetPageDirectory(VOID) { - unsigned int page_dir=0; - Ke386GetPageTableDirectory(page_dir); - return((PULONG)page_dir); + return (PULONG)__readcr3(); }
static ULONG @@ -2223,7 +2220,7 @@ } } Address = (PVOID)((ULONG_PTR)HYPERSPACE + i * PAGE_SIZE); - FLUSH_TLB_ONE(Address); + __invlpg(Address); return Address; }
@@ -2245,7 +2242,7 @@ Entry = InterlockedExchange((PLONG)ADDR_TO_PTE(Address), PFN_TO_PTE(NewPage) | PA_PRESENT | PA_READWRITE); Pfn = PTE_TO_PFN(Entry); } - FLUSH_TLB_ONE(Address); + __invlpg(Address); return Pfn; }
@@ -2267,7 +2264,7 @@ Entry = InterlockedExchange((PLONG)ADDR_TO_PTE(Address), 0); Pfn = PTE_TO_PFN(Entry); } - FLUSH_TLB_ONE(Address); + __invlpg(Address); return Pfn; }
Removed: branches/cache_manager_rewrite/mm/i386/pfault.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/i386/pf... ============================================================================== --- branches/cache_manager_rewrite/mm/i386/pfault.c (original) +++ branches/cache_manager_rewrite/mm/i386/pfault.c (removed) @@ -1,135 +1,0 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/mm/i386/pfault.c - * PURPOSE: Paging file functions - * - * PROGRAMMERS: David Welch (welch@mcmail.com) - */ - -/* INCLUDES *****************************************************************/ - -#include <ntoskrnl.h> -#define NDEBUG -#include <internal/debug.h> - -/* EXTERNS *******************************************************************/ - -extern VOID MmSafeReadPtrStart(VOID); -extern VOID MmSafeReadPtrEnd(VOID); - - -extern BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address); -extern ULONG KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2); - -extern BOOLEAN Ke386NoExecute; - -/* FUNCTIONS *****************************************************************/ - -ULONG KiPageFaultHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr) -{ - ULONG_PTR cr2; - NTSTATUS Status; - KPROCESSOR_MODE Mode; - - ASSERT(ExceptionNr == 14); - - /* Store the exception number in an unused field in the trap frame. */ - Tf->DbgArgMark = 14; - - /* get the faulting address */ - cr2 = Ke386GetCr2(); - Tf->DbgArgPointer = cr2; - - /* it's safe to enable interrupts after cr2 has been saved */ - if (Tf->EFlags & (X86_EFLAGS_VM|X86_EFLAGS_IF)) - { - Ke386EnableInterrupts(); - } - - if (cr2 >= (ULONG_PTR)MmSystemRangeStart) - { - /* check for an invalid page directory in kernel mode */ - if (!(Tf->ErrCode & 0x5) && Mmi386MakeKernelPageTableGlobal((PVOID)cr2)) - { - return 0; - } - - /* check for non executable memory in kernel mode */ - if (Ke386NoExecute && Tf->ErrCode & 0x10) - { - KEBUGCHECKWITHTF(ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY, 0, 0, 0, 0, Tf); - } - } - - Mode = Tf->ErrCode & 0x4 ? UserMode : KernelMode; - - /* handle the fault */ - if (Tf->ErrCode & 0x1) - { - Status = MmAccessFault(Mode, cr2, FALSE); - } - else - { - Status = MmNotPresentFault(Mode, cr2, FALSE); - } - - /* handle the return for v86 mode */ - if (Tf->EFlags & X86_EFLAGS_VM) - { - if (!NT_SUCCESS(Status)) - { - /* FIXME: This should use ->VdmObjects */ - if(!KeGetCurrentProcess()->Unused) - { - *((PKV86M_TRAP_FRAME)Tf)->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; - } - return 1; - } - return 0; - } - - if (Mode == KernelMode) - { - if (!NT_SUCCESS(Status)) - { - if (Tf->Eip >= (ULONG_PTR)MmSafeReadPtrStart && - Tf->Eip < (ULONG_PTR)MmSafeReadPtrEnd) - { - Tf->Eip = (ULONG_PTR)MmSafeReadPtrEnd; - Tf->Eax = 0; - return 0; - } - } - } - else - { - if (KeGetCurrentThread()->ApcState.UserApcPending) - { - KIRQL oldIrql; - - KeRaiseIrql(APC_LEVEL, &oldIrql); - KiDeliverApc(UserMode, NULL, NULL); - KeLowerIrql(oldIrql); - } - } - - if (NT_SUCCESS(Status)) - { - return 0; - } - - /* - * Handle user exceptions differently - */ - if (Mode == KernelMode) - { - return(KiKernelTrapHandler(Tf, 14, (PVOID)cr2)); - } - else - { - return(KiUserTrapHandler(Tf, 14, (PVOID)cr2)); - } -} -
Modified: branches/cache_manager_rewrite/mm/iospace.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/iospace... ============================================================================== --- branches/cache_manager_rewrite/mm/iospace.c (original) +++ branches/cache_manager_rewrite/mm/iospace.c Fri Jan 5 23:28:18 2007 @@ -140,7 +140,7 @@ MmUnmapIoSpace (IN PVOID BaseAddress, IN ULONG NumberOfBytes) { - ULONG Offset; + LONG Offset; PVOID Address = BaseAddress;
Offset = (ULONG_PTR)Address % PAGE_SIZE;
Modified: branches/cache_manager_rewrite/mm/mdl.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/mdl.c?r... ============================================================================== --- branches/cache_manager_rewrite/mm/mdl.c (original) +++ branches/cache_manager_rewrite/mm/mdl.c Fri Jan 5 23:28:18 2007 @@ -433,7 +433,7 @@
if (!MmIsPagePresent(NULL, Address)) { - Status = MmNotPresentFault(Mode, (ULONG_PTR)Address, TRUE); + Status = MmAccessFault(FALSE, Address, Mode, NULL); if (!NT_SUCCESS(Status)) { for (j = 0; j < i; j++) @@ -457,7 +457,7 @@ if ((Operation == IoWriteAccess || Operation == IoModifyAccess) && (!(MmGetPageProtect(NULL, (PVOID)Address) & PAGE_READWRITE))) { - Status = MmAccessFault(Mode, (ULONG_PTR)Address, TRUE); + Status = MmAccessFault(TRUE, Address, Mode, NULL); if (!NT_SUCCESS(Status)) { for (j = 0; j < i; j++)
Modified: branches/cache_manager_rewrite/mm/mm.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/mm.c?re... ============================================================================== --- branches/cache_manager_rewrite/mm/mm.c (original) +++ branches/cache_manager_rewrite/mm/mm.c Fri Jan 5 23:28:18 2007 @@ -14,9 +14,6 @@ #include <internal/debug.h>
/* GLOBALS *****************************************************************/ - -extern LDR_DATA_TABLE_ENTRY NtoskrnlModuleObject; -extern LDR_DATA_TABLE_ENTRY HalModuleObject;
ULONG MmUserProbeAddress = 0; PVOID MmHighestUserAddress = NULL; @@ -78,9 +75,9 @@
NTSTATUS NTAPI -MmAccessFault(KPROCESSOR_MODE Mode, - ULONG_PTR Address, - BOOLEAN FromMdl) +MmpAccessFault(KPROCESSOR_MODE Mode, + ULONG_PTR Address, + BOOLEAN FromMdl) { PMADDRESS_SPACE AddressSpace; MEMORY_AREA* MemoryArea; @@ -112,7 +109,7 @@ { DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode, Address); DbgPrint("%s:%d\n",__FILE__,__LINE__); - return(STATUS_UNSUCCESSFUL); + return(STATUS_ACCESS_VIOLATION); } AddressSpace = MmGetKernelAddressSpace(); } @@ -134,13 +131,13 @@ { MmUnlockAddressSpace(AddressSpace); } - return (STATUS_UNSUCCESSFUL); + return (STATUS_ACCESS_VIOLATION); }
switch (MemoryArea->Type) { case MEMORY_AREA_SYSTEM: - Status = STATUS_UNSUCCESSFUL; + Status = STATUS_ACCESS_VIOLATION; break;
case MEMORY_AREA_PAGED_POOL: @@ -155,15 +152,15 @@ break;
case MEMORY_AREA_VIRTUAL_MEMORY: - Status = STATUS_UNSUCCESSFUL; + Status = STATUS_ACCESS_VIOLATION; break;
case MEMORY_AREA_SHARED_DATA: - Status = STATUS_UNSUCCESSFUL; + Status = STATUS_ACCESS_VIOLATION; break;
default: - Status = STATUS_UNSUCCESSFUL; + Status = STATUS_ACCESS_VIOLATION; break; } } @@ -173,32 +170,6 @@ if (!FromMdl) { MmUnlockAddressSpace(AddressSpace); - } - return(Status); -} - -NTSTATUS -NTAPI -MmCommitPagedPoolAddress(PVOID Address, BOOLEAN Locked) -{ - NTSTATUS Status; - PFN_TYPE AllocatedPage; - Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE, &AllocatedPage); - if (!NT_SUCCESS(Status)) - { - MmUnlockAddressSpace(MmGetKernelAddressSpace()); - Status = MmRequestPageMemoryConsumer(MC_PPOOL, TRUE, &AllocatedPage); - MmLockAddressSpace(MmGetKernelAddressSpace()); - } - Status = - MmCreateVirtualMapping(NULL, - (PVOID)PAGE_ROUND_DOWN(Address), - PAGE_READWRITE, - &AllocatedPage, - 1); - if (Locked) - { - MmLockPage(AllocatedPage); } return(Status); } @@ -230,7 +201,7 @@ DPRINT("No current process\n"); if (Address < (ULONG_PTR)MmSystemRangeStart) { - return(STATUS_UNSUCCESSFUL); + return(STATUS_ACCESS_VIOLATION); } }
@@ -245,7 +216,7 @@ if (Mode != KernelMode) { CPRINT("Address: %x\n", Address); - return(STATUS_UNSUCCESSFUL); + return(STATUS_ACCESS_VIOLATION); } AddressSpace = MmGetKernelAddressSpace(); } @@ -271,7 +242,7 @@ { MmUnlockAddressSpace(AddressSpace); } - return (STATUS_UNSUCCESSFUL); + return (STATUS_ACCESS_VIOLATION); }
switch (MemoryArea->Type) @@ -283,7 +254,7 @@ }
case MEMORY_AREA_SYSTEM: - Status = STATUS_UNSUCCESSFUL; + Status = STATUS_ACCESS_VIOLATION; break;
case MEMORY_AREA_SECTION_VIEW: @@ -313,7 +284,7 @@ break;
default: - Status = STATUS_UNSUCCESSFUL; + Status = STATUS_ACCESS_VIOLATION; break; } } @@ -326,6 +297,67 @@ } return(Status); } + +extern BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address); + +NTSTATUS +NTAPI +MmAccessFault(IN BOOLEAN StoreInstruction, + IN PVOID Address, + IN KPROCESSOR_MODE Mode, + IN PVOID TrapInformation) +{ + /* Cute little hack for ROS */ + if ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart) + { + /* Check for an invalid page directory in kernel mode */ + if (Mmi386MakeKernelPageTableGlobal(Address)) + { + /* All is well with the world */ + return STATUS_SUCCESS; + } + } + + /* Keep same old ReactOS Behaviour */ + if (StoreInstruction) + { + /* Call access fault */ + return MmpAccessFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE); + } + else + { + /* Call not present */ + return MmNotPresentFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE); + } +} + +NTSTATUS +NTAPI +MmCommitPagedPoolAddress(PVOID Address, BOOLEAN Locked) +{ + NTSTATUS Status; + PFN_TYPE AllocatedPage; + Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE, &AllocatedPage); + if (!NT_SUCCESS(Status)) + { + MmUnlockAddressSpace(MmGetKernelAddressSpace()); + Status = MmRequestPageMemoryConsumer(MC_PPOOL, TRUE, &AllocatedPage); + MmLockAddressSpace(MmGetKernelAddressSpace()); + } + Status = + MmCreateVirtualMapping(NULL, + (PVOID)PAGE_ROUND_DOWN(Address), + PAGE_READWRITE, + &AllocatedPage, + 1); + if (Locked) + { + MmLockPage(AllocatedPage); + } + return(Status); +} + +
/* Miscellanea functions: they may fit somewhere else */
@@ -371,38 +403,88 @@ * @implemented */ PVOID -STDCALL -MmGetSystemRoutineAddress ( - IN PUNICODE_STRING SystemRoutineName - ) -{ - PVOID ProcAddress; - ANSI_STRING AnsiRoutineName; - NTSTATUS Status; - - if(!NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiRoutineName, - SystemRoutineName, - TRUE))) - { - return NULL; - } - - Status = LdrGetProcedureAddress(NtoskrnlModuleObject.DllBase, - &AnsiRoutineName, - 0, - &ProcAddress); - - if(!NT_SUCCESS(Status)) - { - Status = LdrGetProcedureAddress(HalModuleObject.DllBase, - &AnsiRoutineName, - 0, - &ProcAddress); - } - - RtlFreeAnsiString(&AnsiRoutineName); - - return (NT_SUCCESS(Status) ? ProcAddress : NULL); +NTAPI +MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName) +{ + PVOID ProcAddress; + ANSI_STRING AnsiRoutineName; + NTSTATUS Status; + PLIST_ENTRY NextEntry; + extern LIST_ENTRY ModuleListHead; + PLDR_DATA_TABLE_ENTRY LdrEntry; + BOOLEAN Found = FALSE; + UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe"); + UNICODE_STRING HalName = RTL_CONSTANT_STRING(L"hal.dll"); + + /* Convert routine to ansi name */ + Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName, + SystemRoutineName, + TRUE); + if (!NT_SUCCESS(Status)) return NULL; + + /* Loop the loaded module list */ + NextEntry = ModuleListHead.Flink; + while (NextEntry != &ModuleListHead) + { + /* Get the entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + /* Check if it's the kernel or HAL */ + if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE)) + { + /* Found it */ + Found = TRUE; + } + else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE)) + { + /* Found it */ + Found = TRUE; + } + + /* Check if we found a valid binary */ + if (Found) + { + /* Find the procedure name */ + Status = LdrGetProcedureAddress(LdrEntry->DllBase, + &AnsiRoutineName, + 0, + &ProcAddress); + break; + } + + /* Keep looping */ + NextEntry = NextEntry->Flink; + } + + /* Free the string and return */ + RtlFreeAnsiString(&AnsiRoutineName); + return (NT_SUCCESS(Status) ? ProcAddress : NULL); +} + +NTSTATUS +NTAPI +NtGetWriteWatch(IN HANDLE ProcessHandle, + IN ULONG Flags, + IN PVOID BaseAddress, + IN ULONG RegionSize, + IN PVOID *UserAddressArray, + OUT PULONG EntriesInUserAddressArray, + OUT PULONG Granularity) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtResetWriteWatch(IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN ULONG RegionSize) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; }
/* EOF */
Modified: branches/cache_manager_rewrite/mm/mminit.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/mminit.... ============================================================================== --- branches/cache_manager_rewrite/mm/mminit.c (original) +++ branches/cache_manager_rewrite/mm/mminit.c Fri Jan 5 23:28:18 2007 @@ -19,6 +19,7 @@ /* * Compiler defined symbols */ +extern unsigned int _image_base__; extern unsigned int _text_start__; extern unsigned int _text_end__;
@@ -158,8 +159,8 @@ 0, BoundaryAddressMultiple);
- BaseAddress = (PVOID)KERNEL_BASE; - Length = PAGE_ROUND_UP(((ULONG_PTR)&_text_end__)) - KERNEL_BASE; + BaseAddress = (PVOID)&_image_base__; + Length = PAGE_ROUND_UP(((ULONG_PTR)&_text_end__)) - (ULONG_PTR)&_image_base__; ParamLength = ParamLength - Length;
/* @@ -299,11 +300,15 @@ ULONG i; ULONG kernel_len; ULONG_PTR MappingAddress; + PLDR_DATA_TABLE_ENTRY LdrEntry;
DPRINT("MmInit1(FirstKrnlPhysAddr, %p, LastKrnlPhysAddr %p, LastKernelAddress %p)\n", FirstKrnlPhysAddr, LastKrnlPhysAddr, LastKernelAddress); + + /* Set the page directory */ + PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart = (ULONG)MmGetPageDirectory();
if ((BIOSMemoryMap != NULL) && (AddressRangeCount > 0)) { @@ -317,15 +322,31 @@ last = (BIOSMemoryMap[i].BaseAddrLow + BIOSMemoryMap[i].LengthLow + PAGE_SIZE -1) / PAGE_SIZE; } } - if ((last - 256) * 4 > KeLoaderBlock.MemHigher) + if ((last - 256) * 4 > MmFreeLdrMemHigher) { - KeLoaderBlock.MemHigher = (last - 256) * 4; + MmFreeLdrMemHigher = (last - 256) * 4; } }
- if (KeLoaderBlock.MemHigher >= (MaxMem - 1) * 1024) - { - KeLoaderBlock.MemHigher = (MaxMem - 1) * 1024; + /* NTLDR Hacks */ + if (!MmFreeLdrMemHigher) MmFreeLdrMemHigher = 65536; + if (!MmFreeLdrPageDirectoryEnd) MmFreeLdrPageDirectoryEnd = 0x40000; + if (!FirstKrnlPhysAddr) + { + /* Get the kernel entry */ + LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + /* Get the addresses */ + FirstKrnlPhysAddr = (ULONG_PTR)LdrEntry->DllBase - KSEG0_BASE; + + /* FIXME: How do we get the last address? */ + } + + if (MmFreeLdrMemHigher >= (MaxMem - 1) * 1024) + { + MmFreeLdrMemHigher = (MaxMem - 1) * 1024; }
/* Set memory limits */ @@ -357,7 +378,7 @@ /* * Free physical memory not used by the kernel */ - MmStats.NrTotalPages = KeLoaderBlock.MemHigher/4; + MmStats.NrTotalPages = MmFreeLdrMemHigher/4; if (!MmStats.NrTotalPages) { DbgPrint("Memory not detected, default to 8 MB\n"); @@ -413,9 +434,9 @@ #endif
DPRINT("Invalidating between %x and %x\n", - LastKernelAddress, KERNEL_BASE + 0x00600000); + LastKernelAddress, KSEG0_BASE + 0x00600000); for (MappingAddress = LastKernelAddress; - MappingAddress < KERNEL_BASE + 0x00600000; + MappingAddress < KSEG0_BASE + 0x00600000; MappingAddress += PAGE_SIZE) { MmRawDeleteVirtualMapping((PVOID)MappingAddress); @@ -458,7 +479,6 @@ MmDeletePageTable(NULL, 0); #endif
- MmInitZeroPageThread(); MmCreatePhysicalMemorySection(); MiInitBalancerThread();
Modified: branches/cache_manager_rewrite/mm/pagefile.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/pagefil... ============================================================================== --- branches/cache_manager_rewrite/mm/pagefile.c (original) +++ branches/cache_manager_rewrite/mm/pagefile.c Fri Jan 5 23:28:18 2007 @@ -586,7 +586,7 @@ RetrievalPointers = PagingFileList[MmCoreDumpPageFile]->RetrievalPointers;
/* Dump the header. */ - MdlMap[0] = MmGetPhysicalAddress(MmCoreDumpPageFrame).QuadPart >> PAGE_SHIFT; + MdlMap[0] = (ULONG)(MmGetPhysicalAddress(MmCoreDumpPageFrame).QuadPart >> PAGE_SHIFT); #if defined(__GNUC__)
DiskOffset = MmGetOffsetPageFile(RetrievalPointers, (LARGE_INTEGER)0LL);
Modified: branches/cache_manager_rewrite/mm/pe.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/pe.c?re... ============================================================================== --- branches/cache_manager_rewrite/mm/pe.c (original) +++ branches/cache_manager_rewrite/mm/pe.c Fri Jan 5 23:28:18 2007 @@ -677,4 +677,108 @@ 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 */
Modified: branches/cache_manager_rewrite/mm/pool.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/pool.c?... ============================================================================== --- branches/cache_manager_rewrite/mm/pool.c (original) +++ branches/cache_manager_rewrite/mm/pool.c Fri Jan 5 23:28:18 2007 @@ -161,53 +161,62 @@ return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag); }
-/* - * @implemented - */ -PVOID STDCALL +_SEH_DEFINE_LOCALS(ExQuotaPoolVars) +{ + PVOID Block; +}; + +_SEH_FILTER(FreeAndGoOn) +{ + _SEH_ACCESS_LOCALS(ExQuotaPoolVars); + + /* Couldn't charge, so free the pool and let the caller SEH manage */ + ExFreePool(_SEH_VAR(Block)); + return EXCEPTION_CONTINUE_SEARCH; +} + +/* + * @implemented + */ +PVOID +NTAPI ExAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType, - IN ULONG NumberOfBytes, - IN ULONG Tag) -{ - PVOID Block; + IN ULONG NumberOfBytes, + IN ULONG Tag) +{ PEPROCESS Process; + _SEH_DECLARE_LOCALS(ExQuotaPoolVars);
/* Allocate the Pool First */ - Block = EiAllocatePool(PoolType, - NumberOfBytes, - Tag, - &ExAllocatePoolWithQuotaTag); + _SEH_VAR(Block) = EiAllocatePool(PoolType, + NumberOfBytes, + Tag, + &ExAllocatePoolWithQuotaTag);
/* "Quota is not charged to the thread for allocations >= PAGE_SIZE" - OSR Docs */ - if (!(NumberOfBytes >= PAGE_SIZE)) { - + if (!(NumberOfBytes >= PAGE_SIZE)) + { /* Get the Current Process */ Process = PsGetCurrentProcess();
/* PsChargePoolQuota returns an exception, so this needs SEH */ -#if defined(__GNUC__) - _SEH_FILTER(FreeAndGoOn) { - /* Couldn't charge, so free the pool and let the caller SEH manage */ - ExFreePool(Block); - return EXCEPTION_CONTINUE_SEARCH; - } _SEH_TRY { - //* FIXME: Is there a way to get the actual Pool size allocated from the pool header? */ - PsChargePoolQuota(Process, PoolType & PAGED_POOL_MASK, NumberOfBytes); - } _SEH_EXCEPT(FreeAndGoOn) { + _SEH_TRY + { + /* FIXME: Is there a way to get the actual Pool size allocated from the pool header? */ + PsChargePoolQuota(Process, + PoolType & PAGED_POOL_MASK, + NumberOfBytes); + } + _SEH_EXCEPT(FreeAndGoOn) + { /* Quota Exceeded and the caller had no SEH! */ KeBugCheck(STATUS_QUOTA_EXCEEDED); - } _SEH_END; -#else /* assuming all other Win32 compilers understand SEH */ - __try { - PsChargePoolQuota(Process, PoolType & PAGED_POOL_MASK, NumberOfBytes); - } - __except (ExFreePool(Block), EXCEPTION_CONTINUE_SEARCH) { - KeBugCheck(STATUS_QUOTA_EXCEEDED); - } -#endif + } + _SEH_END; }
- return Block; + /* Return the allocated block */ + return _SEH_VAR(Block); }
/*
Modified: branches/cache_manager_rewrite/mm/process.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/process... ============================================================================== --- branches/cache_manager_rewrite/mm/process.c (original) +++ branches/cache_manager_rewrite/mm/process.c Fri Jan 5 23:28:18 2007 @@ -291,7 +291,7 @@
/* Map NLS Tables */ DPRINT("Mapping NLS\n"); - Status = MmMapViewOfSection(NlsSectionObject, + Status = MmMapViewOfSection(ExpNlsSectionPointer, (PEPROCESS)Process, &TableBase, 0, @@ -322,9 +322,9 @@ Peb->Mutant = NULL;
/* NLS */ - Peb->AnsiCodePageData = (char*)TableBase + NlsAnsiTableOffset; - Peb->OemCodePageData = (char*)TableBase + NlsOemTableOffset; - Peb->UnicodeCaseTableData = (char*)TableBase + NlsUnicodeTableOffset; + Peb->AnsiCodePageData = (PCHAR)TableBase + ExpAnsiCodePageDataOffset; + Peb->OemCodePageData = (PCHAR)TableBase + ExpOemCodePageDataOffset; + Peb->UnicodeCaseTableData = (PCHAR)TableBase + ExpUnicodeCaseTableDataOffset;
/* Default Version Data (could get changed below) */ Peb->OSMajorVersion = NtMajorVersion;
Modified: branches/cache_manager_rewrite/mm/rmap.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/rmap.c?... ============================================================================== --- branches/cache_manager_rewrite/mm/rmap.c (original) +++ branches/cache_manager_rewrite/mm/rmap.c Fri Jan 5 23:28:18 2007 @@ -408,7 +408,7 @@ KEBUGCHECK(0); } new_entry->Address = Address; - new_entry->Process = Process; + new_entry->Process = (PEPROCESS)Process; #ifdef DBG new_entry->Caller = __builtin_return_address(0); #endif @@ -510,7 +510,7 @@ current_entry = MmGetRmapListHeadPage(Page); while (current_entry != NULL) { - if (current_entry->Process == Process && + if (current_entry->Process == (PEPROCESS)Process && current_entry->Address == Address) { if (previous_entry == NULL)
Modified: branches/cache_manager_rewrite/mm/section.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/section... ============================================================================== --- branches/cache_manager_rewrite/mm/section.c (original) +++ branches/cache_manager_rewrite/mm/section.c Fri Jan 5 23:28:18 2007 @@ -142,6 +142,65 @@
/* Return the file object */ return Section->FileObject; // Section->ControlArea->FileObject on NT +} + +NTSTATUS +NTAPI +MmGetFileNameForSection(IN PROS_SECTION_OBJECT Section, + OUT POBJECT_NAME_INFORMATION *ModuleName) +{ + POBJECT_NAME_INFORMATION ObjectNameInfo; + NTSTATUS Status; + ULONG ReturnLength; + + /* Make sure it's an image section */ + *ModuleName = NULL; + if (!(Section->AllocationAttributes & SEC_IMAGE)) + { + /* It's not, fail */ + return STATUS_SECTION_NOT_IMAGE; + } + + /* Allocate memory for our structure */ + ObjectNameInfo = ExAllocatePoolWithTag(PagedPool, + 1024, + TAG('M', 'm', ' ', ' ')); + if (!ObjectNameInfo) return STATUS_NO_MEMORY; + + /* Query the name */ + Status = ObQueryNameString(Section->FileObject, + ObjectNameInfo, + 1024, + &ReturnLength); + if (!NT_SUCCESS(Status)) + { + /* Failed, free memory */ + ExFreePool(ObjectNameInfo); + return Status; + } + + /* Success */ + *ModuleName = ObjectNameInfo; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +MmGetFileNameForAddress(IN PVOID Address, + OUT PUNICODE_STRING ModuleName) +{ + /* + * FIXME: TODO. + * Filip says to get the MADDRESS_SPACE from EPROCESS, + * then use the MmMarea routines to locate the Marea that + * corresponds to the address. Then make sure it's a section + * view type (MEMORY_AREA_SECTION_VIEW) and use the marea's + * per-type union to get the .u.SectionView.Section pointer to + * the SECTION_OBJECT. Then we can use MmGetFileNameForSection + * to get the full filename. + */ + RtlCreateUnicodeString(ModuleName, L"C:\ReactOS\system32\ntdll.dll"); + return STATUS_SUCCESS; }
/* Note: Mmsp prefix denotes "Memory Manager Section Private". */ @@ -2916,7 +2975,7 @@ return(STATUS_SUCCESS); }
-VOID STATIC +VOID static MmAlterViewAttributes(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress, ULONG RegionSize, @@ -4586,7 +4645,7 @@ return(Status); }
-NTSTATUS STATIC +NTSTATUS static MmMapViewOfSegment(PMADDRESS_SPACE AddressSpace, PROS_SECTION_OBJECT Section, PMM_SECTION_SEGMENT Segment, @@ -4835,7 +4894,7 @@ return(Status); }
-VOID STATIC +VOID static MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty) { @@ -4927,7 +4986,7 @@ } }
-STATIC NTSTATUS +static NTSTATUS MmUnmapViewOfSegment(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress) { @@ -5066,7 +5125,8 @@ * and calculate the image base address */ for (i = 0; i < NrSegments; i++) { - if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + // This field is RESERVED and not respected by Windows + //if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { if (Segment == &SectionSegments[i]) { @@ -5082,7 +5142,8 @@
for (i = 0; i < NrSegments; i++) { - if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + // This field is RESERVED and not respected by Windows + //if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { PVOID SBaseAddress = (PVOID) ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].VirtualAddress); @@ -5626,7 +5687,8 @@ ImageSize = 0; for (i = 0; i < NrSegments; i++) { - if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + // This field is RESERVED and not respected by Windows + //if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { ULONG_PTR MaxExtent; MaxExtent = (ULONG_PTR)SectionSegments[i].VirtualAddress + @@ -5656,7 +5718,8 @@
for (i = 0; i < NrSegments; i++) { - if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + // This field is RESERVED and not respected by Windows + //if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { PVOID SBaseAddress = (PVOID) ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].VirtualAddress); @@ -6629,4 +6692,54 @@ return STATUS_SUCCESS; }
+NTSTATUS +NTAPI +NtAllocateUserPhysicalPages(IN HANDLE ProcessHandle, + IN OUT PULONG NumberOfPages, + IN OUT PULONG UserPfnArray) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtMapUserPhysicalPages(IN PVOID *VirtualAddresses, + IN ULONG NumberOfPages, + IN OUT PULONG UserPfnArray) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtMapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses, + IN ULONG NumberOfPages, + IN OUT PULONG UserPfnArray) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtFreeUserPhysicalPages(IN HANDLE ProcessHandle, + IN OUT PULONG NumberOfPages, + IN OUT PULONG UserPfnArray) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage, + IN PVOID File2MappedAsFile) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + + /* EOF */
Modified: branches/cache_manager_rewrite/mm/verifier.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/verifie... ============================================================================== --- branches/cache_manager_rewrite/mm/verifier.c (original) +++ branches/cache_manager_rewrite/mm/verifier.c Fri Jan 5 23:28:18 2007 @@ -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 */
Modified: branches/cache_manager_rewrite/mm/virtual.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/virtual... ============================================================================== --- branches/cache_manager_rewrite/mm/virtual.c (original) +++ branches/cache_manager_rewrite/mm/virtual.c Fri Jan 5 23:28:18 2007 @@ -263,6 +263,7 @@ MmUnlockAddressSpace(AddressSpace); if (Address < MmSystemRangeStart) { + ASSERT(Process); ObDereferenceObject(Process); }