MmSplitRegion函数
//改变区块属性,并分裂区块保持属性一致:
MmSplitRegion
//改变区块属性,并分裂区块保持属性一致:
PMM_REGION static
MmSplitRegion(PMM_REGION InitialRegion, PVOID InitialBaseAddress,
PVOID StartAddress, ULONG Length, ULONG NewType,
ULONG NewProtect, PMADDRESS_SPACE AddressSpace,
PMM_ALTER_REGION_FUNC AlterFunc)
{
PMM_REGION NewRegion1;
PMM_REGION NewRegion2;
ULONG InternalLength;
/* Allocate this in front otherwise the failure case is too difficult. */
NewRegion2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
TAG_MM_REGION);
if (NewRegion2 == NULL)
{
return(NULL);
}
/* Create the new region. */
NewRegion1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
TAG_MM_REGION);
if (NewRegion1 == NULL)
{
ExFreePool(NewRegion2);
return(NULL);
}
NewRegion1->Type = NewType;
NewRegion1->Protect = NewProtect;
InternalLength = ((char*)InitialBaseAddress + InitialRegion->Length) - (char*)StartAddress;
InternalLength = min(InternalLength, Length);
NewRegion1->Length = InternalLength;
InsertAfterEntry(&InitialRegion->RegionListEntry,
&NewRegion1->RegionListEntry);
/*
* Call our helper function to do the changes on the addresses contained
* in the initial region.
*/
AlterFunc(AddressSpace, StartAddress, InternalLength, InitialRegion->Type,
InitialRegion->Protect, NewType, NewProtect);
/*
* If necessary create a new region for the portion of the initial region
* beyond the range of addresses to alter.
*/
if (((char*)InitialBaseAddress + InitialRegion->Length) > ((char*)StartAddress + Length))
{
NewRegion2->Type = InitialRegion->Type;
NewRegion2->Protect = InitialRegion->Protect;
NewRegion2->Length = ((char*)InitialBaseAddress + InitialRegion->Length) -
((char*)StartAddress + Length);
InsertAfterEntry(&NewRegion1->RegionListEntry,
&NewRegion2->RegionListEntry);
}
else
{
ExFreePool(NewRegion2);
}
/* Either remove or shrink the initial region. */
if (InitialBaseAddress == StartAddress)
{
RemoveEntryList(&InitialRegion->RegionListEntry);
ExFreePool(InitialRegion);
}
else
{
InitialRegion->Length = (char*)StartAddress - (char*)InitialBaseAddress;
}
return(NewRegion1);
}