加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactos操作系统实现(32)

发布时间:2020-12-15 05:01:54 所属栏目:百科 来源:网络整理
导读:这个函数主要功能就是实现访问不存在的页面。 #001 NTSTATUS #002 NTAPI #003 MmNotPresentFault(KPROCESSOR_MODE Mode, #004 ULONG_PTR Address, #005 BOOLEAN FromMdl) #006 { #007 PMM_AVL_TABLE AddressSpace; #008 MEMORY_AREA* MemoryArea; #009 NTSTA

这个函数主要功能就是实现访问不存在的页面。

#001 NTSTATUS

#002 NTAPI

#003 MmNotPresentFault(KPROCESSOR_MODE Mode,

#004 ULONG_PTR Address,

#005 BOOLEAN FromMdl)

#006 {

#007 PMM_AVL_TABLE AddressSpace;

#008 MEMORY_AREA* MemoryArea;

#009 NTSTATUS Status;

#010 BOOLEAN Locked = FromMdl;

#011 PFN_TYPE Pfn;

#012

#013 DPRINT("MmNotPresentFault(Mode %d,Address %x)/n",Mode,Address);

#014

判断访问内存的级别。

#015 if (KeGetCurrentIrql() >= DISPATCH_LEVEL)

#016 {

#017 DPRINT1("Page fault at high IRQL was %d,address %x/n",KeGetCurrentIrql(),Address);

#018 return(STATUS_UNSUCCESSFUL);

#019 }

#020

判断是否在内核内存,还是在进程内存空间上。

#021 /*

#022 * Find the memory area for the faulting address

#023 */

#024 if (Address >= (ULONG_PTR)MmSystemRangeStart)

#025 {

#026 /*

#027 * Check permissions

#028 */

#029 if (Mode != KernelMode)

#030 {

#031 DPRINT1("Address: %x/n",Address);

#032 return(STATUS_ACCESS_VIOLATION);

#033 }

#034 AddressSpace = MmGetKernelAddressSpace();

#035 }

#036 else

#037 {

#038 AddressSpace = &PsGetCurrentProcess()->VadRoot;

#039 }

#040

#041 if (!FromMdl)

#042 {

#043 MmLockAddressSpace(AddressSpace);

#044 }

#045

根据内存类型调用不同的缺页中断处理函数。

#046 /*

#047 * Call the memory area specific fault handler

#048 */

#049 do

#050 {

#051 MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,(PVOID)Address);

#052 if (MemoryArea == NULL || MemoryArea->DeleteInProgress)

#053 {

#054 if (!FromMdl)

#055 {

#056 MmUnlockAddressSpace(AddressSpace);

#057 }

#058 return (STATUS_ACCESS_VIOLATION);

#059 }

#060

#061 switch (MemoryArea->Type)

#062 {

#063 case MEMORY_AREA_PAGED_POOL:

#064 {

#065 Status = MmCommitPagedPoolAddress((PVOID)Address,Locked);

#066 break;

#067 }

#068

#069 case MEMORY_AREA_SYSTEM:

#070 Status = STATUS_ACCESS_VIOLATION;

#071 break;

#072

#073 case MEMORY_AREA_SECTION_VIEW:

#074 Status = MmNotPresentFaultSectionView(AddressSpace,

#075 MemoryArea,

#076 (PVOID)Address,

#077 Locked);

#078 break;

#079

#080 case MEMORY_AREA_VIRTUAL_MEMORY:

#081 case MEMORY_AREA_PEB_OR_TEB:

#082 Status = MmNotPresentFaultVirtualMemory(AddressSpace,

#083 MemoryArea,

#084 (PVOID)Address,

#085 Locked);

#086 break;

#087

#088 case MEMORY_AREA_SHARED_DATA:

#089 Pfn = MmSharedDataPagePhysicalAddress.LowPart >> PAGE_SHIFT;

#090 Status =

#091 MmCreateVirtualMapping(PsGetCurrentProcess(),

#092 (PVOID)PAGE_ROUND_DOWN(Address),

#093 PAGE_READONLY,

#094 &Pfn,

#095 1);

#096 break;

#097

#098 default:

#099 Status = STATUS_ACCESS_VIOLATION;

#100 break;

#101 }

#102 }

#103 while (Status == STATUS_MM_RESTART_OPERATION);

#104

#105 DPRINT("Completed page fault handling/n");

#106 if (!FromMdl)

#107 {

#108 MmUnlockAddressSpace(AddressSpace);

#109 }

#110 return(Status);

#111 }

通过上面的函数,就可以实现读取内存不存在的缺页中断处理。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读